vdr-plugin-live/0000755000175000017500000000000012650773437013444 5ustar tobiastobiasvdr-plugin-live/debian/0000755000175000017500000000000012650773437014666 5ustar tobiastobiasvdr-plugin-live/debian/install0000644000175000017500000000020712650773437016256 0ustar tobiastobiaslibvdr-live.so.* usr/lib/vdr/plugins/ debian/plugin.live.conf etc/vdr/plugins/ live/* usr/share/vdr-plugin-live/ vdr-plugin-live/debian/patches/0000755000175000017500000000000012650773437016315 5ustar tobiastobiasvdr-plugin-live/debian/patches/00list0000644000175000017500000000001212650773437017344 0ustar tobiastobias#90_clean vdr-plugin-live/debian/patches/90_clean.dpatch0000755000175000017500000000067212650773437021104 0ustar tobiastobias#!/bin/sh /usr/share/dpatch/dpatch-run ## 99_clean.dpatch - Tobias Grimm ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Fixes clean target @DPATCH@ --- vdr-plugin-live-0.1.0.orig/pages/Makefile +++ vdr-plugin-live-0.1.0/pages/Makefile @@ -53,4 +53,4 @@ $(AR) r $@ $^ clean: - @rm -f *~ *.o core* libpages.a $(OBJS:%.o=%.cpp) + @rm -f *~ *.o core* libpages.a $(OBJS:%.o=%.cpp) $(DEPFILE) vdr-plugin-live/debian/postrm0000644000175000017500000000204512650773437016136 0ustar tobiastobias#!/bin/sh # postrm script for vdr-plugin-live # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in purge) rm -f /var/lib/vdr/plugins/live/httpd.config rm -f /var/lib/vdr/plugins/live/httpd.properties ;; remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 vdr-plugin-live/debian/rules0000755000175000017500000000355612650773437015757 0ustar tobiastobias#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CFLAGS += -g endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif # To use dpatch uncomment the following line and set Build-Depends to dpatch DPATCH=yes ifdef DPATCH include /usr/share/dpatch/dpatch.make else patch: patch-stamp: unpatch: endif MAKE_OPTIONS = DVBDIR=/usr LIBDIR=. LOCDIR=locale configure: configure-stamp configure-stamp: patch-stamp dh_testdir touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir $(MAKE) all $(MAKE_OPTIONS) touch build-stamp clean: clean-patched unpatch clean-patched: dh_testdir dh_testroot rm -f build-stamp configure-stamp -$(MAKE) -o .dependencies clean $(MAKE_OPTIONS) rm -f libvdr-*.so.* rm -rf locale dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) install $(MAKE_OPTIONS) dh_install # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot # dh_installdebconf dh_installdocs dh_installexamples # dh_installmenu # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_installinit # dh_installcron # dh_installman # dh_installinfo # dh_undocumented dh_installchangelogs HISTORY dh_link dh_strip dh_compress dh_fixperms # dh_makeshlibs dh_installdeb # dh_perl dh_shlibdeps # sh /usr/share/vdr-dev/patchlevel.sh subst sh /usr/share/vdr-dev/dependencies.sh dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure \ clean-patched patch unpatch vdr-plugin-live/debian/postinst0000644000175000017500000000177212650773437016503 0ustar tobiastobias#!/bin/sh # postinst script for vdr-plugin-live # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in configure) chown -R vdr:vdr /var/lib/vdr/plugins/live ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 vdr-plugin-live/debian/compat0000644000175000017500000000000212650773437016064 0ustar tobiastobias5 vdr-plugin-live/debian/changelog0000644000175000017500000000610712650773437016544 0ustar tobiastobiasvdr-plugin-live (0.1.0-30) unstable; urgency=low * cg-update 20071202 -- Michael Brueckner Sun, 02 Dec 2007 01:00:18 +0100 vdr-plugin-live (0.1.0-29) unstable; urgency=low * cg-update 20071202 -- Michael Brueckner Sun, 02 Dec 2007 00:58:57 +0100 vdr-plugin-live (0.1.0-28) unstable; urgency=low * cg-update 20071021 -- Michael Brueckner Sun, 21 Oct 2007 17:36:23 +0200 vdr-plugin-live (0.1.0-27) unstable; urgency=low * cg-update 20071021 -- Michael Brueckner Sun, 21 Oct 2007 17:17:30 +0200 vdr-plugin-live (0.1.0-26) unstable; urgency=low * cg-update 20071005 -- Michael Brueckner Fri, 05 Oct 2007 17:25:49 +0200 vdr-plugin-live (0.1.0-25) unstable; urgency=low * cg-update 20070917 -- Michael Brueckner Mon, 17 Sep 2007 01:11:54 +0200 vdr-plugin-live (0.1.0-24) unstable; urgency=low * cg-update 20070917 -- Michael Brueckner Mon, 17 Sep 2007 01:07:41 +0200 vdr-plugin-live (0.1.0-23) unstable; urgency=low * cg-update 20070917 -- Michael Brueckner Mon, 17 Sep 2007 01:06:00 +0200 vdr-plugin-live (0.1.0-22) unstable; urgency=low * cg-update 20070917 -- Michael Brueckner Mon, 17 Sep 2007 01:00:08 +0200 vdr-plugin-live (0.1.0-21) unstable; urgency=low * cg-update 20070917 -- Michael Brueckner Mon, 17 Sep 2007 00:36:35 +0200 vdr-plugin-live (0.1.0-20) unstable; urgency=low * cg-update 20070916 -- Michael Brueckner Sun, 16 Sep 2007 23:43:27 +0200 vdr-plugin-live (0.1.0-19) unstable; urgency=low * cg-update 20070909 -- Michael Brueckner Sun, 09 Sep 2007 00:18:35 +0200 vdr-plugin-live (0.1.0-18) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 01:01:21 +0200 vdr-plugin-live (0.1.0-17) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 00:50:18 +0200 vdr-plugin-live (0.1.0-16) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 00:44:14 +0200 vdr-plugin-live (0.1.0-15) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 00:28:30 +0200 vdr-plugin-live (0.1.0-14) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 00:10:31 +0200 vdr-plugin-live (0.1.0-13) unstable; urgency=low * cg-update 20070907 -- Michael Brueckner Fri, 07 Sep 2007 00:00:46 +0200 vdr-plugin-live (0.1.0-1) unstable; urgency=low * Initial release (Closes: #426762) -- Tobias Grimm Wed, 30 May 2007 20:54:17 +0200 vdr-plugin-live/debian/links0000644000175000017500000000037312650773437015734 0ustar tobiastobiasusr/share/vdr-plugin-live/css usr/share/vdr/plugins/live/css usr/share/vdr-plugin-live/img usr/share/vdr/plugins/live/img usr/share/vdr-plugin-live/js usr/share/vdr/plugins/live/js usr/share/vdr-plugin-live/themes usr/share/vdr/plugins/live/themes vdr-plugin-live/debian/control0000644000175000017500000000204712650773437016274 0ustar tobiastobiasSource: vdr-plugin-live Section: misc Priority: extra Maintainer: Debian VDR Team Uploaders: Thomas Schmidt , Tobias Grimm Build-Depends: debhelper (>= 5), dpatch, vdr-dev (>= 1.4.6-2ctvdr1), libtntnet-dev, libcxxtools-dev, libssl-dev Standards-Version: 3.7.2 XS-Vcs-Svn: svn://svn.debian.org/pkg-vdr-dvb/vdr/vdr-plugin-live/trunk/ XS-Vcs-Browser: http://svn.debian.org/wsvn/pkg-vdr-dvb/vdr/vdr-plugin-live/trunk/ Package: vdr-plugin-live Architecture: any Depends: ${shlibs:Depends}, ${vdr:Depends} Description: Web administration plugin for VDR Live, the "Live Interactive VDR Environment", is a plugin providing the possibility to interactively control the Linux Video Disc Recorder VDR and some of it's plugins from a web interface. . Unlike external programs, like the VDR web frontend "VDRAdmin-AM", that communicate with VDR via its SVDRP socket interface, Live has direct access to VDR's data structures and thus is very fast. XB-VDR-Patchlevel: ${vdr:Patchlevel} vdr-plugin-live/debian/copyright0000644000175000017500000003217412650773437016630 0ustar tobiastobiasThis package was debianized by Tobias Grimm on Wed, 30 May 2007 20:54:17 +0200. It was downloaded from http://live.vdr-developer.org Upstream Authors: Thomas Keil Sascha Volkenandt Dieter Hametner Christian Wieninger Michael Brueckner Debian Maintainers: Tobias Grimm Copyright: (C) 2007 Thomas Keil, Sascha Volkenandt, Dieter Hametner, Christian Wieninger, Michael Brueckner (C) 2003-2006 Tommi Maekitalo (Tntnet httpd) (C) 2002-2005 Dan Allen, Mojavelinux.com (DOM Tooltip JavaScript library) License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. The complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL on most Debian systems. License (DOM Tooltip JavaScript library): Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. The Debian packaging is (C) 2007, Tobias Grimm and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. vdr-plugin-live/debian/plugin.live.conf0000644000175000017500000000033212650773437017767 0ustar tobiastobias# # Command line parameters for vdr-plugin-live # # For more details see: # - /usr/share/doc/vdr-plugin-live/README # - `vdr --help -Plive` --port=8008 --ip=0.0.0.0 --log=INFO --epgimages=/var/cache/vdr/epgimages vdr-plugin-live/debian/docs0000644000175000017500000000000712650773437015536 0ustar tobiastobiasREADME vdr-plugin-live/debian/watch0000644000175000017500000000011212650773437015711 0ustar tobiastobiasversion=3 http://live.vdr-developer.org/downloads/vdr-live-(.*)\.tar\.gz vdr-plugin-live/debian/dirs0000644000175000017500000000003112650773437015544 0ustar tobiastobiasvar/lib/vdr/plugins/live vdr-plugin-live/setup.h0000644000175000017500000001423012650773437014755 0ustar tobiastobias#ifndef VDR_LIVE_SETUP_H #define VDR_LIVE_SETUP_H #include #include #include #include #include "live.h" #include "tntfeatures.h" #include #define LIVEVERSION "0.3.0" #define LIVEVERSNUM 300 #define LIVESUMMARY trNOOP("Live Interactive VDR Environment") namespace vdrlive { // forward declaration, see below class cMenuSetupLive; class Setup { friend Setup& LiveSetup(); friend class cMenuSetupLive; // friend declaration is not forward // declaration, although gcc 3.3 claims so public: typedef std::list< std::string > IpList; // commandline int GetServerPort() const { return m_serverPort; } int GetServerSslPort() const { return m_serverSslPort; } std::string GetServerSslCert() const { return m_serverSslCert; } std::string GetServerSslKey() const { return m_serverSslKey; } IpList const& GetServerIps() const { return m_serverIps; } // vdr-setup int GetLastChannel() const { return m_lastChannel == 0 ? std::numeric_limits< int >::max() : m_lastChannel; } int GetScreenshotInterval() const { return m_screenshotInterval; } std::string const GetAdminLogin() const { return m_adminLogin; } std::string const GetMD5HashAdminPassword() const; int GetAdminPasswordLength() const; bool GetUseAuth() const { return m_useAuth; } bool UseAuth() const; std::string const GetTimes() const { return m_times; } std::string const GetChannelGroups() const { return m_channelGroups; } std::string const GetScheduleDuration() const { return m_scheduleDuration; } std::string const GetStartScreen() const { return m_startscreen; } std::string const GetStartScreenLink() const; std::string const GetTheme() const { return m_theme; } std::string const GetThemedLink(std::string const & type, const std::string& name) const { return "themes/" + GetTheme() + "/" + type + "/" + name; } std::string const GetLocalNetMask() const { return m_localnetmask; }; bool GetIsLocalNet() const { return m_islocalnet; }; std::string const GetLastWhatsOnListMode() const { return m_lastwhatsonlistmode; } std::string const GetLastSortingMode() const { return m_lastsortingmode; } std::string const GetTntnetLogLevel() const { return m_tntnetloglevel; } bool GetShowLogo() const { return m_showLogo != 0; } bool GetUseAjax() const { return m_useAjax != 0; } bool GetShowInfoBox() const { return m_showInfoBox != 0; } bool GetUseStreamdev() const { return m_useStreamdev != 0; } int GetStreamdevPort() const { return m_streamdevPort; } std::string const GetStreamdevType() const { return m_streamdevType; } bool GetShowIMDb() const { return m_showIMDb != 0; } std::string const GetEpgImageDir() { return m_epgimagedir; } bool GetShowChannelsWithoutEPG() const { return m_showChannelsWithoutEPG != 0; } void SetLastChannel(int lastChannel) { m_lastChannel = lastChannel; } void SetAdminLogin(std::string const & login) { m_adminLogin = login; } std::string SetAdminPassword(std::string password); void SetUseAuth(int auth) { m_useAuth = auth; } void SetScreenshotInterval(int interval) { m_screenshotInterval = interval; } void SetTimes(std::string const & times) { m_times = times; } void SetChannelGroups(std::string const & channelGroups) { m_channelGroups = channelGroups; } void SetScheduleDuration(std::string const & scheduleDuration) { m_scheduleDuration = scheduleDuration; } void SetStartScreen(std::string const & startscreen) { m_startscreen = startscreen; } void SetTheme(std::string const & theme) { m_theme = theme; } void SetLocalNetMask(std::string const & localnetmask) { m_localnetmask = localnetmask; } void SetIsLocalNet(bool islocalnet) { m_islocalnet = islocalnet; } void SetLastWhatsOnListMode(std::string const & mode) { m_lastwhatsonlistmode = mode; SaveSetup(); } void SetLastSortingMode(std::string const & mode) { m_lastsortingmode = mode; SaveSetup(); } void SetShowLogo(bool show) { m_showLogo = show ? 1 : 0; } void SetUseAjax(bool use) { m_useAjax = use ? 1 : 0; } void SetShowInfoBox(bool show) { m_showInfoBox = show ? 1 : 0; } void SetUseStreamdev(bool use) { m_useStreamdev = use ? 1 : 0; } void SetStreamdevPort(int port) { m_streamdevPort = port; } void SetStreamdevType(std::string const & type) { m_streamdevType = type; } void SetShowIMDb(bool show) { m_showIMDb = show ? 1 : 0; } void SetShowChannelsWithoutEPG(bool show) { m_showChannelsWithoutEPG = show ? 1 : 0; } bool SaveSetup(); bool ParseCommandLine( int argc, char* argv[] ); char const* CommandLineHelp() const; bool ParseSetupEntry( char const* name, char const* value ); bool CheckLocalNet(std::string const & ip); private: Setup(); Setup( Setup const& ); // me cPlugin* liveplugin; mutable std::string m_helpString; // commandline options int m_serverPort; int m_serverSslPort; std::string m_serverSslCert; std::string m_serverSslKey; static std::string m_configDirectory; IpList m_serverIps; std::string m_epgimagedir; // setup options int m_lastChannel; int m_screenshotInterval; int m_useAuth; std::string m_adminLogin; std::string m_adminPasswordMD5; std::string m_times; std::string m_channelGroups; std::string m_scheduleDuration; std::string m_startscreen; std::string m_theme; std::string m_localnetmask; bool m_islocalnet; std::string m_lastwhatsonlistmode; std::string m_lastsortingmode; std::string m_tntnetloglevel; int m_showLogo; int m_useAjax; int m_showInfoBox; int m_useStreamdev; int m_streamdevPort; std::string m_streamdevType; int m_showIMDb; int m_showChannelsWithoutEPG; bool CheckServerPort(); bool CheckServerIps(); bool CheckServerSslPort(); }; Setup& LiveSetup(); class cMenuSetupLive : public cMenuSetupPage { protected: virtual void Store(void); virtual eOSState ProcessKey(eKeys Key); public: cMenuSetupLive(); private: int m_lastChannel; int m_screenshotInterval; int m_useAuth; char m_adminLogin[20]; char m_adminPassword[20]; char m_tmpPassword[20]; std::string m_oldpasswordMD5; std::string m_newpasswordMD5; void Set(void); bool InEditMode(const char* ItemText, const char* ItemName, const char* ItemValue); }; } // namespace vdrlive #endif // VDR_LIVE_SETUP_H vdr-plugin-live/timerconflict.h0000644000175000017500000000447212650773437016466 0ustar tobiastobias#ifndef VDR_LIVE_TIMERCONFLICT_H #define VDR_LIVE_TIMERCONFLICT_H #include #include "stdext.h" namespace vdrlive { // classes for timer conflict interface // conflicting timer class TimerInConflict { public: int timerIndex; // it's index in VDR int percentage; // percentage of recording std::list concurrentTimerIndices; // concurrent timer indices TimerInConflict(int TimerIndex=-1, int Percentage=0) : timerIndex(TimerIndex), percentage(Percentage) {} }; class TimerConflict; bool operator<( TimerConflict const& left, TimerConflict const& right ); // one timer conflict time class TimerConflict { time_t conflictTime; // time of conflict std::list< TimerInConflict > conflictingTimers; // conflicting timers at this time friend bool operator<( TimerConflict const& left, TimerConflict const& right ); public: TimerConflict( std::string const& data ); TimerConflict(); void Init(); time_t ConflictTime() { return conflictTime; } const std::list< TimerInConflict >& ConflictingTimers() { return conflictingTimers; } }; class TimerConflicts { public: typedef std::list< TimerConflict > ConflictList; typedef ConflictList::size_type size_type; typedef ConflictList::iterator iterator; typedef ConflictList::const_iterator const_iterator; TimerConflicts(); size_type size() const { return m_conflicts.size(); } iterator begin() { return m_conflicts.begin(); } const_iterator begin() const { return m_conflicts.begin(); } iterator end() { return m_conflicts.end(); } const_iterator end() const { return m_conflicts.end(); } static bool CheckAdvised(); private: ConflictList m_conflicts; }; class TimerConflictNotifier { public: typedef std::tr1::shared_ptr TimerConflictsPtr; TimerConflictNotifier(); virtual ~TimerConflictNotifier(); bool ShouldNotify(); void SetTimerModification(); std::string Message() const; std::string Url() const; TimerConflictsPtr const CurrentConflicts() const { return conflicts; } static int const CHECKINTERVAL = 5; // recheck value in seconds. private: time_t lastCheck; time_t lastTimerModification; TimerConflictsPtr conflicts; }; // class TimerConflictNotifier } // namespace vdrlive #endif // VDR_LIVE_TIMERCONFLICT_H vdr-plugin-live/COPYING0000644000175000017500000004310612650773437014503 0ustar tobiastobias GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. vdr-plugin-live/CONTRIBUTORS0000644000175000017500000000220312650773437015321 0ustar tobiastobiasGrams of suggestions, bugreports, patches and other contributions have been provided by the people on the VDR-Portal and VDR-Portal chatrooms. Special thanks go to the following individuals (if your name is missing here, please send an email to dh+vdr@gekrumbel.de): Michael Brueckner for icons and images and parts of the overall visual design. Rolf Ahrenberg for lots of finish translations and the initial implementation of streaming of live tv via streamdev into a browser window using the vlc plugin for firefox. And a lot of usefull hints about the features of the vlc plugins, some of which still need to be added to LIVE. Patrice Staudt (in memoriam) for the french translations. Matthias Kortstiege for a patch that activates the SSL support in tntnet. LIVE can then be used over https too. This works only with tntnet versions above 1.6.0.6. Recomended is tntnet version 1.6.2 and higher. Diego Pierotto for the italian translations. John Germs, Chavonbravo from CaptiveWorks (http://captiveworks.org) for the addition of channel numbers on the live pages. Martin Wache contributed the MultiSchedule view. vdr-plugin-live/md5.h0000644000175000017500000000655712650773437014317 0ustar tobiastobias///////////////////////////////////////////////////////////////////////// // MD5.cpp // Implementation file for MD5 class // // This C++ Class implementation of the original RSA Data Security, Inc. // MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle. // All rights reserved. This software is a derivative of the "RSA Data // Security, Inc. MD5 Message-Digest Algorithm" // // You may use this software free of any charge, but without any // warranty or implied warranty, provided that you follow the terms // of the original RSA copyright, listed below. // // Original RSA Data Security, Inc. Copyright notice ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All // rights reserved. // // License to copy and use this software is granted provided that it // is identified as the "RSA Data Security, Inc. MD5 Message-Digest // Algorithm" in all material mentioning or referencing this software // or this function. // License is also granted to make and use derivative works provided // that such works are identified as "derived from the RSA Data // Security, Inc. MD5 Message-Digest Algorithm" in all material // mentioning or referencing the derived work. // RSA Data Security, Inc. makes no representations concerning either // the merchantability of this software or the suitability of this // software for any particular purpose. It is provided "as is" // without express or implied warranty of any kind. // These notices must be retained in any copies of any part of this // documentation and/or software. ///////////////////////////////////////////////////////////////////////// typedef unsigned int uint4; typedef unsigned short int uint2; typedef unsigned char uchar; char* PrintMD5(uchar md5Digest[16]); char* MD5String(char* szString); class md5 { // Methods public: md5() { Init(); } void Init(); void Update(uchar* chInput, uint4 nInputLen); void Finalize(); uchar* Digest() { return m_Digest; } private: void Transform(uchar* block); void Encode(uchar* dest, uint4* src, uint4 nLength); void Decode(uint4* dest, uchar* src, uint4 nLength); inline uint4 rotate_left(uint4 x, uint4 n) { return ((x << n) | (x >> (32-n))); } inline uint4 F(uint4 x, uint4 y, uint4 z) { return ((x & y) | (~x & z)); } inline uint4 G(uint4 x, uint4 y, uint4 z) { return ((x & z) | (y & ~z)); } inline uint4 H(uint4 x, uint4 y, uint4 z) { return (x ^ y ^ z); } inline uint4 I(uint4 x, uint4 y, uint4 z) { return (y ^ (x | ~z)); } inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += F(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += G(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += H(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { a += I(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } // Data private: uint4 m_State[4]; uint4 m_Count[2]; uchar m_Buffer[64]; uchar m_Digest[16]; uchar m_Finalized; }; vdr-plugin-live/status.cpp0000644000175000017500000000051712650773437015476 0ustar tobiastobias#include "status.h" #include "timers.h" namespace vdrlive { StatusMonitor::StatusMonitor() { } void StatusMonitor::Recording( cDevice const*, char const*, char const*, bool ) { LiveTimerManager().DoReloadTimers(); } StatusMonitor& LiveStatusMonitor() { static StatusMonitor instance; return instance; } } // namespace vdrlive vdr-plugin-live/live.h0000644000175000017500000000207212650773437014555 0ustar tobiastobias#ifndef VDR_LIVE_LIVE_H #define VDR_LIVE_LIVE_H #include #include #include #include #include "thread.h" namespace vdrlive { class Plugin : public cPlugin { public: Plugin(void); virtual const char *Version(void) { return VERSION; } virtual const char *Description(void) { return tr(DESCRIPTION); } virtual const char *CommandLineHelp(void); virtual bool ProcessArgs(int argc, char *argv[]); virtual bool Start(void); virtual void Stop(void); virtual void MainThreadHook(void); virtual cString Active(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); static std::string const& GetConfigDirectory() { return m_configDirectory; } static std::string const& GetResourceDirectory() { return m_resourceDirectory; } private: static const char *VERSION; static const char *DESCRIPTION; static std::string m_configDirectory; static std::string m_resourceDirectory; std::auto_ptr< ServerThread > m_thread; }; } // namespace vdrlive #endif // VDR_LIVE_LIVE_H vdr-plugin-live/epgsearch.h0000644000175000017500000003434612650773437015570 0ustar tobiastobias#ifndef VDR_LIVE_EPGSEARCH_H #define VDR_LIVE_EPGSEARCH_H #include #include #include #include #include #include #include "tools.h" namespace vdrlive { class SearchTimer; bool operator<( SearchTimer const& left, SearchTimer const& right ); class SearchTimer { public: enum eUseChannel { NoChannel = 0, Interval = 1, Group = 2, FTAOnly = 3 }; SearchTimer(); SearchTimer( std::string const& data ); void Init(); std::string ToText(); friend bool operator<( SearchTimer const& left, SearchTimer const& right ); int Id() const { return m_id; } void SetId(int id) { m_id = id; } std::string const& Search() const { return m_search; } void SetSearch(std::string const& search) { m_search = search; } int SearchMode() { return m_mode; } void SetSearchMode(int mode) { m_mode = mode; } int Tolerance() const { return m_fuzzytolerance; } void SetTolerance(int tolerance) { m_fuzzytolerance = tolerance; } bool MatchCase() const { return m_useCase; } void SetMatchCase(bool useCase) { m_useCase = useCase; } bool UseTime() const { return m_useTime; } void SetUseTime(bool useTime) { m_useTime = useTime; } bool UseTitle() const { return m_useTitle; } void SetUseTitle(bool useTitle) { m_useTitle = useTitle; } bool UseSubtitle() const { return m_useSubtitle; } void SetUseSubtitle(bool useSubtitle) { m_useSubtitle = useSubtitle; } bool UseDescription() const { return m_useDescription; } void SetUseDescription(bool useDescription) { m_useDescription = useDescription; } int StartTime() const { return m_startTime; } std::string StartTimeFormatted(); void SetStartTime(int startTime) { m_startTime = startTime; } int StopTime() const { return m_stopTime; } std::string StopTimeFormatted(); void SetStopTime(int stopTime) { m_stopTime = stopTime; } eUseChannel UseChannel() const { return static_cast< eUseChannel >( m_useChannel ); } void SetUseChannel(eUseChannel useChannel) { m_useChannel = useChannel; } tChannelID ChannelMin() const { return m_channelMin; } void SetChannelMin(tChannelID channelMin) { m_channelMin = channelMin; } tChannelID ChannelMax() const { return m_channelMax; } void SetChannelMax(tChannelID channelMax) { m_channelMax = channelMax; } std::string ChannelText() const { return m_channels; } void SetChannelText(std::string channels) { m_channels = channels; } int UseAsSearchTimer() const { return m_useAsSearchtimer; } void SetUseAsSearchTimer(int useAsSearchtimer) { m_useAsSearchtimer = useAsSearchtimer; } bool UseDuration() const { return m_useDuration; } void SetUseDuration(bool useDuration) { m_useDuration = useDuration; } int MinDuration() const { return m_minDuration; } void SetMinDuration(int minDuration) { m_minDuration = minDuration; } int MaxDuration() const { return m_maxDuration; } void SetMaxDuration(int maxDuration) { m_maxDuration = maxDuration; } bool UseDayOfWeek() const { return m_useDayOfWeek; } void SetUseDayOfWeek(bool useDayOfWeek) { m_useDayOfWeek = useDayOfWeek; } int DayOfWeek() const { return m_dayOfWeek; } void SetDayOfWeek(int dayOfWeek) { m_dayOfWeek = dayOfWeek; } bool UseInFavorites() const { return m_useInFavorites; } void SetUseInFavorites(bool useInFavorites) { m_useInFavorites = useInFavorites; } int SearchTimerAction() const { return m_action; } void SetSearchTimerAction(int action) { m_action = action; } bool UseSeriesRecording() const { return m_useEpisode; } void SetUseSeriesRecording(bool useEpisode) { m_useEpisode = useEpisode; } std::string const& Directory() const { return m_directory; } void SetDirectory(std::string const& directory) { m_directory = directory; } int DelRecsAfterDays() const { return m_delAfterDays; } void SetDelRecsAfterDays(int delAfterDays) { m_delAfterDays = delAfterDays; } int KeepRecs() const { return m_recordingsKeep; } void SetKeepRecs(int recordingsKeep) { m_recordingsKeep = recordingsKeep; } int PauseOnRecs() const {return m_pauseOnNrRecordings; } void SetPauseOnRecs(int pauseOnNrRecordings) { m_pauseOnNrRecordings = pauseOnNrRecordings; } int BlacklistMode() const {return m_blacklistmode; } void SetBlacklistMode(int blacklistmode) { m_blacklistmode = blacklistmode; } bool BlacklistSelected(int id) const; void ParseBlacklist( std::string const& data ); int SwitchMinBefore() const { return m_switchMinBefore; } void SetSwitchMinBefore(int switchMinBefore) { m_switchMinBefore = switchMinBefore; } bool UseExtEPGInfo() const { return m_useExtEPGInfo; } void SetUseExtEPGInfo(bool useExtEPGInfo) { m_useExtEPGInfo = useExtEPGInfo; } std::vector< std::string > ExtEPGInfo() const { return m_ExtEPGInfo; } void SetExtEPGInfo(std::vector< std::string > ExtEPGInfo) { m_ExtEPGInfo = ExtEPGInfo; } bool AvoidRepeats() const { return m_avoidrepeats; } void SetAvoidRepeats(bool avoidrepeats) { m_avoidrepeats = avoidrepeats; } int AllowedRepeats() const { return m_allowedrepeats; } void SetAllowedRepeats(int allowedrepeats) { m_allowedrepeats = allowedrepeats; } int RepeatsWithinDays() const { return m_repeatsWithinDays; } void SetRepeatsWithinDays(int repeatsWithinDays) { m_repeatsWithinDays = repeatsWithinDays; } bool CompareTitle() const { return m_compareTitle; } void SetCompareTitle(bool compareTitle) { m_compareTitle = compareTitle; } int CompareSubtitle() const { return m_compareSubtitle; } void SetCompareSubtitle(int compareSubtitle) { m_compareSubtitle = compareSubtitle; } bool CompareSummary() const { return m_compareSummary; } void SetCompareSummary(bool compareSummary) { m_compareSummary = compareSummary; } unsigned long CompareCategories() const { return m_catvaluesAvoidRepeat; } void SetCompareCategories(unsigned long compareCategories) { m_catvaluesAvoidRepeat = compareCategories; } int Priority() const { return m_priority; } void SetPriority(int priority) { m_priority = priority; } int Lifetime() const { return m_lifetime; } void SetLifetime(int lifetime) { m_lifetime = lifetime; } int MarginStart() const { return m_marginstart; } void SetMarginStart(int marginstart) { m_marginstart = marginstart; } int MarginStop() const { return m_marginstop; } void SetMarginStop(int marginstop) { m_marginstop = marginstop; } bool UseVPS() const { return m_useVPS; } void SetUseVPS(bool useVPS) { m_useVPS = useVPS; } int DelMode() const { return m_delMode; } void SetDelMode(int delMode) { m_delMode = delMode; } int DelAfterCountRecs() const { return m_delAfterCountRecs; } void SetDelAfterCountRecs(int delAfterCountRecs) { m_delAfterCountRecs = delAfterCountRecs; } int DelAfterDaysOfFirstRec() const { return m_delAfterDaysOfFirstRec; } void SetDelAfterDaysOfFirstRec(int delAfterDaysOfFirstRec) { m_delAfterDaysOfFirstRec = delAfterDaysOfFirstRec; } std::string UseAsSearchTimerFrom(std::string const& format); void SetUseAsSearchTimerFrom(std::string const& datestring, std::string const& format); std::string UseAsSearchTimerTil(std::string const& format); void SetUseAsSearchTimerTil(std::string const& datestring, std::string const& format); bool IgnoreMissingEPGCats() const { return m_ignoreMissingEPGCats; } void SetIgnoreMissingEPGCats(bool ignoreMissingEPGCats) { m_ignoreMissingEPGCats = ignoreMissingEPGCats; } private: int m_id; std::string m_search; bool m_useTime; int m_startTime; int m_stopTime; int m_useChannel; tChannelID m_channelMin; tChannelID m_channelMax; std::string m_channels; bool m_useCase; int m_mode; bool m_useTitle; bool m_useSubtitle; bool m_useDescription; bool m_useDuration; int m_minDuration; int m_maxDuration; bool m_useDayOfWeek; int m_dayOfWeek; bool m_useEpisode; int m_priority; int m_lifetime; int m_fuzzytolerance; bool m_useInFavorites; int m_useAsSearchtimer; int m_action; std::string m_directory; int m_delAfterDays; int m_recordingsKeep; int m_pauseOnNrRecordings; int m_switchMinBefore; int m_marginstart; int m_marginstop; bool m_useVPS; bool m_useExtEPGInfo; std::vector< std::string > m_ExtEPGInfo; bool m_avoidrepeats; int m_allowedrepeats; bool m_compareTitle; int m_compareSubtitle; bool m_compareSummary; int m_repeatsWithinDays; int m_blacklistmode; std::vector< std::string > m_blacklistIDs; int m_menuTemplate; unsigned long m_catvaluesAvoidRepeat; int m_delMode; int m_delAfterCountRecs; int m_delAfterDaysOfFirstRec; time_t m_useAsSearchTimerFrom; time_t m_useAsSearchTimerTil; bool m_ignoreMissingEPGCats; void ParseChannel( std::string const& data ); void ParseChannelIDs( std::string const& data ); void ParseExtEPGInfo( std::string const& data ); }; class ExtEPGInfo { public: ExtEPGInfo(std::string const& data ); int Id() const { return m_id; } std::string Name() const { return m_menuname; } std::vector< std::string > Values() const { return m_values; } bool Selected(unsigned int index, std::string const& values); private: int m_id; std::string m_name; std::string m_menuname; std::vector< std::string > m_values; int m_searchmode; void ParseValues( std::string const& data ); }; class ExtEPGInfos { public: typedef std::list< ExtEPGInfo > ExtEPGInfoList; typedef ExtEPGInfoList::size_type size_type; typedef ExtEPGInfoList::iterator iterator; typedef ExtEPGInfoList::const_iterator const_iterator; ExtEPGInfos(); size_type size() const { return m_infos.size(); } iterator begin() { return m_infos.begin(); } const_iterator begin() const { return m_infos.begin(); } iterator end() { return m_infos.end(); } const_iterator end() const { return m_infos.end(); } private: ExtEPGInfoList m_infos; }; class ChannelGroup { public: ChannelGroup(std::string const& data ); std::string Name() { return m_name; } private: std::string m_name; }; class ChannelGroups { public: typedef std::list< ChannelGroup > ChannelGroupList; typedef ChannelGroupList::size_type size_type; typedef ChannelGroupList::iterator iterator; typedef ChannelGroupList::const_iterator const_iterator; ChannelGroups(); size_type size() const { return m_list.size(); } iterator begin() { return m_list.begin(); } const_iterator begin() const { return m_list.begin(); } iterator end() { return m_list.end(); } const_iterator end() const { return m_list.end(); } private: ChannelGroupList m_list; }; class SearchTimers { public: typedef std::list< SearchTimer > TimerList; typedef TimerList::size_type size_type; typedef TimerList::iterator iterator; typedef TimerList::const_iterator const_iterator; SearchTimers(); bool Save(SearchTimer* searchtimer); bool Reload(); size_type size() const { return m_timers.size(); } iterator begin() { return m_timers.begin(); } const_iterator begin() const { return m_timers.begin(); } iterator end() { return m_timers.end(); } const_iterator end() const { return m_timers.end(); } SearchTimer* GetByTimerId( std::string const& id ); bool ToggleActive(std::string const& id); bool Delete(std::string const& id); void TriggerUpdate(); private: TimerList m_timers; }; class Blacklist { public: Blacklist( std::string const& data ); std::string const& Search() const { return m_search; } int Id() const { return m_id; } bool operator<( Blacklist const& other ) const { return Search() < other.Search(); } private: int m_id; std::string m_search; }; class Blacklists { public: typedef std::list< Blacklist > blacklist; typedef blacklist::size_type size_type; typedef blacklist::iterator iterator; typedef blacklist::const_iterator const_iterator; Blacklists(); size_type size() const { return m_list.size(); } iterator begin() { return m_list.begin(); } const_iterator begin() const { return m_list.begin(); } iterator end() { return m_list.end(); } const_iterator end() const { return m_list.end(); } private: blacklist m_list; }; class SearchResult { public: SearchResult( std::string const& data ); int SearchId() const { return m_searchId; } tEventID EventId() const { return m_eventId; } std::string const& Title() const { return m_title; } std::string const& ShortText() const { return m_shorttext; } std::string const& Description() const { return m_description; } time_t StartTime() const { return m_starttime; } time_t StopTime() const { return m_stoptime; } tChannelID Channel() const { return m_channel; } time_t TimerStartTime() const { return m_timerstart; } time_t TimerStopTime() const { return m_timerstop; } int TimerMode() const { return m_timerMode; } bool operator<( SearchResult const& other ) const { return m_starttime < other.m_starttime; } const cEvent* GetEvent(); const cChannel* GetChannel() { return Channels.GetByChannelID(m_channel); } private: int m_searchId; tEventID m_eventId; std::string m_title; std::string m_shorttext; std::string m_description; time_t m_starttime; time_t m_stoptime; tChannelID m_channel; time_t m_timerstart; time_t m_timerstop; std::string m_file; int m_timerMode; }; class SearchResults { static std::set querySet; public: typedef std::list< SearchResult > searchresults; typedef searchresults::size_type size_type; typedef searchresults::iterator iterator; typedef searchresults::const_iterator const_iterator; SearchResults() {} void GetByID(int id); void GetByQuery(std::string const& query); size_type size() const { return m_list.size(); } iterator begin() { return m_list.begin(); } const_iterator begin() const { return m_list.begin(); } iterator end() { return m_list.end(); } const_iterator end() const { return m_list.end(); } void merge(SearchResults& r) {m_list.merge(r.m_list); m_list.sort();} static std::string AddQuery(std::string const& query); static std::string PopQuery(std::string const& md5); private: searchresults m_list; }; class RecordingDirs { public: typedef std::set< std::string > recordingdirs; typedef recordingdirs::size_type size_type; typedef recordingdirs::iterator iterator; typedef recordingdirs::const_iterator const_iterator; RecordingDirs(bool shortList=false); iterator begin() { return m_set.begin(); } const_iterator begin() const { return m_set.begin(); } iterator end() { return m_set.end(); } const_iterator end() const { return m_set.end(); } private: recordingdirs m_set; }; class EPGSearchSetupValues { public: static std::string ReadValue(const std::string& entry); static bool WriteValue(const std::string& entry, const std::string& value); }; class EPGSearchExpr { public: static std::string EvaluateExpr(const std::string& expr, const cEvent* event); }; } // namespace vdrlive #endif // VDR_LIVE_EPGSEARCH_H vdr-plugin-live/README0000644000175000017500000002022712650773437014327 0ustar tobiastobiasThis is a "plugin" for the Video Disk Recorder (VDR). Written by: Thomas Keil Sascha Volkenandt Currently maintained by: Dieter Hametner Christian Wieninger Project's homepage: http://live.vdr-developer.org Latest version available at: http://live.vdr-developer.org See the file COPYING for license information. IMPORTANT: ========== This version of LIVE does not support VDR versions older than 2.0.0 any more (maybe still some older VDR devel versions leading to VDR 2.0.0 but that is not tested). If you can not update your VDR the Version 0.3.x of LIVE is still 'up to date' enough and works with very old VDR versions and with old versions of Tntnet. The LIVE version 0.4.x adds only compatibility changes for newer VDR versions. Description: ============ Live, the "Live Interactive VDR Environment", is a plugin providing the possibility to interactively control the VDR and some of it's plugins by a web interface. Unlike external utility programs that communicate with VDR and it's plugins by SVDRP, Live has direct access to VDR's data structures and is thus very fast. Requirements: ============= VDR >= 2.0.0 gcc >= 3.1 if gcc < 4.0: boost >= 1.32.0 - http://www.boost.org PCRE >= 8.0.2 - http://www.pcre.org/ Tntnet >= 1.5.3 - http://www.tntnet.org/download.hms Cxxtools >= 1.4.3 - http://www.tntnet.org/download.hms Tntnet provides basic webserver functions for live and needs cxxtools. Boost provides some data structures we need. While currently relying on the full blown package we might provide a stripped down version in the future. PCRE provides filtering for recordings. Some older versions pcre-config tool doesn't contain C++ wrapper option, but filtering support can be forced via commandline: make HAVE_LIBPCRECPP="-lpcrecpp -lpcre" If you optionaly want to regenerate the i18n-generated.h header file for backward compatible i18n (VDR version prior to 1.5.7) you also need: (See also the Internationalization section below) Locale::PO - perl module from CPAN www.cpan.org The default i18n-generated.h header contains all translations from GIT. Users that just want to stay on bleeding development edge of live do not need Locale::PO installed. How to get Locale::PO - Use search function on www.cpan.org to obtain module. - Check if your distribution provides the package. (e.g. in Debian the package name is liblocale-po-perl) If you added new translations in your language specific .po file and still want to use an VDR older than version 1.5.7 you must regenerate i18n-generated.h by calling make with the target generate-i18n. Only in this case you need to have Locale::PO installed on your system. Installation: ============= If you compile the plugin outside of the VDR source codes you must copy the resulting binary to VDRs directory where the other plugins are expected. In order to work correctly you must copy the subdirectory 'live' from the source distribution to the directory where the vdr plugins look for their resource files. The pure VDR default for this config directory is: /video/plugins, but this depends also from the parameters -c or -v (see 'vdr --help' for details). cp -a /live /plugins Setup ===== Live provides a username/password protection, so that it can be used from the internet. The default username and password are: admin/live The default port is 8008. You can also specifiy this parameter via commandline: -p PORT, --port=PORT use PORT to listen for incoming connections (default: 8008) -i IP, --ip=IP bind server only to specified IP, may appear multiple times (default: 0.0.0.0, ::0) Additional SSL options are available now. See "How to make LIVE listen for ssl connections" section below on hints how to setup SSL. The rest of the parameters can be adjusted in VDR's OSD or in the web interface. The password is stored as a MD5 hash. "Last Channel" is the last channel in the channels list, that live displays. This is especially useful if you have VDR's automatic channel update active. For example, you can add a group seperator ":@1000 Found automatically" to channels.conf an set this parameter to "1000". Thus, everything VDR finds during scanning (which can after a few months be well more than 3000 channels) won't be displayed. How to make LIVE listen for ssl connections =========================================== To make LIVE listen for incoming ssl connections you`ll have to use a Tntnet version > 1.6.0.6. By default it will listen on port 8443. * Example: https://localhost:8443 In order to start the SslListener LIVE requires a SSL certificate. If no SSL certificate is specified via commandline option, LIVE will try to use the default certificate location '$VDRDIR/plugins/live/live.pem'. If neither the default nor the custom certificate (given by the commandline option) could be found, LIVE will only start the default HTTP Listener (default: 8008) Note: Since the gnutls SslListener was broken in Tntnet versions prior to SVN revision 1035 you will have to recompile Tntnet with "./configure --with-ssl=openssl" to make it work. Alternatively install version 1.6.2 or higher of tntnet on your system. SSL Commandline options ======================= -s PORT, --sslport=PORT use PORT to listen for incoming ssl connections (default: 8443) -c CERT, --cert=CERT path to a custom ssl certificate file (default: $CONFIGDIR/live.pem) -k KEY, --cert=CERT path to a custom ssl certificate key file (default: $CONFIGDIR/live-key.pem) Creating a self-signed SSL server certificate ============================================= To create a self-signed certificate file you`ll have to run this litte command. $> cd /put/your/path/here/vdr/plugins/live $> openssl req -new -x509 -keyout live-key.pem -out live.pem -days 365 -nodes While generating the certifcate you`ll be asked to answer a couple of questions. When it prompts to enter the "Common Name" you`ll have to specify the full qualified dns server name of the machine LIVE is running on (eg. vdr.example.com). If your vdr doesn`t have a full qualified dns name, you should use the ip LIVE is listening on. Note: This is just a quick'n dirty way to create a SSL self-signed certicate. Recent browsers (like Firefox 3) will complain about it because the certificate wasn´t signed by a known Certificate Authority (CA). So how does LIVE work? ====================== Basically, Live itself is a Tntnet webserver integrated into the plugin structure VDR needs. This webserver, running in VDR's environment, is provided with all public data structures VDR provides for plugins and thus has very fast access to information like the EPG, timers or recordings. Live's "pages" are written in "ecpp", a language integrating C++ and HTML in one file, very much like e.g. PHP or ASP weave functionality and "static" content information together. Contribute! =========== If you would like to contribute, please read doc/dev-contribute.txt and doc/TODO.txt. Internationalization (i18n) =========================== LIVE uses the same i18n support like VDR does since version 1.5.7. This version of LIVE can not support i18n compatible with VDR versions older than 1.5.7. All localization files are found in the po subdirectory of the LIVE plugin source. Security consideratios ====================== Live uses the tntnet MapUrl mechanism to map different request urls to tntnet components. One component 'content.ecpp' delivers files found in the file system. When given the wrong 'path' it could retrieve any file from the server where live runs on. Therefore content.ecpp has beem enhanced to check the paths before returning files. A second measure against missuse is to limit the mappings from MapUrl to only valid files. In the current version this approach has been taken. But due to the 'difficulty' to fully understand regular expressions, this might get spoiled again by 'unchecked' code contribution. vdr-plugin-live/tools.h0000644000175000017500000000662212650773437014763 0ustar tobiastobias#ifndef VDR_LIVE_TOOLS_H #define VDR_LIVE_TOOLS_H #include #include #include #include #include #include #include #include #include #include #include #include std::istream& operator>>( std::istream& is, tChannelID& ret ); inline std::ostream& operator<<( std::ostream& os, tChannelID const& id ) { return os << *id.ToString(); } namespace vdrlive { std::string FormatDuration( char const* format, int hours, int minutes ); std::string FormatDateTime( char const* format, time_t time ); std::string StringReplace( std::string const& text, std::string const& substring, std::string const& replacement ); std::vector< std::string > StringSplit( std::string const& text, char delimiter ); int StringToInt( std::string const& string, int base = 10 ); std::string StringRepeat(int times, const std::string& input); std::string StringWordTruncate(const std::string& input, size_t maxLen, bool& truncated); inline std::string StringWordTruncate(const std::string& input, size_t maxLen) { bool dummy; return StringWordTruncate(input, maxLen, dummy); } std::string StringEscapeAndBreak( std::string const& input ); std::string StringFormatBreak(std::string const& input); std::string StringTrim(const std::string& str); std::string ZeroPad(int number); std::string MD5Hash(std::string const& str); time_t GetTimeT(std::string timestring); std::string ExpandTimeString(std::string timestring); std::string StringUrlEncode( std::string const& input ); std::string GetXMLValue( std::string const& xml, std::string const& element ); time_t GetDateFromDatePicker(std::string const& datestring, std::string const& format); std::string DatePickerToC(time_t date, std::string const& format); std::string EncodeDomId(std::string const & toEncode, char const * from = ".-:", char const * to = "pmc"); std::string DecodeDomId(std::string const & toDecode, char const * from = "pmc", char const * to = ".-:"); std::string FileSystemExchangeChars(std::string const & s, bool ToFileSystem); bool MoveDirectory(std::string const & sourceDir, std::string const & targetDir, bool copy = false); struct bad_lexical_cast: std::runtime_error { bad_lexical_cast(): std::runtime_error( "bad lexical cast" ) {} }; template< typename To, typename From > To lexical_cast( From const& from ) { std::stringstream parser; parser << from; To result; parser >> result; if ( !parser ) throw bad_lexical_cast(); return result; } template< typename From > std::string ConvertToString( From const& from, std::locale const& loc = std::locale() ) { std::ostringstream parser; parser.imbue( loc ); parser << from; return parser.str(); } class ReadLock { private: typedef void (ReadLock::*safe_bool)() const; public: ReadLock(cRwLock& lock, int timeout = 100) : m_lock(lock) , m_locked(false) { if (m_lock.Lock( false, timeout )) m_locked = true; } ~ReadLock() { if (m_locked) m_lock.Unlock(); } operator safe_bool() const { return m_locked ? &ReadLock::safe_bool_idiom : 0; } private: ReadLock(ReadLock const&); cRwLock& m_lock; bool m_locked; void safe_bool_idiom() const {} }; } // namespace vdrlive #endif // VDR_LIVE_TOOLS_H vdr-plugin-live/setup.cpp0000644000175000017500000003346412650773437015322 0ustar tobiastobias#include #include #include #include #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #include #endif #include #include #include #include #include "setup.h" #include "tools.h" namespace vdrlive { using namespace std; Setup::Setup(): m_serverPort( 8008 ), m_serverSslPort( 8443 ), m_serverSslCert(), m_serverSslKey(), m_lastChannel( 0 ), m_screenshotInterval( 1000 ), m_useAuth( 1 ), m_adminLogin("admin"), m_channelGroups( "" ), m_scheduleDuration( "8" ), m_theme("marine"), m_lastwhatsonlistmode("detail"), m_lastsortingmode("nameasc"), m_tntnetloglevel("WARN"), m_showLogo(1), m_useAjax(1), m_showInfoBox(1), m_useStreamdev(1), m_streamdevPort(3000), m_streamdevType(), m_showIMDb(1), m_showChannelsWithoutEPG(0) { m_adminPasswordMD5 = "4:" + MD5Hash("live"); liveplugin = cPluginManager::GetPlugin("live"); } bool Setup::ParseCommandLine( int argc, char* argv[] ) { static struct option opts[] = { { "port", required_argument, NULL, 'p' }, { "ip", required_argument, NULL, 'i' }, { "log", required_argument, NULL, 'l' }, { "epgimages", required_argument, NULL, 'e' }, { "sslport", required_argument, NULL, 's' }, { "cert", required_argument, NULL, 'c' }, { "key", required_argument, NULL, 'k' }, { 0 } }; int optchar, optind = 0; while ( ( optchar = getopt_long( argc, argv, "p:i:l:e:s:c:", opts, &optind ) ) != -1 ) { switch ( optchar ) { case 'p': m_serverPort = atoi( optarg ); break; case 'i': m_serverIps.push_back( optarg ); break; case 'l': m_tntnetloglevel = optarg; break; case 'e': m_epgimagedir = optarg; break; case 's': m_serverSslPort = atoi( optarg ); break; case 'c': m_serverSslCert = optarg; break; case 'k': m_serverSslKey = optarg; break; default: return false; } } return CheckServerPort() && CheckServerSslPort() && CheckServerIps(); } char const* Setup::CommandLineHelp() const { if ( m_helpString.empty() ) { ostringstream builder; builder << " -p PORT, --port=PORT use PORT to listen for incoming connections\n" " (default: " << m_serverPort << ")\n" << " -i IP, --ip=IP bind server only to specified IP, may appear\n" " multiple times\n" " (default: 0.0.0.0)\n" << " -s PORT, --sslport=PORT use PORT to listen for incoming ssl connections\n" " (default: " << m_serverSslPort << ")\n" << " -c CERT, --cert=CERT full path to a custom ssl certificate file\n" << " -k KEY, --key=KEY full path to a custom ssl certificate key file\n" << " -l level, --log=level log level for tntnet (values: WARN, ERROR, INFO, DEBUG, TRACE)\n" << " -e , --epgimages= directory for epgimages\n"; m_helpString = builder.str(); } return m_helpString.c_str(); } bool Setup::ParseSetupEntry( char const* name, char const* value ) { if ( strcmp( name, "LastChannel" ) == 0 ) m_lastChannel = atoi( value ); else if ( strcmp( name, "ScreenshotInterval" ) == 0 ) m_screenshotInterval = atoi( value ); else if ( strcmp( name, "UseAuth" ) == 0 ) m_useAuth = atoi( value ); else if ( strcmp( name, "AdminLogin" ) == 0 ) m_adminLogin = value; else if ( strcmp( name, "AdminPasswordMD5" ) == 0 ) m_adminPasswordMD5 = value; else if ( strcmp( name, "UserdefTimes" ) == 0 ) m_times = value; else if ( strcmp( name, "ChannelGroups" ) == 0 ) m_channelGroups = value; else if ( strcmp( name, "ScheduleDuration" ) == 0 ) m_scheduleDuration = value; else if ( strcmp( name, "StartPage" ) == 0 ) m_startscreen = value; else if ( strcmp( name, "Theme" ) == 0 ) m_theme = value; else if ( strcmp( name, "LocalNetMask" ) == 0 ) { m_localnetmask = value; } else if ( strcmp( name, "LastWhatsOnListMode" ) == 0 ) { m_lastwhatsonlistmode = value; } else if ( strcmp( name, "LastSortingMode" ) == 0 ) { m_lastsortingmode = value; } else if ( strcmp( name, "ShowLogo" ) == 0 ) { m_showLogo = atoi(value); } else if ( strcmp( name, "UseAjax" ) == 0 ) { m_useAjax = atoi(value); } else if ( strcmp( name, "ShowInfoBox" ) == 0 ) { m_showInfoBox = atoi(value); } else if ( strcmp( name, "UseStreamdev" ) == 0 ) { m_useStreamdev = atoi(value); } else if ( strcmp( name, "StreamdevPort" ) == 0 ) { m_streamdevPort = atoi(value); } else if ( strcmp( name, "StreamdevType" ) == 0 ) { m_streamdevType = value; } else if ( strcmp( name, "ScreenShotInterval" ) == 0 ) { m_screenshotInterval = atoi(value); } else if ( strcmp( name, "ShowIMDb" ) == 0 ) { m_showIMDb = atoi(value); } else if ( strcmp( name, "ShowChannelsWithoutEPG" ) == 0 ) { m_showChannelsWithoutEPG = atoi(value); } else return false; return true; } bool Setup::CheckServerPort() { if ( m_serverPort <= 0 || m_serverPort > numeric_limits< uint16_t >::max() ) { esyslog( "[live] ERROR: server port %d is not a valid port number", m_serverPort ); cerr << "ERROR: live server port " << m_serverPort << " is not a valid port number" << endl; return false; } return true; } bool Setup::CheckServerSslPort() { if ( m_serverSslPort <= 0 || m_serverSslPort > numeric_limits< uint16_t >::max() ) { esyslog( "[live] ERROR: server ssl port %d is not a valid port number", m_serverSslPort ); cerr << "ERROR: live server ssl port " << m_serverSslPort << " is not a valid port number" << endl; return false; } return true; } namespace { struct IpValidator { bool operator() (string const & ip) { struct in6_addr buf; struct in_addr buf4; esyslog( "[live] INFO: validating server ip '%s'", ip.c_str()); cerr << "INFO: validating live server ip '" << ip << "'" << endl; bool valid = inet_aton(ip.c_str(), &buf4) || inet_pton(AF_INET6, ip.c_str(), &buf); if (!valid) { esyslog( "[live] ERROR: server ip %s is not a valid ip address", ip.c_str()); cerr << "ERROR: live server ip '" << ip << "' is not a valid ip address" << endl; } return valid; } }; } bool Setup::CheckServerIps() { if ( m_serverIps.empty() ) { #if TNT_IPV6_V6ONLY m_serverIps.push_back(""); return true; #else FILE* f = fopen("/proc/sys/net/ipv6/bindv6only", "r"); if (f) { bool bindv6only = false; int c = fgetc(f); if (c != EOF) { bindv6only = ((c - '0') != 0); } fclose(f); f = NULL; esyslog( "[live] INFO: bindv6only=%d", bindv6only); // add a default IPv6 listener address m_serverIps.push_back("::"); // skip the default IPv4 listener address if the IPv6 one will be bound also to v4 if (!bindv6only) return true; } // add a default IPv4 listener address m_serverIps.push_back("0.0.0.0"); // we assume these are ok :) return true; #endif // TNT_IPV6_V6ONLY } IpList::iterator i = partition(m_serverIps.begin(), m_serverIps.end(), IpValidator()); m_serverIps.erase(i, m_serverIps.end()); return !m_serverIps.empty(); } std::string const Setup::GetMD5HashAdminPassword() const { // format is : vector< string > parts = StringSplit( m_adminPasswordMD5, ':' ); return (parts.size() > 1) ? parts[1] : ""; } int Setup::GetAdminPasswordLength() const { // format is : vector< string > parts = StringSplit( m_adminPasswordMD5, ':' ); return (parts.size() > 0) ? lexical_cast< int >( parts[0] ) : 0; } std::string Setup::SetAdminPassword(std::string password) { ostringstream passwordStr; passwordStr << password.size() << ":" << MD5Hash(password); m_adminPasswordMD5 = passwordStr.str(); return m_adminPasswordMD5; } std::string const Setup::GetStartScreenLink() const { if (m_startscreen == "whatsonnext") return "whats_on.html?type=next"; else if (m_startscreen == "schedule") return "schedule.html"; else if (m_startscreen == "multischedule") return "multischedule.html"; else if (m_startscreen == "timers") return "timers.html"; else if (m_startscreen == "recordings") return "recordings.html"; else return "whats_on.html?type=now"; } bool Setup::UseAuth() const { return m_useAuth && !GetIsLocalNet(); } bool Setup::CheckLocalNet(const std::string& ip) { // split local net mask in net and range vector< string > parts = StringSplit( m_localnetmask, '/' ); if (parts.size() != 2) return false; string net = parts[0]; int range = lexical_cast< int >(parts[1]); // split net and ip addr in its 4 subcomponents vector< string > netparts = StringSplit( net, '.' ); vector< string > addrparts = StringSplit( ip, '.' ); if (netparts.size() != 4 || addrparts.size() != 4) return false; // to binary representation ostringstream bin_netstream; bin_netstream << bitset<8>(lexical_cast(netparts[0])) << bitset<8>(lexical_cast(netparts[1])) << bitset<8>(lexical_cast(netparts[2])) << bitset<8>(lexical_cast(netparts[3])); ostringstream bin_addrstream; bin_addrstream << bitset<8>(lexical_cast(addrparts[0])) << bitset<8>(lexical_cast(addrparts[1])) << bitset<8>(lexical_cast(addrparts[2])) << bitset<8>(lexical_cast(addrparts[3])); // compare range string bin_net = bin_netstream.str(); string bin_addr = bin_addrstream.str(); string bin_net_range(bin_net.begin(), bin_net.begin() + range); string addr_net_range(bin_addr.begin(), bin_addr.begin() + range); m_islocalnet = (bin_net_range == addr_net_range); return m_islocalnet; } bool Setup::SaveSetup() { if (!liveplugin) return false; liveplugin->SetupStore("LastChannel", m_lastChannel); liveplugin->SetupStore("UseAuth", m_useAuth); if (m_useAuth) { liveplugin->SetupStore("AdminLogin", m_adminLogin.c_str()); liveplugin->SetupStore("AdminPasswordMD5", m_adminPasswordMD5.c_str()); liveplugin->SetupStore("LocalNetMask", m_localnetmask.c_str()); } liveplugin->SetupStore("UserdefTimes", m_times.c_str()); liveplugin->SetupStore("ChannelGroups", m_channelGroups.c_str()); liveplugin->SetupStore("ScheduleDuration", m_scheduleDuration.c_str()); liveplugin->SetupStore("StartPage", m_startscreen.c_str()); liveplugin->SetupStore("Theme", m_theme.c_str()); liveplugin->SetupStore("LastWhatsOnListMode", m_lastwhatsonlistmode.c_str()); liveplugin->SetupStore("LastSortingMode", m_lastsortingmode.c_str()); liveplugin->SetupStore("ShowLogo", m_showLogo); liveplugin->SetupStore("UseAjax", m_useAjax); liveplugin->SetupStore("ShowInfoBox", m_showInfoBox); liveplugin->SetupStore("UseStreamdev", m_useStreamdev); liveplugin->SetupStore("StreamdevPort", m_streamdevPort); liveplugin->SetupStore("StreamdevType", m_streamdevType.c_str()); liveplugin->SetupStore("ScreenShotInterval", m_screenshotInterval); liveplugin->SetupStore("ShowIMDb", m_showIMDb); liveplugin->SetupStore("ShowChannelsWithoutEPG", m_showChannelsWithoutEPG); return true; } Setup& LiveSetup() { static Setup instance; return instance; } cMenuSetupLive::cMenuSetupLive(): cMenuSetupPage() { m_lastChannel = vdrlive::LiveSetup().GetLastChannel(); m_useAuth = vdrlive::LiveSetup().UseAuth(); strcpy(m_adminLogin, vdrlive::LiveSetup().GetAdminLogin().c_str()); m_oldpasswordMD5 = m_newpasswordMD5 = vdrlive::LiveSetup().GetMD5HashAdminPassword(); string strHidden(vdrlive::LiveSetup().GetAdminPasswordLength(), '*'); strn0cpy(m_tmpPassword, strHidden.c_str(), sizeof(m_tmpPassword)); strcpy(m_adminPassword, ""); Set(); } void cMenuSetupLive::Set(void) { int current = Current(); Clear(); //Add(new cMenuEditIntItem(tr("Last channel to display"), &m_lastChannel, 0, 65536)); Add(new cMenuEditChanItem(tr("Last channel to display"), &m_lastChannel, tr("No limit"))); //Add(new cMenuEditIntItem(tr("Screenshot interval"), &m_lastChannel, 0, 65536)); Add(new cMenuEditBoolItem(tr("Use authentication"), &m_useAuth, tr("No"), tr("Yes"))); Add(new cMenuEditStrItem( tr("Admin login"), m_adminLogin, sizeof(m_adminLogin), tr(FileNameChars))); Add(new cMenuEditStrItem( tr("Admin password"), m_tmpPassword, sizeof(m_tmpPassword), tr(FileNameChars))); SetCurrent(Get(current)); Display(); } void cMenuSetupLive::Store(void) { vdrlive::LiveSetup().SetLastChannel(m_lastChannel); vdrlive::LiveSetup().SetUseAuth(m_useAuth); vdrlive::LiveSetup().SetAdminLogin(m_adminLogin); if (m_oldpasswordMD5 != m_newpasswordMD5) // only save the password if needed vdrlive::LiveSetup().SetAdminPassword(m_adminPassword); LiveSetup().SaveSetup(); } bool cMenuSetupLive::InEditMode(const char* ItemText, const char* ItemName, const char* ItemValue) { bool bEditMode = true; // ugly solution to detect, if in edit mode char* value = strdup(ItemText); strreplace(value, ItemName, ""); strreplace(value, ":\t", ""); // for bigpatch strreplace(value, "\t", ""); if (strlen(value) == strlen(ItemValue)) bEditMode = false; free(value); return bEditMode; } eOSState cMenuSetupLive::ProcessKey(eKeys Key) { const char* ItemText = Get(Current())->Text(); bool bPassWasInEditMode = false; if (ItemText && strlen(ItemText) > 0 && strstr(ItemText, tr("Admin password")) == ItemText) bPassWasInEditMode = InEditMode(ItemText, tr("Admin password"), m_tmpPassword); eOSState state = cMenuSetupPage::ProcessKey(Key); ItemText = Get(Current())->Text(); bool bPassIsInEditMode = false; if (ItemText && strlen(ItemText) > 0 && strstr(ItemText, tr("Admin password")) == ItemText) bPassIsInEditMode = InEditMode(ItemText, tr("Admin password"), m_tmpPassword); if (bPassWasInEditMode && !bPassIsInEditMode) { strcpy(m_adminPassword, m_tmpPassword); m_newpasswordMD5 = MD5Hash(m_tmpPassword); string strHidden(strlen(m_adminPassword), '*'); strcpy(m_tmpPassword, strHidden.c_str()); Set(); Display(); } if (!bPassWasInEditMode && bPassIsInEditMode) { strcpy(m_tmpPassword, ""); Set(); Display(); state = cMenuSetupPage::ProcessKey(Key); } return state; } } // namespace vdrlive vdr-plugin-live/css/0000755000175000017500000000000012650773437014234 5ustar tobiastobiasvdr-plugin-live/css/styles.css0000644000175000017500000005241012650773437016273 0ustar tobiastobias/* ###################### # Globals ###################### */ html, body { color: black; background-color: white; } body { margin: 0px; padding: 0px; font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; } table { font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; } tr, td { padding-top: 0px; padding-bottom: 0px; } form { margin: 0; padding: 0; } input { border: 1px solid #6D96A9; font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; background: #FEFEFE; margin: 0; } select { border: 1px solid #6D96A9; font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; } img { border: 0; } a { text-decoration: none; } a:hover { text-decoration: underline; } a:active { text-decoration: underline; } /* ######################### # global style properties ######################### */ .bold { font-weight: bold; } /* ============================== = Dotted Frame ============================== */ .dotted { border: 1px dotted #bbbbbb; padding: 3px; margin: 2px; float: left; background-color: #f3f3f3; } .title { font-weight: bold; } .short { font-weight: normal; } .more { font-weight: bold; cursor: pointer; } .withmargin { margin: 5px; } .nomargin { margin: 0px; } .notpresent { display: none; } .nowrap { white-space: nowrap; } /* ###################### # Tooltip style for hints ###################### */ .hint-tip { margin: 0px auto; max-width: 480px; /* depends on the tip backround image width */ color: #fff; } .hint-tip .hint-tip-top .hint-tip-c, .hint-tip .hint-tip-bot .hint-tip-c { font-size: 1px; /* ensure minimum height */ height: 17px; } .hint-tip .hint-tip-top { background: transparent url(img/rounded-box-blue-tl.png) no-repeat 0px 0px; margin-right: 17px; /* space for right corner */ } .hint-tip .hint-tip-top .hint-tip-c { background: transparent url(img/rounded-box-blue-tr.png) no-repeat right 0px; margin-right: -17px; /* pull right corner back over "empty" space (from above margin) */ } .hint-tip .hint-tip-bdy { background: transparent url(img/rounded-box-blue-ml.png) repeat-y 0px 0px; margin-right: 17px; } .hint-tip .hint-tip-bdy .hint-tip-c { background: transparent url(img/rounded-box-blue-mr.png) repeat-y right 0px; margin-right: -17px; } .hint-tip .hint-tip-bdy .hint-tip-c .hint-tip-s { /* optional gradient overlay */ /* background: transparent url(img/rounded-box-blue-ms.jpg) repeat-x 0px 0px; */ padding: 0px 17px 0px 17px; } .hint-tip .hint-tip-bot { background: transparent url(img/rounded-box-blue-bl.png) no-repeat 0px 0px; margin-right: 17px; } .hint-tip .hint-tip-bot .hint-tip-c { background: transparent url(img/rounded-box-blue-br.png) no-repeat right 0px; margin-right: -17px; } .hint-title { display: none; } /* ###################### # Style for positive notification popup ###################### */ .ok-info { margin: 0px auto; max-width: 480px; /* depends on the tip backround image width */ color: #fff; } .ok-info .ok-info-top .ok-info-c, .ok-info .ok-info-bot .ok-info-c { font-size: 1px; /* ensure minimum height */ height: 17px; } .ok-info .ok-info-top { background: transparent url(/img/rounded-box-green-tl.png) no-repeat 0px 0px; margin-right: 17px; /* space for right corner */ } .ok-info .ok-info-top .ok-info-c { background: transparent url(/img/rounded-box-green-tr.png) no-repeat right 0px; margin-right: -17px; /* pull right corner back over "empty" space (from above margin) */ } .ok-info .ok-info-body { background: transparent url(/img/rounded-box-green-ml.png) repeat-y 0px 0px; margin-right: 17px; } .ok-info .ok-info-body .ok-info-c { background: transparent url(/img/rounded-box-green-mr.png) repeat-y right 0px; margin-right: -17px; } .ok-info .ok-info-body .ok-info-c .ok-info-s { /* optional gradient overlay */ /* background: transparent url(/img/rounded-box-green-ms.jpg) repeat-x 0px 0px; */ padding: 0px 17px 0px 17px; } .ok-info .ok-info-bot { background: transparent url(/img/rounded-box-green-bl.png) no-repeat 0px 0px; margin-right: 17px; } .ok-info .ok-info-bot .ok-info-c { background: transparent url(/img/rounded-box-green-br.png) no-repeat right 0px; margin-right: -17px; } /* ###################### # Style for negative notification popup ###################### */ .err-info { margin: 0px auto; max-width: 480px; /* depends on the tip backround image width */ color: #fff; } .err-info .err-info-top .err-info-c, .err-info .err-info-bot .err-info-c { font-size: 1px; /* ensure minimum height */ height: 17px; } .err-info .err-info-top { background: transparent url(/img/rounded-box-redwine-tl.png) no-repeat 0px 0px; margin-right: 17px; /* space for right corner */ } .err-info .err-info-top .err-info-c { background: transparent url(/img/rounded-box-redwine-tr.png) no-repeat right 0px; margin-right: -17px; /* pull right corner back over "empty" space (from above margin) */ } .err-info .err-info-body { background: transparent url(/img/rounded-box-redwine-ml.png) repeat-y 0px 0px; margin-right: 17px; } .err-info .err-info-body .err-info-c { background: transparent url(/img/rounded-box-redwine-mr.png) repeat-y right 0px; margin-right: -17px; } .err-info .err-info-body .err-info-c .err-info-s { /* optional gradient overlay */ /* background: transparent url(/img/rounded-box-redwine-ms.jpg) repeat-x 0px 0px; */ padding: 0px 17px 0px 17px; } .err-info .err-info-bot { background: transparent url(/img/rounded-box-redwine-bl.png) no-repeat 0px 0px; margin-right: 17px; } .err-info .err-info-bot .err-info-c { background: transparent url(/img/rounded-box-redwine-br.png) no-repeat right 0px; margin-right: -17px; } /* ###################### # General styles for epg info ###################### */ div.epg_content { border: 1px solid black; } span.epg_images { float: right; margin-left: 5px; } /* ############################## # Infowin styles for epg infos ############################## */ div.info-win { width: 560px; max-width: 2048px; border: none; margin: 0px auto; } .info-win .info-win-top .info-win-c { /*font-size: 1px;*/ /* ensure minimum height */ height: 37px; } .info-win .info-win-bot .info-win-c { font-size: 1px; /* ensure minimum height */ height: 21px; } .info-win .info-win-top { background: transparent url(img/info-win-t-l.png) no-repeat 0px 0px; margin-right: 26px; /* space for right corner */ } .info-win .info-win-top .info-win-c { background: transparent url(img/info-win-t-r.png) no-repeat right 0px; margin-right: -26px; /* pull right corner back over "empty" space (from above margin) */ overflow: hidden; } .info-win .info-win-top .info-win-c .info-win-t { color: #FFF; font-weight: bold; margin-top: 14px; margin-left: 15px; float: left; } .info-win .info-win-top .info-win-c .info-win-b { margin-top: 17px; margin-right: 26px; float: right; } .info-win .info-win-top .info-win-c .info-win-b .close { width: 16px; height: 16px; background: transparent url(img/close.png) no-repeat top right; } .info-win .info-win-top .info-win-c .info-win-b .close:hover { width: 16px; height: 16px; background: transparent url(img/close_red.png) no-repeat top right; } .info-win .info-win-body { background: transparent url(img/info-win-m-l.png) repeat-y 0px 0px; margin-right: 26px; } .info-win .info-win-body .info-win-c { background: transparent url(img/info-win-m-r.png) repeat-y right 0px; margin-right: -26px; } .info-win .info-win-body .info-win-c .info-win-s { padding: 0px 26px 0px 14px; } .info-win .info-win-bot { background: transparent url(img/info-win-b-l.png) no-repeat 0px 0px; margin-right: 26px; } .info-win .info-win-bot .info-win-c { background: transparent url(img/info-win-b-r.png) no-repeat right 0px; margin-right: -26px; } .hint-title { display: none; } /* ####################### # Menue ####################### */ div.menu { background: #000057 url(img/menu_line_bg.png) repeat-x; min-height: 27px; margin: 0; padding: 0 0 0 10px; line-height: 20px; vertical-align: middle; border-top: 1px solid black; border-bottom: 1px solid black; color: #6D96A9; } div.menu a { color: white; font-weight: bold; } a#login { color: #F5FF2D; } div.menu a.active { color: #FFDB88; font-weight: bold; } div.menu form { display: inline; } div.inhalt { overflow: auto; padding: 10px; } /* styles for pagemenu */ div#pagemenu { margin-top: 2px; padding-top: 6px; background: #FFFFFF url(img/bg_line.png) top repeat-x; } div#pagemenu div { padding-bottom: 6px; background: #FFFFFF url(img/bg_line_top.png) bottom repeat-x; } div#pagemenu div div { padding: 2px 0px 2px 10px; background: #E9EFFF; border-top: 1px solid #C0C1DA; border-bottom: 1px solid #C0C1DA; } div#pagemenu div div div { border: 0; padding: 0; margin: 0; } div#pagemenu form { display: inline; } div#pagemenu a { color: black; font-weight: bold; } div#pagemenu a.active { color: blue; font-weight: bold; } div#pagemenu form a { margin-left: 1em; } div#pagemenu form a img { vertical-align: middle; margin-top: -5px; } /* styles for messagebar */ div#messagebar { margin-top: 8px; margin-bottom: 2px; line-height: 20px; min-height: 27px; vertical-align: middle; background: #7CAD3F url(img/msgbar_line_bg.png) top repeat-x; border-top: 1px solid #2B6B00; border-bottom: 1px solid #2B6B00; } div#messagebar div { color: black; } div#messagebar div div { padding-left: 10px; background: transparent; } div#messagebar div div div { border: 0; padding: 0; margin: 0; } div#messagebar a { color: black; font-weight: bold; } div#messagebar a.active { color: blue; font-weight: bold; } div#messagebar span#mbmessage { padding: 0em 1em 0em 1em; color: #A14040; font-weight: bold; } /* ####################### # Info Box (near logo) ####################### */ img.logo { float: left; margin-top: 5px; margin-left: 5px; margin-right: 25px; } div#infobox { float: left; border: 1px solid #C0C1DA; margin: 5px; width: 320px; } div#infobox div.st_header { overflow: hidden; padding: 1px 4px; background: #E9EFFF; border-bottom: 1px solid #C0C1DA; } div#infobox div.st_header div.now { float: right; } div#infobox div.st_header div.caption { float: left; overflow: hidden; font-weight: bold; padding: 0px; } div#infobox div.st_content { overflow: hidden; padding: 4px; background: white url(img/bg_line_top.png) top left repeat-x; } div#infobox div.st_content div.duration { float: right; } div#infobox div.st_content div.name { float: left; overflow: hidden; font-weight: bold; } div#infobox div.st_controls { overflow: hidden; padding: 4px; } div#infobox div.st_controls div.st_pbar { padding-top: 4px; float: right; } div#infobox div.st_controls div { float: left; } div#infobox div.st_controls div.st_update { padding-right: 5px; border-right: 1px solid #C0C1DA; } div#infobox div.st_controls div#infobox_recording_buttons { padding-left: 5px; } div#infobox div.st_controls div#infobox_channel_buttons { padding-left: 5px; } /* ################################# # Buttons ################################# */ button { width: 100px; height: 20px; background-color: inherit; background-image: url(img/button_green.png); background-repeat: no-repeat; color: #FFFFFF; font-size: 11px; border: 0px; vertical-align: middle; text-align: center; cursor: pointer; padding-bottom: 3px; } button.green { background-image: url(img/button_green.png); } button.red { background-image: url(img/button_red.png); } button.blue { background-image: url(img/button_blue.png); } button.yellow { background-image: url(img/button_yellow.png); } /* ################################ # general table cell classes ################################ */ table td.buttonpanel { text-align: right; } table td.toprow { } table th.toprow { } table td.bottomrow { border-bottom: 1px solid black !important; } table td.leftcol { border-left: 1px solid black; } table td.rightcol { border-right: 1px solid black; } table td.topaligned { vertical-align: top; } table td.padded { padding: 3px 7px 3px 3px; } /* ################ # Event (page: whats_on.html) ################ */ div.event { width: 255px; height: 255px; padding: 0; margin-right: 5px; float: left; } div.event div.station { margin: 0; padding: 0; width: 255px; } div.station div { margin: 0; padding: 0; background: url(img/bg_box_l.png) top left no-repeat; height: 23px; } div.station div div { background: url(img/bg_box_r.png) top right no-repeat; } div.station div div div { background: url(img/bg_box_h.png) repeat-x; line-height: 20px; vertical-align: middle; text-align: left; margin-right: 3px; margin-left: 3px; padding-left: 5px; padding-top: 2px; font-weight: bold; } div.station div div div a { color: #ffffff; font-weight: bold; } td div.station { vertical-align: middle; } td div.station a { color: black; font-weight: bold; } div.content { width: 253px; height: 220px; padding: 0; margin: 0; overflow: hidden; background: white url(img/bg_tools.png) top left repeat-y; border-left: 1px solid #000000; border-right: 1px solid #000000; border-bottom: 1px solid #000000; } div.content div.tools { float: left; width: 26px; height: 220px; margin: 0; padding: 0; padding-top: 3px; text-align: center; vertical-align: top; } div.content div.tools img { margin: 2px 5px; } div.content div { padding-left: 0px; margin-left: 35px; } div.content div div { margin-left: 0px; } div.description { margin: 5px 5px 0px 5px; overflow: hidden; } div.title { margin: 5px; } div.short { margin: 5px; } div.info { padding: 5px 5px 5px 0px; overflow: hidden; } div.info div.time { float: right; padding: 0px; } div.info div.date { float: left; padding: 0px; } div.progress { overflow: hidden; padding-right: 4px; margin: 0px; } div.progress div { float: right; padding: 0px; } div.__progress { overflow: hidden; width: 100px; height: 8px; border: 1px solid #C0C1DA; } div.__progress_invisible { overflow: hidden; width: 100px; height: 10px; border: 0px none transparent; } div.__progress div.__elapsed { float: left; height: 8px; background-color: #E9EFFF; } /* ################################## # table listing # (this is used in listing tables) ################################## */ table.listing { padding: 0px; margin: 0px; } table.listing tr td { background: transparent url(img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #C0C1DA; } table.listing tr td.action { padding-left: 3px; padding-right: 5px; } table.listing tr td.leftcol { padding-left: 7px; padding-right: 5px; } table.listing tr td.current { color: blue; } table.listing tr.head td { color: white; font-weight: bold; margin: 0px; padding: 0px; border-bottom: 1px solid black; } table.listing tr.description td { font-weight: bold; background: #E9EFFF; } table.listing tr.spacer td { height: 10px; background: transparent; border-bottom: 0px; } table.listing a { color: black; font-weight: bold; } /* ################################## # table schedule # (this is used for the MultiSchedule) ################################## */ table.mschedule { padding: 0px; margin: 0px; } table.mschedule tr { height: 12px; } table.mschedule tr td.event { background: transparent url(img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #C0C1DA; } table.mschedule tr td.has_timer { background-color: #FFE0E0; } table.mschedule tr td.odd { background-color: #D0D0ff; } table.mschedule tr td.even { background-color: #ffffff; } table.mschedule tr td.current_row { background-color: #ffB0B0; } table.mschedule tr td.leftcol { padding-left: 7px; padding-right: 5px; } table.mschedule div.content1 { min-width: 10em; max-width: 30em; } table.mschedule div.tools1 { float: right; } table.mschedule div.start { float: left; } table.mschedule tr td div.title { padding: 3px; clear: both; } table.mschedule tr td div.short { clear: both; overflow: hidden; } table.mschedule tr td div.description { overflow: hidden; clear: both; } table.mschedule a { color: black; font-weight: bold; } /* ############################## # Blue Background Thingy ############################## */ div.boxheader { margin: 0px; padding: 0px; background: url(img/bg_box_l.png) top left no-repeat; } div.boxheader div { margin: 0px; background: url(img/bg_box_r.png) top right no-repeat; } div.boxheader div div { background: url(img/bg_box_h.png) repeat-x; vertical-align: middle; text-align: left; margin-right: 3px; margin-left: 3px; padding-left: 5px; padding-top: 2px; color: white; font-weight: bold; height: 21px; line-height: 20px; } /* ############################## # Recordings ############################## */ div.recordings { border: 1px solid black; } .recordings ul { list-style-type: none; padding: 0px; margin: 0px; } div.recording_item { overflow: hidden; background: url(img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #C0C1DA; } .recording_item div { float: left; } .recording_item div.recording_imgs{ margin-right: 0.5em; } .recording_item div.recording_spec { padding-top: 0.5ex; } .recording_item div.recording_day { width: 13em; } .recording_item div.recording_date { width: 5.25em; } .recording_item div.recording_time { width: 5.75em; } .recording_item div.recording_duration { width: 4em; } .recording_item div.recording_name { font-weight: bold; cursor: pointer; } .recording_item div.recording_name span { font-weight: normal; cursor: pointer; } .recording_item div.recording_arch { float: right; padding-top: 0.5ex; padding-left: 0.5em; padding-right: 0.5em; } .recording_item div.recording_actions { float: right; padding-right: 3em; } /* ############################## # Remote Control Keypad ############################## */ div.screenshot { background-image: url(img/tv.jpg); background-repeat: no-repeat; height: 320px; width: 569px; float: left; padding: 20px 20px 98px 21px; margin-right: 20px; } div.screenshot img { width: 569px; height: 320px; } /* ############################## # Error widget ############################## */ table.error { border: 1px solid #E9360D; margin: 2px; padding: 0px; } table.error tr td.message { padding: 5px; } table.error tr td.title { background: #E9360D; color: white; font-weight: bold; margin: 0; padding: 3px 3px 3px 10px; } table.error td.border { padding: 0; margin: 0; width: 1px; } /* ############################## # Formular Tables # (are used in forms to group input elements) ############################## */ table.formular { margin-top: 10px; } table.formular tr td { vertical-align: top; vertical-align: middle; background: url(img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #C0C1DA; } table.formular tr td input { margin-top: 5px; margin-bottom: 2px; } table.formular tr td .dotted input { margin-top: 0px; } table.formular tr td.leftcol { padding-left: 2px; } table.formular tr td.rightcol { padding-right: 7px; } table.formular tr td.label { font-weight: bold; vertical-align: top; } table.formular tr.head td { color: white; font-weight: bold; margin: 0; padding: 0; border: none; } table.dependent { background-color: #FFFFFF; margin-top: 0px; } table.dependent tr td { background: transparent; vertical-align: middle; } /* ############################## # Login ############################## */ table.login { margin: 0 auto; } table.login tr td { padding: 3px 5px; text-align: right; } /* ############################## # Styles for EPG-Boxes ############################## */ div.caption { padding: 2px 0px 0px 5px; } div.epg_content { padding: 0px 0px 7px 0px; margin: 0px 0px 0px 0px; background: transparent url(img/bg_tools.png) top left repeat-y; border: 1px solid black; overflow: hidden; } div.epg_content div { margin-left: 35px; } div.epg_content div.epg_tools { float: left; width: 26px; margin: 0; padding: 0; padding-top: 3px; text-align: center; vertical-align: top; } div.epg_content div div { margin-left: 0px; } div.epg_content div.epg_tools img { margin: 2px 5px; } span.epg_images img.epg_image { width: 100%; } /* some adaptions when shown in info-win subwindow */ /* .info-win div.epg_content div div.progress div { margin-left: 0px; } */ .info-win div.boxheader { display: none; } .info-win div.epg_content { border: 0px; } /* ############################## # Style adaptions for About box ############################## */ div.epg_content div.about_left { text-align: right; float: left; width: 175px; } div.epg_content div.about_right { padding-left: 200px; } div.epg_content div.about_line { padding-left: 0px; } div.epg_content div.about_head { font-weight: bold; margin-left: -9px; padding-top: 6px; } div.epg_content div.about_head div { padding-bottom: 6px; margin-left: 0px; } div.epg_content div.about_head div div { padding: 2px 0px 2px 10px; background: #E9EFFF; border-top: 1px solid #C0C1DA; border-bottom: 1px solid #C0C1DA; } /* ############################## # VLC page ############################## */ div#vlcControls { padding-top: 5px; text-align: center; } vdr-plugin-live/css/Makefile0000644000175000017500000000127712650773437015703 0ustar tobiastobias### The official name of this plugin. PLUGIN = live ### Additional options to silence TNTNET warnings TNTFLAGS ?= -Wno-overloaded-virtual -Wno-unused-function ### Includes and Defines (add further entries here): INCLUDES += -I$(VDRDIR)/include -I.. ### The object files (add further files here): OBJS = styles.o ### The main target: all: libcss.a ### Implicit rules: %.o: %.cpp $(CXX) $(CXXFLAGS) $(TNTFLAGS) -c $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $< %.cpp: %.css $(ECPPC) $(ECPPFLAGS) $(ECPPFLAGS_CSS) -b -m "text/css" $< ### Targets: libcss.a: $(OBJS) $(AR) r $@ $^ clean: @rm -f *~ *.o core* libcss.a $(OBJS:%.o=%.cpp) dist: clean @echo "Nothing to do for distribution here ..." vdr-plugin-live/css/siteprefs.css0000644000175000017500000000405412650773437016755 0ustar tobiastobias/* ###################### # This file is part of vdr-live! # It is here to give the users the possibility to change the # default css style of vdr-live to their needs. # # If you don't want to change default settings, make this file # empty, but don't delete it. ###################### */ /* uncomment this below, to make all tables full page width. */ /* table { width: 100%; } */ /* comment this out, if you want epg images at their native size * the popup windows. This here restricts their width to 120 px. * You might also only change size. */ .info-win span.epg_images { width: 120px; } div#vlcControls { text-align: center; } .notify-win { margin: 0px auto; max-width: 480px; /* depends on the tip backround image width */ color: #fff; } .notify-win .notify-win-top .notify-win-c, .notify-win .notify-win-bot .notify-win-c { font-size: 1px; /* ensure minimum height */ height: 17px; } .notify-win .notify-win-top { background: transparent url(/img/rounded-box-green-tl.png) no-repeat 0px 0px; margin-right: 17px; /* space for right corner */ } .notify-win .notify-win-top .notify-win-c { background: transparent url(/img/rounded-box-green-tr.png) no-repeat right 0px; margin-right: -17px; /* pull right corner back over "empty" space (from above margin) */ } .notify-win .notify-win-body { background: transparent url(/img/rounded-box-green-ml.png) repeat-y 0px 0px; margin-right: 17px; } .notify-win .notify-win-body .notify-win-c { background: transparent url(/img/rounded-box-green-mr.png) repeat-y right 0px; margin-right: -17px; } .notify-win .notify-win-body .notify-win-c .notify-win-s { /* optional gradient overlay */ /* background: transparent url(/img/rounded-box-green-ms.jpg) repeat-x 0px 0px; */ padding: 0px 17px 0px 17px; } .notify-win .notify-win-bot { background: transparent url(/img/rounded-box-green-bl.png) no-repeat 0px 0px; margin-right: 17px; } .notify-win .notify-win-bot .notify-win-c { background: transparent url(/img/rounded-box-green-br.png) no-repeat right 0px; margin-right: -17px; } vdr-plugin-live/timers.h0000644000175000017500000000454312650773437015126 0ustar tobiastobias#ifndef VDR_LIVE_TIMERS_H #define VDR_LIVE_TIMERS_H #include #include #include #include #include #include #include "live.h" namespace vdrlive { class SortedTimers: public std::list< cTimer > { friend class TimerManager; public: static std::string GetTimerId(cTimer const& timer); cTimer* GetByTimerId(std::string const& timerid); // en- or decodes a timer into an id usable for DOM Ids. static std::string EncodeDomId(std::string const& timerid); static std::string DecodeDomId(std::string const &timerDomId); bool Modified() { return Timers.Modified(m_state); } static std::string GetTimerDays(cTimer const& timer); static std::string GetTimerInfo(cTimer const& timer); private: SortedTimers(); SortedTimers( SortedTimers const& ); int m_state; void ReloadTimers( bool initial = false ); }; class TimerManager: public cMutex { friend TimerManager& LiveTimerManager(); public: SortedTimers& GetTimers() { return m_timers; } void UpdateTimer( cTimer* timer, int flags, tChannelID& channel, std::string const& weekdays, std::string const& day, int start, int stop, int priority, int lifetime, std::string const& title, std::string const& aux ); void DelTimer( cTimer* timer); void ToggleTimerActive( cTimer* timer); // may only be called from Plugin::MainThreadHook void DoPendingWork(); void DoReloadTimers() { m_timers.ReloadTimers(); } const cTimer* GetTimer(tEventID eventid, tChannelID channelid); private: typedef std::pair< cTimer*, std::string > TimerPair; typedef std::pair< TimerPair, std::string > ErrorPair; typedef std::list< TimerPair > TimerList; typedef std::list< ErrorPair > ErrorList; TimerManager(); TimerManager( TimerManager const& ); SortedTimers m_timers; TimerList m_updateTimers; ErrorList m_failedUpdates; cCondVar m_updateWait; void DoUpdateTimers(); void DoInsertTimer( TimerPair& timerData ); void DoUpdateTimer( TimerPair& timerData ); void DoDeleteTimer( TimerPair& timerData ); void DoToggleTimer( TimerPair& timerData ); void StoreError( TimerPair const& timerData, std::string const& error ); std::string GetError( TimerPair const& timerData ); }; TimerManager& LiveTimerManager(); } // namespace vdrlive #endif // VDR_LIVE_TIMERS_H vdr-plugin-live/epgsearch.cpp0000644000175000017500000005265112650773437016122 0ustar tobiastobias#include #include #include #include #include #include "epgsearch/services.h" #include "epgsearch.h" #include "exception.h" #include "livefeatures.h" #include "tools.h" namespace vdrlive { using namespace std; static char ServiceInterface[] = "Epgsearch-services-v1.0"; bool operator<( SearchTimer const& left, SearchTimer const& right ) { string leftlower = left.m_search; string rightlower = right.m_search; std::transform(leftlower.begin(), leftlower.end(), leftlower.begin(), (int(*)(int)) tolower); std::transform(rightlower.begin(), rightlower.end(), rightlower.begin(), (int(*)(int)) tolower); return leftlower < rightlower; } bool CheckEpgsearchVersion() { /* @winni: Falls Du an der Versionsnummer Anpassungen vornehmen willst, mach das bitte in livefeatures.h ganz unten. Danke */ Features< features::epgsearch >& f = LiveFeatures< features::epgsearch >(); if ( f.Loaded() ) { if ( !f.Recent() ) throw HtmlError( tr("Required minimum version of epgsearch: ") + string( f.MinVersion() )); return true; } return false; } SearchTimer::SearchTimer() { Init(); } void SearchTimer::Init() { m_id = -1; m_useTime = false; m_startTime = 0; m_stopTime = 0; m_useChannel = NoChannel; m_useCase = false; m_mode = 0; m_useTitle = true; m_useSubtitle = true; m_useDescription = true; m_useDuration = false; m_minDuration = 0; m_maxDuration = 0; m_useDayOfWeek = false; m_dayOfWeek = 0; m_useEpisode = false; m_priority = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefPriority")); m_lifetime = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefLifetime")); m_fuzzytolerance = 1; m_useInFavorites = false; m_useAsSearchtimer = 0; m_action = 0; m_delAfterDays = 0; m_recordingsKeep = 0; m_pauseOnNrRecordings = 0; m_switchMinBefore = 1; m_useExtEPGInfo = false; m_useVPS = false; m_marginstart = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefMarginStart")); m_marginstop = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefMarginStop")); m_avoidrepeats = false; m_allowedrepeats = 0; m_compareTitle = false; m_compareSubtitle = 0; m_compareSummary = false; m_repeatsWithinDays = 0; m_blacklistmode = 0; m_menuTemplate = 0; m_delMode = 0; m_delAfterCountRecs = 0; m_delAfterDaysOfFirstRec = 0; m_useAsSearchTimerFrom = 0; m_useAsSearchTimerTil = 0; m_catvaluesAvoidRepeat = 0; m_ignoreMissingEPGCats = false; } SearchTimer::SearchTimer( string const& data ) { Init(); vector< string > parts = StringSplit( data, ':' ); try { vector< string >::const_iterator part = parts.begin(); for ( int i = 0; part != parts.end(); ++i, ++part ) { switch ( i ) { case 0: m_id = lexical_cast< int >( *part ); break; case 1: m_search = StringReplace( StringReplace( *part, "|", ":" ), "!^pipe^!", "|" ); break; case 2: m_useTime = lexical_cast< bool >( *part ); break; case 3: if ( m_useTime ) m_startTime = lexical_cast< int >( *part ); break; case 4: if ( m_useTime ) m_stopTime = lexical_cast< int >( *part ); break; case 5: m_useChannel = lexical_cast< int >( *part ); break; case 6: ParseChannel( *part ); break; case 7: m_useCase = lexical_cast< int >( *part ); break; case 8: m_mode = lexical_cast< int >( *part ); break; case 9: m_useTitle = lexical_cast< bool >( *part ); break; case 10: m_useSubtitle = lexical_cast< bool >( *part ); break; case 11: m_useDescription = lexical_cast< bool >( *part ); break; case 12: m_useDuration = lexical_cast< bool >( *part ); break; case 13: if ( m_useDuration ) m_minDuration = lexical_cast< int >( *part ); break; case 14: if ( m_useDuration ) m_maxDuration = lexical_cast< int >( *part ); break; case 15: m_useAsSearchtimer = lexical_cast< int >( *part ); break; case 16: m_useDayOfWeek = lexical_cast< bool >( *part ); break; case 17: m_dayOfWeek = lexical_cast< int >( *part ); break; case 18: m_useEpisode = lexical_cast< bool >( *part ); break; case 19: m_directory = StringReplace( StringReplace( *part, "|", ":" ), "!^pipe^!", "|" ); break; case 20: m_priority = lexical_cast< int >( *part ); break; case 21: m_lifetime = lexical_cast< int >( *part ); break; case 22: m_marginstart = lexical_cast< int >( *part ); break; case 23: m_marginstop = lexical_cast< int >( *part ); break; case 24: m_useVPS = lexical_cast< bool >( *part ); break; case 25: m_action = lexical_cast< int >( *part ); break; case 26: m_useExtEPGInfo = lexical_cast< bool >( *part ); break; case 27: ParseExtEPGInfo( *part ); break; case 28: m_avoidrepeats = lexical_cast< bool >( *part ); break; case 29: m_allowedrepeats = lexical_cast< int >( *part ); break; case 30: m_compareTitle = lexical_cast< bool >( *part ); break; case 31: m_compareSubtitle = lexical_cast< int >( *part ); break; case 32: m_compareSummary = lexical_cast< bool >( *part ); break; case 33: m_catvaluesAvoidRepeat = lexical_cast< long >( *part ); break; case 34: m_repeatsWithinDays = lexical_cast< int >( *part ); break; case 35: m_delAfterDays = lexical_cast< int >( *part ); break; case 36: m_recordingsKeep = lexical_cast< int >( *part ); break; case 37: m_switchMinBefore = lexical_cast< int >( *part ); break; case 38: m_pauseOnNrRecordings = lexical_cast< int >( *part ); break; case 39: m_blacklistmode = lexical_cast< int >( *part ); break; case 40: ParseBlacklist( *part ); break; case 41: m_fuzzytolerance = lexical_cast< int >( *part ); break; case 42: m_useInFavorites = lexical_cast< bool >( *part ); break; case 43: m_menuTemplate = lexical_cast< int >( *part ); break; case 44: m_delMode = lexical_cast< int >( *part ); break; case 45: m_delAfterCountRecs = lexical_cast< int >( *part ); break; case 46: m_delAfterDaysOfFirstRec = lexical_cast< int >( *part ); break; case 47: m_useAsSearchTimerFrom = lexical_cast< time_t >( *part ); break; case 48: m_useAsSearchTimerTil = lexical_cast< time_t >( *part ); break; case 49: m_ignoreMissingEPGCats = lexical_cast< bool >( *part ); break; } } } catch ( bad_lexical_cast const& ex ) { } } std::string SearchTimer::ToText() { std::string tmp_Start; std::string tmp_Stop; std::string tmp_minDuration; std::string tmp_maxDuration; std::string tmp_chanSel; std::string tmp_search; std::string tmp_directory; std::string tmp_catvalues; std::string tmp_blacklists; tmp_search = StringReplace(StringReplace(m_search, "|", "!^pipe^!"), ":", "|"); tmp_directory = StringReplace(StringReplace(m_directory, "|", "!^pipe^!"), ":", "|"); if (m_useTime) { ostringstream os; os << setw(4) << setfill('0') << m_startTime; tmp_Start = os.str(); os.str(""); os << setw(4) << setfill('0') << m_stopTime; tmp_Stop = os.str(); } if (m_useDuration) { ostringstream os; os << setw(4) << setfill('0') << m_minDuration; tmp_minDuration = os.str(); os.str(""); os << setw(4) << setfill('0') << m_maxDuration; tmp_maxDuration = os.str(); } if (m_useChannel==1) { cChannel const* channelMin = Channels.GetByChannelID( m_channelMin ); cChannel const* channelMax = Channels.GetByChannelID( m_channelMax ); if (channelMax && channelMin->Number() < channelMax->Number()) tmp_chanSel = *m_channelMin.ToString() + std::string("|") + *m_channelMax.ToString(); else tmp_chanSel = *m_channelMin.ToString(); } if (m_useChannel==2) tmp_chanSel = m_channels; if (m_useExtEPGInfo) { for(unsigned int i=0; i0 && m_useChannel<3)?tmp_chanSel:"0") << ":" << (m_useCase?1:0) << ":" << m_mode << ":" << (m_useTitle?1:0) << ":" << (m_useSubtitle?1:0) << ":" << (m_useDescription?1:0) << ":" << (m_useDuration?1:0) << ":" << tmp_minDuration << ":" << tmp_maxDuration << ":" << m_useAsSearchtimer << ":" << (m_useDayOfWeek?1:0) << ":" << m_dayOfWeek << ":" << (m_useEpisode?1:0) << ":" << tmp_directory << ":" << m_priority << ":" << m_lifetime << ":" << m_marginstart << ":" << m_marginstop << ":" << (m_useVPS?1:0) << ":" << m_action << ":" << (m_useExtEPGInfo?1:0) << ":" << tmp_catvalues << ":" << (m_avoidrepeats?1:0) << ":" << m_allowedrepeats << ":" << (m_compareTitle?1:0) << ":" << m_compareSubtitle << ":" << (m_compareSummary?1:0) << ":" << m_catvaluesAvoidRepeat << ":" << m_repeatsWithinDays << ":" << m_delAfterDays << ":" << m_recordingsKeep << ":" << m_switchMinBefore << ":" << m_pauseOnNrRecordings << ":" << m_blacklistmode << ":" << tmp_blacklists << ":" << m_fuzzytolerance << ":" << (m_useInFavorites?1:0) << ":" << m_menuTemplate << ":" << m_delMode << ":" << m_delAfterCountRecs << ":" << m_delAfterDaysOfFirstRec << ":" << (long) m_useAsSearchTimerFrom << ":" << (long) m_useAsSearchTimerTil << ":" << m_ignoreMissingEPGCats; return os.str(); } void SearchTimer::ParseChannel( string const& data ) { switch ( m_useChannel ) { case NoChannel: m_channels = tr("All"); break; case Interval: ParseChannelIDs( data ); break; case Group: m_channels = data; break; case FTAOnly: m_channels = tr("FTA"); break; } } void SearchTimer::ParseChannelIDs( string const& data ) { vector< string > parts = StringSplit( data, '|' ); m_channelMin = lexical_cast< tChannelID >( parts[ 0 ] ); cChannel const* channel = Channels.GetByChannelID( m_channelMin ); if ( channel != 0 ) m_channels = channel->Name(); if ( parts.size() < 2 ) return; m_channelMax = lexical_cast< tChannelID >( parts[ 1 ] ); channel = Channels.GetByChannelID( m_channelMax ); if ( channel != 0 ) m_channels += string( " - " ) + channel->Name(); } void SearchTimer::ParseExtEPGInfo( string const& data ) { m_ExtEPGInfo = StringSplit( data, '|' ); } void SearchTimer::ParseBlacklist( string const& data ) { m_blacklistIDs = StringSplit( data, '|' ); } string SearchTimer::StartTimeFormatted() { time_t start = cTimer::SetTime(time(NULL), (((StartTime() / 100 ) % 100) * 60 * 60) + (StartTime() % 100 * 60)); return FormatDateTime(tr("%I:%M %p"), start); } string SearchTimer::StopTimeFormatted() { time_t stop = cTimer::SetTime(time(NULL), (((StopTime() / 100 ) % 100) * 60 * 60) + (StopTime() % 100 * 60)); return FormatDateTime(tr("%I:%M %p"), stop); } string SearchTimer::UseAsSearchTimerFrom(string const& format) { return DatePickerToC(m_useAsSearchTimerFrom, format); } string SearchTimer::UseAsSearchTimerTil(string const& format) { return DatePickerToC(m_useAsSearchTimerTil, format); } void SearchTimer::SetUseAsSearchTimerFrom(std::string const& datestring, std::string const& format) { m_useAsSearchTimerFrom = GetDateFromDatePicker(datestring, format); } void SearchTimer::SetUseAsSearchTimerTil(std::string const& datestring, std::string const& format) { m_useAsSearchTimerTil = GetDateFromDatePicker(datestring, format); } SearchTimers::SearchTimers() { Reload(); } bool SearchTimers::Reload() { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); ReadLock channelsLock( Channels, 0 ); list< string > timers = service.handler->SearchTimerList(); m_timers.assign( timers.begin(), timers.end() ); m_timers.sort(); return true; } bool SearchTimers::Save(SearchTimer* searchtimer) { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); if (!searchtimer) return false; ReadLock channelsLock( Channels, 0 ); if (searchtimer->Id() >= 0) return service.handler->ModSearchTimer(searchtimer->ToText()); else { searchtimer->SetId(0); int id = service.handler->AddSearchTimer(searchtimer->ToText()); if (id >= 0) searchtimer->SetId(id); return (id >= 0); } } SearchTimer* SearchTimers::GetByTimerId( std::string const& id ) { for (SearchTimers::iterator timer = m_timers.begin(); timer != m_timers.end(); ++timer) if (timer->Id() == lexical_cast< int >(id)) return &*timer; return NULL; } bool SearchTimers::ToggleActive(std::string const& id) { SearchTimer* search = GetByTimerId( id ); if (!search) return false; search->SetUseAsSearchTimer(search->UseAsSearchTimer()==1?0:1); return Save(search); } bool SearchTimers::Delete(std::string const& id) { SearchTimer* search = GetByTimerId( id ); if (!search) return false; Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); if (service.handler->DelSearchTimer(lexical_cast< int >( id ))) return Reload(); return false; } void SearchTimers::TriggerUpdate() { Epgsearch_updatesearchtimers_v1_0 service; service.showMessage = true; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService("Epgsearch-updatesearchtimers-v1.0", &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); } bool SearchTimer::BlacklistSelected(int id) const { for(unsigned int i=0; i parts = StringSplit( data, '|' ); try { vector< string >::const_iterator part = parts.begin(); for ( int i = 0; part != parts.end(); ++i, ++part ) { switch ( i ) { case 0: m_id = lexical_cast< int >( *part ); break; case 1: m_name = *part; break; case 2: m_menuname = *part; break; case 3: ParseValues( *part ); break; case 4: m_searchmode = lexical_cast< int >( *part ); break; } } } catch ( bad_lexical_cast const& ex ) { } } void ExtEPGInfo::ParseValues( string const& data ) { m_values = StringSplit( data, ',' ); } bool ExtEPGInfo::Selected(unsigned int index, std::string const& values) { if (index >= m_values.size()) return false; string extepgvalue = StringTrim(m_values[index]); vector< string > parts; parts = StringSplit( values, ',' ); for(unsigned int i=0; i infos = service.handler->ExtEPGInfoList(); m_infos.assign( infos.begin(), infos.end() ); } ChannelGroup::ChannelGroup( string const& data ) { vector< string > parts = StringSplit( data, '|' ); try { vector< string >::const_iterator part = parts.begin(); for ( int i = 0; part != parts.end(); ++i, ++part ) { switch ( i ) { case 0: m_name = *part; break; } } } catch ( bad_lexical_cast const& ex ) { } } ChannelGroups::ChannelGroups() { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); list< string > list = service.handler->ChanGrpList(); m_list.assign( list.begin(), list.end() ); } Blacklist::Blacklist( string const& data ) { vector< string > parts = StringSplit( data, ':' ); try { vector< string >::const_iterator part = parts.begin(); for ( int i = 0; part != parts.end(); ++i, ++part ) { switch ( i ) { case 0: m_id = lexical_cast< int >( *part ); break; case 1: m_search = StringReplace( StringReplace( *part, "|", ":" ), "!^pipe^!", "|" ); break; } } } catch ( bad_lexical_cast const& ex ) { } } Blacklists::Blacklists() { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); list< string > list = service.handler->BlackList(); m_list.assign( list.begin(), list.end() ); m_list.sort(); } SearchResult::SearchResult( string const& data ) { vector< string > parts = StringSplit( data, ':' ); try { vector< string >::const_iterator part = parts.begin(); for ( int i = 0; part != parts.end(); ++i, ++part ) { switch ( i ) { case 0: m_searchId = lexical_cast< int >( *part ); break; case 1: m_eventId = lexical_cast< u_int32_t >( *part ); break; case 2: m_title = StringReplace( *part, "|", ":" ); break; case 3: m_shorttext = StringReplace( *part, "|", ":" ); break; case 4: m_description = StringReplace( *part, "|", ":" ); break; case 5: m_starttime = lexical_cast< unsigned long >( *part ); break; case 6: m_stoptime = lexical_cast< unsigned long >( *part ); break; case 7: m_channel = lexical_cast< tChannelID >( *part ); break; case 8: m_timerstart = lexical_cast< unsigned long >( *part ); break; case 9: m_timerstop = lexical_cast< unsigned long >( *part ); break; case 10: m_file = *part; break; case 11: m_timerMode = lexical_cast< int >( *part ); break; } } } catch ( bad_lexical_cast const& ex ) { } } const cEvent* SearchResult::GetEvent() { cSchedulesLock schedulesLock; const cSchedules* Schedules = cSchedules::Schedules(schedulesLock); if (!Schedules) return NULL; const cChannel *Channel = GetChannel(); if (!Channel) return NULL; const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (!Schedule) return NULL; return Schedule->GetEvent(m_eventId); } std::set SearchResults::querySet; void SearchResults::GetByID(int id) { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); list< string > list = service.handler->QuerySearchTimer(id); m_list.assign( list.begin(), list.end() ); m_list.sort(); } void SearchResults::GetByQuery(std::string const& query) { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); list< string > list = service.handler->QuerySearch(query); m_list.assign( list.begin(), list.end() ); m_list.sort(); } std::string SearchResults::AddQuery(std::string const& query) { querySet.insert(query); return MD5Hash(query); } std::string SearchResults::PopQuery(std::string const& md5) { std::string query; if (!md5.empty()) { std::set::iterator it; for (it = querySet.begin(); it != querySet.end(); it++) { if (md5 == MD5Hash(*it)) { query = *it; querySet.erase(it); break; } } } return query; } RecordingDirs::RecordingDirs(bool shortList) { if (shortList) { Epgsearch_services_v1_2 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); m_set = service.handler->ShortDirectoryList(); } else { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); m_set = service.handler->DirectoryList(); } } std::string EPGSearchSetupValues::ReadValue(const std::string& entry) { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); return service.handler->ReadSetupValue(entry); } bool EPGSearchSetupValues::WriteValue(const std::string& entry, const std::string& value) { Epgsearch_services_v1_0 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); return service.handler->WriteSetupValue(entry, value); } std::string EPGSearchExpr::EvaluateExpr(const std::string& expr, const cEvent* event) { Epgsearch_services_v1_2 service; if ( !CheckEpgsearchVersion() || cPluginManager::CallFirstService(ServiceInterface, &service) == 0 ) throw HtmlError( tr("EPGSearch version outdated! Please update.") ); return service.handler->Evaluate(expr, event); } } // namespace vdrlive vdr-plugin-live/timers.cpp0000644000175000017500000002225212650773437015456 0ustar tobiastobias#include #include #include #include "exception.h" #include "timers.h" #include "tools.h" #include "i18n.h" static bool operator<( cTimer const& left, cTimer const& right ) { return left.Compare( right ) < 0; } namespace vdrlive { using namespace std; using namespace vdrlive; static char const* const TIMER_DELETE = "DELETE"; static char const* const TIMER_TOGGLE = "TOGGLE"; SortedTimers::SortedTimers(): m_state( 0 ) { ReloadTimers( true ); } string SortedTimers::GetTimerId( cTimer const& timer ) { ostringstream builder; builder << timer.Channel()->GetChannelID() << ":" << timer.WeekDays() << ":" << timer.Day() << ":" << timer.Start() << ":" << timer.Stop(); return builder.str(); } cTimer* SortedTimers::GetByTimerId( string const& timerid ) { vector< string > parts = StringSplit( timerid, ':' ); if ( parts.size() < 5 ) { esyslog("GetByTimerId: invalid format %s", timerid.c_str() ); return 0; } cChannel* channel = Channels.GetByChannelID( tChannelID::FromString( parts[0].c_str() ) ); if ( channel == 0 ) { esyslog("GetByTimerId: no channel %s", parts[0].c_str() ); return 0; } try { int weekdays = lexical_cast< int >( parts[1] ); time_t day = lexical_cast< time_t >( parts[2] ); int start = lexical_cast< int >( parts[3] ); int stop = lexical_cast< int >( parts[4] ); for ( SortedTimers::iterator timer = begin(); timer != end(); ++timer ) { if ( timer->Channel() == channel && ( ( weekdays != 0 && timer->WeekDays() == weekdays ) || ( weekdays == 0 && timer->Day() == day ) ) && timer->Start() == start && timer->Stop() == stop ) return &*timer; } } catch ( bad_lexical_cast const& ex ) { esyslog("GetByTimer: bad cast"); } return 0; } string SortedTimers::EncodeDomId(string const& timerid) { string tId("timer_"); tId += vdrlive::EncodeDomId(timerid, ".-:", "pmc"); return tId; } string SortedTimers::DecodeDomId(string const &timerDomId) { string const timerStr("timer_"); string tId = timerDomId.substr(timerStr.length()); return vdrlive::DecodeDomId(tId, "pmc", ".-:"); } void SortedTimers::ReloadTimers( bool initial ) { // dsyslog("live reloading timers"); clear(); for ( cTimer* timer = Timers.First(); timer; timer = Timers.Next( timer ) ) { push_back( *timer ); } sort(); } string SortedTimers::GetTimerDays(cTimer const& timer) { string currentDay = timer.WeekDays() > 0 ? *cTimer::PrintDay(0, timer.WeekDays(), true) : FormatDateTime(tr("%A, %x"), timer.Day()); return currentDay; } string SortedTimers::GetTimerInfo(cTimer const& timer) { ostringstream info; info << trVDR("Priority") << ": " << timer.Priority() << endl; info << trVDR("Lifetime") << ": " << timer.Lifetime() << endl; info << trVDR("VPS") << ": " << (timer.HasFlags(tfVps)?trVDR("yes"):trVDR("no")) << endl; if (timer.Aux()) { string epgsearchinfo = GetXMLValue(timer.Aux(), "epgsearch"); if (!epgsearchinfo.empty()) { string searchtimer = GetXMLValue(epgsearchinfo, "searchtimer"); if (!searchtimer.empty()) info << tr("Searchtimer") << ": " << searchtimer << endl; } } return info.str(); } TimerManager::TimerManager() { } void TimerManager::UpdateTimer( cTimer* timer, int flags, tChannelID& channel, string const& weekdays, string const& day, int start, int stop, int priority, int lifetime, string const& title, string const& aux ) { cMutexLock lock( this ); ostringstream builder; builder << flags << ":" << channel << ":" << ( weekdays != "-------" ? weekdays : "" ) << ( weekdays == "-------" || day.empty() ? "" : "@" ) << day << ":" << start << ":" << stop << ":" << priority << ":" << lifetime << ":" << StringReplace(title, ":", "|" ) << ":" << StringReplace(aux, ":", "|" ); // Use StringReplace here because if ':' are characters in the // title or aux string it breaks parsing of timer definition // in VDRs cTimer::Parse method. The '|' will be replaced // back to ':' by the cTimer::Parse() method. // Fix was submitted by rofafor: see // http://www.vdr-portal.de/board/thread.php?threadid=100398 // dsyslog("%s", builder.str().c_str()); TimerPair timerData( timer, builder.str() ); // dsyslog("SV: in UpdateTimer"); m_updateTimers.push_back( timerData ); // dsyslog("SV: wait for update"); m_updateWait.Wait( *this ); // dsyslog("SV: update done"); string error = GetError( timerData ); if ( !error.empty() ) throw HtmlError( error ); } void TimerManager::DelTimer( cTimer* timer ) { cMutexLock lock( this ); TimerPair timerData( timer, TIMER_DELETE ); m_updateTimers.push_back( timerData ); m_updateWait.Wait( *this ); string error = GetError( timerData ); if ( !error.empty() ) throw HtmlError( error ); } void TimerManager::ToggleTimerActive( cTimer* timer) { cMutexLock lock( this ); TimerPair timerData( timer, TIMER_TOGGLE ); m_updateTimers.push_back( timerData ); m_updateWait.Wait( *this ); string error = GetError( timerData ); if ( !error.empty() ) throw HtmlError( error ); } void TimerManager::DoPendingWork() { if ( m_updateTimers.size() == 0 && !m_timers.Modified() ) return; cMutexLock lock( this ); if ( m_updateTimers.size() > 0 ) { DoUpdateTimers(); } DoReloadTimers(); // dsyslog("SV: signalling waiters"); m_updateWait.Broadcast(); } void TimerManager::DoUpdateTimers() { // dsyslog("SV: updating timers"); for ( TimerList::iterator timer = m_updateTimers.begin(); timer != m_updateTimers.end(); ++timer ) { if ( timer->first == 0 ) // new timer DoInsertTimer( *timer ); else if ( timer->second == TIMER_DELETE ) // delete timer DoDeleteTimer( *timer ); else if ( timer->second == TIMER_TOGGLE ) // toggle timer DoToggleTimer( *timer ); else // update timer DoUpdateTimer( *timer ); } m_updateTimers.clear(); } void TimerManager::DoInsertTimer( TimerPair& timerData ) { auto_ptr< cTimer > newTimer( new cTimer ); if ( !newTimer->Parse( timerData.second.c_str() ) ) { StoreError( timerData, tr("Error in timer settings") ); return; } cTimer* checkTimer = Timers.GetTimer( newTimer.get() ); if ( checkTimer ) { StoreError( timerData, tr("Timer already defined") ); return; } Timers.Add( newTimer.get() ); Timers.SetModified(); isyslog( "live timer %s added", *newTimer->ToDescr() ); newTimer.release(); } void TimerManager::DoUpdateTimer( TimerPair& timerData ) { if ( Timers.BeingEdited() ) { StoreError( timerData, tr("Timers are being edited - try again later") ); return; } cTimer* oldTimer = Timers.GetTimer( timerData.first ); if ( oldTimer == 0 ) { StoreError( timerData, tr("Timer not defined") ); return; } cTimer copy = *oldTimer; if ( !copy.Parse( timerData.second.c_str() ) ) { StoreError( timerData, tr("Error in timer settings") ); return; } *oldTimer = copy; Timers.SetModified(); isyslog("live timer %s modified (%s)", *oldTimer->ToDescr(), oldTimer->HasFlags(tfActive) ? "active" : "inactive"); } void TimerManager::DoDeleteTimer( TimerPair& timerData ) { if ( Timers.BeingEdited() ) { StoreError( timerData, tr("Timers are being edited - try again later") ); return; } cTimer* oldTimer = Timers.GetTimer( timerData.first ); if ( oldTimer == 0 ) { StoreError( timerData, tr("Timer not defined") ); return; } cTimer copy = *oldTimer; if ( oldTimer->Recording() ) { oldTimer->Skip(); cRecordControls::Process( time( 0 ) ); } Timers.Del( oldTimer ); Timers.SetModified(); isyslog("live timer %s deleted", *copy.ToDescr()); } void TimerManager::DoToggleTimer( TimerPair& timerData ) { if ( Timers.BeingEdited() ) { StoreError( timerData, tr("Timers are being edited - try again later") ); return; } cTimer* toggleTimer = Timers.GetTimer( timerData.first ); if ( toggleTimer == 0 ) { StoreError( timerData, tr("Timer not defined") ); return; } toggleTimer->OnOff(); Timers.SetModified(); isyslog("live timer %s toggled %s", *toggleTimer->ToDescr(), toggleTimer->HasFlags(tfActive) ? "on" : "off"); } void TimerManager::StoreError( TimerPair const& timerData, std::string const& error ) { m_failedUpdates.push_back( ErrorPair( timerData, error ) ); } string TimerManager::GetError( TimerPair const& timerData ) { for ( ErrorList::iterator error = m_failedUpdates.begin(); error != m_failedUpdates.end(); ++error ) { if ( error->first == timerData ) { string message = error->second; m_failedUpdates.erase( error ); return message; } } return ""; } const cTimer* TimerManager::GetTimer(tEventID eventid, tChannelID channelid) { cMutexLock timersLock( &LiveTimerManager() ); SortedTimers& timers = LiveTimerManager().GetTimers(); for ( SortedTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer ) if (timer->Channel() && timer->Channel()->GetChannelID() == channelid) { if (!timer->Event()) timer->SetEventFromSchedule(); if (timer->Event() && timer->Event()->EventID() == eventid) return &*timer; } return NULL; } TimerManager& LiveTimerManager() { static TimerManager instance; return instance; } } // namespace vdrlive vdr-plugin-live/timerconflict.cpp0000644000175000017500000000725012650773437017016 0ustar tobiastobias#include #include #include #include "tools.h" #include "exception.h" #include "epgsearch.h" #include "epgsearch/services.h" #include "timerconflict.h" namespace vdrlive { bool CheckEpgsearchVersion(); using namespace std; static char ServiceInterface[] = "Epgsearch-services-v1.1"; bool operator<( TimerConflict const& left, TimerConflict const& right ) { return left.conflictTime < right.conflictTime; } TimerConflict::TimerConflict() { Init(); } void TimerConflict::Init() { conflictTime = 0; } TimerConflict::TimerConflict( string const& data ) { Init(); vector< string > parts = StringSplit( data, ':' ); try { vector< string >::const_iterator part = parts.begin(); if (parts.size() > 0) { conflictTime = lexical_cast< time_t >( *part++ ); for ( int i = 1; part != parts.end(); ++i, ++part ) { vector< string > timerparts = StringSplit( *part, '|' ); vector< string >::const_iterator timerpart = timerparts.begin(); TimerInConflict timer; for ( int j = 0; timerpart != timerparts.end(); ++j, ++timerpart ) switch (j) { case 0: timer.timerIndex = lexical_cast< int >( *timerpart ); break; case 1: timer.percentage = lexical_cast< int >( *timerpart ); break; case 2: { vector< string > conctimerparts = StringSplit( *timerpart, '#' ); vector< string >::const_iterator conctimerpart = conctimerparts.begin(); for ( int k = 0; conctimerpart != conctimerparts.end(); ++k, ++conctimerpart ) timer.concurrentTimerIndices.push_back(lexical_cast< int >( *conctimerpart )); break; } } conflictingTimers.push_back(timer); } } } catch ( bad_lexical_cast const& ex ) { } } TimerConflicts::TimerConflicts() { Epgsearch_services_v1_1 service; if ( CheckEpgsearchVersion() && cPluginManager::CallFirstService(ServiceInterface, &service)) { cServiceHandler_v1_1* handler = dynamic_cast(service.handler.get()); if (handler) { list< string > conflicts = service.handler->TimerConflictList(); m_conflicts.assign( conflicts.begin(), conflicts.end() ); m_conflicts.sort(); } } } bool TimerConflicts::CheckAdvised() { Epgsearch_services_v1_1 service; if (CheckEpgsearchVersion() && cPluginManager::CallFirstService(ServiceInterface, &service)) { cServiceHandler_v1_1* handler = dynamic_cast(service.handler.get()); if (!handler) return false; else return handler->IsConflictCheckAdvised(); } else return false; } TimerConflictNotifier::TimerConflictNotifier() : lastCheck(0) , lastTimerModification(0) , conflicts() { } TimerConflictNotifier::~TimerConflictNotifier() { } bool TimerConflictNotifier::ShouldNotify() { time_t now = time(0); bool reCheckAdvised((now - lastCheck) > CHECKINTERVAL); bool recentTimerChange((now - lastTimerModification) <= CHECKINTERVAL); if (recentTimerChange || (reCheckAdvised && TimerConflicts::CheckAdvised())) { lastCheck = now; conflicts.reset(new TimerConflicts()); return conflicts->size() > 0; } return false; } void TimerConflictNotifier::SetTimerModification() { lastTimerModification = time(0); } std::string TimerConflictNotifier::Message() const { int count = conflicts ? conflicts->size() : 0; std::string msg = tr("Timer conflict check detected "); msg += ConvertToString(count) + " "; if (count == 1) msg += tr("conflict"); else msg += tr("conflicts"); return count > 0 ? msg + "!" : ""; } std::string TimerConflictNotifier::Url() const { return "timerconflicts.html"; } } // namespace vdrlive vdr-plugin-live/preload.h0000644000175000017500000000026612650773437015247 0ustar tobiastobias#ifndef VDR_LIVE_PRELOAD_H #define VDR_LIVE_PRELOAD_H #include namespace vdrlive { void PreLoadFileCache(std::string const& configDir); }; #endif // VDR_LIVE_PRELOAD_H vdr-plugin-live/tasks.cpp0000644000175000017500000001364412650773437015305 0ustar tobiastobias#include #include #include #include #include #include "stdext.h" #include "exception.h" #include "recman.h" #include "tools.h" #include "tasks.h" namespace vdrlive { using namespace std; using namespace std::tr1; using namespace std::tr1::placeholders; const char* NowReplaying() { return cReplayControl::NowReplaying(); } StickyTask::StickyTask() { LiveTaskManager().AddStickyTask( *this ); } StickyTask::~StickyTask() { LiveTaskManager().RemoveStickyTask( *this ); } void SwitchChannelTask::Action() { ReadLock lock( Channels ); cChannel* channel = Channels.GetByChannelID( m_channel ); if ( channel == 0 ) { SetError( tr("Couldn't find channel or no channels available.") ); return; } if ( !Channels.SwitchTo( channel->Number() ) ) SetError( tr("Couldn't switch to channel.") ); } void PlayRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const* recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError( tr("Couldn't find recording or no recordings available.") ); return; } const char *current = NowReplaying(); if (!current || (0 != strcmp(current, recording->FileName()))) { cReplayControl::SetRecording( 0 ); cControl::Shutdown(); cReplayControl::SetRecording( recording->FileName() ); cControl::Launch( new cReplayControl ); cControl::Attach(); } else { cReplayControl* replayControl = reinterpret_cast(cControl::Control()); if (! replayControl) { SetError(tr("Cannot control playback!")); return; } replayControl->Play(); } } void PauseRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const* recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError( tr("Couldn't find recording or no recordings available.") ); return; } const char *current = NowReplaying(); if (!current) { SetError(tr("Not playing a recording.")); return; } if (0 != strcmp(current, recording->FileName())) { // not replaying same recording like in request SetError(tr("Not playing the same recording as from request.")); return; } cReplayControl* replayControl = reinterpret_cast(cControl::Control()); if (! replayControl) { SetError(tr("Cannot control playback!")); return; } replayControl->Pause(); } void StopRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const* recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError( tr("Couldn't find recording or no recordings available.") ); return; } const char *current = NowReplaying(); if (!current) { SetError(tr("Not playing a recording.")); return; } cReplayControl::SetRecording( 0 ); cControl::Shutdown(); } void ForwardRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const* recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError( tr("Couldn't find recording or no recordings available.") ); return; } const char *current = NowReplaying(); if (!current) { SetError(tr("Not playing a recording.")); return; } if (0 != strcmp(current, recording->FileName())) { // not replaying same recording like in request SetError(tr("Not playing the same recording as from request.")); return; } cReplayControl* replayControl = reinterpret_cast(cControl::Control()); if (! replayControl) { SetError(tr("Cannot control playback!")); return; } replayControl->Forward(); } void BackwardRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const* recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError(tr("Couldn't find recording or no recordings available.")); return; } const char *current = NowReplaying(); if (!current) { SetError(tr("Not playing a recording.")); return; } if (0 != strcmp(current, recording->FileName())) { // not replaying same recording like in request SetError(tr("Not playing the same recording as from request.")); return; } cReplayControl* replayControl = reinterpret_cast(cControl::Control()); if (! replayControl) { SetError(tr("Cannot control playback!")); return; } replayControl->Backward(); } void RemoveRecordingTask::Action() { RecordingsManagerPtr recordings = LiveRecordingsManager(); cRecording const * recording = recordings->GetByMd5Hash( m_recording ); if ( recording == 0 ) { SetError( tr("Couldn't find recording or no recordings available.") ); return; } m_recName = recording->Name(); const char *current = NowReplaying(); if (current && (0 == strcmp(current, recording->FileName()))) { SetError(tr("Attempt to delete recording currently in playback.")); return; } recordings->DeleteRecording(recording); } TaskManager::TaskManager() { } void TaskManager::AddStickyTask( Task& task ) { cMutexLock lock( this ); m_stickyTasks.push_back( &task ); } void TaskManager::RemoveStickyTask( Task& task ) { cMutexLock lock( this ); m_stickyTasks.erase( find( m_stickyTasks.begin(), m_stickyTasks.end(), &task ) ); } bool TaskManager::Execute( Task& task ) { cMutexLock lock( this ); m_taskQueue.push_back( &task ); m_scheduleWait.Wait( *this ); return task.Result(); } void TaskManager::DoScheduledTasks() { if ( m_taskQueue.empty() && m_stickyTasks.empty() ) return; cMutexLock lock( this ); /*while ( !m_taskQueue.empty() ) { Task* current = m_taskQueue.front(); current->Action(); m_taskQueue.pop_front(); }*/ for_each( m_taskQueue.begin(), m_taskQueue.end(), bind( &Task::Action, _1 ) ); for_each( m_stickyTasks.begin(), m_stickyTasks.end(), bind( &Task::Action, _1 ) ); m_taskQueue.clear(); m_scheduleWait.Broadcast(); } TaskManager& LiveTaskManager() { static TaskManager instance; return instance; } } // namespace vdrlive vdr-plugin-live/stdext.h0000644000175000017500000000217012650773437015130 0ustar tobiastobias#ifndef VDR_LIVE_STDEXT_H #define VDR_LIVE_STDEXT_H #if __GNUC__ >= 4 # include # include #else # include # define BOOST_MAJOR_VERSION (BOOST_VERSION / 100000) # define BOOST_MINOR_VERSION ((BOOST_VERSION / 100) % 1000) # if BOOST_MAJOR_VERSION >= 1 && BOOST_MINOR_VERSION >= 34 # include # include # elif BOOST_MAJOR_VERSION >= 1 && BOOST_MINOR_VERSION >= 32 # include # include # include namespace std { namespace tr1 { using boost::bind; using boost::shared_ptr; using boost::weak_ptr; namespace placeholders { using ::_1; using ::_2; using ::_3; using ::_4; using ::_5; using ::_6; using ::_7; using ::_8; using ::_9; } } // namespace std } // namespace tr1 # else # error "Your Compiler is too old and you don't have boost >= 1.32.0 installed." # error "Please either install boost 1.32.0 or higher (1.34.0 is recommended)" # error "or upgrade your compiler suite to at least GCC 4.0" # endif #endif #endif // VDR_LIVE_STDEXT_H vdr-plugin-live/po/0000755000175000017500000000000012650773437014062 5ustar tobiastobiasvdr-plugin-live/po/ca_ES.po0000644000175000017500000003061212650773437015376 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Marc Rovira Vall , 2003 # Ramon Roca , 2003 # Jordi Vilà , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Jordi Vilà \n" "Language-Team: see developers in README\n" "Language: ca_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Gravar" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/es_ES.po0000644000175000017500000004713212650773437015427 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Ruben Nunez Francisco , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Javier Bradineras \n" "Language-Team: see developers in README\n" "Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Último canal para mostrar" msgid "No limit" msgstr "Sin límite" msgid "Use authentication" msgstr "Usar autentificación" msgid "No" msgstr "No" msgid "Yes" msgstr "Si" msgid "Admin login" msgstr "Nombre del administrador" msgid "Admin password" msgstr "Contraseña del administrador" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "Buscador Programaciones" msgid "Error in timer settings" msgstr "Error en la configuración de la programación" msgid "Timer already defined" msgstr "Programación ya definida" msgid "Timers are being edited - try again later" msgstr "Las programaciones están siendo editadas - inténtelo de nuevo más tarde" msgid "Timer not defined" msgstr "Programación no definida" msgid "On archive DVD No." msgstr "En archivo DVD número" msgid "On archive HDD No." msgstr "En archivo HDD número" msgid "Couldn't find channel or no channels available." msgstr "No se puede encontrar el canal o canales no disponibles" msgid "Couldn't switch to channel." msgstr "No se puede cambiar al canal" msgid "Couldn't find recording or no recordings available." msgstr "No se puede encontrar la grabación o grabaciones no disponibles" msgid "Cannot control playback!" msgstr "No se puede controlar la reproducción" msgid "Not playing a recording." msgstr "No se está reproduciendo una grabación" msgid "Not playing the same recording as from request." msgstr "No se está reproduciendo la misma grabación que la solicitada" msgid "Attempt to delete recording currently in playback." msgstr "Intentar borrar la grabación que se está reproduciendo" msgid "Epg error" msgstr "Error en EPG" msgid "Wrong channel id" msgstr "Id de canal erróneo" msgid "Channel has no schedule" msgstr "El canal no tiene programación" msgid "Wrong event id" msgstr "Id de evento erróneo" msgid "Required minimum version of epgsearch: " msgstr "Versión mínima de epgsearch requerida: " msgid "All" msgstr "Todo" msgid "FTA" msgstr "FTA" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "¡Versión de EPGSearch antigua!. Por favor actualice" msgid "Couldn't aquire primary device" msgstr "No se puede capturar el sintonizador principal" msgid "Couldn't grab image from primary device" msgstr "No se puede capturar la imagen con el sintonizador principal" msgid "Timer conflict check detected " msgstr "Detectados conflictos de programaciones" msgid "conflict" msgstr "conflicto" msgid "conflicts" msgstr "conflictos" msgid "Couldn't aquire access to channels, please try again later." msgstr "No se puede tener acceso a los canales, por favor inténtelo más tarde" msgid "Sorry, no permission. Please contact your administrator!" msgstr "Lo siento, no tiene permiso. ¡Por favor contacte con su administrador!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "No se puede encontrar la grabación. ¿Puede haberla escrito erróneamente?" msgid "Please set a name for the recording!" msgstr "¡Por favor, introduzca un nombre para la grabación!" msgid "Cannot copy, rename or move the recording." msgstr "No se puede copiar, renombre o mueva la grabación." msgid "Edit recording" msgstr "Editar grabación" msgid "Name" msgstr "Nombre" msgid "Directory" msgstr "Directorio" msgid "Delete resume information" msgstr "Borrar marcador de continuación" msgid "Delete marks information" msgstr "Borrar información de marcadores" msgid "Copy only" msgstr "Copia únicamente" msgid "Short description" msgstr "Descripción corta" msgid "Description" msgstr "Descripción" msgid "Auxiliary info" msgstr "Información auxiliar" msgid "Save" msgstr "Grabar" msgid "Cancel" msgstr "Cancelar" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "No se puede encontrar la programación. ¿Puede que la haya escrito erróneamente?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd/mm/yyyy" msgid "Edit search timer" msgstr "Editar la programación de búsqueda" msgid "New search timer" msgstr "Nueva programación de búsqueda" msgid "Search text too short - use anyway?" msgstr "Texto a buscar demasiado corto - ¿usar de todos modos?" msgid "Search term" msgstr "Término de búsqueda" msgid "Search mode" msgstr "Modo de búsqueda" msgid "phrase" msgstr "Frase" msgid "all words" msgstr "Todas las palabras" msgid "at least one word" msgstr "Al menos una palabra" msgid "match exactly" msgstr "Coincidencia exacta" msgid "regular expression" msgstr "Expresión Regular" msgid "fuzzy" msgstr "aproximada" msgid "Tolerance" msgstr "Tolerancia" msgid "Match case" msgstr "Coincidir Mayúscula/Minúscula" msgid "Search in" msgstr "Buscar en" msgid "Title" msgstr "Título" msgid "Episode" msgstr "Episodio" msgid "Use extended EPG info" msgstr "Usar información EPG ampliada" msgid "Ignore missing EPG info" msgstr "Ignorar EPG sin información" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Cuando se activa esta opción se pueden producir muchas programaciones. Por lo tanto, haga el favor de testear siempre la programación de búsqueda antes de usarla" msgid "Use channel" msgstr "Usar canal" msgid "interval" msgstr "intervalo" msgid "channel group" msgstr "grupo de canales" msgid "only FTA" msgstr "Únicamente FTA" msgid "from channel" msgstr "del canal" msgid "to channel" msgstr "al canal" msgid "Use time" msgstr "Usar hora" msgid "Start after" msgstr "Inicia después de" msgid "The time the show may start at the earliest" msgstr "La hora del programa puede comenzar antes de" msgid "Start before" msgstr "Iniciar antes de" msgid "The time the show may start at the latest" msgstr "La hora del programa puede comenzar después de" msgid "Use duration" msgstr "Usar duración" msgid "Min. duration" msgstr "Duración mínima" msgid "Max. duration" msgstr "Duración máxima" msgid "Use day of week" msgstr "Usar día de la semana" msgid "Monday" msgstr "Lunes" msgid "Tuesday" msgstr "Martes" msgid "Wednesday" msgstr "Miércoles" msgid "Thursday" msgstr "Jueves" msgid "Friday" msgstr "Viernes" msgid "Saturday" msgstr "Sábado" msgid "Sunday" msgstr "Domingo" msgid "Use blacklists" msgstr "Usar lista negra" msgid "Selection" msgstr "Selección" msgid "all" msgstr "Todo" msgid "Use in favorites menu" msgstr "Usar en menú de favoritos" msgid "Use as search timer" msgstr "Usar como programador de búsqueda" msgid "user defined" msgstr "definido por el usuario" msgid "from date" msgstr "desde la fecha" msgid "to date" msgstr "hasta la fecha" msgid "Record" msgstr "Grabar" msgid "Announce only" msgstr "Únicamente avisar" msgid "Switch only" msgstr "Únicamente cambiar" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Grabación de series" msgid "Delete recordings after ... days" msgstr "Borrar grabaciones después de ... días" msgid "Keep ... recordings" msgstr "Mantener ... grabaciones" msgid "Pause when ... recordings exist" msgstr "Pausar cuando existan ... grabaciones" msgid "Avoid repeats" msgstr "Evitar repeticiones" msgid "Allowed repeats" msgstr "Repeticiones permitidas" msgid "Only repeats within ... days" msgstr "Únicamente repeticiones dentro de ... días" msgid "Compare title" msgstr "Comparar título" msgid "Compare subtitle" msgstr "Comparar subtítulo" msgid "if present" msgstr "si está presente" msgid "Compare summary" msgstr "Comparar resumen" msgid "Compare" msgstr "Comparar" msgid "Use VPS" msgstr "Usar VPS" msgid "Auto-delete search timer" msgstr "Borrado automático de la programación de búsqueda" msgid "after ... recordings" msgstr "tras ... grabaciones" msgid "after ... days after first rec." msgstr "tras ... días después de la primera grabación" msgid "Switch ... minutes before start" msgstr "Cambia ... minutos antes de comenzar" msgid "Test" msgstr "Probar" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "No se puede encontrar la programación. ¿Puede que la haya escrito erróneamente?" msgid "Please set a title for the timer!" msgstr "¡Por favor introduzca un título para la programación!" msgid "Edit timer" msgstr "Editar programación" msgid "New timer" msgstr "Nueva programación" msgid "Weekday" msgstr "Día de la semana" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "No se puede encontrar el usuario. ¿Puede que lo haya escrito erróneamente?" msgid "This user name is already in use!" msgstr "¡Este nombre de usuario ya se está usando!" msgid "Edit user" msgstr "Editar usuario" msgid "New user" msgstr "Nuevo usuario" msgid "Password" msgstr "Contraseña" msgid "User rights" msgstr "Derechos de usuario" msgid "Edit setup" msgstr "Editar configuración" msgid "Add or edit timers" msgstr "Añadir o editar programaciones" msgid "Delete timers" msgstr "Borrar programaciones" msgid "Delete recordings" msgstr "Borrar grabaciones" msgid "Use remote menu" msgstr "Usar menú remoto" msgid "Start replay" msgstr "Iniciar de nuevo la reproducción" msgid "Switch channel" msgstr "Cambiar canal" msgid "Add or edit search timers" msgstr "Añadir o editar programaciones de búsqueda" msgid "Delete search timers" msgstr "Borrar programaciones de búsqueda" msgid "Edit recordings" msgstr "Editar grabaciones" msgid "Electronic program guide information" msgstr "Información de la Guía Electrónica de Programación (EPG)" msgid "Couldn't find recording or no recordings available" msgstr "No se puede encontrar la grabación o no hay programaciones disponibles" msgid "Error aquiring schedules lock" msgstr "Error adquiriendo el bloqueo de las programaciones" msgid "Error aquiring schedules" msgstr "Error adquiriendo programaciones" msgid "%b %d %y" msgstr "%b %d %y" msgid "Page error" msgstr "Error en la página" msgid "playing recording" msgstr "reproduciendo grabación" msgid "no epg info for current event!" msgstr "¡No hay información de epg para este programa!" msgid "no epg info for current channel!" msgstr "¡no hay información de epg para el canal actual!" msgid "no current channel!" msgstr "¡no canal actual!" msgid "error retrieving status info!" msgstr "error recibiendo la información de estado" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Usuario o contraseña erróneos" msgid "Login" msgstr "Entrar" msgid "VDR Live Login" msgstr "Acceso a VDR Live" msgid "User" msgstr "Usuario" msgid "What's on?" msgstr "¿Qué se emite ahora?" msgid "MultiSchedule" msgstr "Multi programación" msgid "Search" msgstr "Buscar" msgid "Searchtimers" msgstr "Programadores de búsqueda" msgid "Recordings" msgstr "Grabaciones" msgid "Remote Control" msgstr "Mando a distancia" msgid "Logout" msgstr "Salir" msgid "Your attention is required" msgstr "Se requiere su atención" msgid "React" msgstr "Resolver" msgid "Dismiss" msgstr "Ignorar" msgid "Now" msgstr "Ahora" msgid "%A, %b %d %Y" msgstr "%A, %b %d %Y" msgid "Time" msgstr "Hora" msgid "Switch to this channel." msgstr "Cambiar a este canal" msgid "Search for repeats." msgstr "Buscar repeticiones" msgid "Click to view details." msgstr "Pulsar para ver detalles" msgid "more" msgstr "más" msgid "Channel" msgstr "Canal" msgid "Find more at the Internet Movie Database." msgstr "Encontrar más en la Base de Datos de Películas de Internet" msgid "Stream this channel into browser." msgstr "Reproduce este canal en el navegador" msgid "Stream this recording into browser." msgstr "Reproduce esta grabación en el navegador" msgid "Record this" msgstr "Grabar esto" msgid "loading data" msgstr "cargando datos" msgid "an error occured!" msgstr "¡ha ocurrido un error!" msgid "Request succeeded!" msgstr "¡Búsqueda completada!" msgid "Request failed!" msgstr "¡La búsqueda ha fallado!" msgid "January" msgstr "Enero" msgid "February" msgstr "Febrero" msgid "March" msgstr "Marzo" msgid "April" msgstr "Abril" msgid "May" msgstr "Mayo" msgid "June" msgstr "Junio" msgid "July" msgstr "Julio" msgid "August" msgstr "Agosto" msgid "September" msgstr "Septiembre" msgid "October" msgstr "Octubre" msgid "November" msgstr "Noviembre" msgid "December" msgstr "Diciembre" msgid "retrieving status ..." msgstr "recibiendo estado ..." msgid "Toggle updates on/off." msgstr "Activar actualizaciones activado/desactivado" msgid "stop playback" msgstr "detener reproducción" msgid "resume playback" msgstr "continuar reproducción" msgid "pause playback" msgstr "pausar reproducción" msgid "fast rewind" msgstr "rebobinado rápido" msgid "fast forward" msgstr "avance rápido" msgid "previous channel" msgstr "canal previo" msgid "next channel" msgstr "canal siguiente" msgid "No server response!" msgstr "¡El servidor no responde!" msgid "Failed to update infobox!" msgstr "¡La actualización de infobox ha fallado!" msgid "Authors" msgstr "Autores" msgid "Project Idea" msgstr "Idea del proyecto" msgid "Webserver" msgstr "Servidor Web" msgid "Project leader" msgstr "Jefe del proyecto" msgid "Content" msgstr "Contenido" msgid "Graphics" msgstr "Gráficos" msgid "Information" msgstr "Información" msgid "LIVE version" msgstr "Versión LIVE" msgid "VDR version" msgstr "Versión VDR" msgid "Features" msgstr "Características" msgid "active" msgstr "activo" msgid "required" msgstr "requerido" msgid "Homepage" msgstr "Página principal" msgid "Bugs and suggestions" msgstr "Sugerencias y bugs" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Si encuentra algún bug o le gustaría sugerir nuevas características, por favor use nuestro bugtracker" msgid "ERROR:" msgstr "ERROR" msgid "Deleted recording:" msgstr "Grabación borrada:" msgid "List of recordings" msgstr "Lista de grabaciones" msgid "No recordings found" msgstr "No se han encontrado grabaciones" msgid "Delete selected" msgstr "Borrar selección" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "Ordenar por nombre" msgid "Sort by date" msgstr "Ordenar por fecha" msgid "Filter" msgstr "Filtrar" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Buscar en grabaciones títulos y subtítulos la cadena indicada y mostrar únicamente las que coincidan. Puede también usar expresiones regulares tipo perl (PCRE)." msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "¡Borrar esta grabación del disco duro!" msgid "play this recording." msgstr "reproducir esta grabación" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "No se puede encontrar el canal o no hay canales disponibles. ¿Puede que lo haya escrito de forma errónea?" msgid "Snapshot interval" msgstr "Intervalo de visionado" msgid "No schedules available for this channel" msgstr "No hay programaciones disponibles para este canal" msgid "Search settings" msgstr "Configuración de búsquedas" msgid "Extended search" msgstr "Búsqueda extendida" msgid "no" msgstr "no" msgid "Search results" msgstr "Resultados de la búsqueda" msgid "No search results" msgstr "Búsqueda sin resultados" msgid "Expression" msgstr "Expresión" msgid "Starts between" msgstr "Iniciar entre" msgid "Toggle search timer actions (in)active" msgstr "Cambiar acciones de la programación de búsqueda (in)activo" msgid "Browse search timer results" msgstr "Navegar por los resultados de la búsqueda" msgid "Delete this search timer?" msgstr "Borrar este programador de búsqueda" msgid "Delete search timer" msgstr "Borrar programador de búsqueda" msgid "Trigger search timer update" msgstr "Actualizar las programaciones" msgid "Please set login and password!" msgstr "Por favor introduzca nombre de usuario y contraseña" msgid "Setup saved." msgstr "Configuración guardada" msgid "Setup" msgstr "Configuración" msgid "User management" msgstr "Administración de usuarios" msgid "Local net (no login required)" msgstr "Red local (sin autentificación requerida)" msgid "Show live logo image" msgstr "Muestra la imagen del logo Live" msgid "Use ajax technology" msgstr "Usar tecnología ajax" msgid "Show dynamic VDR information box" msgstr "Mostrar información dinámica de VDR box" msgid "Allow video streaming" msgstr "Permitir streaming de vídeo" msgid "Streamdev server port" msgstr "Puerto del servidor streamdev" msgid "Streamdev stream type" msgstr "Tipo de stream de streamdev" msgid "Add links to IMDb" msgstr "Añadir enlaces a IMDb" msgid "Additional fixed times in 'What's on?'" msgstr "Horas fijas adicionales en '¿Qué se emite ahora?'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "El formato es HH:MM. Separado múltiples veces con un punto y coma" msgid "Channel groups for MultiSchedule" msgstr "Grupos de canales para multi programación" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Canales separados con una coma ',', grupos separados con un punto y coma ';'" msgid "Duration of MultiSchedule in hours" msgstr "Duración de la multi programación en horas" msgid "Show channels without EPG" msgstr "Mostrar canales sin EPG" msgid "Start page" msgstr "Página de inicio" msgid "Theme" msgstr "Tema" msgid "Timer conflicts" msgstr "Conflictos de programaciones" msgid "No timer conflicts" msgstr "No hay conflictos de programaciones" msgid "Timer has a conflict." msgstr "La programación tiene un conflicto" msgid "Timer is active." msgstr "La programación está activa" msgid "Toggle timer active/inactive" msgstr "Cambiar programación activa/inactiva" msgid "Delete timer" msgstr "Borrar programación" msgid "No timer defined" msgstr "No hay definida programación" msgid "Timer is recording." msgstr "La programación se está grabando." msgid "Users" msgstr "Usuarios" msgid "Delete user" msgstr "Borrar usuario" msgid "VLC: live video stream" msgstr "VLC: reproducción de vídeo en vivo" msgid "VLC: play recording" msgstr "VLC: reproducir grabación" msgid "Stop" msgstr "Detener" msgid "Play" msgstr "Reproducir" msgid "Sound on" msgstr "Sonido activado" msgid "Sound off" msgstr "Sonido desactivado" msgid "Fullscreen" msgstr "Pantalla completa" msgid "Close" msgstr "Cerrar" msgid "VLC media URL" msgstr "medios URL VLC" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "¿Qué se está reproduciendo?" msgid "at" msgstr "a las" msgid "What's on next?" msgstr "¿Qué hay a continuación?" msgid "Favorites" msgstr "Favoritos" msgid "View the schedule of this channel" msgstr "Ver la programación de este canal" msgid " - " msgstr " - " msgid "Next" msgstr "Siguiente" msgid "What's on" msgstr "¿Qué hay ahora?" msgid "Details view" msgstr "Ver detalles" msgid "List view" msgstr "Ver lista" msgid "Live Interactive VDR Environment" msgstr "Entorno interactivo de Live VDR" msgid "No EPG information available" msgstr "No hay información disponible de la EPG" #~ msgid "(%d')" #~ msgstr "(%d')" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Duración del programa en 'Grabaciones'" vdr-plugin-live/po/hr_HR.po0000644000175000017500000003055112650773437015430 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Drazen Dupor , 2004 # Dino Ravnic , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Drazen Dupor \n" "Language-Team: see developers in README\n" "Language: hr_HR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Snimi" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/pl_PL.po0000644000175000017500000004421612650773437015437 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Michael Rakowski , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Michael Rakowski \n" "Language-Team: see developers in README\n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Ostatni kana³ na li¶cie" msgid "No limit" msgstr "Bez limitu" msgid "Use authentication" msgstr "U¿yj autoryzacji" msgid "No" msgstr "Nie" msgid "Yes" msgstr "Tak" msgid "Admin login" msgstr "Login Admina" msgid "Admin password" msgstr "Has³o Admina" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "Timer wyszukiwania" msgid "Error in timer settings" msgstr "B³±d w ustawieniach timera" msgid "Timer already defined" msgstr "Timer zosta³ ju¿ zdefiniowany" msgid "Timers are being edited - try again later" msgstr "Timery s± edytowane - spróbuj ponownie pó¼niej" msgid "Timer not defined" msgstr "Timer nie zdefiniowany" msgid "On archive DVD No." msgstr "W archiwum DVD nr" msgid "On archive HDD No." msgstr "W archiwum HDD nr" msgid "Couldn't find channel or no channels available." msgstr "Nie mo¿na odnale¶æ kana³u lub kana³y nie s± dostêpne." msgid "Couldn't switch to channel." msgstr "Nie mo¿na prze³±czyæ kana³u." msgid "Couldn't find recording or no recordings available." msgstr "Nie mo¿na odnale¼æ nagrania lub nagranie nie jest dostêpne." msgid "Cannot control playback!" msgstr "Nie mo¿na kontrolowaæ odtwarzania!" msgid "Not playing a recording." msgstr "Nie mo¿na odtworzyæ nagrania." msgid "Not playing the same recording as from request." msgstr "Nie mo¿na odtworzyæ ¿±danego nagrania." msgid "Attempt to delete recording currently in playback." msgstr "Próba usuniêcia aktualnie odtwarzanego nagrania." msgid "Epg error" msgstr "B³±d EPG" msgid "Wrong channel id" msgstr "B³êdny id kana³u" msgid "Channel has no schedule" msgstr "Brak programu dla wybranego kana³u" msgid "Wrong event id" msgstr "B³êdny id audycji" msgid "Required minimum version of epgsearch: " msgstr "Wymagana wersja epgsearch (minimum):" msgid "All" msgstr "Wszystkie" msgid "FTA" msgstr "Niekodowane - FTA" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "Plugin EPGSearch jest nieaktualny! Proszê zaktualizowaæ." msgid "Couldn't aquire primary device" msgstr "Nie mozna uzyskaæ dostêpu do pierwszego interfejsu DVB" msgid "Couldn't grab image from primary device" msgstr "Nie mo¿na pobraæ obrazu z pierwszego interfejsu DVB" msgid "Timer conflict check detected " msgstr "Wykryto kolizje timerów " msgid "conflict" msgstr "kolizjê" msgid "conflicts" msgstr "kolizje" msgid "Couldn't aquire access to channels, please try again later." msgstr "Nie mo¿na uzyskaæ dostêpu do kana³ów, spróbój pó¼niej." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Brak uprawenieñ. Skontaktuj siê ze swoim administratorem!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Nie mo¿na odnale¼æ nagrania." msgid "Please set a name for the recording!" msgstr "Proszê podaæ nazwê nagrania!" msgid "Cannot copy, rename or move the recording." msgstr "Nie mo¿na skopiowaæ, przenie¶æ ani zmieniæ nazwy nagrania." msgid "Edit recording" msgstr "Edycja nagrania" msgid "Name" msgstr "Nazwa" msgid "Directory" msgstr "Katalog" msgid "Delete resume information" msgstr "Usuñ informacjê o wznowieniu" msgid "Delete marks information" msgstr "Usuñ informacjê o znacznikach" msgid "Copy only" msgstr "Skopiuj do katalogu" msgid "Short description" msgstr "Krótki opis" msgid "Description" msgstr "Opis" msgid "Auxiliary info" msgstr "Dodatkowe informacje" msgid "Save" msgstr "Zapisz" msgid "Cancel" msgstr "Anuluj" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Nie mo¿na odnale¼æ timera wyszukiwania." #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd/mm/yyyy" msgid "Edit search timer" msgstr "Edycja timera wyszukiwania" msgid "New search timer" msgstr "Nowy timer wyszukiwania" msgid "Search text too short - use anyway?" msgstr "Wyszukiwany tekst jest za krótki - czy napewno kontynuowaæ?" msgid "Search term" msgstr "Szukany tekst" msgid "Search mode" msgstr "Tryb wyszukiwania" msgid "phrase" msgstr "wyra¿enie" msgid "all words" msgstr "wszystkie s³owa" msgid "at least one word" msgstr "dowolne s³owo" msgid "match exactly" msgstr "dok³adnie ca³e wyra¿enie" msgid "regular expression" msgstr "wyra¿enie regularne" msgid "fuzzy" msgstr "niedoprecyzowane" msgid "Tolerance" msgstr "Tolerancja" msgid "Match case" msgstr "Uwzglêdnij wielko¶æ liter" msgid "Search in" msgstr "Szukaj w" msgid "Title" msgstr "Tytu³" msgid "Episode" msgstr "Epizod" msgid "Use extended EPG info" msgstr "U¿yj rozszerzonej informacji EPG" msgid "Ignore missing EPG info" msgstr "Ignoruj brakuj±ce informacje EPG" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Aktywacja timera wyszukiwania mo¿e spowodowaæ dodanie wielu niepotrzebnych timerów, wiêc przed zapisem najpiew przetestuj dzia³anie wyszukiwania!" msgid "Use channel" msgstr "Kana³" msgid "interval" msgstr "zakres" msgid "channel group" msgstr "grupa kana³ów" msgid "only FTA" msgstr "tylko niekodowane" msgid "from channel" msgstr "od kana³u" msgid "to channel" msgstr "do kana³u" msgid "Use time" msgstr "Czas" msgid "Start after" msgstr "Rozpoczêcie po" msgid "The time the show may start at the earliest" msgstr "Wyszukiwana audycja mo¿e rozpocz±æ siê najwcze¶niej o ..." msgid "Start before" msgstr "Rozpoczêcie przed" msgid "The time the show may start at the latest" msgstr "Wyszukiwana audycja mo¿e rozpocz±æ siê najpó¼niej o ..." msgid "Use duration" msgstr "Czas trwania" msgid "Min. duration" msgstr "Min. czas trwania" msgid "Max. duration" msgstr "Max. czas trwania" msgid "Use day of week" msgstr "Dzieñ" msgid "Monday" msgstr "Poniedzia³ek" msgid "Tuesday" msgstr "Wtorek" msgid "Wednesday" msgstr "¦roda" msgid "Thursday" msgstr "Czwartek" msgid "Friday" msgstr "Pi±tek" msgid "Saturday" msgstr "Sobota" msgid "Sunday" msgstr "Niedziela" msgid "Use blacklists" msgstr "Czarna lista" msgid "Selection" msgstr "wybrane" msgid "all" msgstr "wszystkie" msgid "Use in favorites menu" msgstr "U¿yj ulubionych" msgid "Use as search timer" msgstr "Aktywuj timer" msgid "user defined" msgstr "w wybranym okersie" msgid "from date" msgstr "od dnia" msgid "to date" msgstr "do dnia" msgid "Record" msgstr "Nagraj" msgid "Announce only" msgstr "Tylko powiadomienie" msgid "Switch only" msgstr "Tylko prze³±cz" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Nagrywanie serii" msgid "Delete recordings after ... days" msgstr "Usuñ nagranie po ... dniach:" msgid "Keep ... recordings" msgstr "Zatrzymaj ... nagrañ:" msgid "Pause when ... recordings exist" msgstr "Zatrzymaj gdy istnieje ... nagrañ" msgid "Avoid repeats" msgstr "Opcje powtórek" msgid "Allowed repeats" msgstr "Liczba powtórek" msgid "Only repeats within ... days" msgstr "Nagrywaj powtórki przez ... dni" msgid "Compare title" msgstr "Porównaj tytu³y" msgid "Compare subtitle" msgstr "Porównaj podtytu³y" msgid "if present" msgstr "je¿eli isteniej±" msgid "Compare summary" msgstr "Podsumowanie porównania" msgid "Compare" msgstr "Porównaj" msgid "Use VPS" msgstr "U¿yj VPS" msgid "Auto-delete search timer" msgstr "Automatycznie usuñ timer" msgid "after ... recordings" msgstr "po ... nagraniach" msgid "after ... days after first rec." msgstr "po ... dniach nagrywania" msgid "Switch ... minutes before start" msgstr "Prze³±cz na ... minut przed rozpoczêcziem" msgid "Test" msgstr "Testuj" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Nie mo¿na odnale¼æ timera." msgid "Please set a title for the timer!" msgstr "Proszê podaæ tytu³ dla timera!" msgid "Edit timer" msgstr "Edycja timera" msgid "New timer" msgstr "Nowy timer" msgid "Weekday" msgstr "Dzieñ" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Nie mo¿na odnale¼æ u¿ytkownika." msgid "This user name is already in use!" msgstr "Nazwa u¿ytkownika jest ju¿ u¿ywana!" msgid "Edit user" msgstr "Edycja u¿ytkownia" msgid "New user" msgstr "Nowy u¿ytkownik" msgid "Password" msgstr "Has³o" msgid "User rights" msgstr "Uprawnienia" msgid "Edit setup" msgstr "Edycja ustawieñ" msgid "Add or edit timers" msgstr "Dodawanie i edycja timerów" msgid "Delete timers" msgstr "Usuwanie timerów" msgid "Delete recordings" msgstr "Usuwanie niagrañ" msgid "Use remote menu" msgstr "U¿ywanie pilota" msgid "Start replay" msgstr "Startowane odtwarzania" msgid "Switch channel" msgstr "Prze³±czanie kana³ów" msgid "Add or edit search timers" msgstr "Dodawanie i edycja timerów wyszukiwania" msgid "Delete search timers" msgstr "Usuwanie timerów wyszukiwania" msgid "Edit recordings" msgstr "Edycja nagrañ" msgid "Electronic program guide information" msgstr "Informacje EPG" msgid "Couldn't find recording or no recordings available" msgstr "Nie mo¿na odnale¼æ nagrania" msgid "Error aquiring schedules lock" msgstr "B³±d podczas próby blokady programu" msgid "Error aquiring schedules" msgstr "B³±d podczas ¶ci±gania programu" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "B³±d strony" msgid "playing recording" msgstr "Odtwarzanie nagrania" msgid "no epg info for current event!" msgstr "brak informacji o audycji!" msgid "no epg info for current channel!" msgstr "brak informacji epg dla kana³u!" msgid "no current channel!" msgstr "brak informacji o kanale!" msgid "error retrieving status info!" msgstr "b³±d podczas odczytu stanu" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "B³êdna nazwa lub has³o u¿ytkownika" msgid "Login" msgstr "Nazwa" msgid "VDR Live Login" msgstr "Login VDR Live" msgid "User" msgstr "U¿ytkownik" msgid "What's on?" msgstr "Teraz w TV" msgid "MultiSchedule" msgstr "Multiprzewodnik" msgid "Search" msgstr "Szukaj" msgid "Searchtimers" msgstr "Timery wyszukiwania" msgid "Recordings" msgstr "Nagrania" msgid "Remote Control" msgstr "Pilot" msgid "Logout" msgstr "Wyloguj" msgid "Your attention is required" msgstr "Uwaga, co¶ nie gra " msgid "React" msgstr "Sprawd¼" msgid "Dismiss" msgstr "Anuluj" msgid "Now" msgstr "Teraz" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "Czas" msgid "Switch to this channel." msgstr "Prze³±cz na ten kana³" msgid "Search for repeats." msgstr "Szukaj powtórek" msgid "Click to view details." msgstr "Kliknij aby zobaczyæ szczegó³y" msgid "more" msgstr "wiêcej" msgid "Channel" msgstr "Kana³" msgid "Find more at the Internet Movie Database." msgstr "Szukaj w IMDb.com" msgid "Stream this channel into browser." msgstr "Ogl±daj kana³ w przegl±darce" msgid "Stream this recording into browser." msgstr "Ogl±daj nagranie w przegl±darce" msgid "Record this" msgstr "Nagraj" msgid "loading data" msgstr "³adujê ..." msgid "an error occured!" msgstr "wyst±pi³ b³±d!" msgid "Request succeeded!" msgstr "Zakoñczono powodzeniem!" msgid "Request failed!" msgstr "Zakoñczono niepowodzeniem!" msgid "January" msgstr "Styczeñ" msgid "February" msgstr "Luty" msgid "March" msgstr "Marzec" msgid "April" msgstr "Kwiecieñ" msgid "May" msgstr "Maj" msgid "June" msgstr "Czerwiec" msgid "July" msgstr "Lipiec" msgid "August" msgstr "Sierpieñ" msgid "September" msgstr "Wrzesieñ" msgid "October" msgstr "Pa¼dziernik" msgid "November" msgstr "Listopad" msgid "December" msgstr "Grudzieñ" msgid "retrieving status ..." msgstr "odczytywanie stanu ..." msgid "Toggle updates on/off." msgstr "W³±cz/wy³±cz aktualizacjê stanu." msgid "stop playback" msgstr "zatrzymaj odtwarzanie" msgid "resume playback" msgstr "wznów odtwarzanie" msgid "pause playback" msgstr "pauzuj odtwarzanie" msgid "fast rewind" msgstr "przewiñ do ty³u" msgid "fast forward" msgstr "przewiñ do przodu" msgid "previous channel" msgstr "poprzeni kana³" msgid "next channel" msgstr "nastêpny kana³" msgid "No server response!" msgstr "Serwer nie odpowiada!" msgid "Failed to update infobox!" msgstr "B³±d poczas aktualizacji panela!" msgid "Authors" msgstr "Autorzy" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "Informacje" msgid "LIVE version" msgstr "Wersja LIVE" msgid "VDR version" msgstr "Wersja VDR" msgid "Features" msgstr "Dodatki" msgid "active" msgstr "aktywny" msgid "required" msgstr "wymagany" msgid "Homepage" msgstr "Strona domowa" msgid "Bugs and suggestions" msgstr "B³êdy i sugestie" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Je¶li znajdziesz jakie¶ b³êdy lub chcia³by¶ zasugerowaæ nowe funkcje, skorzystaj z naszego bugtrackera" msgid "ERROR:" msgstr "B£¡D:" msgid "Deleted recording:" msgstr "Usuniêto nagranie:" msgid "List of recordings" msgstr "Lista nagrañ" msgid "No recordings found" msgstr "Nie znaleziono nagrañ" msgid "Delete selected" msgstr "Usuñ zaznaczone" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "Sortuj wed³ug nazwy" msgid "Sort by date" msgstr "Sortuj wed³ug daty" msgid "Filter" msgstr "Filtr" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Poka¿ nagrania zgodne z wpisanym wyra¿eniem (mo¿na u¿ywaæ tak¿e wyra¿eñ regularnych typu PERL)." msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "Usuñ to nagranie z twardego dysku!" msgid "play this recording." msgstr "Odtwórz nagranie" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Nie mo¿na odnale¶æ kana³u lub kana³y nie s± dostêpne." msgid "Snapshot interval" msgstr "Okres pomiêdzy migawkami" msgid "No schedules available for this channel" msgstr "Brak listy audycji dla tego kana³u" msgid "Search settings" msgstr "Ustawienia wyszukiwania" msgid "Extended search" msgstr "Wyszukiwanie zaawansowane" msgid "no" msgstr "nie" msgid "Search results" msgstr "Wyniki wyszykiwania" msgid "No search results" msgstr "Nic nie znaleziono" msgid "Expression" msgstr "Wyra¿enie" msgid "Starts between" msgstr "Pocz±tek miêdzy" msgid "Toggle search timer actions (in)active" msgstr "Aktywuj/deaktywuj timer wyszukiwania" msgid "Browse search timer results" msgstr "Przegl±daj wyniki timera wyszukiwania" msgid "Delete this search timer?" msgstr "Usun±æ ten timer wyszukiwania?" msgid "Delete search timer" msgstr "Usuñ timer wyszukiwania" msgid "Trigger search timer update" msgstr "Zaprogramuj aktywne timery wyszukiwania" msgid "Please set login and password!" msgstr "Proszê wpisaæ login i has³o!" msgid "Setup saved." msgstr "Zapisano ustawienia." msgid "Setup" msgstr "Ustawienia" msgid "User management" msgstr "Zarz±dzanie u¿ytkownikami" msgid "Local net (no login required)" msgstr "Sieæ lokalna (logowanie nie wymagane)" msgid "Show live logo image" msgstr "Pokazuj logo VDR-Live" msgid "Use ajax technology" msgstr "U¿ywaj technologii ajax" msgid "Show dynamic VDR information box" msgstr "Pokazuj panel informacyjny" msgid "Allow video streaming" msgstr "Zezwól na streamowanie strumienia video" msgid "Streamdev server port" msgstr "Port serwera Streamdev" msgid "Streamdev stream type" msgstr "Typ strumienia Streamdev" msgid "Add links to IMDb" msgstr "Pokazuj odno¶niki do IMDb" msgid "Additional fixed times in 'What's on?'" msgstr "Lista wyboru godzin w zak³adce 'Teraz w TV'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Wpisz czasy, które maj± byæ wy¶wietlane na li¶cie wyboru w formacie GG:MM. Oddzielaj poszczególne wpisy ¶rednikiem." msgid "Channel groups for MultiSchedule" msgstr "Grypy kana³ów w 'Multipzewodniku'" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Kana³y oddzielaj przecinkiem, grypu kana³ów oddzielaj ¶rednikiem (np. 1,2,7,3,11;4,5,6;21,22,23,40" msgid "Duration of MultiSchedule in hours" msgstr "Czas jaki ma obejmowaæ Multiprzewodnik (w godzinach) " msgid "Show channels without EPG" msgstr "Pokazuj kana³y bez EPG" msgid "Start page" msgstr "Strona startowa" msgid "Theme" msgstr "Skórka" msgid "Timer conflicts" msgstr "Kolizje timerów" msgid "No timer conflicts" msgstr "Brak kolizji timerów" msgid "Timer has a conflict." msgstr "Timer jest w kolizji." msgid "Timer is active." msgstr "Timer jest aktywny." msgid "Toggle timer active/inactive" msgstr "Aktywuj/deaktywuj timer." msgid "Delete timer" msgstr "Usuñ timer" msgid "No timer defined" msgstr "Brak zdefiniowanych timerów." msgid "Timer is recording." msgstr "Trwa nagranie timera." msgid "Users" msgstr "U¿ytkownicy" msgid "Delete user" msgstr "Usuñ u¿ytkownika" msgid "VLC: live video stream" msgstr "VLC: streamuj video" msgid "VLC: play recording" msgstr "VLC: odtwarzaj nagranie" msgid "Stop" msgstr "Stop" msgid "Play" msgstr "Play" msgid "Sound on" msgstr "W³±cz g³os" msgid "Sound off" msgstr "Wycisz g³os" msgid "Fullscreen" msgstr "Pe³ny ekran" msgid "Close" msgstr "Zamknij" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "Teraz w TV:" msgid "at" msgstr "o godz." msgid "What's on next?" msgstr "Nastepnie" msgid "Favorites" msgstr "Ulubione" msgid "View the schedule of this channel" msgstr "Wy¶wietl program dla tego kana³u" msgid " - " msgstr "" msgid "Next" msgstr "Nastêpnie" msgid "What's on" msgstr "Audycje" msgid "Details view" msgstr "Widek szczegó³owy" msgid "List view" msgstr "Widok listy" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "Brak informacji EPG" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Pokazuj czas trwania nagrañ" vdr-plugin-live/po/el_GR.po0000644000175000017500000003051012650773437015411 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Dimitrios Dimitrakos , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Dimitrios Dimitrakos \n" "Language-Team: see developers in README\n" "Language: el_GR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-7\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "ÅããñáöÞ" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/sk_SK.po0000644000175000017500000004537012650773437015445 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Vladimír Bárta , 2006 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" "PO-Revision-Date: 2012-12-03 21:41+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: Slovak \n" "Language: sk_SK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Posledný zobrazený kanál na obrazovke" msgid "No limit" msgstr "Bez obmedzenia" msgid "Use authentication" msgstr "Pou¾i» overenie toto¾nosti" msgid "No" msgstr "Nie" msgid "Yes" msgstr "Áno" msgid "Admin login" msgstr "Prihlasovacie meno admina" msgid "Admin password" msgstr "Heslo admina" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "Vyhµadávaè vysielacieho èasu" msgid "Error in timer settings" msgstr "Chyba v nastavení plánu" msgid "Timer already defined" msgstr "Plán nahrávania nie je stanovený." msgid "Timers are being edited - try again later" msgstr "Plány sa upravujú - skúste to znova neskôr" msgid "Timer not defined" msgstr "Plán nahrávania nie je stanovený." msgid "On archive DVD No." msgstr "Na archívne DVD." msgid "On archive HDD No." msgstr "Na archívne HDD." msgid "Couldn't find channel or no channels available." msgstr "Nena¹iel ¾iadny kanál alebo kanály nie sú k dispozícii." msgid "Couldn't switch to channel." msgstr "Nedá sa prepnú» na kanál." msgid "Couldn't find recording or no recordings available." msgstr "Nena¹li sa ¾iadne záznamy alebo nahrávky nie sú k dispozícii." msgid "Cannot control playback!" msgstr "Nemo¾no ovláda» prehrávanie!" msgid "Not playing a recording." msgstr "Záznam sa neprehráva." msgid "Not playing the same recording as from request." msgstr "Ak sa vy¾iada rovnaká nahrávka, tak ju neprehraje." msgid "Attempt to delete recording currently in playback." msgstr "Pokus o vymazanie nahrávky, ktorá je v súèasnosti v prehrávaní." msgid "Epg error" msgstr "Epg chyba" msgid "Wrong channel id" msgstr "©patný id kanálu" msgid "Channel has no schedule" msgstr "Kanál nemá sprievodcu televíznym programom" msgid "Wrong event id" msgstr "Nesprávne ID udalosti" msgid "Required minimum version of epgsearch: " msgstr "Povinná minimálna verzia epgsearch:" msgid "All" msgstr "V¹etky" msgid "FTA" msgstr "Voµné" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "Zastaralá verzia EPGSearch! Prosím aktualizujte ju." msgid "Couldn't aquire primary device" msgstr "Nepodarilo sa získa» hlavné zariadenie" msgid "Couldn't grab image from primary device" msgstr "Nemo¾no stiahnu» obraz z hlavného zariadenia" msgid "Timer conflict check detected " msgstr "Konflikt plánu nahrávania " msgid "conflict" msgstr "konflikt " msgid "conflicts" msgstr "konflikty " msgid "Couldn't aquire access to channels, please try again later." msgstr "Nedá sa získa» prístup ku kanálom, prosím skúste to znova neskôr." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Prepáète, nemáte oprávnenie. Prosím kontaktujte va¹eho administrátora!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Nena¹la sa nahrávka. Mo¾no ste zle napísali va¹u po¾iadavku?" msgid "Please set a name for the recording!" msgstr "Prosím zvolte meno pre nahrávku!" msgid "Cannot copy, rename or move the recording." msgstr "Nemo¾no kopírova», premenova» alebo presunú» nahrávku." msgid "Edit recording" msgstr "Upravi» nahrávku" msgid "Name" msgstr "Meno" msgid "Directory" msgstr "Adresár" msgid "Delete resume information" msgstr "Znovu zmaza» informácie" msgid "Delete marks information" msgstr "Vymaza» informaèné znaèky" msgid "Copy only" msgstr "Iba kopírova»" msgid "Short description" msgstr "Struèný opis" msgid "Description" msgstr "v popise" msgid "Auxiliary info" msgstr "Pomocné info" msgid "Save" msgstr "Ulo¾i»" msgid "Cancel" msgstr "Zru¹i»" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Nena¹iel sa vyhµadávaný èas. Mo¾no ste zle napísali va¹u po¾iadavku?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "mm/dd/yyyy" msgid "Edit search timer" msgstr "Úprava vyhµadávaèa vysielacieho èasu" msgid "New search timer" msgstr "Nový vyhµadávaè vysielacieho èasu" msgid "Search text too short - use anyway?" msgstr "Hµadaný text je príli¹ krátky - pou¾i» aj tak?" msgid "Search term" msgstr "Hµadaný pojem" msgid "Search mode" msgstr "Spôsob hµadania" msgid "phrase" msgstr "výraz" msgid "all words" msgstr "v¹etky slová" msgid "at least one word" msgstr "aspoò jedno slovo" msgid "match exactly" msgstr "porovna» presne" msgid "regular expression" msgstr "regulárny výraz" msgid "fuzzy" msgstr "nejasný" msgid "Tolerance" msgstr "tolerancia" msgid "Match case" msgstr "Prípadne porovna»" msgid "Search in" msgstr "Hµada» v" msgid "Title" msgstr "V názve" msgid "Episode" msgstr "v epizóde" msgid "Use extended EPG info" msgstr "Pou¾i» roz¹írené EPG informácie" msgid "Ignore missing EPG info" msgstr "Ignorova» chýbajúce EPG informácie" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Aktívny mô¾e spôsobi» veµmi veµa plánov nahrávania. Tak¾e, prosím, v¾dy najprv testujte vyhµadávanie pred pou¾itím!" msgid "Use channel" msgstr "Urèi» kanál" msgid "interval" msgstr "rozmedzie" msgid "channel group" msgstr "skupina kanálov" msgid "only FTA" msgstr "iba volne ¹íriteµné" msgid "from channel" msgstr "od kanálu" msgid "to channel" msgstr "po kanál" msgid "Use time" msgstr "Urèi» èas" msgid "Start after" msgstr "©tart po" msgid "The time the show may start at the earliest" msgstr "Èas, keï show mô¾e zaèa» èo najskôr" msgid "Start before" msgstr "©tart pred" msgid "The time the show may start at the latest" msgstr "V èase, keï show mô¾e zaèa» najneskôr" msgid "Use duration" msgstr "Urèi» då¾ku" msgid "Min. duration" msgstr "Minimálna då¾ka" msgid "Max. duration" msgstr "Maximálna då¾ka" msgid "Use day of week" msgstr "Urèi» deò v tý¾dni" msgid "Monday" msgstr "Pondelok" msgid "Tuesday" msgstr "Utorok" msgid "Wednesday" msgstr "Streda" msgid "Thursday" msgstr "©tvrtok" msgid "Friday" msgstr "Piatok" msgid "Saturday" msgstr "Sobota" msgid "Sunday" msgstr "Nedeµa" msgid "Use blacklists" msgstr "Pou¾i» èiernu listinu" msgid "Selection" msgstr "Vybrané" msgid "all" msgstr "v¹etky" msgid "Use in favorites menu" msgstr "Pou¾ite v menu obµúbených" msgid "Use as search timer" msgstr "Pou¾i» ako vyhµadávaè plánu" msgid "user defined" msgstr "pou¾ívateµom definované" msgid "from date" msgstr "od dátumu" msgid "to date" msgstr "do dátumu" msgid "Record" msgstr "Nahra»" msgid "Announce only" msgstr "Len oznamova»" msgid "Switch only" msgstr "Iba prepína»" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Sériové nahrávky" msgid "Delete recordings after ... days" msgstr "Odstránenie nahrávok po ... dòoch" msgid "Keep ... recordings" msgstr "Uchova» ... nahrávok" msgid "Pause when ... recordings exist" msgstr "Pauza, keï ... nahrávky existujú" msgid "Avoid repeats" msgstr "Vyhnú» sa reprízam" msgid "Allowed repeats" msgstr "Povolené reprízy" msgid "Only repeats within ... days" msgstr "Opakova» iba do ... dní" msgid "Compare title" msgstr "Porovna» titul" msgid "Compare subtitle" msgstr "Porovna» titulky" msgid "if present" msgstr "ak je prítomný" msgid "Compare summary" msgstr "Porovna» celkovo" msgid "Compare" msgstr "Porovnanie" msgid "Use VPS" msgstr "Pou¾i» VPS" msgid "Auto-delete search timer" msgstr "Samo zmazanie vyhµadaného plánu" msgid "after ... recordings" msgstr "po ... nahrávkach" msgid "after ... days after first rec." msgstr "po ... dòoch po prvom nahratí." msgid "Switch ... minutes before start" msgstr "Prepnú» ... minút pred zaèiatkom" msgid "Test" msgstr "Testova»" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Nena¹iel sa plán nahrávania. Je mo¾né, ¾e ste zle napísali va¹u po¾iadavku." msgid "Please set a title for the timer!" msgstr "Prosím nastavte titul pre plán nahrávania!" msgid "Edit timer" msgstr "Upravi» plán" msgid "New timer" msgstr "Nový plán" msgid "Weekday" msgstr "Pracovný deò" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Nepodarilo sa nájs» u¾ívateµa. Mo¾no ste preklepli va¹u po¾iadavku?" msgid "This user name is already in use!" msgstr "To to u¾ívateµské meno sa u¾ pou¾íva" msgid "Edit user" msgstr "Upravi» U¾ívateµa" msgid "New user" msgstr "Nový u¾ívateµ" msgid "Password" msgstr "Heslo" msgid "User rights" msgstr "U¾ívateµské práva" msgid "Edit setup" msgstr "Upravi» nastavenie" msgid "Add or edit timers" msgstr "Prida» a upravi» plány" msgid "Delete timers" msgstr "Vymaza» plány" msgid "Delete recordings" msgstr "Vymaza» nahrávky" msgid "Use remote menu" msgstr "Pou¾i vzdialené menu" msgid "Start replay" msgstr "Spusti» prehrávanie" msgid "Switch channel" msgstr "Prepnú» kanál" msgid "Add or edit search timers" msgstr "Prida» alebo upravi» vyhµadávanie plánov" msgid "Delete search timers" msgstr "Vymaza» vyhµadávaè plánov" msgid "Edit recordings" msgstr "Upravi» nahrávky" msgid "Electronic program guide information" msgstr "Elektronický sprievodca televíznym programom" msgid "Couldn't find recording or no recordings available" msgstr "Nena¹iel sa záznam alebo nahrávky nie sú k dispozícii" msgid "Error aquiring schedules lock" msgstr "Uzamknuté získavanie televízneho programu" msgid "Error aquiring schedules" msgstr "Chyba pri získavaní televízneho programu" msgid "%b %d %y" msgstr "%b %d %y" msgid "Page error" msgstr "Chyba stránky" msgid "playing recording" msgstr "Prehrávanie záznamu" msgid "no epg info for current event!" msgstr "¾iadne EPG informácie na aktuálnu udalos»!" msgid "no epg info for current channel!" msgstr "®iadne epg pre vybraný kanál!" msgid "no current channel!" msgstr "®iadny vybraný kanál!" msgid "error retrieving status info!" msgstr "Chyba pri naèítaní informácií o stave!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Chybné u¾ívateµské meno alebo heslo" msgid "Login" msgstr "Meno" msgid "VDR Live Login" msgstr "VDR Live meno" msgid "User" msgstr "U¾ívateµ" msgid "What's on?" msgstr "Èo práve ide?" msgid "MultiSchedule" msgstr "TV program v ståpcoch" msgid "Search" msgstr "Hµada»" msgid "Searchtimers" msgstr "Vyhµadávaè vysielacieho èasu" msgid "Recordings" msgstr "Nahrávky" msgid "Remote Control" msgstr "Diaµkové ovládanie" msgid "Logout" msgstr "Odhlási»" msgid "Your attention is required" msgstr "Upozornenie! " msgid "React" msgstr "Reagova»" msgid "Dismiss" msgstr "Zru¹" msgid "Now" msgstr "Teraz ide" msgid "%A, %b %d %Y" msgstr "%A, %b %d %Y" msgid "Time" msgstr "Èas" msgid "Switch to this channel." msgstr "Prepnú» na tento kanál." msgid "Search for repeats." msgstr "Vyhµada» reprízy." msgid "Click to view details." msgstr "Podrobnosti získate kliknutím." msgid "more" msgstr "viac" msgid "Channel" msgstr "Kanál" msgid "Find more at the Internet Movie Database." msgstr "Viac na Internet Movie Database." msgid "Stream this channel into browser." msgstr "Prezera» tento kanál v prehliadaèi." msgid "Stream this recording into browser." msgstr "Prezera» túto nahrávku v prehliadaèi." msgid "Record this" msgstr "Nahra»" msgid "loading data" msgstr "naèítanie dát" msgid "an error occured!" msgstr "do¹lo k chybe!" msgid "Request succeeded!" msgstr "Vyhovelo ¾iadosti!" msgid "Request failed!" msgstr "Chyba ¾iadosti!" msgid "January" msgstr "Január" msgid "February" msgstr "február" msgid "March" msgstr "Marec" msgid "April" msgstr "Apríl" msgid "May" msgstr "Máj" msgid "June" msgstr "Jún" msgid "July" msgstr "Júl" msgid "August" msgstr "August" msgid "September" msgstr "September" msgid "October" msgstr "Október" msgid "November" msgstr "November" msgid "December" msgstr "December" msgid "retrieving status ..." msgstr "naèítavanie stavu" msgid "Toggle updates on/off." msgstr "Prepínaè aktualizácii zapnú»/vypnú»." msgid "stop playback" msgstr "zastavenie prehrávania" msgid "resume playback" msgstr "obnovi» prehrávanie" msgid "pause playback" msgstr "pozastavenie prehrávania" msgid "fast rewind" msgstr "rýchlo pretoèi»" msgid "fast forward" msgstr "rýchlo vpred" msgid "previous channel" msgstr "predchádzajúci kanál" msgid "next channel" msgstr "ïal¹í kanál" msgid "No server response!" msgstr "Server neodpovedá!" msgid "Failed to update infobox!" msgstr "Nepodarilo sa aktualizova» infobox!" msgid "Authors" msgstr "Autori" msgid "Project Idea" msgstr "My¹lienka projektu" msgid "Webserver" msgstr "Webový server" msgid "Project leader" msgstr "Vedúci projektu" msgid "Content" msgstr "Obsah" msgid "Graphics" msgstr "Grafika" msgid "Information" msgstr "Informácie" msgid "LIVE version" msgstr "LIVE verzia" msgid "VDR version" msgstr "VDR verzia" msgid "Features" msgstr "Charakteristika" msgid "active" msgstr "aktívny" msgid "required" msgstr "po¾adované" msgid "Homepage" msgstr "Domovská stránka" msgid "Bugs and suggestions" msgstr "Chyby a podnety" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Ak narazíte na akúkoµvek chybu, alebo ak chcete navrhnú» nové funkcie, pou¾ite prosím ná¹ BUGTRACKER." msgid "ERROR:" msgstr "CHYBA:" msgid "Deleted recording:" msgstr "Vymazaný nahrávka:" msgid "List of recordings" msgstr "Zoznam nahrávok" msgid "No recordings found" msgstr "Nena¹la sa nahrávka" msgid "Delete selected" msgstr "Vymaza» vybrané" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "(%d:%02d)" msgid "Sort by name" msgstr "Zotriedi» podla mena" msgid "Sort by date" msgstr "Zotriedi» podla dátumu" msgid "Filter" msgstr "Filter" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Pozrite sa na nahrávky titulov a titulky pre daný re»azec a zobrazi» iba tie vyhovujúce. Mô¾ete pou¾i» kompatibilné perl regulárne výrazy (PCRE)." msgid "Expand all folders" msgstr "Rozbali» v¹etky zlo¾ky" msgid "Collapse all folders" msgstr "Zbali» v¹etky zlo¾ky" msgid "Delete this recording from hard disc!" msgstr "Vymaza» nahrávku z HDD" msgid "play this recording." msgstr "Prehra» záznam." msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Nena¹iel sa ¾iadny kanál alebo kanály nie sú k dispozícii. Mo¾no ste zle napísali va¹u po¾iadavku?" msgid "Snapshot interval" msgstr "Interval snímkovania" msgid "No schedules available for this channel" msgstr "Pre tento kanál sa nena¹iel ¾iadny televízny program." msgid "Search settings" msgstr "Nastavenie hµadania" msgid "Extended search" msgstr "Roz¹írené vyhµadávanie" msgid "no" msgstr "nie" msgid "Search results" msgstr "Výsledky vyhµadávania" msgid "No search results" msgstr "Hµadanie bez výsledku" msgid "Expression" msgstr "Pripomienky" msgid "Starts between" msgstr "Zaèína medzi" msgid "Toggle search timer actions (in)active" msgstr "Vypínaè vyhµadávania. Zapnú»/Vypnú»" msgid "Browse search timer results" msgstr "Zobrazi» výsledky vyhµadávania" msgid "Delete this search timer?" msgstr "Vymaza» tento vyhµadaný plán?" msgid "Delete search timer" msgstr "Vymaza» vyhµadávaè" msgid "Trigger search timer update" msgstr "Spusti» obnovenie vyhµadávania èasu" msgid "Please set login and password!" msgstr "Prosím nastavte u¾ívateµské meno a heslo!" msgid "Setup saved." msgstr "Nastavenie ulo¾ené." msgid "Setup" msgstr "Nastavenie" msgid "User management" msgstr "U¾ívateµský mana¾ment" msgid "Local net (no login required)" msgstr "Miestna sie» (nevy¾aduje prihlásenie)" msgid "Show live logo image" msgstr "Zobrazi» obrázok live loga" msgid "Use ajax technology" msgstr "Pou¾i» ajax technológiu" msgid "Show dynamic VDR information box" msgstr "Zobrazi» dynamicky VDR informaèný box" msgid "Allow video streaming" msgstr "Povoli» prúdové video" msgid "Streamdev server port" msgstr "Streamdev port servera" msgid "Streamdev stream type" msgstr "Typ prúdového videa" msgid "Add links to IMDb" msgstr "Prida» odkazy na IMDB" msgid "Additional fixed times in 'What's on?'" msgstr "Dodatoèný èas v ponuke 'Èo práve ide?'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Vo formáte HH:MM. Oddelené niekoµkokrát bodkoèiarkou" msgid "Channel groups for MultiSchedule" msgstr "Skupiny kanálov pre televízny program v ståpcoch" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Kanály oddeli» s èiarkou ',', skupiny kanálov oddeµova» bodkoèiarkou ';'" msgid "Duration of MultiSchedule in hours" msgstr "Då¾ka ståpcovitého televízneho programu v hodinách" msgid "Show channels without EPG" msgstr "Zobrazi» kanály s EPG" msgid "Start page" msgstr "©tartovacia stránka" msgid "Theme" msgstr "Vzhµad" msgid "Timer conflicts" msgstr "Konflikty plánu" msgid "No timer conflicts" msgstr "®iadne konflikty" msgid "Timer has a conflict." msgstr "Plán má konflikt." msgid "Timer is active." msgstr "Plán je aktívny." msgid "Toggle timer active/inactive" msgstr "Vypínaè plánu Zapnú»/vypnú»" msgid "Delete timer" msgstr "Vymaza» plán" msgid "No timer defined" msgstr "®iadny plán nahrávania nie je stanovený" msgid "Timer is recording." msgstr "Nahráva sa podµa plánu." msgid "Users" msgstr "U¾ívatelia" msgid "Delete user" msgstr "Vymaza» u¾ívateµa" msgid "VLC: live video stream" msgstr "VLC: ¾ivé vysielanie" msgid "VLC: play recording" msgstr "VLC: Prehrávaný záznam" msgid "Stop" msgstr "Zastavi»" msgid "Play" msgstr "Prehra»" msgid "Sound on" msgstr "Zapnú» zvuk" msgid "Sound off" msgstr "Vypnú» zvuk" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "Zavrie»" msgid "VLC media URL" msgstr "VLC média URL" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "Èo práve ide?" msgid "at" msgstr "o" msgid "What's on next?" msgstr "Èo nasleduje?" msgid "Favorites" msgstr "Obµúbené" msgid "View the schedule of this channel" msgstr "Zobrazi» televízny program pre tento kanál" msgid " - " msgstr " - " msgid "Next" msgstr "Nasleduje" msgid "What's on" msgstr "Èo bude" msgid "Details view" msgstr "Zobrazi» podrobnosti" msgid "List view" msgstr "Zobrazi» ako zoznam" msgid "Live Interactive VDR Environment" msgstr "®ivé interaktívne VDR prostredie" msgid "No EPG information available" msgstr "EPG informácie sú nedostupné" #~ msgid "(%d')" #~ msgstr "(%d')" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Zobrazi» då¾ku v 'Nahrávkach'" vdr-plugin-live/po/it_IT.po0000644000175000017500000004743212650773437015444 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Alberto Carraro , 2001 # Antonio Ospite , 2003 # Sean Carlos , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" "PO-Revision-Date: 2011-12-25 23:22+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: see developers in README\n" "Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Italian\n" "X-Poedit-Country: ITALY\n" "X-Poedit-SourceCharset: utf-8\n" msgid "Last channel to display" msgstr "Ultimo canale da visualizzare" msgid "No limit" msgstr "Mostra tutti" msgid "Use authentication" msgstr "Utilizza autenticazione" msgid "No" msgstr "No" msgid "Yes" msgstr "Sì" msgid "Admin login" msgstr "Nome amministratore" msgid "Admin password" msgstr "Password amministratore" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "Timer di ricerca" msgid "Error in timer settings" msgstr "Errore nelle impostazioni timer" msgid "Timer already defined" msgstr "Timer già definito" msgid "Timers are being edited - try again later" msgstr "I timer sono stati modificati - riprova più tardi" msgid "Timer not defined" msgstr "Timer non definito" msgid "On archive DVD No." msgstr "In archivio DVD No." msgid "On archive HDD No." msgstr "In archivio HDD No." msgid "Couldn't find channel or no channels available." msgstr "Impossibile trovare canale o canali disponibili." msgid "Couldn't switch to channel." msgstr "Impossibile cambiare canale." msgid "Couldn't find recording or no recordings available." msgstr "Impossibile trovare registrazione o registrazioni disponibili." msgid "Cannot control playback!" msgstr "Impossibile controllare la riproduzione!" msgid "Not playing a recording." msgstr "Nessuna registrazione in riproduzione." msgid "Not playing the same recording as from request." msgstr "Riproduzione di una registrazione diversa da quella richiesta." msgid "Attempt to delete recording currently in playback." msgstr "Tentativo di eliminare una registrazione in corso." msgid "Epg error" msgstr "Errore EPG" msgid "Wrong channel id" msgstr "ID canale errato" msgid "Channel has no schedule" msgstr "Il canale non ha programmazione" msgid "Wrong event id" msgstr "ID evento errato" msgid "Required minimum version of epgsearch: " msgstr "Versione minima richiesta di EPGSearch:" msgid "All" msgstr "Tutti" msgid "FTA" msgstr "Gratuiti" msgid "%I:%M %p" msgstr "%I:%M %p" msgid "EPGSearch version outdated! Please update." msgstr "Versione di EPGSearch troppo vecchia! Devi aggiornarla." msgid "Couldn't aquire primary device" msgstr "Impossibile identificare la scheda primaria" msgid "Couldn't grab image from primary device" msgstr "Impossibile ottenere immagini dalla scheda primaria" msgid "Timer conflict check detected " msgstr "Verifica conflitti timer rilevati" msgid "conflict" msgstr "conflitto" msgid "conflicts" msgstr "conflitti" msgid "Couldn't aquire access to channels, please try again later." msgstr "Impossibile avere accesso ai canali, riprova più tardi." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Spiacenti, senza permessi. Per favore contatta l'amministratore!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Impossibile trovare la registrazione. Hai digitato correttamente la richiesta?" msgid "Please set a name for the recording!" msgstr "Imposta un nome alla registrazione!" msgid "Cannot copy, rename or move the recording." msgstr "Impossibile copiare, rinominare o spostare la registrazione." msgid "Edit recording" msgstr "Modifica registrazione" msgid "Name" msgstr "Nome" msgid "Directory" msgstr "Directory" msgid "Delete resume information" msgstr "Elimina informazione ripristino" msgid "Delete marks information" msgstr "Elimina informazione marcatori" msgid "Copy only" msgstr "Solo copia" msgid "Short description" msgstr "Descrizione breve" msgid "Description" msgstr "Descrizione" msgid "Auxiliary info" msgstr "Informazioni ausiliarie" msgid "Save" msgstr "Salva" msgid "Cancel" msgstr "Annulla" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Impossibile trovare timer di ricerca. Hai digitato correttamente la richiesta?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "mm/dd/yyyy" msgid "Edit search timer" msgstr "Modifica timer di ricerca" msgid "New search timer" msgstr "Nuovo timer di ricerca" msgid "Search text too short - use anyway?" msgstr "Testo da cercare troppo breve - continuare lo stesso?" msgid "Search term" msgstr "Termine ricerca" msgid "Search mode" msgstr "Modalità ricerca" msgid "phrase" msgstr "frase" msgid "all words" msgstr "tutte le parole" msgid "at least one word" msgstr "almeno una parola" msgid "match exactly" msgstr "corrispondenza esatta" msgid "regular expression" msgstr "espressione regolare" msgid "fuzzy" msgstr "imprecisa" msgid "Tolerance" msgstr "Tolleranza" msgid "Match case" msgstr "Maiuscolo/Minuscolo" msgid "Search in" msgstr "Cerca in" msgid "Title" msgstr "Titolo" msgid "Episode" msgstr "Episodio" msgid "Use extended EPG info" msgstr "Utilizza informazioni EPG estesa" msgid "Ignore missing EPG info" msgstr "Ignora info EPG mancante" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Attivare questa opzione può creare molti timer. Quindi prova sempre questa ricerca prima di usarla come timer di ricerca!" msgid "Use channel" msgstr "Utilizza canale" msgid "interval" msgstr "intervallo" msgid "channel group" msgstr "gruppo canali" msgid "only FTA" msgstr "solo gratuiti" msgid "from channel" msgstr "da canale" msgid "to channel" msgstr "a canale" msgid "Use time" msgstr "Utilizza ora" msgid "Start after" msgstr "Inizio dopo" msgid "The time the show may start at the earliest" msgstr "L'ora precedente più vicina per l'inizio evento" msgid "Start before" msgstr "Inizio prima" msgid "The time the show may start at the latest" msgstr "L'ora successiva più tardi per l'inizio evento" msgid "Use duration" msgstr "Utilizza durata" msgid "Min. duration" msgstr "Durata Minima" msgid "Max. duration" msgstr "Durata Massima" msgid "Use day of week" msgstr "Utilizza giorno della settimana" msgid "Monday" msgstr "Lunedì" msgid "Tuesday" msgstr "Martedì" msgid "Wednesday" msgstr "Mercoledì" msgid "Thursday" msgstr "Giovedì" msgid "Friday" msgstr "Venerdì" msgid "Saturday" msgstr "Sabato" msgid "Sunday" msgstr "Domenica" msgid "Use blacklists" msgstr "Utilizza lista esclusioni" msgid "Selection" msgstr "Selezione" msgid "all" msgstr "tutti" msgid "Use in favorites menu" msgstr "Utilizza nel menu Preferiti" msgid "Use as search timer" msgstr "Utilizza come timer di ricerca" msgid "user defined" msgstr "definito dall'utente" msgid "from date" msgstr "da data" msgid "to date" msgstr "a data" msgid "Record" msgstr "Registra" msgid "Announce only" msgstr "Solo annuncio" msgid "Switch only" msgstr "Solo cambio canale" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Registrazioni in serie" msgid "Delete recordings after ... days" msgstr "Elimina registrazioni dopo ... giorni" msgid "Keep ... recordings" msgstr "Mantieni ... registrazioni" msgid "Pause when ... recordings exist" msgstr "Pausa, quando ... la registrazione esiste" msgid "Avoid repeats" msgstr "Evita repliche" msgid "Allowed repeats" msgstr "Repliche permesse" msgid "Only repeats within ... days" msgstr "Ripeti solo entro ... giorni" msgid "Compare title" msgstr "Confronta titoli" msgid "Compare subtitle" msgstr "Confronta sottotitoli" msgid "if present" msgstr "se presente" msgid "Compare summary" msgstr "Confronta descrizione" msgid "Compare" msgstr "Confronta" msgid "Use VPS" msgstr "Utilizza VPS" msgid "Auto-delete search timer" msgstr "Eliminazione automatica timer di ricerca" msgid "after ... recordings" msgstr "dopo ... registrazioni" msgid "after ... days after first rec." msgstr "dopo ... giorni dopo la prima registrazione" msgid "Switch ... minutes before start" msgstr "Cambia ... minuti prima dell'inizio" msgid "Test" msgstr "Prova" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Impossibile trovare il timer. Hai digitato correttamente la richiesta?" msgid "Please set a title for the timer!" msgstr "Imposta il titolo del timer!" msgid "Edit timer" msgstr "Modifica timer" msgid "New timer" msgstr "Nuovo timer" msgid "Weekday" msgstr "Giorno della settimana" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Impossibile trovare l'utente. Hai digitato correttamente la richiesta?" msgid "This user name is already in use!" msgstr "Questo nome utente è già in uso!" msgid "Edit user" msgstr "Modifica utente" msgid "New user" msgstr "Nuovo utente" msgid "Password" msgstr "Password" msgid "User rights" msgstr "Permessi utente" msgid "Edit setup" msgstr "Modifica opzioni" msgid "Add or edit timers" msgstr "Aggiungi o modifica timer" msgid "Delete timers" msgstr "Elimina timer" msgid "Delete recordings" msgstr "Elimina registrazioni" msgid "Use remote menu" msgstr "Utilizza menu remoto" msgid "Start replay" msgstr "Avvia riproduzione" msgid "Switch channel" msgstr "Cambia canale" msgid "Add or edit search timers" msgstr "Aggiungi o modifica timer di ricerca" msgid "Delete search timers" msgstr "Elimina timer di ricerca" msgid "Edit recordings" msgstr "Modifica registrazioni" msgid "Electronic program guide information" msgstr "Info Guida Elettronica Programmi (EPG)" msgid "Couldn't find recording or no recordings available" msgstr "Impossibile trovare registrazioni o nessuna registrazione disponibile" msgid "Error aquiring schedules lock" msgstr "Errore acquisizione blocco programmi" msgid "Error aquiring schedules" msgstr "Errore acquisizione programmi" msgid "%b %d %y" msgstr "%b %d %y" msgid "Page error" msgstr "Errore pagina" msgid "playing recording" msgstr "Riproduzione registrazione" msgid "no epg info for current event!" msgstr "Evento attuale senza info EPG!" msgid "no epg info for current channel!" msgstr "Canale attuale senza info EPG!" msgid "no current channel!" msgstr "Canale non trovato!" msgid "error retrieving status info!" msgstr "Errore: stato non disponibile!" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" msgid "Wrong username or password" msgstr "Nome utente o password errata" msgid "Login" msgstr "Entra" msgid "VDR Live Login" msgstr "Accesso VDR Live" msgid "User" msgstr "Utente" msgid "What's on?" msgstr "In programmazione" msgid "MultiSchedule" msgstr "Multi Programmazione" msgid "Search" msgstr "Ricerca" msgid "Searchtimers" msgstr "Timer di ricerca" msgid "Recordings" msgstr "Registrazioni" msgid "Remote Control" msgstr "Telecomando" msgid "Logout" msgstr "Esci" msgid "Your attention is required" msgstr "ATTENZIONE" msgid "React" msgstr "Risolvi" msgid "Dismiss" msgstr "Ignora" msgid "Now" msgstr "Adesso" msgid "%A, %b %d %Y" msgstr "%A, %b %d %Y" msgid "Time" msgstr "Ora" msgid "Switch to this channel." msgstr "Sintonizza questo canale" msgid "Search for repeats." msgstr "Cerca repliche" msgid "Click to view details." msgstr "Fai click per vedere i dettagli" msgid "more" msgstr "Altro" msgid "Channel" msgstr "Canale" msgid "Find more at the Internet Movie Database." msgstr "Cerca ulteriori informazioni nel database internet (IMDB)" msgid "Stream this channel into browser." msgstr "Trasmetti questo canale nel browser" msgid "Stream this recording into browser." msgstr "Trasmetti questa registrazione nel browser" msgid "Record this" msgstr "Registra questa trasmissione" msgid "loading data" msgstr "caricamento dati" msgid "an error occured!" msgstr "Errore rilevato!" msgid "Request succeeded!" msgstr "Richiesta completata!" msgid "Request failed!" msgstr "Richiesta fallita!" msgid "January" msgstr "Gennaio" msgid "February" msgstr "Febbraio" msgid "March" msgstr "Marzo" msgid "April" msgstr "Aprile" msgid "May" msgstr "Maggio" msgid "June" msgstr "Giugno" msgid "July" msgstr "Luglio" msgid "August" msgstr "Agosto" msgid "September" msgstr "Settembre" msgid "October" msgstr "Ottobre" msgid "November" msgstr "Novembre" msgid "December" msgstr "Dicembre" msgid "retrieving status ..." msgstr "Rilevamento stato ..." msgid "Toggle updates on/off." msgstr "Attiva/disattiva aggiornamenti" msgid "stop playback" msgstr "Ferma" msgid "resume playback" msgstr "Continua" msgid "pause playback" msgstr "Pausa" msgid "fast rewind" msgstr "Riavvolgi" msgid "fast forward" msgstr "Avanza" msgid "previous channel" msgstr "Canale precedente" msgid "next channel" msgstr "Canale successivo" msgid "No server response!" msgstr "Nessuna risposta dal server!" msgid "Failed to update infobox!" msgstr "Aggiornamento tabella info fallita!" msgid "Authors" msgstr "Autori" msgid "Project Idea" msgstr "Idea progetto" msgid "Webserver" msgstr "Server web" msgid "Project leader" msgstr "Capo progetto" msgid "Content" msgstr "Contenuti" msgid "Graphics" msgstr "Grafiche" msgid "Information" msgstr "Informazioni" msgid "LIVE version" msgstr "Versione LIVE" msgid "VDR version" msgstr "Versione VDR" msgid "Features" msgstr "Funzioni" msgid "active" msgstr "attivo" msgid "required" msgstr "richiesto" msgid "Homepage" msgstr "Pagina principale" msgid "Bugs and suggestions" msgstr "Rapporto errori e proposte" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Se riscontri degli errori o vuoi chiedere nuove funzioni utilizza il nostro bugtracker" msgid "ERROR:" msgstr "ERRORE:" msgid "Deleted recording:" msgstr "Registrazione eliminata:" msgid "List of recordings" msgstr "Elenco registrazioni" msgid "No recordings found" msgstr "Nessuna registrazione trovata" msgid "Delete selected" msgstr "Elimina selezionati" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "(%d:%02d)" msgid "Sort by name" msgstr "Ordina per nome" msgid "Sort by date" msgstr "Ordina per data" msgid "Filter" msgstr "Filtro" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Cerca nei titoli e sottotitoli delle registrazioni determinati valori e mostra solo quelli attinenti. Puoi anche usare espressioni regolari compatibili perl (PCRE)" msgid "Expand all folders" msgstr "Espandi tutte le cartelle" msgid "Collapse all folders" msgstr "Comprimi tutte le cartelle" msgid "Delete this recording from hard disc!" msgstr "Elimina questa registrazione dal disco fisso!" msgid "play this recording." msgstr "Riproduci questa registrazione" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Impossibile trovare il canale o i canali disponibili. Hai digitato correttamente la richiesta?" msgid "Snapshot interval" msgstr "Intervallo schermata" msgid "No schedules available for this channel" msgstr "Nessun programma disponibile per questo canale" msgid "Search settings" msgstr "Impostazioni ricerca" msgid "Extended search" msgstr "Ricerca avanzata" msgid "no" msgstr "no" msgid "Search results" msgstr "Risultati ricerca" msgid "No search results" msgstr "Nessun risultato ricerca" msgid "Expression" msgstr "Termine ricerca" msgid "Starts between" msgstr "Inizia tra" msgid "Toggle search timer actions (in)active" msgstr "Attiva/disattiva azioni ricerca timer" msgid "Browse search timer results" msgstr "Visualizza risultati ricerca" msgid "Delete this search timer?" msgstr "Eliminare questo timer di ricerca?" msgid "Delete search timer" msgstr "Elimina timer di ricerca" msgid "Trigger search timer update" msgstr "Avvia aggiornamento timer di ricerca" msgid "Please set login and password!" msgstr "Digita un nome utente e password!" msgid "Setup saved." msgstr "Opzioni salvate." msgid "Setup" msgstr "Opzioni" msgid "User management" msgstr "Gestione utenti" msgid "Local net (no login required)" msgstr "Rete locale (nessun accesso richiesto)" msgid "Show live logo image" msgstr "Mostra logo immagine Live" msgid "Use ajax technology" msgstr "Utilizza tecnologia Ajax" msgid "Show dynamic VDR information box" msgstr "Mostra tabella informazione dinamica VDR" msgid "Allow video streaming" msgstr "Permetti trasmissione video" msgid "Streamdev server port" msgstr "Porta server Streamdev" msgid "Streamdev stream type" msgstr "Tipo trasmissione Streamdev" msgid "Add links to IMDb" msgstr "Aggiungi collegamenti a IMDB" msgid "Additional fixed times in 'What's on?'" msgstr "Ore aggiuntive fisse menu \"In programmazione\"" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Il formato è HH:MM. Separa le ore multiple con un punto e virgola" msgid "Channel groups for MultiSchedule" msgstr "Gruppi canali per Multi Programmazione" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Separa canali con una virgola ',', separa gruppi con un punto e virgola ';'" msgid "Duration of MultiSchedule in hours" msgstr "Durata Multi Programmazione (in ore)" msgid "Show channels without EPG" msgstr "Mostra canali senza EPG" msgid "Start page" msgstr "Pagina iniziale" msgid "Theme" msgstr "Tema" msgid "Timer conflicts" msgstr "Conflitti timer" msgid "No timer conflicts" msgstr "Nessun timer in conflitto" msgid "Timer has a conflict." msgstr "Il timer ha un conflitto." msgid "Timer is active." msgstr "Timer attivo." msgid "Toggle timer active/inactive" msgstr "Attiva/disattiva timer" msgid "Delete timer" msgstr "Elimina timer" msgid "No timer defined" msgstr "Nessun timer definito" msgid "Timer is recording." msgstr "Timer in registrazione." msgid "Users" msgstr "Utenti" msgid "Delete user" msgstr "Elimina utente" msgid "VLC: live video stream" msgstr "VLC: trasmissione video Live" msgid "VLC: play recording" msgstr "VLC: riproduci registrazione" msgid "Stop" msgstr "Ferma" msgid "Play" msgstr "Riproduci" msgid "Sound on" msgstr "Volume" msgid "Sound off" msgstr "Muto" msgid "Fullscreen" msgstr "Ingrandisci" msgid "Close" msgstr "Chiudi" msgid "VLC media URL" msgstr "Collegamento multimediale di VLC" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "In programmazione alle" msgid "at" msgstr "alle" msgid "What's on next?" msgstr "In programmazione dopo" msgid "Favorites" msgstr "Preferiti" msgid "View the schedule of this channel" msgstr "Visualizza scheda programmi del canale" msgid " - " msgstr " - " msgid "Next" msgstr "Prossimi" msgid "What's on" msgstr "In programmazione" msgid "Details view" msgstr "Vedi come dettagli" msgid "List view" msgstr "Vedi come elenco" msgid "Live Interactive VDR Environment" msgstr "Ambiente interattivo LIVE per VDR" msgid "No EPG information available" msgstr "Nessuna informazione EPG disponibile" #~ msgid "(%d')" #~ msgstr "(%d')" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Mostra durata in 'Registrazioni'" #, fuzzy #~ msgid "Subtitle" #~ msgstr "Titolo" #, fuzzy #~ msgid "Please set a name and password for the user!" #~ msgstr "Digita un nome utente e password!" #~ msgid "Interval" #~ msgstr "Intervallo" #~ msgid "Show schedule of channel" #~ msgstr "Mostra scheda programmi canale" #~ msgid "%a, %b %d" #~ msgstr "%a, %b %d" #~ msgid "Stream into browser" #~ msgstr "Trasmetti nel browser" #~ msgid "Edit this" #~ msgstr "Modifica timer" #, fuzzy #~ msgid "Start" #~ msgstr "Pagina iniziale" #, fuzzy #~ msgid "File" #~ msgstr "Titolo" #, fuzzy #~ msgid "%A, %B %d %Y" #~ msgstr "%A, %b %d %Y" vdr-plugin-live/po/pt_PT.po0000644000175000017500000003046112650773437015454 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Paulo Lopes , 2001 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Paulo Lopes \n" "Language-Team: see developers in README\n" "Language: pt_PT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Gravar" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/fi_FI.po0000644000175000017500000004536612650773437015414 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Rolf Ahrenberg # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Rolf Ahrenberg \n" "Language-Team: see developers in README\n" "Language: fi_FI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Näytä viimeisenä kanava" msgid "No limit" msgstr "ei rajoitusta" msgid "Use authentication" msgstr "Käytä autentikointia" msgid "No" msgstr "ei" msgid "Yes" msgstr "kyllä" msgid "Admin login" msgstr "Ylläpidon käyttäjätunnus" msgid "Admin password" msgstr "Ylläpidon salasana" #, c-format msgid "%A, %x" msgstr "%A %x" msgid "Searchtimer" msgstr "Hakuajastimet" msgid "Error in timer settings" msgstr "Ajastimen asetukset virheelliset" msgid "Timer already defined" msgstr "Ajastin jo määritelty" msgid "Timers are being edited - try again later" msgstr "Ajastimia muokataan - yritä uudelleen myöhemmin" msgid "Timer not defined" msgstr "Ajastinta ei ole määritelty" msgid "On archive DVD No." msgstr "Arkistointi-DVD:llä numero" msgid "On archive HDD No." msgstr "Arkistointi-HDD:llä numero" msgid "Couldn't find channel or no channels available." msgstr "Kanavaa ei löydy tai yhtään kanavaa ei ole saatavilla." msgid "Couldn't switch to channel." msgstr "Kanavan valinta epäonnistui." msgid "Couldn't find recording or no recordings available." msgstr "Tallennetta ei löydy tai yhtään tallennetta ei ole saatavilla." msgid "Cannot control playback!" msgstr "Toiston hallinta epäonnistui!" msgid "Not playing a recording." msgstr "Tallennetta ei toisteta." msgid "Not playing the same recording as from request." msgstr "Pyydettyä tallennetta ei toisteta." msgid "Attempt to delete recording currently in playback." msgstr "Yritetään poistaa toistettavaa tallennetta." msgid "Epg error" msgstr "Ohjelmaoppaan virhe" msgid "Wrong channel id" msgstr "Väärä kanavan tunniste" msgid "Channel has no schedule" msgstr "Kanavalla ei ole ohjelmatietoja" msgid "Wrong event id" msgstr "Väärä tapahtuman tunniste" msgid "Required minimum version of epgsearch: " msgstr "Vaadittava versio EPGSearch-laajennoksesta: " msgid "All" msgstr "Kaikki" msgid "FTA" msgstr "Vapaat" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "EPGSearch-laajennos pitäisi päivittää!" msgid "Couldn't aquire primary device" msgstr "Ensisijaisen DVB-sovittimen käyttäminen epäonnistui!" msgid "Couldn't grab image from primary device" msgstr "Kuvan kaappaus ensisijaiselta DVB-sovittimelta epäonnistui!" msgid "Timer conflict check detected " msgstr "Tarkistuksessa löydettiin " msgid "conflict" msgstr "päällekkäinen ajastin" msgid "conflicts" msgstr "päällekkäistä ajastinta" msgid "Couldn't aquire access to channels, please try again later." msgstr "Kanavien käyttäminen epäonnistui! Yritä myöhemmin uudelleen." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Ei käyttöoikeutta. Ota yhteyttä ylläpitäjään!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Tallennetta ei löydy. Kirjoititko varmasti oikein?" msgid "Please set a name for the recording!" msgstr "Aseta nimi tallenteelle!" msgid "Cannot copy, rename or move the recording." msgstr "Tallenteen kopioiminen, uudelleen nimeäminen tai siirto epäonnistui!" msgid "Edit recording" msgstr "Muokkaa tallennetta" msgid "Name" msgstr "Nimi" msgid "Directory" msgstr "Hakemisto" msgid "Delete resume information" msgstr "Poista paluutiedot" msgid "Delete marks information" msgstr "Poista merkinnät" msgid "Copy only" msgstr "Kopioi ainoastaan" msgid "Short description" msgstr "Lyhyt kuvaus" msgid "Description" msgstr "Kuvaus" msgid "Auxiliary info" msgstr "Lisätiedot" msgid "Save" msgstr "Tallenna" msgid "Cancel" msgstr "Peru" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Hakuajastimia ei löydetä! Onko pyyntö oikein kirjoitettu?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "mm/dd/yyyy" msgid "Edit search timer" msgstr "Muokkaa hakuajastinta" msgid "New search timer" msgstr "Luo uusi hakuajastin" msgid "Search text too short - use anyway?" msgstr "Liian suppea hakuehto - etsitäänkö silti?" msgid "Search term" msgstr "Hakuehto" msgid "Search mode" msgstr "Hakutapa" msgid "phrase" msgstr "fraasi" msgid "all words" msgstr "kaikki sanat" msgid "at least one word" msgstr "yksi sana" msgid "match exactly" msgstr "täsmällinen" msgid "regular expression" msgstr "säännöllinen lauseke" msgid "fuzzy" msgstr "sumea" msgid "Tolerance" msgstr "Toleranssi" msgid "Match case" msgstr "Huomioi kirjainkoko" msgid "Search in" msgstr "Hae kentistä" msgid "Title" msgstr "Otsikko" msgid "Episode" msgstr "Jakson nimi" msgid "Use extended EPG info" msgstr "Käytä laajennettua ohjelmaopasta" msgid "Ignore missing EPG info" msgstr "Jätä puuttuvat ohjelmatiedot huomioimatta" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Asetuksen ottaminen käyttöön saattaa luoda lukemattomia ajastimia. Testaa haku ennenkuin teet siitä hakuajastimen!" msgid "Use channel" msgstr "Käytä kanavaa" msgid "interval" msgstr "kyllä" msgid "channel group" msgstr "kanavaryhmä" msgid "only FTA" msgstr "vapaat kanavat" msgid "from channel" msgstr "Kanavasta" msgid "to channel" msgstr "Kanavaan" msgid "Use time" msgstr "Käytä aloitusaikaa" msgid "Start after" msgstr "Aloitusaika aikaisintaan" msgid "The time the show may start at the earliest" msgstr "Lähetyksen aloitusaika aikaisintaan" msgid "Start before" msgstr "Aloitusaika viimeistään" msgid "The time the show may start at the latest" msgstr "Lähetyksen aloitusaika viimeistään" msgid "Use duration" msgstr "Käytä kestoaikaa" msgid "Min. duration" msgstr "Kestoaika vähintään" msgid "Max. duration" msgstr "Kestoaika enintään" msgid "Use day of week" msgstr "Käytä viikonpäivää" msgid "Monday" msgstr "Maanantai" msgid "Tuesday" msgstr "Tiistai" msgid "Wednesday" msgstr "Keskiviikko" msgid "Thursday" msgstr "Torstai" msgid "Friday" msgstr "Perjantai" msgid "Saturday" msgstr "Lauantai" msgid "Sunday" msgstr "Sunnuntai" msgid "Use blacklists" msgstr "Käytä mustia listoja" msgid "Selection" msgstr "valittu" msgid "all" msgstr "kaikki" msgid "Use in favorites menu" msgstr "Käytä suosikkina" msgid "Use as search timer" msgstr "Käytä hakuajastimena" msgid "user defined" msgstr "käyttäjän määrittelemä" msgid "from date" msgstr "alkaen" msgid "to date" msgstr "päättyen" msgid "Record" msgstr "Tallenna" msgid "Announce only" msgstr "Muistutus" msgid "Switch only" msgstr "Kanavanvaihto" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Sarjatallennus" msgid "Delete recordings after ... days" msgstr "Poista tallenteet ... päivän jälkeen" msgid "Keep ... recordings" msgstr "Säilytä ... tallennetta" msgid "Pause when ... recordings exist" msgstr "Keskeytä ... tallenteen jälkeen" msgid "Avoid repeats" msgstr "Estä uusinnat" msgid "Allowed repeats" msgstr "Sallittujen uusintojen lukumäärä" msgid "Only repeats within ... days" msgstr "Vain uusinnat ... päivän sisällä" msgid "Compare title" msgstr "Vertaa nimeä" msgid "Compare subtitle" msgstr "Vertaa jakson nimeä" msgid "if present" msgstr "jos olemassa" msgid "Compare summary" msgstr "Vertaa kuvausta" msgid "Compare" msgstr "Vertaa" msgid "Use VPS" msgstr "Käytä VPS-toimintoa" msgid "Auto-delete search timer" msgstr "Poista automaattisesti hakuajastimet" msgid "after ... recordings" msgstr "... tallenteen jälkeen" msgid "after ... days after first rec." msgstr "... päivän jälkeen ensimmäisestä" msgid "Switch ... minutes before start" msgstr "Vaihda ... minuuttia ennen alkua" msgid "Test" msgstr "Testaa" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Ajastinta ei löydy. Kirjoititko varmasti oikein?" msgid "Please set a title for the timer!" msgstr "Aseta nimi ajastimelle!" msgid "Edit timer" msgstr "Muokkaa ajastinta" msgid "New timer" msgstr "Luo uusi ajastin" msgid "Weekday" msgstr "Viikonpäivä" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Käyttäjää ei löydy. Kirjoititko varmasti oikein?" msgid "This user name is already in use!" msgstr "Käyttäjänimi on jo käytössä!" msgid "Edit user" msgstr "Muokkaa käyttäjää" msgid "New user" msgstr "Luo uusi käyttäjä" msgid "Password" msgstr "Salasana" msgid "User rights" msgstr "Käyttöoikeudet" msgid "Edit setup" msgstr "Muokkaa asetuksia" msgid "Add or edit timers" msgstr "Lisää/muokkaa ajastimia" msgid "Delete timers" msgstr "Poista ajastimia" msgid "Delete recordings" msgstr "Poista tallenteita" msgid "Use remote menu" msgstr "Käytä kauko-ohjainta" msgid "Start replay" msgstr "Aloita toisto" msgid "Switch channel" msgstr "Vaihda kanavaa" msgid "Add or edit search timers" msgstr "Lisää/muokkaa hakuajastimia" msgid "Delete search timers" msgstr "Poista hakuajastimia" msgid "Edit recordings" msgstr "Muokkaa tallenteita" msgid "Electronic program guide information" msgstr "Ohjelmaoppaan tiedot" msgid "Couldn't find recording or no recordings available" msgstr "Tallennetta ei löydy tai yhtään tallennetta ei ole saatavilla." msgid "Error aquiring schedules lock" msgstr "Ohjelmatietojen lukitus epäonnistui!" msgid "Error aquiring schedules" msgstr "Ohjelmatietojen haku epäonnistui!" msgid "%b %d %y" msgstr "%d.%m.%y" msgid "Page error" msgstr "Sivuvirhe" msgid "playing recording" msgstr "Toistetaan tallennetta" msgid "no epg info for current event!" msgstr "Lähetyksellä ei ole ohjelmatietoja!" msgid "no epg info for current channel!" msgstr "Kanavalla ei ole ohjelmatietoja!" msgid "no current channel!" msgstr "Kanavaa ei löydy!" msgid "error retrieving status info!" msgstr "Virhe: tilannetietoja ei saatavilla!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Väärä käyttäjätunnus tai salasana" msgid "Login" msgstr "Kirjaudu sisään" msgid "VDR Live Login" msgstr "VDR Live - sisäänkirjautuminen" msgid "User" msgstr "Käyttäjä" msgid "What's on?" msgstr "Menossa?" msgid "MultiSchedule" msgstr "Ohjelmaopas" msgid "Search" msgstr "Etsi" msgid "Searchtimers" msgstr "Hakuajastimet" msgid "Recordings" msgstr "Tallenteet" msgid "Remote Control" msgstr "Kauko-ohjain" msgid "Logout" msgstr "Kirjaudu ulos" msgid "Your attention is required" msgstr "Huomiotasi tarvitaan" msgid "React" msgstr "Reagoi" msgid "Dismiss" msgstr "Ohita" msgid "Now" msgstr "Nyt" msgid "%A, %b %d %Y" msgstr "%A %d.%m.%Y" msgid "Time" msgstr "Ajankohta" msgid "Switch to this channel." msgstr "Vaihda kanavalle" msgid "Search for repeats." msgstr "Etsi toistuvat" msgid "Click to view details." msgstr "Napsauta katsoaksesi lisätietoja." msgid "more" msgstr "lisätietoja" msgid "Channel" msgstr "Kanava" msgid "Find more at the Internet Movie Database." msgstr "Hae IMDB:stä" msgid "Stream this channel into browser." msgstr "Aloita kanavan suoratoisto" msgid "Stream this recording into browser." msgstr "Aloita tallenteen suoratoisto" msgid "Record this" msgstr "Tallenna ohjelma" msgid "loading data" msgstr "ladataan tietoja" msgid "an error occured!" msgstr "virhe havaittu!" msgid "Request succeeded!" msgstr "Pyyntö onnistui!" msgid "Request failed!" msgstr "Pyyntö epäonnistui!" msgid "January" msgstr "Tammikuu" msgid "February" msgstr "Helmikuu" msgid "March" msgstr "Maaliskuu" msgid "April" msgstr "Huhtikuu" msgid "May" msgstr "Toukokuu" msgid "June" msgstr "Kesäkuu" msgid "July" msgstr "Heinäkuu" msgid "August" msgstr "Elokuu" msgid "September" msgstr "Syyskuu" msgid "October" msgstr "Lokakuu" msgid "November" msgstr "Marraskuu" msgid "December" msgstr "Joulukuu" msgid "retrieving status ..." msgstr "Haetaan tietoja ..." msgid "Toggle updates on/off." msgstr "Aseta tilannekysely päälle/pois" msgid "stop playback" msgstr "Lopeta toisto" msgid "resume playback" msgstr "Jatka toistoa" msgid "pause playback" msgstr "Pysäytä toisto" msgid "fast rewind" msgstr "Pikakelaus taaksepäin" msgid "fast forward" msgstr "Pikakelaus eteenpäin" msgid "previous channel" msgstr "Edellinen kanava" msgid "next channel" msgstr "Seuraava kanava" msgid "No server response!" msgstr "Palvelin ei vastaa!" msgid "Failed to update infobox!" msgstr "Infolaatikon päivitys epäonnistui!" msgid "Authors" msgstr "Tekijät" msgid "Project Idea" msgstr "Projektin idea" msgid "Webserver" msgstr "HTTP-palvelin" msgid "Project leader" msgstr "Projektipäällikkö" msgid "Content" msgstr "Sisältö" msgid "Graphics" msgstr "Grafiikka" msgid "Information" msgstr "Tietoja" msgid "LIVE version" msgstr "LIVE-versio" msgid "VDR version" msgstr "VDR-versio" msgid "Features" msgstr "Tuetut laajennokset" msgid "active" msgstr "käytössä" msgid "required" msgstr "vaadittava" msgid "Homepage" msgstr "Kotisivu" msgid "Bugs and suggestions" msgstr "Virheraportoinnit ja parannusehdotukset" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Voit raportoida sekä virheet että parannusehdotukset suoraan havaintotietokantaan" msgid "ERROR:" msgstr "VIRHE:" msgid "Deleted recording:" msgstr "Poistettu tallenne:" msgid "List of recordings" msgstr "Tallennelistaus" msgid "No recordings found" msgstr "Tallenteita ei löydy" msgid "Delete selected" msgstr "Poista valitut" #, no-c-format msgid "%a," msgstr "%a" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "Järjestä nimen mukaan" msgid "Sort by date" msgstr "Järjestä päivämäärän mukaan" msgid "Filter" msgstr "Suodata" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Suodata tallenteet nimi- ja kuvauskentistä hakusanan avulla. Voit käyttää myös Perl-yhteensopivia säännöllisiä lausekkeita (PCRE)." msgid "Expand all folders" msgstr "Avaa kaikki kansiot" msgid "Collapse all folders" msgstr "Sulje kaikki kansiot" msgid "Delete this recording from hard disc!" msgstr "Poista tallenne kovalevyltä!" msgid "play this recording." msgstr "Toista tallenne" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Kanavaa ei löydy. Kirjoititko varmasti oikein?" msgid "Snapshot interval" msgstr "Kuvien päivitysväli" msgid "No schedules available for this channel" msgstr "Tälle kanavalle ei ole saatavilla ohjelmistoa" msgid "Search settings" msgstr "Hakuasetukset" msgid "Extended search" msgstr "Laajennettu haku" msgid "no" msgstr "ei" msgid "Search results" msgstr "Hakutulokset" msgid "No search results" msgstr "Ei hakutuloksia" msgid "Expression" msgstr "Hakutermi" msgid "Starts between" msgstr "Alkaa välillä" msgid "Toggle search timer actions (in)active" msgstr "Aseta hakuajastin päälle/pois" msgid "Browse search timer results" msgstr "Selaa hakutuloksia" msgid "Delete this search timer?" msgstr "Poistetaanko tämä hakuajastin?" msgid "Delete search timer" msgstr "Poista hakuajastin" msgid "Trigger search timer update" msgstr "Päivitä hakuajastimet" msgid "Please set login and password!" msgstr "Aseta käyttäjätunnus sekä salasana!" msgid "Setup saved." msgstr "Asetukset tallennettu." msgid "Setup" msgstr "Asetukset" msgid "User management" msgstr "Käyttäjähallinta" msgid "Local net (no login required)" msgstr "Paikallinen verkko (ei autentikointia)" msgid "Show live logo image" msgstr "Näytä Live-logo" msgid "Use ajax technology" msgstr "Käytä AJAX-tekniikkaa" msgid "Show dynamic VDR information box" msgstr "Näytä dynaaminen VDR:n infolaatikko" msgid "Allow video streaming" msgstr "Salli lähetyksen suoratoisto" msgid "Streamdev server port" msgstr "Streamdev-palvelimen portti" msgid "Streamdev stream type" msgstr "Streamdev-lähetteen tyyppi" msgid "Add links to IMDb" msgstr "Lisää linkit IMDb:hen" msgid "Additional fixed times in 'What's on?'" msgstr "Lisäajankohdat 'Menossa?'-sivulle" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Käytä HH:MM formaattia ja erota ajankohdat puolipisteellä" msgid "Channel groups for MultiSchedule" msgstr "Kanavaryhmät 'Ohjelmaopas'-sivulle" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Käytä pilkkua erottimena kanaville ja puolipistettä kanavaryhmille" msgid "Duration of MultiSchedule in hours" msgstr "'Ohjelmaopas'-sivun kesto tunteina" msgid "Show channels without EPG" msgstr "Näytä ohjelmaoppaattomat kanavat" msgid "Start page" msgstr "Aloitussivu" msgid "Theme" msgstr "Ulkoasu" msgid "Timer conflicts" msgstr "Päällekkäiset ajastimet" msgid "No timer conflicts" msgstr "Ei päällekkäisiä ajastimia" msgid "Timer has a conflict." msgstr "Päällekkäinen ajastin" msgid "Timer is active." msgstr "Aktiivinen ajastin" msgid "Toggle timer active/inactive" msgstr "Aseta ajastin päälle/pois" msgid "Delete timer" msgstr "Poista ajastin" msgid "No timer defined" msgstr "Ajastinta ei ole määritelty" msgid "Timer is recording." msgstr "Ajastinta tallennetaan" msgid "Users" msgstr "Käyttäjät" msgid "Delete user" msgstr "Poista käyttäjä" msgid "VLC: live video stream" msgstr "VLC: live-lähetyksen suoratoisto" msgid "VLC: play recording" msgstr "VLC: toista tallenne" msgid "Stop" msgstr "Pysäytä" msgid "Play" msgstr "Toista" msgid "Sound on" msgstr "Poista mykistys" msgid "Sound off" msgstr "Mykistä" msgid "Fullscreen" msgstr "Kokonäyttö" msgid "Close" msgstr "Sulje" msgid "VLC media URL" msgstr "VLC:n URL" #, c-format msgid "%a, %x" msgstr "%a %x" msgid "What's running on" msgstr "Menossa" msgid "at" msgstr "kello" msgid "What's on next?" msgstr "Tulossa seuraavaksi?" msgid "Favorites" msgstr "Suosikit" msgid "View the schedule of this channel" msgstr "Näytä ohjelmisto kanavalta" msgid " - " msgstr "" msgid "Next" msgstr "Seuraavaksi" msgid "What's on" msgstr "Menossa" msgid "Details view" msgstr "Ruudukkonäkymä" msgid "List view" msgstr "Listanäkymä" msgid "Live Interactive VDR Environment" msgstr "Interaktiivinen VDR-ympäristö" msgid "No EPG information available" msgstr "Ohjelmatietoja ei saatavilla" #~ msgid "(%d')" #~ msgstr "%d'" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Näytä kestoajat 'Tallenteet'-sivulla" #~ msgid "Subtitle" #~ msgstr "Lyhyt kuvaus" vdr-plugin-live/po/fr_FR.po0000644000175000017500000004706212650773437015431 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Jean-Claude Repetto , 2001 # Olivier Jacques , 2003 # Gregoire Favre , 2003 # Nicolas Huillard , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Nicolas Huillard \n" "Language-Team: see developers in README\n" "Language: fr_FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Dernière chaîne affichée" msgid "No limit" msgstr "Afficher tout" msgid "Use authentication" msgstr "Utiliser l'authentification" msgid "No" msgstr "Non" msgid "Yes" msgstr "Oui" msgid "Admin login" msgstr "Ouverture Admin" msgid "Admin password" msgstr "Mot de passe de l'Admin" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "Recherche de programmation" msgid "Error in timer settings" msgstr "Erreur dans la configuration de programmation" msgid "Timer already defined" msgstr "Programmation déjà définit" msgid "Timers are being edited - try again later" msgstr "Programmation sont en cours d'édition - essayer plus tard" msgid "Timer not defined" msgstr "Programmation non définit" msgid "On archive DVD No." msgstr "Sur le DVD archive no°" msgid "On archive HDD No." msgstr "Sur le HDD archive noä" msgid "Couldn't find channel or no channels available." msgstr "Impossible de trouver la chaîne ou pas de chaînes disponibles." msgid "Couldn't switch to channel." msgstr "Impossible de passer à la chaîne." msgid "Couldn't find recording or no recordings available." msgstr "Impossible de trouver l'enregistrement ou aucun enregistrements disponibles." msgid "Cannot control playback!" msgstr "Ne peut pas contrôler la lecture!" msgid "Not playing a recording." msgstr "Ne joue pas l'enregistrement." msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "Tentative d'effacer l'enregistrement en cours de lecture." msgid "Epg error" msgstr "Erreur EPG" msgid "Wrong channel id" msgstr "Faux ID de chaîne" msgid "Channel has no schedule" msgstr "La chaîne n'a pas de programmation" msgid "Wrong event id" msgstr "Faux ID d'événement" msgid "Required minimum version of epgsearch: " msgstr "Version minimum requise d'epgsearch: " msgid "All" msgstr "Tout" msgid "FTA" msgstr "FTA" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "Version EPGSearch périmée! Mettre à jour Svp." msgid "Couldn't aquire primary device" msgstr "Impossible d'acquérir périphérique primaire" msgid "Couldn't grab image from primary device" msgstr "Impossible de récupérer l'image du périphérique primaire" #, fuzzy msgid "Timer conflict check detected " msgstr "Programmation est active." #, fuzzy msgid "conflict" msgstr "Programmation est active." #, fuzzy msgid "conflicts" msgstr "Programmation est active." msgid "Couldn't aquire access to channels, please try again later." msgstr "Impossible d'avoir accès à des chaînes, réessayer ultérieurement." msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "Dossier" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" #, fuzzy msgid "Short description" msgstr "Description" msgid "Description" msgstr "Description" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "Sauvegarde" msgid "Cancel" msgstr "Interrompre" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Impossible de trouver la programmation de recherche. Peut-être que votre demande de fautes de frappe?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "mm/dd/yyyy" msgid "Edit search timer" msgstr "Editer l'expression de recherche" msgid "New search timer" msgstr "Créer nouvelle programmation de recherche" msgid "Search text too short - use anyway?" msgstr "Texte de recherche est trop court - l'utiliser quand même?" msgid "Search term" msgstr "Mot clé" msgid "Search mode" msgstr "Mode de recherche" msgid "phrase" msgstr "Phrase" msgid "all words" msgstr "tout les mots" msgid "at least one word" msgstr "un mot" msgid "match exactly" msgstr "correspond exactement" msgid "regular expression" msgstr "expression réguliere" msgid "fuzzy" msgstr "imprécis" msgid "Tolerance" msgstr "Tolérance" msgid "Match case" msgstr "Maj/Minuscule" msgid "Search in" msgstr "Recherche dans" msgid "Title" msgstr "Titre" msgid "Episode" msgstr "Épisode" msgid "Use extended EPG info" msgstr "Utiliser les infos EPG avancées" msgid "Ignore missing EPG info" msgstr "Ignorez EPG info manquante" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Lorsqu'elle est active, cela peut provoquer de très nombreuses programmations. Donc s¿il vous plaît toujours d'abord tester cette recherche avant de l'utiliser comme progammation de recherche!" msgid "Use channel" msgstr "Utiliser la chaîne" msgid "interval" msgstr "intervalle" msgid "channel group" msgstr "Groupe de chaînes" msgid "only FTA" msgstr "sans TV-Payante" msgid "from channel" msgstr "de la chaîne" msgid "to channel" msgstr "à la chaîne" msgid "Use time" msgstr "Utiliser l'heure" msgid "Start after" msgstr "Départ après" msgid "The time the show may start at the earliest" msgstr "L'heure lorsque l'émission doit commencer au plus tôt" msgid "Start before" msgstr "Départ avant" msgid "The time the show may start at the latest" msgstr "L'heure lorsque l'émission doit commencer au plus tard" msgid "Use duration" msgstr "Durée d'utilisation" msgid "Min. duration" msgstr "Durée min." msgid "Max. duration" msgstr "Durée max." msgid "Use day of week" msgstr "Utiliser les jours de la semaine" msgid "Monday" msgstr "Lundi" msgid "Tuesday" msgstr "Mardi" msgid "Wednesday" msgstr "Mercredi" msgid "Thursday" msgstr "Jeudi" msgid "Friday" msgstr "Vendredi" msgid "Saturday" msgstr "Samedi" msgid "Sunday" msgstr "Dimanche" msgid "Use blacklists" msgstr "Utiliser la liste des exclus" msgid "Selection" msgstr "Selection" msgid "all" msgstr "tous" msgid "Use in favorites menu" msgstr "Utiliser dans le menu favoris" msgid "Use as search timer" msgstr "Utiliser la recherche" msgid "user defined" msgstr "Définis par l'utilisateur" msgid "from date" msgstr "à partir de la date" msgid "to date" msgstr "à ce jour" msgid "Record" msgstr "Enregistre" msgid "Announce only" msgstr "Annoncer seulement le début de l'émission" msgid "Switch only" msgstr "Seulement changer de chaine" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Enregistrement de série" msgid "Delete recordings after ... days" msgstr "Effacer l'enregistrement après ... jours" msgid "Keep ... recordings" msgstr "Garder .... les enregistrements" msgid "Pause when ... recordings exist" msgstr "Pause, lorsque ... l'enregistrement existe." msgid "Avoid repeats" msgstr "Eviter les répétitions" msgid "Allowed repeats" msgstr "Répétitions autorisées" msgid "Only repeats within ... days" msgstr "Que répétition, pendant ... jours" msgid "Compare title" msgstr "Comparer titres" msgid "Compare subtitle" msgstr "Comparer les sous-titres" msgid "if present" msgstr "" msgid "Compare summary" msgstr "Comparer les descriptions" msgid "Compare" msgstr "Comparer" msgid "Use VPS" msgstr "Utiliser VPS" msgid "Auto-delete search timer" msgstr "Auto-suppression de programmation de recherche" msgid "after ... recordings" msgstr "après ... enregistrements" msgid "after ... days after first rec." msgstr "après ... jours après le premier enregistrement" msgid "Switch ... minutes before start" msgstr "Changer ... minutes avant le début" msgid "Test" msgstr "Tester" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "N'a pas pu trouver la programmation. Peut-être vous avez une erreur dans votre requête?" msgid "Please set a title for the timer!" msgstr "Veuillez indiquer un titre pour la programmation!" msgid "Edit timer" msgstr "Editer la programmation" msgid "New timer" msgstr "Nouvelle programmation" msgid "Weekday" msgstr "Jour de la semaine" #, fuzzy msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "N'a pas pu trouver la programmation. Peut-être vous avez une erreur dans votre requête?" msgid "This user name is already in use!" msgstr "" #, fuzzy msgid "Edit user" msgstr "Editer la programmation" #, fuzzy msgid "New user" msgstr "Nouvelle programmation" msgid "Password" msgstr "Mot de passe" #, fuzzy msgid "User rights" msgstr "Utilisateur" #, fuzzy msgid "Edit setup" msgstr "Editer la programmation" #, fuzzy msgid "Add or edit timers" msgstr "Editer la programmation" #, fuzzy msgid "Delete timers" msgstr "Effacer la programmation" #, fuzzy msgid "Delete recordings" msgstr "Enregistrement de série" #, fuzzy msgid "Use remote menu" msgstr "Utiliser dans le menu favoris" #, fuzzy msgid "Start replay" msgstr "Page de départ" #, fuzzy msgid "Switch channel" msgstr "Changer vers cette chaîne. " #, fuzzy msgid "Add or edit search timers" msgstr "Editer l'expression de recherche" #, fuzzy msgid "Delete search timers" msgstr "Effacer la programmation de recherche" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "Guide électronique d'information des programmes EPG" msgid "Couldn't find recording or no recordings available" msgstr "Impossible de trouver un enregistrement ou aucun enregistrements disponibles" msgid "Error aquiring schedules lock" msgstr "Erreur lors de l'acquisition du verrouillage de programmation de recherche" msgid "Error aquiring schedules" msgstr "Erreur lors de l'acquisition de programmation" msgid "%b %d %y" msgstr "%d.%m.%y" msgid "Page error" msgstr "Erreur de paging" msgid "playing recording" msgstr "Lire l'enregistrement" msgid "no epg info for current event!" msgstr "Pas d'infos pour l'émission!" msgid "no epg info for current channel!" msgstr "Cette chaîne n'a pas d'EPG!" msgid "no current channel!" msgstr "pas de chaîne trouvé!" msgid "error retrieving status info!" msgstr "erreur de récupération du statut d'info!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Nom de l'utilisateur ou mot de passei sont erroné" msgid "Login" msgstr "Session" msgid "VDR Live Login" msgstr "Session VDR Live" msgid "User" msgstr "Utilisateur" msgid "What's on?" msgstr "Actuellement?" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "Recherche" msgid "Searchtimers" msgstr "Recherche de programmation" msgid "Recordings" msgstr "Enregistrements" msgid "Remote Control" msgstr "Télécommande du VDR" msgid "Logout" msgstr "Fin de session" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "maintenant" msgid "%A, %b %d %Y" msgstr "%A, %d.%m.%Y" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "Changer vers cette chaîne. " msgid "Search for repeats." msgstr "Recherche de répétitions." msgid "Click to view details." msgstr "Clic pour voire les détails." msgid "more" msgstr "plus" msgid "Channel" msgstr "Chaîne" msgid "Find more at the Internet Movie Database." msgstr "Trouver plus d'information du film dans la base de données film IMDB." msgid "Stream this channel into browser." msgstr "Diffusez cette chaîne vers le navigateur." #, fuzzy msgid "Stream this recording into browser." msgstr "Diffusez cette chaîne vers le navigateur." msgid "Record this" msgstr "Enregistrer cette émission" msgid "loading data" msgstr "Chargement des données" msgid "an error occured!" msgstr "Une erreur s'est produite!" msgid "Request succeeded!" msgstr "Demande réussi!" msgid "Request failed!" msgstr "Échec de la requête!" msgid "January" msgstr "Janvier" msgid "February" msgstr "Février" msgid "March" msgstr "Mars" msgid "April" msgstr "Avril" msgid "May" msgstr "Mai" msgid "June" msgstr "Juin" msgid "July" msgstr "Juillet" msgid "August" msgstr "Août" msgid "September" msgstr "Septembre" msgid "October" msgstr "Octobre" msgid "November" msgstr "Novembre" msgid "December" msgstr "Décembre" msgid "retrieving status ..." msgstr "mise à jours de l'état" msgid "Toggle updates on/off." msgstr "Activer/Désactiver l'update du status" msgid "stop playback" msgstr "arrêter la lecture" msgid "resume playback" msgstr "continuer" msgid "pause playback" msgstr "pause" msgid "fast rewind" msgstr "retour rapide" msgid "fast forward" msgstr "avance rapide" msgid "previous channel" msgstr "chaîne précédent" msgid "next channel" msgstr "Chaîne suivante" msgid "No server response!" msgstr "Pas de réponse du serveur!" msgid "Failed to update infobox!" msgstr "Échec de la mise à jour infobox!" msgid "Authors" msgstr "Auteur" #, fuzzy msgid "Project Idea" msgstr "Chef de projet" msgid "Webserver" msgstr "Serveur Web" msgid "Project leader" msgstr "Chef de projet" msgid "Content" msgstr "Contenu" msgid "Graphics" msgstr "Graphiques" msgid "Information" msgstr "Information" msgid "LIVE version" msgstr "Version LIVE" msgid "VDR version" msgstr "Version VDR" msgid "Features" msgstr "Soutien des plugins" msgid "active" msgstr "actif" msgid "required" msgstr "requis" msgid "Homepage" msgstr "Page d'accueil" msgid "Bugs and suggestions" msgstr "Bogues et suggestions" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Si vous rencontrez n'importe quels bogue ou voudriez suggérer de nouveaux dispositifs, employer notre bugtracker svp" msgid "ERROR:" msgstr "ERREUR:" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "Liste des enregistrements" msgid "No recordings found" msgstr "Pas d'enregistrement" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "lire cette enregistrement." msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "N'a pas pu trouver la chaîne. Votre requête est t'elle corrête? " #, fuzzy msgid "Snapshot interval" msgstr "intervalle" msgid "No schedules available for this channel" msgstr "Aucune programmation disponible pour cette chaîne" msgid "Search settings" msgstr "Règlages de recherche" msgid "Extended search" msgstr "Recherche étendue" msgid "no" msgstr "non" msgid "Search results" msgstr "Résultats" msgid "No search results" msgstr "pas de résultat de recherche" msgid "Expression" msgstr "Expression de recherche" msgid "Starts between" msgstr "Départ entre" msgid "Toggle search timer actions (in)active" msgstr "Actions de la programmation de recherche (in)actives" msgid "Browse search timer results" msgstr "Passer en revue les résultats de programmation de recherche" msgid "Delete this search timer?" msgstr "Effacer cette programmation de recherche?" msgid "Delete search timer" msgstr "Effacer la programmation de recherche" msgid "Trigger search timer update" msgstr "Mise à jour des recherches de programmation maintenant" msgid "Please set login and password!" msgstr "Entrée le nom d'utilisateur et le mot de passe svp!" msgid "Setup saved." msgstr "Paramètre sauvegardé" msgid "Setup" msgstr "Configuration" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "Réseau local (non requis)" msgid "Show live logo image" msgstr "Afficher l'image du logo de live" msgid "Use ajax technology" msgstr "Utilisez la technologie Ajax" msgid "Show dynamic VDR information box" msgstr "Voir la boîte d'information dynamique VDR" msgid "Allow video streaming" msgstr "Permettez-streaming vidéo" msgid "Streamdev server port" msgstr "Port du serveur streamdev" msgid "Streamdev stream type" msgstr "Type du serveur streamdev" msgid "Add links to IMDb" msgstr "Ajouter des liens vers IMDb" msgid "Additional fixed times in 'What's on?'" msgstr "périodes fixes additionnelles dans 'actuellement?'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Le format est HH:MM . Plusieurs périodes séparées avec un point-virgule" #, fuzzy msgid "Channel groups for MultiSchedule" msgstr "La chaîne n'a pas de programmation" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "Page de départ" msgid "Theme" msgstr "Thème" #, fuzzy msgid "Timer conflicts" msgstr "Programmation est active." #, fuzzy msgid "No timer conflicts" msgstr "Programmation est active." #, fuzzy msgid "Timer has a conflict." msgstr "Programmation est active." msgid "Timer is active." msgstr "Programmation est active." msgid "Toggle timer active/inactive" msgstr "Programmation basculer actif/inactif" msgid "Delete timer" msgstr "Effacer la programmation" msgid "No timer defined" msgstr "Aucune programmation définie" msgid "Timer is recording." msgstr "Enregistrement de série" #, fuzzy msgid "Users" msgstr "Utilisateur" #, fuzzy msgid "Delete user" msgstr "Effacer la programmation" msgid "VLC: live video stream" msgstr "VLC: live vidéo stream" #, fuzzy msgid "VLC: play recording" msgstr "Lire l'enregistrement" msgid "Stop" msgstr "Stop" msgid "Play" msgstr "Lecture" msgid "Sound on" msgstr "Son" msgid "Sound off" msgstr "Coupure du son" msgid "Fullscreen" msgstr "Plein écran" msgid "Close" msgstr "fermer" msgid "VLC media URL" msgstr "VLC lien média " #, fuzzy, c-format msgid "%a, %x" msgstr "%A, %x" #, fuzzy msgid "What's running on" msgstr "Qu'y a t'il au programme vers" msgid "at" msgstr "à" msgid "What's on next?" msgstr "Quoi faire ensuite?" msgid "Favorites" msgstr "Favoris" msgid "View the schedule of this channel" msgstr "Regarder le programme de cette chaîne" msgid " - " msgstr "" msgid "Next" msgstr "prochainement" msgid "What's on" msgstr "Actuellement" msgid "Details view" msgstr "Vue détailée" msgid "List view" msgstr "Vue en liste" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" #, fuzzy #~ msgid "Subtitle" #~ msgstr "Titre" #, fuzzy #~ msgid "Please set a name and password for the user!" #~ msgstr "Entrée le nom d'utilisateur et le mot de passe svp!" #~ msgid "Interval" #~ msgstr "Intervalle" #~ msgid "Show schedule of channel" #~ msgstr "Montrer le programme de la chaîne" #~ msgid "%a, %b %d" #~ msgstr "%a, %d.%m." #, fuzzy #~ msgid "Stream into browser" #~ msgstr "Diffusez cette chaîne vers le navigateur." #~ msgid "Edit this" #~ msgstr "Changer cette programmation" #, fuzzy #~ msgid "Start" #~ msgstr "Page de départ" #, fuzzy #~ msgid "File" #~ msgstr "Titre" vdr-plugin-live/po/tr_TR.po0000644000175000017500000003053312650773437015460 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Oktay Yolgeçen , 2007 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-01-15 19:12+0100\n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Oktay Yolgeçen \n" "Language-Team: \n" "Language: tr_TR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-9\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/cs_CZ.po0000644000175000017500000004401512650773437015427 0ustar tobiastobias# translation of cs_CZ.po to # VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR-LIVE package. # Vladimr Brta , 2006 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2010-05-10 22:15+0200\n" "Last-Translator: Vladimír Bárta ,Radek Stastny \n" "Language-Team: see developers in README\n" "Language: cs_CZ\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Poslední zobrazovaný kanál" msgid "No limit" msgstr "Bez limitu" msgid "Use authentication" msgstr "Použít autentifikaci" msgid "No" msgstr "Ne" msgid "Yes" msgstr "Ano" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "Admin heslo" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "Nahrávání" msgid "Error in timer settings" msgstr "Chyba v nastavení nahrávání" msgid "Timer already defined" msgstr "Nahrávaní již nastaveno" msgid "Timers are being edited - try again later" msgstr "Nahrávaní nÄ›kdo mÄ›ní - zkuste pozdÄ›ji" msgid "Timer not defined" msgstr "Nahrávaní není nastaveno" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "Kanál neexistuje, nebo je nedostupný." msgid "Couldn't switch to channel." msgstr "Nelze pÅ™epnout na kanál." msgid "Couldn't find recording or no recordings available." msgstr "Nelze nalézt nahrávky, nebo žádné neexistují" msgid "Cannot control playback!" msgstr "PÅ™ehrávaní nelze ovládat!" msgid "Not playing a recording." msgstr "NepÅ™ehrává se nahrávka." msgid "Not playing the same recording as from request." msgstr "NepÅ™ehrává se požadovaná nahrávka." msgid "Attempt to delete recording currently in playback." msgstr "Pokus o smazání sledované nahrávky" msgid "Epg error" msgstr "Chyba EPG" msgid "Wrong channel id" msgstr "Å patné Äíslo kanálu" msgid "Channel has no schedule" msgstr "Kanál nemá žádný program" msgid "Wrong event id" msgstr "Chybné id poÅ™adu" msgid "Required minimum version of epgsearch: " msgstr "PotÅ™ebná minimální verze epgsearch: " msgid "All" msgstr "VÅ¡e" msgid "FTA" msgstr "FTA" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "Verze EPGSearch je zastaralá! Použijte novÄ›jší." msgid "Couldn't aquire primary device" msgstr "Nelze otevřít primární zarízení" msgid "Couldn't grab image from primary device" msgstr "Nelze získat obrázek z primárního zařízení" msgid "Timer conflict check detected " msgstr "" #, fuzzy msgid "conflict" msgstr "Nahrávání bez kolize" #, fuzzy msgid "conflicts" msgstr "Nahrávání bez kolize" msgid "Couldn't aquire access to channels, please try again later." msgstr "Nelze získat přístup k programům, zkuste pozdÄ›ji." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Bohužel chybÄ›jící oprávnÄ›ní. Zeptejte se svého administrátora!" #, fuzzy msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Nelze nalézt zadaného uživatele. Byl zadán správnÄ›?" #, fuzzy msgid "Please set a name for the recording!" msgstr "Prosím nastavte název nahrávání!" msgid "Cannot copy, rename or move the recording." msgstr "" #, fuzzy msgid "Edit recording" msgstr "Seznam nahrávek" msgid "Name" msgstr "Jméno" msgid "Directory" msgstr "Složka" #, fuzzy msgid "Delete resume information" msgstr "Elektronický průvodce programem (EPG)" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" #, fuzzy msgid "Short description" msgstr "Popis" msgid "Description" msgstr "Popis" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "Uložit" msgid "Cancel" msgstr "ZruÅ¡it" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Nelze najít Automatické nahrávání. Byl požadavek správnÄ› zadán?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd.mm.yyyy" msgid "Edit search timer" msgstr "ZmÄ›na automatického nahrávaní" msgid "New search timer" msgstr "Nové automatické nahrávání" msgid "Search text too short - use anyway?" msgstr "Zadaný text je krátký - opravdu použít?" msgid "Search term" msgstr "Vyhledej" msgid "Search mode" msgstr "Vyhledávací režim" msgid "phrase" msgstr "slovní spojení" msgid "all words" msgstr "vÅ¡echna slova" msgid "at least one word" msgstr "alespoň jedno slovo" msgid "match exactly" msgstr "pÅ™esný výraz" msgid "regular expression" msgstr "regulární výraz" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "Tolerance" msgid "Match case" msgstr "Velikost písmen" msgid "Search in" msgstr "Vyhledávat v" msgid "Title" msgstr "Název" msgid "Episode" msgstr "Epizoda" msgid "Use extended EPG info" msgstr "Použít rozšířené EPG" msgid "Ignore missing EPG info" msgstr "Ignorovat chybÄ›jící EPG" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Toto nastavení vytvoří mnoho požadavků na nahrávání. PÅ™ed uložením oveÅ™te chování pomocí Testu!" msgid "Use channel" msgstr "Použij kanál" msgid "interval" msgstr "" msgid "channel group" msgstr "skupina kanálů" msgid "only FTA" msgstr "Pouze FTA" msgid "from channel" msgstr "od kanálu" msgid "to channel" msgstr "do kanálu" msgid "Use time" msgstr "Použij Äas" msgid "Start after" msgstr "ZaÄíná po" msgid "The time the show may start at the earliest" msgstr "ÄŒas, kdy může zaÄít nejdříve." msgid "Start before" msgstr "ZaÄíná pÅ™ed" msgid "The time the show may start at the latest" msgstr "ÄŒas, kdy může zaÄít nejpozdÄ›ji" msgid "Use duration" msgstr "Použij délku" msgid "Min. duration" msgstr "délka min." msgid "Max. duration" msgstr "délka max." msgid "Use day of week" msgstr "Použij den v týdnu" msgid "Monday" msgstr "PondÄ›lí" msgid "Tuesday" msgstr "Úterý" msgid "Wednesday" msgstr "StÅ™eda" msgid "Thursday" msgstr "ÄŒtvrtek" msgid "Friday" msgstr "Pátek" msgid "Saturday" msgstr "Sobota" msgid "Sunday" msgstr "NedÄ›le" msgid "Use blacklists" msgstr "Použít blacklist" msgid "Selection" msgstr "výbÄ›r" msgid "all" msgstr "vÅ¡e" msgid "Use in favorites menu" msgstr "PÅ™idat do Oblíbených" msgid "Use as search timer" msgstr "Další podmínky vyhledávání" msgid "user defined" msgstr "ano - doÄasný" msgid "from date" msgstr "od data" msgid "to date" msgstr "do data" msgid "Record" msgstr "Nahrát" msgid "Announce only" msgstr "Pouze upozornit" msgid "Switch only" msgstr "PÅ™epnout" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Nahrávání seriálu" msgid "Delete recordings after ... days" msgstr "Vymazat nahrávky po ... dnech" msgid "Keep ... recordings" msgstr "Ponechat ... nahrávek" msgid "Pause when ... recordings exist" msgstr "Vynechat pokud existuje ... nahrávek" msgid "Avoid repeats" msgstr "Vynechávat reprízy" msgid "Allowed repeats" msgstr "Povolit reprízy" msgid "Only repeats within ... days" msgstr "Reprízy po ... dnech" msgid "Compare title" msgstr "Porovnávat název" msgid "Compare subtitle" msgstr "Porovnávat popis" msgid "if present" msgstr "pokud existuje" msgid "Compare summary" msgstr "Porovnávat popis" msgid "Compare" msgstr "Porovnat" msgid "Use VPS" msgstr "Použít VPS" msgid "Auto-delete search timer" msgstr "Smazání automatického nahrávání" msgid "after ... recordings" msgstr "po ... nahrávkách" msgid "after ... days after first rec." msgstr "po ... dnech po první nahrávce" msgid "Switch ... minutes before start" msgstr "PÅ™epnout ... minut pÅ™ed zaÄátkem" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Nelze najít nahrávaní. Je správnÄ› zadáno?" msgid "Please set a title for the timer!" msgstr "Prosím nastavte název nahrávání!" msgid "Edit timer" msgstr "ZmÄ›na nahrávání" msgid "New timer" msgstr "Nové nahrávání" msgid "Weekday" msgstr "Den v týdnu" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Nelze nalézt zadaného uživatele. Byl zadán správnÄ›?" msgid "This user name is already in use!" msgstr "Toto jméno již použito!" msgid "Edit user" msgstr "ZmÄ›na uživatele" msgid "New user" msgstr "Nový uživatel" msgid "Password" msgstr "Heslo" msgid "User rights" msgstr "OprávnÄ›ní" msgid "Edit setup" msgstr "MÄ›nit nastavení" msgid "Add or edit timers" msgstr "Nastavení nahrávání" msgid "Delete timers" msgstr "RuÅ¡ení nahrávání" msgid "Delete recordings" msgstr "Mazání nahrávek" msgid "Use remote menu" msgstr "Menu dálkového ovládání" msgid "Start replay" msgstr "PÅ™ehrávání" msgid "Switch channel" msgstr "PÅ™epínání" msgid "Add or edit search timers" msgstr "Nastavení aut. nahrávání" msgid "Delete search timers" msgstr "Mazání aut. nahrávání" #, fuzzy msgid "Edit recordings" msgstr "Seznam nahrávek" msgid "Electronic program guide information" msgstr "Elektronický průvodce programem (EPG)" msgid "Couldn't find recording or no recordings available" msgstr "Nelze nalézt nahrávky, nebo žádné neexistují" msgid "Error aquiring schedules lock" msgstr "Chyba pÅ™i vytváření zámku pro nahrávky" msgid "Error aquiring schedules" msgstr "Chyba pÅ™i plánování" msgid "%b %d %y" msgstr "%d.%m." msgid "Page error" msgstr "Chyba stránky" msgid "playing recording" msgstr "sledování nahrávky" msgid "no epg info for current event!" msgstr "chybí detaily pro tento poÅ™ad" msgid "no epg info for current channel!" msgstr "chybí program pro tento kanál" msgid "no current channel!" msgstr "není zvolen žádný kanál" msgid "error retrieving status info!" msgstr "chyba pÅ™i zjišťování statusu!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Chybné jméno, nebo heslo" msgid "Login" msgstr "pÅ™ihlásit" msgid "VDR Live Login" msgstr "VDR Live autorizace" msgid "User" msgstr "Uživatel" msgid "What's on?" msgstr "PrávÄ› se vysílá" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "Vyhledej" msgid "Searchtimers" msgstr "Automatické nahrávání" msgid "Recordings" msgstr "Nahrávky" msgid "Remote Control" msgstr "Dálkové ovládání" msgid "Logout" msgstr "Odhlášení" msgid "Your attention is required" msgstr "Nutná reakce" msgid "React" msgstr "Å™eÅ¡it" msgid "Dismiss" msgstr "neÅ™eÅ¡it" msgid "Now" msgstr "Nyní" msgid "%A, %b %d %Y" msgstr "%a, %d.%m. " msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "PÅ™epnout" msgid "Search for repeats." msgstr "Vyhledat reprízy" msgid "Click to view details." msgstr "Detaily" msgid "more" msgstr "více" msgid "Channel" msgstr "Kanál" msgid "Find more at the Internet Movie Database." msgstr "Vyhledej více na Internet Movie Database." msgid "Stream this channel into browser." msgstr "PÅ™ehrávej v prohlížeÄi" msgid "Stream this recording into browser." msgstr "PÅ™ehrávej tuto nahrávku v prohlížeÄi." msgid "Record this" msgstr "Nahrát" msgid "loading data" msgstr "aktualizace údajů" msgid "an error occured!" msgstr "problém!" msgid "Request succeeded!" msgstr "Požadevek úspěšný." msgid "Request failed!" msgstr "Požadavek selhal!" msgid "January" msgstr "leden" msgid "February" msgstr "únor" msgid "March" msgstr "bÅ™ezen" msgid "April" msgstr "duben" msgid "May" msgstr "kvÄ›ten" msgid "June" msgstr "Äerven" msgid "July" msgstr "Äervenec" msgid "August" msgstr "srpen" msgid "September" msgstr "září" msgid "October" msgstr "říjen" msgid "November" msgstr "listopad" msgid "December" msgstr "prosinec" msgid "retrieving status ..." msgstr "zjišťování stavu..." msgid "Toggle updates on/off." msgstr "aktualizovat zmÄ›ny ano/ne." msgid "stop playback" msgstr "ukonÄit pÅ™ehrávání" msgid "resume playback" msgstr "pokraÄovat v pÅ™ehrávání" msgid "pause playback" msgstr "pÅ™eruÅ¡it pÅ™ehrávání" msgid "fast rewind" msgstr "rychle zpÄ›t" msgid "fast forward" msgstr "rychle vpÅ™ed" msgid "previous channel" msgstr "pÅ™edchozí kanál" msgid "next channel" msgstr "další kanál" msgid "No server response!" msgstr "Server neodpovídá!" msgid "Failed to update infobox!" msgstr "Aktualizace infookna selhala!" msgid "Authors" msgstr "AutoÅ™i" msgid "Project Idea" msgstr "nápad" msgid "Webserver" msgstr "web server" msgid "Project leader" msgstr "vedoucí týmu" msgid "Content" msgstr "obsah" msgid "Graphics" msgstr "grafika" msgid "Information" msgstr "Informace" msgid "LIVE version" msgstr "LIVE verze" msgid "VDR version" msgstr "VDR verze" msgid "Features" msgstr "Moduly" msgid "active" msgstr "aktivní" msgid "required" msgstr "vyżadováno" msgid "Homepage" msgstr "Domovská stránka" msgid "Bugs and suggestions" msgstr "Chyby a pÅ™ipomínky" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Pokud odhalíte nÄ›jaké chyby, příp. si pÅ™ejete nové vlastnosti, použijte prosím bugtracker" msgid "ERROR:" msgstr "CHYBA:" msgid "Deleted recording:" msgstr "Smazaná nahrávka:" msgid "List of recordings" msgstr "Seznam nahrávek" msgid "No recordings found" msgstr "žádné nahrávky" #, fuzzy msgid "Delete selected" msgstr "Smazat automatické nahrávání?" #, fuzzy, no-c-format msgid "%a," msgstr "%a, %x" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" #, fuzzy msgid "Sort by date" msgstr "do data" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "Smazat nahrávku!" msgid "play this recording." msgstr "PÅ™ehrát nahrávku" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Kanál je nedostupný, nebo neexistuje. Zkontrolujte zadání." msgid "Snapshot interval" msgstr "Interval snímků obrazovky" msgid "No schedules available for this channel" msgstr "Pro kanál není dostupný program" msgid "Search settings" msgstr "Nastavení hledání" msgid "Extended search" msgstr "Rozšířené hledání" msgid "no" msgstr "ne" msgid "Search results" msgstr "Výsledky vyhledávání" msgid "No search results" msgstr "žádné výsledky vyhledávání" msgid "Expression" msgstr "Výraz" msgid "Starts between" msgstr "ZaÄíná mezi" msgid "Toggle search timer actions (in)active" msgstr "(De)Aktivace automatického nahrávání" msgid "Browse search timer results" msgstr "Listování výsledky vyhledávání" msgid "Delete this search timer?" msgstr "Smazat automatické nahrávání?" msgid "Delete search timer" msgstr "Smazat automatické nahrávání?" msgid "Trigger search timer update" msgstr "Aktualizovat položky nahrávání" msgid "Please set login and password!" msgstr "Nastavte uživatele a heslo!" msgid "Setup saved." msgstr "Nastavení uloženo." msgid "Setup" msgstr "Nastavení" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "Lokální síť (bez pÅ™ilášení)" msgid "Show live logo image" msgstr "Zobrazit logo" msgid "Use ajax technology" msgstr "Používat dynamické stránky (ajax)" msgid "Show dynamic VDR information box" msgstr "Použít dynamický blok informací" msgid "Allow video streaming" msgstr "Povolit streamování videa" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "Streamdev typ streamu" msgid "Add links to IMDb" msgstr "PÅ™idat odkazy k IMDb" #, fuzzy msgid "Additional fixed times in 'What's on?'" msgstr "PÅ™idat Äasy pro zobrazení v \"PrávÄ› se vysílá\"" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Formát je HH:MM. OddÄ›lte více Äasů stÅ™edníkem" #, fuzzy msgid "Channel groups for MultiSchedule" msgstr "Kanál nemá žádný program" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "Startovací stránka" msgid "Theme" msgstr "Téma" #, fuzzy msgid "Timer conflicts" msgstr "Nahrávání bez kolize" msgid "No timer conflicts" msgstr "Nahrávání bez kolize" msgid "Timer has a conflict." msgstr "Kolize v nastavení nahrávání" msgid "Timer is active." msgstr "Nahrávaní povoleno" msgid "Toggle timer active/inactive" msgstr "Povolit/zruÅ¡it nahrávání" msgid "Delete timer" msgstr "ZruÅ¡it nahrávání!" msgid "No timer defined" msgstr "Nahrávání není nastaveno" msgid "Timer is recording." msgstr "Probíhá nahrávání" msgid "Users" msgstr "Uživatelé" msgid "Delete user" msgstr "Smazat uživatele" msgid "VLC: live video stream" msgstr "VLC: stream běžícího vysílání" msgid "VLC: play recording" msgstr "VLC: streamování nahrávky" msgid "Stop" msgstr "" msgid "Play" msgstr "PÅ™ehrávat" msgid "Sound on" msgstr "Se zvukem" msgid "Sound off" msgstr "Bez zvuku" msgid "Fullscreen" msgstr "Celá obrazovka" msgid "Close" msgstr "Zavřít" msgid "VLC media URL" msgstr "VLC adresa" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "Co právÄ› bÄ›zí v " msgid "at" msgstr " " msgid "What's on next?" msgstr "Co běží potom?" msgid "Favorites" msgstr "Oblíbené" msgid "View the schedule of this channel" msgstr "Zobraz program kanálu" msgid " - " msgstr "" msgid "Next" msgstr "Další" msgid "What's on" msgstr "Co poběží v" msgid "Details view" msgstr "Detailní pohled" msgid "List view" msgstr "Souhrný pohled" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "Nejsou dostupné informace o programu" vdr-plugin-live/po/nn_NO.po0000644000175000017500000003054412650773437015437 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Jørgen Tvedt , 2001 # Truls Slevigen , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Truls Slevigen \n" "Language-Team: see developers in README\n" "Language: nn_NO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Ta opp" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/de_DE.po0000644000175000017500000004553712650773437015400 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Klaus Schmiedinger , 2003 # Christian Wieniger , 2007 # Dieter Hametner , 2007 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Dieter Hametner \n" "Language-Team: see developers in README\n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "EPG-Anzeige bis Kanal" msgid "No limit" msgstr "Alle zeigen" msgid "Use authentication" msgstr "Authentifizierung nutzen" msgid "No" msgstr "Nein" msgid "Yes" msgstr "Ja" msgid "Admin login" msgstr "Admin Login" msgid "Admin password" msgstr "Admin Passwort" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "Suchtimer" msgid "Error in timer settings" msgstr "Fehler in den Timer Einstellungen" msgid "Timer already defined" msgstr "Timer ist bereits vorhanden" msgid "Timers are being edited - try again later" msgstr "Timer werden bearbeitet - später nochmal versuchen" msgid "Timer not defined" msgstr "Timer wurde nicht erstellt" msgid "On archive DVD No." msgstr "Auf Archiv-DVD Nr." msgid "On archive HDD No." msgstr "Auf Archiv-HDD Nr." msgid "Couldn't find channel or no channels available." msgstr "Kann das Programm nicht finden oder keine vorhanden." msgid "Couldn't switch to channel." msgstr "Kann nicht zu dem Programm umschalten." msgid "Couldn't find recording or no recordings available." msgstr "Kann die Aufnahme nicht finden oder keine Aufnahmen vorhanden." msgid "Cannot control playback!" msgstr "Kann die Wiedergabe nicht steuern." msgid "Not playing a recording." msgstr "Es wird keine Aufnahme abgespielt." msgid "Not playing the same recording as from request." msgstr "Es wird nicht die selbe Aufnahme abgespielt." msgid "Attempt to delete recording currently in playback." msgstr "Versuch die gerade abgepielte Aufnahme zu löschen." msgid "Epg error" msgstr "EPG Fehler" msgid "Wrong channel id" msgstr "Fehlerhafte Kanal Id" msgid "Channel has no schedule" msgstr "Kanal hat keine Programminfos" msgid "Wrong event id" msgstr "Fehlerhafte Sendungs Id" msgid "Required minimum version of epgsearch: " msgstr "Benötigte Mindestversion von epgsearch: " msgid "All" msgstr "Alle" msgid "FTA" msgstr "FTA" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "EPGSearch-Version zu alt, bitte updaten!" msgid "Couldn't aquire primary device" msgstr "Konnte auf das 'primary device' nicht zugreifen" msgid "Couldn't grab image from primary device" msgstr "Konnte kein Bild vom 'primary device' bekommen" msgid "Timer conflict check detected " msgstr "Die Timer Konflikt Überprüfung hat " msgid "conflict" msgstr "Timerkonflikt entdeckt" msgid "conflicts" msgstr "Timerkonflikte entdeckt" msgid "Couldn't aquire access to channels, please try again later." msgstr "Zugriff auf die Kanäle wurde verweigert. Bitte später versuchen." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Leider nicht erlaubt. Bitte kontaktieren Sie Ihren Administrator!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Konnte die Aufnahme nicht finden. Möglicherweise ein Tippfehler in der Anfrage?" msgid "Please set a name for the recording!" msgstr "Bitte einen Namen für die Aufnahme setzen!" msgid "Cannot copy, rename or move the recording." msgstr "Konnte die Aufnahme nicht umbenennen oder verschieben." msgid "Edit recording" msgstr "Aufnahme editieren" msgid "Name" msgstr "Name" msgid "Directory" msgstr "Verzeichnis" msgid "Delete resume information" msgstr "Wiedergabeposition löschen" msgid "Delete marks information" msgstr "Schnittmarken löschen" msgid "Copy only" msgstr "Nur kopieren" msgid "Short description" msgstr "Kurzbeschreibung" msgid "Description" msgstr "Beschreibung" msgid "Auxiliary info" msgstr "Zusätzliche Infos" msgid "Save" msgstr "Speichern" msgid "Cancel" msgstr "Abbrechen" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Keinen Suchtimer gefunden. Möglicherweise ein Tippfehler in der Anfrage?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd.mm.yyyy" msgid "Edit search timer" msgstr "Suchtimer bearbeiten" msgid "New search timer" msgstr "Neuen Suchtimer anlegen" msgid "Search text too short - use anyway?" msgstr "Suchtext zu kurz - trotzdem verwenden?" msgid "Search term" msgstr "Suchbegriff" msgid "Search mode" msgstr "Suchmodus" msgid "phrase" msgstr "Ausdruck" msgid "all words" msgstr "alle Worte" msgid "at least one word" msgstr "ein Wort" msgid "match exactly" msgstr "exakt" msgid "regular expression" msgstr "regulärer Ausdruck" msgid "fuzzy" msgstr "unscharf" msgid "Tolerance" msgstr "Toleranz" msgid "Match case" msgstr "Groß/klein" msgid "Search in" msgstr "Suche in" msgid "Title" msgstr "Titel" msgid "Episode" msgstr "Episode" msgid "Use extended EPG info" msgstr "Verw. erweiterte EPG Info" msgid "Ignore missing EPG info" msgstr "Ignoriere fehlende EPG Info" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Diese Einstellung kann bei Aktivierung sehr viele Timer erzeugen. Also bitte immer zuerst die Suche testen, bevor sie als Suchtimer verwendet wird!" msgid "Use channel" msgstr "Verw. Kanal" msgid "interval" msgstr "Bereich" msgid "channel group" msgstr "Kanalgruppe" msgid "only FTA" msgstr "ohne PayTV" msgid "from channel" msgstr "von Kanal" msgid "to channel" msgstr "bis Kanal" msgid "Use time" msgstr "Verw. Uhrzeit" msgid "Start after" msgstr "Start nach" msgid "The time the show may start at the earliest" msgstr "Die Zeit, zu der die Sendung frühestens anfangen darf" msgid "Start before" msgstr "Start vor" msgid "The time the show may start at the latest" msgstr "Die Zeit, zu der die Sendung spätestens angefangen haben muss" msgid "Use duration" msgstr "Verw. Dauer" msgid "Min. duration" msgstr "Min. Dauer" msgid "Max. duration" msgstr "Max. Dauer" msgid "Use day of week" msgstr "Verw. Wochentag" msgid "Monday" msgstr "Montag" msgid "Tuesday" msgstr "Dienstag" msgid "Wednesday" msgstr "Mittwoch" msgid "Thursday" msgstr "Donnerstag" msgid "Friday" msgstr "Freitag" msgid "Saturday" msgstr "Samstag" msgid "Sunday" msgstr "Sonntag" msgid "Use blacklists" msgstr "Verw. Ausschlusslisten" msgid "Selection" msgstr "Auswahl" msgid "all" msgstr "alle" msgid "Use in favorites menu" msgstr "In Favoritenmenü verw." msgid "Use as search timer" msgstr "Als Suchtimer verwenden" msgid "user defined" msgstr "benutzer-definiert" msgid "from date" msgstr "ab Datum" msgid "to date" msgstr "bis Datum" msgid "Record" msgstr "Aufnehmen" msgid "Announce only" msgstr "Nur ankündigen" msgid "Switch only" msgstr "Nur umschalten" msgid "Announce via email" msgstr "Mit E-Mail ankündigen" msgid "Series recording" msgstr "Serienaufnahme" msgid "Delete recordings after ... days" msgstr "Aufn. nach ... Tagen löschen" msgid "Keep ... recordings" msgstr "Behalte ... Aufnahmen" msgid "Pause when ... recordings exist" msgstr "Pause, wenn ... Aufnahmen exist." msgid "Avoid repeats" msgstr "Vermeide Wiederholung" msgid "Allowed repeats" msgstr "Erlaubte Wiederholungen" msgid "Only repeats within ... days" msgstr "Nur Wiederh. innerhalb ... Tagen" msgid "Compare title" msgstr "Vergleiche Titel" msgid "Compare subtitle" msgstr "Vergleiche Untertitel" msgid "if present" msgstr "wenn vorhanden" msgid "Compare summary" msgstr "Vergleiche Beschreibung" msgid "Compare" msgstr "Vergleiche" msgid "Use VPS" msgstr "VPS verwenden" msgid "Auto-delete search timer" msgstr "Suchtimer automatisch löschen" msgid "after ... recordings" msgstr "nach ... Aufnahmen" msgid "after ... days after first rec." msgstr "nach ... Tagen nach erster Aufnahme" msgid "Switch ... minutes before start" msgstr "Umschalten ... Minuten vor Start" msgid "Test" msgstr "Testen" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Konnte Timer nicht finden. Evtl. fehlerhafte Anforderung?" msgid "Please set a title for the timer!" msgstr "Bitte einen Titel fᅵr den Timer angeben!" msgid "Edit timer" msgstr "Timer bearbeiten" msgid "New timer" msgstr "Neuen Timer anlegen" msgid "Weekday" msgstr "Wochentag" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Konnte Benutzer nicht finden. Evtl. fehlerhafte Anforderung?" msgid "This user name is already in use!" msgstr "Dieser Benutzername wird bereits verwendet!" msgid "Edit user" msgstr "Benutzer bearbeiten" msgid "New user" msgstr "Neuen Benutzer anlegen" msgid "Password" msgstr "Passwort" msgid "User rights" msgstr "Benutzerrechte" msgid "Edit setup" msgstr "Einstellungen bearbeiten" msgid "Add or edit timers" msgstr "Timer hinzufügen oder ändern" msgid "Delete timers" msgstr "Timer löschen" msgid "Delete recordings" msgstr "Aufnahmen löschen" msgid "Use remote menu" msgstr "Menü Fernbedienung nutzen" msgid "Start replay" msgstr "Wiedergabe starten" msgid "Switch channel" msgstr "Zu diesem Kanal umschalten." msgid "Add or edit search timers" msgstr "Suchtimer hinzufügen oder ändern" msgid "Delete search timers" msgstr "Suchtimer löschen" msgid "Edit recordings" msgstr "Aufnahmen editieren" msgid "Electronic program guide information" msgstr "Elektronische Programminformation" msgid "Couldn't find recording or no recordings available" msgstr "Die Aufnahme nicht finden oder keine Aufnahmen vorhanden" msgid "Error aquiring schedules lock" msgstr "Fehler beim Zugriffschutz für die Programminfos" msgid "Error aquiring schedules" msgstr "Fehler beim Zugriff auf Programinfos" msgid "%b %d %y" msgstr "%d.%m.%y" msgid "Page error" msgstr "Seitenfehler" msgid "playing recording" msgstr "Wiedergabe" msgid "no epg info for current event!" msgstr "Keine Infos zur Sendung!" msgid "no epg info for current channel!" msgstr "Dieser Kanal hat kein EPG!" msgid "no current channel!" msgstr "Keinen Kanal gefunden!" msgid "error retrieving status info!" msgstr "Fehler: Status nicht verfügbar!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Falscher Benutzername oder Passwort" msgid "Login" msgstr "Anmelden" msgid "VDR Live Login" msgstr "VDR Live Login" msgid "User" msgstr "Benutzer" msgid "What's on?" msgstr "Was läuft?" msgid "MultiSchedule" msgstr "Zeitleiste" msgid "Search" msgstr "Suchen" msgid "Searchtimers" msgstr "Suchtimer" msgid "Recordings" msgstr "Aufnahmen" msgid "Remote Control" msgstr "Fernbedienung" msgid "Logout" msgstr "Abmelden" msgid "Your attention is required" msgstr "Ihre Aufmerksamkeit ist erforderlich" msgid "React" msgstr "Reagieren" msgid "Dismiss" msgstr "Verwerfen" msgid "Now" msgstr "Jetzt" msgid "%A, %b %d %Y" msgstr "%A, %d.%m.%Y" msgid "Time" msgstr "Zeit" msgid "Switch to this channel." msgstr "Zu diesem Kanal umschalten." msgid "Search for repeats." msgstr "Nach Wiederholungen suchen." msgid "Click to view details." msgstr "Für Details klicken." msgid "more" msgstr "mehr" msgid "Channel" msgstr "Kanal" msgid "Find more at the Internet Movie Database." msgstr "Weitere Informationen in der Internet Movie Database." msgid "Stream this channel into browser." msgstr "Sendung im Browser anzeigen." msgid "Stream this recording into browser." msgstr "Aufnahme im Browser anzeigen." msgid "Record this" msgstr "Diese Sendung aufnehmen" msgid "loading data" msgstr "Daten nachladen" msgid "an error occured!" msgstr "Es ist ein Fehler aufgetreten!" msgid "Request succeeded!" msgstr "Aktion durchgeführt!" msgid "Request failed!" msgstr "Aktion fehlgeschlagen!" msgid "January" msgstr "Januar" msgid "February" msgstr "Februar" msgid "March" msgstr "März" msgid "April" msgstr "April" msgid "May" msgstr "Mai" msgid "June" msgstr "Juni" msgid "July" msgstr "Juli" msgid "August" msgstr "August" msgid "September" msgstr "September" msgid "October" msgstr "Oktober" msgid "November" msgstr "November" msgid "December" msgstr "Dezember" msgid "retrieving status ..." msgstr "Hole Status ..." msgid "Toggle updates on/off." msgstr "Statusabfrage ein- oder ausschalten." msgid "stop playback" msgstr "Anhalten" msgid "resume playback" msgstr "Fortsetzen" msgid "pause playback" msgstr "Pause" msgid "fast rewind" msgstr "Suchlauf rückwärts" msgid "fast forward" msgstr "Suchlauf vorwärts" msgid "previous channel" msgstr "Sender zurück" msgid "next channel" msgstr "Sender vor" msgid "No server response!" msgstr "Der Server antwortet nicht!" msgid "Failed to update infobox!" msgstr "Kann Infobox nicht aktualisieren!" msgid "Authors" msgstr "Autoren" msgid "Project Idea" msgstr "Projekt Idee" msgid "Webserver" msgstr "Webserver" msgid "Project leader" msgstr "Projektleiter" msgid "Content" msgstr "Inhalte" msgid "Graphics" msgstr "Grafiken" msgid "Information" msgstr "Informationen" msgid "LIVE version" msgstr "LIVE Version" msgid "VDR version" msgstr "VDR Version" msgid "Features" msgstr "Unterstütze Plugins" msgid "active" msgstr "aktiv" msgid "required" msgstr "erforderlich" msgid "Homepage" msgstr "Homepage" msgid "Bugs and suggestions" msgstr "Fehlerberichte und Vorschläge" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Für Fehler oder Verbesserungsvorschläge steht unser Bugtracker bereit" msgid "ERROR:" msgstr "FEHLER:" msgid "Deleted recording:" msgstr "Gelöschte Aufnahme:" msgid "List of recordings" msgstr "Liste der Aufnahmen" msgid "No recordings found" msgstr "Keine Aufnahmen vorhanden" msgid "Delete selected" msgstr "Löschen" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "(%d:%02d)" msgid "Sort by name" msgstr "Sortiere nach Name" msgid "Sort by date" msgstr "Sortiere nach Datum" msgid "Filter" msgstr "Filter" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Suche in Aufnahme-Titel und Untertitel nach dem angegebenen Wort und zeige nur die zutreffenden an. Es sind auch Perl kompatible reguläre Ausdrücke (PCRE) erlaubt." msgid "Expand all folders" msgstr "Alle Ordner aufklappen" msgid "Collapse all folders" msgstr "Alle Ordner einklappen" msgid "Delete this recording from hard disc!" msgstr "Diese Aufnahme von der Festplatte löschen!" msgid "play this recording." msgstr "Diese Aufnahme abspielen." msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Konnte Kanal nicht finden oder keine Kanäle verfügbar. Ist die Anfrage korrekt?" msgid "Snapshot interval" msgstr "Snapshot-Intervall" msgid "No schedules available for this channel" msgstr "Für diesen Kanal liegen keine EPG-Informationen vor" msgid "Search settings" msgstr "Einstellungen zur Suche" msgid "Extended search" msgstr "Erweiterte Suche" msgid "no" msgstr "nein" msgid "Search results" msgstr "Suchergebnisse" msgid "No search results" msgstr "keine Suchergebnisse" msgid "Expression" msgstr "Suchbegriff" msgid "Starts between" msgstr "Beginnt zwischen" msgid "Toggle search timer actions (in)active" msgstr "Aktionen des Suchtimers (de)aktivieren" msgid "Browse search timer results" msgstr "Suchtimerergebnisse betrachten" msgid "Delete this search timer?" msgstr "Diesen Suchtimer löschen?" msgid "Delete search timer" msgstr "Suchtimer löschen" msgid "Trigger search timer update" msgstr "Suchtimer-Update starten" msgid "Please set login and password!" msgstr "Bitte Login und Passwort angeben!" msgid "Setup saved." msgstr "Einstellungen gespeichert." msgid "Setup" msgstr "Einstellungen" msgid "User management" msgstr "Benutzerverwaltung" msgid "Local net (no login required)" msgstr "Lokales Netz (keine Anmeldung notwendig)" msgid "Show live logo image" msgstr "Zeige das Live Logo" msgid "Use ajax technology" msgstr "Verwende AJAX Technologie" msgid "Show dynamic VDR information box" msgstr "Zeige dynamische VDR Status Box" msgid "Allow video streaming" msgstr "Erlaube Videoanzeige im Browser" msgid "Streamdev server port" msgstr "Streamdev Server Port" msgid "Streamdev stream type" msgstr "Streamdev Stream Typ" msgid "Add links to IMDb" msgstr "Füge Links zur IMDb hinzu" msgid "Additional fixed times in 'What's on?'" msgstr "Zusätzliche Zeitpunkte in 'Was läuft?'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Format ist HH:MM. Mehrere Zeiten durch Semikolon trennen" msgid "Channel groups for MultiSchedule" msgstr "Kanalgruppen für die Zeitleiste" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Trenne Kanäle mit Komma ',', trenne Kanalgruppen mit Semikolon ';'" msgid "Duration of MultiSchedule in hours" msgstr "Dauer der Zeitleiste in Stunden" msgid "Show channels without EPG" msgstr "Zeige Kanäle ohne EPG" msgid "Start page" msgstr "Startseite" msgid "Theme" msgstr "Thema" msgid "Timer conflicts" msgstr "Timer-Konflikte" msgid "No timer conflicts" msgstr "Keine Timer-Konflikte" msgid "Timer has a conflict." msgstr "Timer hat einen Konflikt." msgid "Timer is active." msgstr "Timer ist aktiv." msgid "Toggle timer active/inactive" msgstr "Timer aktiv/inaktiv schalten" msgid "Delete timer" msgstr "Timer löschen" msgid "No timer defined" msgstr "Keine Timer vorhanden" msgid "Timer is recording." msgstr "Timer zeichnet auf." msgid "Users" msgstr "Benutzer" msgid "Delete user" msgstr "Benutzer löschen" msgid "VLC: live video stream" msgstr "VLC: Video Stream" msgid "VLC: play recording" msgstr "VLC: Aufnahme abspielen" msgid "Stop" msgstr "Stopp" msgid "Play" msgstr "Wiedergabe" msgid "Sound on" msgstr "Ton an" msgid "Sound off" msgstr "Ton aus" msgid "Fullscreen" msgstr "Vollbild" msgid "Close" msgstr "Schließen" msgid "VLC media URL" msgstr "VLC Medien URL" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "Was läuft am" msgid "at" msgstr "um" msgid "What's on next?" msgstr "Was läuft als nächstes?" msgid "Favorites" msgstr "Favoriten" msgid "View the schedule of this channel" msgstr "Zeige Programm dieses Kanals" msgid " - " msgstr " - " msgid "Next" msgstr "als Nächstes" msgid "What's on" msgstr "Was läuft" msgid "Details view" msgstr "Ausführliche Ansicht" msgid "List view" msgstr "Listenansicht" msgid "Live Interactive VDR Environment" msgstr "Live Interactive VDR Environment" msgid "No EPG information available" msgstr "Keine EPG Daten vorhanden" #~ msgid "(%d')" #~ msgstr "%d'" #~ msgid "Show duration in 'Recordings'" #~ msgstr "Aufnahmedauer bei 'Aufnahmen' anzeigen" vdr-plugin-live/po/ro_RO.po0000644000175000017500000003060412650773437015445 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Paul Lacatus , 2002 # Lucian Muresan , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Lucian Muresan \n" "Language-Team: see developers in README\n" "Language: ro_RO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Înregistr." msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/ru_RU.po0000644000175000017500000005562112650773437015467 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Dmitrii Kiselev , 2013 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.3.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2013-06-21 20:15+0200\n" "Last-Translator: Dmitrii Kiselev \n" "Language-Team: see developers in README\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "ПоÑледний канал Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ" msgid "No limit" msgstr "Без ограничений" msgid "Use authentication" msgstr "Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" msgid "No" msgstr "Ðет" msgid "Yes" msgstr "Да" msgid "Admin login" msgstr "Ð˜Ð¼Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратора" msgid "Admin password" msgstr "Пароль админиÑтратора" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "ПоиÑковый таймер" msgid "Error in timer settings" msgstr "Ошибка в наÑтройках таймера" msgid "Timer already defined" msgstr "Таймер уÑтановлен" msgid "Timers are being edited - try again later" msgstr "Таймер редактируетÑÑ - попробуйте позже" msgid "Timer not defined" msgstr "Таймер не уÑтановлен" msgid "On archive DVD No." msgstr "Ð’ архиве на DVD No." msgid "On archive HDD No." msgstr "Ð’ архиве на HDD No." msgid "Couldn't find channel or no channels available." msgstr "Канал не найден или недоÑтупен." msgid "Couldn't switch to channel." msgstr "Переключение на канал невозможно." msgid "Couldn't find recording or no recordings available." msgstr "ЗапиÑÑŒ не найдена или более недоÑтупна." msgid "Cannot control playback!" msgstr "Управление воÑпроÑизведением недоÑтупно!" msgid "Not playing a recording." msgstr "ЗапиÑÑŒ не проигрываетÑÑ." msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "Ошибка телегида" msgid "Wrong channel id" msgstr "Ðеверный id канала" msgid "Channel has no schedule" msgstr "Ðет раÑпиÑÐ°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð°" msgid "Wrong event id" msgstr "Ошибка id ÑобытиÑ" msgid "Required minimum version of epgsearch: " msgstr "Минимальный Ñ‚Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº верÑии EPGSearch: " msgid "All" msgstr "Ð’Ñе" msgid "FTA" msgstr "Открытые" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "ВерÑÐ¸Ñ EPGSearch уÑтарела! ПожалуйÑта обновите EPGSearch. " msgid "Couldn't aquire primary device" msgstr "Ðет доÑтупа к оÑновному уÑтройÑтву" msgid "Couldn't grab image from primary device" msgstr "Ðе могу получить изображение Ñ Ð¾Ñновного уÑтройÑтва" msgid "Timer conflict check detected " msgstr "Обнаружен конфликт таймеров" msgid "conflict" msgstr "конфликт" msgid "conflicts" msgstr "конфликты" msgid "Couldn't aquire access to channels, please try again later." msgstr "Ðет доÑтупа к каналу, попробуйте позже" msgid "Sorry, no permission. Please contact your administrator!" msgstr "Ðет доÑтупа, обратитеÑÑŒ к админиÑтратору! " msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "ЗапиÑÑŒ не найдена. Проверьте правильноÑть запроÑа." msgid "Please set a name for the recording!" msgstr "ПожалуйÑта приÑвойте Ð¸Ð¼Ñ Ð·Ð°Ð¿Ð¸Ñи!" msgid "Cannot copy, rename or move the recording." msgstr "Копирование невозможно, переименуйте или перемеÑтите запиÑÑŒ. " msgid "Edit recording" msgstr "Изменить запиÑÑŒ." msgid "Name" msgstr "ИмÑ" msgid "Directory" msgstr "Каталог" msgid "Delete resume information" msgstr "Удалить информацию о воÑпроизведении" msgid "Delete marks information" msgstr "Удалить маркеры" msgid "Copy only" msgstr "Копировать" msgid "Short description" msgstr "Краткое опиÑание" msgid "Description" msgstr "ОпиÑание" msgid "Auxiliary info" msgstr "Другое" msgid "Save" msgstr "Сохранить" msgid "Cancel" msgstr "Отменить" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "ПоиÑковый таймер не найден. Проверьте правильноÑть запроÑа." #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd/mm/yyyy" msgid "Edit search timer" msgstr "Изменить поиÑковый таймер" msgid "New search timer" msgstr "Ðовый поиÑковый таймер" msgid "Search text too short - use anyway?" msgstr "ТекÑÑ‚ запроÑа Ñлишком короткий, продолжить?" msgid "Search term" msgstr "ПоиÑковый запроÑ" msgid "Search mode" msgstr "Метод поиÑка" msgid "phrase" msgstr "фраза" msgid "all words" msgstr "вÑе Ñлова" msgid "at least one word" msgstr "Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одно Ñлово" msgid "match exactly" msgstr "точное Ñовпадение" msgid "regular expression" msgstr "Ñтандартное выражение" msgid "fuzzy" msgstr "неопределенное" msgid "Tolerance" msgstr "ДопуÑтимое" msgid "Match case" msgstr "С учетом региÑтра" msgid "Search in" msgstr "ИÑкать в" msgid "Title" msgstr "Ðазвание" msgid "Episode" msgstr "Эпизод" msgid "Use extended EPG info" msgstr "РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑŽ телегида" msgid "Ignore missing EPG info" msgstr "Игнорировать отÑутÑтвие информации телегида" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Внимание! Проверьте поиÑковый таймер перед включением Ñтой функции. Это поможет избежать ошибочных запиÑей." msgid "Use channel" msgstr "Канал" msgid "interval" msgstr "интервал" msgid "channel group" msgstr "группа каналов" msgid "only FTA" msgstr "только открытые" msgid "from channel" msgstr "Ñ ÐºÐ°Ð½Ð°Ð»Ð°" msgid "to channel" msgstr "по канал" msgid "Use time" msgstr "ВремÑ" msgid "Start after" msgstr "ЗапуÑкать поÑле" msgid "The time the show may start at the earliest" msgstr "Программа может начатьÑÑ Ñ€Ð°Ð½ÑŒÑˆÐµ" msgid "Start before" msgstr "ЗапуÑкать до" msgid "The time the show may start at the latest" msgstr "Программа может начатьÑÑ Ð¿Ð¾Ð·Ð¶Ðµ" msgid "Use duration" msgstr "ПродолжительноÑть" msgid "Min. duration" msgstr "Мин. продолжительноÑть" msgid "Max. duration" msgstr "МакÑ. продолжительноÑть" msgid "Use day of week" msgstr "День недели" msgid "Monday" msgstr "Понедельник" msgid "Tuesday" msgstr "Вторник" msgid "Wednesday" msgstr "Среда" msgid "Thursday" msgstr "Четверг" msgid "Friday" msgstr "ПÑтница" msgid "Saturday" msgstr "Суббота" msgid "Sunday" msgstr "ВоÑкреÑенье" msgid "Use blacklists" msgstr "Черный ÑпиÑок" msgid "Selection" msgstr "Выбор" msgid "all" msgstr "вÑе" msgid "Use in favorites menu" msgstr "Ð’ избранное меню" msgid "Use as search timer" msgstr "ПоиÑковый таймер" msgid "user defined" msgstr "наÑтроить" msgid "from date" msgstr "Ñ Ð´Ð°Ñ‚Ñ‹" msgid "to date" msgstr "по дату" msgid "Record" msgstr "ЗапиÑÑŒ" msgid "Announce only" msgstr "Только объÑвлÑть" msgid "Switch only" msgstr "Только переключать" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "ЗапиÑÑŒ Ñерий" msgid "Delete recordings after ... days" msgstr "Удалить запиÑÑŒ поÑле … дней" msgid "Keep ... recordings" msgstr "Хранить запиÑÑŒ … дней" msgid "Pause when ... recordings exist" msgstr "ОÑтанавлить по доÑтижению … запиÑей" msgid "Avoid repeats" msgstr "Избегать повторов" msgid "Allowed repeats" msgstr "Разрешать повторы" msgid "Only repeats within ... days" msgstr "Разрешать повторы … дней" msgid "Compare title" msgstr "Сравнить название" msgid "Compare subtitle" msgstr "Сравнить Ñубтитры" msgid "if present" msgstr "еÑли еÑть" msgid "Compare summary" msgstr "Сравнить размер" msgid "Compare" msgstr "Сравнить" msgid "Use VPS" msgstr "VPS" msgid "Auto-delete search timer" msgstr "ÐвтоматичеÑки удалÑть поиÑковый таймер" msgid "after ... recordings" msgstr "поÑле … запиÑей" msgid "after ... days after first rec." msgstr "поÑле … дней поÑле первой запиÑи" msgid "Switch ... minutes before start" msgstr "ПереключатьÑÑ Ð·Ð° … минут до начала" msgid "Test" msgstr "ТеÑÑ‚" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Таймер не найден. Проверьте правильноÑть запроÑа." msgid "Please set a title for the timer!" msgstr "Введите название таймера" msgid "Edit timer" msgstr "Изменить таймер" msgid "New timer" msgstr "Ðовый таймер" msgid "Weekday" msgstr "День недели" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Пользователь не найден. Проверьте правильноÑть запроÑа." msgid "This user name is already in use!" msgstr "Это Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÐ¶Ðµ иÑпользуетÑÑ!" msgid "Edit user" msgstr "Изменить пользователÑ" msgid "New user" msgstr "Ðовый пользователь" msgid "Password" msgstr "Пароль" msgid "User rights" msgstr "Права пользователÑ" msgid "Edit setup" msgstr "ИзменÑть наÑтройки" msgid "Add or edit timers" msgstr "ДобавлÑть или изменÑть таймеры" msgid "Delete timers" msgstr "УдалÑть таймеры" msgid "Delete recordings" msgstr "УдалÑть запиÑи" msgid "Use remote menu" msgstr "Удаленное управление" msgid "Start replay" msgstr "Ðачинать воÑпроизведение" msgid "Switch channel" msgstr "Переключать каналы" msgid "Add or edit search timers" msgstr "ДобавлÑть или изменÑть поиÑковые таймеры" msgid "Delete search timers" msgstr "УдалÑть поиÑковые таймеры" msgid "Edit recordings" msgstr "ИзменÑть запиÑÑŒ" msgid "Electronic program guide information" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐ»ÐµÐ³Ð¸Ð´Ð°" msgid "Couldn't find recording or no recordings available" msgstr "ЗапиÑÑŒ не найдена или недоÑтупна" msgid "Error aquiring schedules lock" msgstr "Ошибка во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ€Ð°ÑпиÑаниÑ" msgid "Error aquiring schedules" msgstr "Ошибка в раÑпиÑании" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "Ошибка Ñтраницы" msgid "playing recording" msgstr "воÑпроизведение запиÑи" msgid "no epg info for current event!" msgstr "нет информации телегида о текущем Ñобытии!" msgid "no epg info for current channel!" msgstr "нет информации телегида на данном канале!" msgid "no current channel!" msgstr "нет канала!" msgid "error retrieving status info!" msgstr "ошибка при получении ÑтатуÑа" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Ðеправильное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ пароль" msgid "Login" msgstr "Вход" msgid "VDR Live Login" msgstr "VDR Live Login" msgid "User" msgstr "Пользователь" msgid "What's on?" msgstr "СейчаÑ" msgid "MultiSchedule" msgstr "МультираÑпиÑание" msgid "Search" msgstr "ПоиÑк" msgid "Searchtimers" msgstr "ПоиÑковый таймер" msgid "Recordings" msgstr "ЗапиÑи" msgid "Remote Control" msgstr "Удаленное управление" msgid "Logout" msgstr "Выход" msgid "Your attention is required" msgstr "ТребуетÑÑ Ð’Ð°ÑˆÐµ внимание" msgid "React" msgstr "Реагировать" msgid "Dismiss" msgstr "ОÑвободить" msgid "Now" msgstr "СейчаÑ" msgid "%A, %b %d %Y" msgstr "%A, %d.%m.%Y" msgid "Time" msgstr "ВремÑ" msgid "Switch to this channel." msgstr "ПереключитьÑÑ Ð½Ð° Ñтот канал." msgid "Search for repeats." msgstr "Ðайти повторы." msgid "Click to view details." msgstr "Ðажмите чтобы узнать больше." msgid "more" msgstr "еще" msgid "Channel" msgstr "Канал" msgid "Find more at the Internet Movie Database." msgstr "Ðайти на Kinopoisk.ru." msgid "Stream this channel into browser." msgstr "Стриминг Ñтого канала в браузер." msgid "Stream this recording into browser." msgstr "Стриминг Ñтой запиÑи в браузер." msgid "Record this" msgstr "ЗапиÑÑŒ." msgid "loading data" msgstr "загрузка данных" msgid "an error occured!" msgstr "обнаружена ошибка!" msgid "Request succeeded!" msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½!" msgid "Request failed!" msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ выполнен!" msgid "January" msgstr "Январь" msgid "February" msgstr "Февраль" msgid "March" msgstr "Март" msgid "April" msgstr "Ðпрель" msgid "May" msgstr "Май" msgid "June" msgstr "Июнь" msgid "July" msgstr "Июль" msgid "August" msgstr "ÐвгуÑÑ‚" msgid "September" msgstr "СентÑбрь" msgid "October" msgstr "ОктÑбрь" msgid "November" msgstr "ÐоÑбрь" msgid "December" msgstr "Декабрь" msgid "retrieving status ..." msgstr "получение ÑтатуÑа … " msgid "Toggle updates on/off." msgstr "Включить Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ on/off." msgid "stop playback" msgstr "оÑтановить воÑпроизведение" msgid "resume playback" msgstr "продолжить воÑпроизведение" msgid "pause playback" msgstr "пауза" msgid "fast rewind" msgstr "перемотка вперед" msgid "fast forward" msgstr "перемотка назад" msgid "previous channel" msgstr "предыдущий канал" msgid "next channel" msgstr "Ñледующий канал" msgid "No server response!" msgstr "Сервер не отвечает!" msgid "Failed to update infobox!" msgstr "Ошибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ infobox!" msgid "Authors" msgstr "Ðвторы" msgid "Project Idea" msgstr "Ð˜Ð´ÐµÑ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°" msgid "Webserver" msgstr "WEB Ñервер" msgid "Project leader" msgstr "Ведущий проекта" msgid "Content" msgstr "Содержание" msgid "Graphics" msgstr "Графика" msgid "Information" msgstr "ИнформациÑ" msgid "LIVE version" msgstr "ВерÑÐ¸Ñ LIVE" msgid "VDR version" msgstr "ВерÑÐ¸Ñ VDR" msgid "Features" msgstr "Опции" msgid "active" msgstr "активный" msgid "required" msgstr "требуетÑÑ" msgid "Homepage" msgstr "ДомашнÑÑ Ñтраница" msgid "Bugs and suggestions" msgstr "Ошибки и пожеланиÑ" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "ЕÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑƒÑ‚ ошибки или Ð’Ñ‹ хотите раÑширить функции LIVE, пожалуйÑта, воÑпользуйтеÑÑŒ bugtracker" msgid "ERROR:" msgstr "ОШИБКÐ:" msgid "Deleted recording:" msgstr "Удаленный запиÑи:" msgid "List of recordings" msgstr "СпиÑок запиÑей" msgid "No recordings found" msgstr "ЗапиÑи не найдены" msgid "Delete selected" msgstr "Удалить выбранные" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "Ðазвание" msgid "Sort by date" msgstr "Дата" msgid "Filter" msgstr "Фильтр" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "ИÑкать только в названиÑÑ… запиÑей и Ñубтитров в данной Ñтроке и отобразить Ñовпадающие. Также вы можете иÑпользовать perl ÑовмеÑтимые Ñтандартные команды (PCRE)." msgid "Expand all folders" msgstr "Развернуть вÑе папки" msgid "Collapse all folders" msgstr "Свернуть вÑе папки" msgid "Delete this recording from hard disc!" msgstr "Удалить Ñту запиÑÑŒ Ñ Ð¶ÐµÑткого диÑка!" msgid "play this recording." msgstr "Проиграть Ñту запиÑÑŒ." msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Канал не найден или недоÑтупен. Проверьте правильноÑть запроÑа." msgid "Snapshot interval" msgstr "Интервал между Ñнимками" msgid "No schedules available for this channel" msgstr "РаÑпиÑание Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ канала недоÑтупно" msgid "Search settings" msgstr "ÐаÑтройки поиÑка" msgid "Extended search" msgstr "РаÑширенный поиÑк" msgid "no" msgstr "нет" msgid "Search results" msgstr "Результат поиÑка" msgid "No search results" msgstr "Ðет результатов поиÑка" msgid "Expression" msgstr "ЗапроÑ" msgid "Starts between" msgstr "Ðачинать между" msgid "Toggle search timer actions (in)active" msgstr "Включить поиÑковый таймер" msgid "Browse search timer results" msgstr "ПроÑмотреть результаты поиÑкового таймера" msgid "Delete this search timer?" msgstr "Удалить Ñтот поиÑковый таймер?" msgid "Delete search timer" msgstr "Удалить поиÑковый таймер" msgid "Trigger search timer update" msgstr "Обновить" msgid "Please set login and password!" msgstr "ПожалуйÑта уÑтановите логин и пароль!" msgid "Setup saved." msgstr "ÐаÑтройки Ñохранены." msgid "Setup" msgstr "ÐаÑтройка" msgid "User management" msgstr "ÐаÑтройки пользователÑ" msgid "Local net (no login required)" msgstr "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñеть (Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ðµ требуетÑÑ)" msgid "Show live logo image" msgstr "Показать логотип LIVE" msgid "Use ajax technology" msgstr "ИÑпользовать ajax" msgid "Show dynamic VDR information box" msgstr "Показывать инфо панель VDR" msgid "Allow video streaming" msgstr "Разрешить видео Ñтриминг" msgid "Streamdev server port" msgstr "Streamdev порт" msgid "Streamdev stream type" msgstr "Streamdev тип Ñтриминга" msgid "Add links to IMDb" msgstr "Добавить ÑÑылки на Kinopoisk.ru" msgid "Additional fixed times in 'What's on?'" msgstr "Поправка времени в разделе 'СейчаÑ'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Формат HH:MM. РазделÑетÑÑ Ð½ÐµÑколько раз при помощи запÑтой" msgid "Channel groups for MultiSchedule" msgstr "Группа каналов Ð´Ð»Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ñ€Ð°ÑпиÑаниÑ" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Разделить каналы при помощи ',', разделите группы при помощи ';'" msgid "Duration of MultiSchedule in hours" msgstr "ПродолжительноÑть мультираÑпиÑÐ°Ð½Ð¸Ñ Ð² чаÑах" msgid "Show channels without EPG" msgstr "Показывать каналы без EPG" msgid "Start page" msgstr "Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ Ñтраница" msgid "Theme" msgstr "Тема" msgid "Timer conflicts" msgstr "Таймер конфликт" msgid "No timer conflicts" msgstr "Ðет конфликта таймеров" msgid "Timer has a conflict." msgstr "ЕÑть конфликт таймеров" msgid "Timer is active." msgstr "Таймер активен" msgid "Toggle timer active/inactive" msgstr "Переключить таймер активны/неактивный" msgid "Delete timer" msgstr "Удалить таймер" msgid "No timer defined" msgstr "Таймер не уÑтановлен" msgid "Timer is recording." msgstr "Таймер запиÑывает." msgid "Users" msgstr "Пользователь" msgid "Delete user" msgstr "Удалить пользователÑ" msgid "VLC: live video stream" msgstr "VLC: live видео Ñтриминг" msgid "VLC: play recording" msgstr "VLC: проиграть запиÑÑŒ" msgid "Stop" msgstr "Стоп" msgid "Play" msgstr "ВоÑпроизведение" msgid "Sound on" msgstr "Включить звук" msgid "Sound off" msgstr "Выключить звук" msgid "Fullscreen" msgstr "Полный Ñкран" msgid "Close" msgstr "Закрыть" msgid "VLC media URL" msgstr "VLC медиа URL" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "Что идет ÑейчаÑ?" msgid "at" msgstr "в" msgid "What's on next?" msgstr "Что даллее?" msgid "Favorites" msgstr "Избранные" msgid "View the schedule of this channel" msgstr "ПроÑмотреть раÑпиÑание на Ñтом канале" msgid " - " msgstr "" msgid "Next" msgstr "Далее" msgid "What's on" msgstr "СейчаÑ" msgid "Details view" msgstr "Подробно" msgid "List view" msgstr "СпиÑок" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "EPG Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна" #~ msgid "ERROR" #~ msgstr "ОШИБКÐ" vdr-plugin-live/po/nl_NL.po0000644000175000017500000003255212650773437015433 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Arnold Niessen , 2001 # Hans Dingemans , 2003 # Maarten Wisse , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Maarten Wisse \n" "Language-Team: see developers in README\n" "Language: nl_NL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" #, fuzzy msgid "Searchtimer" msgstr "Gebruik als zoek timer" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" #, fuzzy msgid "Timer conflict check detected " msgstr "Serie's opnemen" #, fuzzy msgid "conflict" msgstr "Serie's opnemen" #, fuzzy msgid "conflicts" msgstr "Serie's opnemen" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "Directory" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "Zoek tekst tekort - toch gebruiken?" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "uitdruk" msgid "all words" msgstr "alle woorden" msgid "at least one word" msgstr "ten minste een woord" msgid "match exactly" msgstr "precies passend" msgid "regular expression" msgstr "reguliere uitdruk king" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "Idem case" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "Gebruik uitgebreide EPG info" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "Gebruik kanaal" msgid "interval" msgstr "interval" msgid "channel group" msgstr "kanaal groep" msgid "only FTA" msgstr "alleen FTA" msgid "from channel" msgstr "van kanaal" msgid "to channel" msgstr "tot kanaal" msgid "Use time" msgstr "Gebruik tijd" msgid "Start after" msgstr "Start na" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "Start voor" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "Gebruiks duur" msgid "Min. duration" msgstr "Min. duur" msgid "Max. duration" msgstr "Max. duur" msgid "Use day of week" msgstr "Gebruik dag van de week" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "Gebruik als zoek timer" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Opnemen" msgid "Announce only" msgstr "Alleen aankondigen (geen timer)" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Serie's opnemen" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" #, fuzzy msgid "Edit user" msgstr "Serie's opnemen" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" #, fuzzy msgid "Edit setup" msgstr "Serie's opnemen" #, fuzzy msgid "Add or edit timers" msgstr "Gebruik als zoek timer" #, fuzzy msgid "Delete timers" msgstr "Serie's opnemen" #, fuzzy msgid "Delete recordings" msgstr "Serie's opnemen" #, fuzzy msgid "Use remote menu" msgstr "Gebruik tijd" #, fuzzy msgid "Start replay" msgstr "Start voor" #, fuzzy msgid "Switch channel" msgstr "tot kanaal" #, fuzzy msgid "Add or edit search timers" msgstr "Gebruik als zoek timer" #, fuzzy msgid "Delete search timers" msgstr "Serie's opnemen" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" #, fuzzy msgid "Deleted recording:" msgstr "Serie's opnemen" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" #, fuzzy msgid "Snapshot interval" msgstr "interval" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" #, fuzzy msgid "Timer conflicts" msgstr "Serie's opnemen" #, fuzzy msgid "No timer conflicts" msgstr "Serie's opnemen" #, fuzzy msgid "Timer has a conflict." msgstr "Serie's opnemen" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" #, fuzzy msgid "Timer is recording." msgstr "Serie's opnemen" msgid "Users" msgstr "" #, fuzzy msgid "Delete user" msgstr "Serie's opnemen" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" #, fuzzy #~ msgid "Start" #~ msgstr "Start na" vdr-plugin-live/po/sv_SE.po0000644000175000017500000004416312650773437015451 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Dmitrii Kiselev , 2013 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.3.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2013-06-21 20:15+0200\n" "Last-Translator: Fredrik Olofsson \n" "Language-Team: see developers in README\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Sista kanal att visa" msgid "No limit" msgstr "Ingen gräns" msgid "Use authentication" msgstr "Använd inloggning" msgid "No" msgstr "Nej" msgid "Yes" msgstr "Ja" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "Admin lösen" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "Söktimer" msgid "Error in timer settings" msgstr "Fel i timer-inställning" msgid "Timer already defined" msgstr "Timer redan satt" msgid "Timers are being edited - try again later" msgstr "Timers redigieras - försök igen senare" msgid "Timer not defined" msgstr "Timer ej definierad" msgid "On archive DVD No." msgstr "PÃ¥ arkiv-dvd nr." msgid "On archive HDD No." msgstr "PÃ¥ arkiv-hd nr." msgid "Couldn't find channel or no channels available." msgstr "Kunde inte hitta kanal eller inga kanaler tillgängliga" msgid "Couldn't switch to channel." msgstr "Kunde inte byta till kanal." msgid "Couldn't find recording or no recordings available." msgstr "Kunde inte hitta inspelning eller inga inspelningar tillgängliga" msgid "Cannot control playback!" msgstr "Kan inte styra uppspelning!" msgid "Not playing a recording." msgstr "Spelar inte en inspelning" msgid "Not playing the same recording as from request." msgstr "Spelar inte samma inspelnging som begärdes." msgid "Attempt to delete recording currently in playback." msgstr "Försök att ta bort inspelning som för närvarande spelas upp." msgid "Epg error" msgstr "EPG-fel." msgid "Wrong channel id" msgstr "Fel kanal-id" msgid "Channel has no schedule" msgstr "Kanalen har inga scheman" msgid "Wrong event id" msgstr "Fel händelse-id" msgid "Required minimum version of epgsearch: " msgstr "Minsta version av epgsearch som krävs:" msgid "All" msgstr "Alla" msgid "FTA" msgstr "Okrypterade" msgid "%I:%M %p" msgstr "%H:%M" msgid "EPGSearch version outdated! Please update." msgstr "För gammal version av EPGSearch. Vänligen uppdatera." msgid "Couldn't aquire primary device" msgstr "Kunde inte fÃ¥ tillgÃ¥ng till primära enheten." msgid "Couldn't grab image from primary device" msgstr "Kunde inte fÃ¥ bild frÃ¥n primära enheten" msgid "Timer conflict check detected " msgstr "Timer-konflikt koll upptäckt" msgid "conflict" msgstr "konflikt" msgid "conflicts" msgstr "konflikter" msgid "Couldn't aquire access to channels, please try again later." msgstr "Kunde inte fÃ¥ tillgÃ¥ng till kanaler, försök igen senare" msgid "Sorry, no permission. Please contact your administrator!" msgstr "Inte tillÃ¥tet för dig. Kontakta din administratör!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "Kunde inte hitta inspelningen. Kolla stavningen?" msgid "Please set a name for the recording!" msgstr "Bestäm namn för inspelningen" msgid "Cannot copy, rename or move the recording." msgstr "Kan inte kopiera, byta namn pÃ¥ eller flytta inspelningen " msgid "Edit recording" msgstr "Redigera inspelningen" msgid "Name" msgstr "Namn" msgid "Directory" msgstr "Bibliotek" msgid "Delete resume information" msgstr "Radera information för att Ã¥teruppta" msgid "Delete marks information" msgstr "Ta bort märkningsinformation" msgid "Copy only" msgstr "Kopiera endast" msgid "Short description" msgstr "Kort beskrivning" msgid "Description" msgstr "Beskrivning" msgid "Auxiliary info" msgstr "Ytterligare information" msgid "Save" msgstr "Spara" msgid "Cancel" msgstr "Avbryt" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Kunde inte hitta sök-timer. Kontrollera stavningen?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "dd/mm/yyyy" msgid "Edit search timer" msgstr "Redigera sök-timer" msgid "New search timer" msgstr "Ny sök-timer" msgid "Search text too short - use anyway?" msgstr "Sök-timerns text är för kort. Använd ändÃ¥?" msgid "Search term" msgstr "Sök fras" msgid "Search mode" msgstr "Sökläge" msgid "phrase" msgstr "fras" msgid "all words" msgstr "Alla ord" msgid "at least one word" msgstr "Minst ett ord" msgid "match exactly" msgstr "Matcha exakt" msgid "regular expression" msgstr "Reguljärt uttryck" msgid "fuzzy" msgstr "Lurvigt" msgid "Tolerance" msgstr "Tolerans" msgid "Match case" msgstr "Matcha versaler / gemener" msgid "Search in" msgstr "Sök i" msgid "Title" msgstr "Titel" msgid "Episode" msgstr "Avsnitt" msgid "Use extended EPG info" msgstr "Använd utökad EPG-information" msgid "Ignore missing EPG info" msgstr "Ignorera saknad EPG-info" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "När aktiverad kan detta skapa väldigt mÃ¥nga timers. SÃ¥ pröva därför endast detta först innan du använder det som sök-timer" msgid "Use channel" msgstr "Använd kanal" msgid "interval" msgstr "Intervall" msgid "channel group" msgstr "Kanalgrupp" msgid "only FTA" msgstr "endast okodade" msgid "from channel" msgstr "frÃ¥n kanal" msgid "to channel" msgstr "till kanal" msgid "Use time" msgstr "Använd tid" msgid "Start after" msgstr "Börja efter" msgid "The time the show may start at the earliest" msgstr "Tidigaste begynnelsetid för program" msgid "Start before" msgstr "Börja innan" msgid "The time the show may start at the latest" msgstr "När programmet senast mÃ¥ste börja (vilken tid)" msgid "Use duration" msgstr "Använd längd" msgid "Min. duration" msgstr "Minsta längd" msgid "Max. duration" msgstr "Största längd" msgid "Use day of week" msgstr "Använd veckodag" msgid "Monday" msgstr "MÃ¥ndag" msgid "Tuesday" msgstr "Tisdag" msgid "Wednesday" msgstr "Onsdag" msgid "Thursday" msgstr "Torsdag" msgid "Friday" msgstr "Fredag" msgid "Saturday" msgstr "Lördag" msgid "Sunday" msgstr "Söndag" msgid "Use blacklists" msgstr "Använd svartlista" msgid "Selection" msgstr "Val" msgid "all" msgstr "alla" msgid "Use in favorites menu" msgstr "Använd i favoriter-menyn" msgid "Use as search timer" msgstr "Använd som sök-timer" msgid "user defined" msgstr "användardefinierad" msgid "from date" msgstr "FrÃ¥n datum" msgid "to date" msgstr "till datum" msgid "Record" msgstr "Spela in" msgid "Announce only" msgstr "Publicera endast" msgid "Switch only" msgstr "Byt endast" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Serieinspelning" msgid "Delete recordings after ... days" msgstr "Ta bort inspelningar efter ... dagar" msgid "Keep ... recordings" msgstr "Spara ... inspelningar" msgid "Pause when ... recordings exist" msgstr "Pausa när ... inspelning existerar" msgid "Avoid repeats" msgstr "Undvik upprepningar" msgid "Allowed repeats" msgstr "TillÃ¥tna upprepningar" msgid "Only repeats within ... days" msgstr "Endast upprepningar inom ... dagar" msgid "Compare title" msgstr "Jämför titel" msgid "Compare subtitle" msgstr "Jämför undertitel" msgid "if present" msgstr "om tillgänglig" msgid "Compare summary" msgstr "Jämför sammanfattning" msgid "Compare" msgstr "Jämför" msgid "Use VPS" msgstr "VPS" msgid "Auto-delete search timer" msgstr "Ta automatiskt bort sök-timer" msgid "after ... recordings" msgstr "efter ... inspelningar" msgid "after ... days after first rec." msgstr "efter ... dagar efter första inspelning." msgid "Switch ... minutes before start" msgstr "Byt ... minuter innan start" msgid "Test" msgstr "Test" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Kan inte hitta timer. Kontrollera stavningen?" msgid "Please set a title for the timer!" msgstr "Sätt ett namn pÃ¥ timern!" msgid "Edit timer" msgstr "Redigera timer" msgid "New timer" msgstr "Ny timer" msgid "Weekday" msgstr "Veckodag" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Kan inte hitta användare. Kontrollera stavningen?" msgid "This user name is already in use!" msgstr "Användarnamnet används redan!" msgid "Edit user" msgstr "Redigera användare" msgid "New user" msgstr "Ny användare" msgid "Password" msgstr "Lösenord" msgid "User rights" msgstr "Användarrättigheter" msgid "Edit setup" msgstr "Redigera inställningar" msgid "Add or edit timers" msgstr "Lägg till eller ta bort timers" msgid "Delete timers" msgstr "Radera timers" msgid "Delete recordings" msgstr "Radera inspelningar" msgid "Use remote menu" msgstr "Använd fjärrmeny" msgid "Start replay" msgstr "PÃ¥börja repetetionsuppspelning" msgid "Switch channel" msgstr "Byt kanal" msgid "Add or edit search timers" msgstr "Lägg till eller redigera sök-timers" msgid "Delete search timers" msgstr "Radera sök-timers" msgid "Edit recordings" msgstr "Redigera inspelningar" msgid "Electronic program guide information" msgstr "EPG-information" msgid "Couldn't find recording or no recordings available" msgstr "Kunde inte hitta inspelning eller inga inspelningar tillgängliga" msgid "Error aquiring schedules lock" msgstr "Fil vid lÃ¥sning av scheman" msgid "Error aquiring schedules" msgstr "Fel vid hämtning av scheman" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "Fel pÃ¥ sidan" msgid "playing recording" msgstr "Spelar upp inspelning" msgid "no epg info for current event!" msgstr "Ingen epg-info för nuvarande händelse!" msgid "no epg info for current channel!" msgstr "Ingen epg-info för nuvarande kanal!" msgid "no current channel!" msgstr "Ingen nuvarande kanal!" msgid "error retrieving status info!" msgstr "fel vid hämtning av statusinfo!" msgid "%I:%M:%S %p" msgstr "%H:%M:%S" msgid "Wrong username or password" msgstr "Fel användarnamn eller lösenord" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "VDR Live Login" msgid "User" msgstr "Användare" msgid "What's on?" msgstr "Vad spelas?" msgid "MultiSchedule" msgstr "MultiSchema" msgid "Search" msgstr "Sök" msgid "Searchtimers" msgstr "Sök-timers" msgid "Recordings" msgstr "Inspelningar" msgid "Remote Control" msgstr "Fjärrkontroll" msgid "Logout" msgstr "Logga ut" msgid "Your attention is required" msgstr "Din uppmärksamhet krävs" msgid "React" msgstr "Reagera" msgid "Dismiss" msgstr "Avfärda" msgid "Now" msgstr "Nu" msgid "%A, %b %d %Y" msgstr "%A, %d.%m.%Y" msgid "Time" msgstr "Tid" msgid "Switch to this channel." msgstr "Byt till denna kanal." msgid "Search for repeats." msgstr "Sök efter upprepningar." msgid "Click to view details." msgstr "Klicka för detaljer" msgid "more" msgstr "mera" msgid "Channel" msgstr "Kanal" msgid "Find more at the Internet Movie Database." msgstr "Hitta mera pÃ¥ IMDB" msgid "Stream this channel into browser." msgstr "Strömma denna kanal till webläsaren" msgid "Stream this recording into browser." msgstr "Strömma denna inspelning till webläsaren." msgid "Record this" msgstr "Spela in detta." msgid "loading data" msgstr "Laddar data" msgid "an error occured!" msgstr "Ett fel inträffade!" msgid "Request succeeded!" msgstr "Begäran lyckades!" msgid "Request failed!" msgstr "Begäran misslyckades!" msgid "January" msgstr "Januari" msgid "February" msgstr "Februari" msgid "March" msgstr "Mars" msgid "April" msgstr "April" msgid "May" msgstr "Maj" msgid "June" msgstr "Juni" msgid "July" msgstr "Juli" msgid "August" msgstr "Augusti" msgid "September" msgstr "September" msgid "October" msgstr "Oktober" msgid "November" msgstr "November" msgid "December" msgstr "December" msgid "retrieving status ..." msgstr "Hämtar status ..." msgid "Toggle updates on/off." msgstr "Uppdateringar pÃ¥/av." msgid "stop playback" msgstr "stoppa uppspelning" msgid "resume playback" msgstr "Ã¥teruppta uppspelning" msgid "pause playback" msgstr "pausa uppspelning" msgid "fast rewind" msgstr "spola bakÃ¥t" msgid "fast forward" msgstr "spola framÃ¥t" msgid "previous channel" msgstr "förra kanalen" msgid "next channel" msgstr "nästa kanal" msgid "No server response!" msgstr "Inget svar frÃ¥n servern!" msgid "Failed to update infobox!" msgstr "Misslyckades att uppdatera info-rutan!" msgid "Authors" msgstr "Författare" msgid "Project Idea" msgstr "Projekt-idé" msgid "Webserver" msgstr "Webserver" msgid "Project leader" msgstr "Projektledare" msgid "Content" msgstr "InnehÃ¥ll" msgid "Graphics" msgstr "Grafik" msgid "Information" msgstr "" msgid "LIVE version" msgstr "Version av LIVE" msgid "VDR version" msgstr "Version av VDR" msgid "Features" msgstr "" msgid "active" msgstr "aktiv" msgid "required" msgstr "krävs" msgid "Homepage" msgstr "Hemsida" msgid "Bugs and suggestions" msgstr "Felrapporter och förslag" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Om du hittar nÃ¥gra fel eller vill föreslÃ¥ nya funktioner, vänligen använd vÃ¥r bugg-tracker" msgid "ERROR:" msgstr "FEL:" msgid "Deleted recording:" msgstr "Raderade inspelningar:" msgid "List of recordings" msgstr "Lista över inspelningar" msgid "No recordings found" msgstr "Inga inspelningar funna" msgid "Delete selected" msgstr "Ta bort valda" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "Sortera efter namn" msgid "Sort by date" msgstr "Sortera efter datum" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "Titta efter given sträng i inspelningarnas titlar och undertitlar och visa endast de som matchar. Du kan ocksÃ¥ använda PERL-kompatibla reguljära uttryck. (PCRE)" msgid "Expand all folders" msgstr "Utöka alla bibliotek" msgid "Collapse all folders" msgstr "Kollapsa alla bibliotek" msgid "Delete this recording from hard disc!" msgstr "Ta bort den inspelning frÃ¥n hÃ¥rddisken!" msgid "play this recording." msgstr "Spela upp denna inspelning" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Kan inte hitta kanal eller inga kanaler är tillgängliga. Kontrollera stavningen?" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "Inga scheman för denna kanal!" msgid "Search settings" msgstr "Sök inställningar" msgid "Extended search" msgstr "Utökad sökning" msgid "no" msgstr "nej" msgid "Search results" msgstr "Sökresultat" msgid "No search results" msgstr "Inga sökresultat" msgid "Expression" msgstr "Uttryck" msgid "Starts between" msgstr "Börjar mellan" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "Visa söktimer-resultat" msgid "Delete this search timer?" msgstr "Ta bort denna sök-timer?" msgid "Delete search timer" msgstr "Ta bort sök-timer" msgid "Trigger search timer update" msgstr "Tvinga sök-timer uppdatering" msgid "Please set login and password!" msgstr "Vänligen sätt login och lösenord!" msgid "Setup saved." msgstr "Inställningar sparade" msgid "Setup" msgstr "Inställningar" msgid "User management" msgstr "Användarhantering" msgid "Local net (no login required)" msgstr "Lokalt nät (inget login krävs)" msgid "Show live logo image" msgstr "Visa live logo" msgid "Use ajax technology" msgstr "Använd ajax-teknik" msgid "Show dynamic VDR information box" msgstr "Visa dynamisk VDR-informationsruta" msgid "Allow video streaming" msgstr "TillÃ¥t videoströmmning" msgid "Streamdev server port" msgstr "Streamdev serverns port" msgid "Streamdev stream type" msgstr "Streamdev strömtyp" msgid "Add links to IMDb" msgstr "Lägg till länkar till IMDb" msgid "Additional fixed times in 'What's on?'" msgstr "Ytterligare fixerade tider i 'Vad spelas?'" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Formatet är HH:MM. Avdela flera tider med semi-kolon" msgid "Channel groups for MultiSchedule" msgstr "Kanal-grupper för MultiSchedule" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "Avdela kanaler med ett komma ',', avdela grupper med semi-kolon ';'" msgid "Duration of MultiSchedule in hours" msgstr "Längd pÃ¥ MultiSchedule i timmar" msgid "Show channels without EPG" msgstr "Visa kanaler utan EPG" msgid "Start page" msgstr "Startsida" msgid "Theme" msgstr "Tema" msgid "Timer conflicts" msgstr "Timerkonflikter" msgid "No timer conflicts" msgstr "Inga timerkonflikter" msgid "Timer has a conflict." msgstr "Upptäckt konflikt för timern" msgid "Timer is active." msgstr "Timern är aktiv" msgid "Toggle timer active/inactive" msgstr "Välj aktiv/inaktiv för timer" msgid "Delete timer" msgstr "Ta bort timer" msgid "No timer defined" msgstr "Ingen timer definierad" msgid "Timer is recording." msgstr "Timern spelar in." msgid "Users" msgstr "Användare" msgid "Delete user" msgstr "Radera användare" msgid "VLC: live video stream" msgstr "VLC: live videoström" msgid "VLC: play recording" msgstr "VLC: Spela inspelning" msgid "Stop" msgstr "Stop" msgid "Play" msgstr "" msgid "Sound on" msgstr "Ljud pÃ¥" msgid "Sound off" msgstr "Ljud av" msgid "Fullscreen" msgstr "Helskärm" msgid "Close" msgstr "Stäng" msgid "VLC media URL" msgstr "VLC media-URL" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "Vad körs pÃ¥" msgid "at" msgstr "kl" msgid "What's on next?" msgstr "Vad är nästa program?" msgid "Favorites" msgstr "Favoriter" msgid "View the schedule of this channel" msgstr "Visa schemat för denna kanal" msgid " - " msgstr "" msgid "Next" msgstr "Nästa" msgid "What's on" msgstr "Vad är pÃ¥?" msgid "Details view" msgstr "Detaljvy" msgid "List view" msgstr "Listvy" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "EPG-information saknas" #~ msgid "ERROR" #~ msgstr "FEL" vdr-plugin-live/po/et_EE.po0000644000175000017500000003047212650773437015411 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Arthur Konovalov , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Arthur Konovalov \n" "Language-Team: see developers in README\n" "Language: et_EE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-13\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Salvesta" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/da_DK.po0000644000175000017500000003046712650773437015376 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Mogens Elneff , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Mogens Elneff \n" "Language-Team: see developers in README\n" "Language: da_DK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Optag" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/sl_SI.po0000644000175000017500000003057612650773437015446 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Miha Setina , 2000 # Matjaz Thaler , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Matjaz Thaler \n" "Language-Team: see developers in README\n" "Language: sl_SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Posnemi" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/hu_HU.po0000644000175000017500000003064612650773437015443 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Istvan Koenigsberger , 2002 # Guido Josten , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Istvan Koenigsberger , Guido Josten \n" "Language-Team: see developers in README\n" "Language: hu_HU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "" msgid "No limit" msgstr "" msgid "Use authentication" msgstr "" msgid "No" msgstr "" msgid "Yes" msgstr "" msgid "Admin login" msgstr "" msgid "Admin password" msgstr "" #, c-format msgid "%A, %x" msgstr "" msgid "Searchtimer" msgstr "" msgid "Error in timer settings" msgstr "" msgid "Timer already defined" msgstr "" msgid "Timers are being edited - try again later" msgstr "" msgid "Timer not defined" msgstr "" msgid "On archive DVD No." msgstr "" msgid "On archive HDD No." msgstr "" msgid "Couldn't find channel or no channels available." msgstr "" msgid "Couldn't switch to channel." msgstr "" msgid "Couldn't find recording or no recordings available." msgstr "" msgid "Cannot control playback!" msgstr "" msgid "Not playing a recording." msgstr "" msgid "Not playing the same recording as from request." msgstr "" msgid "Attempt to delete recording currently in playback." msgstr "" msgid "Epg error" msgstr "" msgid "Wrong channel id" msgstr "" msgid "Channel has no schedule" msgstr "" msgid "Wrong event id" msgstr "" msgid "Required minimum version of epgsearch: " msgstr "" msgid "All" msgstr "" msgid "FTA" msgstr "" msgid "%I:%M %p" msgstr "" msgid "EPGSearch version outdated! Please update." msgstr "" msgid "Couldn't aquire primary device" msgstr "" msgid "Couldn't grab image from primary device" msgstr "" msgid "Timer conflict check detected " msgstr "" msgid "conflict" msgstr "" msgid "conflicts" msgstr "" msgid "Couldn't aquire access to channels, please try again later." msgstr "" msgid "Sorry, no permission. Please contact your administrator!" msgstr "" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "" msgid "Directory" msgstr "" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" msgid "Short description" msgstr "" msgid "Description" msgstr "" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "" msgid "Cancel" msgstr "" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "" msgid "Edit search timer" msgstr "" msgid "New search timer" msgstr "" msgid "Search text too short - use anyway?" msgstr "" msgid "Search term" msgstr "" msgid "Search mode" msgstr "" msgid "phrase" msgstr "" msgid "all words" msgstr "" msgid "at least one word" msgstr "" msgid "match exactly" msgstr "" msgid "regular expression" msgstr "" msgid "fuzzy" msgstr "" msgid "Tolerance" msgstr "" msgid "Match case" msgstr "" msgid "Search in" msgstr "" msgid "Title" msgstr "" msgid "Episode" msgstr "" msgid "Use extended EPG info" msgstr "" msgid "Ignore missing EPG info" msgstr "" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "" msgid "Use channel" msgstr "" msgid "interval" msgstr "" msgid "channel group" msgstr "" msgid "only FTA" msgstr "" msgid "from channel" msgstr "" msgid "to channel" msgstr "" msgid "Use time" msgstr "" msgid "Start after" msgstr "" msgid "The time the show may start at the earliest" msgstr "" msgid "Start before" msgstr "" msgid "The time the show may start at the latest" msgstr "" msgid "Use duration" msgstr "" msgid "Min. duration" msgstr "" msgid "Max. duration" msgstr "" msgid "Use day of week" msgstr "" msgid "Monday" msgstr "" msgid "Tuesday" msgstr "" msgid "Wednesday" msgstr "" msgid "Thursday" msgstr "" msgid "Friday" msgstr "" msgid "Saturday" msgstr "" msgid "Sunday" msgstr "" msgid "Use blacklists" msgstr "" msgid "Selection" msgstr "" msgid "all" msgstr "" msgid "Use in favorites menu" msgstr "" msgid "Use as search timer" msgstr "" msgid "user defined" msgstr "" msgid "from date" msgstr "" msgid "to date" msgstr "" msgid "Record" msgstr "Felvenni" msgid "Announce only" msgstr "" msgid "Switch only" msgstr "" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "" msgid "Delete recordings after ... days" msgstr "" msgid "Keep ... recordings" msgstr "" msgid "Pause when ... recordings exist" msgstr "" msgid "Avoid repeats" msgstr "" msgid "Allowed repeats" msgstr "" msgid "Only repeats within ... days" msgstr "" msgid "Compare title" msgstr "" msgid "Compare subtitle" msgstr "" msgid "if present" msgstr "" msgid "Compare summary" msgstr "" msgid "Compare" msgstr "" msgid "Use VPS" msgstr "" msgid "Auto-delete search timer" msgstr "" msgid "after ... recordings" msgstr "" msgid "after ... days after first rec." msgstr "" msgid "Switch ... minutes before start" msgstr "" msgid "Test" msgstr "" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "" msgid "Please set a title for the timer!" msgstr "" msgid "Edit timer" msgstr "" msgid "New timer" msgstr "" msgid "Weekday" msgstr "" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "" msgid "This user name is already in use!" msgstr "" msgid "Edit user" msgstr "" msgid "New user" msgstr "" msgid "Password" msgstr "" msgid "User rights" msgstr "" msgid "Edit setup" msgstr "" msgid "Add or edit timers" msgstr "" msgid "Delete timers" msgstr "" msgid "Delete recordings" msgstr "" msgid "Use remote menu" msgstr "" msgid "Start replay" msgstr "" msgid "Switch channel" msgstr "" msgid "Add or edit search timers" msgstr "" msgid "Delete search timers" msgstr "" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "" msgid "Couldn't find recording or no recordings available" msgstr "" msgid "Error aquiring schedules lock" msgstr "" msgid "Error aquiring schedules" msgstr "" msgid "%b %d %y" msgstr "" msgid "Page error" msgstr "" msgid "playing recording" msgstr "" msgid "no epg info for current event!" msgstr "" msgid "no epg info for current channel!" msgstr "" msgid "no current channel!" msgstr "" msgid "error retrieving status info!" msgstr "" msgid "%I:%M:%S %p" msgstr "" msgid "Wrong username or password" msgstr "" msgid "Login" msgstr "" msgid "VDR Live Login" msgstr "" msgid "User" msgstr "" msgid "What's on?" msgstr "" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "" msgid "Searchtimers" msgstr "" msgid "Recordings" msgstr "" msgid "Remote Control" msgstr "" msgid "Logout" msgstr "" msgid "Your attention is required" msgstr "" msgid "React" msgstr "" msgid "Dismiss" msgstr "" msgid "Now" msgstr "" msgid "%A, %b %d %Y" msgstr "" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "" msgid "Search for repeats." msgstr "" msgid "Click to view details." msgstr "" msgid "more" msgstr "" msgid "Channel" msgstr "" msgid "Find more at the Internet Movie Database." msgstr "" msgid "Stream this channel into browser." msgstr "" msgid "Stream this recording into browser." msgstr "" msgid "Record this" msgstr "" msgid "loading data" msgstr "" msgid "an error occured!" msgstr "" msgid "Request succeeded!" msgstr "" msgid "Request failed!" msgstr "" msgid "January" msgstr "" msgid "February" msgstr "" msgid "March" msgstr "" msgid "April" msgstr "" msgid "May" msgstr "" msgid "June" msgstr "" msgid "July" msgstr "" msgid "August" msgstr "" msgid "September" msgstr "" msgid "October" msgstr "" msgid "November" msgstr "" msgid "December" msgstr "" msgid "retrieving status ..." msgstr "" msgid "Toggle updates on/off." msgstr "" msgid "stop playback" msgstr "" msgid "resume playback" msgstr "" msgid "pause playback" msgstr "" msgid "fast rewind" msgstr "" msgid "fast forward" msgstr "" msgid "previous channel" msgstr "" msgid "next channel" msgstr "" msgid "No server response!" msgstr "" msgid "Failed to update infobox!" msgstr "" msgid "Authors" msgstr "" msgid "Project Idea" msgstr "" msgid "Webserver" msgstr "" msgid "Project leader" msgstr "" msgid "Content" msgstr "" msgid "Graphics" msgstr "" msgid "Information" msgstr "" msgid "LIVE version" msgstr "" msgid "VDR version" msgstr "" msgid "Features" msgstr "" msgid "active" msgstr "" msgid "required" msgstr "" msgid "Homepage" msgstr "" msgid "Bugs and suggestions" msgstr "" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "" msgid "ERROR:" msgstr "" msgid "Deleted recording:" msgstr "" msgid "List of recordings" msgstr "" msgid "No recordings found" msgstr "" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "" #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "" msgid "play this recording." msgstr "" msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "" msgid "Snapshot interval" msgstr "" msgid "No schedules available for this channel" msgstr "" msgid "Search settings" msgstr "" msgid "Extended search" msgstr "" msgid "no" msgstr "" msgid "Search results" msgstr "" msgid "No search results" msgstr "" msgid "Expression" msgstr "" msgid "Starts between" msgstr "" msgid "Toggle search timer actions (in)active" msgstr "" msgid "Browse search timer results" msgstr "" msgid "Delete this search timer?" msgstr "" msgid "Delete search timer" msgstr "" msgid "Trigger search timer update" msgstr "" msgid "Please set login and password!" msgstr "" msgid "Setup saved." msgstr "" msgid "Setup" msgstr "" msgid "User management" msgstr "" msgid "Local net (no login required)" msgstr "" msgid "Show live logo image" msgstr "" msgid "Use ajax technology" msgstr "" msgid "Show dynamic VDR information box" msgstr "" msgid "Allow video streaming" msgstr "" msgid "Streamdev server port" msgstr "" msgid "Streamdev stream type" msgstr "" msgid "Add links to IMDb" msgstr "" msgid "Additional fixed times in 'What's on?'" msgstr "" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "" msgid "Channel groups for MultiSchedule" msgstr "" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "" msgid "Start page" msgstr "" msgid "Theme" msgstr "" msgid "Timer conflicts" msgstr "" msgid "No timer conflicts" msgstr "" msgid "Timer has a conflict." msgstr "" msgid "Timer is active." msgstr "" msgid "Toggle timer active/inactive" msgstr "" msgid "Delete timer" msgstr "" msgid "No timer defined" msgstr "" msgid "Timer is recording." msgstr "" msgid "Users" msgstr "" msgid "Delete user" msgstr "" msgid "VLC: live video stream" msgstr "" msgid "VLC: play recording" msgstr "" msgid "Stop" msgstr "" msgid "Play" msgstr "" msgid "Sound on" msgstr "" msgid "Sound off" msgstr "" msgid "Fullscreen" msgstr "" msgid "Close" msgstr "" msgid "VLC media URL" msgstr "" #, c-format msgid "%a, %x" msgstr "" msgid "What's running on" msgstr "" msgid "at" msgstr "" msgid "What's on next?" msgstr "" msgid "Favorites" msgstr "" msgid "View the schedule of this channel" msgstr "" msgid " - " msgstr "" msgid "Next" msgstr "" msgid "What's on" msgstr "" msgid "Details view" msgstr "" msgid "List view" msgstr "" msgid "Live Interactive VDR Environment" msgstr "" msgid "No EPG information available" msgstr "" vdr-plugin-live/po/lt_LT.po0000644000175000017500000004507512650773437015453 0ustar tobiastobias# VDR LIVE plugin language source file. # Copyright (C) 2007 LIVE Development team. See http://live.vdr-developer.org # This file is distributed under the same license as the VDR-LIVE package. # Valdemaras Pipiras , 2009 # msgid "" msgstr "" "Project-Id-Version: VDR-LIVE 0.2.0\n" "Report-Msgid-Bugs-To: \n" "PO-Revision-Date: 2007-08-19 20:15+0200\n" "Last-Translator: Valdemaras Pipiras \n" "Language-Team: see developers in README\n" "Language: lt_LT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Last channel to display" msgstr "Paskutinis rodytas kanalas" msgid "No limit" msgstr "Neribojama" msgid "Use authentication" msgstr "Reikia autentifikuotis" msgid "No" msgstr "Ne" msgid "Yes" msgstr "Taip" msgid "Admin login" msgstr "Administratoriaus prisijungimo vardas" msgid "Admin password" msgstr "Administratoriaus slapyvardis" #, c-format msgid "%A, %x" msgstr "%A, %x" msgid "Searchtimer" msgstr "PaieÅ¡ka laikmatyje" msgid "Error in timer settings" msgstr "Klaida laikmaÄio nustatymuose" msgid "Timer already defined" msgstr "Laikmatis jau nustatytas" msgid "Timers are being edited - try again later" msgstr "Laikmatis Å¡io metu kuoreguojamas - pabandykit vÄ—liau" msgid "Timer not defined" msgstr "Laikmatis nenustatytas" msgid "On archive DVD No." msgstr "DVB Nr." #, fuzzy msgid "On archive HDD No." msgstr "DVB Nr." msgid "Couldn't find channel or no channels available." msgstr "Nerastas arba neegzistuojantis kanalas." msgid "Couldn't switch to channel." msgstr "Negali perjungti kanalo." msgid "Couldn't find recording or no recordings available." msgstr "Negali rasti įraÅ¡o arba įraÅ¡o visai nÄ—ra" msgid "Cannot control playback!" msgstr "Negali valdyti grojimo!" msgid "Not playing a recording." msgstr "Negroja įraÅ¡o." msgid "Not playing the same recording as from request." msgstr "Negroja to paties norimo įraÅ¡o." msgid "Attempt to delete recording currently in playback." msgstr "Bandoma iÅ¡trinti įrašą iÅ¡ grojaraÅ¡Äio." msgid "Epg error" msgstr "Epg klaida" msgid "Wrong channel id" msgstr "Klaidingas kanalo ID" msgid "Channel has no schedule" msgstr "Kainalas neturi programos apraÅ¡o" msgid "Wrong event id" msgstr "Klaidingas įvykio ID" msgid "Required minimum version of epgsearch: " msgstr "Darbui reikalinga minimali epgsearch įskiepo versija: " msgid "All" msgstr "Visi" msgid "FTA" msgstr "Nukoduoti kanalai" msgid "%I:%M %p" msgstr "%I:%M %p" msgid "EPGSearch version outdated! Please update." msgstr "Pasenusi EPGSearch įskiepo versija! Atsinaujinkit." msgid "Couldn't aquire primary device" msgstr "Negali nustatyti pirminio įvesties įrenginio" msgid "Couldn't grab image from primary device" msgstr "Negali nuskaityti paveikslo iÅ¡ pirminio įvesties įrenginio" msgid "Timer conflict check detected " msgstr "Eina laikmaÄio nesklandumų paieÅ¡ka " msgid "conflict" msgstr "nesklandumas" msgid "conflicts" msgstr "nesklandumai" msgid "Couldn't aquire access to channels, please try again later." msgstr "Neprieina prie kanalų, pabandykit vÄ—liau." msgid "Sorry, no permission. Please contact your administrator!" msgstr "Atleiskit, bet jÅ«s neturite užtektinai teisių. Susisiekite su sistemos administratoriumi!" msgid "Couldn't find recording. Maybe you mistyped your request?" msgstr "" msgid "Please set a name for the recording!" msgstr "" msgid "Cannot copy, rename or move the recording." msgstr "" msgid "Edit recording" msgstr "" msgid "Name" msgstr "Vardas" msgid "Directory" msgstr "Katalogas" msgid "Delete resume information" msgstr "" msgid "Delete marks information" msgstr "" msgid "Copy only" msgstr "" #, fuzzy msgid "Short description" msgstr "ApraÅ¡ymas" msgid "Description" msgstr "ApraÅ¡ymas" msgid "Auxiliary info" msgstr "" msgid "Save" msgstr "IÅ¡saugoti" msgid "Cancel" msgstr "Atmesti" msgid "Couldn't find searchtimer. Maybe you mistyped your request?" msgstr "Nerandamas paieÅ¡kos laikmatis. Gal pateikÄ—te netiksliÄ… užklausÄ…?" #. TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's msgid "mm/dd/yyyy" msgstr "yyyy-mm-dd" msgid "Edit search timer" msgstr "Koreguoti paieÅ¡kos laikmatį" msgid "New search timer" msgstr "Naujas paieÅ¡kos laikmatis" msgid "Search text too short - use anyway?" msgstr "IeÅ¡koma frazÄ— per trumpa - vistiek jÄ… naudoti?" msgid "Search term" msgstr "PaieÅ¡kos frazÄ—" msgid "Search mode" msgstr "PaieÅ¡kos ręžimas" msgid "phrase" msgstr "frazÄ—" msgid "all words" msgstr "visi žodžiai" msgid "at least one word" msgstr "bent vienas žodis" msgid "match exactly" msgstr "tikslus atitikmuo" msgid "regular expression" msgstr "reguliari iÅ¡raiÅ¡ka" msgid "fuzzy" msgstr "neapibrėžta" msgid "Tolerance" msgstr "Tolerancija" msgid "Match case" msgstr "Kreiti dÄ—mesį į raidžių registrÄ…" msgid "Search in" msgstr "IeÅ¡koti" msgid "Title" msgstr "Pavadinimas" msgid "Episode" msgstr "Epizodas" msgid "Use extended EPG info" msgstr "Naudoti iÅ¡plÄ—stÄ… EPG informacijÄ…" msgid "Ignore missing EPG info" msgstr "Ignoruoti trÅ«kstamÄ… EPG informacijÄ…" msgid "When active this can cause very many timers. So please always first test this search before using it as search timer!" msgstr "Aktyvavus gali įjungti labai daug laikmaÄių. Taigi visalaik pirmiausia iÅ¡bandykit Å¡iÄ… paiesÅ¡kÄ… prieÅ¡ naudodamiesi laikmaÄio paieÅ¡ka!" msgid "Use channel" msgstr "Naudoti kanalÄ…" msgid "interval" msgstr "intervalas" msgid "channel group" msgstr "kanalo grupÄ—" msgid "only FTA" msgstr "tik nekoduoti" msgid "from channel" msgstr "iÅ¡ kanalo" msgid "to channel" msgstr "į kanalÄ…" msgid "Use time" msgstr "Naudoti laikÄ…" msgid "Start after" msgstr "PradÄ—ti po to" msgid "The time the show may start at the earliest" msgstr "Laikas kada laida gali prasidÄ—ti anksÄiausiai" msgid "Start before" msgstr "PradÄ—ti prieÅ¡" msgid "The time the show may start at the latest" msgstr "Laikas kada laida gali prasidÄ—ti vÄ—liausiai" msgid "Use duration" msgstr "Naudoti trukmÄ™" msgid "Min. duration" msgstr "Min. trukmÄ—" msgid "Max. duration" msgstr "Max. trukmÄ—" msgid "Use day of week" msgstr "Naudoti savaitÄ—s dianÄ…" msgid "Monday" msgstr "Pirmadienis" msgid "Tuesday" msgstr "Antradienis" msgid "Wednesday" msgstr "TreÄiadienis" msgid "Thursday" msgstr "Ketvirtadienis" msgid "Friday" msgstr "Penktadienis" msgid "Saturday" msgstr "Å eÅ¡tadienis" msgid "Sunday" msgstr "Sekmadienis" msgid "Use blacklists" msgstr "Naudoti juoduosius sÄ…raÅ¡us" msgid "Selection" msgstr "Pasirinkimas" msgid "all" msgstr "visi" msgid "Use in favorites menu" msgstr "Naudoti mÄ—giamiausiųjų sÄ…raÅ¡e" msgid "Use as search timer" msgstr "Naudoti kaip paieÅ¡kos laikmatį" msgid "user defined" msgstr "vartotojo pasirinktas" msgid "from date" msgstr "nuo" msgid "to date" msgstr "iki" msgid "Record" msgstr "Ä®raÅ¡yti" msgid "Announce only" msgstr "Tik pristato" msgid "Switch only" msgstr "Tik pereina" msgid "Announce via email" msgstr "" msgid "Series recording" msgstr "Ä®raÅ¡ai" msgid "Delete recordings after ... days" msgstr "IÅ¡trinti įraÅ¡us po ... dienų" msgid "Keep ... recordings" msgstr "Laikyti ... įrašų" msgid "Pause when ... recordings exist" msgstr "Sustapdyti kai pasiekia ... įrašų ribÄ…" msgid "Avoid repeats" msgstr "IÅ¡vengti pakartojimų" msgid "Allowed repeats" msgstr "Leisti pakartojimus" msgid "Only repeats within ... days" msgstr "Kartoti tik po ... dienų" msgid "Compare title" msgstr "Palyginti pavadinimus" msgid "Compare subtitle" msgstr "Palyginti apraÅ¡us" msgid "if present" msgstr "jei egzistuoja" msgid "Compare summary" msgstr "Palyginti santraukÄ…" msgid "Compare" msgstr "Palyginti" msgid "Use VPS" msgstr "Naudoti VPS" msgid "Auto-delete search timer" msgstr "AutomatiÅ¡kai iÅ¡trinti paieÅ¡kos laikmatį" msgid "after ... recordings" msgstr "po ... įrašų" msgid "after ... days after first rec." msgstr "po ... dienų kai buvo padarytas pirmas įraÅ¡as" msgid "Switch ... minutes before start" msgstr "Ä®jungti ... minutÄ—mis anksÄiau prieÅ¡ pradedant įrašą" msgid "Test" msgstr "Pabandyti" msgid "Couldn't find timer. Maybe you mistyped your request?" msgstr "Toks laikmatis nerastas. Gal įvedÄ—te klaidingÄ… paieÅ¡kos frazÄ™?" msgid "Please set a title for the timer!" msgstr "LaikmaÄiui bÅ«tina įvesti pavadinimÄ…!" msgid "Edit timer" msgstr "Koreguoti laikmatį" msgid "New timer" msgstr "Naujas laikmatis" msgid "Weekday" msgstr "SavaitÄ—s diena" msgid "Couldn't find user. Maybe you mistyped your request?" msgstr "Toks vartotojas nerastas. Gal klaidingai įvedÄ—te užklausos frazÄ™?" msgid "This user name is already in use!" msgstr "Toks vartotojo vardas jau naudojamas!" msgid "Edit user" msgstr "Koreguoti vartotojÄ…" msgid "New user" msgstr "Naujas vartotojas" msgid "Password" msgstr "Slapyvardis" msgid "User rights" msgstr "Vartotojo teisÄ—s" msgid "Edit setup" msgstr "Koreguoti nustatymus" msgid "Add or edit timers" msgstr "PridÄ—ti arba koreguoti laikmaÄius" msgid "Delete timers" msgstr "IÅ¡trinti laikmaÄius" msgid "Delete recordings" msgstr "IÅ¡trinti įraÅ¡us" msgid "Use remote menu" msgstr "Naudoti nuotolinį meniu" msgid "Start replay" msgstr "Paleisti kartojimÄ…" msgid "Switch channel" msgstr "Perjungti kanalÄ…" msgid "Add or edit search timers" msgstr "PridÄ—ti arba koreguoti paieÅ¡kos laikmaÄius" msgid "Delete search timers" msgstr "IÅ¡trinti paieÅ¡kos laikmaÄius" msgid "Edit recordings" msgstr "" msgid "Electronic program guide information" msgstr "Elektroninis programų gidas" msgid "Couldn't find recording or no recordings available" msgstr "Negali rasti įraÅ¡o arba įrašų iÅ¡ vis nÄ—ra" msgid "Error aquiring schedules lock" msgstr "Negali gauti programų užrakto" msgid "Error aquiring schedules" msgstr "Negauna programų aprašų" msgid "%b %d %y" msgstr "%b %d %y" msgid "Page error" msgstr "Puslapio klaida" msgid "playing recording" msgstr "grojamas įraÅ¡as" msgid "no epg info for current event!" msgstr "Å¡is įvykis neturi epg įraÅ¡o!" msgid "no epg info for current channel!" msgstr "Å¡is kanalas neturi epg įraÅ¡o!" msgid "no current channel!" msgstr "nÄ—ra Å¡ito kanalo!" msgid "error retrieving status info!" msgstr "negali gauti informacijos apie bÅ«klÄ™!" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" msgid "Wrong username or password" msgstr "Blogas prisijungimo vardas arba slapyvardis" msgid "Login" msgstr "Prisijungimas" msgid "VDR Live Login" msgstr "VDR Live prisijungimas" msgid "User" msgstr "Vartotojo vardas" msgid "What's on?" msgstr "Kas rodoma Å¡iuo metu?" msgid "MultiSchedule" msgstr "" msgid "Search" msgstr "PaieÅ¡ka" msgid "Searchtimers" msgstr "PaieÅ¡kos laikmaÄiai" msgid "Recordings" msgstr "Ä®raÅ¡ai" msgid "Remote Control" msgstr "Distancinis pultas" msgid "Logout" msgstr "Atsijungti" msgid "Your attention is required" msgstr "DÄ—mesio" msgid "React" msgstr "Reguoti" msgid "Dismiss" msgstr "Atmesti" msgid "Now" msgstr "Dabar" msgid "%A, %b %d %Y" msgstr "%A, %b %d %Y" msgid "Time" msgstr "" msgid "Switch to this channel." msgstr "Pereiti į šį kanalÄ…." msgid "Search for repeats." msgstr "IeÅ¡koti pasikartojimų." msgid "Click to view details." msgstr "Spustelkit kad gautumÄ—t daugiau informacijos." msgid "more" msgstr "daugiau" msgid "Channel" msgstr "Kanalas" msgid "Find more at the Internet Movie Database." msgstr "Gauti daugiau informacijos iÅ¡ IMDb." msgid "Stream this channel into browser." msgstr "Transliuoti šį kanalÄ… į narÅ¡yklÄ™." msgid "Stream this recording into browser." msgstr "Transliuoti šį įrašą į narÅ¡yklÄ™." msgid "Record this" msgstr "Ä®raÅ¡yti" msgid "loading data" msgstr "duomenys kraunami" msgid "an error occured!" msgstr "klaida!" msgid "Request succeeded!" msgstr "Užklausa pavyko!" msgid "Request failed!" msgstr "Užklausa nepavyko!" msgid "January" msgstr "Sausis" msgid "February" msgstr "Vasaris" msgid "March" msgstr "Kovas" msgid "April" msgstr "Balandis" msgid "May" msgstr "Gegužė" msgid "June" msgstr "Birželis" msgid "July" msgstr "Liepa" msgid "August" msgstr "RugpjÅ«tis" msgid "September" msgstr "RugsÄ—jis" msgid "October" msgstr "Spalis" msgid "November" msgstr "Lapkritis" msgid "December" msgstr "Gruodis" msgid "retrieving status ..." msgstr "užklausos bÅ«klÄ— ..." msgid "Toggle updates on/off." msgstr "Ä®jungti/IÅ¡junti atnaujinimus" msgid "stop playback" msgstr "sustapdyti grojimÄ…" msgid "resume playback" msgstr "paleisti grojimÄ… iÅ¡ naujo" msgid "pause playback" msgstr "pristapdyti grojimÄ…" msgid "fast rewind" msgstr "greitas atsukimas atgal" msgid "fast forward" msgstr "greitas prasukimas pirmyn" msgid "previous channel" msgstr "prieÅ¡ tai buvÄ™s kanalas" msgid "next channel" msgstr "sekantis kanalas" msgid "No server response!" msgstr "Serveris neatsako!" msgid "Failed to update infobox!" msgstr "Negali atnaujinti infolentelÄ—s!" msgid "Authors" msgstr "Autoriai" msgid "Project Idea" msgstr "Projekto idÄ—ja" msgid "Webserver" msgstr "Web serveris" msgid "Project leader" msgstr "Projekto vadovas" msgid "Content" msgstr "Turinys" msgid "Graphics" msgstr "Grafika" msgid "Information" msgstr "Informacija" msgid "LIVE version" msgstr "LIVE versija" msgid "VDR version" msgstr "VDR versija" msgid "Features" msgstr "SavybÄ—s" msgid "active" msgstr "aktyvus" msgid "required" msgstr "reikalingas" msgid "Homepage" msgstr "Pradžia" msgid "Bugs and suggestions" msgstr "Klaidos ir pasiÅ«lymai" msgid "If you encounter any bugs or would like to suggest new features, please use our bugtracker" msgstr "Jei radote klaidų ar norÄ—tumÄ—te pasiÅ«lyti naujų savybių, raÅ¡ykit į mÅ«sų bugtrakerį" msgid "ERROR:" msgstr "KLAIDA:" msgid "Deleted recording:" msgstr "IÅ¡trynÄ— įrašą:" msgid "List of recordings" msgstr "Ä®rašų sÄ…raÅ¡as" msgid "No recordings found" msgstr "Ä®rašų nÄ—ra" msgid "Delete selected" msgstr "" #, no-c-format msgid "%a," msgstr "%a," #. TRANSLATORS: recording duration format HH:MM #, c-format msgid "(%d:%02d)" msgstr "" msgid "Sort by name" msgstr "" msgid "Sort by date" msgstr "" msgid "Filter" msgstr "" msgid "Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE)." msgstr "" msgid "Expand all folders" msgstr "" msgid "Collapse all folders" msgstr "" msgid "Delete this recording from hard disc!" msgstr "IÅ¡trinti šį įrašą iÅ¡ disko!" msgid "play this recording." msgstr "groti šį įrašą." msgid "Couldn't find channel or no channels available. Maybe you mistyped your request?" msgstr "Kanalas nerastas arba jo iÅ¡ vis nÄ—ra. Gal klaidingai įvedÄ—te paieÅ¡kos frazÄ™?" msgid "Snapshot interval" msgstr "Momentinių nuotraukų intervalas" msgid "No schedules available for this channel" msgstr "Å is kanalas neturi programos" msgid "Search settings" msgstr "PaieÅ¡kos nustatymai" msgid "Extended search" msgstr "IÅ¡plÄ—stinÄ— paieÅ¡ka" msgid "no" msgstr "ne" msgid "Search results" msgstr "PaieÅ¡kos rezultatai" msgid "No search results" msgstr "NÄ—ra paieÅ¡kos rezultatų" msgid "Expression" msgstr "IÅ¡raiÅ¡ka" msgid "Starts between" msgstr "Prasideda tarp" msgid "Toggle search timer actions (in)active" msgstr "Ä®jungti/IÅ¡jungti paieÅ¡kos laikmaÄio aktyvumÄ…" msgid "Browse search timer results" msgstr "NarÅ¡yti po paieÅ¡kos laikmaÄio rezultatus" msgid "Delete this search timer?" msgstr "IÅ¡trinti šį paieÅ¡kos laikmatį?" msgid "Delete search timer" msgstr "IÅ¡trinti paieÅ¡kos laikmatį" msgid "Trigger search timer update" msgstr "Ä®jungti paieÅ¡kos laikmaÄio atnaujinimÄ…" msgid "Please set login and password!" msgstr "Nurodykite prisijungimo vardÄ… ir slapyvardį!" msgid "Setup saved." msgstr "Nustatymai iÅ¡saugoti." msgid "Setup" msgstr "Nustatymai" msgid "User management" msgstr "Vartotojo koregavimas" msgid "Local net (no login required)" msgstr "Vietinis tinklas (nereikalingas prisijungimas)" msgid "Show live logo image" msgstr "Rodyti live įskiepo logotipÄ…" msgid "Use ajax technology" msgstr "Naudoti AJAX" msgid "Show dynamic VDR information box" msgstr "Rodyti dinaminį VDR informacijos skydelį" msgid "Allow video streaming" msgstr "Leisti video transliavimÄ…" msgid "Streamdev server port" msgstr "Streamdev serverio prievadas" msgid "Streamdev stream type" msgstr "Streamdev serverio tipas" msgid "Add links to IMDb" msgstr "PridÄ—ti nuorodas į IMDb" msgid "Additional fixed times in 'What's on?'" msgstr "papildomi nustatyti laikai 'Kas Å¡io metu rodoma?' skiltyje" msgid "Format is HH:MM. Separate multiple times with a semicolon" msgstr "Laiko formatas yra HH:MM. Jei naudosite keletÄ… laikų, atskirkite juos naudodami kabliataÅ¡kį" #, fuzzy msgid "Channel groups for MultiSchedule" msgstr "Kainalas neturi programos apraÅ¡o" msgid "Separate channels with a comma ',', separate groups with a semi-colon ';'" msgstr "" msgid "Duration of MultiSchedule in hours" msgstr "" msgid "Show channels without EPG" msgstr "Rodyti EPG neturinÄius kanalis" msgid "Start page" msgstr "Pradinis puslapis" msgid "Theme" msgstr "Tema" msgid "Timer conflicts" msgstr "LaikmaÄio klaidos" msgid "No timer conflicts" msgstr "NÄ—ra laikmaÄio klaidų" msgid "Timer has a conflict." msgstr "Laikmatis turi klaidų." msgid "Timer is active." msgstr "Laikmatis įjungtas." msgid "Toggle timer active/inactive" msgstr "Perjungti laikmaÄio aktyvumo/neaktyvumo bÅ«senÄ…" msgid "Delete timer" msgstr "IÅ¡trinti laikmatį" msgid "No timer defined" msgstr "Nenustatytas laikmatis" msgid "Timer is recording." msgstr "Laikmatis įraÅ¡inÄ—ja." msgid "Users" msgstr "Vartotojai" msgid "Delete user" msgstr "IÅ¡trinti vartotojÄ…" msgid "VLC: live video stream" msgstr "VLC: gyvas srautas" msgid "VLC: play recording" msgstr "VLC: groti įrašą" msgid "Stop" msgstr "Sustapdyti" msgid "Play" msgstr "Groti" msgid "Sound on" msgstr "Ä®jungti garsÄ…" msgid "Sound off" msgstr "IÅ¡jungti garsÄ…" msgid "Fullscreen" msgstr "Per visÄ… ekranÄ…" msgid "Close" msgstr "Uždaryti" msgid "VLC media URL" msgstr "Adresas VLC grotuvui" #, c-format msgid "%a, %x" msgstr "%a, %x" msgid "What's running on" msgstr "Kas rodoma" msgid "at" msgstr " " msgid "What's on next?" msgstr "Kas bus transliuojama po to?" msgid "Favorites" msgstr "MÄ—giamiausi" msgid "View the schedule of this channel" msgstr "ŽiÅ«rÄ—ti Å¡io kanalo programÄ…" msgid " - " msgstr " - " msgid "Next" msgstr "Sekantis" msgid "What's on" msgstr "Kas rodoma Å¡io metu" msgid "Details view" msgstr "Detalus sÄ…raÅ¡as" msgid "List view" msgstr "SÄ…raÅ¡as" msgid "Live Interactive VDR Environment" msgstr "Live interaktyvioji VDR aplinka" msgid "No EPG information available" msgstr "NÄ—ra EPG informacijos" #, fuzzy #~ msgid "Subtitle" #~ msgstr "Pavadinimas" vdr-plugin-live/javascript/0000755000175000017500000000000012650773437015612 5ustar tobiastobiasvdr-plugin-live/javascript/HOWTO.html0000644000175000017500000002711612650773437017407 0ustar tobiastobias DOM Tooltip Library :: HOWTO

DOM Tooltip Library HOWTO

Usage

This library offers a variety of ways to enable custom tooltips. The standard way of creating a tooltip is to add the domTT_activate() call to one of the event handlers of the target element. Tips can also be created programatically, which can be used for popping up inline windows. Another option is to call the method domTT_replaceTitles(), which replaces all elements containing the class 'tooltip' and the title attribute with a custom tooltip on mouseover.

Examples

<a href="index.html" onmouseover="domTT_activate(this, event, 'content', 'My first tooltip', 'trail', true);">sample link</a>

Options

The only required option to create a tooltip is the 'content' option. Most of the options below have a default value which is held in a global variable. If the option is specified, it overrides the default. The options are summarized below.

caption [text|xhtml|DOM Node]
An auto-generated caption will be created if this text is present. Set this to false when creating a sticky tip to prevent the automatic caption with close link.
content [text|xhtml|DOM Node|function] (required)
The main content of the tip, which may be XHTML text. Note that when using a function, it is only called when the tip is activated, so it is necessary to use 'closeMethod' of 'destroy' to redraw each time.
clearMouse [boolean]
This option flags whether the tip should attempt to avoid the mouse when the direction is south.
closeAction ['hide'|'destroy']
Determines if the tip should be destroyed (removed from DOM) or just hidden when deactivated. (If fading is used, hiding is forced)
closeLink [text|xhtml|DOM Node]
The text that should be used for the auto-generated close link used for sticky tips.
delay [ms]
Time in milliseconds before the tip appears.
direction ['southeast'|'southwest'|'northeast'|'northwest'|'north'|'south']
The position of the tip relative to the mouse.
draggable [boolean]
Determines of the sticky tooltip can be dragged.
fade ['in'|'out'|'neither'|'both']
Sets the alpha effect when the tip is created or destroyed.
fadeMax [0-100]
Sets the maximum alpha that should be used for the alpha effect. (Minimum is always 0, or invisible)
grid [px]
Snaps the trailing to a grid, so that the tip only moves after a set number of pixels.
id [string]
The XML id that should be assigned to the tip. Using this setting allows for external manipulation of the tip.
inframe [boolean]
Hints that the tooltip is inside an iframe, so that the tip can be manipulated from the parent frame.
lifetime [ms]
The duration of time before the tooltip is automatically terminated, as long as it is still activated.
offsetX [px]
The left-to-right offset from the event where the tip should be placed.
offsetY [px]
The top-to-bottom offset from the event where the tip should be placed.
parent [DOM Node]
The parent node on which the tip should be appended. Usually used for tips with a relative position.
position ['absolute'|'relative'|'fixed']
The style position of the tip. (In most cases, the position is 'absolute')
predefined [string]
A reference to a previously defined tooltip using domTT_addPredefined()
statusText [string]
Sets the text to be used in the statusbar when the tip is activated. If used with mouseover, it is necessary to wrap the domTT_activate() call in 'return domTT_true()'.
styleClass [string]
The class that will be assigned to the tip. The contents of the tip is assigned the class 'content' and the caption of the tip is assigned the class 'caption'.
type ['greasy'|'sticky'|'velcro']
Sets the fate of the tip. A greasy tip disappears when a mouse out occurs on owner. A sticky tip stays active until explicitly destroyed (a caption is also forced). A velcro tip disappears when a mouse out occurs on the tip itself.
trail [true|false|'x'|'y']
On which axis the tip should be updated when the mouse moves. A value of true updates on both axes.
lazy [boolean]
Whether or not to enable a delay when updating the mouse position of a trailing tip (drunk tooltip).
width [px]
A manual width for the tip.
maxWidth [px]
A manual maximum width for the tip. (In Firefox, this is controlled by the max-width style of the element)
x [px]
The absolute x position to be used for the tip location. This can be a calculated value, such as 'this.offsetLeft + 5'.
y [px]
The absolute y position to be used for the tip location. This can be a calculated value, such as 'this.offsetTop + 5'.

Function Reference

The DOM tooltip library offers a handful of functions, prefixed with 'domTT_', to aid in manipulating the tooltips. The following is a reference of these function calls.

domTT_activate()
The primary method for activating a tooltip, typically placed in an event handler such as onmouseover. The first two arguments must always be this and event, respectively. These two variable capture the environment on which to act. The rest of the arguments alternate between option name and option value from the list above.
domTT_addPredefined()
For times when tooltip creation should be seperated from activation, this method can be used to prepare the tooltips. The first argument is a unique name for the configuration, and the rest of the arguments alternate between option name and option value from the list of options above. A preconfigured tip can be reused any number of times, and the activate call can override options in the predefined configuration. A typical activate call for a predefined tooltip looks like: domTT_activate(this, event, 'predefined', 'mytip')
domTT_close()
A more flexible alternative to domTT_deactivate(), this function assists in immediately closing the tooltip. The argument can either be a child object of the tip, the tip id or the owner id. From within a tooltip, the call is typically: domTT_close(this)
domTT_deactivate()
In most cases, this method is automatically registered on the target element when domTT_activate() is first called. However, it may be necessary to programmatically close a tooltip. In this case, this method can be used. It requires one parameter, which can be the ID of the tooltip, the ID of the target or the target object itself.
domTT_mouseout()
When a tooltip is activate, it automatically registers a mouseout handler to close to tooltip unless one already exists. If you intend to have a custom mouseout handler on the target that activates the tip, you must make a call to domTT_mouseout(this, event) from within your mouseout handler. Otherwise, the tooltip will never be deactivated!
domTT_update()
If you find that you need to update the contents or caption of a tooltip after it has been created, you will find this function convenient. You must specify a tooltip id, target id or target node and new text or XHTML content and it will be used to replace the content of the existing tooltip. The third parameter allows you to specify either 'content' or 'caption', though it is optional and 'content' is the default.
makeTrue()/makeFalse()
These methods are indended soley for coaxing the return value of an event handler. Of times, it is necessary to return either true or false to the event handler, regardless of what the function in the handler might return. These methods will guarantee that result. For instance, the onclick handler must return false for a link or else the browser will follow the target href. Conversely, the handler must return true or else the browser will stall. These methods just help to achieve the desired behavior.

Global Settings

All of the options above can be used a global settings by prepending the 'domTT_' prefix. These assignments are a good way to establish common behaviors for your tooltips on the webpage. A couple of additional settings are documented here. Be sure to include your custom values below the point when the domTT library is included so that they override the default values.

domTT_oneOnly
Set to this true to allow only one active tip at a time. When a tooltip is created, it will deactivate the last opened tooltip. You can access the last opened tooltip using the global variable domTT_lastOpened
fading
In order to use the fading feature, you must include the library fadomatic.js in your web page. See examples #5.
dragging
In order to drag tooltips, you must include the library domTT_drag.js in your web page. See example #4.
domTT_useGlobalMousePosition
This setting will allow domTT to register an event handler on the document to track the position of the mouse. Registering this event allows the trailing feature to behave more smoothly.
domTT_screenEdgeDetection
Enable the screen edge detection feature, which will prevent the tip from leaving the page. Setting this to false disables this feature.
domTT_screenEdgePadding
When using screen edge detection, this setting specifies how close to the edge the tip should be allowed to travel.
domTT_detectCollisions
If you would rather not having the select boxes and other interfering elements hidden when a visual collision is detected, you may turn off the functionality globally using this flag.

Common Problems

  • If tips are not disappearing in low latency situations, use onmouseover = domTT_deactivate(this.id); to be sure it is discarded. (It seems, though, that a bug fix in 0.7.3 solved this problem.)
  • If the error 'operation aborted' is being thrown in IE, use the domTT_postponeActivation along with domTT_documentLoaded to prevent these types of page load problems.
  • To get dynamic updates on your tips using AJAX, you can either address the tip by its id, manipulate the node linked to the content, or use this domTT_update method. This point to remember is that the content is only processed when the tip is activated.
  • Disabled form fields do not have positions in the page. This prevents tooltips from being placed next to them. In order to use tooltips with form fields that are inactive, please use the onfocus="this.blur()" trick along with appropriate visual styling. In general, the disabled attribute causes other side-effects anyway.
vdr-plugin-live/javascript/README0000644000175000017500000001550712650773437016502 0ustar tobiastobias$Id: README,v 1.1 2007/01/04 22:29:18 thomas Exp $ Project: DOM Tooltip Maintainer: Dan Allen (Mojavelinux) Contributors: Josh Gross (JPortalHome) Jason Rust (CodeJanitor) License: Apache 2.0 What is it? ----------- This javascript library will allow you to have dynamic and configurable tooltips on your html pages. There are several other tooltip libraries on the web, but you will find that this library is very complete and stable. It includes support for all the modern browsers and behaves in a consistent way across these platforms. This library does not support Netscape 4. Netscape 4 is no longer an acceptable browser and it is time to move forward. That is why I prefixed the project title with DOM. If your browser doesn't support the DOM standard, then this library won't work. How does it work? ----------------- This library supports Gecko (Mozilla/Netscape6+,Firefox, etc), IE 5.5+, IE on Mac, Safari, Konqueror and Opera 7 (which includes full DOM and CSS2 support). The tooltips are configured through class definitions in your stylesheet and the rest is up to javascript. The tooltips may consist of two parts, the caption and the content. The caption is optional. The tips can either be greasy, sticky, or velcro. Greasy means that they move around when you move the mouse around and go away when you leave the element. Sticky means that they stick around after you leave the element and are otherwise stationary. Velcro tips disappear after a mouseout occurs on the tip itself. The tooltips also have directionality, so you can have tips that are 'northeast', 'northwest', 'southeast' or 'southwest' of the mouse. Be sure to include the file 'domLib.js' whereever you use 'domTT.js' and if you want to have draggable tips or opacity fading, include the 'domTT_drag.js' and 'fadomatic.js' files as well. **Some of these libraries are available under the domLib project.** Please see the HOWTO.html for details on how to use the library and the options that are available. Why is this program so big? --------------------------- Partly because it is feature rich and thus there is lots of code, partly because we try to use comments where ever necessary to clarify issues, and partly because our coding style is one which makes liberal use of whitespace. However, to save your users the trouble of downloading 50k of JavaScript every time they come to your page you can use Douglas Crockford's excellent jsmin program to strip all non-essentials from the code, reducing it's size by as much as 50%. This program has been verified to work with his program, located at: http://www.crockford.com/javascript/jsmin.html An example usage would be: bash# ./jsmin domTT.js domTT_min.js \ "domTT is Copyright Dan Allen (dan.allen@mojavelinux.com) (2002 - 2005). Licensed under the Apache 2.0 license" Anything I should know? ----------------------- Additionally, this tooltip library autodetects select boxes in IE and the scrollbar on multiple selects in mozilla (the only issue mozilla has) and HIDES them whenever the tooltip collides with them. Hence, it has full collision detection with components which cannot use the zIndex propery!! In order for it to work correctly you'll want to follow the example stylesheet pretty closely. It has been crafted to work well on all the supported browsers. Note the body { margin: 0; } style which is needed if you want it to work decently on Mac IE and Opera. (According the W3C standard, a body cannot have a margin anyway). By default, the library accounts for the size of the mouse when the tip is in one of the two southern positions. If you need to turn off this correction on a given tip, set the option 'clearMouse' to false. If the size of the mouse needs to be adjusted, overwrite the global variable domTT_mouseHeight. In 0.7.1, the hiding of flash animations was added for those browsers that cannot put html over top of flash. However, there are a couple of requirements. First, the syntax that must be used is: ...alternate (non-flash) html here!... If you use the object+embed syntax, the flash will not be properly detected. The second requirement is that the flash must be included in an element with a position of either absolute or relative. If it is not, the flash animation will be relocated in the DOM and therefore will not be aware of its location on the page, making collision detection worthless. Why did you write it? --------------------- The reason I wrote this library is because I wanted a library which used 100% DOM to do the tooltips, was easy to configure, was fast, and which was freely distributable. You may use this library in personal or company, open source or proprietry projects. I wrote it for you, so enjoy it. All I ask is that you spread the word and please give me credit by leaving in my comments. If you do make patches, please let me know about them on my forums. Viva Open Source!! Important Changes in 0.7.1 -------------------------- Fading library is now fadomatic.js, so be sure to change your include when using the fade feature. This is a third party library developed by fadomatic@chimpen.com. You can find this library at the following URL: http://chimpen.com/fadomatic The global setting domTT_classPrefix was changed to domTT_styleClass and the equivalent options without the domTT_ prefix in the domTT_activate() function call have been changed. Important Changes in 0.70 ----------------------------- IE 5.0 is no longer supported because its DOM implementation is just too crippled. Many of the complaints about the positioning of the tips and the screen edge detecting are now fixed. Important API Changes in 0.60 ------------------------------ The release is 0.60 and it introduced several significant changes over the 0.55 release. Several of the options have changed names. The following is a list: 'status' -> 'statusText' 'close' -> 'closeAction' 'prefix' -> 'classPrefix' 'id' -> *no longer an option* There is also a new option 'trail' which is used in place of mousemove. Do not use domTT_activate() in the onmousemove event handler any longer!!! It was far too slow to parse the same options all over again from onmouseover, so now just specify the domTT_activate() in onmouseover with the option trail. Also to note, the functions domTT_true() and domTT_false() have been changed to makeTrue() and makeFalse() respectively to make them more understandable. Be sure to include the file 'domLib.js' whereever you use 'domTT.js' and if you want to have draggable tips or opacity fading, include the 'domTT_drag.js' and 'fadomatic.js' files as well. vdr-plugin-live/javascript/domTT_drag.js0000644000175000017500000000504012650773437020173 0ustar tobiastobias/** $Id: domTT_drag.js,v 1.1 2007/01/04 22:29:18 thomas Exp $ */ // {{{ license /* * Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // }}} // {{{ globals (DO NOT EDIT) var domTT_dragEnabled = true; var domTT_currentDragTarget; var domTT_dragMouseDown; var domTT_dragOffsetLeft; var domTT_dragOffsetTop; // }}} // {{{ domTT_dragStart() function domTT_dragStart(in_this, in_event) { if (typeof(in_event) == 'undefined') { in_event = window.event; } var eventButton = in_event[domLib_eventButton]; if (eventButton != 1 && !domLib_isKHTML) { return; } domTT_currentDragTarget = in_this; in_this.style.cursor = 'move'; // upgrade our z-index in_this.style.zIndex = ++domLib_zIndex; var eventPosition = domLib_getEventPosition(in_event); var targetPosition = domLib_getOffsets(in_this); domTT_dragOffsetLeft = eventPosition.get('x') - targetPosition.get('left'); domTT_dragOffsetTop = eventPosition.get('y') - targetPosition.get('top'); domTT_dragMouseDown = true; } // }}} // {{{ domTT_dragUpdate() function domTT_dragUpdate(in_event) { if (domTT_dragMouseDown) { if (domLib_isGecko) { window.getSelection().removeAllRanges() } if (domTT_useGlobalMousePosition && domTT_mousePosition != null) { var eventPosition = domTT_mousePosition; } else { if (typeof(in_event) == 'undefined') { in_event = window.event; } var eventPosition = domLib_getEventPosition(in_event); } domTT_currentDragTarget.style.left = (eventPosition.get('x') - domTT_dragOffsetLeft) + 'px'; domTT_currentDragTarget.style.top = (eventPosition.get('y') - domTT_dragOffsetTop) + 'px'; // update the collision detection domLib_detectCollisions(domTT_currentDragTarget); } } // }}} // {{{ domTT_dragStop() function domTT_dragStop() { if (domTT_dragMouseDown) { domTT_dragMouseDown = false; domTT_currentDragTarget.style.cursor = 'default'; domTT_currentDragTarget = null; if (domLib_isGecko) { window.getSelection().removeAllRanges() } } } // }}} vdr-plugin-live/javascript/fadomatic.js0000644000175000017500000001075412650773437020106 0ustar tobiastobias/** $Id: fadomatic.js,v 1.1 2007/01/04 22:29:18 thomas Exp $ */ // Title: Fadomatic // Version: 1.2 // Homepage: http://chimpen.com/fadomatic // Author: Philip McCarthy // Fade interval in milliseconds // Make this larger if you experience performance issues Fadomatic.INTERVAL_MILLIS = 50; // Creates a fader // element - The element to fade // speed - The speed to fade at, from 0.0 to 100.0 // initialOpacity (optional, default 100) - element's starting opacity, 0 to 100 // minOpacity (optional, default 0) - element's minimum opacity, 0 to 100 // maxOpacity (optional, default 0) - element's minimum opacity, 0 to 100 function Fadomatic (element, rate, initialOpacity, minOpacity, maxOpacity) { this._element = element; this._intervalId = null; this._rate = rate; this._isFadeOut = true; // Set initial opacity and bounds // NB use 99 instead of 100 to avoid flicker at start of fade this._minOpacity = 0; this._maxOpacity = 99; this._opacity = 99; if (typeof minOpacity != 'undefined') { if (minOpacity < 0) { this._minOpacity = 0; } else if (minOpacity > 99) { this._minOpacity = 99; } else { this._minOpacity = minOpacity; } } if (typeof maxOpacity != 'undefined') { if (maxOpacity < 0) { this._maxOpacity = 0; } else if (maxOpacity > 99) { this._maxOpacity = 99; } else { this._maxOpacity = maxOpacity; } if (this._maxOpacity < this._minOpacity) { this._maxOpacity = this._minOpacity; } } if (typeof initialOpacity != 'undefined') { if (initialOpacity > this._maxOpacity) { this._opacity = this._maxOpacity; } else if (initialOpacity < this._minOpacity) { this._opacity = this._minOpacity; } else { this._opacity = initialOpacity; } } // See if we're using W3C opacity, MSIE filter, or just // toggling visiblity if(typeof element.style.opacity != 'undefined') { this._updateOpacity = this._updateOpacityW3c; } else if(typeof element.style.filter != 'undefined') { // If there's not an alpha filter on the element already, // add one if (element.style.filter.indexOf("alpha") == -1) { // Attempt to preserve existing filters var existingFilters=""; if (element.style.filter) { existingFilters = element.style.filter+" "; } element.style.filter = existingFilters+"alpha(opacity="+this._opacity+")"; } this._updateOpacity = this._updateOpacityMSIE; } else { this._updateOpacity = this._updateVisibility; } this._updateOpacity(); } // Initiates a fade out Fadomatic.prototype.fadeOut = function () { this._isFadeOut = true; this._beginFade(); } // Initiates a fade in Fadomatic.prototype.fadeIn = function () { this._isFadeOut = false; this._beginFade(); } // Makes the element completely opaque, stops any fade in progress Fadomatic.prototype.show = function () { this.haltFade(); this._opacity = this._maxOpacity; this._updateOpacity(); } // Makes the element completely transparent, stops any fade in progress Fadomatic.prototype.hide = function () { this.haltFade(); this._opacity = 0; this._updateOpacity(); } // Halts any fade in progress Fadomatic.prototype.haltFade = function () { clearInterval(this._intervalId); } // Resumes a fade where it was halted Fadomatic.prototype.resumeFade = function () { this._beginFade(); } // Pseudo-private members Fadomatic.prototype._beginFade = function () { this.haltFade(); var objref = this; this._intervalId = setInterval(function() { objref._tickFade(); },Fadomatic.INTERVAL_MILLIS); } Fadomatic.prototype._tickFade = function () { if (this._isFadeOut) { this._opacity -= this._rate; if (this._opacity < this._minOpacity) { this._opacity = this._minOpacity; this.haltFade(); } } else { this._opacity += this._rate; if (this._opacity > this._maxOpacity ) { this._opacity = this._maxOpacity; this.haltFade(); } } this._updateOpacity(); } Fadomatic.prototype._updateVisibility = function () { if (this._opacity > 0) { this._element.style.visibility = 'visible'; } else { this._element.style.visibility = 'hidden'; } } Fadomatic.prototype._updateOpacityW3c = function () { this._element.style.opacity = this._opacity/100; this._updateVisibility(); } Fadomatic.prototype._updateOpacityMSIE = function () { this._element.filters.alpha.opacity = this._opacity; this._updateVisibility(); } Fadomatic.prototype._updateOpacity = null; vdr-plugin-live/javascript/ajax.js0000644000175000017500000000325212650773437017075 0ustar tobiastobiasfunction LiveAjaxCall(mode, url) { var xml = null; if (window.XMLHttpRequest) { xml = new XMLHttpRequest(); if (("xml" == mode) && xml.overrideMimeType) xml.overrideMimeType('text/xml'); } else if (window.ActiveXObject) { try { xml = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xml = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } this.url = url; this.xml = xml; this.onerror = function(message) {}; this.oncomplete = function() {}; this.request = function(param, value) { var url = this.url; if (param != "") { var url = this.url+'?'+param+"="+value; } var obj = this; this.xml.onreadystatechange = function() { obj.readystatechanged(); } this.xml.open('GET', url, true); this.xml.send(null); }; this.readystatechanged = function() { try { if (this.xml.readyState == 4) { if (this.xml.status == 200) { if ("xml" == mode) { var xmldoc = xml.responseXML; var result = Number(xmldoc.getElementsByTagName('response').item(0).firstChild.data); if (!result) { var error = xmldoc.getElementsByTagName('error').item(0).firstChild.data; this.onerror(error); } else { this.oncomplete(); } } else { this.oncomplete(); } } else { this.onerror('Invocation of webservice "'+this.url+'" failed with http status code '+this.xml.status); } } } catch (e) { this.onerror('Invocation of webservice "'+this.url+'" failed with exception: '+e.message); } }; } function LiveSimpleAjaxRequest(url, param, value) { var xml = new LiveAjaxCall("xml", url); xml.onerror = function(message) { alert(message); } xml.request(param, value); }; vdr-plugin-live/javascript/domLib.js0000644000175000017500000004105512650773437017363 0ustar tobiastobias/** $Id: domLib.js,v 1.1 2007/01/04 22:29:18 thomas Exp $ */ // {{{ license /* * Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // }}} // {{{ intro /** * Title: DOM Library Core * Version: 0.70 * * Summary: * A set of commonly used functions that make it easier to create javascript * applications that rely on the DOM. * * Updated: 2005/05/17 * * Maintainer: Dan Allen * Maintainer: Jason Rust * * License: Apache 2.0 */ // }}} // {{{ global constants (DO NOT EDIT) // -- Browser Detection -- var domLib_userAgent = navigator.userAgent.toLowerCase(); var domLib_isMac = navigator.appVersion.indexOf('Mac') != -1; var domLib_isWin = domLib_userAgent.indexOf('windows') != -1; // NOTE: could use window.opera for detecting Opera var domLib_isOpera = domLib_userAgent.indexOf('opera') != -1; var domLib_isOpera7up = domLib_userAgent.match(/opera.(7|8)/i); var domLib_isSafari = domLib_userAgent.indexOf('safari') != -1; var domLib_isKonq = domLib_userAgent.indexOf('konqueror') != -1; // Both konqueror and safari use the khtml rendering engine var domLib_isKHTML = (domLib_isKonq || domLib_isSafari || domLib_userAgent.indexOf('khtml') != -1); var domLib_isIE = (!domLib_isKHTML && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1 || domLib_userAgent.indexOf('msie 7') != -1)); var domLib_isIE5up = domLib_isIE; var domLib_isIE50 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1); var domLib_isIE55 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1); var domLib_isIE5 = (domLib_isIE50 || domLib_isIE55); // safari and konq may use string "khtml, like gecko", so check for destinctive / var domLib_isGecko = domLib_userAgent.indexOf('gecko/') != -1; var domLib_isMacIE = (domLib_isIE && domLib_isMac); var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50 && !domLib_isMacIE; var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55; // -- Browser Abilities -- var domLib_standardsMode = (document.compatMode && document.compatMode == 'CSS1Compat'); var domLib_useLibrary = (domLib_isOpera7up || domLib_isKHTML || domLib_isIE5up || domLib_isGecko || domLib_isMacIE || document.defaultView); // fixed in Konq3.2 var domLib_hasBrokenTimeout = (domLib_isMacIE || (domLib_isKonq && domLib_userAgent.match(/konqueror\/3.([2-9])/) == null)); var domLib_canFade = (domLib_isGecko || domLib_isIE || domLib_isSafari || domLib_isOpera); var domLib_canDrawOverSelect = (domLib_isMac || domLib_isOpera || domLib_isGecko); var domLib_canDrawOverFlash = (domLib_isMac || domLib_isWin); // -- Event Variables -- var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget'; var domLib_eventButton = domLib_isIE ? 'button' : 'which'; var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget'; var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer'; // NOTE: a bug exists in Opera that prevents maxWidth from being set to 'none', so we make it huge var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none'; var domLib_hidePosition = '-1000px'; var domLib_scrollbarWidth = 14; var domLib_autoId = 1; var domLib_zIndex = 100; // -- Detection -- var domLib_collisionElements; var domLib_collisionsCached = false; var domLib_timeoutStateId = 0; var domLib_timeoutStates = new Hash(); // }}} // {{{ DOM enhancements if (!document.ELEMENT_NODE) { document.ELEMENT_NODE = 1; document.ATTRIBUTE_NODE = 2; document.TEXT_NODE = 3; document.DOCUMENT_NODE = 9; document.DOCUMENT_FRAGMENT_NODE = 11; } function domLib_clone(obj) { var copy = {}; for (var i in obj) { var value = obj[i]; try { if (value != null && typeof(value) == 'object' && value != window && !value.nodeType) { copy[i] = domLib_clone(value); } else { copy[i] = value; } } catch(e) { copy[i] = value; } } return copy; } // }}} // {{{ class Hash() function Hash() { this.length = 0; this.numericLength = 0; this.elementData = []; for (var i = 0; i < arguments.length; i += 2) { if (typeof(arguments[i + 1]) != 'undefined') { this.elementData[arguments[i]] = arguments[i + 1]; this.length++; if (arguments[i] == parseInt(arguments[i])) { this.numericLength++; } } } } // using prototype as opposed to inner functions saves on memory Hash.prototype.get = function(in_key) { if (typeof(this.elementData[in_key]) != 'undefined') { return this.elementData[in_key]; } return null; } Hash.prototype.set = function(in_key, in_value) { if (typeof(in_value) != 'undefined') { if (typeof(this.elementData[in_key]) == 'undefined') { this.length++; if (in_key == parseInt(in_key)) { this.numericLength++; } } return this.elementData[in_key] = in_value; } return false; } Hash.prototype.remove = function(in_key) { var tmp_value; if (typeof(this.elementData[in_key]) != 'undefined') { this.length--; if (in_key == parseInt(in_key)) { this.numericLength--; } tmp_value = this.elementData[in_key]; delete this.elementData[in_key]; } return tmp_value; } Hash.prototype.size = function() { return this.length; } Hash.prototype.has = function(in_key) { return typeof(this.elementData[in_key]) != 'undefined'; } Hash.prototype.find = function(in_obj) { for (var tmp_key in this.elementData) { if (this.elementData[tmp_key] == in_obj) { return tmp_key; } } return null; } Hash.prototype.merge = function(in_hash) { for (var tmp_key in in_hash.elementData) { if (typeof(this.elementData[tmp_key]) == 'undefined') { this.length++; if (tmp_key == parseInt(tmp_key)) { this.numericLength++; } } this.elementData[tmp_key] = in_hash.elementData[tmp_key]; } } Hash.prototype.compare = function(in_hash) { if (this.length != in_hash.length) { return false; } for (var tmp_key in this.elementData) { if (this.elementData[tmp_key] != in_hash.elementData[tmp_key]) { return false; } } return true; } // }}} // {{{ domLib_isDescendantOf() function domLib_isDescendantOf(in_object, in_ancestor, in_bannedTags) { if (in_object == null) { return false; } if (in_object == in_ancestor) { return true; } if (typeof(in_bannedTags) != 'undefined' && (',' + in_bannedTags.join(',') + ',').indexOf(',' + in_object.tagName + ',') != -1) { return false; } while (in_object != document.documentElement) { try { if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor) { return true; } else if ((tmp_object = in_object.parentNode) == in_ancestor) { return true; } else { in_object = tmp_object; } } // in case we get some wierd error, assume we left the building catch(e) { return false; } } return false; } // }}} // {{{ domLib_detectCollisions() /** * For any given target element, determine if elements on the page * are colliding with it that do not obey the rules of z-index. */ function domLib_detectCollisions(in_object, in_recover, in_useCache) { // the reason for the cache is that if the root menu is built before // the page is done loading, then it might not find all the elements. // so really the only time you don't use cache is when building the // menu as part of the page load if (!domLib_collisionsCached) { var tags = []; if (!domLib_canDrawOverFlash) { tags[tags.length] = 'object'; } if (!domLib_canDrawOverSelect) { tags[tags.length] = 'select'; } domLib_collisionElements = domLib_getElementsByTagNames(tags, true); domLib_collisionsCached = in_useCache; } // if we don't have a tip, then unhide selects if (in_recover) { for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++) { var thisElement = domLib_collisionElements[cnt]; if (!thisElement.hideList) { thisElement.hideList = new Hash(); } thisElement.hideList.remove(in_object.id); if (!thisElement.hideList.length) { domLib_collisionElements[cnt].style.visibility = 'visible'; if (domLib_isKonq) { domLib_collisionElements[cnt].style.display = ''; } } } return; } else if (domLib_collisionElements.length == 0) { return; } // okay, we have a tip, so hunt and destroy var objectOffsets = domLib_getOffsets(in_object); for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++) { var thisElement = domLib_collisionElements[cnt]; // if collision element is in active element, move on // WARNING: is this too costly? if (domLib_isDescendantOf(thisElement, in_object)) { continue; } // konqueror only has trouble with multirow selects if (domLib_isKonq && thisElement.tagName == 'SELECT' && (thisElement.size <= 1 && !thisElement.multiple)) { continue; } if (!thisElement.hideList) { thisElement.hideList = new Hash(); } var selectOffsets = domLib_getOffsets(thisElement); var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2)); var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius'); // the encompassing circles are overlapping, get in for a closer look if (center2centerDistance < radiusSum) { // tip is left of select if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) || // tip is right of select (objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) || // tip is above select (objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) || // tip is below select (objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom'))) { thisElement.hideList.remove(in_object.id); if (!thisElement.hideList.length) { thisElement.style.visibility = 'visible'; if (domLib_isKonq) { thisElement.style.display = ''; } } } else { thisElement.hideList.set(in_object.id, true); thisElement.style.visibility = 'hidden'; if (domLib_isKonq) { thisElement.style.display = 'none'; } } } } } // }}} // {{{ domLib_getOffsets() function domLib_getOffsets(in_object, in_preserveScroll) { if (typeof(in_preserveScroll) == 'undefined') { in_preserveScroll = false; } var originalObject = in_object; var originalWidth = in_object.offsetWidth; var originalHeight = in_object.offsetHeight; var offsetLeft = 0; var offsetTop = 0; while (in_object) { offsetLeft += in_object.offsetLeft; offsetTop += in_object.offsetTop; in_object = in_object.offsetParent; // consider scroll offset of parent elements if (in_object && !in_preserveScroll) { offsetLeft -= in_object.scrollLeft; offsetTop -= in_object.scrollTop; } } // MacIE misreports the offsets (even with margin: 0 in body{}), still not perfect if (domLib_isMacIE) { offsetLeft += 10; offsetTop += 10; } return new Hash( 'left', offsetLeft, 'top', offsetTop, 'right', offsetLeft + originalWidth, 'bottom', offsetTop + originalHeight, 'leftCenter', offsetLeft + originalWidth/2, 'topCenter', offsetTop + originalHeight/2, 'radius', Math.max(originalWidth, originalHeight) ); } // }}} // {{{ domLib_setTimeout() function domLib_setTimeout(in_function, in_timeout, in_args) { if (typeof(in_args) == 'undefined') { in_args = []; } if (in_timeout == -1) { // timeout event is disabled return 0; } else if (in_timeout == 0) { in_function(in_args); return 0; } // must make a copy of the arguments so that we release the reference var args = domLib_clone(in_args); if (!domLib_hasBrokenTimeout) { return setTimeout(function() { in_function(args); }, in_timeout); } else { var id = domLib_timeoutStateId++; var data = new Hash(); data.set('function', in_function); data.set('args', args); domLib_timeoutStates.set(id, data); data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout)); return id; } } // }}} // {{{ domLib_clearTimeout() function domLib_clearTimeout(in_id) { if (!domLib_hasBrokenTimeout) { if (in_id > 0) { clearTimeout(in_id); } } else { if (domLib_timeoutStates.has(in_id)) { clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId')) domLib_timeoutStates.remove(in_id); } } } // }}} // {{{ domLib_getEventPosition() function domLib_getEventPosition(in_eventObj) { var eventPosition = new Hash('x', 0, 'y', 0, 'scrollX', 0, 'scrollY', 0); // IE varies depending on standard compliance mode if (domLib_isIE) { var doc = (domLib_standardsMode ? document.documentElement : document.body); // NOTE: events may fire before the body has been loaded if (doc) { eventPosition.set('x', in_eventObj.clientX + doc.scrollLeft); eventPosition.set('y', in_eventObj.clientY + doc.scrollTop); eventPosition.set('scrollX', doc.scrollLeft); eventPosition.set('scrollY', doc.scrollTop); } } else { eventPosition.set('x', in_eventObj.pageX); eventPosition.set('y', in_eventObj.pageY); eventPosition.set('scrollX', in_eventObj.pageX - in_eventObj.clientX); eventPosition.set('scrollY', in_eventObj.pageY - in_eventObj.clientY); } return eventPosition; } // }}} // {{{ domLib_cancelBubble() function domLib_cancelBubble(in_event) { var eventObj = in_event ? in_event : window.event; eventObj.cancelBubble = true; } // }}} // {{{ domLib_getIFrameReference() function domLib_getIFrameReference(in_frame) { if (domLib_isGecko || domLib_isIE) { return in_frame.frameElement; } else { // we could either do it this way or require an id on the frame // equivalent to the name var name = in_frame.name; if (!name || !in_frame.parent) { return null; } var candidates = in_frame.parent.document.getElementsByTagName('iframe'); for (var i = 0; i < candidates.length; i++) { if (candidates[i].name == name) { return candidates[i]; } } return null; } } // }}} // {{{ domLib_getElementsByClass() function domLib_getElementsByClass(in_class) { var elements = domLib_isIE5 ? document.all : document.getElementsByTagName('*'); var matches = []; var cnt = 0; for (var i = 0; i < elements.length; i++) { if ((" " + elements[i].className + " ").indexOf(" " + in_class + " ") != -1) { matches[cnt++] = elements[i]; } } return matches; } // }}} // {{{ domLib_getElementsByTagNames() function domLib_getElementsByTagNames(in_list, in_excludeHidden) { var elements = []; for (var i = 0; i < in_list.length; i++) { var matches = document.getElementsByTagName(in_list[i]); for (var j = 0; j < matches.length; j++) { // skip objects that have nested embeds, or else we get "flashing" if (matches[j].tagName == 'OBJECT' && domLib_isGecko) { var kids = matches[j].childNodes; var skip = false; for (var k = 0; k < kids.length; k++) { if (kids[k].tagName == 'EMBED') { skip = true; break; } } if (skip) continue; } if (in_excludeHidden && domLib_getComputedStyle(matches[j], 'visibility') == 'hidden') { continue; } elements[elements.length] = matches[j]; } } return elements; } // }}} // {{{ domLib_getComputedStyle() function domLib_getComputedStyle(in_obj, in_property) { if (domLib_isIE) { var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); }); return eval('in_obj.currentStyle.' + humpBackProp); } // getComputedStyle() is broken in konqueror, so let's go for the style object else if (domLib_isKonq) { //var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); }); return eval('in_obj.style.' + in_property); } else { return document.defaultView.getComputedStyle(in_obj, null).getPropertyValue(in_property); } } // }}} // {{{ makeTrue() function makeTrue() { return true; } // }}} // {{{ makeFalse() function makeFalse() { return false; } // }}} vdr-plugin-live/javascript/AUTHORS0000644000175000017500000000030112650773437016654 0ustar tobiastobiasDOM Tooltip Library 0.70 Maintainer: Dan Allen Contributors: Josh Gross Jason Rust Vic Mackey vdr-plugin-live/javascript/treeview.js0000644000175000017500000000403212650773437020001 0ustar tobiastobias// --------------------------------------------- // --- Name: Easy DHTML Treeview -- // --- Author: D.D. de Kerf -- // --- Adapted: Dieter Hametner -- // --- Version: 0.2 Date: 13-6-2001 -- // --------------------------------------------- function findSibling(node, name) { while ((node.nextSibling.nodeType != Node.ELEMENT_NODE) || (node.nextSibling.nodeName != name)) { node = node.nextSibling; } if (node.nextSibling.nodeName == name) return node.nextSibling; return null; } function findChildNode(node, className) { for (idx = 0; idx < node.childNodes.length; idx++) { n = node.childNodes.item(idx); if (n.nodeType == Node.ELEMENT_NODE) { attr = n.getAttributeNode("class"); if ((attr != null) && (attr.nodeValue == className)) { return n; } } } return null; } function findImageNode(node, className) { for (idx = 0; idx < node.childNodes.length; idx++) { n = node.childNodes.item(idx); if ((n.nodeType == Node.ELEMENT_NODE) && (n.nodeName == "IMG")) { attr = n.getAttributeNode("class"); if ((attr != null) && (attr.nodeValue == className)) { return n; } } } return null; } function setImages(node, expand, folder) { // Change the image (if there is an image) if (node.childNodes.length > 0) { expandNode = findImageNode(node, "recording_expander"); if (expandNode != null) expandNode.src = expand; folderNode = findImageNode(node, "recording_folder"); if (folderNode != null) folderNode.src = folder; } } function Toggle(node) { // Unfold the branch if it isn't visible sibling = findSibling(node, "UL"); if (sibling == null) return; imgChild = findChildNode(node, "recording_imgs"); if (sibling.style.display == 'none') { if (imgChild != null) setImages(imgChild, "img/minus.png", "img/folder_open.png"); sibling.style.display = 'block'; } // Collapse the branch if it IS visible else { if (imgChild != null) setImages(imgChild, "img/plus.png", "img/folder_closed.png"); sibling.style.display = 'none'; } } vdr-plugin-live/javascript/LICENSE0000644000175000017500000002613612650773437016627 0ustar tobiastobias Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. vdr-plugin-live/javascript/BUGS0000644000175000017500000000155112650773437016277 0ustar tobiastobias$Id: BUGS,v 1.1 2007/01/04 22:29:18 thomas Exp $ These are the known bugs/issues in the DOM Tooltip library: - Opera7 popups up a native tooltip title for the link, which goes over the custom tooltip (all you need to do is disable tooltips in the opera preferences) - you cannot use the margin style on the body in Opera7, you have to use padding instead you can read over at opera.com why they don't support this...apparently not a legit style - offset* properties do not account for margins, so styles with margins could lead to issues - fading in and fading out in mozilla is somewhat flaky...it works but has flickering...this flickering is NOT the tooltip code, it is the rendering of the styles in mozilla...only time will help us here (this seems to be resolved in Firefox 1.0) - inframe tips do not appear over top of the iframe in Opera and Konqueror vdr-plugin-live/javascript/Changelog0000644000175000017500000003771312650773437017437 0ustar tobiastobias$Id: Changelog,v 1.1 2007/01/04 22:29:18 thomas Exp $ DOM Tootip: Javascript tooltip generator version 0.7.3 (SVN HEAD): * added example integration with behaviour.js * added domTT_postponeActivation option to workaround 'operation aborted' error * added domTT_closeAll function to remove all tooltips on page * 'content' option can now be a function to return the content * make id prefix configurable * close velcro tip by clicking on it * allow tips to be created with no event (null value) * allow disabling of collision detection * fixed problem of tip not disappearing on rapid mouse movement * fixed problem of using global mouse position before first mouse movement * prevent tooltip events on banned tags, such as OPTION (for consistency) * improvements to example14 to allow caption to render properly version 0.7.2 (2006/04/12): * added example to demonstrate custom positioning with a parent * fixes in clear timeout made in domLib.js * fixed a regression in the collision detection that left elements hidden * content and caption are only cloned if domTT_cloneNodes is set to true, otherwise the reference is used version 0.7.1 (2005/07/16): * changed fading library from alphaAPI to fadomatic * fixed problem with fade where links and buttons would become inactive * fixed problem where tooltips would hang around if browser doesn't support fading * released under Apache 2.0 license * added example for dynamically updating tooltip content * added method for updating tooltip content, domTT_update() * enabled caption to be html or a DOM node * removed the clone() prototype method in domLib to prevent conflicts with other libraries * option to have only one tip show at a time * fixed edge detection to be more precise * added fadeMax as upper limit for an alpha fade-in * fixed wrapping problem when tip nears edge in opera and IE * replace domLib_isKonq with domLib_isKHTML * added auto-generated tooltips from the title attribute for elements with class "tooltip" * custom offsets can be set on a per-tip basis * tips are now indexed on both tip id and owner id, for greater flexibility * added a convenient method for use in custom close events, domTT_close() * custom id can now be used for the tip for easy reference * domTT_classPrefix is now domTT_styleClass, option classPrefix is now styleClass * wrapper div for contents styled with generic class 'contents' * wrapper for caption is now styled with generic class 'caption' * make drag an optional parameter for tip to turn on/off dragging of sticky tips * trail can now be either 'x' or 'y' which will lock trailing to a single axis * added HOWTO * updated all examples version 0.7.0 (2004/11/10): * Create tip on parent specified instead on document.body and then moving the tip in the DOM * Added a standards mode detection, which was the root of edge bleed issues * Added info in README about how to make the program smaller using jsmin * Fixed memory leaks in IE caused by using inner functions * Now works in Mac IE * Tooltips can be created from a child iframe element * IE 5.0 (Windows) removed from supported list of browsers version 0.6.0 (2003/02/13): * major rewrite (please consult this changelog and example for new requirements) * made fading modular using alphaAPI (seperate file, alphaAPI.js) * large gains in speed and compliance (fix Konq and IE 5 bugs) * eliminate need for domTT_activate() in the mousemove event handler!!! * new option 'trail' to specify tip to follow mouse movement (only for absolute) * changed domTT_true/false() functions to makeTrue/false()!!! * changed option 'status' option to 'statusText'!!! * changed 'prefix' option to 'classPrefix'!!! * changed 'close' option to 'closeAction'!!! * made dragging of tips loadable (seperate file, domTT_drag.js) * divided out common functions from domTT functions (seperate file, domLib.js) * browser detection variables now prefixed with domLib_is*!!! * to create an onload window, first option is unique id (no longer have 'id' option) version 0.5.5 (2003/02/09): * fixed major crashes in IE 5.0 (cannot use delays since setTimeout is buggy) * fixed hideList error in all browsers * fixed a bug on example10.html when using a popup version 0.5.4 (2003/02/05): * fixed a scroll offset problem when IE is in compatibility mode * fixed problem where select box detection nixed element inside tooltip version 0.5.3 (2003/01/29): * fix misspelled document on like 971 in domTT.js version 0.5.2 (2003/01/17): * fix for document.documentElement.scrollTop for IE in standards compliance mode version 0.5.1 (2002/12/19): * implemented callTimeout() as an wrapper for setTimeout() for variable persistence * konqueror can now implement delays for tips!!! * konqueror can now handle tip lifetime!!! * added workaround for some konqueror quirks version 0.5.0 (2002/12/19): * fixed invalid variable name tmp_offsetX...regression from fixes in 0.4.9 version 0.4.9 (2002/12/18): * reworked domTT_deactivate() a bit * can now specify an 'id' option on each tip to have multiple tips on one trigger * fixed the activateTimeout process to rid of lingering bugs * updated demos version 0.4.8 (2002/12/11): * fixed recursion bug version 0.4.7 (2002/12/08): * dragging of sticky tips in konqueror!! * cleaned up the mouseout code a great deal and now it actually works as expected * selects only appear again when all tooltips which hid them are cleared away!!! * fixed IE javascript error caused by global onmousemove operating before page load * simplified deactivate by putting code for unhide selects in detectCollisions() * updated demos version 0.4.6 (2002/12/07): * eliminated unnecessary code in domTT_show() * konqueror fixes (checks in wrong place, clientHeight problem) * fixed onclick x, y measurement in konqueror version 0.4.5 (2002/12/06): * added maxWidth option (false to disable) and width option now independent * added workaround for maxWidth bug in Opera * switch to toggling display property to hide rather than using visibility hidden * fixed error in IE 5.5 bypassing a safeguard and causing a javascript error * fixed compliance error with IE 5.5 when executing IE hack for float * fixed height calculation with IE 5.5 vs IE 6 (compliance difference) * fixed case when hack IE code was executing under the wrong circumstances * fixing small javascript errors * totally block IE 5.0 until I can get to testing it * demo fixes and cleanups * fixed missing check for tip object existance in mouseout function version 0.4.4 (2002/12/06): * fixed onload problem in IE version 0.4.3 (2002/12/05): * code cleanups with strict compliance mozilla * fixed so that using domTT_activate() can be used as an onload event * closeLink will be interpreted as html (but note the link is automatically created) version 0.4.2 (2002/12/05): * fixed missing units in drag update * fixed width calculation in IE in strict mode * fix document.body.clientHeight -> document.documentElement.clientHeight (IE strict.dtd) * catch permission errors in mozilla to write status text version 0.4.1 (2002/12/05): * forget to add contentEditable when made changed to domTT_create() in 0.4.0 * fixes to the domTT_isDescendantOf to exclude absolute elements * fixed error in mozilla (tip was trying to be destroyed twice) * fixed regexp bug in IE 5.01 * fixed link in demo for opera (example8.html) * fixed javascript error in IE when triggerObj was #document * fixed IE bug when contentEditable property was screwing up the height * demo fixes version 0.4.0 (2002/12/02): * add required 'this' add the beginning of every domTT_activate() call * prevent tip from disappearing when mouseout goes to child of target element * tons of code cleanup dealing with onmouseout * 'status' now clears after each mouseout, even if tip is sticky or velcro * added 'width' option, which overides the global domTT_maxWidth (and the style) * merged logic in create() and show() so that create() can use show() (normalize) version 0.3.2 (2002/12/01): * changed 'close' to 'closeLink' since it was confusing what it was * added relative positioned tips (inline), added option 'position' * maxWidth of 0 will be ignored * fixed a fade bug when tooltip object exists (domTT_show()) * several other fade bugs fixed version 0.3.1 (2002/12/01): * 'caption' can be set to false to force it not to show, even when using 'type' sticky * fixed error "Could not get cursor property" in IE5 because must use 'hand' not 'pointer' * misspelled descendant * cleaned up the preserving of onmouseout a ton * 'caption' only has to be set to false if type is 'sticky', otherwise it can be left off * updated demos version 0.3.0 (2002/11/30): * added global domTT_lifetime to set how long the tip stays alive when mouse is stationary * added option 'lifetime' for each individual tip (0 for infinite) * added fixed position tooltip option by passing in 'x' and 'y' as options * changed hash method itemExists to hasItem to be DOM compliant * perserve the onmouseout that existed on the target rather than just overwriting * new type 'velcro', which disappears when you mouseout of the tooltip instead of target * added ability to fade out and changed 'fade' option from boolean to in/out/both/neither * added fade direction to the domTT_doFade() function to hande fade in both directions * made a global variable for domTT_onClose, either 'hide' or 'remove' * changed 'deactivate' option to 'onClose' which can be 'hide' or 'remove' * added 'grid' option and domTT_grid global to snap to a grid on updates (0 for no grid) * got rid of domTT_defaultStatus, just use window.defaultStatus for this value * code cleanups * demo addition and cleanups version 0.2.3 (2002/11/27): * added domTT_false() as a wrapper for links that make IFRAME tooltips to cancel click * fixed case when domTT_isGecko was not deteting select-multiple with size=1 * can specify only 'status' to domTT_activate, and will change status and register clear * made demo pages for library * removed a hack width setting width because I was confused before...and didn't need it * made global setting variable for domTT_prefix version 0.2.2 (2002/11/21): * fade-in on tips!!! (mozilla and IE only) * global option for fade on or off (click events don't use fade ever) * added option to domTT_activate for fade version 0.2.1 (2002/11/21): * perfect support for Opera7 !!! (what a great browser as far as standards go!) * no need for select collision detection in opera (again, tremendous) * prevented the close element from being draggable in all browsers (works this time) * fixed bug that opera does not hide IFRAME children when tip is hidden or destroyed * added domTT_defaultStatus to be used when clearing status bar * for opera, you will want to disable all opera tooltips except 'element titles' * added 'mousedown' as a trigger to set delay to 0 (3 types of mouse depress possible) version 0.2.0 (2002/11/20): * domTT_activate returns the id of the tip if it needs to be referenced externally * added domTT_isActive() to check for an activated tip, returns tip object if active * create domTT_true() function, which should be used to wrap domTT_activate for onmouseover * second option to domTT_deactivate is optional (default to true) * domTT_predefined now takes all the options domTT_activate takes * domTT_activate loads in predefined options if predefined is the first option * domTT_activate uses options from domTT_activate call to override predefined options * take off restriction for status of onmouseover and just let it happen as it will * caption now not used if empty, even if it is sticky (can externally close tip) * added 'contextmenu' event type alongside 'click' for auto changing delay to 0 * if content is empty, bail on creating the tip (hmmm...still thinking on this) * Gecko always makes the tip 4px too wide, for some unknown reason (maybe gecko bug?) * bug in right edge detection (was giving the width the padding instead of taking away) * fixed bug in global onmousemove (wasn't passing event to function for mozilla) * fixed edge detection, which was not accounting for scroll offset * made function domTT_correctEdgeBleed() for edge bleeding (since I used it twice) * code cleanups, added docs and another example page version 0.1.7 (2002/11/18): * domTT_close can be an object, hence an image for an 'X' for close * drag limited to the caption bar for sticky tips * added domTT_addPredefined function for caching tip definitions * added ability to pass in custom prefix for class styles, other than domTT * can pass in 'close' option for text/image to be used as close markup * fixed bug for onmouseover sticky tip which prevented cancel of tip creation onmouseout * added a new example.html file version 0.1.6 (2002/11/17): * added option for directionality in tips (southeast, southwest, northeast, northwest) * set default options at beginning of domTT_activate() instead of checking for each * global setting for mouse height so that offset is from edge of mouse cursor * added LICENSE, README to package * finished screen edge detection and correction * custom close text for sticky * can globally turn off dragging of sticky tips version 0.1.5 (2002/11/16): * ability to grab current mouse position when tip is created on delay * option for not using current mouse position when tip is created on delay (use passed in) * changed mouseover to mousemove for event on the tooltip (prevent artifact tooltips) * added delay as option (will use global if not passed in) * added status as an option, which will change the status bar text * eliminated collision detection delay when tip is already visible * 'sticky' option changed to 'type' and can be 'greasy' or 'sticky' * fixed some serious bugs in setTimout logic when destroying tips * created function domTT_show() for showing hidden tip (previously created) version 0.1.4 (2002/11/15): * ability to drag sticky tooltips (lots of work here) * change domTT_getPosition to domTT_getOffsets * return more information from domTT_getOffsets * simplify domTT_detectCollisions (now requires only one argument) * made function for getting mouse position (since browsers do crazy things) * the 'X' part of the tip is not draggable version 0.1.3 (2002/11/14): * konqueror support (lots of fixes for this) (onclick is somewhate hacked) * browser variables instead of using javascript objects to differentiate * eliminated duplicate mouse_x and mouse_y code * changed lamda function calls in setTimeout to support konqueror * getPosition returns right and bottom as well version 0.1.2 (2002/11/13): * fixed case when you flew over object and then clicked fast to create sticky and it failed * domTT_deactivate now takes an object instead of id (avoids lookup) * fixed problem with onmousemove after onclick beating setTimeout(...,0) on windows * fixed the e.target to e.currentTarget for mozilla (which is the registered target) * sticky tips now work correctly * fixed domTT_detectCollisions to be subject to the activate delay on tip unhide * no longer dependent on global Hash() function...arguments become hash internally * account for the scroll offset when working with event coordinates * compensated for lack of max-width for IE * fixed broken float right for IE (cannot assign through DOM) * float right causes tooltip to stretch to widht of page, fixed that * fixed javascript error because IE doesn't have e.target (event.srcElement instead) version 0.1.1 (2002/11/10): * pass in options as Hash * cache created tips to reuse via visibility style * auto-assign onmouseout to deactivate * add ability to have sticky * implemented zIndex so new tips can go over old tips * no delay for onclick tips * implemented delay when toggling visibility of cached tips * ability to pass in html content version 0.1.0 (2002/10/30): * Initial release vdr-plugin-live/javascript/Makefile0000644000175000017500000000133312650773437017252 0ustar tobiastobias### The official name of this plugin. PLUGIN = live ### Additional options to silence TNTNET warnings TNTFLAGS ?= -Wno-overloaded-virtual -Wno-unused-function ### Includes and Defines (add further entries here): INCLUDES += -I$(VDRDIR)/include -I.. ### The object files (add further files here): OBJS = treeview.o ### The main target: all: libjavascript.a ### Implicit rules: %.o: %.cpp $(CXX) $(CXXFLAGS) $(TNTFLAGS) -c $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $< %.cpp: %.js $(ECPPC) $(ECPPFLAGS) $(ECPPFLAGS_JS) -b -m "text/javascript" $< ### Targets: libjavascript.a: $(OBJS) $(AR) r $@ $^ clean: @rm -f *~ *.o core* libjavascript.a $(OBJS:%.o=%.cpp) dist: clean @echo "Nothing to do for distribution here ..." vdr-plugin-live/javascript/TODO0000644000175000017500000002524012650773437016305 0ustar tobiastobias$Id: TODO,v 1.1 2007/01/04 22:29:18 thomas Exp $ TODO ---- [+] deactivate delay with appropriate timeout cancel handles (can then do the fancy work with velcro tip) [+] use json for options to tip [+] content can be a function, but until tip is destroyed, it isn't called again (call in domTT_show) [+] option to use the DOM node rather than cloning for caption/content [+] possible edge detection problem in Opera [+] build a namespace for dom.lib dom.tt dom.menu or something [+] doInDomTT() which would allow a function to be run when the tip is to be positioned [+] issue a callback to fadomatic to destroy tip on fadeOut completion (allow the destory action for fading tips) [+] make this domTT_runShow more clear as to what it is doing...maybe even rework the timeout process we cannot allow for the timeout to hold onto any object that might reference the DOM, else it won't get garbage collected [+] think about creating a lightweight version that uses replaceTitles [+] create addEvent() function for posting global events [+] lazy trailing broken in Opera [+] maxWidth handling is a bit ugly [+] maybe not show contents when dragging? (also resize of sticky tooltips) [+] drag API / add snap to grid when dragging THOUGHTS -------- [+] make alpha settings a sub-object or array...so we can set: max, step, etc... [+] a more smooth lazy trail should be implemented by not moving the full amount each time [+] make cursor "move" if caption is draggable [+] Konq and Opera don't allow tip to flow over IFRAME in example11...but the code is working NOTES ----- never use: onmouseover = function(e) { ... } as it will create a circular reference because of the function definition [1,2,3] array object {'one' : 1, 'two' : 2} object cannot use setTimeout() with anonymous function in IE 5.0 since it crashes the browser when you execute clearTimeout() following this call in compliance mode, IE measures use document.documentElement for many of the document.body functions Text node cannot have an event in IE, but it can in mozilla IE bubbles by default, which means that the child nodes get the event before the offsetParent nodes setting an event to null in mozilla does not remove events registered using addEventListener...but it does in IE. IE 5.0* does not have the .*? functionality in regexp bug in linux onmousedown causes onmouseout beforehand on IE, if there is an onmousemove and onmouseover, both will fire onmouseover // innerHTML the DOM way var range = document.createRange(); range.selectNodeContents(document.body); var fragment = range.createContextualFragment('test'); var tooltip = document.createElement('div'); tooltip.appendChild(fragment); WHAT I AM NOT THRILLED ABOUT ---------------------------- - (mozilla keeps firing events after javascript functions have been unloaded - when appending a tooltip to a table cell, the table seems to get stretched out DONE ---- [@] delay firing tooltip events until page has loaded (fix IE bug) [@] missing fade should still allow tip to close [@] one tooltip at a time [@] mousemove makes konqueror flip the tip up (was a konqueror bug, fixed in 3.2) [@] IE not detecting bottom edge of browser [@] created global constant for standards mode detection [@] if position relative, don't append to parent until tip is done creating or else parent get's all screwed up [@] show should not set left and top style if position relative [@] incorrect use of pending...pending should be between inactive and active [@] fade fails when mouseout while fading when fading in 'in' only [@] fade in is VERY slow [@] domTT_isActive awkward [@] velcro not working right [@] strange stuff going on when doing click to stick [@] mouseover then mouseout still has issues (sticky tips) [@] what if tooltip is inactive and domTT_activate() fires again [@] fix the FIXME's [@] change domTT_true and domTT_false to makeTrue() and makeFalse() [@] fix fades [@] drag not working [@] put delay back in for IE 5.0/Konq [@] mousemove update is overridden by the mouseover placement, firing at wrong time [@] cut the use of writing onmouseout() if is specified, same with onmousemove (make automatic) [@] get rid of the float and go with tables instead so we can cut code [@] try to speed it up a bit [@] create lite version for simpler cases [@] make a domTT_deactivate() that the user can use to make his/her own onmouseout() [@] check for standards compliance mode, make it work either way [@] problem if select box is inside tooltip [@] infinite recursion bug in konqueror when using onmouseover [@] be able to specify unique id as option [@] use callTimeout [@] problem with the setTimeout calls when using mousemove...before the tooltip activates, many setTimeouts can be registered, but only one can be cancelled [@] have domTT_deactivate take a tip id or a tip object [@] possibly make use of 'this' in the drag functions [@] fix onmouseout to work as expected [@] show off the preserving of the onmouseout [@] talk about the auto width in the demo (which overlib does not have) [@] select detection does not account for visible sticky tooltips...for this we have to have a global hash of the open tips...then, when we are going to change the style of a select element to visible, we check the open tips and make sure it is not conflicting with any of them [@] some demos not working in Konqueror [@] maxWidth handling is a bit awkward [@] velcro having a rough time in IE, and in mozilla linux, cannot mousedown before it closes [@] use typeof() instead of this.undefined [@] strip out the javascript code for reporting errors in the packaged file [@] store onmouseout function in the eventTarget attribute? [@] common function for placing the tip (show and create do this stuff) [@] be able to specify the width [@] make function for domTT_mouseout() [@] think about window.status on Example 4, right link [@] few places where I get the mouse_x/mouse_y when I don't need it (relative position) [@] when doing onmouseout for a greasy, make sure we are not entering a child...hmmm [@] make example for relative position [@] make maxWidth of 0 ignored [@] since we can specify parent, be able to specify relative position or something so that we can just have the tooltip expand into the container [@] have makefile fill in the version [@] if event target is documentElement, coax it to document.body [@] cursor errors in IE 5.5 [@] we don't need domTT_defaultStatus, just use window.defaultStatus [@] add option for lifetime to tip [@] create demo for velcro [@] snap to grid tooltip (problem is we need to determine the difference from where the tip is located now, and where we would put it next, not just the mouse position) [@] be able to fade out on close [@] mouseover tip functionality...be able to keep it open when you mouseover, maybe another type...velcro [@] don't kill the onmouseout the existed on tip...try to just add the close (see foo.html) [@] fixed position tooltip (maybe pass in coordinates) [@] change domTT_deactivate attribute to domTT_destroy [@] tip lifetime for onmouseover [@] set prefix for each tooltip in example pages [@] maybe creat a domTT_writeStatus() function to be used for onmouseover [@] added domTT_false() for onclick events on links that open IFRAMES [@] remove hardcoded -1000px for a setting [@] make fade a passed in option [@] fading tooltip [@] check for valid browser and don't execute if not meet requirements [@] opera7 does not hide contents of IFRAME when tooltip is hidden [@] make domTT_defaultStatus option [@] prevent dragging close element [@] drag bug in Opera 7 [@] full Opera 7 support! [@] try Opera 7 [@] function for detect screen edge? [@] edge detection not account for scroll (messes up placement bigtime when scroll is in effect) [@] if content is empty, need to bail on creating tip [@] why oncontextmenu no deliver onclick [@] add domTT_isActive() [@] add option 'deactivate' to be 'hide' or 'destroy', important for embedded IFRAMES [@] option not to have X for sticky, but put onclick on document [@] maybe remove the restriction for onmouseover and let it happen as it will [@] more options for predefined can come over to tip definition, overridden by those passed in [@] release to dynamic drive ddsubmit@yahoo.com [@] if you have onmouseover sticky, and you mouseover then leave, it doesn't kill tip [@] variable for tipObj visibility state to prevent all the lookups [@] be able to specify style prefix for different styles on different tips [@] add addPredefined() function [@] make only draggable from caption [@] be able to turn off dragging of sticky tips [@] cleaner call to domTT_show() [@] screenshot for freshmeat [@] custom close text [@] full screen edge detection [@] handle the mouse cursor height automatically [@] prettier way to handle default options [@] support for directional tips (extending west from mouse action instead of east) [@] eventDelay should be set to 0 if onmousemove and visible so it updates right away [@] make function for reappear, domTT_show() [@] when mouseover, use most recent location of mouse position [@] perhaps do type instead of 'sticky' true or false? [@] collision detection shouldn't delay when doing mousemove/click and tip is visible [@] adjustable delay for tip in options [@] change in_options to options in domTT_activate [@] drag in IE jumps when select domTTContent area [@] mouseout in IE when sticky active makes select boxes come back, event when tooptip is over it [@] X should not be a dragable part of tooltip [@] function for get mouse event position [@] domTT_detectCollisions should do the lines just above it [@] be able to drag sticky [@] have getPosition return all 4 coordinates [@] konqueror support [@] browser variables [@] code for x and y is twice in the activate function [@] when you fly in and then click on the object while the tip is being created, it bugs out [@] another paramater to domTT_activate() whether to unhide selects [@] domTT_deactivate to take object instead of id [@] fix problem with onmousemove after onclick beating setTimeout(...,0) on windows [@] after we use a sticky, and it is closed, mousemove no longer works [@] if we are sticky, all events on the same object should be cancelled [@] be able to do sticky on click when onmousemove is used for non-sticky [@] hiding of select boxes is not subject to the delay that the tooltip is subject to [@] do internal hash, from the arguments after event [@] itemExists to hash [@] account for scroll offset of page [@] fix max-width for IE [@] fix broken float right for IE [@] fix e.target to event.srcElement for IE [@] need delay on reappear from cache [@] no delay for onclick [@] implement zIndex so new tips can go over old tips [@] cache tooltips created by using visibility style [@] pass in options as Hash [@] auto-assign onmouseout [@] add ability to have sticky (x in caption...what if we don't have caption?) vdr-plugin-live/javascript/alphaAPI.js0000644000175000017500000001460312650773437017573 0ustar tobiastobias/** $Id: alphaAPI.js,v 1.1 2007/01/04 22:29:18 thomas Exp $ */ // {{{ license /* * Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // }}} // {{{ intro /** * Title: alphaAPI * Original Author: chrisken * Original Url: http://www.cs.utexas.edu/users/chrisken/alphaapi.html * * Modified by Dan Allen * Note: When the stopAlpha is reached and it is equal to 0, the element's * style is set to display: none to fix a bug in domTT */ // }}} function alphaAPI(element, fadeInDelay, fadeOutDelay, startAlpha, stopAlpha, offsetTime, deltaAlpha) { // {{{ properties this.element = typeof(element) == 'object' ? element : document.getElementById(element); this.fadeInDelay = fadeInDelay || 40; this.fadeOutDelay = fadeOutDelay || this.fadeInDelay; this.startAlpha = startAlpha; this.stopAlpha = stopAlpha; // make sure a filter exists so an error is not thrown if (typeof(this.element.filters) == 'object') { if (typeof(this.element.filters.alpha) == 'undefined') { this.element.style.filter += 'alpha(opacity=100)'; } } this.offsetTime = (offsetTime || 0) * 1000; this.deltaAlpha = deltaAlpha || 10; this.timer = null; this.paused = false; this.started = false; this.cycle = false; this.command = function() {}; return this; // }}} } // use prototype methods to save memory // {{{ repeat() alphaAPI.prototype.repeat = function(repeat) { this.cycle = repeat ? true : false; } // }}} // {{{ setAlphaBy() alphaAPI.prototype.setAlphaBy = function(deltaAlpha) { this.setAlpha(this.getAlpha() + deltaAlpha); } // }}} // {{{ toggle() alphaAPI.prototype.toggle = function() { if (!this.started) { this.start(); } else if (this.paused) { this.unpause(); } else { this.pause(); } } // }}} // {{{ timeout() alphaAPI.prototype.timeout = function(command, delay) { this.command = command; this.timer = setTimeout(command, delay); } // }}} // {{{ setAlpha() alphaAPI.prototype.setAlpha = function(opacity) { if (typeof(this.element.filters) == 'object') { this.element.filters.alpha.opacity = opacity; } else if (this.element.style.setProperty) { this.element.style.setProperty('opacity', opacity / 100, ''); // handle the case of mozilla < 1.7 this.element.style.setProperty('-moz-opacity', opacity / 100, ''); // handle the case of old kthml this.element.style.setProperty('-khtml-opacity', opacity / 100, ''); } } // }}} // {{{ getAlpha() alphaAPI.prototype.getAlpha = function() { if (typeof(this.element.filters) == 'object') { return this.element.filters.alpha.opacity; } else if (this.element.style.getPropertyValue) { var opacityValue = this.element.style.getPropertyValue('opacity'); // handle the case of mozilla < 1.7 if (opacityValue == '') { opacityValue = this.element.style.getPropertyValue('-moz-opacity'); } // handle the case of old khtml if (opacityValue == '') { opacityValue = this.element.style.getPropertyValue('-khtml-opacity'); } return opacityValue * 100; } return 100; } // }}} // {{{ start() alphaAPI.prototype.start = function() { this.started = true; this.setAlpha(this.startAlpha); // determine direction if (this.startAlpha > this.stopAlpha) { var instance = this; this.timeout(function() { instance.fadeOut(); }, this.offsetTime); } else { var instance = this; this.timeout(function() { instance.fadeIn(); }, this.offsetTime); } } // }}} // {{{ stop() alphaAPI.prototype.stop = function() { this.started = false; this.setAlpha(this.stopAlpha); if (this.stopAlpha == 0) { this.element.style.display = 'none'; } this.stopTimer(); this.command = function() {}; } // }}} // {{{ reset() alphaAPI.prototype.reset = function() { this.started = false; this.setAlpha(this.startAlpha); this.stopTimer(); this.command = function() {}; } // }}} // {{{ pause() alphaAPI.prototype.pause = function() { this.paused = true; this.stopTimer(); } // }}} // {{{ unpause() alphaAPI.prototype.unpause = function() { this.paused = false; if (!this.started) { this.start(); } else { this.command(); } } // }}} // {{{ stopTimer() alphaAPI.prototype.stopTimer = function() { clearTimeout(this.timer); this.timer = null; } // }}} // {{{ fadeOut() alphaAPI.prototype.fadeOut = function() { this.stopTimer(); if (this.getAlpha() > this.stopAlpha) { this.setAlphaBy(-1 * this.deltaAlpha); var instance = this; this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay); } else { if (this.cycle) { var instance = this; this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay); } else { if (this.stopAlpha == 0) { this.element.style.display = 'none'; } this.started = false; } } } // }}} // {{{ fadeIn() alphaAPI.prototype.fadeIn = function() { this.stopTimer(); if (this.getAlpha() < this.startAlpha) { this.setAlphaBy(this.deltaAlpha); var instance = this; this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay); } else { if (this.cycle) { var instance = this; this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay); } else { this.started = false; } } } // }}} vdr-plugin-live/javascript/domTT.js0000644000175000017500000007303412650773437017206 0ustar tobiastobias/** $Id: domTT.js,v 1.2 2007/01/21 21:23:02 tadi Exp $ */ // {{{ license /* * Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // }}} // {{{ intro /** * Title: DOM Tooltip Library * Version: 0.7.3 * * Summary: * Allows developers to add custom tooltips to the webpages. Tooltips are * generated using the domTT_activate() function and customized by setting * a handful of options. * * Maintainer: Dan Allen * Contributors: * Josh Gross * Jason Rust * * License: Apache 2.0 * However, if you use this library, you earn the position of official bug * reporter :) Please post questions or problem reports to the newsgroup: * * http://groups-beta.google.com/group/dom-tooltip * * If you are doing this for commercial work, perhaps you could send me a few * Starbucks Coffee gift dollars or PayPal bucks to encourage future * developement (NOT REQUIRED). E-mail me for my snail mail address. * * Homepage: http://www.mojavelinux.com/projects/domtooltip/ * * Newsgroup: http://groups-beta.google.com/group/dom-tooltip * * Freshmeat Project: http://freshmeat.net/projects/domtt/?topic_id=92 * * Updated: 2005/07/16 * * Supported Browsers: * Mozilla (Gecko), IE 5.5+, IE on Mac, Safari, Konqueror, Opera 7 * * Usage: * Please see the HOWTO documentation. **/ // }}} // {{{ settings (editable) // IE mouse events seem to be off by 2 pixels var domTT_offsetX = (domLib_isIE ? -2 : 0); var domTT_offsetY = (domLib_isIE ? 4 : 2); var domTT_direction = 'southeast'; var domTT_mouseHeight = domLib_isIE ? 13 : 19; var domTT_closeLink = 'X'; var domTT_closeAction = 'hide'; var domTT_activateDelay = 500; var domTT_maxWidth = false; var domTT_styleClass = 'domTT'; var domTT_fade = 'neither'; var domTT_lifetime = 0; var domTT_grid = 0; var domTT_trailDelay = 200; var domTT_useGlobalMousePosition = true; var domTT_postponeActivation = false; var domTT_tooltipIdPrefix = '[domTT]'; var domTT_screenEdgeDetection = true; var domTT_screenEdgePadding = 4; var domTT_oneOnly = false; var domTT_cloneNodes = false; var domTT_detectCollisions = true; var domTT_bannedTags = ['OPTION']; var domTT_draggable = false; if (typeof(domTT_dragEnabled) == 'undefined') { domTT_dragEnabled = false; } // }}} // {{{ globals (DO NOT EDIT) var domTT_predefined = new Hash(); // tooltips are keyed on both the tip id and the owner id, // since events can originate on either object var domTT_tooltips = new Hash(); var domTT_lastOpened = 0; var domTT_documentLoaded = false; var domTT_mousePosition = null; // }}} // {{{ document.onmousemove if (domLib_useLibrary && domTT_useGlobalMousePosition) { document.onmousemove = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = window.event; } domTT_mousePosition = domLib_getEventPosition(in_event); if (domTT_dragEnabled && domTT_dragMouseDown) { domTT_dragUpdate(in_event); } } } // }}} // {{{ domTT_activate() function domTT_activate(in_this, in_event) { if (!domLib_useLibrary || (domTT_postponeActivation && !domTT_documentLoaded)) { return false; } // make sure in_event is set (for IE, some cases we have to use window.event) if (typeof(in_event) == 'undefined') { in_event = window.event; } // don't allow tooltips on banned tags (such as OPTION) if (in_event != null) { var target = in_event.srcElement ? in_event.srcElement : in_event.target; if (target != null && (',' + domTT_bannedTags.join(',') + ',').indexOf(',' + target.tagName + ',') != -1) { return false; } } var owner = document.body; // we have an active event so get the owner if (in_event != null && in_event.type.match(/key|mouse|click|contextmenu/i)) { // make sure we have nothing higher than the body element if (in_this.nodeType && in_this.nodeType != document.DOCUMENT_NODE) { owner = in_this; } } // non active event (make sure we were passed a string id) else { if (typeof(in_this) != 'object' && !(owner = domTT_tooltips.get(in_this))) { // NOTE: two steps to avoid "flashing" in gecko var embryo = document.createElement('div'); owner = document.body.appendChild(embryo); owner.style.display = 'none'; owner.id = in_this; } } // make sure the owner has a unique id if (!owner.id) { owner.id = '__autoId' + domLib_autoId++; } // see if we should only be opening one tip at a time // NOTE: this is not "perfect" yet since it really steps on any other // tip working on fade out or delayed close, but it get's the job done if (domTT_oneOnly && domTT_lastOpened) { domTT_deactivate(domTT_lastOpened); } domTT_lastOpened = owner.id; var tooltip = domTT_tooltips.get(owner.id); if (tooltip) { if (tooltip.get('eventType') != in_event.type) { if (tooltip.get('type') == 'greasy') { tooltip.set('closeAction', 'destroy'); domTT_deactivate(owner.id); } else if (tooltip.get('status') != 'inactive') { return owner.id; } } else { if (tooltip.get('status') == 'inactive') { tooltip.set('status', 'pending'); tooltip.set('activateTimeout', domLib_setTimeout(domTT_runShow, tooltip.get('delay'), [owner.id, in_event])); return owner.id; } // either pending or active, let it be else { return owner.id; } } } // setup the default options hash var options = new Hash( 'caption', '', 'content', '', 'clearMouse', true, 'closeAction', domTT_closeAction, 'closeLink', domTT_closeLink, 'delay', domTT_activateDelay, 'direction', domTT_direction, 'draggable', domTT_draggable, 'fade', domTT_fade, 'fadeMax', 100, 'grid', domTT_grid, 'id', domTT_tooltipIdPrefix + owner.id, 'inframe', false, 'lifetime', domTT_lifetime, 'offsetX', domTT_offsetX, 'offsetY', domTT_offsetY, 'parent', document.body, 'position', 'absolute', 'styleClass', domTT_styleClass, 'type', 'greasy', 'trail', false, 'lazy', false ); // load in the options from the function call for (var i = 2; i < arguments.length; i += 2) { // load in predefined if (arguments[i] == 'predefined') { var predefinedOptions = domTT_predefined.get(arguments[i + 1]); for (var j in predefinedOptions.elementData) { options.set(j, predefinedOptions.get(j)); } } // set option else { options.set(arguments[i], arguments[i + 1]); } } options.set('eventType', in_event != null ? in_event.type : null); // immediately set the status text if provided if (options.has('statusText')) { try { window.status = options.get('statusText'); } catch(e) {} } // if we didn't give content...assume we just wanted to change the status and return if (!options.has('content') || options.get('content') == '' || options.get('content') == null) { if (typeof(owner.onmouseout) != 'function') { owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); }; } return owner.id; } options.set('owner', owner); domTT_create(options); // determine the show delay options.set('delay', (in_event != null && in_event.type.match(/click|mousedown|contextmenu/i)) ? 0 : parseInt(options.get('delay'))); domTT_tooltips.set(owner.id, options); domTT_tooltips.set(options.get('id'), options); options.set('status', 'pending'); options.set('activateTimeout', domLib_setTimeout(domTT_runShow, options.get('delay'), [owner.id, in_event])); return owner.id; } // }}} // {{{ domTT_create() function domTT_create(in_options) { var tipOwner = in_options.get('owner'); var parentObj = in_options.get('parent'); var parentDoc = parentObj.ownerDocument || parentObj.document; // create the tooltip and hide it // NOTE: two steps to avoid "flashing" in gecko var embryo = parentDoc.createElement('div'); var tipObj = parentObj.appendChild(embryo); tipObj.style.position = 'absolute'; tipObj.style.left = '0px'; tipObj.style.top = '0px'; tipObj.style.visibility = 'hidden'; tipObj.id = in_options.get('id'); tipObj.className = in_options.get('styleClass'); var contentBlock; var tableLayout = false; if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false)) { tableLayout = true; // layout the tip with a hidden formatting table var tipLayoutTable = tipObj.appendChild(parentDoc.createElement('table')); tipLayoutTable.style.borderCollapse = 'collapse'; if (domLib_isKHTML) { tipLayoutTable.cellSpacing = 0; } var tipLayoutTbody = tipLayoutTable.appendChild(parentDoc.createElement('tbody')); var numCaptionCells = 0; var captionRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr')); var captionCell = captionRow.appendChild(parentDoc.createElement('td')); captionCell.style.padding = '0px'; var caption = captionCell.appendChild(parentDoc.createElement('div')); caption.className = 'caption'; if (domLib_isIE50) { caption.style.height = '100%'; } if (in_options.get('caption').nodeType) { caption.appendChild(domTT_cloneNodes ? in_options.get('caption').cloneNode(1) : in_options.get('caption')); } else { caption.innerHTML = in_options.get('caption'); } if (in_options.get('type') == 'sticky') { var numCaptionCells = 2; var closeLinkCell = captionRow.appendChild(parentDoc.createElement('td')); closeLinkCell.style.padding = '0px'; var closeLink = closeLinkCell.appendChild(parentDoc.createElement('div')); closeLink.className = 'caption'; if (domLib_isIE50) { closeLink.style.height = '100%'; } closeLink.style.textAlign = 'right'; closeLink.style.cursor = domLib_stylePointer; // merge the styles of the two cells closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px'; closeLink.style.paddingLeft = caption.style.paddingRight = '0px'; closeLink.style.marginLeft = caption.style.marginRight = '0px'; if (in_options.get('closeLink').nodeType) { closeLink.appendChild(in_options.get('closeLink').cloneNode(1)); } else { closeLink.innerHTML = in_options.get('closeLink'); } closeLink.onclick = function() { domTT_deactivate(tipOwner.id); }; closeLink.onmousedown = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = window.event; } in_event.cancelBubble = true; }; // MacIE has to have a newline at the end and must be made with createTextNode() if (domLib_isMacIE) { closeLinkCell.appendChild(parentDoc.createTextNode("\n")); } } // MacIE has to have a newline at the end and must be made with createTextNode() if (domLib_isMacIE) { captionCell.appendChild(parentDoc.createTextNode("\n")); } var contentRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr')); var contentCell = contentRow.appendChild(parentDoc.createElement('td')); contentCell.style.padding = '0px'; if (numCaptionCells) { if (domLib_isIE || domLib_isOpera) { contentCell.colSpan = numCaptionCells; } else { contentCell.setAttribute('colspan', numCaptionCells); } } contentBlock = contentCell.appendChild(parentDoc.createElement('div')); if (domLib_isIE50) { contentBlock.style.height = '100%'; } } else { contentBlock = tipObj.appendChild(parentDoc.createElement('div')); } contentBlock.className = 'contents'; var content = in_options.get('content'); // allow content has a function to return the actual content if (typeof(content) == 'function') { content = content(in_options.get('id')); } if (content != null && content.nodeType) { contentBlock.appendChild(domTT_cloneNodes ? content.cloneNode(1) : content); } else { contentBlock.innerHTML = content; } // adjust the width if specified if (in_options.has('width')) { tipObj.style.width = parseInt(in_options.get('width')) + 'px'; } // check if we are overridding the maxWidth // if the browser supports maxWidth, the global setting will be ignored (assume stylesheet) var maxWidth = domTT_maxWidth; if (in_options.has('maxWidth')) { if ((maxWidth = in_options.get('maxWidth')) === false) { tipObj.style.maxWidth = domLib_styleNoMaxWidth; } else { maxWidth = parseInt(in_options.get('maxWidth')); tipObj.style.maxWidth = maxWidth + 'px'; } } // HACK: fix lack of maxWidth in CSS for KHTML and IE if (maxWidth !== false && (domLib_isIE || domLib_isKHTML) && tipObj.offsetWidth > maxWidth) { tipObj.style.width = maxWidth + 'px'; } in_options.set('offsetWidth', tipObj.offsetWidth); in_options.set('offsetHeight', tipObj.offsetHeight); // konqueror miscalcuates the width of the containing div when using the layout table based on the // border size of the containing div if (domLib_isKonq && tableLayout && !tipObj.style.width) { var left = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-left-width'); var right = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-right-width'); left = left.substring(left.indexOf(':') + 2, left.indexOf(';')); right = right.substring(right.indexOf(':') + 2, right.indexOf(';')); var correction = 2 * ((left ? parseInt(left) : 0) + (right ? parseInt(right) : 0)); tipObj.style.width = (tipObj.offsetWidth - correction) + 'px'; } // if a width is not set on an absolutely positioned object, both IE and Opera // will attempt to wrap when it spills outside of body...we cannot have that if (domLib_isIE || domLib_isOpera) { if (!tipObj.style.width) { // HACK: the correction here is for a border tipObj.style.width = (tipObj.offsetWidth - 2) + 'px'; } // HACK: the correction here is for a border tipObj.style.height = (tipObj.offsetHeight - 2) + 'px'; } // store placement offsets from event position var offsetX, offsetY; // tooltip floats if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y'))) { // determine the offset relative to the pointer switch (in_options.get('direction')) { case 'northeast': offsetX = in_options.get('offsetX'); offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY'); break; case 'northwest': offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX'); offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY'); break; case 'north': offsetX = 0 - parseInt(tipObj.offsetWidth/2); offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY'); break; case 'southwest': offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX'); offsetY = in_options.get('offsetY'); break; case 'southeast': offsetX = in_options.get('offsetX'); offsetY = in_options.get('offsetY'); break; case 'south': offsetX = 0 - parseInt(tipObj.offsetWidth/2); offsetY = in_options.get('offsetY'); break; } // if we are in an iframe, get the offsets of the iframe in the parent document if (in_options.get('inframe')) { var iframeObj = domLib_getIFrameReference(window); if (iframeObj) { var frameOffsets = domLib_getOffsets(iframeObj); offsetX += frameOffsets.get('left'); offsetY += frameOffsets.get('top'); } } } // tooltip is fixed else { offsetX = 0; offsetY = 0; in_options.set('trail', false); } // set the direction-specific offsetX/Y in_options.set('offsetX', offsetX); in_options.set('offsetY', offsetY); if (in_options.get('clearMouse') && in_options.get('direction').indexOf('south') != -1) { in_options.set('mouseOffset', domTT_mouseHeight); } else { in_options.set('mouseOffset', 0); } if (domLib_canFade && typeof(Fadomatic) == 'function') { if (in_options.get('fade') != 'neither') { var fadeHandler = new Fadomatic(tipObj, 10, 0, 0, in_options.get('fadeMax')); in_options.set('fadeHandler', fadeHandler); } } else { in_options.set('fade', 'neither'); } // setup mouse events if (in_options.get('trail') && typeof(tipOwner.onmousemove) != 'function') { tipOwner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); }; } if (typeof(tipOwner.onmouseout) != 'function') { tipOwner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); }; } if (in_options.get('type') == 'sticky') { if (in_options.get('position') == 'absolute' && domTT_dragEnabled && in_options.get('draggable')) { // inserted by tadi: begin if (typeof(captionRow) == 'undefined') { captionRow = tipObj; } // inserted by tadi: end if (domLib_isIE) { captionRow.onselectstart = function() { return false; }; } // setup drag captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event); }; captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); }; captionRow.onmouseup = function() { domTT_dragStop(); }; } } else if (in_options.get('type') == 'velcro') { /* can use once we have deactivateDelay tipObj.onmouseover = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = window.event; } var tooltip = domTT_tooltips.get(tipObj.id); if (in_options.get('lifetime')) { domLib_clearTimeout(in_options.get('lifetimeTimeout'); } }; */ tipObj.onmouseout = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = window.event; } if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj, domTT_bannedTags)) { domTT_deactivate(tipOwner.id); } }; // NOTE: this might interfere with links in the tip tipObj.onclick = function(in_event) { domTT_deactivate(tipOwner.id); }; } if (in_options.get('position') == 'relative') { tipObj.style.position = 'relative'; } in_options.set('node', tipObj); in_options.set('status', 'inactive'); } // }}} // {{{ domTT_show() // in_id is either tip id or the owner id function domTT_show(in_id, in_event) { // should always find one since this call would be cancelled if tip was killed var tooltip = domTT_tooltips.get(in_id); var status = tooltip.get('status'); var tipObj = tooltip.get('node'); if (tooltip.get('position') == 'absolute') { var mouseX, mouseY; if (tooltip.has('x') && tooltip.has('y')) { mouseX = tooltip.get('x'); mouseY = tooltip.get('y'); } else if (!domTT_useGlobalMousePosition || domTT_mousePosition == null || status == 'active' || tooltip.get('delay') == 0) { var eventPosition = domLib_getEventPosition(in_event); var eventX = eventPosition.get('x'); var eventY = eventPosition.get('y'); if (tooltip.get('inframe')) { eventX -= eventPosition.get('scrollX'); eventY -= eventPosition.get('scrollY'); } // only move tip along requested trail axis when updating position if (status == 'active' && tooltip.get('trail') !== true) { var trail = tooltip.get('trail'); if (trail == 'x') { mouseX = eventX; mouseY = tooltip.get('mouseY'); } else if (trail == 'y') { mouseX = tooltip.get('mouseX'); mouseY = eventY; } } else { mouseX = eventX; mouseY = eventY; } } else { mouseX = domTT_mousePosition.get('x'); mouseY = domTT_mousePosition.get('y'); if (tooltip.get('inframe')) { mouseX -= domTT_mousePosition.get('scrollX'); mouseY -= domTT_mousePosition.get('scrollY'); } } // we are using a grid for updates if (tooltip.get('grid')) { // if this is not a mousemove event or it is a mousemove event on an active tip and // the movement is bigger than the grid if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouseX) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouseY) > tooltip.get('grid')))) { tooltip.set('lastX', mouseX); tooltip.set('lastY', mouseY); } // did not satisfy the grid movement requirement else { return false; } } // mouseX and mouseY store the last acknowleged mouse position, // good for trailing on one axis tooltip.set('mouseX', mouseX); tooltip.set('mouseY', mouseY); var coordinates; if (domTT_screenEdgeDetection) { coordinates = domTT_correctEdgeBleed( tooltip.get('offsetWidth'), tooltip.get('offsetHeight'), mouseX, mouseY, tooltip.get('offsetX'), tooltip.get('offsetY'), tooltip.get('mouseOffset'), tooltip.get('inframe') ? window.parent : window ); } else { coordinates = { 'x' : mouseX + tooltip.get('offsetX'), 'y' : mouseY + tooltip.get('offsetY') + tooltip.get('mouseOffset') }; } // update the position tipObj.style.left = coordinates.x + 'px'; tipObj.style.top = coordinates.y + 'px'; // increase the tip zIndex so it goes over previously shown tips tipObj.style.zIndex = domLib_zIndex++; } // if tip is not active, active it now and check for a fade in if (status == 'pending') { // unhide the tooltip tooltip.set('status', 'active'); tipObj.style.display = ''; tipObj.style.visibility = 'visible'; var fade = tooltip.get('fade'); if (fade != 'neither') { var fadeHandler = tooltip.get('fadeHandler'); if (fade == 'out' || fade == 'both') { fadeHandler.haltFade(); if (fade == 'out') { fadeHandler.halt(); } } if (fade == 'in' || fade == 'both') { fadeHandler.fadeIn(); } } if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0) { tooltip.set('lifetimeTimeout', domLib_setTimeout(domTT_runDeactivate, tooltip.get('lifetime'), [tipObj.id])); } } if (tooltip.get('position') == 'absolute' && domTT_detectCollisions) { // utilize original collision element cache domLib_detectCollisions(tipObj, false, true); } } // }}} // {{{ domTT_close() // in_handle can either be an child object of the tip, the tip id or the owner id function domTT_close(in_handle) { var id; if (typeof(in_handle) == 'object' && in_handle.nodeType) { var obj = in_handle; while (!obj.id || !domTT_tooltips.get(obj.id)) { obj = obj.parentNode; if (obj.nodeType != document.ELEMENT_NODE) { return; } } id = obj.id; } else { id = in_handle; } domTT_deactivate(id); } // }}} // {{{ domTT_closeAll() // run through the tooltips and close them all function domTT_closeAll() { // NOTE: this will iterate 2x # of tooltips for (var id in domTT_tooltips.elementData) { domTT_close(id); } } // }}} // {{{ domTT_deactivate() // in_id is either the tip id or the owner id function domTT_deactivate(in_id) { var tooltip = domTT_tooltips.get(in_id); if (tooltip) { var status = tooltip.get('status'); if (status == 'pending') { // cancel the creation of this tip if it is still pending domLib_clearTimeout(tooltip.get('activateTimeout')); tooltip.set('status', 'inactive'); } else if (status == 'active') { if (tooltip.get('lifetime')) { domLib_clearTimeout(tooltip.get('lifetimeTimeout')); } var tipObj = tooltip.get('node'); if (tooltip.get('closeAction') == 'hide') { var fade = tooltip.get('fade'); if (fade != 'neither') { var fadeHandler = tooltip.get('fadeHandler'); if (fade == 'out' || fade == 'both') { fadeHandler.fadeOut(); } else { fadeHandler.hide(); } } else { tipObj.style.display = 'none'; } } else { tooltip.get('parent').removeChild(tipObj); domTT_tooltips.remove(tooltip.get('owner').id); domTT_tooltips.remove(tooltip.get('id')); } tooltip.set('status', 'inactive'); if (domTT_detectCollisions) { // unhide all of the selects that are owned by this object // utilize original collision element cache domLib_detectCollisions(tipObj, true, true); } } } } // }}} // {{{ domTT_mouseout() function domTT_mouseout(in_owner, in_event) { if (!domLib_useLibrary) { return false; } if (typeof(in_event) == 'undefined') { in_event = window.event; } var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner, domTT_bannedTags); var tooltip = domTT_tooltips.get(in_owner.id); if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active')) { // deactivate tip if exists and we moved away from the owner if (!toChild) { domTT_deactivate(in_owner.id); try { window.status = window.defaultStatus; } catch(e) {} } } else if (!toChild) { try { window.status = window.defaultStatus; } catch(e) {} } } // }}} // {{{ domTT_mousemove() function domTT_mousemove(in_owner, in_event) { if (!domLib_useLibrary) { return false; } if (typeof(in_event) == 'undefined') { in_event = window.event; } var tooltip = domTT_tooltips.get(in_owner.id); if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active') { // see if we are trailing lazy if (tooltip.get('lazy')) { domLib_setTimeout(domTT_runShow, domTT_trailDelay, [in_owner.id, in_event]); } else { domTT_show(in_owner.id, in_event); } } } // }}} // {{{ domTT_addPredefined() function domTT_addPredefined(in_id) { var options = new Hash(); for (var i = 1; i < arguments.length; i += 2) { options.set(arguments[i], arguments[i + 1]); } domTT_predefined.set(in_id, options); } // }}} // {{{ domTT_correctEdgeBleed() function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_mouseOffset, in_window) { var win, doc; var bleedRight, bleedBottom; var pageHeight, pageWidth, pageYOffset, pageXOffset; var x = in_x + in_offsetX; var y = in_y + in_offsetY + in_mouseOffset; win = (typeof(in_window) == 'undefined' ? window : in_window); // Gecko and IE swaps values of clientHeight, clientWidth properties when // in standards compliance mode from documentElement to document.body doc = ((domLib_standardsMode && (domLib_isIE || domLib_isGecko)) ? win.document.documentElement : win.document.body); // for IE in compliance mode if (domLib_isIE) { pageHeight = doc.clientHeight; pageWidth = doc.clientWidth; pageYOffset = doc.scrollTop; pageXOffset = doc.scrollLeft; } else { pageHeight = doc.clientHeight; pageWidth = doc.clientWidth; if (domLib_isKHTML) { pageHeight = win.innerHeight; } pageYOffset = win.pageYOffset; pageXOffset = win.pageXOffset; } // we are bleeding off the right, move tip over to stay on page // logic: take x position, add width and subtract from effective page width if ((bleedRight = (x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0) { x -= bleedRight; } // we are bleeding to the left, move tip over to stay on page // if tip doesn't fit, we will go back to bleeding off the right // logic: take x position and check if less than edge padding if ((x - pageXOffset) < domTT_screenEdgePadding) { x = domTT_screenEdgePadding + pageXOffset; } // if we are bleeding off the bottom, flip to north // logic: take y position, add height and subtract from effective page height if ((bleedBottom = (y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0) { y = in_y - in_height - in_offsetY; } // if we are bleeding off the top, flip to south // if tip doesn't fit, we will go back to bleeding off the bottom // logic: take y position and check if less than edge padding if ((y - pageYOffset) < domTT_screenEdgePadding) { y = in_y + domTT_mouseHeight + in_offsetY; } return {'x' : x, 'y' : y}; } // }}} // {{{ domTT_isActive() // in_id is either the tip id or the owner id function domTT_isActive(in_id) { var tooltip = domTT_tooltips.get(in_id); if (!tooltip || tooltip.get('status') != 'active') { return false; } else { return true; } } // }}} // {{{ domTT_runXXX() // All of these domMenu_runXXX() methods are used by the event handling sections to // avoid the circular memory leaks caused by inner functions function domTT_runDeactivate(args) { domTT_deactivate(args[0]); } function domTT_runShow(args) { domTT_show(args[0], args[1]); } // }}} // {{{ domTT_replaceTitles() function domTT_replaceTitles(in_decorator) { var elements = domLib_getElementsByClass('tooltip'); for (var i = 0; i < elements.length; i++) { if (elements[i].title) { var content; if (typeof(in_decorator) == 'function') { content = in_decorator(elements[i]); } else { content = elements[i].title; } content = content.replace(new RegExp('\'', 'g'), '\\\''); elements[i].onmouseover = new Function('in_event', "domTT_activate(this, in_event, 'content', '" + content + "')"); elements[i].title = ''; } } } // }}} // {{{ domTT_update() // Allow authors to update the contents of existing tips using the DOM // Unfortunately, the tip must already exist, or else no work is done. // TODO: make getting at content or caption cleaner function domTT_update(handle, content, type) { // type defaults to 'content', can also be 'caption' if (typeof(type) == 'undefined') { type = 'content'; } var tip = domTT_tooltips.get(handle); if (!tip) { return; } var tipObj = tip.get('node'); var updateNode; if (type == 'content') { //
... updateNode = tipObj.firstChild; if (updateNode.className != 'contents') { // ... <%cpp> } <# ---------------------------------------------------------------------- #> <%def epg_tt_box> <%args> string boxId; string caption; string tools_comp; string time; string title; string short_descr; string long_descr; string archived; int elapsed = -1;
<$ (caption) $>
<& (tools_comp) id=(boxId) archived=(archived) detail=(1) title=(title) &>
<%cpp> if (!archived.empty()) { <$ (archived + " ") $><%cpp> } <$ (time) $>
<%cpp> if (elapsed >= 0) {
<& pageelems.progressbar progress=(elapsed) &>
<%cpp> }
<$ (title) $>
<$ (short_descr) $>
<%cpp> list images = EpgEvents::EpgImages(boxId); for(std::list::iterator it = images.begin(); it != images.end(); ++it ) { <%cpp> } <%cpp> reply.out() << StringEscapeAndBreak(long_descr);
<# ---------------------------------------------------------------------- #> <%def about_tt_box>
<$ tr(LIVESUMMARY) $>
<$ tr("Authors") $>
<$ tr("Project Idea") $>:
Thomas Keil (Thomas)
<$ tr("Webserver") $>:
Sascha Volkenandt (LordJaxom)
<$ tr("Project leader") $>:
Dieter Hametner (tadi)
<$ tr("Content") $>:
Christian Wieninger (winni)
<$ tr("Graphics") $>:
Michael Brückner (skiller2k1)
<$ tr("Information") $>
<$ tr("LIVE version") $>:
<$ LIVEVERSION $><$ VERSION_SUFFIX $>
<$ tr("VDR version") $>:
<$ VDRVERSION $>
<$ tr("Features") $>
EPGsearch:
<%cpp> Features< features::epgsearch >& epgsearch = LiveFeatures< features::epgsearch >(); "/> <%cpp> if ( epgsearch.Recent() ) { <$ tr("active") $>: <$ epgsearch.Version() $> <%cpp> } else { <$ tr("required") $>: <$ epgsearch.MinVersion() $> <%cpp> } (<$ tr("Homepage") $>)
Streamdev server:
<%cpp> Features< features::streamdev_server >& streamdev = LiveFeatures< features::streamdev_server >(); "/> <%cpp> if ( streamdev.Loaded() ) { <$ tr("active") $>: <$ streamdev.Version() $> <%cpp> } else { <$ tr("required") $>: <$ streamdev.MinVersion() $> <%cpp> } (<$ tr("Homepage") $>)
<$ tr("Bugs and suggestions") $>
<$ tr("If you encounter any bugs or would like to suggest new features, please use our bugtracker") $>:
http://projects.vdr-developer.org/projects/plg-live
 
vdr-plugin-live/pages/page_init.eh0000644000175000017500000000056712650773437017030 0ustar tobiastobias<%pre> // do not add to Makefile // and do not write a ecpp comment into this file. It must produce no // html output not even a empty line. #include #include "exception.h" <%request scope="global"> std::string pageTitle; <%cpp> try { reply.setHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); tnt::Savepoint spoint( reply ); vdr-plugin-live/pages/searchepg.ecpp0000644000175000017500000004472712650773437017373 0ustar tobiastobias<%pre> #include #include #include #include #include #include #include "exception.h" #include "tools.h" #include "epgsearch.h" #include "setup.h" using namespace std; using namespace vdrlive; <%args> // input parameters // form parameters bool useextendedsearch = false; string search = ""; int mode = 0; bool matchcase = false; int tolerance = 1; bool usetitle = false; bool usesubtitle = false; bool usedescr = false; int usechannel = SearchTimer::NoChannel; tChannelID channelidfrom; tChannelID channelfrom; tChannelID channelidto; tChannelID channelto; string changrpsel = ""; bool usetime = false; string start_h = "00"; string start_m = "00"; string stop_h = "00"; string stop_m = "00"; bool useduration = false; int durationmin = 0; int durationmax = 90; bool useweekday = false; bool wday_mon = false; bool wday_tue = false; bool wday_wed = false; bool wday_thu = false; bool wday_fri = false; bool wday_sat = false; bool wday_sun = false; int blacklistmode = 0; string blacklistids[]; bool useextepginfo = false; string extepgvalues[]; string blacklistids_internal; <%session scope="global"> bool logged_in(false); <%request scope="page"> SearchTimer* searchtimer; ExtEPGInfos extEPGInfos; ChannelGroups channelGroups; Blacklists blacklists; <%include>page_init.eh <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }> <%cpp> #define SELECTIF(x) reply.out() << ( (x) ? "selected=\"selected\"" : "" ); #define CHECKIF(x) reply.out() << ( (x) ? "checked=\"checked\"" : "" ); searchtimer = 0; if ( request.getMethod() == "POST") { SearchTimer searchtimer; searchtimer.SetSearch(search); searchtimer.SetSearchMode(mode); searchtimer.SetTolerance(tolerance); searchtimer.SetMatchCase(matchcase); searchtimer.SetUseTitle(usetitle); searchtimer.SetUseSubtitle(usesubtitle); searchtimer.SetUseDescription(usedescr); searchtimer.SetUseExtEPGInfo(useextepginfo); if (useextepginfo) { vector< string > infos; unsigned int i=0; for (ExtEPGInfos::iterator extinfo = extEPGInfos.begin(); extinfo != extEPGInfos.end(); ++extinfo, i++) { ostringstream os; os << extinfo->Id() << "#" << (i <& pageelems.doc_type &> VDR Live - <$ tr("Search") $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("searchepg") &>
... updateNode = updateNode.firstChild.firstChild.nextSibling.firstChild.firstChild; } } else { updateNode = tipObj.firstChild; if (updateNode.className == 'contents') { // missing caption return; } // <$ currentTime $><$ title $><$ duration $><$ elapsed $><$ next_chan $><$ prev_chan $> <%cpp> if (!infoMsg.empty()) { <$ infoMsg $> <$ infoUrl $> <%cpp> } vdr-plugin-live/pages/screenshot.ecpp0000644000175000017500000000076712650773437017603 0ustar tobiastobias<%pre> #include #include "setup.h" #include "grab.h" using namespace vdrlive; <%args> int quality = 80; int width = 569; int height = 320; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType("image/jpg"); GrabImageInfo image = LiveGrabImageManager().GetImage(); if ( image.second > 0 ) reply.out().write( image.first.get(), image.second ); vdr-plugin-live/pages/ffw_recording.ecpp0000644000175000017500000000115212650773437020231 0ustar tobiastobias<%pre> #include #include #include "exception.h" #include "setup.h" #include "tasks.h" #include "tools.h" using namespace std; using namespace vdrlive; <%args> string param; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType( "application/xml" ); ForwardRecordingTask task( param ); LiveTaskManager().Execute( task ); <& xmlresponse.ajax name=("ffw_recording") pname=("recording") value=(param) result=(task.Result()) error=(task.Error()) &> vdr-plugin-live/pages/edit_recording.ecpp0000644000175000017500000001325412650773437020402 0ustar tobiastobias<%pre> #include #include #include #include "exception.h" #include "tools.h" #include "epg_events.h" #include "recman.h" #include "setup.h" #include "i18n.h" #include "livefeatures.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> // input parameters string recid; string async; // form parameters string name = ""; string directory = ""; string options[]; <%session scope="global"> bool logged_in(false); string edit_rec_referer; <%request scope="page"> const cRecording* recording; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); if (!cUser::CurrentUserHasRightTo(UR_EDITRECS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); bool ajaxReq = !async.empty() && (lexical_cast(async) != 0); string message; recording = NULL; if (!recid.empty()) { recording = LiveRecordingsManager()->GetByMd5Hash(recid); if (!recording) throw HtmlError(tr("Couldn't find recording. Maybe you mistyped your request?")); } if (request.getMethod() == "POST") { if (name.empty()) message = tr("Please set a name for the recording!"); else if (recording) { bool copy_only = false; for (options_type::const_iterator it = options.begin(); it != options.end(); ++it) { if (*it == "delresume") LiveRecordingsManager()->DeleteResume(recording); else if (*it == "delmarks") LiveRecordingsManager()->DeleteMarks(recording); else if (*it == "copy") copy_only = true; } options.clear(); string filename = directory.empty() ? name : StringReplace(directory, "/", "~") + "~" + name; if (LiveRecordingsManager()->MoveRecording(recording, FileSystemExchangeChars(filename, true), copy_only)) return reply.redirect(!edit_rec_referer.empty() ? edit_rec_referer : "recordings.html"); else message = tr("Cannot copy, rename or move the recording."); } } if (message.empty()) edit_rec_referer = request.getHeader("Referer:", "recordings.html"); if (recording) { string path = recording->Name(); size_t found = path.find_last_of("~"); if (found != string::npos) { directory = StringReplace(path.substr(0, found), "~", "/"); name = path.substr(found + 1); } else { directory = ""; name = path; } } <& pageelems.doc_type &> VDR Live - <$ tr("Edit recording") $> <%cpp> if (!ajaxReq) { <& pageelems.stylesheets &> <& pageelems.ajax_js &> <%cpp> } <%cpp> if (!ajaxReq) { <& pageelems.logo &> <& menu active=("recordings") &> <%cpp> }
... updateNode = updateNode.firstChild.firstChild.firstChild.firstChild; } // TODO: allow for a DOM node as content updateNode.innerHTML = content; } // }}} vdr-plugin-live/doc/0000755000175000017500000000000012650773437014211 5ustar tobiastobiasvdr-plugin-live/doc/TODO.txt0000644000175000017500000000145512650773437015524 0ustar tobiastobiasThis is a list of ideas and TODO-Items for live plugin. - Add better support for the numerous CSS bugs in IE. Maybe by splitting style files in a similar way like it is done for YAML (http://www.yaml.de) - Create a CSS-themeing friendly url scheme. I.E. something like img//button.png. Where default as theme is always taken if is not found. - Give users the chance to override the selected style with some user-override settings. - Deliver truely static content, like images, styles, ECMAscript with tntnets sendfile functionality after resolving user selected themes paths. Take care to support browser cache optimization. - Deliver epg box infos through AJAX. This would make a ECMAScript capable browser mandatory. - Provide a way to get the infos on extra 'static' pages. vdr-plugin-live/doc/css-themeing.txt0000644000175000017500000001054312650773437017343 0ustar tobiastobiasLive themeing in a few steps: ============================= - Copy the 'themes' directory from the sources to $VDRCONFIG/plugins/live (default: /video/vdr/plugins/live) - Go to setup page, select desired theme from listbox. You can add own themes by creating in themes a subdirectory with your theme. Read further for more detailed information about themeing. How to do live theming with CSS. ================================ Live supports CSS theming. While the structure of the html pages is given by the plugin, there is the possibility to change the look through CSS and exchanged images. Themable resources ------------------ CSS stylesheets and referenced images are themable. That means a theme can replace the icons and background images in the markup. Access scheme for the css stylesheets ------------------------------------- Each live page requests at least three stylesheets in the following order: 1. 'styles.css' (the build in stylesheet) is requested. 2. The theme master stylesheet 'theme.css' is requested. 3. A site preferences stylesheet is requested ('siteprefs.css') Location for the stylesheets ---------------------------- The initial stylesheet 'styles.css' provides a basic layout. It is a builtin stylesheet and can not be altered after live is compiled and installed. The theme stylesheed 'theme.css' is requested through following url: themes//css/theme.css The site preference stylesheet is requested through this url: css/siteprefs.css Access scheme for themable images --------------------------------- All themable images in the pages, that live delivers to the browser are accessed through the url themes//img/ If a image is not found under that url, the image is searched in common/img/ And if not found there, an attempt to deliver a built in image is taken. Location of the resources in the file system -------------------------------------------- All themable content must be present in the directory specified by 'GetConfigDir'. GetConfigDir returns at runtime the position in the filesystem where the plugins configuration file is stored. The location is build from the vdr config path appended with the plugins name (i.E. /var/lib/vdr/plugins/live). The themes are located in the 'themes' subdirectory of the above path. Structure of a theme package ---------------------------- A theme package consists of directory named after the theme name. It must contain the subdirectories 'css' and 'img'. Under css and img no other subdirectories are allowed for security reasons (see below). In the subdirectory css a stylesheet theme.css must exist in oder to override or extend the already defined styles from 'styles.css'. Additional images referenced through the stylesheet and images replacing the default images go to the 'img' subdirectory. Replacing images must have the same name like the image to be replaced. The live distribution comes with a few predefinded theme packages. You should take look into them to better understand this structure. Selecting a theme in live ------------------------- In the live setup page, the user can select the desired theme. When the settings are saved the selected themes become active. Live detects the available themes dynamicaly by scanning the 'themes' directory in plugins config directory for available themes and creates the select box from this information. So the installation of a new theme is easyly done by unpacking a theme-archive in the themes directory. This assumes the theme-archive follows the structure of a theme package as described above. Security provisions ------------------- Live will map every url starting with themes//css or themes//img to exactly these directories under the location of the themes directory. That means any path components after 'img' or 'css' are discarded. Only the basename of the url is appended to these directories. This is to prevent possible malicous requests to other locations in the filesystem by adding '..' to the request path. The downside of this is, that no additional directories below 'img' and 'css' are possible for the theme designer. User Contribution ================= If you created a nice new look, you can provide it to us. We will try to include it into the live distribution. If you need special html support for your styling needs, don't hesitate to submit a suggestion. vdr-plugin-live/doc/dev-conventions.txt0000644000175000017500000000550212650773437020075 0ustar tobiastobiasLive development guidelines =========================== This file contains some guidelines for developers about what to obey when adding new functionality to live plugin. First of all please look at the existing code and how it was done there. We are still open for improvement suggestions though. We want to support a broad range of browsers. On one side are hand held devices like WEB-enabled PDAs or mobile phones. They often lack full grown support for ECMAScript and have small screen sizes. The other extreme are the desktop browsers like FireFox, Konqueror, Opera and perhaps IE (if the 'powers that be' make him more CSS compliant). Here WEB 2.0 features can improve the users experience. With or without ECMAScript -------------------------- Since not all browsers support ECMAScript, we need to make sure all functions live wants to provide need to be accessible through links. With the mootools framework and its selection functions we can enhance the user experience through ECMAScript by selecting the relevant elements in the DOM and attaching event handlers from the loaded script files. Thus when the user disables ECMAScript in his browser (or the browser does not support it) the traditional web technique of jumping between pages provides the functions. With enabled ECMAScript the event handlers can take over and provide a nifty Web 2.0 technique solution to the user. To enable a tooltip just add a 'title' attribute on the element and load 'hinttips.js' in your pages (Actually this will be allready done for you if you use the live page-framework). For popup windows that asynchronously load its contents you need to use normal links like your link text here . If 'infowin.js' is loaded it will enhance these links with AJAX functionality. If not the link will change to a new page with the requested information. This means that both users with and without ECMAScript support will benefit from the functions in live. Themeing -------- Current CSS based themeing in live depends on additional stylesheets and a configurable location to retrieve images from (see css-themeing.txt). Developers must use the <& pageelems.stylesheets &> component in their pages to include both the default and the themed stylesheet. This is the easy part, because stylesheets are referred in the header at a central location. More difficult is the access to images, which is spread around the pages at the corresponding locations. To support this, a new method in the live Setup class (see file setup.h) has been added. It is called 'GetThemedLink'. For every image, that might be customized, you must use a img tag according to this example: ") $>" alt="someimage" /> Please take a look in the existing ecpp pages for additional usage examples. vdr-plugin-live/doc/ChangeLog0000644000175000017500000003077212650773437015774 0ustar tobiastobias2013-04-04 Dieter Hametner * This file is discontinued. To get an overview of the changes please consult the git history found on http://projects.vdr-developer.org/git/vdr-plugin-live.git/ 2009-09-07 Christian Wieninger * new user management within setup that also handles different user rights 2008-11-19 Christian Wieninger * new setup option to display channels without EPG 2008-10-21 Christian Wieninger * edit_timer.ecpp: new menu entry to select a recording directory. requires epgsearch plugin. * epgsearch.h/cpp: read the directory list via epgsearch's service interface version 1.2 2008-08-04 Christian Wieninger * italian translation update, thanks to Diego Pierotto 2008-02-07 Christian Wieninger * new menu with timer conflicts 2008-02-07 Dieter Hametner * buildutil/version-util: Further posix-ified the script. 2008-02-06 Dieter Hametner * buildutil/version-util: Function definitions in shell should not have whitespaces between the name and the parentheses. * i18n-generated.h: updated with latest translation contributions. 2008-01-25 Dieter Hametner * recman.cpp: Fixed memory leak, which resulted through the use of circular references by using tr1::shared_ptr, where a tr1::weak_ptr would have been needed. * pages/recordings.ecpp: Added button to delete that single recording. This feature is somehow limited in usability and should be used only for occasional deletion of recordings, because the page reloads when a recording is deleted. Unfortunately there is currently no way to remember the position to where the user navigated before he hit the delete button. In order to delete an other recording in the same subdirectory he will need to navigate there again after the page reloaded. 2008-01-18 Dieter Hametner * buildutil/version-util*: Added a shell and an awk script to calculate a version suffix string out of CVS current working dir status. This was a request bei jo01 and helps distinguish if newer versions are awailable. It should not break builds if something goes wrong in the script. At least it was my intention. The script also supports git repositories. But it has not been tested if it determines the correct git commit id based on current workdir contents. The caluculated version suffix is appended to the LIVE version string visible in the about box (?-Menu entry). 2008-01-15 Christian Wieninger * whats_on.ecpp: added listing 'Favorites', that lists all search results of search timers with setting 'Use in favorites menu' * Makefile: reversed Makefile changes that avoided commit conflicts, but caused compile time problems * po/*.po: added "translation team" since msgfmt complains about that 2008-01-04 Dieter Hametner * Makefile: Thanks to user 'ernie' in vdr-portal.de, who pointed out that the Makefile uses a bashism without setting SHELL to bash. UPDATE: User 'Keef' pointed out a way to omit bash arithmetic expressions. So the dependency on bash could be dropped again. 2007-12-25 Dieter Hametner - Added configuration option to disable the creation of IMDb URLs in the epg-info sections. This was done upon of feature reqest (Bug #401). Some minor fixes for the IMDb URLs in recordings. 2007-12-23 Dieter Hametner * po/*.po Modified headers in the .po files and updated copyright information to be more LIVE plugin aware. * Makefile Changed top level Makefile to not create headers in live.pot file. This prevents creation of new date header in .po file at fresh translations after updates from CVS and should avoid continous conflicts at every cvs update even if no changes took place in the local files. 2007-12-22 Dieter Hametner * live/js/live/vlc.js Added an own mootools based implementation of a controlling class for the vlc plugin as proposed by Rolf Ahrenberg. Features currently supported are: - start/stop play (pause is left out because it provides no timeshift functionality). - mute sound. (Use this instead of pause) - switch to full screen mode. - close the popup window. The class is customizable and you can see in vlc.ecpp how customization for the changed button strings has been done. 2007-12-18 Dieter Hametner - Integrated a new patch Rolf Ahrenberg sent to me privately The patch updates finish translations. Autoplay and the 'standard' video size is used in the playback window. 2007-12-17 Dieter Hametner - Adapted Rolf Ahrenbergs patch for VLC plugin streaming to the browser window using streamdev-server plugin on VDR. See Bug-Entry #343. You can stream current running program from the "whats_on now" schedules page into an extra browser window if javascript is active. Otherwise you get redirected onto a dedicated new live streaming page. 2007-10-21 Dieter Hametner - Renamed recordings.h/cpp files to recman.h/cpp. Adapted files that included them. - recman.h has extended functionality for recordings. It is not used yet. 2007-10-17 Dieter Hametner * css/styles.css * live/themes/orange-blue/css/theme.css Fix missing background color settings for browsers that don't have white as default background. Thanks to zirias. See: http://www.vdr-portal.de/board/thread.php?postid=659497#post659497 2007-09-18 Dieter Hametner - Eliminated 'images' directory. The images are now not longer compiled with ecpp into the executable module of live. With the content.ecpp part and file cache we have a equally performant solution to compiled in files. - Added file cache preload functionality. The file cache is filled with a list of files defined at compile time on plugin startup time. 2007-09-09 Dieter Hametner * tntconfig.cpp: allways give absolute paths to content.ecpp * pages/content.ecpp: check for absolute paths which don't contain upward references (e.g. '../') and deny such requests. 2007-09-07 Dieter Hametner * tntconfig.cpp: Checked and adapted MapUrl regular expressions to be more live setup secure. 2007-08-19 Dieter Hametner - Adapted (but not tested) live for the new localisation scheme since VDR 1.5.7 Might need some additional tweaking... 2007-07-29 Dieter Hametner - Implemented status notification popup if ajax is active. - Without Ajax it is now possible to request actions from vdr via a static page. 2007-07-22 Dieter Hametner Added toolbox buttons to epg info popup windows. Some style fixes for this. * pages/whats_on.ecpp: Use new pageelems.epg_tool_box component. * pages/pageelems.ecpp: new epg_tool_box component. 2007-07-21 Dieter Hametner * live/js/live/pageenhance.js: Enhance a normal web page with nifty web 2.0 features. * live/js/live/infowin.js: stand alone class. Used by pageenhance.js * live/js/live/hinttips.js: stand alone class. Used by pageenhance.js 2007-07-21 Dieter Hametner Made epgimages better styleable. Displaying them as floats right of the epg description text. 2007-07-20 Christian Wieninger Added support for EPG images: Specify the directory with your EPG images via the new commandline option '-e ' or '--epgimages= like -P'live -e /video/epgimages' 2007-07-12 Dieter Hametner Changed the javascript base of live. We now use the 'mootools' framework (see http://www.mootools.net for infos) to handle javascript in a browser independend fashion and for nifty Web 2.0 features. Based on this framework we have now tooltips that use the XHTML standard 'title' attribute and Web-2.0 popup windows for epg information. This Epg information is loaded on demand and once loaded, they are cached in the page for further viewing. On the other hand this also provides us with a solution to have live functioning without javascript at all. When done right, the same functionality can be achieved with or without enabled javascript in the browser. Currently there still are javascript only features, which will be resolved in the next weeks. This is a rather big change on many files, so they are not all mentioned here. 2007-06-22 Dieter Hametner Start of new 'standalone' javascript source directory for live javascript files. - Use mootools http://www.mootools.net/ as base library for 'modern' Javascript based functionality. 2007-06-15 Dieter Hametner * setup.ecpp: added option to disable infobox at all. 2007-06-14 Dieter Hametner * infobox: Keep update status of infobox in session. This allows the user to switch off status updates and change live pages. After a page change the status is updated once and then the users choice is respected. 2007-06-14 Dieter Hametner * infobox: show 'user friendly' error message when something went wrong while updating the status box. Fixed tooltip message for toggle update on/off of status box. 2007-06-13 Dieter Hametner * pages/schedule.ecpp: If no channel is given, and a current channel is known to vdr, select it when calling the schedule page in live. 2007-06-12 Dieter Hametner Added orange-blue theme as an example of a theme with dark background and light foreground colors. This theme also demonstrates the use of exchanged images (logo.png, tv.jpg and remotecontrol.jpg) * styles.css: some minor style fixes, that became visible while creating the orange-blue theme. 2007-06-11 Dieter Hametner Fixed style layout of the tables. Added class 'bottomrow' to the rows that are followed by empty spacer rows. 2007-06-06 Dieter Hametner Use GetConfigDir instead of USRDIR define. * pages/*.ecpp: begin of unification of table markup. Still needs some tweaking but the general framework is in place. * styles.css: Removed different table styles. Added two general table styles: - listing: for tables showing listings like search results or schedules. - formular: for tables used in input forms to layout the input elements. Added some general use styles, like 'bold', 'more', 'withmargin', 'nomargin', 'short', 'title', 'dotted' 2007-06-03 Dieter Hametner Added CSS based themeing support. For details please read doc/css-themeing.txt and doc/dev-conventions.txt. * setup.h, setup.cpp, setup.ecpp: added setup for theme and selection of theme. * pages/*.ecpp: added support for themable images. * tntconfig.cpp: cascaded search for images, to support themeing. 2007-06-03 Christian Wieninger Setup includes now a local net mask specifying the address range without necessary login (#321) 2007-06-02 Christian Wieninger required version of VDR is now >= 1.4.0-2 2007-06-01 Sascha Volkenandt The detection of featured plugins was uniformed. The display in the about box now reads "active: " or "required: " 2007-06-01 Dieter Hametner These changes fix bug entry #339 * css-themeing.txt: describe how to do css themeing. * content.ecpp: - check for additional parameter and use it as mime type. - use compile time variable USRDIR for path to the files loaded via content.ecpp * pageelems.ecpp: link to css/siteprefs.css * pages/*.ecpp: changed style link to pageelems.stylesheet component. * tntconfig.cpp: added MapUrl for css/cssfile. unrecorded Sascha Volkenandt Due to the introduction of a uniform header for C++ standard extenstions, the boost library is now only necessary if the used g++ compiler version is less than 4.0 vdr-plugin-live/epg_events.h0000644000175000017500000001471612650773437015765 0ustar tobiastobias#ifndef VDR_LIVE_WHATS_ON_H #define VDR_LIVE_WHATS_ON_H #include #include #include #include #include #include #include #include "live.h" #include "stdext.h" namespace vdrlive { class EpgInfo; typedef std::tr1::shared_ptr EpgInfoPtr; // ------------------------------------------------------------------------- namespace EpgEvents { std::string EncodeDomId(tChannelID const &chanId, tEventID const &eventId); void DecodeDomId(std::string const &epgid, tChannelID &chanId, tEventID &eventId); /** * Allocate and initalize an epgEvent instance with the * passed channel and event information. */ EpgInfoPtr CreateEpgInfo(cChannel const *chan, cEvent const *event, char const *idOverride = 0); /** * This is the inverse creator for epgInfos to the creator above. */ EpgInfoPtr CreateEpgInfo(std::string const &epgid, cSchedules const *schedules); /** * Allocate and initalize an epgEvent instance with the * passed recording information. */ EpgInfoPtr CreateEpgInfo(std::string const &recid, cRecording const *recording, char const *caption = 0); /** * Allocate and initalize an epgEvent instance with the * passed string informations */ EpgInfoPtr CreateEpgInfo(std::string const &id, std::string const &caption, std::string const &info); /** * Return a list of EpgImage paths for a given epgid. */ std::list EpgImages(std::string const &epgid); /** * Calculate the duration. A duration can be zero or * negative. Negative durations are considered invalid by * LIVE. */ int Duration(time_t const startTime, time_t const endTime); /** * Calculate the elapsed time of a positive duration. This * takes into account the startTime and the current time. If * the current time is not in the interval startTime <= * currTime <= endTime the return value is -1. */ int ElapsedTime(time_t const startTime, time_t const endTime); } // namespace EpgEvents // ------------------------------------------------------------------------- class EpgInfo { protected: EpgInfo(std::string const &id, std::string const &caption); public: virtual ~EpgInfo(); virtual std::string const Id() const { return m_eventId; } virtual std::string const Caption() const { return m_caption; } virtual std::string const Title() const = 0; virtual std::string const ShortDescr() const = 0; virtual std::string const LongDescr() const = 0; virtual cChannel const * Channel() const { return 0; } virtual std::string const Archived() const { return ""; } virtual std::string const StartTime(const char* format) const; virtual std::string const EndTime(const char* format) const; virtual std::string const CurrentTime(const char* format) const; virtual int Duration() const; virtual int Elapsed() const; // virtual const cTimer* GetTimer() const = 0; virtual time_t GetStartTime() const = 0; virtual time_t GetEndTime() const = 0; private: std::string m_eventId; std::string m_caption; }; // ------------------------------------------------------------------------- class EpgString : public EpgInfo { friend EpgInfoPtr EpgEvents::CreateEpgInfo(std::string const &, std::string const &, std::string const &); protected: EpgString(std::string const &id, std::string const &caption, std::string const &info); public: virtual ~EpgString(); virtual std::string const Title() const; virtual std::string const ShortDescr() const; virtual std::string const LongDescr() const; virtual time_t GetStartTime() const; virtual time_t GetEndTime() const; private: const std::string m_info; }; // ------------------------------------------------------------------------- class EpgEvent : public EpgInfo { friend EpgInfoPtr EpgEvents::CreateEpgInfo(cChannel const *, cEvent const *, char const *); protected: EpgEvent(std::string const &id, cEvent const *event, char const *channelName); public: virtual ~EpgEvent(); virtual std::string const Title() const { return std::string(m_event->Title() ? m_event->Title() : ""); } virtual std::string const ShortDescr() const { return std::string(m_event->ShortText() ? m_event->ShortText() : ""); } virtual std::string const LongDescr() const { return std::string(m_event->Description() ? m_event->Description() : ""); } virtual time_t GetStartTime() const { return m_event->StartTime(); } virtual time_t GetEndTime() const { return m_event->EndTime(); } virtual cChannel const * Channel() const { return Channels.GetByChannelID(m_event->ChannelID());} private: cEvent const * m_event; }; // ------------------------------------------------------------------------- class EmptyEvent : public EpgInfo { friend EpgInfoPtr EpgEvents::CreateEpgInfo(cChannel const *, cEvent const *, char const *); protected: EmptyEvent(std::string const &id, tChannelID const &channelID, const char* channelName); public: virtual ~EmptyEvent(); virtual std::string const Title() const { return tr("No EPG information available"); } virtual std::string const ShortDescr() const { return ""; } virtual std::string const LongDescr() const { return ""; } virtual time_t GetStartTime() const { return 0; } virtual time_t GetEndTime() const { return 0; } virtual cChannel const * Channel() const { return Channels.GetByChannelID(m_channelID);} private: tChannelID m_channelID; }; // ------------------------------------------------------------------------- class EpgRecording : public EpgInfo { friend EpgInfoPtr EpgEvents::CreateEpgInfo(std::string const &, cRecording const *, char const *); protected: EpgRecording(std::string const &recid, cRecording const *recording, char const *caption); const std::string Name() const; public: virtual ~EpgRecording(); virtual std::string const Caption() const; virtual std::string const Title() const; virtual std::string const ShortDescr() const; virtual std::string const LongDescr() const; virtual std::string const Archived() const; virtual time_t GetStartTime() const; virtual time_t GetEndTime() const; virtual int Elapsed() const; private: const cRecording* m_recording; bool m_ownCaption; mutable bool m_checkedArchived; mutable std::string m_archived; }; }; // namespace vdrlive #endif // VDR_LIVE_WHATS_ON_H vdr-plugin-live/.gitignore0000644000175000017500000000016312650773437015434 0ustar tobiastobiasCVS .#* *~ *.o *.a *.so gen_version_suffix.h pages/*.cpp po/*.mo po/live.pot .dependencies .cvsignore .libs locale vdr-plugin-live/filecache.cpp0000644000175000017500000000162212650773437016054 0ustar tobiastobias#include #include #include #include #include "filecache.h" namespace vdrlive { std::time_t FileObject::get_filetime( std::string const& path ) { struct stat sbuf; if ( stat( path.c_str(), &sbuf ) < 0 ) return 0; return sbuf.st_ctime; } bool FileObject::load() { std::ifstream ifs( m_path.c_str(), std::ios::in | std::ios::binary | std::ios::ate ); if ( !ifs ) return false; std::streamsize size = ifs.tellg(); ifs.seekg( 0, std::ios::beg ); std::vector< char > data( size ); data.resize( size ); ifs.read( &data[0], size ); ifs.close(); m_ctime = get_filetime( m_path ); m_data.swap( data ); return true; } FileCache& LiveFileCache() { static FileCache instance( 1000000 ); return instance; } } // namespace vdrlive #if 0 using namespace vdrlive; int main() { FileCache::ptr_type f = LiveFileCache().get("/tmp/live/active.png"); } #endif vdr-plugin-live/thread.cpp0000644000175000017500000000143512650773437015422 0ustar tobiastobias#include #include #include #include #include #include "thread.h" #include "tntconfig.h" namespace vdrlive { using namespace std; using namespace tnt; ServerThread::ServerThread() { } ServerThread::~ServerThread() { Stop(); } void ServerThread::Stop() { if ( Active() ) { m_server->shutdown(); Cancel( 5 ); } } void ServerThread::Action() { try { m_server.reset(new Tntnet()); TntConfig::Get().Configure(*m_server); m_server->run(); m_server.reset(0); } catch (exception const& ex) { // XXX move initial error handling to live.cpp esyslog("ERROR: live httpd server crashed: %s", ex.what()); cerr << "HTTPD FATAL ERROR: " << ex.what() << endl; //cThread::EmergencyExit(true); } } } // namespace vdrlive vdr-plugin-live/i18n.h0000644000175000017500000000063412650773437014377 0ustar tobiastobias#ifndef VDR_LIVE_I18N_H #define VDR_LIVE_I18N_H #include #include #include namespace vdrlive { class I18n { friend I18n& LiveI18n(); private: std::string m_encoding; I18n( I18n const& ); // don't copy I18n(); public: std::string const& CharacterEncoding() const { return m_encoding; } }; I18n& LiveI18n(); } // namespace vdrlive #endif // VDR_LIVE_I18N_H vdr-plugin-live/recman.h0000644000175000017500000002606112650773437015067 0ustar tobiastobias#ifndef VDR_LIVE_RECORDINGS_H #define VDR_LIVE_RECORDINGS_H #include #include #include #include #include #include "stdext.h" namespace vdrlive { // Forward declations from epg_events.h class EpgInfo; typedef std::tr1::shared_ptr EpgInfoPtr; /** * Some forward declarations */ class RecordingsManager; class RecordingsTree; class RecordingsTreePtr; class RecordingsList; class RecordingsListPtr; class DirectoryList; class DirectoryListPtr; class RecordingsItem; typedef std::tr1::shared_ptr< RecordingsManager > RecordingsManagerPtr; typedef std::tr1::shared_ptr< RecordingsItem > RecordingsItemPtr; typedef std::tr1::weak_ptr< RecordingsItem > RecordingsItemWeakPtr; typedef std::multimap< std::string, RecordingsItemPtr > RecordingsMap; /** * Class for managing recordings inside the live plugin. It * provides some convenience methods and provides automatic * locking during requests on the recordings or during the * traversion of the recordings tree or lists, which can only be * obtained through methods of the RecordingsManager. */ class RecordingsManager { friend RecordingsManagerPtr LiveRecordingsManager(); public: /** * Returns a shared pointer to a fully populated * recordings tree. */ RecordingsTreePtr GetRecordingsTree() const; /** * Return a shared pointer to a populated recordings * list. The list is optionally sorted ascending or * descending by date and may be constrained by a date * range. */ RecordingsListPtr GetRecordingsList(bool ascending = true) const; RecordingsListPtr GetRecordingsList(time_t begin, time_t end, bool ascending = true) const; /** * Returns a shared pointer to a fully populated * directory list. */ DirectoryListPtr GetDirectoryList() const; /** * generates a Md5 hash from a cRecording entry. It can be used * to reidentify a recording. */ std::string Md5Hash(cRecording const * recording) const; /** * fetches a cRecording from VDR's Recordings collection. Returns * NULL if recording was not found */ cRecording const* GetByMd5Hash(std::string const & hash) const; /** * Move a recording with the given hash according to * VDRs recording mechanisms. */ bool MoveRecording(cRecording const * recording, std::string const & name, bool copy = false) const; /** * Delete recording resume with the given hash according to * VDRs recording mechanisms. */ void DeleteResume(cRecording const * recording) const; /** * Delete recording marks with the given hash according to * VDRs recording mechanisms. */ void DeleteMarks(cRecording const * recording) const; /** * Delete a recording with the given hash according to * VDRs recording deletion mechanisms. */ void DeleteRecording(cRecording const * recording) const; /** * Determine wether the recording has been archived on * removable media (e.g. DVD-ROM) */ static int GetArchiveType(cRecording const * recording); /** * Provide an identification of the removable media * (e.g. DVD-ROM Number or Name) where the recording has * been archived. */ static std::string const GetArchiveId(cRecording const * recording, int archiveType); static std::string const GetArchiveDescr(cRecording const * recording); private: RecordingsManager(); static RecordingsManagerPtr EnsureValidData(); static std::tr1::weak_ptr< RecordingsManager > m_recMan; static std::tr1::shared_ptr< RecordingsTree > m_recTree; static std::tr1::shared_ptr< RecordingsList > m_recList; static std::tr1::shared_ptr< DirectoryList > m_recDirs; static int m_recordingsState; cThreadLock m_recordingsLock; }; /** * Class containing possible recordings compare functions */ class RecordingsItemPtrCompare { public: static bool ByAscendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second); static bool ByDescendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second); static bool ByAscendingName(RecordingsItemPtr & first, RecordingsItemPtr & second); static bool ByDescendingName(RecordingsItemPtr & first, RecordingsItemPtr & second); }; /** * Base class for entries in recordings tree and recordings list. * All opeations possible on recordings are performed against * pointers to instances of recordings items. The C++ polymorphy * delegates them to the 'right' class. */ class RecordingsItem { friend class RecordingsTree; protected: RecordingsItem(const std::string& name, RecordingsItemPtr parent); public: virtual ~RecordingsItem(); virtual time_t StartTime() const = 0; virtual bool IsDir() const = 0; virtual long Duration() const = 0; virtual const std::string& Name() const { return m_name; } virtual const std::string Id() const = 0; virtual const cRecording* Recording() const { return 0; } virtual const cRecordingInfo* RecInfo() const { return 0; } RecordingsMap::const_iterator begin() const { return m_entries.begin(); } RecordingsMap::const_iterator end() const { return m_entries.end(); } private: std::string m_name; RecordingsMap m_entries; RecordingsItemWeakPtr m_parent; }; /** * A recordings item that resembles a directory with other * subdirectories and/or real recordings. */ class RecordingsItemDir : public RecordingsItem { public: RecordingsItemDir(const std::string& name, int level, RecordingsItemPtr parent); virtual ~RecordingsItemDir(); virtual time_t StartTime() const { return 0; } virtual long Duration() const { return 0; } virtual bool IsDir() const { return true; } virtual std::string const Id() const { return ""; } private: int m_level; }; /** * A recordings item that represents a real recording. This is * the leaf item in the recordings tree or one of the items in * the recordings list. */ class RecordingsItemRec : public RecordingsItem { public: RecordingsItemRec(const std::string& id, const std::string& name, const cRecording* recording, RecordingsItemPtr parent); virtual ~RecordingsItemRec(); virtual time_t StartTime() const; virtual long Duration() const; virtual bool IsDir() const { return false; } virtual const std::string Id() const { return m_id; } virtual const cRecording* Recording() const { return m_recording; } virtual const cRecordingInfo* RecInfo() const { return m_recording->Info(); } private: const cRecording *m_recording; std::string m_id; }; /** * The recordings tree contains all recordings in a file system * tree like fashion. */ class RecordingsTree { friend class RecordingsManager; private: RecordingsTree(RecordingsManagerPtr recManPtr); public: virtual ~RecordingsTree(); RecordingsItemPtr const & Root() const { return m_root; } RecordingsMap::iterator begin(const std::vector< std::string >& path); RecordingsMap::iterator end(const std::vector< std::string >&path); int MaxLevel() const { return m_maxLevel; } private: int m_maxLevel; RecordingsItemPtr m_root; RecordingsMap::iterator findDir(RecordingsItemPtr& dir, const std::string& dirname); }; /** * A smart pointer to a recordings tree. As long as an instance of this * exists the recordings are locked in the vdr. */ class RecordingsTreePtr : public std::tr1::shared_ptr< RecordingsTree > { friend class RecordingsManager; private: RecordingsTreePtr(RecordingsManagerPtr recManPtr, std::tr1::shared_ptr< RecordingsTree > recTree); public: RecordingsTreePtr(); virtual ~RecordingsTreePtr(); private: RecordingsManagerPtr m_recManPtr; }; /** * The recordings list contains all real recordings in a list * sorted by a given sorting predicate function. The directory * entries are not part of this list. The path towards the root * can be obtained via the 'parent' members of the recordings * items. */ class RecordingsList { friend class RecordingsManager; private: RecordingsList(RecordingsTreePtr recTree); RecordingsList(std::tr1::shared_ptr< RecordingsList > recList, bool ascending); RecordingsList(std::tr1::shared_ptr< RecordingsList > recList, time_t begin, time_t end, bool ascending); public: typedef std::vector< RecordingsItemPtr > RecVecType; virtual ~RecordingsList(); RecVecType::const_iterator begin() const { return m_pRecVec->begin(); } RecVecType::const_iterator end() const { return m_pRecVec->end(); } RecVecType::size_type size() const { return m_pRecVec->size(); } private: class Ascending { public: bool operator()(RecordingsItemPtr const &x, RecordingsItemPtr const &y) const { return x->StartTime() < y->StartTime(); } }; class Descending { public: bool operator()(RecordingsItemPtr const &x, RecordingsItemPtr const &y) const { return y->StartTime() < x->StartTime(); } }; class NotInRange { public: NotInRange(time_t begin, time_t end); bool operator()(RecordingsItemPtr const &x) const; private: time_t m_begin; time_t m_end; }; private: RecVecType *m_pRecVec; }; /** * A smart pointer to a recordings list. As long as an instance of this * exists the recordings are locked in the vdr. */ class RecordingsListPtr : public std::tr1::shared_ptr< RecordingsList > { friend class RecordingsManager; private: RecordingsListPtr(RecordingsManagerPtr recManPtr, std::tr1::shared_ptr< RecordingsList > recList); public: virtual ~RecordingsListPtr(); private: RecordingsManagerPtr m_recManPtr; }; /** * The recording directory list contains all real directory entries. */ class DirectoryList { friend class RecordingsManager; private: DirectoryList(RecordingsManagerPtr recManPtr); void InjectFoldersConf(cNestedItem * folder, std::string parent = ""); public: typedef std::list< std::string > DirVecType; virtual ~DirectoryList(); DirVecType::const_iterator begin() const { return m_pDirVec->begin(); } DirVecType::const_iterator end() const { return m_pDirVec->end(); } DirVecType::size_type size() const { return m_pDirVec->size(); } private: DirVecType *m_pDirVec; }; /** * A smart pointer to a directory list. As long as an instance of this * exists the recordings are locked in the vdr. */ class DirectoryListPtr : public std::tr1::shared_ptr< DirectoryList > { friend class RecordingsManager; private: DirectoryListPtr(RecordingsManagerPtr recManPtr, std::tr1::shared_ptr< DirectoryList > recDirs); public: virtual ~DirectoryListPtr(); private: RecordingsManagerPtr m_recManPtr; }; /** * return singleton instance of RecordingsManager as a shared Pointer. * This ensures that after last use of the RecordingsManager it is * deleted. After deletion of the original RecordingsManager a repeated * call to this function creates a new RecordingsManager which is again * kept alive as long references to it exist. */ RecordingsManagerPtr LiveRecordingsManager(); } // namespace vdrlive #endif // VDR_LIVE_RECORDINGS_H vdr-plugin-live/tntconfig.h0000644000175000017500000000062212650773437015610 0ustar tobiastobias#ifndef VDR_LIVE_TNTCONFIG_H #define VDR_LIVE_TNTCONFIG_H #include #include #include #include "tntfeatures.h" namespace vdrlive { class TntConfig { public: static TntConfig const& Get(); void Configure(tnt::Tntnet& app) const; private: TntConfig(); TntConfig( TntConfig const& ); }; } // namespace vdrlive #endif // VDR_LIVE_TNTCONFIG_H vdr-plugin-live/live/0000755000175000017500000000000012650773437014403 5ustar tobiastobiasvdr-plugin-live/live/css/0000755000175000017500000000000012650773437015173 5ustar tobiastobiasvdr-plugin-live/live/css/DatePicker.css0000644000175000017500000000206412650773437017722 0ustar tobiastobias input.DatePicker{ display: block; width: 150px; padding: 3px 3px 3px 24px; border: 1px solid #0070bf; cursor: pointer; } .dp_container{ position: relative; padding: 0; z-index: 500; } .dp_cal{ background-color: #fff; border: 1px solid #0070bf; position: absolute; width: 177px; top: 24px; left: 0; margin: 0px 0px 3px 0px; } .dp_cal table{ width: 100%; border-collapse: collapse; border-spacing: 0; } .dp_cal select{ margin: 2px 3px; font-size: 11px; } .dp_cal select option{ padding: 1px 3px; } .dp_cal th, .dp_cal td{ width: 14.2857%; text-align: center; font-size: 11px; padding: 2px 0; } .dp_cal th{ border: solid #aad4f2; border-width: 1px 0; color: #797774; background: #daf2e6; font-weight: bold; } .dp_cal td{ cursor: pointer; } .dp_cal thead th{ background: #d9eefc; } .dp_cal td.dp_roll{ color: #000; background: #fff6bf; } /* must have this for the IE6 select box hiding */ .dp_hide{ visibility: hidden; } .dp_empty{ background: #eee; } .dp_today{ background: #daf2e6; } .dp_selected{ color: #ff0000; background: #328dcf; } vdr-plugin-live/live/css/siteprefs.css0000644000175000017500000000116412650773437017713 0ustar tobiastobias/* ###################### # This file is part of vdr-live! # It is here to give the users the possibility to change the # default css style of vdr-live to their needs. # # If you don't want to change default settings, make this file # empty, but don't delete it. ###################### */ /* uncomment this below, to make all tables full page width. */ /* table { width: 100%; } */ /* comment this out, if you want epg images at their native size * the popup windows. This here restricts their width to 120 px. * You might also only change size. */ .info-win span.epg_images { width: 120px; } vdr-plugin-live/live/themes/0000755000175000017500000000000012650773437015670 5ustar tobiastobiasvdr-plugin-live/live/themes/veltliner/0000755000175000017500000000000012650773437017674 5ustar tobiastobiasvdr-plugin-live/live/themes/veltliner/css/0000755000175000017500000000000012650773437020464 5ustar tobiastobiasvdr-plugin-live/live/themes/veltliner/css/theme.css0000644000175000017500000001314712650773437022306 0ustar tobiastobias/* ############################## # Globals ############################## */ input { border: 1px solid #004F00; } select { border: 1px solid #E0F000; } /* ###################### # Tooltip style for hints ###################### */ .hint-tip { color: white; } .hint-tip .hint-tip-top { background: transparent url(/img/rounded-box-green-tl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-top .hint-tip-c { background: transparent url(/img/rounded-box-green-tr.png) no-repeat right 0px; } .hint-tip .hint-tip-bdy { background: transparent url(/img/rounded-box-green-ml.png) repeat-y 0px 0px; } .hint-tip .hint-tip-bdy .hint-tip-c { background: transparent url(/img/rounded-box-green-mr.png) repeat-y right 0px; } .hint-tip .hint-tip-bot { background: transparent url(/img/rounded-box-green-bl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-bot .hint-tip-c { background: transparent url(/img/rounded-box-green-br.png) no-repeat right 0px; } /* ############################## # Tooltip style for epg infos ############################## */ .info-win .info-win-top { background: transparent url(../img/info-win-t-l.png) no-repeat 0px 0px; } .info-win .info-win-top .info-win-c { background: transparent url(../img/info-win-t-r.png) no-repeat right 0px; } .info-win .info-win-top { color: white; } .info-win-c .info-win-t { color: #000; } /* ####################### # Menue ####################### */ div.menu { background: #000020 url(../img/menu_line_bg.png) repeat-x; color: #005E00; } div#pagemenu { background: #00F0F0 url(../img/bg_line.png) top repeat-x; } div#pagemenu div { background: #00F0F0 url(../img/bg_line_top.png) bottom repeat-x; } div#pagemenu div div { background: #00AE00; border-top: 1px solid #006300; border-bottom: 1px solid #005E00; } div#pagemenu a.active { color: #E03000; } div#pagemenu span.sep { color: #001E00; } div#pagemenu span.active { color: #E03000; } /* ####################### # Info Box (near logo) ####################### */ div#infobox { border: 1px solid #005F00; } div#infobox div.st_header { background: #00AE00; border-bottom: 1px solid #006300; } div#infobox div.st_content { background: white url(../img/bg_line_top.png) top left repeat-x; } div#infobox div.st_controls div.st_update { border-right: 1px solid #009100; } /* ####################### # Head Box ####################### */ div.head_box_l { background-image: url(../img/bg_header_l.png); } div.head_box_m { background-image: url(../img/bg_header_h.png); } div.head_box_r { background-image: url(../img/bg_header_r.png); } button.smallbutton { background-image: url(../img/button_blue.png); } button.green { background-image: url(../img/button_green.png); } button.red { background-image: url(../img/button_red.png); } button.blue { background-image: url(../img/button_blue.png); } /* ################ # Event ################ */ div.station div { background: url(../img/bg_box_l.png) top left no-repeat; } div.station div div { background: url(../img/bg_box_r.png) top right no-repeat; } div.station div div div { background: url(../img/bg_box_h.png) repeat-x; } div.content { background: white url(../img/bg_tools.png) top left repeat-y; } div.__progress { border: 1px solid #006E00; } div.__progress div.__elapsed { background-color: #FFCC00; } /* ############# # Timers ############# */ table.timers tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #006E00; } table.timers tr.description td { background: #00AE00; } /* ############################## # Schedule ############################## */ table.schedule tr td.head { background: #00AE00; } table.schedule tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #006E00; } /* ############################## # Blue Background Thingy ############################## */ div.boxheader { background: url(../img/bg_box_l.png) top left no-repeat; } div.boxheader div { background: url(../img/bg_box_r.png) top right no-repeat; } div.boxheader div div { background: url(../img/bg_box_h.png) repeat-x; } /* ############################## # Recordings ############################## */ div.recording_item { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #006E00; } /* ############################## # Remote Control Keypad ############################## */ div.screenshot { background-image: url(../img/tv.jpg); } /* ############################## # Edit Tables ############################## */ table.edit tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #006E00; } /* ############################## # Search results ############################## */ table.searchresults tr td.head { background: #00AE00; } table.searchresults tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #006E00; } /* ############################## # Infowin support styles for EPG-Boxes ############################## */ .info-win div.epg_content { background: transparent url(../img/bg_tools.png) top left repeat-y; } /* ############################## # About box ############################## */ .about_box div.about_content div.about_head { background: #F0F0F0 url(../img/bg_line.png) top repeat-x; } .about_box div.about_content div.about_head div { background: #F0F0F0 url(../img/bg_line_top.png) bottom repeat-x; } .about_box div.about_content div.about_head div div { background: #009900; border-top: 1px solid #006E00; border-bottom: 1px solid #006E00; } vdr-plugin-live/live/themes/veltliner/img/0000755000175000017500000000000012650773437020450 5ustar tobiastobiasvdr-plugin-live/live/themes/veltliner/img/bg_box_h1.png0000644000175000017500000000025612650773437023011 0ustar tobiastobias‰PNG  IHDREø²X pHYs  šœtIMEר…MIDATxÚ-Ʊ €0 DÑÓ!Øý¡Žè¨Ù„ ±}¦ Å×ûØJáz´ðžñªoÿà]69›-œó8 û’D¸‰PJÂýWIwÚ3o¦0Ú®IEND®B`‚vdr-plugin-live/live/themes/veltliner/img/logo_login.png0000644000175000017500000012367112650773437023320 0ustar tobiastobias‰PNG  IHDR,wÎDMcgAMA± üabKGDÿÿÿ ½§“ pHYs × ×B(›xtIME×,!]Ù] IDATxÚÜ}w”TEöÿ§ê…N“gÈqÈÉŒŠ0çæœs^u +Æ5¬«kDÀPuE‘ dAÒ˜{¦§Ãëî«~¼Ž3ÝÀè~ϯÎy§Ã uëÖ­›ë>ò\Õõbÿþ—p~ }øt¡½ê½{¿œœœg$I.ààÜÐ6f™+®Ëýç oG™B€Áœ#—ˆ DâŒë7(¢ ¶©šZucþsÿnÿÜ·ÃT^ëyj ˜ÚöwÜTôO €gè¹ê[¹ž\µýÿœÇo!8¢ ®|!vÉÁN`1kç]=ÿ=^m¾ßÞý_NšÕ-ÀíŸßÀ^_ñÉ¡­õPª›¡|EÑj¨ºJut9è=$G;òîýV0ÄÄEeõ‡ž1B_ýíÖ4LœöȨ0UÁiã=ÐdO(¤ä>ûì³ñKs(ÿ½ãGrÚ#ûñi‘lt«íjPùƒbOMsïêeQÀžy»±f/2°ü c´ê}\38v¬ 1ø×$€ Ðd¯yÏ_†îùÈa€b D+šã·h€ñw#$ŸJFD+›ÀlýÕ;"ÞÄsÓ03æ‚Zíš•¡µíÿß4«…Žž\Ì!¨ù9ˆ@N|͵ÜQyÎùû ,üqéͦ¦ÞÓ_$±*íV·:´²­B;* €.¦Ñ‘à J 4 ¿!¥W ˆ† Ð0¯xØå%‰à”SŽã»*ª2 ÿ|†cááG¾ à‘ˆË^¡JE–Ê@eϨh¯ÌpU¤ªy‰·4ìÒ«p0T3ÝêOS«ü°šHN…# “à»d§ìt@mÒ†€ì”!9%PJ1oÞ<ôìÓ={÷CÏ>ýGuT$§ É)£yYKNë¯>â]ÑJ*?®&TÙ)£pxÁ€!W b©ýËrŽ£Õ§µé€€Ì)Ü.Ã/´ÜNn—å‰ßNJ¥‚-ë…¦ø )>„Ûš0a¬\¹Ý9Zs»ìë„SŸ¿ã¹Tåp»däæ»ÒÈÉ)‰pËÔtÌÕ‹%å3ä’Æ6e$— j—Õ%ÎK 9…|Ó‡hùäVä9òœ E¹¿rا@=¦,0ìü¦2#›Øòþ"0H ‡M™ÀÚú×¶u/o&а_ß²ÒÕG‡g€ W ®Þ:¼kýÎĨzé˜;Ê (‹pôñ¢Ð#'¨¿}ðyI\½5+ÂŽl<ÌÙK—œ}t8{ë÷ü€·`ü´Á|ü´Á¶0éØä>ˆÎ<@ã´ø9÷ÐNø=„oU ä¨Z\wÞüÜêŨÂ|ù¦½®kʧ»c陵cèÙ[vãNsÂ'EpöÍ…‡ã׺†›‰™Í*Oyf4€uW?Þ´94%þÿÉÏŒä„Ûˆ¶ Ë`à¶ï…˜ƒòÊe¾á)iý<=šƒmU ä˜÷ðf‰|h<±HùbòðÑèbûØ|ò9‹³Ã)¡¢Å,3VÞæ÷¿swÏW~ù@ŸòŠa˜½!n›T8ãœ[àPAˆB)i04}é Ï-Ȧöךä¢HкVÇÃ'¼H:æÍÀ=œ›rD$U»E-¸{ Hÿ›§ãœš¸£äåDŸO-¹‹?2áe"n¯÷öÉñxê0 sì÷RND›î>8é옿ô»‹Ë©H‡€žò1€î£»K°¥ªáš&XZð‚L8ÿ“–*ÕÍØ9µJuÂ5M‰s3fÌà15§><íc¢Ô4A©nÂÉOýXVº<}æP¥º Šý,y×~?7on^Eàókæ‘è®èµ W6«V4`ù? V4@Ý•¸ÎõÄO@r¸Àÿ3Z^­¢ÞŸ§d]y5Y­h„ZÑ&€øsi‚_E+šzjw¾úûæ4´G*šãtº!’T[@«šó|ë¿Ië0ZÝ B€üÂôÙ;ö¢n% 8‡LW«ZÀ9GC¹VªJ”ªQÓßprÓG4æ‚Þ¤¨ý%hÖÍ4 xÿ»àX`VâÏ“uP—ÀÇxŠŠÃѲ=Іßà –~ê°„ÈÙ4«åê°Ëƒ˜:’bÄåAØé¿Rs@ØåA8¦²ôêÕK\[¾[¶nµõùË.ã 8݈?«v«ÆZަ†ä½­Agµ”4ü&q, ¹­”`Cn+åiâ†B€àÐýèn¬y…— ¿qèhˆ4D@«4гgOkõêÕIñ±l9&L}yNpƒ£mƒþ ĽË[0üÆ¡\ #ïÆ¼–mo•'ÎQClî6®„+›"éÂyçû»ˆÇ%£Ï!ÝŽþØävÉP¶…^JÈ@—;\ùêL·|Æ| <ì%[•Ñ;p l{«œÄŸ1dÒ€Ä|n«¼Gßq=© ÿ½ƒ`–òY|òd§!ù mÛ÷¤ž_ܯ;Ü×^ ÷aÇ zË*@ñ†)øeê•ðÿæ¾éäúV€Í¿µfÔÄ<«…RRTàÆ¨ü=ÊÞ®j€¸Ó(goÍ!Rß“ 4go 럯O׿úèpj|˘z8¨ÇžN2ð`ÀZ‚ƒà°ÊÞjB6maõ[»ùØ0.ö¶àì-6âmñÓŸÄÁç·ýbdÖNY:€Çíy㫨HžÈÏùÌ…nü”žÑˆ—ùa6ËÀŽÏýhÛ`’Ý öS—à@¤Îo¸{ g€äίüЇŒz•6;Žž Z‘vr…_÷¾|§7,¡ô¢Àñßlø<ˆ–m᪺¢m°ŸÜœpJÜ$G"ÕÜ"È3EÃ|&©‚<f¸®äI‚}Ð>Š<Ê%jÀ`R;-!ý:ÒQ€@ è–ˆàv†ÂáBf%wÔB²ÿ[éT‡eIX»y-yeܼŒ×¼zˆ+5nõœ—8ž«»‡$Æj65]øêÉÍÚݹú"¡Ç <“F=»¿˜Çµ{}U5£Ð· È%ÇË3¢:síÏ'ïÑ4ý­'†M½)õìÓ•wðàfÏ>Õ· ø¹qéM\ÈЫuÌ8wFFÍ©³vÕòkú9]ŽêÔñ·¼ë…|£yF.ÂkÂøð¦Ä,£#±C8陓îÙ³çJ×w;Z!ˆ–EðÁUì åÓ«ç]ãÜB‘I Î8ôfÝ÷þYï'œ]ׯº>M‹œqÄôâ´/ùì|N$C!Gpusžù~€ºlÞùœ¥Ì¡õäàNèÄ-ßú±ð½E™&á;Ú›ÛpÑgçxAI b.‹bÎcóhWM¨ömÒgqê¤ñ¡"ô{sÿ¹PŒk ERêpCÓ%„Oâ¿…ÀÉk™ÿôª’®pÎ+GóÐÖ¤ÚÜüSØêv¤[Wtá÷*éúýå—óT iñâŨ««›àÔ8">½ðëng¼xÄã„$nÌ޽î`¶lÆÚ½â­šß ¦óÄb 5kqï§§<èh ›š–*X3g“€¥!ë¿w­˜yÆÍƒ>¶çÏ~ˆ^œW$ç}ºÒYç§ß\ʲú„W»ü'圧4H‚©‡Òç9ÝK ±£¼Ï?ó8žøç ¨««€“ôP¾½÷çÇN¾nÀ?(%±ÅÈ!é¯4!5‚UQ4üäÏxýÈ+ûpf°ØŒå³Od&ÿ†]Ü‹Ûtj?§nE”jUˆ{¬k*¶ƒPšà¤Á@Fpºuë¯×;@u¼Ÿá—ôʈ,ðÎ¥!oG­›hA¡Jõ ¿w•*Ŭg sóLð`ÂáFŸÏCuÿ­{&õ²¡· åºÆOjùµÅG˜.¡ 9 â´ÓNÓ~üñGñÇE‹‘[Ø=—X–,]†‰ÆC„*˲Þp.Wš‚Ã-Ž]ïíê  %E’Û]*‰Å‡‡<ý;ª/¹9Ñò~EVBxY)j«ö³»ó X-¿´üÚ)ssëˆí†&ôŸ†3+cô­#xꪾ«E¨RI“(£oÎ I^µõÝr\6ùR\zÉE¦› ‡<0ê]g…#vÔÿЀP¥RÔ^ôÆï_zíh¼9¾ F4ÁÈ|ôZÿ:6mÞ‚šêjüóŠ# Ï~oàgò9A¸.rdWôÀ-Ó¶ÙC%¢±¼Î w¡tøÈ+J3®_WxW¤:„†eî åwʳÒø½Ã¹Ô3ÉBÕj‹k,/›]ö?ðËcåã™Á—µ¿÷ˆç†rB)–÷+p@¨ÍU §Î€¯j-œ²œèšgûÜ´Ìœö›íG^©;!6½Qu¨J}aOU†±ær˜ÆÉ¼¿Pþic.Žü×°ÃS%àO÷mÿ¥Ë:Êñ3J9/°Ín¦Ô™@1õcõKMhZœõ>‹‚Zg,—`*´6áª0‚ ˜Èé-"wû˜µcäù ¼ñîJ q;qõÂz :;UË+ zˆ¹øÂºžñ€íi‹/¬“Îø¢_ŽQãIÝM€CŽÏEÏan¾äÁÁÅ` 7—DjËnu´ßãïÜÿ¦úM¾K,“‘¯`Û—ÖŸ ÒÉ=3ë7ù2‹Å•ôx¼ŸÅ”œëŒ# νªb¬¯Ýк ±è6ß؎¸bÄ7¾êP1À qH!oÓ¼ê¡ã.ö½¯V±½²”`Û⺉äýñ©¢(Œ&„PpË´Z.—þqξèö•§‘÷?ðF*ˆ‡JúŠ‚è ”s€sf™–¥rÆZeY®7tc]8¬|[·—|O”_}è ÒÒɆa2Æsct‰ØºÀÈ7b¾ÑA‰*‰bHUÕ ç¼Á2Œ¯n.~q·”9-øà ‚ Nnmiÿ€i ˜H,ëF0–0G˜Æ@èÌ ìj{«õÞ r\ÎÏ8’J',˜z‚¼âÊ× àÈw{ðQä!p0D|* QL˜¥jç<]q—ŒÅÁ,2¡¶î¦~,‹/º¶à¹ã3o ¹ŒA {VÅÌ.NEÕM‹ørn³£¶ß³ùoÃþ=â êÖ¹E8Q³+.­l;2Eç¦&TKƒ²E@þq¯ü`Ù?îßõ÷ð{zÿ»+ EíHcËŽ¨¦Á¯Z÷»4jèhš“ÞÕêð?‚¨çjïæÁ¨žÝƒÉc®„wʼnG@ú04×Eá(2¸ïxF)Iéú°Ï>¼êþô¸7Òˆê PÂZË n½S!Å$á/1ÍmU£{Ѝ{6Ý4Y–¥Yí!×›MVD`…Xº¡_J "HÝäàu‘ŒÔ¼&B«¢à–­²%†ãb„’æ27¦0”œ— "‘v¾m#hF_7-áe¼¯ìf¡µ*rv‚3^÷☩}Eh éÏ T¼ {à’—EÞ>wÆûŠ"*™QÍäRÑ?Ppz!¤Üh[ÝôÀ—·|ù¯,·“¿”®úúêÆ.½gÎѹ)”ÀÁ;DüþÝãÞ9mOaë·°Ÿgüu×HWÚi.š+¾¾œ ¹Bb>‚ËC˜=åË=BÖŸœ‚âÞÝ91“Äàÿ%€‚qù S3·æ©E/-~´‹$½}“ûÉiTÝ®âóÛ¾Øk/éïLær9á%€ŠE•G¬xþ§UpÚÌÓÈïÿZw µœÐ²­¥‘Y¬"aZ,=†P ÂpîOqÄ­c‡î ùN3ZÃÐaèÁ0jfÔÀ=R„C *Ѓ ôHÆ•íp:æ<ñO¯EB[üЃèz ¡‡…óÞ:½voy*ÉÑwN- @ „‘—ëž??÷â¹¼þ·†uÍeÍ?7—5ÿÌ,V‘æ¢ y}’Svq×PX”»¤ µo¦!V$ézã…zT(®ÔkŒhzŠñŒ3x<áFQÜ}÷ÝHKŠànõ:ïÏHe_¾_•Þ{‹¬°/p®,HëS#>jKdXš‹|úñv3Øÿ½añª4d}sãbó¬çu$'WkÓºg²ÛY/yºÚJJ”2*‹\›À'©¼Ü'‘uä‘G²¥K—¶ëx ÀLÛâÿ}ýoŸúô¸¢+ [îhÛš°ÇBˆ)ê?5¨i‹ú"´Iõ+!¨ÿ¥íx«:8ÿ¸¢¬a €»˜pÃÈ;–LÛòŸÝÐþ6Õ“Û¶=‚>G¹š­VÅÖb"Ü 'ǶråJÒæ÷#¬(xíõ©˜t~Âp83Y@¢afµË~8êÊa3~zû¥{Š,Þ¦œÆ8Y8œ­»|ÓÒV‰/ ½-™¬’Öùœ'Öj4Á½¡ØD´:ür—rm!0oÌ÷±k}õdÒb¼%æ 5ÛÏ´BIdtÂq¸ê² Q]]ïçÎÁ†5+â§u 7¸_*\̄־dOuÊõý9k‚{ð– XsÞÕ>lÿ©áµôþìñ¤ÂÛÁë E¢ 4©‹ˆ.¶[óçøË{Õ†ýɇný)ŠP›67ªDo­M*z ~X„yÇý¦‚mþ“ï¿7aq´¿ïû·ªÊ&^Ú#©É‚Àß”=¨sìÅÝ\àèN†8“Ü.9 TEOñÛ·Ôi @SZô[‰€€BWµìÈR s €M IíÆœT8Ó‚¶²2><•Üa("!ÝLבDŒ¤ù³ø±1 ÅßÖ÷Рݘõ˜q^fd@P3Ò~ûýQ<©(Å+•ü6Ìv™I·Ûu (_‚â5{µçËAÍ„¿Ö€n2–Y¿~æÝ<â¬"ˆNg5h®×ŽÏ†¨Ñ”D¬¤¤-Ôo Šç%iƇ‘2‚‰oBëÄ—P4ö~˜Ekág€Qp9€[b.š$U 4¡¯ºÉ¡Ç"C»“BñHvj«\€â5‡hnýï_HlÒÌN£;ÌãÐ ‚DVUÁè|4oŠÈÈÔdŠR[ªÂX·!Ä2å Aê xX±Áy<þ·»oG´ôLÔµž p@Ó’KÙår-ŒF£G¦â@å´F( QjËn¬€ÉQ³Ø)GøZi2.íÌ×~¼‘µ}fƒsà¥ý9c#•€Þ§÷ôÕטÓ!B’ï‹X‰Ù&.q Y I2(IÛYT@=>ljjÂgž…ÆÆfJÁcÔ¾ú—•xà¡`åO+Ƙàó„8—¤„g¸HѼ- €Ê4‘g B3ÈÓ!ŠÜ¶)€¶ßü£ìŒz3g³•^9€ ¹¦Ïd•ŸÔCoÄ9ᬠ¸²º•‰$‚ É®ÂÕ¸Á×~ŸëExW4CÙ~(‘+!‰¦T@8¾L–e >ªÃìoذ‹~ü…EE˜4iÒ¬>ú¨7€†Á×Û?KpŠhûÍ/Åþ¦©ëÝÙý \©Sx@róJÑÅÈœW&8DGŇ»2KuQ¼Gñšsˆ¾vð…L4"R³†Â$‡p»(RÄžGvƒèÓ&JôŠÄ5Rb¾”óH}†(R”’ÒGzöê…¥K—AQ”´#¬(8 ?–,Y Y’°råʸ’ Q¤ÓÚ?OΑ”O1bì[‹å+¨5_TëûÍGÔºh®BxÔÔúžÑ7ãØw¾½óu®1ô× „áSQ¤ó$@ÉŠ¬ío•¿†(ƒ$ ‰£ï ½Ò®äJž©eghb*{!í~Iàt:±£¼’À¡kÑGD "Ç-¡­­ µµµ „ÜÀ-‰ÂÕ©Ï“Ej“zó¹}=‚ѬC’’÷æôpCèDråÉDB‡À üeÑÁpmhtØÄ:Ríímºs´)ñä¹Ê¯«ÁLþs2ŎȪ­­ÅßnD;0£Èu Øo¿ýðÁÛo€Û Q!égÚ}Åúóo @©ÏߺuF9ËëëyµýÄ ÎǨ«†ftãÊ’˜/‰ÜÔ…ê¹uÇúÝ"KtB ‡ààœ}&tÃàóúŽôÒê°ÏQ'GNgÚ¥þNž8¨“£¯› rÆYøé›à”)D·C€òý=°, ]~Æ Êpû°õŽ6ÔÁAc°„jt5,öû+ew@°@Ix©“CÊ%‚è…öׯûÏæ ‡‰êEuÈíïZ—Š»õ(òàp.8h ìÛDј¼-ñØÁ¶YUƒ¤qÍÃ9‹À×=E;þÀÝðn9îE4íZ—´¢]C‰VŽíå;0¬—¨þ}—nDŸâ¾i—•ͨ¼U©‹¾±'¦Îè+qO©#m#¦‡‚í×tɳ²Û «£_‚°ó €Å º­dÞÍ-È!r8(Æö'g€R8 ±ú‘ÃÑcÐAˆ4lJ»ÇðnH+†õ"¯ò"˜U<÷¹ý —ñæ©5Pê¢ïî©]˜7Z¼6-n.%º; ôœßž©ø:a ÿkØPbïÀ¬¸oû/»]†°òþmç?X`BÌ7ÑûT7Œ¡MóÍØa:ñl¦`¨;OòM w+ú°vj%ƽ?Ô‹!‹4íÐVNX=@kõ ?Œ#ÏiF`Wb‰ÐÖ”:õŒ½qÍüüÀöéÔ¥CÊ·ðKù»B_¥Mr¾±æY«h¾¹ŠæY«ÆNé»°KÈÇ!H…:¤" R‘†<+R±ý}ë¼hù-ü\FFY¤B*Òp¨Cú¶}Z÷" gàÞǶ{Ð}ØX·¹O¾8b·Qè6<ˆ5€¹È CÓ€î—ÖÃÙÇ‚èÒá«ñUX*›»·Ž¿·Wè±HƒX¨C(Ô0`’G½Õ³<‰,{¬J­"©¡°DÆÉ]Z† wW»ƒä4§Æô±¿9iÀfø3êjÝ¢àÈŦ×?éÀ5ýzá j WÚÉ!ù8 ⲛ΂ž} / àg ÏÀš/zã’eõ` ÂÛD”ÞTS·@¶·¾÷x+ºC«çè~””0xºJì ‘^’r"™W³ñebÁ‚0º¡?zG—Ÿêê½oµ=Xþ-&¢Šæròkýaƒ €êñ]Q$YÑÉMŽÐ.ÿ8ú%:©¯ñg¶G·^›STX‚4WÊŒešˆŽ|ãjö¦—Ý35ªŠ½…!o„´§d¿ýøøˆ½>À¡ú-H¹´òÁ~ÿ)ÝÝm/ÔÝè6¸Ù@4¨yÿ5izv€)wldQŒ=Bb$íWz¨L‡PD”gǽž?9+¶}›Rq§aºÂ¢õtÕéˆAÒ9±ÛÖoüˆÈá§–¾¶ü±?K|_üõËÌó¹‡ÔÎÂlÏP€ÈÖ(ZÚZú,feý_­£^ôå$N@1³!‚ }0uîóoé§Ì*»;ð¥OΜµÊˆ(³#uAèF@ÃŒF@ƒŠpEç¼|ʯ؃dÓ=iç½wrS¢Ï-a”ÃoÑš |kZá˜-‘Œzì:ÓoªáŒHç~zY–?òÉ'ù‚ øÂ… ùwß}ÇÏ=÷ܸ(š ÀÙ©~άcUø‰ÖB´.˜onz@ØÓBžäª“Ü¢ã¯&,]QnÒ!èþ$~âøŒ¤È„Õ¦^ÔE÷9Ï&ª³ÅySÓ,•ËöÎûÌÍ·:^hœºä_kæísšz§Ó3¬ÎÑð}!ælØiý¡ídO(ÉMóC0œêSk>ÝÔcåååM¹ãŽ;ËfÀôéÓÑÜÜ Ø™ìDÄolˆúT„À˜J²zI¥ é—9hòà£Ö}¾sù_EXV0ò%—I|wdF‘íÛqòÙÞ †aQ‚øNé¦_ÀmtI?¶[ÂËêNš©×·xR÷‹ù ‰jaâ•Ã"‹ßÛ.í‹ÕwÆ=#¦‘¶ÛhN'xßÕ¿¨€Èv•/¯y|øžƒ¸7óygæÓº53ªù555øøããÇO€eYX¶t 8cdkÖ¬Áòå‰y÷8ÀrØ¥62¶üÎO»{ØtËäסý¦"’ 3Y6@æÀ.Ùmý™uòmƒœD¢B(#Ê;uoEš¢Øö[íYO«½„ÅKE!XÁ澸Å{ÚÕ}Õt<)Ê™'Ï#Õ[ zÌÙ=__þ߯›ÿN¹²÷˺ÞÊâ±µXÐö®óÀoµmR&íRIÖª+:D3#½Gè‹»ï¼ 9<Œæ×ÇÃ!XÕ~ŠþWÎÀ‰Ç‹·ßx·ß‘vO!ìX6Ó¸‰r='¤ƒ‡Å,¨\P¿Ãȇ½FÙ×ÄtÂ¥=$JÈ 8FÖ¢P O:gÆ ì¥[¶R‡ajqŽÍÙwÖŠÝgsd]Ñ!3¶g„sß­{ê˜K{Üb„x/ÉA2òö‚Á@S¹vSßQžÇkËÂ{ƒˆCÎɃb˜[%±¨tºaGEY Ê8Ī53ÍS˜æ.¨DU8„Œ‹Âœr¢—Mb@ÞÁv)en }?€|çU]ÖIÓ¸ÖGMìÈ‹J28QIšóÙçS1öì¢ä$»U‘“NДñƲc»v)Í7#kI.ÚMœD2T­Uê×EƒÖÇè¤YH·À9C¼¦™!¹Kûå7õÞRçQÄ2¼;³ÔZIìêo{ì‚0E‘GˆSã ¿HªÚ³kYîǺ¸È fšG2“>¢j`ŽŒÃ¼÷ò·¶àÔOBaéb¨µv9dG/BÊöžõyÀ±©÷ 7€Ú݉}Å´ì·›ðìA&%¢ÃeèïpM{ÊJ´Künod~Éà×7T†ªU yÂv_­v*ìÄNǵjVëæýÏ/\£)æ€p‹)Ê%4\ó[äÝö`‹{0ñ"g0AIæeë¢u&JO.ÚV1ß7dOÂY#/걂9 Û;ÎÚµšå~ÈÒjßöè ¤Ä)MQ²ãw$ûŠg„‚Ñ+êHÏ{m¶†\Ö÷L¦³9T¦aÏ™Ö߃úœÔmrÝo—Ê幬ïy&ÅQ†•šàŽ0hŽÈ}ÛÂ祱pQJ–Ðè„°,š¤Ö“O>Y™?¾~Zú#jª«!ËrÆyÐ5 ²Óƒ{ï¾/¾ô  ®®Î3eÊ”ÕS¦LyÀsÈ’O®‹Òn ‹SÞøü“ˆÏJ?ÜÆ›R 8(D·¨›aó%¥*ú€ªh‹î*1 ¹¬ï’v¬{ÜŽj+†½93¾z+v|T;XÜqµã£ÚoK¯¼D ›D˜qDc»#´#ø€o°›ì¼AW ‘,Âgg›¦1„u„+Ãc‘R£4aµŠN7 +^€‘‚ÛA½^=öXíŠvçœoþ‹¨Îп_ät´ˆM åååÐ çO¾k߈ŋãò+®Ä”)Sp饗þmÁ‚·{½Þñ~kϽ,Ñ‘îÚî@E„}|£6©¥YNp8ÈàcKMA¼Œ'áŒÃ ›(< Ô!dÅ­g”9cŠatnÁ€gåÇ{•a‰Ž£™n‘xáJåG±#GkÕ–äh!·8tŸÍ« P´W^ó!× 6-• ‚KȘ\­¬nN]§.ˆ!× áÔMÁ# œtÌQ¨ý®Üä7¨Íê{™Ìß¡× ™ÈÀB2+6€²úücÏ?Ôéòà­©oàÕ×ÞÄäÉçwy¼»*ªFñäãaÉ’ÅxèáGñÌÓOâôÓOÇÚµkyCCÃy1ç©×XP¬NÉì Çë~¡ò ÚÖû‹‘²q®«­d\±'§4Ç©ŠyCóHK.í”0#h@pR€ç®÷wí±ÏqðµƒíH!0 Å€«·KsE§¥Økª~~=4¯vŠ¥Z?н!¬3vŠ‘Rˆ2…$Ñäþ,I@ÞÔš-<`zV½ê–aÕR …` ñ 1¾ßL¢¨û®ÎbÇ2µY™Í§"Hrü9 ƒ, D YÀM†cFsè?þˆ·¦¾³Ï> GŽ -îòÑ»G1Üÿ|æ)H’„>óößÿ,Y²%%%öÚŽFLC”$ºJÎbx±áã8’í÷¦T¤ßí­«¡eUk¸rf•ä*tÀRë£éýˆ4¥ O‰Ž –ßP‡];dóéd‡p¸H$I€§›F«XÌIuI¶çKΑ>²TkÚg7ìI;àŽQ™Á*h¬Œl&e²ym ÀÑ¿á§æšv÷ÞÎì¨4usT,ù ð®i6Í–õ¾™D`Ês&rƵ/•¦h¾¶cFÁ‘GŽé3ÞÁºÕ¶(ÌÉÍëòX•P¢D2 ]ņexþßÿÁλàr¹ …À9À Ü1jÙçÄÌžÂ-†êêáß`+öÁ®‡ýn1Œil8 ºw¯á(uaHn±të‡;+÷`Îè!ãD)WL¦+q ~E#ö®ó•ð]ÜÔ”©­¥¬Rr ÿfš A$™@ ±ƒ dLÜÝÕHyýæ!÷¯ˆ € ¢L 8ìO®YP[U´¬÷ÐÐ ɾb‡Dì#ñp‡†1û‹ÙX±xÜn§f„ÁÓ:–b©àFÌÃí´ïY9ëU¼öÖ{X¼üg|ð!0MS_y>ÊÍœ[$Hø<¾?< ‰ß»þ[ Ñ-|ûm.ûd+ÍÆ×¶nß<};‘s…H´!’è7 ŽÜä—zmŽVìwÓ°÷`ÎOrIœè<ñKÑÁ4 Þu¾CS#83aìÃ#ýf+Ë—ŠpÂAxú&±ÆŸÛ;Àµ³ìŠ¡ø¡Œäf‰ÑëLD÷R+ lÿ¤ fĺ"Ò¤ÎÜ?lìã&rÎQ’äš ¶‡r‚y}º¡`â­6…1 áå¯"ÿÆe8èÀýñÕ§ïB ]~þ’»à>æN#Ï¥LÓÄß&€çÏ+çÀ'?û+Ÿ'áR‘jÑ´äÕäk8ª¿kdD›~ñ•¢]©›}ÕÆ>4ò*C1ß•r¤vM"9’ØQúæß|È–»fÃ+å‡îA4…È‹ 1 -u‘ì“”—ÞΦ ¹™_ÍB/ò»ÏÉä¹Éè>Elô$æ<±ÉeÓªáê)/hþÕ2¼¥}÷䈉ŒÇDaìyóŠz  À°óì%řͯ¹clþ¹×.‡f2ôîÕ›YÐqGv{ë´­ý'–XÀbÅ"‚“1 |nº]9OJ*Ó)㫛烮é¬yµìãR;ü‰‘”™–eù©g'Y›üe \½êïÿÞéÞW0íÂ:ú?CEf1ƒ  _‘Ä-ïo!â d¶$«¿À$ºQ¿Äß@—ÂBG½:d",Ø„Eì Š?ö)€ÃÅKºM°IgàÍëqÇ´­xcI¢±;Æúy& ]m@~/€«°3g¢@h@@`€h‚…;ÞãXÕׄœ/Æö6le¯4Áуª +£bî?¨Òpôò`¤ŒåzÆIîI:†˜¢ çX÷luÆW4õêC ð5<×aíÒ°9@TЄ÷~ºsÇÕ{ä í¬­¸³ÜœøÁÀKM¿õ±˜ŸJ²±åJbÒˆ„æÜä¬Vq¨zÍ?‡Ùñ à&Á»"#¶Ø[cM0¿´¹¶Ü @.`À$ żzçp<9y Z}dVäuÝÀGŸ­ÏözZ›K‘Ùx,@Œ•h!ÚìÆ®ò6´)zOÈ…à 0ýÀÆ7!ÐV„Œ¿¬ýt׎¼ 5›9zÐtјBR!¥=ÜÃjZvÔÿ¨¤YŽr¾YÌ8(Ðö³™–jÔºAg8£)sŸfžð]5V™çqŒ–äÿ$UÙH-2,ظö/ÔfëÂp­õåžÄOþ®çDË⋈(ƒC sÌî+Á=¤5FX4ö;¬Žÿ-œíÆI/­ÍÚÇmÇõëæ#Œ€ '8ÔöoûaâkŠÜa2 ö“á)•¨€ß¦4!wˆÐZ;7z,ì"˜þGí„9=s˜ÎB¬*Ò í7µyeŽb2à×;Û¯6:in“gó ±÷p6¶´Á9J„XhÏ«´ÌËbÇütmËŠ}& SÛi?3kSw"ÐŽgã\É‚„;uçIûÏÿßZgsÿÏl·bi–ùŒïl™¡ÓÞ"¢U:ÚÜÁ{fßöõ7¶G–³˜íÞY™ÈÔR‘]iTéØÛÕÿÐþwDãôàQ8Èpô—;rׄjãR3\y¹ka×’èЧª³4–ìûÓë½_±ðò¯áægÓ(í¸Ú ÕêP~ Ãy± îéP›¡• ¾zò«"ü ™›ç}rî—ÃU©×épp"½qG«;T´)¾¾ ïÿ±î¯4~.øjRw‰HM¶I>ÞöÆ„^§ƒëŒ}~ól9“å⌋v~¾³8\.âÉ0‡½áœ«iSÓ~dÊǺâû‹‹pB\4«Ÿ:¸LïÃnüæöïþÔÏås/æ\æíŠê$‰Ý;Ó÷ñ2<ÝsÒêîÇ¿pƒ#¸JÁœg¿ûS ÎýøLSv*f‹ ©¯œ°Rô”íÄnB`Ö_â/Ζ¸èë󧳿NÈ>²ö4ãoˆbÎcßyº :tÈèà¸2#Ú½–¦ƒ«˜¦ƒi±OÕSMpÕ„P8¨ðþÀ¾ÄÝ®²ÏÎ>ši:XÀSíÃR Xª¦ˆî .WžÃ>¯àšK‹]}×»¬ÒP}óbWö_]:'lXê0âa°‚,ÍHÀÇY~¹?E´*’?âì!yø‹›Ý@$ LMâ‰kI¼2MÓMh-*@v_\.ƒ¡N ë“ó¿| 0`F5XªK}j,Mƒ©iûD¢’«ØéüÓ´OËú†S3ƒKÓÁTû0U-KÚ@ 9,ÍþÍb×±øµ±ÃÜ=a <öØcÕÙ³g[ .¬Y¸páª7ß|³Úår6ôvº€¾¸hN9#ú»Z[4‰¯8ÎT –¦'ݧa؄үÿjÂúöÊÜ2bp¤â+Ž+Õ€¥i0BòzåäÿÑþ2îÒ1u£Ú ³þ¢§£9Ñfï=ü‰¹-½o_#áÌ×%–f2ÃD\gOåµÜä`Ô‚#¬¬/g²x§„E)ÿÚk¯-‘e>Ÿ>Ÿ]›CE¼òÊ+xüñÇGÖÖÖ68öVø¬.–/.ÿþšó¦ŸxµáÓ@ô¾¨Â IDAT=´ÝË’^}×êÿcï¼Ã$+ª†ÿ«ª{;LÚœÙÀ², KF$›’E²b@̯((A|%)ŠÁHŠ€‚’I²„ , ì.›ãäžépCU}ÜÛi¦{Âî‚ÊûÕ<õtO÷íºuO:uòÙè¿'†}øV"—ö‚(œ© û9)E]ŠuÂ/m0ºB‰¬ï9ûQgHˆd½Ã„¯ë‚®«LO“è‚9¸`[›x¡¾ Ð…¾‡wô®íÉ,6aºd21Òx}êY[X^}ùâ‹_üâcëׯ¯aJ‹ÆøèG?ÊUW]å×g2HH|èù±¾ý½U²®Y ·6ÏÞgÌ™ýâ-¯¾òV"–)ø)0¦O†@[–hƒB€L] §ñ‚Ñ"..lCKЫU,uƒ"Ö=ŸÿÇÒ~|0A¤[›Ípš¡wQ™ïš4ú'6´nSøÁ…B ´W{ s› ¬[½þ‚}÷ž}ƒ.„eÊPqiáA×7–YI¥ê!W܉ûÈóþ—/<~˱ß?à÷:WŽ^)NËT# #&7^ ÷V1ñ‡^±aÁ¯YÈ©r…uàõÖ7ê‚_–¼CKæõD »E¬3æÍç´¬ÞqV¯Çcæ¾o|㉠Çm+ý­}&™‚©³|ùÍ!"©ÙøzÛ£øÛc* ÆQüÈj½ºˆõ¥U«VÕC$ *Ç;À;€¿ª ¬<­ ö@'%úåÅ/¶ÔxнÁQo¥ÃEnƒ 8©a*"Žð³An ªWÜ)F[üÞÚ…ëë"VØ›ÿiÅçm¯(¥ê«Õ9 òþ±Û’_…ða•Ò„[S ÙðLRÁCÀF›óÊA°•:¬˜Á±šˆ«ÝöZ¸p!‡ò..\PB¬SOû‡ñ~¾wõU¼öÚk•×Ï&¥UªKet¶ðI4¯-êêâ“ –Ž5¾ob‰¼w«JK¼©0†EI\ˆ‡ýƒL4uófØœWÒS[m# V±êJ;»b¡¿'ì*@ÖÃf=LÖÃfý¸{([_`Ÿã¦ÌÙfÈysuWù>Ä÷²9ÛëamÀ’®¾È‘‹¿ë¿ÏV¼f}ÈEê’:­ùç?ÿ^ø5.øÚ×X³f éTŠ“>x<)WpÅe—öMš;a(âßzù5áùUð21üÈzQYè\@¡ÃcüöMcß ¤:êK;>"<_m…*˜’õcxE°Ú<¿ú+B,²6†{_èRa;ýì#¶w©-2|Ð!-#œ;·–_8æ3ÛŸIÁÃT䃳R›–(e FÛ¥€±Ùˆb©Mµ_Rô^ׯÁßg×Ù ×Ýx ŸýÔXkùÜ9ŸàÎ?ÞÁ‹óqÝ5ßeÿw¾ƒgþ5¯x}hŠn‹œW¥{¶U ›¢ÿ¼ŒÇÄiéƒ6¯è}S]Ž<{ÚÃ6ï½’4ØÇ:P¯l»GwgÏ¥ ;Öæ¼¶Œ­ ßë¾k—?zÔǧ }”ñöë˜ Ð±)Ü)– ¶ÊÄc þ¯\WµÁö5~PøvQ‹nò^œK½'S¶Øk©póÈFg̵×^ËE²7Š>ÊGîXÆcϯdt³Ëú úR÷ÄPËäý×±Ìî[º8G,X ¢´à·¿ üá™p¼@ÜçK+"~¨d‘°¢ÓÞ¾>D9ÆvlÌ?9”oò~)Éšú<ì Ùfkï}s”ãŠê"××tw¼ãýc}þÁ¶»¶ïûðD××ZùºÖM,A„£Yÿz¢­¯MÅê/ÙAÖ…ÑúS?zöÎëzcçÌ1—à¾IÓ³i2fÅc¬Z½¶–cPÄòµ™vv¿K+°L$ ¡eO†Y‹üàÓÆ¸RʆXk0ÎÂx³ì/,‡#h ¬!‘’ò–ªð:mí²a^K¾u/ô´Ž6osJP»NÑàˆåk}²Æfµ–TÕ}­¤Ñ¢¿îÞÒÝçcþ …À„¶¦öçùyœ‹c©ÌxÆTxøÑÏ3ÓZ‹_çÁ¥Àyä“öÀª‚{4§{@ßÄ=çÎå„/îËú|ž6«‹ªÁ1„–ƒ÷?uŒ9óõ ¼Ð€¶¦ÊíZªØ11N$ú ‹š~p©4>‡^öLŽDƒÈmz­ðI¡mæ"Õµøu6î ˆõÄ-›rûž:Ößåö)v·† ŠöU~‚$và‰Õ]ŒÐœ „@‡u ¸ù€ž5þTdöBS¬¾ÞP¶tîÔ{p!ÄÞjB7AÎÅuŸ.ÿR òÝi&æX¶± <ãã£Pþ,zSßáê=©•ÁjŒíç Qù •þü¥Ïípé\™×+ÿ,yíÂ<Ëú×ý£ˆJ¹ØAÖ‰BÆë5èÀSs³ ɈX{NAk¼í¾ŠíÞ¦½Vc|EÇ3Ÿ$uð•4M‚Ã6¬èû»÷§ë>£‘rðýŽÄXƒ‘²¦÷Ö@ ±ªÂ/Êú§w“hRôl >`û(Cô°]xg烱êÅ­0*„[„XÆQK‚ÙÙM©šO‘ž èXš“‰fÕà÷è!'ÅŸóáñÒ1"Ð`eÿ±MhP)E×Jï§ôñÌ2R!dœ>£4-[›yà”“O$Cìì§èŒ5ýâàùÑm‚Ð0rD ]ÝQžw)ålcÌ ñ‘ÑY±”,e'®{Mþ©å&ÉÙ’£ÐZ6¼ÐCÕ$Gº+;—åO ÆWÕ'Ì(º‡ŒXBFÂAKÙ¿ E(%~Þ2é Q?Þ¹¯®¶ E9ê²ôºqQ§Ñé"ÊŒgúP:B¡ªæ¡¥$,ÍMaEõ#*¥~óJ!Éf³är}z6K.ÛK -?úþwÊ00†óÎ;ïrà ŽD-eÒHUVqéóYXç}%<ÊÏ*¿²÷vhV=ÞÅêvƒY/£?Ô¹, ðâ"Õày¨¾vÛ†õ³Î˜BXd¢6>6íÐHÓgŸaˆZªóHH´©Mü½îŒ½¸¯‘3þmÕQX‹Y­¤XBˆýÏ9çœÏ_wÝu¼û]‡à‡†žžÚ´Öèа÷Þ{W}~à 7°çž{Þ=þü‰JË…5æ5¦Š’Ö 6aVõ§X[@ˆúìÝ'óF¯#@%%*­pGº/e–e/È®·‹‰ªG ÉrÖG¶›FäÕQäâe¿_»[Å÷‡Wš{—ý~íÃÊš¬•ºJæ"¥TM;˜­èÝÐÍÈ=FŒïZнa°ñf||út ˜Pªßx^›‡jrè]–}¤ÎFG¡¥BαUˆeʹ¶å¥—^úÌ7¿­ÿÖ•—„† Ì—ÈW©?6œøÁ¸ëî{5z4rÈ!΢E‹nÖZO|íZ©‰B”F×TeùùH”íz#G˜ÕQ…TGD eT ©2VH PiEjRª&¢VŽïNHê<Í;5“ßP8-³4ûL|t禋“VêÇB!eCDL‚¶`ש§m·Çš;Ö.˜ññéI G¨–HÏá·ú%oF ϵX©‹e:‰JµÉòkÔV ¦7ß:E¢Îª1…•Vô¯s~7Òuž®«´SåûF¿Us‰{|pÀko¾ùf‰ H'rSÌž3—9swcÎ.»²ÓÎñû¹»1nÂd|mñµåüó#_F†H©¸îºë8묳v>LT¡¡ƒáÌÄqKÏSÙ‹ó z5B©Œ;2½ÐiL¼*SîJµd‡5²Ç„¢`˜Ph«ð»5 2ô®ÈW=cßñ­p½ßxwÁèýÆÞ1ãÌ™§ÇjšáûÍ çVè¬Dg%…Ö㉿Dœ„s½L%нÑwÝ‹³ô¾‘¿PÃB¬7­@:¢ÍBd¬«î‚;ÄäÃ÷0„ÔR2m¢ßªê±„ˆê÷¼ž¹¤žÄ"KµEÍùˆâ8B²×^{M:èàwáû>×^w=S§Mgû™31Ö†º_o9’wžK¨-¶zØad2Î>çÓ„aȦM›˜1cÆ¥À¾TÔ Šçµ‡ÔQÔu.Dçû7ümݾmO·îÖþLëìögÚf´?Û6¹ýÙ¶qíÿjÙþ¯¶æögÛšÚŸmkh¶-Ýþ¯¶tÓôÆ£6³¤Ýöƒåÿʸ.&¯¯žù‰™·nɱºâæå/K%@[¤„Æ©ÝÞ4À•’3¥#‘ :ÒþlÛ3ì`)ÄÑ*ñ6ÅE2:F„8 ¿ÃgÒá“öðì>kÖÙÒ•`l å±z–dp[\mµ­›]T\/‹s¨˜‹!àˆ#Ž¸ç¦›nâŽÛoEJÉn»ïë&(x~Ýîy>žï³ãŽ;jËÅ#â±®¿–±cÇñÐC±Ûn»ÉX1©’B !¦K'žKøÿ·At‘G+ª¯üXò­ì…ʾöÏkÿ¼îžµªy‡¦ï_ã·y¥1‹­òžHŽHf‚íðÉþ¸%È%¥¸Ë†&º‡+:¦~pê„X?ª}ÝñbGQÈZ Øa#Ö²_-›ç$%B[TŒJ ”Š»8)E¢ÅýÃ@Ç¡RâZÕ,JcHu%%Êô®ìÅøæ:(Y¼ŸRñ<*þWNô™ß0räHqÊ©§—]v9ãÇ! ü!u$‰ëHvÜqG.ùÆ7Éårtuu‘L&Oö¬„”еU %Ò•ä׿žÛB^Ý®¼eåE©1ÉÃÝF‡0TßKVÃE h—&Ì'Ï>kÖ÷‡XJœá68¥qÓãRøÓ,K÷ º|üNÿ2¢‚M[¾¥”¼Íj‹”²Lm¤,!Ǩ¹# z‚i}ˆb›û¹R GäâßI‰RI¦`pz–öüº¯îªúe1K÷—¥y))HçÒ¬]»–]çÎà°Cß‹ ô0z".,ùÝï|€Æ¦Fººº?~¼ŒÃñ³M—J -(%£Åå#•DP)EÐnÜ!pÙËÿî6»ŸR®„0^Q^“ž<„Œ‘«'8o§³w±¤kãß[¤ ›æµ"]ù(Qmh»TfÈæ}ZZZ8þøã¹ñ·wàû>®ãSV›å>«gä£9çâTÌ͵ø·É!»!÷<Û0õüŸ¼‚LŠ=Sc\¬5‘ŠË­†‡p‹ó²¤'$1Fÿu88 q²Û £q\‹Pж¨àO}¶±^úá+HG<­ :®˜ÝH¨X'¥,#f6a­½¢ò>R1]Tt#†Šd*‹A¥í/w^Îñ{%ÄŠõ¡Å{ „²±¾ÔòèwâÁoÎ?.'÷Ÿ5…“OÿJJ’PåR˜þ]”°¥ëÂ2iþ,Y²„E‹±hÑ"V­ZŪU«ùô»·CIÑÑ8)-…÷-mEùµ.ëžØ„Ûè,'Jc½M]’_úá+ ÜFùˆŸñAÅëáØ¬¥*¯QÃø$ÙõYvÿüìß uü~°øQÙ ÈmʱöYõàZ&¥h¹ëª¾6Ç­ª¥³ïÅ»Œ0ÚtI§º’}É1M6?ßAëü®–ÜÆBϾ—ì|’I˜;…/Kõ ±"®% ëo'ôÃ`ÓsÓ¤Ð8À;¾¾sÉs­2;ð™TŸÜe*ìú±Èh·â~ÿǧùè¯_æñïf‡™Ó‘bˆÿÒLšÜÈ/YËg/ûÆŽ¢û×’t™ŒeŸGÞ0‰cBÙ¸tý«{Äð°‚×n_…×áŸäuáM ýÚç¢9¶°& ==Q®ÿ åD¥1Ìmhé]—'».—^ûhëpŒÑ)`\¬b bÛ£·M(À¼o¿Ò-S`2™—Nõ±&‹×°ýñ¿ƒÜd&çcKDyGIÒ…Ìê^‚løãtWÕ–“¸Wø¤ÓümÜx>1gRTÚπߓàÔCÆr%ï~ÿyðáGq”Àuïrãµgð@ÚŸø™'¾Oá©«IÎ:TH˸€w%”TóJó(C1<”ëo#5&a¼®àyÞÄxBé2-5EA`K«D½â£Q9 ’‚ 0v+‡y‹Qé¼± ‘·Ån3,îù¤t™—¨âw,ãöhAúl@ Ç6»Éš×Ý!‰ŠŽÅ™ß •©-Þ£8Þi©4—Ìlfì„b‡£#¤òzJÈ•˜´3ÿJdøÔçÎ'ÓÝuÎÀ]™„sŒHZšL/˜NHô9kæ QåRáZ¨˜Wñÿžõ½ä[½‹©SÍa[µy—¿ºF5Š{ýÞ Äʸ Í‹xnãÞÙBvc~Âî_š¹ç¿Åm¦.b%ÍÜ1öû2’¦ßéÚ<Ëeý½âߘyc 8=‰~× `ùý›IŽwV3¿ë3™2UGðá" *ŒÌ”~¦£W°§i ïÜe c›\ÚzÞwì‡X2ïÁò" ?ä¢êõ¶h]ÉCÏ b9š½÷14. ±"ÄIÆ9P‹Ç=°âŽvÒ\»éÙî? ¤ôÝV-‘äx9UÚÂò†T‰M5²Ù'G(T¼ÛwëÂþ€ïÏÞ¯o˜R…—Ëü'ÏÝÛf뙯½ŽÓ`ט.)w]Ñ aÆ`…þ–™ÞƒLÙèšd|]Ò ’†€®¥Ù‹€ž¡#µE&-*ù:>´ä !ùWAw@ÐS® øÜ){ðÚUpòñïÇuä Ga2èÞxj™¨‹.P]1Å HŽÏòÈ ÓÉoÊƒŠž[¥ 2e±ž!ß›§geþ3ÃÙ8[Óž¼à5TƒÝ1µc”ô_¤4ªó”)ÁL¦ #ç&ȬɊ}¯˜qA½ñþÉŽ¡œà=˸³¶¢›â{×¶éQ/ð¡Ît/Z蔎'iJ‹>qÿ&¼.Ÿtk²ø€é¹TÊÐõbžÔ8EnƒÿÌpxââ©Tt¯•Ž͹¨‡ó@/g3¨Öˆm ;!Ì3zò(6]{,W_öU$bÀ?ÓÓFz”#•Ì€ì†Üsò!”kÔ^›°+ „^Pz6™4,þåZÒ•¹þ}¼I›µÚS_Z¶ÌaŸòÚü‘☲1Ò›’ß§ ®ªç•"SZ©@âx.®çâTt×sÉnÈåL€Û±žøôò¥N‹At¨xÂ!*mP)L‡4ï 9/ƒÑñ%RÑw*eiÍÚ¶#]î.T1­QiÍ14BK>¢Z-9p–~ÜMØuw34Áø±,üË/ðµ©ÛÿÇ{¹íŠÏ#FO(#•È@¸^‰¿"`!+™ÌæöFñ¼B–ü¸•†©ËœÊÔ½ÞÚæ&9¸qŽ!xM¢Ò•K§‰“4ñ&פ&ZzV8ðšíþ^íP1¬AÓýR¡Ô»^*о°‡¢½t›!€j0?· ™Q騲!D¤£ÉŒ?ñûÕ"Šß[ƒ3Ú²ñ‰ÞoEwUµ‹âL…ÈTÈ„ÉÙ˜båcËCs8¯€³’›Ê½%ÇòY&îÊg…üó9–._Å}>Æñú4 wåÌÏ]ÀÑûŒ€´Š¨”ì±ä†•"ÒúüxNþ²Ç~¿‘‘;»¤'jÐ,ÿe/4û´/È ¼Ì¿¡Ñ£ŸXÓdqçö"M„D¥µ‰»Œ‘mêRäÚ ï™{î¨æþ°._k<Ͳû6¿?±}è¦fi79K»ÛÕèVng[=€H_tgyŸ—6®‰õIåäMbd©‹(†a Xq}žÆídÐ6Ï.®&Z6„`\P‘NfÙIÞÑT@¡*w-!ô ì‰?“P4È)àî{âî{ª­°åƒ]jØN0k!©Á1ä76pþO³üiåÒS¦¼¿–$Ç^½2‡G–ÜFýÅ Ç<<ÜM³-Û#§®}ò°{Ç¿]Ì>M{”i‰µ ‹…xŠ‚JÆ2j/µ]É ª†£"w)9 fý"ù œ™G:Ñ!H¬p©ÆÃòØbº#@–3ÏL9©‰ ´<äÖ–ýÿùáÌ3¥MÜ UºTsb’ #„ô–:dÚ7Û… Û±"ó¡8ÁÌè|Ô)4Å$jÖ²*&ûê]"I“¬Ä»cK ²BKTA‚Šk|¤…½ào+3ÜÝÚAð/Mð°fd#×¼:cßµwT|Eæ…)wÍ«Lœå’l‘HW PÑœÓX¬¯<²Š_ïÒ„“ "Är4Ý ÇsøwVБ4Œß·‘–YIœIçs‚e÷®§iŽÒëô¶š§©H ðïl¼¯£þ1zßäÞ­ódç(dZWˆ¦•‘¥©±á城¿°JKðB+òkÿºl52ÁJ(˜|¸k+ñIlë8æÖiÖ´¦Pcý~ŠŽ¾!¿ó®è aûÆŠûzö!ªh0¼{Ý1ÝH„´å䯢=‹.tÞæ AF“Û].ü‚!j’Í’¦I.‰fYé"â(™8ÉÆ¨¬Ã•;Ï 9©øÝK›øÕÂõ¤'8ŒÝ5MóŒ$…Vxù÷­4L’8 òþuOä¾ ,åM®Ü±%íèÛ¦½žY w¹;‰[ûh?¬|4Ãø½Ò?úùuW{Çô(‹•6À‚ßm¼açSÆœ«ÒÀœ´äáÏ­.¼iˆuôõ;Þë­VÇ&'Û¾sí—Cæ¹k×Ûœœk þ¼%&Ž£¯ßÑÊ~ãcm¬µ˜Ðb‹ö aVãõ„èBx¯R×­Ìjc¥f4 r ¹Ž€|GT£'5Æ¥i\’uÏöе6KzŒƒÛ¬¬ùgæ‹X^&Š4ü¶c5K„yLa…CÃÌúkäuiò=Ow裯›}¥º`énZØ=]d"B¡àÉqdÖz©§¯^ãmó£Àö¸§©F›5]NÙøY¶—ÎÅ /ô’nNÒöJî…-µ›Ùn[‘ý¯L´laâ4Eù?­µQ}?"ä+¦A*ecñÇó!!‘´xí6½’Á’'ѬHrMÓøÔ¯×=ß}°2æ¥4ÿÁí¾³–Ù÷wçÓEÚÜ®»œR WÑÅ\á°~q/ï½hÇ?ü㪥'ÙŒgñ‹–u¤·ú‘(­’°aa+ŸhC”£uÛ#Öý_}%wÄÅ»ù›_Ï&ÚÞè!ôt•Rl^ΧqLâ®­±›éŒÃ¦—3toÌâçtÍò£ÖÆœ^\kÏZ' +R(Jˆf´Á„­#b#$(W¢'!I4:ŒœÚ¸$ßåß´á宀12ù¼Åµq¶¦=xÁ’;¿x×kÛæG·.ͺܔ+I6ºd×êe2uÓµ>Gï¿wd¼=òMC,›—Í-ãîÔ¾i,d‚¤-ÇÀGF; Í"ÕóúãëÏÛM´Í‰ç€¡ IDAT½GMiú¾5$¼ÞÀ)bK1×XœJÊö¡g66–¡cm­ÕXkÉÍYK&(è A>\ݶ²çõ vÄŒx.¶õ™ÿ&d껂Û<.ýí™QùŒŸŽaWн–JŽJŒÎ¬ó~“»šÒüm£iôzC·ß£[–z=Þ4«/"S?½¢Ý†‹£¶á³ÔFÄ·ohŠiŠtX÷Å[±I# ½1sá7š›/«oâ·ýëéPSÀXÛ›ÉtíqÎè¼ÁÿoÃn_w¬œ½ÃœýS©Ô¤TïRî$¥lÚ> ºù¿¹c< Õ³ XlŒ~9ü6µnzY9î9S&Nùšrœæž©ª\ç›ô`LSÅûþEBPzÕÍüK;ð(µÄ…¾ßYk}°›´Ök€EÖ˜—ßv底‹¿µûŸÂçÚßÜ{ñÿ¸®{Í@Ìçó·=òê[ÅxKî’6W¹cL¬Í[¸ì~`"aJÚîy_4ëšãîn›Ÿ [Ý~°úœ†Ñ#F}4áº*©fa鱫™•X&ΠmÈÛlë ~¿Ï¬ €uíC½í[t5‹fT9;+ö‹„@`­@[Q¥‹õ{-a΢E¦¸i1LS1W;´yS[«: <úŽ'¶9á,ÃKÔ˜k¤¤ˆ`,+ÊÊ,c#øšXïZ$ºÖÚL¨Ã?ûíkW>÷=ï~K4`·d¿~pz$ÅTûÊä; $Áˆpý§Ç~oÇXÄò¼œl¾ð‘tJÜoâWb¨S½¬V@Û‚·YŒ˜µ×¬»ˆRqùÿŸhU·­ýüÄ–¦æëÇù „0á¡­@k‹$ªU£‘(Ê,UÿÍYBÙ~«UrRâªJÌ °ÊC>ØÒ±"GhdƒÆI[l(ò ¯–°ÇtCz¬ i†B9Õª?áÏgbdj¬ZÄËl!Q²T×þ5îV¹*¢¸y„­æ¬âp—Z( b‰ËÖ- …ÆÓb„ü¨tµýNüºûB«µ~(_(|õ5+]³ß}o ޲º¥o=©Þ šžÕ5.t‰ò¯gö)p}û×®RŽs¡m)M C>MÊà –Ög·—döÊ‹wýùå 1áÛ¹}mÁirÚ¤íÎO¸‰+$éø˜05jˆüÄÐ>§¢\O-®AÔ7j¥m¶Ã߭çr¢,ò a0" ð-:ç` f-~{Ï7rgÕ 円ÊaÁ›{š–æ`눹5Þ×#¢C!²­¡+t¨D9È´Éæ²g\´ý/¶©÷éµm_9,ƒìCX»^ éYªq&†­WsíADÉY†â¼´dáEsgïv°òàBÎâT$®:ƒ1Éí¡{E@ã鯟{ÿþø¨[ç?Ôûf·ÿ}ýSMcFŒº]JyŒ<™E ~ë'«OÅZÛÇcSlö·öF·ƒO qËÔÿm™‹(;W”™  ¨4ØFíãŽr$ÓàµÜ&IÓöegÿ j«8Éþ<¦­óDÕ§ ÅV6ý^‹ÕU*ÝûóìÉL7á›®ë^K!‘Aù)èMÅðë¿H¥ª¢Õ>Š5´ý5Mõ6}¸¡òCÛD™lû §e%y΢‘ý”ëÑ;IÛ¾öÐL)2ë<‚.CÓ,™Ü6ªð".eè·¶Ÿ*¼yŒØÕ╆º)¶EY‰~ë#b”%³ÞCñÎQãÆtmÁ§N½z_ÿiË –î£'-ÏÝ÷C‚ Àø[®­j½þù¯:J]m<E¸bPy¿Ö¹vºçHÏtȆÙ/^wäo¯ç-*ÕþïhŸzêg¸ñó¤T{†‰p¼$C³Û Σô;c-Už<%_·¾:yÛg¡EÕcˆ•²›ÎÖ¯ËAT’;€Ž©Á&‹JJl` Z 6´XßbÃÈ-ØJ^<%7aú¸æTÀ²èZôæ²6>UâüE—cŠcCÿûQ*1€L1!¢T@®ˆ¢S\ j’¸-gŒÄ©j¸° Ï}ôh¼5!‰‰Ú úã}}.vøêœ _ûÜmÀéôq±@v‘GöuwŠènË´_0qŸ±­©–dPy‘µÖdsÙÇoØïÖÞA Ày¯|þ)Ät¯E5Ê(SŸ­/»×õµXêl HÎpƒ‹Vísï—XüvÔgõôGœ–-ÏJ)÷)¤²$üÒÔ±òÙéJT » ¹% +lÞ€%R`Æõvñë@nzÃQfÕà)Æ”6wùyJÙXÐñ+ š‰IÉ.î(‡>f®þ@° @uJ¿#Àt[T³Ä†6ôÚýa¯¶6°‹‰åMÙYÑZkMuGc­±Æj k5`¬Å€­ümåk±Fcìe­µÅ-W‚ÖD)iÈb«–2N +„ÂJ$¥’ Ò‘ÍŽ«F)Ç(WeC0¾Åz7 ‰í\ÒsȤ¬y°mIÓž%·°@b’ƒI›ßþâ°ß|ÒfXòÛ¹‹>Ó`[îµÙÕ’Û+Û9È&YÆÝx±Uà Œ õ÷¾÷¯¿ZS$¬lí=§756-E±iPÍj@(X !¢Š´Umšƒ¿Þ#Xí»fOù£›v÷òAþí&ºÉ¦;ý€} ÉN¯‹ B˜j+‘¨£p®lÆ’{)GnQ>ªT’0R`÷Ö¨©ŠD£‹k]¤–(£°¾Å[á!›ë:/¼óì?Ý\±¶Eë˃ɊW*H¤±]KrÂ.FŒ›9vÌè£whß¼lTÒîè¯ð„~9éÑX©’$f$[™0¤D6mÉ/óÒ‘ÜÆöLÇAùô½oôç9‡m‹ØÚk·ö¢æjÏ3v=çè9Ǧ[Òg…†½»—;CT£"½K ܲ%¢XH·*Iè„Q¹S‚îyYSûÈÝgd~{ìï¾<é¨à™ØêÛW)bF‚æ‰Ò™g²ý™ÓÞ× ÈI`ýÉD‰‹òÕ¼jö‰'>µK"™˜o\[0¨f§ƒÔ§ß†Ì?3$&»èsÝïOýí¹üÆo1wõÔ9—I¥þW»!V‚[p«ô|Õuèk£ˆÉ2uv‡È‰˜"àI‹Û‚ T]³%óhj´CgWç7ïÿß¿þ˜(~è?‹-"‚äN˜Ó´×‡÷9#Ù¼Ïn§3ÝâNLÜ>Y”9ûPsчlVšû²ûÑ?þz“Õ8ã]|íä–cwëÛXw*Oºý”YM£›o%`Ýbz éÙi„+éëZÛWjkiã·a{Hþ•,‰iIr~>qç 1RöSOž}›…ÓMÖn °Úbu…¨=ˆ6Ó[Y@¤%¾ãýù/ýù ½xï¹Ç3ÿqæ™RÊ›l!òƒI9 `yÁæü«y’Ó“ôäzNúógþügþÃćÒ>úÈGsç/FZLJãd*½°E¬µÞ¿3¡ÄèÒûl/…eT£‚™Ø/Ac¡q@ ?¶¡¥óÞNœ1.]=W>òýGÈpL±5Nl”ÇüìØÃi÷&òL;CLÞÞ)p×ïU‹¢–Üf4ÞJw’‹qõe·Ÿxûå¼Í]kŽ¿õøÆæ1-÷‰€÷è. Ýá…4‰òY!€ìÂÆ38“ }ÿ±¹›m’µÿC~h´”êFa9ÜŒ;´»Ba fðUˆxISÈ{ϼpÇón^²ùU¢ú9fP‚ð±Ïø…€³MÎ"STmkÉ`^8ùWòèœÆâv¿úÈ«»Ìÿí ÿÍ'ß©>iJ*•Z¤l“AôÈaÙu¬¶tÝŸAç5Îh‡Ä{ NcÙj8ˆÚZÄ«ã¾.œ1ݽ]W>vÍÿ«²të £’MÉ»xOØ­1YCjûd Ï꫈m•=1âÊœ—ÉkrK $&»˜„þιû’·Ã!98^ž| #Õ?LÁ$lÞâŒqEÇz:C“5ô<ÕCbj‚\ûƒ=üË-Ž$Q؆dèYC‹¼XHŸ@öA ÖÿpœÓ˜J?o {˜œA5©¡%j|žy¶Õ¢£xäOŸþË1ü—º:sãûäÈ1c ÁÑ&'@³}œ@ t>Ø.XÜqŠïiB„¢*XÊU`¨Þ–åBûý]8£™ÞÌ•ÿ¼îéÿ:‚Ul'Þ~Üè„ë>f}»[Ø©QI…­åßj&oȾœ/­Kï9ç¯Wþ_ Z'ýñø}©ž·~Ä.‰”,W¶Šëªeÿ°ú¯Ì“½à‚aøÛ×>íß­r’AáÔÛŽ›ä¸Î2ÚëYd£¬‹E•i᪠ºÅä,™s$§¸h'¸øÞ¯<ü=þ ]N¿ãø_ )?)c,6œ¯ªÌ¶ÚùÏ‚vMb¬"9%Az‡DM@*ÅHªÝ:lmtãŽRôäz®|ê—Ïm ÁÀ.BˆÓZZZÞ7qâÄ9£G麮Ìd2býúõ¶­­Íc6ó€»ûˆê(ô; ·´|ë1'(ä]º`„œ’zË¿R˽&è É-õHNq ¬æßÎ{ô÷ÿˆÖ)·û àlZ„#«=ûyòÖ—zðÛ܉jíc?yjÿB—·éß¹g‡l=å·G)¥¸ßøjŠ”†>«Ü¼u…õ>É)®îní>èñï=7￉#8å7G~BHycÑGMçM?Y­VúâS«g~žÜ w´"5%Ab¼ƒÓ¢`ÕkpV%±ÚÌàŽRôæ{¯|öæ‡M°„Gí¼óοûÄ'>1fÆŒƒóêÖ²aÃ~úÓŸ²lÙ2b.ùjàf¢zr¹­Eè~uØ娅6`rØ£qF9UÅÁð­/Ñ*¬öñÛB’“ s}×ÞO]óâ+owÖo<ìP)åß­!J²nk¸$•8ªúÙ; «²¯HLròónŸ¿O÷Úžåà O¸ñ°Ó¥ß1¥ÆjõXËïþä×mS‚pò¯¿Ë7tÁFþ@JÔÆ A[™—£Üù‰ñjå¿~³`Ö×:{þDîÏNJ9¯!¤lèÞ¡N9º.¿. s^w¤Â“…G&ì9êP§Q"QW9:PÀ«Õ–ÍïÁ©È²W>wËÂá¬{ï½÷üÓN;m†RjH„ªo{ã7¸þúë‹ßuO´f·†“9ög»®›xÁ†v·0kp›UKb=n¡âਈ"è^GºàŽ‘/=òÝìgß~î5•í¸Ÿ²¯rœç JÊl´6!°@~m@Ï’ɉÊñîÅûe6ô¾Ê0²n÷óCæJ©^R ZJÉ}#ÀkÛ,Òc?uß—ž¸i°5VÊÑžîÌ7R©Cƒ‹Jɪ'$Ôµô¾a¦¤c^+œ{ŸºÓO¼âÙsøwu8ê{û%ÌC:ô¥“–øífȤJA¡õ™^œI¦»÷/4êû…j>T¡Eä9ÍÀô¿ß?ÆÂ7è`XLMÓž{î¹è ƒšºvíÚ!§ZM)ÅÌ™3Y¾|9ÀHàà{À#À+DÅE¶ˆÛºï OGÿè€w:J½.¦z]!Nƒ€Ÿx¦ :^Ì“Î^~f·O?öƒÆÛ8“ˆ õZ›ÈéÛDª‹zâs¥Ðwéƒ^?*^—×~è‡Ã&ðÚ °2:·DA”œŠ‹*®ÅÜI!_¤©ð¹Új‚õàyÿ²Ç\ýÎ8ÊYi­t[TZª¿©õeãö’î×ó4Lv?þžs÷üûc?žÛªnáˆ+÷ÄâVãÓdBdªÃ<Ü+´¶lz"‹ßš%óÿ¶äªwŸ»û‚¬`Ù«s1U …T‡²ØH$ ýéiÌðÖ%ŽãL]µjÕ+€0 Y·n]åG)àŒøðÑÀâ­Ð©ñ·/?S8ú»û&…x‹d@¥ÊJ½J½à j ªÅßT 5A]8bJão»×e;ߎ¢ááWîÙ`¼àBˆª|úš)jÛˆúøùY(´CÈ‹ÍùŽÂ°¹RS@F)f„¬†¶Ñ–ìº<‰¬¤à)W^Ú6 à¯_{.{ìû!à"BÏ"åÐQ(EÇɲFÆq‰fCn}ž† êúÝ›þÔÂ{W­úOD ×ȯ˜¼’PëƒúºØ!»åìñ›_(àç4‰"»èïËÏò<Ý(šÈûX,FˆÒSS‹ô1–>¯,a´EûÚ—Ã!XpüË/¿ŒçyU¹Ïj©Tšd2AOOZk‚ `ùòåA?&e°+Q¡ÂÖøÄô¶TüúÛó^?úÒ½.ûã[D RÔ B©•V¦ÜÆZ6¯ñ®3~—÷ûÄ37¿öÞFNÌG\¸‹T}Ð~“J twÅáÚ7ük ÌA1~õ¬Éã$…îð%kÉwš¼,k‘BT¹íXm >² 0~(†¢¢Ú¢*÷}ã…—Ž»x×/ ÃÏLÆHÙcõÕc™>|zÓhÝì“ß ÇNJßâ$ä¡¡o ÿIº…c¾6w‘÷ Qí̾a5¶Â—=âÊÂ]×*ŸÞõÉÒ®]Ò~±— ^º@†%r© •Ùú;Û ¤ÃBèûȂĄC–nÒÀv…BÇu¹üòoÑØØHk[+W^~)«W¯®ºøÓŸù,GutÕg¹\ŽóÏûr-b‘¯ÍöÀvD%7±•î+^¦ç‡ 7ñ9iì¦ÒýüÕ*ȾijŠ¥ÜDH¡5 5Z~ Á¯°% ç?±úÊìI24Ï[íMv’ÓQ#G„­•{­Â´{e@ p’R¯¥ý¶-ÑKŠœ_’5m|ÚƒÖ¬±„~€*è!ãïGsÝûí—NÞ»Uø:SÀd=lÎÃÆ¯&ëaóåÿmÞƒ\Üó>ä¢ÏGO±äZ øþ2íbÞ¤R>[ÒŽüÜÌü¿Ú¬‡ @¡·ƒ?Þq—\|ÙîV¦ŒÁïnú%Ưw–X§52·*jð‘.ƒ¬w¹2NÑg LŒ[ÅW*ÖÆVüŸjÒº{å·ñüÖÖV¾õí«¸ý770{Ç™lÚ\³þ_"&T©Ƕ>ÍVÎû“€k1¶ÁX Ì$Ôd/]ð³^w(FŽr–°mÆßnêc…âqñ‚ipS‚Ð/[;Ó™µeî½*ưÊAŒ±¬|ÞŠƒ‡vÁÒ—Ú¯!*ô N9?¶Ø 8VÌÊ€ö}´'±:|ó Öý¿Z­üø”Ã,¼f´Mx8 Q,.ÙfõrN'A¹šL[(GÉ[§ìذ뺥¹Î'YÃU¡ ß-h'é“ e («û¾!Ù(Ú–Îï¸XEä£d!R–Ç•MR !æË–¡%f d 1Ã#Xë~ôñ©«V,çƒG¿—{{=מ5‡í–þŒk¾ð^8ÿ$zaÓ|ìü yàÌ·<¹™_>ÑÅg>þF7'x~þ"žzæ¹î£bü’Ûb=¸qmïa™ø؃¢MVCT®XŒ«©|/$ÙHnŽíÍnï>},BÈ1B°§@%'Óµ¶cqÑÆþ€v®Aq+ÂKXþ¢‡à$yuق̹ÀTÄó ‹©)fµ6ªy]Y)Ô@„„¾ÀXóæ,€~³nå{>2ñÃÖr§Ñß‹”¢B 1Q]ÿÕ<ñø‚Ö€@ÉHÉ>ðbW?gÛê€îö€T³Ô×ä/ÐÚ¾FŸºÐå¼×QtåzU©Dm), ~¨¡©*û4ó´7§KÿxŸ=b_ùÙA0j×ÃVAvUt³ÑˆÑûÑbB>»Ý|öÔ&àÏÜÉØe–9Ò¼²!;ð؆ÍÓúek9¨”LpÐ XÛAD$ ùƒÓ¨Ž~çÆ<é$E(e¿ i£ˆÆb \­®ˆÜ2¥-ÿ_ì•×QÒð)«(Å„ˆšd&^dm£“)*-Nô]èÙÈ·*k‹¼"Lô9Üú°Ÿ¢N ·]³n‰‡“”(eŸ_±8û"÷”.¶Ð‚ŸMY—h©â䬱øAˆ åón}Ñc¿ßø§?<þGFØ/k? ë,À˜Ü2UҺܧY©Sv;bÔC‹ê¼™·8 `ÿÓÇmç};€“ø;$Q£ø¸ÙNÍÆ7 $%½=ÁO»[½'ˆÒcT=‡gŠu-²H°ª mÙd_Q™ ª”‚µaˆÅprK©Q ÎÌ…?Ùq“BœT¤ºÀT#ål±Ìi<Ðy&ä;’8 !»¾+à5‹}¾¶ÓŸ=l¬ØŒC²þ ¥ùƬ¯²2mé@ CÁ IYÒªIÍNÞuu+>ì›ÅÕ!¨¸4D¬¬­ðp³ÃFÝ”3žV3Û`'”áW®®dBËÚ…¼œ!Ù ­ç…×u¾áÿXAze¶|ÍtéÆÂö #ü•Z"äÐ*ao3·¯íW¬µi÷÷ò')CÍŸ86‰QÐÕîÓ4Öùéô}›žX5¯wÙ[¥ÏÚû”1Ê3æi•øy3p…ˆÊÑFAW-È¢‚И¿·®,Ü l¬e%óµ)Ûm V?} æÔZü0€P!‡¾’{væÂ>ôüé[S·}7…¶4ƃÔÄõH·Â– ¼Öt HÏ¢RšÆ‰wh[º7?þ—± jÝc01Vº7R.ù¾Uœ—§ÍæR(‰Ãaz«Ö,´ß ñ|AÞÓµùøÁ“³×§šµ<îk¤ªÏ¿ÆØCœè_,¤¯û‚qÊ£¢¸6¾’'שqS'-µ­ö.6¡]‡¶ZTö]#ë¬eŠ. =š\»ÆëÕ *J2ú•˜‹³o ÁzþŽVv;yô1–[ÅÈ  q’rè)[ãi¦'¸d»Cz»ÂTz”sk¢I½ËïÕoIE¿°–¹ÊF"ׄ±åëd1Òâ¦äš¶e…ˉBTrµ~]Lbé°Šï ׫R7Æc3±µC‚²~ ˆ'—uqá}Gò­=Î%‘û3M“~ƒœX!%€Ô„nŒçлxBu*E¡±“ógts׃ÿ¤§§fêí#€51 ºâ °UžåZÈ|)¿Ø@X5H~z™Vh ®ÇšŠ:ÿ‹!Þ«ÖoD™#-÷(0¤d.¹öÍKr1ɵ8³.¸<ôÌ‹ñ›ÛVL»º2D..Ez“šbƒŒŠ‰TŽ( Dá-#X‹îìè˜{ê¸ã­´Y¬ BJˆJ Ô>RFîØÀæEYdÊî3倿KW<ÜõuÞä0й§;ËÀ'‘`ÕM“bˆbi{5‡Ÿ3$G8~ÏFÿkX:;mbǵÈz"±Ò0z}oX1n6ê÷ÀÅŽ=æ(š&쀘xç‘ßô*zåC–+vBM}7ÎÄ]û‰¸ª]TÝ.e¡áòo\È—¿vI=Ü:'æ² 0hc+5”AIL–5âHê²DÕP4BÆÄ^”ÖaèÔÀƒjØ! •¿ë+øo‹sÚȵ´/Í¡=‹JœåkÏÜÞ½Öÿ –e±Ú"Ï›+Í„ñžèÙÒ¶¹ÏÓâ?´þs·&^„´ßÕ~tòKÕ¿ÌÓ€Ë+¡yF½ë 4¤ÔùSß;êá5ÿè|”7)tgçMÜMÃõNJ HU7y\ßֻѣgC@¢Ù!È›ïyý,ƒÄÑ…Åñ­ÅÊÚŽÔ‘ÊjÈÕÁ ˜¸6ï(YŸ9ˆÝwÛ•B>_¾ªyv·OUs5€ŸÏõçF}Ÿ@[Ž>êòîùË_kîÀNß~üâ IDAT8á´yóæ¸nݺK€k·tch©E¨!k† ZÍZD"¡ƒÄ(E½˜èWò~ úƒ‘ªzu\€êÕkhüÊÏLhÉmòéYSÀï ‘J 'íô Í]ÙõÞ&´Ëc®7Ë–¸+ü›Ú›â¤i„¼ÚJ°I{Bà[”#K&ÍA¡x…c*£Éw‘çþnÄìÆ]»_϶okÀÎ:cJBc”J+ü‚ÁÆÄdCSé}˜Ó´½’ÅiPX)îíYãÝNä³âÂ-”*óZ)Þ¾u4Á&ŽLTz¥æO¥”Ÿ:ñÄoxá…ÔŠ+H¥R\òõ (ø!¶«Çudl ù&6\ú¿_gÁ¢Å¬X±²ß÷Üs'žxâT¥ÔÍwÞy笵ׯÆ}XÅHÙÄ`Â::¦J}Nà‘O’h©†Êø×?¼C«7±qˆ%ƒ¬±Y×îSèðºl•æ“®@ý¿öΧëÖ­êºç>çœß}ö'"‘1™¶…µ²ÐëÜéæœöp]¦CÑë úžÍïlK‘ Õno ýç{¦Ü‹Þ;[˜@ï)«ðÇ©­?ß“?¤€Õþ‹.\Ôv–l6Òé”ti/^@K:~µÕ,¨eè™4¥=½faÍ-é­¹÷`®«ƒ‘òfȨÄõÀÈ*ÏêIZÓPîCßÓȈBÆ­m™-Ù¯Wp清Ñ;–R`Ä Uü@'‚"à&VÓñÇÿØ…^¸àÆo¤··7øu!øò—>Oss+®§q½ãÃÛ¤%ÑR )ë­öVütìxxÝ0¾k°ìb~wþj£Ívö1…¬Q*›Q‘°²Öó "•"a ÃªÜ<Ñhô=ïyÏ{~ÚÐÐ ¿ò•¯àûck䃗_Æi§½×+!nÛŠdM-‰d’X4†eÛ£¦µÆs]ŠÅ"¹l–l.‹ïMÆ—ºúFVÜò}.~ÿp‡X,Æ;ßõÜuçÿÍfyðÁæ’K.©_³fÍw}ôÑ;€Às¡nËÝŸ=æá!^€Ñoe­TÒ—²>B <r½ÚÑ8Ã~Áª»TrUf‚³Ò$'òÊ Õª#¶$>;N|vQûÀN=÷'4ŽÉv0Ú b a c웋ÀA“¨¤rA =<üÔ‚Œ%TLž.,y=AÎ4`îûçžíc®B £¿èÑRr;³Xµ62"u×o»b@Aê›™wÉü 槺¤RŒevØŠùçs8)‡ØŒ¸ãfÜWõ¯îk?Påà¼Ì?x!Pq…Ÿ÷öÇÛ•#½!…]Á/xŸÏ?Ÿÿ Aè³×?êQËìÿú2ž¡÷Á^"õ6Â’_~zè[­­­7]xá…nÙ²…õëŸeÑ¢E¬ZõgÎ?ÿ|þõ_?…”’3¦ÓÚÒ‚/ÎÝ÷}zzzçv±mëV.¿ür±–‰¶DsŸMèS|QÜŒˆ‚i„7cødÇw¼d¹¾æ^2O ÄcÌký¢ÆŠ¯cê :ävçˆMçuÿ±kåüKç'ŒaШÖ„ý©õ)JC%" ¶›ëÈï ;éCXó/‚›Ñ\áƒâ¨jP]íY.hžZ7ŒŒJ¢-ÑgzÿÒ{š›ró/ö)2ÿòùõ:•´ðsþʃêÀåf<úV÷b%-¤-ïÈlÎ|ع/¢àè.›&°ªlñšX•ö“mG!÷ãkzèÅ®·R\ŸèKœýö·¿ý5O<ñ©Tš#Ž8‚?ÿù~Þpúé|á‹×qÔ‘mÔÕÕíéê¶’a îPäèèØÁú Ž`÷œ9m¼õ¼óXñƒï°xñbŽ;î8Òé4÷ß§Öúz` 0%‡ºà²õÓØ*¢ð¿ ½Ì^ÖU0Z]Ôô¬ê!ÒAHq}j}êF`ˆC—‹M">+n·¼®åiɯùŽŒ—ópÓñ1¢­ÑP€‰Šü “•ªåR÷NÚcPq…°ä__Ôñ㎗$Zdþeó§;ŒgÚѨ„5nœ#[GðK>ñéñ\Gö˜¦›ÿSþNÄÆÕ£œ­@Û#µ~8`JþWs¹–™C©>üÌ0-'´Ü#”ø;iÉ™ºècE¬€ÛSw!R†¯Bk‰’Û™EEÔÌú£ë¢éÍ™^ —µðC …DÜ/…X j$”LðûÖñ¡ïá>”%±jì-éMéOÄZ퀶.o™+…¸Xˆ€Ãªvÿ¢Ê±ʯrYTLa Ú§œuÆY³6mÚDçž=¼þ´Ó¸û®;xõ«—ñµëo`î‘G‹Æð}ÿ uíkb±(ÑH„l6‹Y¶l+ï½c ™L†††FN<ñ$6lxŽÁÁAjjjˆF£Ô×××uww/%ðÿÉ…z—IâaËòæ‹¥o—*Ô·™*ëe*¥ z±»@i°D¤.B©¿ôMwÄÝΡ%4Þˆçg6eÚÓÒ7»‹×µ,oÞk¾U"Åž"hˆ$íª÷Tí^D•µbÅVÂÂÏzè¢ŒŠ¨k[–7Q¿¨ö© éC*"?=œk]Þ²QHñOB¾AÙjtŒÑæ(ùÝy„‰š£j>¤"òx•H%£ßóò> `%,¤-ïÙ:òm`O8G/Mj¡§‡Lë‰-·+)>.•°ý’UÁ“ã‰>U—–ÄŠ* =ìû”úEµgÚGvîïB›vbË×…ˆxÈÓ{S_1ylO àç<"ÑBnGöÃÚÑÏ2!Np_Zˉã«ÚµFßËêçFvd)u;œºüTá8kÖ¬áê«?Ã÷¾{¾ïÓÚÚÊŠ[n¡¾®†ÚÚZ´Ö‡¤[–¢PÈ#()˜9c‰D‚Ǥ÷tvò©+¯â/YE¡P X,Ç‘Râ8NC>Ÿo ðÊ0V‰€%^„âBˆf—à2%m*çMV9?üì0 °V{zsææPö’†ù%ß ¯Þ0¼nø«ÓNm}2Zy«ÐS@ÙjtoTÝ2L÷¶g¬¸…´p†´ç/³“öµ-Ë›S^Ö}¼4xèò>5´yÚI-ÍB‰“q R…€‚l´!JvWUQWX Q`œÑ§ï¡>„€H]¤3µ!õ‰ ®ÛÀAФߗ¶åíC–”gEvÔ”4JJ,!QrßzrF‚h]wÈÁŽZ?k>¾±i´Ç|dñyJÊ«”-qPŽD)‰R"¼†{p=«òúJ’Ý–¥Ø_"RÁM9×¹YomhÙïo)¹×k»w1õy'íÒ6­R©Ä®]»8õÔSI ŽŠc×\õijk€Æ÷|Ï=$ÝsJ(a°-9Úß{Á?²té’@Œv]JN‰N\Á²Ù,©TŠt:M2™8x °h uJe׌K””‹dT ÕiSÑ-%&¯%ð3.nÊÅŽ+tÑ¿»bî^6¤öÛþ0´v8­µ¯­mK" ä;óHDõ} &®“±ïÉÊû’š™ MqœGêœÓÌ7Ì8ú²‹åýH%>i)ùl$QÞã"›$Z¡fNg°Q*Œ¿·Ôº~I­øùÎüÕ¶3ÁùZ¾”“óÜÍ›ÿ¬„üœQ¡xeFYõ2XÈŠ×ÊóåsMKð >nÚmm\RÿC‘}¹öñ[2]Jñ)4ÔˆªÅdx-‰”rܵËÇî°ÃІa"5Bóëì®Ü]@¸‰ãARVv1™&•çËÏàx$ 2™ ¹\Žc–.&pôÑ‹8ý §b+DS*ä0Ú=øÝwÉeÓXJ`Wôˆ­øàe@Áœ9sX0o.^˜YÒC:&•JQ(BØ©•³B8äñÿ¼¤NJq£”YkŽœD‡‰] Yõ\¦=ƒ (S©Í™;ÂÍð²×xrMßoÿŠ´d]´.òTÍÌ¥ÁNÊ™´Æ­ !F׫ªvßB`Y’ú£jJPì+6 —MK/[tåÞc›^|Ûø[|%ÅyJI×NX肎-SýÜZìE¼6¨b±æ÷äÉ>Ÿ#RkãçýïKeçëqóó’g[œõºi«¥'+K.ô‹>VD!¥/îHF$8OøY(Ñ›ÌÎ,‘„½¸åUM]CRk÷¦ÏZö‰c¤@Ü/G™+c#Íz3nˆÑkÀÐù@7*ªˆ$#Ÿ¾† ’ýE+þg½vÚ\Q UhŠ2ÈUŽATŒaì³±ñ¦Ú3dvd©­­ÅqŒ1XJréû/âž•â-çžÍëNZ>ºÀµï…¿I¯a4h=vü"ºÑ>Åbaô¸‡KÄ’ßeóæÍ,>z!g¾áTf´6pò‰ËÈçólïØI±X¤T*Q,Ë®¹P—Õô©ˆ,Ì8qÚ/¤` >ª¨:à$*éTž¯1º)»eíJÃ뇉ÖG0ž¹5ß]¸—H›r(ZÿƒNß“+fž:mC$a¿K ! }E¢µö˜h5N5 «è¸‚ûVa¸–_í¸—ŒìÊaÙòì™'O[:¼5s‡vôAç.ûHÏzÝ´)å;ÊY'TDŽŽ7Ù’@ê±u¬ š®‡z±VLýehcêz‚8ÔI±…ò¥ž”µßÙˆP¼CÙ¢7Rká<„YÙe÷GZ -Vø>ü<Þ¥vN‚âP!¹éÈsgÍÛë½(¾,-N6õ>Ê—X…¿)ÔØñè5cï• û‘ «f´!’Oµ§¯Â°ƒ,Ù=v Âû/_[ ,Â.*î¿üò¸Áq1Æ0444Êa­yäQ^³†»oÿ%o>ûãD4;ß)†ÑÝ^PkéEví•ðÝ"–dÜ5"–¤£c;ïÿàÇʈ×40õ>Â"«p~D¸6¤U>cç” z%ÒÐ÷d?VBa%Ôî¡çR?æJê¶þ»›nW¶¨³k­µ5³â‡JxY/¼ßñkµ’•ë¶L“QZ©@©ß|l=ùþ¥té]G_0wÝÜóæÔ¢}þ3eq›P 5€°L8f3º·„„®5½Èˆ Rg÷>;ü…¬ªZÜÅË5)'\¹ô8àißÑ–.ì:5É”;µ­=øNÏ£¨¸"9#þôö»wŸæ¤'Ç<áÊ¥oñgciüf«7Zñë“c^&&ìX—bhsŠXS”Rʹ2³3÷kÆ +ÈýŸ b•1³ª0S™´'Òdì‹Ó»J\=»‰cÚ(® ÏìÊñÙß#¹ù¦oPW[Z•¦6œï¯3ï^#MFzˆ>~ Z»¯®ö˜?þ¨w¼Öc Åb‘¿þõ¯ø¾Ïõ_þ,×ßø=††‡=àa`pßÒ÷Ïm´9r-I®÷°z¢¼`<×Ç}O“Ú‘!ÞÕù¾âÙÝùß¾ÊöÓ–}jé'ÐæÛ^ÎÃÍø$gÇÆ‡ó˜½»CT+0´1Š(â­ÑŒWòßtÛŽç¶.ï5W.µl2¾™_è-‘ë-à5ÚÕ£nt —_r!±hŠ ‡¤õn ¶öVšgÖâ,øŸw#EŸh4ä ó}òùühøÎû^?ï]t4 ( kÚÓ]ýÅæŸÄÎhyUÝQÉ·ˆnr±;“SG¼à©lG·z‰6EÀ˜ƒÏ¦¿>ÁÛ´È“ÖÊÕKæxÂwü¦RK|z {_/SÐ¥’D™Y¼’ObFÜ‚sž½yÛ_6M–_³$‚áSÚ7ïtsž*9¶;â*íja Ba´«7¤¶foÉvæ×øÄ¹{ƒâ—µtí’[µ1ðÓ+©‘1'ɱç©ý˺‘]Ò;³Ô•D{úí¿Ø½ðOúÜbŒ·ÿൔP9 YPUçµZ „_0lûŸNdT©³×õ>>t9°å@EÁr;ñ³KΰJ‡¹®ÇÕœ¨ÂGH •Å;¢ ÞP£©ÙB,ú?œÉ¸H cÀÍÁæÛéïÉsÙ6ñÛuý477ró¿ÓN=yT—uЀ1ø«¾Ik´kÙÅ`Åñ=—¯Þr'7üèäòEñç¾n Ÿ~ß›8iéÄÐÚ>õ MçÁß¯î ½Ø%Þ#šM„¦ü©#+«ó\‚â€ÃŽßu©³°âjUßSß¶UšÉ_)í„Ï.Òð[í™óœ!)‘iª:£%2¨„ÅŽ};×]$ßW$9+ŽŠÉ¯ûö¶‡6a¤@Uõû ÕÃ}yÛÉ_Z¬0b­öͱþ Ø-bjmÔ¹5úM¡ÑÔ´Å»ºV3¼i$}ò—\üXÇ=t‡Õ›ZЍÒvÞÙK)çoäúŸI¿Ó+øOq=¢Oþâ’3UFëÓ¤™8pM´ž“j¢$kÀ¶šÙÐv¨hÇöшÓðX;°í÷ ÷ùØOÛùùcÝ£×N&üì‡7qÚ)')á¯òÃx+¿Dk[#bÑÛƒªÚ{Õ^plÂc¼`ŒÝ«Á”@j†BV²âña¾±q€º¶$‰éQTTÙ>Ä^5ãÞ;ÛîÚƒ•TØ5êé¾'Sð‘ÀÏë[‡ð¤/,~¿ÑæG^Î^?$æÙ{OÚWê®Lð8^¥´Kª=KÍœvõg¾¹í“‡+^öšl{0mç´Ü-ms…Œ[ d} ˆ‡&åQ ” {…O3£ oÌ"#Ô6[3§õ5uG›­? Ë(ïÈ¢½I„Eø;•ÿo |½ÿ‘ é=YbÓlSè+]]ès<Ø:¶s›ç ÅÅHƒ°“*+á ×GšxýL›DR k„9¯kÔ—À/ïT—‚²'~)kf÷:9cA#»Jlè 2ƒº®Ë¯ÿçw”JEÞtú)£~JJ¾øNª±ûQÍM¨úÎØø´ä†×%0…P¢.Ba'ø=`y`û`ûØ5.ód=îÈÒã¹Øu +!‘v@Ÿ²†ò|…tíÊPêsÙ~Wv­$Rc­í{2õ ›^é`°ç/kÛÎn½U%Ä%²Žxi·‹]«13ª`Ý/•ô©8'Ãråõf%ñéQÒ[²È˜8ùˆsZ^›}¾ø+'ív´‡Ë@NùÖ·bøƒŸ3ÈœœîMÔö¢ßÊïvé[—¢~A‚ä¬hÚNÊz÷ˆ,ö@QTãj£‰‰õ¡*~3·ÕeÇ{ˆµÚ øqß㙯,½Ue;õß…–ã*… 7èNšëcY!‹¯%Ô·º…cRàDÎjô¸,"jØHv`˜_=Òχº ?´d75ÔÓþôýÔ$âÌf•ÚWÃs¿¢îˆ¹0íø°.šX©ìnðêôA¶=¬7£Ã×ðX²½1þô\ÛÕC|N„H½´Çr +HoÄh¶—ôú»þÜG¤QaÅå_{Í|Š ÿVšÃÈ…á@Ûën\¨„áÆ7ç”z|lËÆšUA“q鑘î¦BL©XÿFzÉkµˆOlÙY8qË{ö+;èëoZ(µf…0\bsR0¦0Ƙ¨ø¨šÑÓìˆsþdû¦Ã°NûþüëŒæZ@b@½7áž*-yf’>ºç<®çа(Nd¡F5i¬žä>æVøظ¢«"ÖÓ]«ÒÚ–Þjܽ޼àL„Yeü±|X¢bñhmxO©Ž÷Í–$[JA¢.?µ5 Án­®cï͘n)0ÇŒ ‡wÒÝãs_f>‹N9——‡RòÀW1 ÞuÑ=XGš,S%Háp¡Ø¥Îñ 5ñXhÜ‚Åc«¸tS‰¹Qâ­6*&ƒø“4 ‚çÿ;Ãðî ±f £ùuÿ“Ùo[Ãùû_Vã×Ñü1¾ù–“Öè.›Ä±áÎS'a6{ɇj€¿æPIHΉ;#þ«×~½óùýØÃç+MÔ‡EŒ®ž4i¢ œr®ô„x Hîýë';Λ8oÖáD|ÑŸ“‚×ÉYæM~§@5Q=YÃÍ=‘3Þ£ã7E ƒEì3 Ø]Ó1=‰8Õ[hÁöÿN!“šØôH¦gõÈ5r1BÆÂy¨à°Ê“fe õž@Ö” .pWe.K Ðk¡(AÖAt{ ¸&‚˜ @6Îd¶ÕÍ»³;Èõ®Äè¥xÈY¥ÒÖþî¿8¹¦«¥b"”¼&–ð ÛÁä‚y ¬ÂcS”(ßÛ]ÀØ+iPI ãó[=oØ|[?"©I¶Ùnv§sÍÈÎÒBkà‹vî}%´‡>²ýÛ§ß:÷Xœ¿úõN<¿Á"y,ˆ˜ž2«½œÂhQþÎô7Æz¢D¶3ßXsTtû‰_›}Ê×ìyr_è¨Âý¦ È(Æ““˜)±ÃWÿstÌ%Úd%€F&x»V€µúÒsÖÏ<_K³CÎ/¶êŽ8Ö"wŸxAX1˜qj‚´ê¥&7âþ¸ÏåTÿì¹Ý¡PÈ“œc™Üîâg½¼Þx(Å÷ƒ‰óà šRåÎ)YœSc_ØrU¢ h ÐEÐý&c`Õ‰L¬² FA"^ ênbû®àâ_vñî ÞÃ;ÿþ­45Ô¿à¸û†øýÊU¬¸íW<·q ‰ˆâ±;‰ÚÔ"3¤Ü€«òSàìKWS@‰ —†bd¶5ðØF—¯>²“ÍÙNâÓVÁJhTÂGÙA**]´?C.“':C¡¢òÑž‡²Ÿ5¾Ù@Híþo«r{ðÒŽuoüéQM*®Ÿ°N,[hWÄ[,ÔÌÉ{gRbÕ‰Oóð|ëi6é 0Ò‘·êD;廳.xäc]¿y!zŽ>ˆJÏùf4 ©Ó ëþ½ý*.rB‰I܃—Äg(TδS¥¦¥8'଻f/3è§tÁîÔ’|ua׌9Âû\„Tëa=¶J+‰e±„!ó˜ ýö~â³%À­Ý« ßõV‡ÌW笻gž b d°iËò¾oXòÑHóYÛÆƒ”™ ¸ª[`¬ñŸùzÄœ¬Íoïñy÷Ö¿è›|÷‰ÓYqÅ\êÛòP·ìÄHáÜ”»'x_…“òòéMÍ<¹AsËS»y¸; °j%Ñ&El¦E²Í"1ÃÆª“([` ’m?È‘êÊiD›TßàS¥« }þ‚¼I­LÕ+©½éΙ7ß|Üé¿=IòôR n@TX Í NŤb¾ùÃÐæõGÛDêäµ} ïk{£íYwÏ:ÌJ£ ÂàÙõœ.Á³ßë#1[¥jçÛ¹ø 媨WWNHa¤ÍО?å/èüc~7jzŠÃ•øçÞ×ú£ÍxýªT‹<²8JÝÉUé¦N'\ÝOgì{^¯â™/öaÏðˆ6«'ž¿³pE¨·ÊÊEî}­g Á*í€P1PfLåäƒ)ù4(.œÆ«ë‰™9¬ú"*é .*î"#:ЕU50«+3ÔŠq~öKÍå?Ù8þ))Á²ÀRALž6ày¯\«±‚˜>}7|hµsrÍ9Öü€NƒÉ„à¤Ç¸¨°rÏ×±þáZþБ+`%%v£":M›fkUØ«F!”vI6/ãˆ4 ¢Mr`h½ûÅÜ.ÿÁPü;,‚™_îvö½-‹§üœI«¥æµ ëü*;a*ÍÒØ>pû}ºÊP¿Ä"Ö*ÿëѦ./ êªt~óý-çh#V¢ "b€eD0ïf¢Þ¬<ÀÙn‘!:ÇÇ4g>ö/©‡kÖ¸–pn¶§È¸û^¯]! µÈ3MÿhÆÑ?Ì[Z¶PȰôí*¶|gÕ☭R¿/^ê­ùZ&Ü ç·%kѪB'g &bHY†ì>ò.ùµ.¥AD£KáABHÚQ^ÓRÇ›Ú9~‘ öØ^¢s2Áo驹±Âî:žx(Ê·žc‘ BúIDATz–yK¬ ®KXƒ €J”]ü*ô\ÆŒïkJƒlÜ2“eÓ R_ q#p©&úå;kÙ¶¦‘þq ÛrDóâÄÛl¢Ól" 2(X•ȈÀ;oÍÓ÷Ü v“&6S‹õ}kܯ—Ì3@wøpñø[à¾7l~Ëà M*i¶ÎZ^\Ÿ Vß„utqŒÃ2Š¥²kvÈaM|È[mpäÛ£ìþ]?HsÉ)·ÖÌ{îkù³ûóÜɪ/Tu„Gø‘±\°ð$•ÖùJIT éz KÝq‚B·žFPl5ÿŠà°Þ¶²UáX›´ËBws ±^ î• Pær«é¥ä˜ÙV”­&æoc`ÇÏKôm¢æ¥Gvy|Ö¹› NðçÃ~Ûïfžî.H}M‰N¤ÑAeí©}ý¢Á/ü’Ε Ú Ï‚²O^N3[Dx}KË[ë˜×¥®.ð½)=.Ú6Ào·ô‘×>V\©•Dj‚*,Å’ñ¥“ª-v.Î3êù祳˜¶h„ØÌ,2ÐË[{jÜZǯŸà‡k÷»N’˜n“œmoµ°k%2”¨Êï†÷æÈôä‰4@¤Nb׉¾ìnïûCϺ+ ò¿¸šè¿AÔÔí­¿Ÿqƒq¸²Ô#0µ$OpF7@ŒªK„m‡Õ*ˆ—÷Ž1<¿r„ø¨m³· opOxúÆ¡Ìøu=óHh,D…HXì‚'nê"R/²‘:¹ËŠ‹Ðà:bH°‚X³êÜ|ÛÈGݬÞ3Q-#w‚¿í'sÛŒÏ6횈·+Ntž;Nme&ÄÛ‰ŠpÄ2§5)ÖÀÐ:—Í÷ô’œa¬è|8{c¸^’³·Ý6/ðÃò ¨©ÝRBߪ²S{ÕÅ„`fОß„‰0󊯠q³>n^ã4ÚÑÁw rÈ+[`Å%vBbÅ$Êš\„¯Z¸‹©29vÎhƒ›×”Ò>¥´ƒSÒ8^0)ÒX I´Nk²‰7[D,¤” o+ÑûLžÜP»Fb'‘Z¥‘¬ËìtnKït#H“› AÊÿÿA™~Ð@ëÇsÏÆçNV[…Íê_8’2Áù³È {ÊaÕjÛ"Cΰ~õš¯ìé,ÏÇÛn›w°R‚_Žþ\¡Ï°î§]4ÌÒ´(Fr†ŠÊqÏ@d˜±DŠ_>ó½¾ {×çôa¯tŸD𛟯µ¹ÓÏÉZØ­zJ‡3¼ª­;Ã3?ÙM¤A­³ݵzø£Œùë¼$ámß^|¦UÚ7³Y~ĘXAͶQp©p" -ðå2>­Ã¨˜ñ5ÅWÃT'&ˆ×åÅeœ]?_v 3ø¾A»ícÜœ&ÛçëvÈöA¬„DEvBaÇUÉ÷õcÙ®ÒÃÅ'0ô†\T>T¼þ“:€öæï,jÆÏú%33»CS3;‚ª1£ÊD»•©^D•}ësøxÔ·Å\¿dNxøÏæ-ß^|‚•åyu³q’.+Кl÷P +&K[û‘ÔÈ+ŠÃURéØŒo®tÒA™òH­Y¢"lªh…“`|Øx××%Ùì|*õO^ц—8™Û›¿t쨧;FŽ 1>ü«òžF9ÇÊ)ŸÌU¸¤òâ3f|¡ËJ_E ¾ª5J 4E¾gðÏñÑ%CaÄÅÉz3.Å´ƒ“óÐÆ "e–= rò[QéÃ&¯è?6Ò[\î,n1Ú 8o•Á©œ¶øo\ÔÁ\s_]*+îОy{aÀCboUãjœL,ŠÊx&`hGŽb®Dýì„«]sÊ#?ØöÔ¹_:öl+ƒ:›í‹QÌ8{ ƒ10¸%ËàîêfÅœ­÷÷WH¹ekýa®tŸÐV~î¹OŸsåñ–%Í'Ý¢Ï@W‘‘¾"ÅŒƒöÌ>×õTTRߘ,ömM_áýçxE$´™¬zRúŒ6Ó¼’On¨H¦§@!½÷³_­ŠgÈÄš¤“ìEåP˜0û)e‘°œU…in• ·G"1«[û¦Ãwý­ÅwÃHo¡=?ìô…Šñr a”|ö!Bÿoíà´{?³QçŸ}åqŠÅÕÜ¢Ï`{ž‘¾ÅŒƒï™ Ró¾Ž,I¬ÆÆ^)7T´KÈÇb·Ö¦Í+yäK¤{ á>ÕãýÀ*8¸€s ôX‘„…“23Þ$õŒx…Ò^d¦Œ¤‡ÚŸ’Òe?p‡±2Þ/·)\…÷‘ (¾ ÷c~Öf7S¼¯|­ ü1ÎMÕÍAçßÚÁÝGvÅ>RUÖÜÞrAˆpŽ ái¢è^^×ñp¿ŠXÓfŒ§þî¸"!ÿ†ðÇžˆªÈIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_tools.png0000644000175000017500000000020412650773437022762 0ustar tobiastobias‰PNG  IHDR!ß*PtRNSþÿþ}?[ pHYs  šœ$IDATxÚc|ÿÿ%õÀ¥Û×õT5™˜™XXX™X˜XR¿ýøð°™IEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_box_l.png0000644000175000017500000000026312650773437022732 0ustar tobiastobias‰PNG  IHDRA betRNS¼ß·hA¶¦hIDATxÚ}Á @@EßÈ&êЋ‹Vôá íЋ&8ØÁ8X qš—ÿ~ò32N$×ɳ‚+k‡F€º¯ø]-ëHc¦»vyY­n –˜Ý»"8ÀŒÐ³-ÒñK=ìñp:2)ðL‚IEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_box_r.png0000644000175000017500000000026212650773437022737 0ustar tobiastobias‰PNG  IHDRA betRNS¼ß·hA¶¦gIDATxÚ}Œ=@@Fßnö"î¢q0…H†‚„S¸€KPر(ÖNCL3ïûÉg¦¥<¢ë(¬_ ežÎ‰=·íëC¢ž¯éöJ½¦r$¯›[cl|€».¥Céü¥iÅ’îÍ‚7™BIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/info-win-t-l.png0000644000175000017500000000207412650773437023401 0ustar tobiastobias‰PNG  IHDR%4õ«IDATxÚíݽŠ$Uà·~zvÆM¼ ½oKÁÀlA440_dY0½ïÀkXvúÏ ëÈÙšêîùÕ*y8œS[U|Ö»ß×äñ4f§™Ùï¬y‚÷`>öwýßœ¹¾í=àiíËá.ð›#çrÝÜâ9àéíëóm>Þ7'ÎõJ„à¿´Ÿ8Ÿ L}à/€v¸ns3(ÐD8þmãpÀ>gÂSê @;ZÍÄýäfPx:% °Ë™p@3±OºaÕ×õs©öú÷€Ç35N`7¬}?ñB3q]>øwÕÞ««®Ûjos3dÐú{À£ÛOì%°íO¼Xد»tIV9„V£s Œ»èO¯„êpÀfªK@½ÇÔ€‹a=«Î«¼"¨G”߀Ç3)P‚ÛaíÎu(ÿó¿J(àY’ËjÕº‹@=^`¼€‡«G ”s l’lêp@3±×#JÇ€ xžäjX—I^©7ÌϱÎuÇ€vx®Ï¡3Àe’÷†õ<‡°ÀçIòío?¨(ÌÌ80îPº”Q9t (Á€÷“|”äã¿|Ÿõv£¢03%ÐTÿV(á€2Và2‡NWÃõ‡W]÷É—?×­·kÕ€:5V ”±«Â—I^$ùà‹×ß\¬·[•€™š Ô£J@ Ëa¤@Y¯’䳟¾Î›·oTf¬-ÐUû*‡p@>ýñ«¬·€™;Ö9`¼úÑÊz»V=X€þĽº{@½VIòçÛ¿T`hª}è†Õ'ÉõÎHX‚ccêsè†=×›kÕ€èón`¬ÉÍnm’¬·:Àô·|®4Iòú÷_UàX8`ìÅ‹Xƒ}xÁ:<d%I'"iBögÖËN"Dçôxó}0Œ £‡Tu³Þâï-pîOo BŽ•b “3Šóvr!-ÝœûꦰÚÛ-»O„(…Ú(j„.Ý/úŸ£~c‡ºÇ• 2Œ>k~¾_é@HÇ©?ñIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/button_blue.png0000644000175000017500000000070412650773437023501 0ustar tobiastobias‰PNG  IHDRd{À˜•bKGDÿÿÿ ½§“ pHYs  šœtIME× 4!ê$*tEXtCommentCreated with The GIMPïd%n(IDATXÃí˜=JCAFÏÜÌÈDH#DIÐ=DI {Ý€,¬,“RìÄÊ ¸  ÚXÙí´0¾wÝEÞSîYÂwøæc®SUyz»Óó«N– û¨K1f‡ÓÕù{›i­ïà^oN®w?—ZŒ–PüŒœÞd8ĵ/644øè,™\¥(Óû$öMFðÑ‘ ûˆmFqP—"C±0!&Ä0!iܲT!³0ŠP ðý‘2ù2#y2·(ödÙ†&Ä„&ä_ qY v\Ì]Dp¸¬„TËuÄæ$?ˆ‡j¹Žì·º•¤7&V –Íì›±"$½1‡[ÇâT5<'œ]MÞG/L¦¨ýgS àKq•v³+͵m~Twzµ ¢IEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_box_h.png0000644000175000017500000000017712650773437022732 0ustar tobiastobias‰PNG  IHDREø²XFIDATxÚMDZ €@ Áå胚‘è‡>è‚Þ÷Æ$L0lû*§å EZ­_ß[orZ‘!ÏçrhšPªêþyO!à‹¼0!/øü¹IEND®B`‚vdr-plugin-live/live/themes/veltliner/img/info-win-t-r.png0000644000175000017500000000121512650773437023403 0ustar tobiastobias‰PNG  IHDR%\fù¶TIDATxÚ½—ÏjAÆ¿êé™ìfÝ$àÁ‹Þ =û>‰añÊk¦É2ÔíIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/zap.png0000644000175000017500000000151712650773437021754 0ustar tobiastobias‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYsrçntIME×4ÅG¿ôÜIDATxÚm“ËkSyÅ?¿›Û&m“ØGlšÔ´#uŒ¶Ñ±­õý¤&›Á¢uáE‚ 7 "n†Qü,R³Ñ©F”ŠJ-±-µµÏdšÚ™ÄØ´7iîý¹ÐÚýn¾çû=â~p”¥ OËöÀ0Ñɉ÷öb‡ËÌ/û«p{–‰¥z±` ¥”Ö>º‚³¤£åLYÆ\Ç MVö«A!¾H)å• Lôåcd2HRH24ÿúŒukCüvå‚\Ì(ªwÍÎÿ± !„÷ƒ£Ü½Ù#ŸÞQN@* T@¡´DǽÜàÕ› ƒ4’ØD=e9§Ùy0Ããë„ùwZvg0é? I£Ûý4ìÚÂO›6°Ú·-©±¦÷ Ož3ôº#9‡I_FWpŒ­ÓRm ’ŽzXHfóžm;sòëî6+Ûœ;Ø´{ —ÏŽ3Ó?@:ê¡=0ˆ}§eæYYÁ÷FUU\•‹éc"úNCIÄ,áã{AÞÿûÆàmß=Y\"n Jd‹ péÔij7”1—a/YÁÔd’P8™fò–œV¢Ø‹ÿ®4a™ SUÇf¼Ä®LbÖúðU~ P!OûˆMì\Ô T‡ËL u[ ‰ýw‘ùyɵÛ^ÔÌ þlõãõEØ»»›Ž×yˆ‘ˆëDB)£s8\f³½pgy.õÛíœû½’RËUÆF63ŸVì-aF«¥ñç^|­üX“Ϫê<Ô²1üÍÞÏŸxçV·LŒ8iòW.IC‡/×É·BrJݹLM¤¹Ûö–І8Ö  åH-SéµSX¬âpæàpZ¾`ùŸQK<¼7FÊ6@Ë‘ÚoËôW[7á~ƒõU>VUÛXéÍ#3/ d|hŽîþ×xªM´®Ë.SV'âòŸ¿û‰NjÌNK Cb/Rp¸,ø÷­Å]^”UçOÚý+&=FŸIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_header_h.png0000644000175000017500000000022712650773437023366 0ustar tobiastobias‰PNG  IHDRb÷ãtRNS¼ß·hA¶¦LIDATxÚMˆÁ €@ÄâØ‡5 ãGìÇØÇέëã}„°]+Ë>Ëi9C‘–[(2¾×ºî¿y<§C hU¡ºw÷Ë¿)Dðå;|L¶rËIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/menu_line_bg.png0000644000175000017500000000022312650773437023576 0ustar tobiastobias‰PNG  IHDR2:r# pHYs  šœEIDATxÚMˆÁ €0 ÄÜcfFböàÁ"¹¦é£Bð°,›ó:ä´œ¡HË=ßëËN¯ß½=û-j *T1–_þM!Š î~9*Ž >xIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_header_r.png0000644000175000017500000000033512650773437023400 0ustar tobiastobias‰PNG  IHDRf3­tRNS¼ß·hA¶¦’IDATxÚ}Ž1 Â@Eßl!UÎ`áMlÒX{! <ˆ ÅZ¬`.!6‚Eºb7»±H6"Nõøÿ |©j Štj½,cŒÇû°o£|pûÛ®\m´ ¾÷´oÝ@.$òS;f®g“÷õ;z×§I«:¤'‘aŸîº‘b"â<ûE=ØTµÍЦ¸â.IÓ„ù`ˆÈ‚ }×du7÷Æ@'™5ì?â»ÚœÚC73Yº ²m{“®kÛTÕy>]’x“¡MÎ~bÌ<à¾ÖõXöè¾[ˆx¨_êydïÍŸÐÌ@˜¡ÀR&xlàËì]3豯Da]µøÒVÜsåǗЕ_Òêþ§‹fWÕòþe‹."Jü7ÿêí8ùÚA—ÆožwÏpÚò܆Ãß8mÅQ÷¬Ü­|w÷–€ãuϺ}ˆÞž•à2_à(ß]‹-?»Jº¼r÷B¼õ¦Ã0Qµ¿n?Àz6¡ ±¡€_?ßfMy}ÿÆ[?ñ°pn`Àõ> çDÿçäaüøñäËÝ-¿oÄ (œ›ß+ òæEnG8'áÜ|4ìÐ4F2ödÉ'ø87WÅ KúlËÍW/¨ý²ú"ÈÍSQSµÞº}à¦_|ñòòœÐvÀ`î~s7ËÍUÑE½³ØÈHΤQrº<,kŽPMd1ÜÙljUOŽDŸBý‹3ú¼?œ}¨ZQ—ÂA™"÷ô§Fe€’RaÜ©ò§06ͯfñß¾ØL⪄ÕÏU9˜-o܉À8 5Ù.6«îÖ>NgÆ>€à-3Å#Ÿ–ÐA™UÇ%E^”î!iDA0-Ü–!©,é%­3ɳ%úM"ò·¢g2â·^i¼“f>­°L]=Mgœ;@ÀöÅ[‹zòÇú¶üÛ_IÑ€kp’¯;‡µ¨ÆÈWÍ™hd™‘@äã_cí⚯®{^ÉQn‰ÿþ÷ ¯3˜øÁ5‹Ð´«é‰€ _KÜe‘§}ŸðE³ÇF@ÌI ÄªDÏø‘ÀÝwßMD„×_^¯W à//ŸL 4%w¬hé fHñe{ÉÌy|ç¿4†Â&¾{f Kyùô‰Ý ÊMlZÞòìÔ«»õfŒ•Àwójzœ6±[U\Ü}?¿–à´ê!ÛªZ eÂ7p>€Ïà”+»bM•oõî>È¥1y À’d6XXP¶ZCõÞ€“./¤½uìßHExÐUÝ9· R¯½^ùmãÔij«£Óµî—¦eþÝá3]݃â«ÙüJ€vnß Ð"a~Ô± 8èê +ìhnÔ­jÙôT $ðXvî¸ý¶äi‡+V`ÆM3†¿mH)¢r[g—&X%^†Ý0xWøP”û·¾Rš‚×ðC l]Z˜–ŸŽ¾m(ɹ ‘:®bÕ “IXûx´pÌÃC©—ñá7 °#o€»|SFw=©Ã3ïÏŇQÁSöAå M[·¶EáÑKLŽ@y8{Û[åA¤™ÍiËŸ÷"&ǘ”¾=«ª;€šæç%4­¶S\@ lÔnÀ»S‡aâ ˜–Ã_h@þaÙX{_MOGl1æÙ”1<*µºÈßW\ãþÇ™ßô$½«†ŸF4JíÎØA'–|!,=l}^¹É='eÎYÄv¶œvóa3÷­k8 ò 9µÇfÄ–öüR{{Ïz¬”s®‘y…ô÷¡úBÕt¹°°ë"06„sî „-tÆYƒ°ìõ~¿÷áü‚ÂmÛÎà ÅG”@ :gL‚ úmÝokxùøoSÚ™~`)å^—ùø1 û}‘!’Ì’U²Ëþ;IØ2Ba½c`N–•ŒÛ¼»,ä ”[¬‚iÛ:ïÁGþý÷p”í.g/ó1 Žœ^õ™ž¨$×úƒ³9çÓAÀ?Þðïgƾþ×ö}°j*U¹ RŒ³XŸYKt ž²œ… ˆ² dÈ(Ö;)“ƒIÍ ²óJ(>5žÝ¡ÔIwãÚô=¼}Å[mòõ5?^—étº‚Áý~#º\QïzϪ…7ýç„–ùêE“Îè‘ñ`Ü3=ƶ¹ç¾5¼Z°‰ó' µŸ3ª+–‡—¾wåü3¯ÿy :Àü+ße2ø÷Ö‚«àj¡‘´(v0 4`6Zpœ,#PÝÏO²éWÿÄü ï>tü£ê3¤gÜL>¤N£yW¿Ëb:;|ëƒgÀ›cÞH! €p£;'\Óˆpu#κmA U¸©iľ/÷n ×4"\ÓˆP£0sæLºë®»ì»îºË𠬺o BU V´®§Þ5êÆŽæG®¯Yžÿâ‰Ç•#ª¼Œ½õ0+ê §OÚq÷ðYƾzå X·xÓqfyÌòDꛢ‚>ÄìÙ³qÌècà‘ø{ŸÍ\®˜å 0öÕÃÓB4¶,gß>äë8\÷öf…Ñ(¯OàšÎH»–1Ö ƒL+˜^×t“°Ý¿j GªÝQª7FgpßlUÏ¢©aW+D¢u VØÂ˜Ë‹ò8ƒ @ÝÃXYf÷kÕž˜X¶­jè_«nj–ñ¾›WSrØ„¨µÕsT–±?f>ÇKm(*êë@ƒ5¼-Êøj6¬Ìû!¤ÐR;o4¢}Ë`³¦´äM"OÅ/OTÆïÙº&f;¥:Bp@S]pÊMÕâ®î!4Õ…ˆâDØm}šê‚¦º`J2.¸à‚­^qöߨB4vlm‚BªšêB„”Ä{ÑË™øënöý¡-‹Ü…¾Jc|’¶6{ÿºð»¯îùJ+„YNÆÅBU!œNtÝ¥Kü¾pº˜PUÔ®ñ‰8Õ¢õT¬àóÏ??¤g¿Á(ìÖ ]Kúà‡ºuëº8.Z× ¡ª»m”ͯ”ËæW*eó+Þr³(ì#Õ Wÿ<ŒîʸSD‡ªNëvF·¤ªÓÈ)ï~s÷ÇNUSU K¼1ªFåtÈpª ‚»ƒ=âuãõÉùÏû àó4E/¯™Nã/ž€ÜÜÜ•‡ÎÚ-^—Eç…c³aE}cÕ’*&‡SU•ïÄàI|É89d ²Ëê–Õ6ûî’‹â`P3$ô8®(ú»+­U]B{fÕÅ¡:9q6bÄðºdø!t?ò³€lø|>&w¡5ƒCÍÜ<&ûfä*Šš!AÍàÈêªæ0Ö¬Eº²Þ}tìuf+–%LÉPrîë}šÊ8”P]pYJ½ÂÊáEx{ÖýØ<ûzä¸8r]yzmyïÞ< ôá±m@É&Þ̵1Ÿßfq§åW² J6aÐå= þ†g·ÒÆç·±H£¾4-ÂëÙE±¡v3 5†—©Ý ¨Ý 4lôK®§pöuuá ÈÏr /SA^¦µ¸ -@‰W9Ôn*WÔÜÑž ^ÿøŽ\ &ÔnºUqÌ?z'¾ÙNz«z°¥ˆµäâ:Ò;ÜqõÀN0èØxo’´(Â}5Øý<ðàw!òÃjdOˆ~=¶âˆÈ™š…]ó½^ïýÙŽV¹Œ£‚\‘Ã`Ï«0g ‚P…ܾÅwGÀª§*/ö”i·öÈt…ú_ƒ+_CÄcÁ[c‚Éw/ T˜‹:«ºž5»Ÿ-+€`ƒ¾,£D>}ç'îÈÀ r½ßüuw¹M½aƒúÎþMî®D$é¦9ǼùJ‚x×,›4Ž™øœ9Xʆ÷E~Zxýc†¸×,ø3cì„d÷û7ò¯È·¥Å›~ô¬]òÏGì“9Iê9¸»%ÈQT“œ¿z…·Û¿ìžï½„9®ü⊙‰™ÌÉSX:¸6„Å~šðÙÿt|Öþ%ÃÂõ‘Œ˜õƒß?ݺ@ 5;ïÜå`üÄd'¾Qo!àýÝ?Vm8ä&¼sö8®JŸ £™ºõK|(<3\M)«|kxue2 žþyw¯^½@Dذaž|òÉåÎh¹Ÿ{Ö¢ ÑiÒ ù]Ã7Oÿ(Ç­”ƒ-ãß>ÓŽFWš‹ÿ·0–½¸"@ÂQyÑ[g<ÅŽ%Bå'“—^ÙÊœ€&~yÒùÿMŒ³Á¯Wh¿ÆÜb¢3Hýèf4y>I~!÷æ6|U:òô‘G®g-äb¨1Å¡ÊN=õT÷’%KN¡(W°“ˆ¨À‰ïÇ×~³qÜ“£.3½X˜¬vÊÀ‰Sß¿âÍÝÿõ†&Nf*ÂM»Â­êi5î;A 5+‚0).‡[©=KîYÃι¾/IK8לpA¯àÊÏögt)©ªI˜¢yΚ¡vsèy-hü*vÕµF®6eͽeúdHœcÚô›0숑xü;1jÌà(ß$¿ðŽë>8{r¯…Œ±”%Ó·Ã,‰Å|Í%ìY“{,’ü«´6eõ³-‚·"²0™{ÀÞU€!T—ª¤Õ+}‘ð¡–I¿ó$G·PÉuèù÷þ¾Ôód{ˆ¾¬hW£7u„+6„jÊBw€ÛJYØ_KÁõì¼' ä0”/é2÷Â6þ–<£œéÚuB^€å¥,xÜÂè+ºŒ#9¦•êG"ª9 ÑüÀí·ªY·SG Á|Ì[c>Ôª}–Aðø´ÎÅ6†]Öu.cìš—khÚvFÜfZÕmØåÅS¹Ì^%«©Šå«vE1±½lø=¸¶á÷P\Óæ ¿ g¯¾ Û“$€€×^ƒ{| yyyðz½ýìmÑv9z§ˆž™]-Ý×)jµG‰úÍAIÓÃæ©¾©ŽK›–Ñö…õ×öÔ÷*ÆY¢ŽcH2 k‘_Ü­pêw]?‡¡ðW…!bP Më=Õ™ÃãÄ{¶ZvÉ”uôéÓçòH$òþÈ‘G#b|23³ G4ÔÖÔàÔ3ÎÆˆ—ÀéÊ@UUåžššš·MÓœ_Ä"NW/Ön0lAkBûBQ JÑoÅ*r†å¶vGl[ø+?¬,ìH¼ôØ—˜Ä »uT/©æý®íkŒ‡+è[V§t¨ã¼¶?Iª”2ÚáêÈ·û—Tž•\oÈŒA«¹Žî1àÞÐôd`Wà¾äzƒ§"Öbªú¿ àо‡c÷ž]X±bE:[ ê@Û³W]yN;ýLü²êg”••­$¢SCf &²(…ÄUßV#¸7ä µÛÇë¼nÌ)Î.j+SÄ ˜TþA9Vz‹eðÔA¹B·½\• Õkpus"\g³çæà¾ÐKøˆ™‡äÙÛ#»¤Q‚5aM ß³¤b9ó “MÛýßU×6mõöl©&1ójiK ÷ÜyŽ:ò08T'dEi…‡°´H†®¡ÉëÃù]Û¶ašæEGÎ{ŒÔUnt&XrßÇnÔ®k.LÚÖbœáUg+r}ÎHÂ5n…:~!®¸ôB¼úüc­ÞUV>¹×H€ü€Y „~…®£𠳇š)Ûþ]ïŽPaK~§ûú¯!\¯·lg7©…‚ûµàæ+²“ïÿìà«›¼`®¼}ç+í.r-Ë/wíìzòë½IÊnžÛ9:ºf:ôŒŠ¸Ð.‘µE\pu× (q€A@0€Ô,O‚ñåX|º´n·ùùÑhrÑkxoöÅÛÛÕ d›hØœ‹Ú•õ2µ ´J b©gwGè8Lùåî;ù힦ää)4rö@Öjmzª9 JížÇˆcãC »d—TÍ¢ŠË^ù@Î<Ô/[¥ù–£wvFQêëeó«êëVé÷·ÃÙÕç.L Ð8Ï@pO]#Þ¿Ž¡Û¨z¿ó~5pÏÊÓ »8¸Â@t-vÒ€jB×T »¡…ge"÷P‚âR±kaý–êo“ÍþSÊO×U*çü˜ÿO{_ÑÝŽžÍÚ™ëÌlp‡Fpä,Ö Ù9È?Ò9Ël Ñh$<þì);û‰áLû@ÎH}{Ãür4ì ¤•»)ңéU³Í• ˜*E"–;תlÀ [ðV…ÑX G¶ü«{wèÖp£±®#-á–³þ9¬0T.2K”Źn«»‚Ê¡ãKL²›ítÿ~ •¿¹‡í_ç)eïY­`œ—°$ÝÛ4Í'&ª¿õßBøíà}Ç:ê$Æù`Û¶‹çNÎÀbNp""!ˆt9c~"ª&¢RÓ0¾ßS¾§lÈ ¡ó¸$eÚÂÎA‰ùJ¤X ,YrìD.Á À`°˜Å9Ó… ƒ„ˆpÎÝBØkÿÇ7¿ÔaÒ×+ ·82³rjB“»qÈm=ç4&Œ ²¬1 ,Åõ¬5Š7¼}‚ö‰ê¿÷U‘ž”˜€eY °¨oƶ %SEJ¸Òãë'Á©0 ئn!Ô`"³'p¶‰l›S4Fo‘¬2 ‰Ñ”¼¬Œ¿º¶µMîãîìûFZ'W¶3cYf ß>ób 5Ni†Å“+á ;—M<üéÓçmú3ˆ:}Õ81ì°€+ËÐЂdÔA(§­§6ÐÅFC€Qä"§5w[§°¥óB´×6£ffÙÏ×Ü|í­%/¾Ó²^@7£a.›¡ê7oŠV!ûÂú$齨3'&ëò€,_þ'úÿQÂ^ûÃ9Шê&±6¬ÍvB6”Ž0ɪAô1P³Í@V¥uüîO š5÷ÑÝÓ­Ì^¢ªi1âZ š–êšïìþÜû—Ýüw°è¾½F¿˜ü„¸}û ´8aÛïdš4ýVž6Jk73ØÅ6všpõR’%º@BÄüvTÅŽò¥´Ç®²ä Ü¢=†H¹9ÿìçN\øõm+¬Tâdšn¶G·o›±‰1~xr$×ö øký—¾uÑüEKØ™›¦B™ÖV‡áŒv–EW,;$д$–Å å3Ø{4™Œã gcLC#®’EŒ"µ‚ŒÃiÈ Ù0=Ö^÷FÏW`Ð d KX¶mGco€0ƒˆ„Â& K²$).9Ï•ãæÌtN!R³Çd¤x×Îöc÷«g¾•Ø=uóæ©£¬&hfR‡PðòÈ7¢1¯W;]6õÌ[h‰œÁ)ï8hâj¾ŠE0’dl`ef®‰‚qÑü¯ðææÝ¼`€P; Qó3þqfÏîr÷ÍËuôR[°;‡îý‚Ùúí_ÝôåÁªhÇ>26£wYß £«£¥#¡ú€ØZk@0 `¹-ˆw"#²Ã $ïÿ¹æ›IÄ%–2B›ÂøàöE»:wÁ(ì]L\ã‰î› &"î0r†æ&x"¸&„þþq.ÿÀ¿ê³+·ê­ûÕ^ŽVÓ¨7ÿ3ñƒ¢?"Î]1#/<ФÜTƒÉöYðVøÆuç׉–q¯Rþey1‰¨ì 7…½{Þ»9Û>ô’Aª­Y' Ó‚0¢Ë& 8±Ÿ^úUÙŠEnÔÕ#þIº=ÆÖMÝ„0L4~îFî1™†»,„÷…°óç]ÿlÃt͉;ËZ>Øòþ–ï8¨«å5FÙ°f¼µý‘ŒÌÞ®gj6Ö™Kܦߛ0ü²A’0¬“›ñ5AÌF¤"bï^¾7‘ÊT¶¤Ì]_Z_Þ°£¡¼aGC¹·Â[—âgXpá‡÷Mø÷¹÷2'KY>Ìíž8Pä¬pänÍ«‚ÐxW3N‘”F¸õì3fÌ÷·ÜrË)1{“'OF  4¹Þ ‹gŒÿ÷YSlâ CsÞÔ(6»| àô?Ìôgq.=ÐRºëMᔫç½:–9Tå' ˆÎ[|ý2+'ŽmD|0Yn2$3¬£øgݶ¦N˰¿¼tb‘­iÑ]ª1@u?‘s¸²Î ШTâ¦z »vízþ 'œpʺuëÑâo¼O?ýôV}” –J>ÚñÇš î ŸÖ)…¶= Fr$YŠnkH¦y#©Ù,ºy˜eÚ'’EÖD&x¹q­Pä\aÒJInޏ:»ÃÏì3»n[ÓäÎ"%"ú·FÄHé–û$93`RÅwKε,kv2a #¦^C<ñð³›–ï9÷ñ‘ ƒ¥'¡#³Ðé 5jáƒ%®j‰4j¡æïOÁ9ã dš¶ûâ¢,5!õ³;W¯MAˆ¦DSäB4ٺò‡Œ¿+š‚ðýîEõΚiÌqØñË ¤ö½©©©ÇýëÖ­CÿþðÐâ´4! FÇVêTEÌZ*šB ¦`gw® ‡œÔíâƒvØÜwüm2¦üu2n½é†øã¢tÄESèEŠ1E¼M CøµqEØkK Y0bÙõ!'Ê q|«ÖûP±Ù’cO(Ñ/ÔÚŽ[š~‰a’  f/0¶CÝV3RÌCÓÖ~ÐÃz+¨k© zm]½ïùsEÁà“¦ÁoðÕÍ=pÚo#É—ÓÊÔÓ#úÏék8dŒsYa>cŒ 3@˜ À„L]C/Ï€Ël²¹¶‘lT€©t]û@ʦ‘HØcQëO×¶‰ûÍ;ÕæèËŠˆ Æ’ tw½~rG ĨK ¥ˆ°$;ÉÄ®)ÕP¹#8M«•]ÒSó–o;¯{öÀ#öúl@¶Ðsðõ#E6¥2Ò7hZJãˆfKæMÉ JcFG÷âÅLc`¦ÚfqØ{Ö…ÉS©_Ó’!Ó„°a4«9„ÌÓ),ì©AÓBȲ¶m„lžÏÐïÄì#ÛåZ¢·ƒ†@X4_~.„Meóv` IDATQ¸aA‰+"º•ºÀ=÷yµÀ °r«ÞûaäžãðWã K+Î%!4"h1Ϲ½ „Ìæ+œô7la‹!b3hÄ 3ñØßøÿšÅ°sUž*}8€Æ–íÿú‘w³fÒøÚ=ú Õ[#¯´›4²eQÓCƽ.IÍ´wÊÖêµç)³yb²º¯-ÆžŠ‡>,IiÅv6Oß›EúÄ£ç@ ×ÛìÎÉÉyÐï÷OK¶7-òà+Š»E›’ ¶Ô¹ˆVZw%€º ؆¨Ô˜Ç¨jëýí_øZm9h³eÛåØ)œÂÑ~­MOÙÀ«{j+ ")ƒ°n³Á ýÅ„<—åV]͹ÅÅų&_{5Rªi‘0.¼à<,þìsôíÛwÊæÍ›—X’0U¯îÉÍ4KHLY90Ý6b#°'„H½ÉÅw†ökm]l@šT§W÷,ð(ìš_9=vïD7WÏi›¸²rªmŠJÉѼ8»úe£¤8ã/5_Õ|Òº¾¼Ì&–2\L•k‘”jÉŽÖíð(ü3fx^yå\xáxh¦¢¢®`œÁëñ ¢Û¸çÞ{ñõ·Ë°yófLœ8ñ³yóæ °; Wq¤[ lp4l  Y1Wc’ÂÊ‚£ gµ A¶¥àìŸsUåG•ï·ë®—”¿Ñ4BÏ‹{nT²•åäà7 ݆á5ò¶^Üûξ*I‘Áe.E/Gž ²èÝtõe—R¯Ç%ŽÐ¾0 ŸycòôM~¿ç>|øK6ndG= AÏÞ}¡º2àp¸Ðµ¸; 9š!0pà œtòX,]º™™™ ¨Àe~¤$KÍpc8ƒð³w“W î Ê¡=A%´7¤„ö†¡}!GhOÈ¿w[½—QœÙ¥,èmÿÇÚãò½ïìý'ƒ¤Ê0½æl.ñÏ`þÒ ê–Õ?ÀÛ{YqJÏIœC–9$9úW„í¬–ºæ©ƒn烫#Ë¡=Aèõú÷) §Â’e΀þýû_³qÃÌž3š®## GÿÆ®’nÅxiÖ,,ÿéGÔÕÕá°Ã z.į–$–€+IÔª˜‹o®´b¡€¹ÿãýÿpªŠí7£øHÍø©™2˜E÷º~À-íÑÈ‘!…e™dÉÉË2‡^¯Á Y›Û%îÎ×Êng&A–$(’Y’P0,ýÆ÷¹9•hÒ3²àcu$0(™òR´H&Ž?Ã’% vȶmÛ ë:T…ÁÔµèeh0Hâ"a"Ë+C† …Ûí€ËpY’¦Ê<WŽþ W„®Štè‹®X\i9»¨.Ëk¶ÂÏ™£ÂØÏ›2¨ÍýŠ,Oà‚¡ËпýdHv N¬Ï* gq„Ã7‘›–^\ÁHÍy´n}ÃK†Ï86âîTJÓ1ý’“ͪßàEÑ‘¹=D£Jò4'ï\P ÏÎ@ ’6Í'\Z [w`¿‘[€Cëy<@´ÿgHçÍÅ]·MÇ]7Omíþ«Ù†Â,0CÑ«~5ÈØ!U¢`pNê4ŸWß®P>"옇†öÑk­}Î¥uÂõú¾-¯ìé×YX2_d]dûH“ò›C¸ŽL®Ú‹eC2ìDð‘ÇStÛ±ÑÌH‡u' ¯ª‹}óûã‹[GàÜçfãÁ;§ƒ±–Ι@&ÀDÃm|XŽ…‹33ñ“Ó‹m¢ñ—jœìe¾ƒñˆ­}¤´üØú¦Ë]©*®°Ì¾#îêÛ{ãSû*â÷ŽnÄ®OæTbôÙªÛÊöóÎ4¸êîºÒÝ$9džœcAζÑuŒ ¦#0Jζ½o£iC‘F}z[ÓQŠÕ•²m Ø „´0÷‘œsú¨øvœ ‡*§^¬j% VØ;€, ÈŠà‰Lk‚³mÈY6juSÓïÁþHbõ=e§@Ñ!gÙÍW¶.G9 „±'…ñ2ÄÓr¾ù²œo¾,å›/ó|óe+¢ÿÚ)™›ÚÖt 9Ç„œcBÉ7Áó#‰ßrމ†m^ø÷hËÚT[r£õ²²- Ø%°ò= ®\;Wzçá©Yo#b؈6ªë›0ü¸ó‘QðZ@ªØ6 +‹[¸ã)Û4 ç˜Øòb5|e‘ð'¤“ºzŠQV­€œkF¯X3º3é¸Y%W4;;LÈ.ž al{¡~yé‹ Ë›¶ùî´Ì—SßìIrôÎaØþjÃwUßhg´Å5g~Ýu)Áq: ÅÝ$¸zúÁ, ÐÀP¢u=Ï©@•WúHãëü^Q®U-|º 3–ïAñ©ÈåÄo÷{`FÌÉþ]Ö\üI „§/)ÚÃ5‚gÙÑžÆR:ê~ `ó>ëÓ,Àq“iX°ºYà @Û1où•“( ÚÙ?¼‹ÛyÓy‘¶½îCÍÚÌö:&;mpË’çnÐá~C¯3pSÿ.˜ú× E!T/ïgáG8Á Œ3›PµOA£·. ÿy=”V`ÐU°m ›­AÄ#Î WŠ/ñ'ff.;¿á¨Ó‘#7;…™z—‚ìͯò^ïSp+CýûÀ9GËìô‚–P9öçžfT)åJ¡Ý*ÍGóèBhWig{ó@ÑÓW‘%e c¤ VÄÆâ€†ù³‚U†JŽÌOŠ„@b¸du ¬÷MÔ6êÈ`"¯w6?糈¯h\o]†¤ÿÌ¢ZYg„~”–fô²-ÀÁá[«NÎêæ˜ÓF‘jš/¹K±÷Àˆûù¤½gþ­·Ûjõ®íÓF°:!Ý- qIÎÔ½®¾ŽjÎY|ÞÖ†1cÖˆ·ZusÆÆi·ÂÄsLâiíädü‚kB`…lñ[ãß¾ð຃V6ÜøŠí°§s[¼m‘­¿…\i8ƒ£‡R¦2¬}6,Ýüyî%ïNÀ_Æß²ÅÀ‹:»Ò-« WAAvQVqfaæP5Ëyc{„Ê3\ƒàY¼S|DˆnˆÁƒg-œ°ðç¬Æ¶¸‘n)À¾vDÞ°s†]¤(ÊLᣡÌÉà¨&Mˆ¶ÁÛ½\‡ÈWÍ¿hAZãëÆõ7Œ&Âê”-Ýivk;tܸÿý+ÿóO¤; çúý4º˜;ybd:X",Þ†(Ó>¸fákÿ×úïu?^7™)ìMÁ ’Ùö7¯BBÐÊ"FKÈîŸ.x«>×ahúÚÅ.>¸Cî@˜aü;÷ÈÌÏ|Uøìqdj_5qÖd{K¾Û0jM°|vÇ{-xÿÃR2º;N{ä´ÛÁ3¤ ¦;š;´Ù7Y2jûtC{7íéµnκVßúšøÝ5yŒa‹‰žún f£ˆÖÇÇ1'Óª÷ÕLZóÖêOÿ˜Xr¹ì³K‡¬ì!=¹“·ZJâúÐ+ Øaay¼žaß=üîÿ+^ñÙ„a²,ÿN*q4oúh%u½Ëü€JÈ>9’Ûœ_5!º±ö«}óßdÞD9ôÊa8ìÒÃî!ñ饫ܦäMèAÛ­²û?šüé“ÿkcùâ/t)\ÞNêÃ3¥v%0 °2*}yï7wàCfm(?­V‘´ŠÐå ÿ2˜•’IŒ9x»ˆ…¶iàYØüõã?ŒÔ¼ºùß&Ú…sÏ”.g9Wy÷æÍ…­‹ouvX ûHäøybi¾_Äø ÁÐ̵ËfýÔóJN§ó’c=vRß¾}G9Î|ÇÃ6oÞ)--ÝLDïxÑÄÄüãç£Ê\ZeùÅQrŽÔaŒÞ hå'&}qûwóþ׆ò% Î=Ä–c¬µ1Ëšiî[‚ìï–=³ü<üI絩Å_òÖ™×’Io3ÆÀ$Ö¶/Ð&ø¶D ±g¿zpùÿm‰pñ¿Ïø;ØÅd¦aÉÚWp§†p¹!2Êu™}œ%¬cÅû[¦f®]þæš¶˜—ŸrÊ)_]pÁgJRì8Ì4ë|ii)æÌ™KÜ ¬3:ôE¯Ÿöš‹¸3ÊÀ¬K_«6!4ay<ýÖ¾ù{åÿ’yÏyé„,UU=ŒA¦¦ªos¦fmøù­u§´% .˜sò0ÎùVæ‹Þ%‚MúlÆOóÒºÊÒ•';÷ÂÇŒ:]Ï<}ð%FY¥ÐF¤Æ¼ý”[úú‡ç7,ûoë/ÏŸ0ÓG.¶#QŸs:'ºÞdý9‚@Ð÷È€#»n…"%¹ñPf;n™Áƒÿ§Ggþúë¯íÛXDÈÍÍ…Ïç;À;î°²#Iôx§ª²£»é¡ó¤–´nAw9ðì‹È¹Ž\ú¿2–€ëÖ8Ë´eÆYÊÖôtn¶ˆ;˶Bí L+QÆX0zL)¡qu¶böH¬h7ö®y‚SdÆO°|4Tr´­[JÈ4 ßµï®Uõ?›Pã<â(Û~Q’l3½^X„êaØ0>Ùñó¾9OÏ;Qè±õ+ÅJK ‚›!–Þ&d–••]hš&²³³¡ë͇r0Æ0rÔ1(..ÆÏ?¯À–Í›ã[ð`€sT º-©MÙ´ôî_qÎCG^ !j­2X‹`Q˽’a!Rk?üüÞC7/©Øú¿`ܳïÞWøÃs¹Â`Éþ²Öjª°€`u¤˜ëÑNò‹ð…£) ±á"D;wz|áo¹Ì`™áµ—¨ê7–!ʶ­®¼€M¡ç4$I†˜ë“X–Ñ&ºÙN§*¿óö¨ª®A¿>½qÎyßÀ·_-Á¾ŠJ”•íœYÏãÙç^À‚÷&ÏéAzØ×‘üÕ#¿ÎùÛ€'ɦÇrîp3½ã1;'Ü5:Ô\‰èÇ&ÿϤï™7ôf\–^`ÈL.3Xµ©ÆÕººlS¸w®®} íœ&KžPbEß7C:¸™¾{f=}þüŽês¯ëy©mÓb†ÄŽ^–Š äæö[žp~ñ”•Kêþ÷Ù“ºC„ôÅ’„.¦h¶ÂY’8"*,D¼¶^]០€°}¡vbDÉË•Ól“·<Âz q¿ó¦©Óðéƒç¢âñàB‡^?³æüˆ¥Û½˜:ñ/ÈÉlµ‘Ô 3ÆÈê¾¶7ü!@1°Tú¦;oN˜0|t¢yÿ5æ=õŠ"0Î0à:ÆØL7º01!Òq©/·ào¦§!|½mŠv'±í %V4ŠcŒÅǼðåÛ•ŸžtUñ3¶…;¸Ìš?e”–)à ˆ—‡”·tûrïî?J¼ˆe?À9ÎL*˜¦í×Fm…˲ï zuqÝ(; ¢½Ì+PôtÛj“¦æ¡ÝÕЈà‹ÎÆO²ãgd À'ÏDê@ûgଠsÒ1:U–µ‹ˆ 0æhõ‰Œ–Ñ+fÁÔiÌèñ]"’ÂÚV6Û] h`¬9±xÆ`1;vòD| v̸Bû7k°-òûêË"ëGtp†wÈŒ2ñïßBD×aµq~§óMu›î4É>ÁÓq²ƒ·í=Ë&› Iq±¸ÄF ›Ú}6bB—S–õ(—b„c©}À¶Ê7… )l»\Ÿ ¡t¶<Ƥ­1 Úú €Q5^£K@¡K¦°öAÎ2@6ƒV•à(Ö`z²áɉç¤õCôCEJgÜC!Ó¶‰È †’Ç"šLÎ\îR_SºïÉ ]/i«*ñ0|ãn : LÂû¾*óþ˜Þß!–Û®!Àg„D®¯Æ„泡89i:íþCÌ»æ?õ8ôÒ³IfU†AY’ÂÛp¸1döVѸ3rDŸ“sßû½ïžƒQ†_V”g-á 2K#˨ÚsðßÝ{µ¿H96Ûdˆ±ô~¾Ø=¬­µLð^µWǯânô|¬=s¡Ð»`r–ã8PÁß`vêF8µK%Æ|³?¯Z¿?€;cƒ·¦#Þøa ¿´PgiZÜr,°$¹mÆKêgâQ:IÎÒ00йDáØ½p£‰Æa€Á‚À›þZ󹘮ßéµþö‘·@ü£X< JÇCœ52ôŠ’“lA?º¤E1|"”,ùÔýß¹86_ÝLÐj®°Ñ¢Ýʳ#ÍcFµÆiVØ^×Ò•2äÊ’ÄÚöJÓö „EkÝ[‚ ?/çü§ÓùK8Î9zÄ‘øÏ‚·‘‘•Óæ Ô ä÷Âëóá”3ÏOx8ç8ÿüóõ%K–Ü%„xÑo‹¤íÔà+KÀ•`èÑ¡”®Õi4Pxhöÿ­›[×ëÕè°4Iå¢ÿ„kô·…E»:¤ù£å€·©”¾_³¼ÿÄ^÷ “žà<º»,zƺ( Á[˜34»¿¿4ìl—Ÿe  Bt—pFÑj5„LÀVØþ ir>ÍØ1G¬ƒ¥Îfˆ7GO<ñÄù]ºt¹rñâÅpª*žúדð‡4BÚ xE}²š×漌I×^ŒÌLDÂa|öÙgê¤I“^\¶lÙµUUUSlN§ÿY²"(ŸI1?g;+¸i™ I‚f°f£™³h®c 1×SŠ0eH·vÕþADª#3e0‰í†ýµé·¾‹Ôê[=ö.S h…í?©÷ÃŒã!æŒm»4  ¿Ô§ü½Joßkú€­äv<“b»94²ñÓÞùûÇÊÃñ{æí²ßuýO°u1NR¤¢&cŸÙ/Þ­Þ¢ÌþÙoúKWtf6ö¿nÀE`ì6¦0C¤ÃÃâ3߆g[’S~7´+ð>Úú •äh˵›2HÄ¥Ø9ë¬ðÒK/ݹ³¬¬¸±Ñ Î9fÏ™ƒÜ‚"ôèÑ™YYmO8ËBmm šššÐÀ`<ýôÓ¸ãŽ;PPP€^½{ãwÞÁ¸qãF”””ü´~ýú›|øfl$¥„€ &±DŠf[Ü`„Hð}ázë!¡ ؆­20 Šîvˆ}Í„ñØ·<@à©›œ)·BV—\=2!gHmªÆ9Ãò‘3,` ¶f à ®ðJ|¾÷Ý=íQ"I~‡§ I<¦†+9r–² §qI~€Iìx¢hn‡á3àßæSø·1áÁ•¨‚¨\¢˜;¥6!;l#°'g‘sråg•sÛ›ƒ¦ *!Ð>®r‡ÐEz˜Ô-¯cl‹‡ÿü˜>Iéá \JIjC[Æ»ç7¬ˆUuR¿“ºn/-Uòó °ní<õô³¸üòËàp8Rè`¸*öW" aÍê_pß½wÃårá”SOÃW_~ÓN; UUUööíÛ0Ñ-¹£é5Œc.kþ\d¥î§:È.i‘g“w2Zòt…õ¼¨g7É)½a¬qŒ38‹¿„èÁxd H.ù1³I°âÓƒ‹Tœ2ðzaŠ3ÆÀd2 Þí^döÊüȑ︘;xTˆ BÍwµTé;ÿÿÕ꤃eÞ¦ Mv×ÑE_s™Oc61É!sΤØ_ÎdU,‚0ìs²ûgÏ ì ¦k›>˜1ÎVòLÖHÀaI°8gðnñBèv$Rž QÚž4ï:ºpç¬?oCjñ¸*Œîvœ` (q¾þú+̘1—N¸N§¶e¥^v{— UQ kaôíý^ìºuëpü ' ¼¢ õõèÒ¥ ÷ûýG›¦Y‰è‡fµáÓ‡‚q¼#©¼# %ÎÉønZmxVoÔ7þýÒ_êú~÷½×mL×ÇÙÊËoÊlÀá’ÑÝU‚ì’a­“%§ô@Ñ1…[ÜšJ‚6[46*+d%zîžé5q–8Àíh{îõMXCpwð T@püRúêÎߊŠâtªèËV¢Å–!Õ:¨cH Õ!È!Ï;²ÙÇ}súǽ›lHHB$3=3gvÿØÇy|÷;ßù¾ß÷û¨“@&tÜïCçì BvÐ7‡ŽDOlçŽ^”I;¥Ñ®úûû‰DP\TˆÊŸÝKK‘`$†À ÂÔ¦ÐUè‰(˜-¼«_XƒåË—£®®Ås ñäc@¦Ñh°Øš J¾;·T–¥?S¯€Ìé„ãÕŒA\ãka±-ŸRßhéÝÿjËœô<÷*<Î&_G…Â[”cP_ìô:zÊxöI•¨Ù÷»ƒº¢Ðœi2³(gå{!Kxœ!|`T"¿uÇ?H½è’S1áK_(A …Åx 'Å%icÆûT$šPÒå+Ú6m€KŸX˜-ºy–á’ÂÊ(ƒ4µ6ZGMˆŒÏýÍáoÛá_hçîF IDAT1…qÕ¢"9M‚±¹VE”â¥3¼(šW3Fu}6uåbõs«åÍ!Ó["©£Rk5®©êÆìÙyÉÓhnnÆ7^;v²æ®h;?í½Ò[ŠÖг pN|Áa‡ßë‚ì¦uþæðm|˜AêÅ.œ/oÒCf¦+×1±œ¬ e™3¦ì¡—ï{µ}÷IÊQ%ÓXU¨u±î8˜ÆA$ÙMë}Á[ô`20útÚ¢§Ëç.‹8dšNÆ­7Gø?@öHý Áƒí1uÑ3å›™W_J£„6õ¶ÛWD"¤&"‡ãKõˆ±sªG墧ËG ï°F&À’?H÷àÊâBÐò›¬lJ!€„‘]ÿÄ’wcOW =x*ï» ’D@¦¸\"Úô]¿gñh;Úƒûž{ ¡H 7/9ܼÿ§‹AÕ~òq/šJâðhÞáåD‘Ý£ÿî‡8ø|p™`¢_ çÒUejô ¹LÉA]dtÊÒq€=@ êPC:ÒÎtÞº·ª}ãtž}Œ®€ÁÆ›+9•]üBÙ÷¸Á7Á” ¹1¦€aÒÚ»-„ô¹®¿d¥}!Üì·¤˜‚ñƃ-qô7†À™X>}'Q}ñš²Z!D‘FϺ²p]žDv%ß²½GIÄÈQÈÜŠk×ìÆÎŽ(¥¨Ùô®¸ì¢)-˜q¤ýµPJ*¦ܸÍ:õü dŽÍÀ÷·u!û‚L(étôBF†Õñ/3áÑëM•7áäE¿t»ìù÷²8ÿT9GF@q†È‘8Ò œÏ6½txõLŒ‰œê¼ªªä6H”<DÿDKôŠ!ç¢ b²Ï3¾„9Zß)½åÛ1ô Ž«3éXÖ–Ö n ¯­~)eaÉ|˜pä™çZ÷Ö$½²sFïXý6üêãxiõ¸ÿîÛ¦”Aݱ^Ñ’[n «ÐìȰÄö<PPPŽpwn« Â?‡BÉ £L¦ ´­ï‡äƱ@sì;LãÍ_µà&Û×^)=‡3ÞdôÀíš79»78Í1¤ÏsþmϯÝÁãûÿ®Z[ú¤p±E†qb,Eœ‚Ää=Ûh¿hÚ¶Iõ}:{˜fˆ+™O¾LÎf)³™jF&AÂ'AM÷c–– dŽ­D8Ðþf®\i_ï¶¡g0 ¶Rša‚pŒ:„€dÚ”µŒZòãø˜½húc?œ9dC×ÇñÊ“µsSÛ ïÖ Cª ¥`¸!Àâfœƒ%¸õ>Ê¡…hHà|§¥é.¸$‚žŽº#„aÂ#Ã饭Ó0Â%åö`÷³©•çåàÜR!€mÀ[ñ~gigɘUîBznô|ª"p0gÑ8çoìÒ«¸!Úm°‹ÀiÞ®¯És‹¸´7Ñâ(ñÛ÷œ ˜ùB­81Mg†|ù–ÊÞݰâÂub¥dZ¤Ï½Ÿ¨è¬mO›M7R‡µÆ²›@’ÉŽ–·†g\ók¿ª~²LÉ"“ÿš7ôBr‰ýÇ>\aûs§­u®¯*« £­)‹™L¯f³ægÜ`º7¸6/qHŒÁ¼+}Å"I²€5†ÊaªLçH„LhaQŸ§WÖ@°-æÓׇ¨ÛØòé/°cNÙWKù«: ~¤8dÈ“ 4£}:Ô! î3œ+¶¾p¨fùÚë ÄJ0ä%3¯I Y¬—Z â2b#¿¡ª³wF.lcäÑ︉h 5ksCP#:Fåø§ø™Á ¸iÌpè§°ê}©ãÒìwĵˆ‰@dž|*˜ÎÇjÿ‰üµb4GØË!! ¸Ý“äwBX±…€:(¨BÚ„À^ScŸ vÇâA½VÍ'Ó€žŽíÃ{ÛàÇßüÅy!¾¡o§µÞã&µ€ÚeíX‘²©hQN>ësF̓ÿP‘þLuì÷HËVÌàјVõ#A¾Â9ûaQ01Œ”ÁBߟÊMµJ5Ÿº“æø¤äñ:Ç 2þšd¯·4Áš{¯µ%ESö‰œ@6ŒäçÿÎM¯üIIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_line.png0000644000175000017500000000015212650773437022553 0ustar tobiastobias‰PNG  IHDRrcf pHYs  šœIDATxÚcø÷ÿÓ_†ßLþ0ýÒÿþ¤¨ â‚ò÷eIEND®B`‚vdr-plugin-live/live/themes/veltliner/img/bg_line_top.png0000644000175000017500000000013112650773437023432 0ustar tobiastobias‰PNG  IHDRrcf IDATxÚcxÿÿ%33  +3 ÿÿÿF:÷‹>¸IEND®B`‚vdr-plugin-live/live/themes/orange-blue/0000755000175000017500000000000012650773437020070 5ustar tobiastobiasvdr-plugin-live/live/themes/orange-blue/css/0000755000175000017500000000000012650773437020660 5ustar tobiastobiasvdr-plugin-live/live/themes/orange-blue/css/theme.css0000644000175000017500000001452012650773437022476 0ustar tobiastobias/* ###################### # Globals ###################### */ html, body { background-color: #081966; color: white; } table { background-color: #263480; } input { border: 1px solid #081966; background: #DDDDFF; } select { border: 1px solid #081966; background: #DDDDFF; } a { color: #F5EE74; } /* ###################### # Tooltip style for hints ###################### */ .hint-tip { color: black; } .hint-tip .hint-tip-top { background: transparent url(/img/rounded-box-orange-tl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-top .hint-tip-c { background: transparent url(/img/rounded-box-orange-tr.png) no-repeat right 0px; } .hint-tip .hint-tip-bdy { background: transparent url(/img/rounded-box-orange-ml.png) repeat-y 0px 0px; } .hint-tip .hint-tip-bdy .hint-tip-c { background: transparent url(/img/rounded-box-orange-mr.png) repeat-y right 0px; } .hint-tip .hint-tip-bot { background: transparent url(/img/rounded-box-orange-bl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-bot .hint-tip-c { background: transparent url(/img/rounded-box-orange-br.png) no-repeat right 0px; } /* ############################## # Tooltip style for epg infos ############################## */ .info-win .info-win-top { background: transparent url(../img/info-win-t-l.png) no-repeat 0px 0px; } .info-win .info-win-top .info-win-c { background: transparent url(../img/info-win-t-r.png) no-repeat right 0px; } .info-win .info-win-top .info-win-c .info-win-t { color: #000; } .info-win .info-win-body { background: transparent url(../img/info-win-m-l.png) repeat-y 0px 0px; } .info-win .info-win-body .info-win-c { background: transparent url(../img/info-win-m-r.png) repeat-y right 0px; } .info-win .info-win-bot { background: transparent url(../img/info-win-b-l.png) no-repeat 0px 0px; } .info-win .info-win-bot .info-win-c { background: transparent url(../img/info-win-b-r.png) no-repeat right 0px; } /* ####################### # Menue ####################### */ div.menu { background: #FCBC40 url(../img/menu_line_bg.png) repeat-x; border-top: 1px solid #FFFDDD; border-bottom: 1px solid #FFFDDD; color: #122DBA; } div.menu a { color: black; } a#login { color: red; } div.menu a.active { color: #122DBA; } div#pagemenu { background: #FFFFFF url(../img/bg_line.png) top repeat-x; } div#pagemenu div { background: #FFFFFF url(../img/bg_line_top.png) bottom repeat-x; } div#pagemenu div div { background: #122DBA; border-top: 1px solid #C0C0FF; border-bottom: 1px solid #C0C0FF; } div#pagemenu a { color: #FCBC40; } div#pagemenu a.active { color: #FFFDDD; } div#pagemenu span { color: #FCBC40; } div#pagemenu span.sep { color: #FCBC40; } /* ####################### # Info Box (near logo) ####################### */ div#infobox { border: 1px solid #FCBC40; } div#infobox div.st_header { background: #122DBA; border-bottom: 1px solid #C0C0FF; } div#infobox div.st_content { background: #081966 url(../img/bg_line_top.png) top left repeat-x; } div#infobox div.st_controls div.st_update { border-right: 1px solid #FCBC40; } /* ################################ # general table cell classes ################################ */ table td.bottomrow { border-bottom: 1px solid #FFFDDD !important; } table td.leftcol { border-left: 1px solid #FFFDDD; } table td.rightcol { border-right: 1px solid #FFFDDD; } /* ################ # Mulitschedule ################ */ table.mschedule tr td.even { background-color: #081999; } table.mschedule tr td.odd { background-color: #081966; } /* ################ # Event ################ */ div.station div { background: url(../img/bg_box_l.png) top left no-repeat; } div.station div div { background: url(../img/bg_box_r.png) top right no-repeat; } div.station div div div { background: url(../img/bg_box_h.png) repeat-x; } div.station div div div a { color: #000000; } td div.station a { color: #FCBC40; } div.content { background: #263480 url(../img/bg_tools.png) top left repeat-y; border-left: 1px solid #FFFDDD; border-right: 1px solid #FFFDDD; border-bottom: 1px solid #FFFDDD; } div.__progress { border: 1px solid #C0C0FF; } div.__progress div.__elapsed { background-color: #FCB840; } /* ############# # Timers ############# */ table.listing tr td { /* background: url(../img/bg_line.png) bottom repeat-x; */ background: transparent; border-bottom: 1px solid #FCBC40; } table.listing tr.description td { background: #122DBA; } table.listing tr td.current { color: #FCBC40; } table.listing tr.spacer td { background-color: #081966; } table.listing a { color: #FCBC40; } /* ############################## # Blue Background Thingy ############################## */ div.boxheader { background: url(../img/bg_box_l.png) top left no-repeat; } div.boxheader div { background: url(../img/bg_box_r.png) top right no-repeat; } div.boxheader div div { background: url(../img/bg_box_h.png) repeat-x; color: black; } /* ############################## # Recordings ############################## */ div.recordings { border: 1px solid #FFFDDD; background-color: #263480; } div.recording_item { /* background: url(../img/bg_line.png) bottom repeat-x; */ background: transparent; border-bottom: 1px solid #FCBC40; } /* ############################## # Remote Control Keypad ############################## */ div.screenshot { background-image: url(../img/tv.jpg); } /* ############################## # Dotted Frame ############################## */ div.dotted { border: 1px dotted #bbbbbb; padding: 3px; margin: 2px; float: left; background-color: #122dBA; } /* ############################## # Edit Tables ############################## */ table.formular tr td { /* background: url(../img/bg_line.png) bottom repeat-x; */ background: transparent; border-bottom: 1px solid #FCBC40; } table.dependent { background-color: #263480; } /* ############################## # Infowin support styles for EPG-Boxes ############################## */ .info-win div.epg_content { background: transparent url(../img/bg_tools.png) top left repeat-y; } /* ############################## # About box ############################## */ .info-win div.epg_content div.about_head div div { background: #122DBA; border-top: 1px solid #C0C1DA; border-bottom: 1px solid #C0C1DA; } vdr-plugin-live/live/themes/orange-blue/img/0000755000175000017500000000000012650773437020644 5ustar tobiastobiasvdr-plugin-live/live/themes/orange-blue/img/bg_tools.png0000644000175000017500000000024012650773437023156 0ustar tobiastobias‰PNG  IHDR!PHÇYbKGD&4€y¯· pHYs  šœtIME× PÄ"-IDAT×cÒÝõŸ`Ó$K¿¼ã LŒ?X?1°2}f`eúÄÀÌø|T ÛRþ#IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_box_l.png0000644000175000017500000000021212650773437023120 0ustar tobiastobias‰PNG  IHDRÎoõ2QIDATÓË1€@DÑÁxÿ“YZº÷@ÇB câ&RñÂøf£=KÄc6†Ï€ñŠÖ@jFÍôz[L…aGÁR…u³×åïÏ1/Íî/IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_box_r.png0000644000175000017500000000021512650773437023131 0ustar tobiastobias‰PNG  IHDRÎoõ2TIDATÓŽ1€0 Ý(ÿ##ýG´f¢5C%2åâ³@‡­òÝ-óCdì`«tàg€ªQ5MÀXÀ•Û»çŸ^šÊRû$;¼>1ÅgòuIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/info-win-m-l.png0000644000175000017500000000027312650773437023565 0ustar tobiastobias‰PNG  IHDR¨ÈU‹bKGDÿÿÿ ½§“ pHYs  šœtIME×8#™9ÁHIDAThÞíñ ÂP@Á÷1‚’FKÎY-µSˆ:„ÅܨF_ã÷TMÕ¹ºTsµTku«îï×±_Û3àï}^"o²¢# IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/info-win-t-l.png0000644000175000017500000000214312650773437023572 0ustar tobiastobias‰PNG  IHDR%4õ«bKGDÿÿÿ ½§“ pHYs  šœtIME×-‡ñðIDATxÚíÝ1nÜFàv)YŠ`|Ÿ"¾Ü)ÈIrQ*§L—t)£.¥w†¼ÖŠ)ÌAÆW+­w“¥ñ}Àà Mr‹QÉßï•ìO ptÊ‘ý°gåï Àñèû!¿l¹~è=à°úºyÌü²a_¯Ëž¯o÷ùx_îÙ·• Àÿ©ŸØo L}ீÅp½ÈÝ @‰püׯá€>[ÂSÚ ÀbTeâ~r7(N ÜfK8 L¬S€åPíuû\šµý=`¦Æ ÜÕw/”‰ëúÁÙ¬ÝPËæzѬ‹Ü ,ü=`ïú‰µ†ÖÝ=/¶öÛ.Ë$'ù8ík``ÜE@Ç8¼ hÃ7S]Úu<>  œõ¤ÙŸäóA;‚ þ® ìÏx¤@ ¬‡ºÝÖ9 þÏÿ¨¡€'IΚjmv¼À¸€/׎¨û¸IrÓ†ÊÄÚŽ¨j0à"Éùóçß>}ûö]ׯ¯^;o8>eb_Cu,@—»œ%ùf¨‹$—¿¼ùáûW/^&ÉÇÕßNŽÌx¬À¸{@íPGœ&9Ïè×W—õÅÕê/§ G¨†Æê8¨cÎòi¬ÀùÏ—o~L’ÕõŸNŽX™XëH¨ÝΓ0z\dº.ïDèÈ8q›rI*"$•øÐ†—Úa)•£Ðiˆ¦$~nŽRNg¿¤r„‘3ø¬äÐ~ùųó›x…Å/QǸ¨VÞåIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/remotecontrol.jpg0000644000175000017500000004404012650773437024244 0ustar tobiastobiasÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀz¢"ÿÄÿÄ] !1AQ"aq±2‘²#35Bstu¡³Á$%'47RbrCDc‚¢£ÑÒÓáð&Ude’ÂÃñ6SETƒ„“•´ÿÄÿÄ+!13Aq±"2Qa‘¡BðÿÚ ?¡8#€øŸŒjV+%¹ä˜+Îþ¬I¸É-ìÎp2qá¯Ip/ýønØ’MÄ5r^eüÄ€mà 9ëãôcØ}²’ÙÙÍ)")ßÐÃ3ç«3(b}»œþŸX±ŒÀþX:ö¸Þkšr”`ê?Ù_Ç}È{M²Ýf£J;M58P{¨#å^b3œ <ï[<¿GüṳQýEø GÞ.Ôšt¨¸NÐÆìT0‰ßpŒä £N’F¼‡mÛ,]ëù/Ñÿk½aâ§æÿŽ› à%±lHÛgá¤s¬ÏÏ »Æ0}ùÖŒ­æ4žu£ L¯Ž¿£Z¿£I“¶³#@X¡•ó¹F°Í&1‘ôi<ëYÐ+Iý G¸i­Ì%MD5Ç4rDÊèè¥Xv÷#¥ ÒsœÁ ð*~2Œ½öCÂ7Ê!V=¶­ƒ1zc„fn‡”Œ`޾ìQÀ·~ªf ô !HjlÛdd~ Çò8νqo9µ§M—Bœ]I ÂÝUEPœÑMF\‡¦2럃¯O„æy°É);ìã“ d´Üò6³Su\;r†ªX{€y®yóÐãY­_ù¢û”)žÜì”ÿ¼;Ÿ ]7ê—G1´?¸è²CžÏxwÙl§è—Gp'ìarõ%åûgª¶#§Û—ñkðˆ¾Ùè¯&…kãY ¥¨3˜XeeÌRFU†w’AÆÁÔµY)ÿ¿ª¿¸ÒXëžÙA#GGtnW•—øaº¢’#rH$q””½ŽØpÏ4Ô ­²N~ ,U@˜,$*…áPåCN\¹G.1“Œ ô½Ûà«Z‰*Z¥ƒSÈÍ*±-$FÇü˜sNŒ}L‚IÉ©ÏÔÅWpŠrÒ±SDà r\?9'Û¢Îíi‚zb"ÀHDz`œdŽƒsÔ`FH¯/Ýlz¹ù‡É£Ktž«þýYo¾zé¬3Í-å¨JÅ*$˜’YXqÐ œð9ߪZˆª©¢©‚@ñJ¡Ñ‡ˆ?·ÀûAÓ[©î%¤¸t?u)ÿ!û #b|Z£{Ž‚6Ãü¾'ÐåðìãþzhŠÙ÷¥7ÎÇã¡«áõ[ÄÿÃO¹¥¸Vâ¾ ß½o‰Öj:ç÷Ê«ñÏõ޳ZÁ4ŠÇ©{$?ÅçŸü2ŸoÿIt{Üm°tÙóyÿ›)ÿVº>ƒhÜuáeêKËöË=ˆ{™!:÷KõF¼Óx¨yo7XÐæXié3â7—?<’Kóf½-sÈUóî“@ÕÚ \鮢ëe§ô©y 2RórúTË…RHXÝœ¨8 ¬FrªqsÆÒ=^SÄÆâc9íßõj¯þìÐÅpPÉ/wg”±Ü±“Ÿô¥´Óµ¦q I™Qs°î°Aù±Ÿ˜é…ÂñÔӼw7Z*•9’žº‚U>Ô`}£¯™Ó«u׎eŠ×d¢¨ŽÚøRDcVO@pH#bØÀÁ'^dpÎN©£iŸ˜ðØ1¹¹§¦‰4Ûý'ý.5·ËmíZÌÒ$Œ ·R ¡?¤¶¬zˆ¢¨¦’žuç†T1ȹê¤GÎ Ô'Y áû-ªœ°ƒ’9˜’IùÉ?652zcÃ^ÎÚ9–¬âÍQ$öƒCsUR¹ŽbF 0!±áÍ„p<˜i÷×+Üü˜›ÑiÏâÉ#Þ™3æ"Sá$²=éÌ\ VÂJ†Ï/~‹ƒŸ2ÈFà„<¢¥[ušŠÝ3wq¯37VÀÀ'Úwb|yôFÄØ¹^vÿ ?ÿŽ:ìÔ}©™+o-«·¥€7($Ò@7 uòÒÅëÀÚ–”Ÿé-þï@ÝdŸh@75ŒÄyÙ>ì3æGž–žÝJ+ª*$§§™ª R,!ŠâÓ>¦~s¬ ¡e­7œªòÌqÇ* ¢‚I$¹s€BŒŒåv’F‘È,ı۩''@ (M,¦EOO7vY$ $@@$Ø‘‘ᑹÎ×ÍTÐȰ¤FeŒˆQ¶LHÎ7Á8ÉêtÖ¾¨„Ùcž6Bçp®> x‚wtµº¡k©´r!*èNJpÈqÔƒÆÄ±¢…bVʃUJÕq§wJå 6c*\4I+¹ßsKËÑòN–”ƒxìtÂÃW%e¢š¢C<°Ç!X”¥ãG#ÛÅÈßmÀÓɨ}Þa`­¯ï:{Äèfü~_üøh–Ô@´Gž›üN…¸€ú’cÛðÓBe?qì…Oã[âušêã÷£ñ­ñ:Íhcö¢¡é¾ÈñýÏx{óe?êÆ û‹{´Ùýžpï²ÛOú±£ê¹7–5àåêKËöË‹b"¼e£Ò |ÃQ“Â’+$Ь§bdIWýÒ>˜îÓà5s­¦ €MRüª\FŠªYÝÉ¢(³°uɉšH™;¶PtRäîÛæÓªJX)P¬¤`îyF >ÓÔék‘@ÆËV„Œò¼Ð´w›{ºëeî`ö¨ƒœH§ÁÿI§Cù1æÚÑ:dÕsÀ†JÛuM,#åJÒDèžþG$i$iÈe` ƒâ4P¬í¹HÜïÖ:5p»ÃK]¾8g­¯© ÐÒS(iœ’B¢@.ä 3’p%ºœ°S ø¨3Ÿ™ÎŠð…$–U'ÌùökîAólíwG(öI‘†2¦ ~Žma¨’0¾—NôÜç YÑ”Ÿ T°àŸ àè ×Z'm&\c›:aMtZË•EºžjÙ)J©PªÃFv Áª‚@ ’Dë‘€ÜÀo07éj:{œ²㢆G=j 'æ ®+’Hc–Ž`pÀÔàƒäA]((Э9‡Ý¤žQ«ÀÆì PH!€ë‚ ¨öŒdŒ9ØÐŬŸ± å¸ý'B÷ò9$ùþ%µŸàì,?IÐÇŸµÉî?¦•5ÁO§Ô~5¾'Y®ëÿ—T~5¾'Y¯z/éECÒÝ‘oÙç±°uüPÑí9ûI÷h²/æ÷‡Æ?ü6Õ ÓýɽÚñ2õ%åûeµ±q'ž?ůÃBu•)i<8*ˆ½zÓ3t¤BPý#ªÙÌ4Wr>¼Š^žíÞ­tWz'£¸ÁßBÌÅ«£ ° À‚Øë˜’T6N[uv¯i­¶©“˜‰Á‡ØÞÍÖpÕÙÔ ^6â šCYá$ûÉ'Ì3ýÊqr8ööOŸ£Ñÿ¸Ó´œµÐÁ“Tȉ)iYÈ  ÉÎØÆs ö[p©«áèûã!2!/žnLžPs¾qŽºHðEExX¯\KwºS© `˜ÅlAÈæ"s›f‹(­ð[é0 U`47`Cð•B'ñŒržZçZƒ›«QˆØ_0&3g ê4SAQ9¸Ó­4ª“Gr0§Ìçmºèvñb¡¹Ëó¬ÑUÓdÓÕSÊcš,ã 8 p2§ àd DVðÅÚg&>5¿F¿Ñ)JI‡:÷ˆ*eŠZzv/$pÆQ&yUÞS’I8''`Nq¡<¹¥/ÜË¿+¼%`îf?sÇ´>ÌN¡ÇÞ”íÇ7ágýœÑpDYeÖéq»MÜÍ\€„ó!ùŸn‹g…ª§¨´SÉUåG1:ì–­[€Ö•˜ …%ƹ.iŸ\TµLŽKxúÊÈAñR¸Û!0$0£(C÷>¶VÜZç•¶û‹ ŽJª–…äQÐ8WÆN9Á#Ã;€WC<’M$qO1Œ‚¯(ŒJ22ŽÀ‘æGMgW$·yZ)U×’0B°p„ C ›c>8Õ?W;8ߊ@>‘ ÿÛÖ“‚딌ñ¯< LCá‹AC®>»˜…ª’óZõ¢DPwƒ“ìÉQï#ËEPHÆ™Yö$dý°p}¶Ù;U—©««r ÏU3K#c ,I88x¢7PÐ Ø bØßÁGÞß¡‹ûz’{ÃD¶¿½gûOáí:¿µËî? Ob¯¯#Óª?߬×}>£ñ­ñ:Í{Ñ_J+QénÈ›ÎüÝOúµÑí7Ü»@]ÿ7œ?ù¶¨º=§?j>㯠/R^_¶[[·#ë ÿ¿ C\+E9§"yêj¥îéàÒ6 ;’I$:˜¹ï"~-~ »Ü"³qÝŽç\ëºZZ»kNÇ ó4cÐî]>.£ÇQBÇšKtoâªîÀaåú¶öÛ²B• %‰ÉUrGP5’ËÉsH]îTSÚ#JYj9–¬÷pȪ Œ€¶ëâIÛN‚ÈÉM]-;M"SΈ 8›œÔ…#| ð|;k"«‚¦š9©äI"u ¬§ ƒ¸#Ln×Ê;-—;BÁOæfn¤ø:’NrH®…{&ôáÃ‘Š¨Ú }eˆÿ{’æ6†¨,%žá4×eµÒ-exˆO7y'w 4DW‘ÌA  H'CÕ·ß^DŽ9­™€US’vl3¾ xf©-üoÄtn"žê)ªè]ŽñÇâSâQr<¥ÈñÁ]X†ãO!‘#ä•[Ô²©H3×B@4«´ñ5#ªÔ›D|à•æïF@÷¤e©ª·„{œt«°A=<Å‘XpÊ äÀ$’»ÏJ‹J±3UÊþÔŸs>·©ì'Î=™ÐWiwxixFº‘œ5U|-MK>³HÀë…ùDørùãEhJêà ‚‘Ðý%ÖéyºÖRpݾ–zZ Œ—ê–Š˜LQFiAÛã$‚4§ ½GØjvª$¸Q’z!Ùt¢“„šÁ3¸Û+jý.2}gÔË*LW(Ï¿C@µí›Ú›ûoñ:¿}ÎLy†‰íŸ{ûoõŽ…ï¿s{þ2¬¸Ÿá Æ·Äë4Ȳ5?މÖkß‹úQPô×d;öwÃÿ› æ.iöŒû´ÙóyÃþËtýèòŸîgݯ/R^_¶\[·º'â×ᨊÊZzÊYijé⨧™JI¨OPA|Ž¥îxçAþ-~‚¯«™jémô0¬Õµe„jìB"(ËÈäB¨ l2IP79ÔPÊžÏ8ZU %m* ‚S\ªb@<‚,€ì 6þæ¼8 <×ÿ¸«ÿy£G¶Ö`¾ `71Ð…R}€¹#ç'KÕpõΞ&œñ ¸Rc‚'Á9 `?:t}»³¾§©Ž¨ÑKQ,G1½UL•š™àãÄcEPÒÅMŽ5UP6Mªb»QÀÓÓÕÃsîÁf¦4ÝÔ’Ô#‡#›'lŒç]Ûn”wKtÔ3,ÔóÆ$Lj# ýH.–Ê •/¢Üh «€0`“Fg¡8#x@Õp5Žy †¹ÇŸºTô 5'QWs¸_^Éd4°½4)=}mTfHé•ËÑcKÈüŽ@æI;€^Å`½O­EßÜnµ?ï4öÕÁv::“V´Í%Aïf‘¤r:㙉8ögS5|9|¥1—âõdŽ–è[?:kY=ÂÇÕ\ké®þuI&Ž˜Á$0ç`êI‘‚2 d‡¨O$aU@l G×Ú­õÎUJ’K"9FVD¨0@>@éûJ’(d!èAØèzÍUyâzÊÙmUTÖ«KÒzd´æiëfC‰JHT*\óA2P jx.Û$……]ÙA9À¹Ôcëé!Àö°w¨»7°Üç?úôU\*OúáUD†IèàUU ŸPž¤ ë­ÔX+hêLSñMs•ÁÊÓS`@ ƒÈ6 ƒóéêM—…m²^š•UØó3É>dÉöM²òŒ ¶ÓZÊ“l0 ʘåŠgîÒa!‚B°É 88; ²è°aAi1kûÔÞ'þ±ÐÅóä7ÏðÑ5³ï[ÿmþ±ÐÕëåìÓ@Ê‚èßÂu[ÿ~¬ušFìøºÕþîÿXë5ïÅ}(¦zŸ²AŽÏ¸| u9úcC£ÊoG°è ²æìöÁì·Sþ¬ Ó}ÌëÂÌ«$—íûeÕ± slCþ-~¼Ö/ÐqêÆÝ5M kª’iÒf‰Öbü¡¡ Hè'`H.¹¶'âÇÃQÜ»’zêC1{¶MËOr¢š'WIÕ•èAikòØðQSÓWS4qD^CÞ™Xžlç®P¿ˆ¹ð‡ \eik¸zÓ<¬r]èã,O™$d2ýÀpjG ÙÁTQÿ«NÂ…øƒŒ-:CQ5dsT¸Rà y§E$“ãÐ ’@ê+²Š ú†:ì Ë(è ÜìÉ8Ôí«…,÷/Cg¡¥$`˜`T'߀56"HâåUc`47` ÐÖÁ`âk±¸È´ôW–‚jz§8f;¦…Øì¤€Œ¹Ø’àn$vëÅ=ÒšyêÅ¡˜¤ƒ œŒv‘xÕ”£*²°ÁR2ò#ÇPU|ÂõR™&áû[9ê}2F„èKÝæ†¡h㊲žy"GIwq[*`ò@ÏŽ3 ^Ñoô†ÃYb¦*.Z`‰ƒ2+Œ`: ž§i÷î„ÇN¶ÿlŸêÔ¥¯†ìöð=ÝOŽ  Ø(oÂñOš©,YTg:à+…/Ú›„n’¥E%eT”o3JÈ&æWF8‡xU—¨+œ`‚Jä@4Þh£š&ŠX’HØ`£€A÷ƒ¶ Ûø‚ÙMQ's§Š)"hÛt‘Np@e$ddxvoyâ[]uÊJ„¯¥HùR4敪H$Ó8Ô-GðÔ²k ´“ÔŠdÿV“N á¥Ýlvàs±È?fŠˆ^1¾Czj[5šu«aR“O4'™# œ/0ر' ;sŒ[•ÒŽ5ž` |ñ¤¨-T4`)£Ñ =$ʆìiP/l?ÁÒ)ë ÞzŸìѹ±A"ãnñþ±Ðåçåíýš™L^>ûV~=þ±Öi;Ë VþQ'Ö:ÍhྔT=]Ùþ/lAœ~,hò›t:ìƒÜòÁû:Ÿò©¾æužÍÔ——í—ÚBÝ?ý±¦$m“ƒä4òíò¢>1ûtÎFP$I×5°W»å²ÒÄ\'0‘Nó¨(O:«¢¸±i7%†¤B’:cCœC‚ñ[lš¢áË-RΆÈp=ÛT°F#͈iª`C"¸¤0\ާZ‘¹F:vùðFs“á A-u¬ÔuÒ[¨m°Å-ªS4)cWÕBÎÄ@'"b›†h*ªá¦Ž²ôÒJá5Ö`2|NÏa¡á%Oq=Ææijj­wxà&š#$”³ÂC”PY£t` PJ”ŒBÐv‰ÃV»œ½Ò ÐH££¡ u+qŸ 4Ýo Ú)ã‚xî7‰àœ7vâéR¹*pAý ûAÔuå–ÇmžçOUU=52™*`©“¼"!»:9Ù$‚H 0zÇVöÁóAKIGvU‚˜9@ÅØ¹ç Œƒâž$Ž÷j¨³XÖz§­ŒÃ4ýˤqFÃr@É Î ÉÆ74 °âž²*ÈVhX20È#Ë]çm·Ô7 RIClŠÉ%5. 1Ï]µ Å@œuÎ*§«·ÔÔQ¤I9㈾Y˜Žƒ`3îαڣ»/Q¹°›$Œg=¥D.µ øCˆ©xŠÐµ´á£pÆ9¡}ž)áF50pUfU†.Óøš…÷2¥5IPvcˆÜ}§W\-@šgW¯ŽšU[ ˜óº–9ñÓâ¾9ÐíGPÅU%STwÑÝb·õwï0£0óʑƀ%®¬JzéU·D„2®]2~&±­DQz\Ì$„Ì$Jiå…€$¬*"ÀÆå€ë€eèª)ë(¢«¦”Iª7ŒƒÓc‚=Ädh•„Ó\È'9'¦œrê+‹$4Ü;pœ Ó>>Â4W=WÔÍ4µSRpü2¡Žä’µÃnª€ädnN@ ‚Kiì\3Ží¸jÇ)lŒÔQG3¾‹¸,O´’u ¬ÔöZHàˆÈb¢B±©»îvÉ$œùG˜êçKU=YbŽQ@–-ÌHÈ0>M" »ú-]Í ÷Éæ{SLZž¥GUŒ1=Óù`„'b7Ȱø:ÿEÄÖ.Ö÷-£pFÄàA؃Ðíá –3ˆ„“DÐ1b±Ücôoú5Ø­i§ãÎ2³DÙ¦j´¨EðGtøòË3iIPâÛ (?’Íø×úÇC×Ëxh†€þö¨ükýc¡ÛÆÅŽ”Eûïåå2}c¬Ö¯ß+ÿ)“ëf´p_J*¸ìcù¶áÏÍ”ÿ«°i÷MWÝŒ6ü;ù²Ÿõk«˜ŽS¬în¬¼¿l¹µ¨±#p#9ô6øW‚°V5šqÉI<ÒOk˜ìŽ$c#ÀO@èåÈ(F3ÊØ±ûFNû‡ª¡ÆÏLAú›ÉEI]lj:Úhj©åP)P:60FAò |Ô"è° VOI‚wÍ—PÁ8ÆèÔEòëIk£zªÉ9Tlª7gcÑTu$ùh²çÀ”Ì·]îÔ+á˜J¸Ê®ÃéÔ]·³:î+]YQ=lëÒJ‰ ‘çŒì=À©|ˆüuÔŠì6Í]-ÚóÄwÊOZPòõ2@\øà3ãŒêâBU@=q¤¬Öè(m2,H ÛÇmac¾N¢I r7нþ.¶]£ª«‚¢{¥F$Žž™^Y¤ :KžEèÑrÍ€2A#;sž`¼ÄFu]Á[4Æz¥’8ꮵóTÌê‚ Ã `‚Øœd¹êIÓHöŠ>DJ+êÝ‘={ŒåaDS"3¢ãÑáå A%RNNécŽž’:xÆ% £l@Ð5XÅ!™§V›¼§g&u”‰£u1 #ÞF ǘÜä‰.˯“ÔE[fšG˜[ªä§‰Ü’Æ r€“¹!HÉ P&œŽší™8FâÀïÜ7ìÔç9ýz‡ã…G WÄ 4€€¹Sµ HûY‰¼ð_xcÄ|ñZ4«J¢XÈ‘º1‚“îÆÒž*Š ñ¬‘°VCž IË+¥u ?€®®>bàŸÓ©)q°7ˆ¯T¶Š#<äÉ+HaC—™ÏEQâOÐIÀN{±VÓTÝoWzU[‰%#§;Hð€=€jFÕÙ¥N©–ZªŒ`K<…Ü è=ƒÙ«"Õo†‚Å …Us(ã®ÚMØÒ Vƒh'ã¤úÇC÷Œå½ÇD_r¨öM'Ö:¼ÛçÓ†¿gìå~ßá2}c¬Öï­‹Ýx$dTÈ?Î:Íh¢ÚH§HõÇc;voß›)ÿV5`Sn§U÷c_ÍÇþl§ýZêÀ¦ù'YÜÝYy~Ùv?jxü„±ÔÈÝ™‰ùÐõ}îxæËJBÕiÉS<À˜iç—˜ ¹Á!IŸíy¸v±NÙ¥Õ{ÃwÜ3M^Ç2ÜÙî7‰21(Ÿ,b4ÄQV Ðúi*XóMwºT8èÂaåˆ(Ç¿'Ì)Oz¸Ñs$·—vŠDQ0% è‘“¾8ìœIJÇÌŒ»# ô8;ý:ÒT£3 u ܾ°ÁÔ©ù=Ë.Át£ºX}*Še–)X:2ˆ#c­žšªû2ºIGÇüEdV>Šâ*¸tFà{ߘüúµ NÄæ}šºÛ*(^~ê†Zª)$y¹Ny .Åœ=b A\IÀGG®£/·Ë-‰bk½ÊžŒÌH…³$§ÉÎ}€=ƒr®­¹È%0Z¬—*ªÖÄÔÒÃ[`Ϋ„>¨É>^ ³³N¨²Q—«c%LÎÒÌäcØ’Ç$íáÓRt|Q•U±Óýõ7,I[O-+H|J«Ì}ƒ'D@ cæÑvuáã¨Î'q×HÝu&F¢8¿¹‹‘n‚™Éᤄjî2ÇqIÝ«¢ŽòidŒA˜‚2wÀU™&%¦¹ÝäaÑ–°Ãòb¿H?>”©¨X­ñI#QšB$–ìp7;“äÔL—(Ìa–*€Îè:{³©¤AË]þÎÞ,Hjš¢kÕ¶1ÍQ±¨«…WŒ På ‡À$3a[.4—.Zš)ãž XI£e]J‚#¨ ê´†rè*# 9°ÁÈÁ?¤{¸=7q7 ©ýéGX%¦@6%Q/  ðÔd¨q•„´[GSøçúÇC÷ŸÃ>ýQ}Ϋl}ºO¬t?yü/ŸLlóבû£¹ïþ/×:Í6âþ¥º~Y7×:ÍiྔP=ØÎýœpïæÚÕ.é¾IÐc?ÍÇxSþ­tMòN³9º’òý³Ð_j¸®”VPIJIXJä#?§U Ï%<¼5V;ªÛdŽ#S·yN\²2ù…æä>\ ìf빯1Oì~Ó þ*á:ãG3‰iêâ<ÐÔÂydŒã{6 ìFĶ¡A%`ÌÕR+ üΣnUé 4•5•b‰K;»`(rIÓºîã(”­ÞÓT£`Õ4Œ¯ï%}Ê¢é»3¼Ý«b›Šï WO‡T±á$‚Ù$œuÁ$má©|ˆ|]ˆv7GUq½Ýxªhž%¯‘VX`ˆcRG†@É:¸Ôú£}6¶[i¨i–(UQTtuœgQ&‘Ä·Adáú뱄ÎÔЖŽpe3áÌÅF}ºŠž‚zúꕨ¼ÎÙ ‰¼®zÇŠÄʃ“’I$<O=G Uµ24’Ó<5ad¿s2LTDdiâØÅÖZ–E‘IÆÀìàƒŒh9Ò“j-Å[G~çš0Èê-êÿ_÷~Û˜—Ê´3QÈ­<2)SÕF$ ‚H#Kð•õ­7ßÜÍTÏ-$úEºI³ª‡„“»r`ðê $F,–ùbªÔ@ €3¹$cöé•l­[ÚE² V'ìu4ó°32¾ð#ÉÖz†Np¹ªeŽe‡‡ÁŸáÃÊãK½ÓüZß·óEæ®®—ptÖíLµvÚŠW8Yc*}Äcöë»yaEmÎ<´·(pA8] {O$±Ó%4ùZŠUÈ3¾`0öþy×UÎÓ8ögE·¾§¯Ä‹#C:Œ,©±Ãæ=‡B^â¸W d‹Ð ~aï!€'ܤ¤»”[#owX(h¦®¸TrA–vcÐ/2|Ü%زºi®¼Spá’éPeX›ªÆ6@} >muoìÚ²åu†«Šn‚¹a`ñÒÄœ+„ޤi8ð#Vµ $T‹ON¡T1Ó¦“v8Æj?¹Õñò}c¡ûÇáyo¢ L«ütŸXèzóò_Ý¡<íÄ€ž"¹årøÿ\ë4ÊHýÓÝ-›ëf´ð¿Š*žÙìkù¹áßÍ”ÿª]X4øäÕ{ØÉþ.xwóm?ê—V 9õ»Y¬ÝIy~ÙmlˆšüöiÔ]Ê® }¾¢¾­ûºzhšY[€I?@ÓëìíOHóÇO5KÅ 8†Œ«’N02@É몚¢á]Ä×gU®•-‘È—…eviQG,‘±C…uÁ(áиœ°^ka½ÂJ.!¯šõ,“Ó=-º V¥jJ”`Füä úÈÀ†GØ‚âÓÆÜ1u­Z*­$µ ’±¬È]±Ô…œX­oÅO ÊQdSRò`UN\¦qÊI F0 ! mñÀ¤’Ðë_PÖÊÍÀò ``:ÆéF:H ™%dnƒæ ¨+‚3×:ç;èC².!­â>¶WÜc Vð1 Œ‘±8ðÉmöùô‰ í¾„¯-S<–ŠdÉcERŒrJ:‚PIÁg¦51[¶SNiÍG{8ë d{‚GÏÜ{KáÊZ*ŠÚyTª¹SÄãÞ¼å‡Î43r²ñÜŒi`¤µ[”œÄïPÃ>*¥gÈ’}ÇSÜ ÁQYг»Ë;’òÍ)ËÈç©'ÄŸø †ºƒµN˜ò}—³uÛxùƒøè’‚ÿo«fÙbn’ìñŸòЕý:wbДE Ž€c] ì׺ȪÈÁ”îH a×OŸ~È~ â‹5Žxà¸VG²TœÇÀÉ8ß|oŒizkͺªÙ= Zx¡Ö!ÎøQ’ÉÇ€ß$ W¼ȼSÅ5•MÏxJ僙¾\TÆ$pÉZS6qԠ䀮47Jˆ¾×R Z!‘$Fæå NRQÔ¤l2FFAu¡•hLðÕ}}Á¥’ºŽš‘\ )áYCÈ"$€X‚Uƒ Pàd®årf¼|5XÛ£û3S%ÊÑM %ÝȤ­†HÁ08‚Í’D^³w%e\Y4ÂU‚%¨ey‚# –ÀÉÀœ "V R|š¼xO'Ö:€½cî:Ÿ¥ÛÓ?'Ö:½‡÷i¢/cͼRë=×òÙ¾¹Ökž(úËtü²o®ušÔCíESÚ}‹ÿ7;áüê×V9õN«ÞÅñqÃß›`ýZêÁ§ù'YœÝIy~Ùm}¨ˆ¹ìÑÿcövF:Z%šr ׈r4 `Hß$ë°òÑõÐzÑÿcö@_íT÷z#KT¤¨!• ©#pwê#Àƒ¾ ‡D»ÛÒÜ(f MKõàHò² P˜I`)ù œd†¨k+.½­q‹ÒÅ+§Q8IÝX‘PÀì€ø¨9$Øäœäf¿öspºÂi¿u5qҸĊ!A+Ôs€0˜ûNˆ¸[†­<bÔÈSÁ,ÇI'æ:mÙ¨ê¶p¥ZgJzxT(nN0rO@€îÊt í¹>'RtòÛíì¶»}5h¤ˆ¨i–<€:€dè.çÇÖ–‰Z–JŠº‡ÈPÆMBpVDüAç dlN™RUñÅÕƒÒ[-ÖèÎãÒäyŸМ sJÒØƒM–UÕ•ì’°äIS|0zàl}£Ã:‡—‡8~JƒUK@¶Ê¿ÿ5msI.|ÉýÎóQÑY»@ùqÕðõG‰àšÿ”ñôw5Òáf qE¢kLDàV,‚z2s™@3þ1T{N‹OqSZ’t×N"á¢ÕÊovÔ¥–8–:¸TnKƸIÀ’ÈX¶êøn‹"ÿê årýs¬Öžj*žÚì_nÎ8{ól«]X4û.«îÆþç;œãìm?_Å®¬byN³9º’òý²ÚÙ÷CëGýŸÚtÀŽºsÉhÿ²~'L±®hf€Û¦5_öÃu¨J:{-,µUr(€ä¸HãpF\Ÿè«Ÿ XLp³UtÍöKµ–•ÈhíÑË2çÁ£D‰ÓS1÷ >’zë5¦‹„Ç ÔD+hy¨i6iå'æ$n¹. ƒŒcÜ=v¸ÉÄŸ¸ûÕÜÕA¦;aéÓç”$€t”Ž~„o±hˆ'%È-âzcUogA®Sܸ²rÀÖLÍ6Å!RDkô ûÉ:o±½ËSŠï–ªJŽšš’§PÔ“Ôù“¾„©/p'sù£tß¡ Ž›Ž=ÑËZaßWŽáë‡ÃBkbT,eùDnÌK±é$|=GAz+t¶Éª«««Âû]O¯ €@9Ä?%=Rw9$bÂá:ûgð umš†ãJc¨Çƒ®Œ<ÉÚ5Zp”u1Xg³VHòÕØ«fµI+ V" N}ñ4g>':QÜ”®Ž8FæÜ7ÚÛ$r-WÎi!RvŠpGx£ÈÊãÚÏà5mÜ‚1æ5Dö†;Ü#ÈšÝW JÔqüÜ’1ù†¯ =RÜ-Uãü&%8ó* ý$èj˜GT:Ír|úvG·\†‘.À|í•ß”?Äè~óøZž€ý¶·ò‡øA^ MìyÒõH²^+\°ª$;ÿhë4âô9o5«Œb¢AþqÖkS qNû"­#Ø=Œâã‡6Óþ­u`Óü“ª÷±‘ü\ð÷æÚÕ.¬a±Ç—]f3u%åûe¸ý¨ˆ¹ü¨ÿ²~'M:iåÄúÉî?¦šæ¶')õNª~‘Û‹x¦P¡åŽíIÆI©©dôÏ"oîÕ±7È>íU4©è¢Ü©›eªŽ`3âs¨¼5Aÿ êKq=ˆî.‘ð­Ú¦r¢¥iª ªb,€ ÜïããìÔÑ…ì®ãh¢9óÊŒèÒísóÃ8-©GjAôö5UpUOÕȶÛ$´®:2a^R·Mî(ê…û3Âö{f ŒºJïý¶žBùùÉ6Œè5-ŽK„”0ÖÈkIK…Uä,pƒ–Æ'lo¸àÙÑ]YµŸjtšZ«~vDì^DÔrÇNèp_C_]BY¨ªžäsrã‚H8;ddàõ8:“Ô!â5¾Ûk«’–S4Òžf$Æ‚wA3 î@ ƒÙ;ã!®ØRFØß:t+kULWMœœ«çœ0rsç¡þ/¼ÓXlòÖÉ™d‚ò¦”ìˆRIúOA©lˆîô ÿè¿#ËiâªP?{Ó_ªÖÐ.N¸“¨ÉÕ×»EX À©¢‘02†‰s·™åS£žÁxb£ƒû-€]ˆ[…k=e[1ÆBXäû3 .©7 e߉؞[ýÖzÚbTƒèÈ2šD{jÜé-3ÚJœwj¾U”Ûå8B  mú­NÌŸ³û1$š@7ò @ýjíN¨' ÕÜÉW$tÈbÄ–Q'?© œ±P¤ä²ä NöîµÑ[m–ô«¹N¦: È@ü e˜ã  9H·dR¡n,àÚ$¦Y”2̤I±9GGnóÐr24'-§m¹‰¨é¯Q®ÂTSÎGõ”‚Œ}  ö :ø¶Ý?¥Û¸¦:ª·%ªhëiÇ 9'ä l_ A;è‚‹´ È”-ó‚o¸ØËn1WÂ}£‘„€{РÑ^ÇuÜÐp\‘HvÖ×Ĉž#.O»o~‹û>왡¾ÁÅm_ÒãM5däAßV}GÃß°w8̶ŠÉÐLO)Œ³dÄðNNTùœnÇÚè.v™-×dŽ¢9‘Š0 ѱ(¾ ̺õWõ”Ʀ"^èïÔQÌ’ °Ìr.åsñËÇACC{µßknPÓ€­Hãš0ÀT"Æ0$9nè•l’rä€ {%{Ÿñ…GI4µTqÓ-U#¹Ë™˜'Ìo£Û«¡àI¡å’1"°Ü0È?6“Ð žÝx£®y#¥¨ ,GÂêRh“ÆÀ2aO¶C¬R¬rB3 €q±#ÄgE×Þ²^B ú(f1ýÍ¥Nv‹û³§ÌÃCµ]˜H âÅð_Lï€ÿù’CútìÇð5оhiªeÌÎsÉ€ ¶øñ'ôcÏL.W¸éàyê*ežG  y’NÉÙmÎVûo]Jy“ó¤ þ‘§VÞÇøb*„ª¹5UÒtù/U+JG¸¹`>`4X|%q_y¸q|sØxbÚ×4­C •3D})Ø•ÈêÀµyðe¡¸{†i(&äzÄŒw®7<ر>,|OÑÔæNÕn µÓ÷4±S©ëÈ78é’w?9ÔgÖËm°VÖÂ…Ú™öìÿ[’ª;_㦰ѭ¶Óûæó\ÝÝÇÁõ¬8:j»ìDîiÃÙÿ³áúº°à;kŸ©//Û,ÇdDܾZ{Äé£ltêæpËäÏÒtȲõæP=úæ1òÓCz¶ËAp„IƒÀÊŸ1ŸùêRý:ˆÄµ¯ëlW;2ãÃq­”¿HеšÞÙÇ2îqò†°2ù§þa  kSCD ¨Ž®¤mò°ºÃ_¤k]äcðÓ?Ú†Ãzáµôeºžén‹>ˆ­RðIøEêÇ uz¤.9µ/aáú¹n){âéëqKKñR¯³9Ëlz’ðP¤ÝìCmAŸë hÏë4ùÆØhvÚÛlt‘©§yâÿÎ5¸æŠRDR#‘¹å9Æãjˆ þPû|ú»g-©òs_p#§¤> nÇåi¡=?ßþÿ\?*“ëf³ˆ>ÿ\?*“ëf¶¸ºqð½"³Üõ×bÍ·~oƒê XPôÕw؉þ-¸{ó|?WV$5ŒÏÔ——í–c²xÖêg¡§¨Nò^FŒŸUÊç”1¿Cã߯V[1Ž9mQÔÕK–Š–––7•€8fõ¹UTdzÌÀo¾x³{ÿ‰›ôªGŽ¥ž‹ˆ«j% !«††_Á">`cöÌXs媹§(AÊ*ËÜ¿‡‡Ä,y%Q}ü+'ß­ƒ#÷\µhþþ·XT¨­á™íðŸ•S,T²GóaŒÀyžRSª¢¦èÆC†;i¤—Gˆ‰ñƒ·™ö?wŽ©./-ìj%È84ŸÖÓòGÀ”3†„çpDAsÓBuümbŠ¡â¡á¹î‘+50SS$,GP†WBãÚ_"u Ù¯Ù*Ž’Ý9x§z9bƒ'2Á¹|1‘¿³CWŠãK;S¼~ŽÑ€«^^ìƒ΃Ã^¤UŸ=㸙põðWwýïÇ6Ñׂ«1ã‘B?÷µ)ÂüKÃ|A<Ô[–Šº$çzJºXÕÙ3ŽtdæWPv8m¼@Õ3=ɤ8 %e¬¬^-µ=– ËÊËÑc*C}¤®Þ8ZrŠJì«Ãqù²åQ”t=qke1³[c¨šwî©é©èÖI§|ÊŠ€’HILåû2…ìî¬íŸZ{hú~Üw÷m§6zŽîëGqŸÕÅÔâCýíâo›˜&3àFéŠI5-4.aÕCÈÉÌAØ•ußm0nÓíäð•x÷¥ûÝU÷7ž…ÅLM´Ñ¬F&)Ê1ü6ë¨Ù*˜“ëkèK•ðßò“oÿ ärånôEùœg`â*§£‚¨k•;ÏG«§Œ4ˆ1–FBÊÀddg#=4[@ÑÇ]LðÅ2¡äP Vصå»=Egî†ØôŒðU¬¥”|„Á OÌO¿^á™Þ_BiF§‹ëkÆã0ÃW;Eˆ[Zî&¿ÊëößÒã¨+°9mN¯òˆ6ýðÿAÝú¶«¢OcÏ÷ÿ¿·ʤúÇY¬â¿×ʤúÇY­®.œ|/H¬÷=q؉Ïf¼<2?CõubSôÕ}ØÌ^ÙÇÇ&U…¾e#LãGÑHª¤’5ŒÍÔ——í–c²8²’jŠª9¡ Æ á9•ƒ ³·—_ èj{%LÑ<2Ь±>Ì’¨¥@±Rà¶%ŒêÒWŽx»ªûts=Rí#üý™UÕ$Ž8Y¢”–BA$(# @ Gà禴j§Áe¥&1•˜·.2ò§B7DH> ƒ·ŒŽn)ªjÊûû–[ƒó-²¿ôÓý½?¶ð4'íè£Ï«${ÿ£š§’(¢dd•Ì*¨u ˜d÷dyo¦ïW:#sÀÃ*…i€Ü†9ñÆÊØð'lçFâPŠÕ*"ÏZ«…€`m¼±ø•¨šþ§¬—½’Ý9ë‡Aÿ«E±ÖTÉ¢wY¹Ãr/+±m¼.~|Ž˜8*¥æåx£„ý°•’B !eüë0™[#®Úƒ„dí¯Lè§(ªOø`JösFòpLgÿV¤é¸fJ0{ªuõĉþÖ‰D³²SÈ"@“ȱ!f –2˜ù?'89ò=6ݼ•’,ÍrÊcÞ“×`GN›ùäxiÆ *’þ¨R““ú›ÿÐvëÂésŒG]o† (õL… ?6 Ïf6’sö"›éOöµe%°ùH­ŒçPq­à tR—g§’4€KgÒÑ´QSÅãê”·D6ÛDUDò˜R8ÜH}|³Ü†@ÎOA¶¥Ï_ pzƒá¨¶Û¶:üÊ?~Üýáþ:ƒ»õmJµe:×׎ðÔ?O~¡nÓÆyˆa¦¶"ʈ~ÿÜ*—ëf³ˆ7ë ÕKƒþYÖkk‹§ Ò+½ÏMv+Ä4ÕÜAEPSD"§ ðÑÿÙ*7é׎»'ã™xZ±é'ÃQÎO¬½±Æþìxjø¢âêZÚdšž©a‘‚onzdyë3Ì89`ÊßfuÅ‘J!Þ¶½fPÔÅåLƒî ‚4Ñx†ºŠ«_8ó‚@CñÐÙ¾$’Ãý)Ùðõ磥ØM[i½"œø‰!8úFFžÓ^muCp¥r|;ÑŸ£BBº'Ý‚Ÿ=†¸‘h&l‚2?³ ,=YQ·VSŸo]t[|çþ|>'U× ÛÇ܃D| 9_†”XdLwWJä÷T·úô–z{:~ÏÙ¬æþ·_ùç¹(õ/•ƒÞTüF´j/@m~¨ÿÈŸìè°²À×ùßZæñëúïŸW­U{9ÏTòý#$×Vù|AX}ÅGÀ e[|“¸?FúäÈ«’XŸU„«Pßu¼ÜÝRÃàF›IEBù烙od’³|t–MeîÕKü¦åKß…0ù¼uSÆÖ½Xª$©>PDÌ>žš Û û}UÉÈñ¬š'%¾Ç¢#âXÛ” O™Ó…¿¥€Ç_ Qö‰eÄ#½|õŽ/KèñýµþHü#¯#//XÝ)c–ûßg“/ôë–¾¦6qôë\#2X£i!Î:²ƒ¤îôâFÄr y²U&Ž«SR_Ptq¤$¿¨ü1¥-4ôï0ç‚&ßÅÖv©KM´ÐSÃ××DºùÒ4Þ[뻲+3òºe~|ãUÄLÓÛ¡3±”ªË‚ç›'ž…–I;Æãã>zö1rò]Ïú9K-v-Ê®%ÑêQJg˜Û¯MDÔñu'3æ¨ôØrÌ~†«—fgÌO¼ë]Çȱ´›9ˈk°aUÆ)Ý’©1`NG(ǰg:…®âjúž3c±c’Í×çÔN³V×(á±;«òAç›7WS]X¨¨fRsÊ6@ÒQ«×})¬ÕØã„WÒ¨æäÙšÍf³]ÿÙvdr-plugin-live/live/themes/orange-blue/img/info-win-b-r.png0000644000175000017500000000073312650773437023561 0ustar tobiastobias‰PNG  IHDRXþbKGDÿÿÿ ½§“ pHYs  šœtIME×/ Þ;hIDATHǽ•[rƒ0 E…dÿ»èúÝ$Mú €ÝyæV‘=¤ÕŒÆéZˆ.o¯™Àºþð ŒÀ7ð \€7à œìþ¼_¶wnÀfžÍºþð$ñ°3°ˆ—õU¥H®‘åÁ2) €&»ÎZìÙM@I€ê¿l°²uó*AgàjÉŒ®:•'Á³} M*™4É9¬’TjUS@gɪ¸V5JS”êf‘±&áèd)´XWƒrv‹k /[VÐQ6eiŠ"Íâä+ íD_Q(ÝÑmðMQ|–3š¶:XUº£´¹v_D®„Z÷•3òTÂädŒ¾§-.lo\5¸N\]uµ Qý–›cQ·dÛ8Z¯Ž£ÁÚ6²T¦ Ë"ÈtSkt3,Uu°¥‹Eg’É2˜Þì€Ñȼ 耞¶åë­ÿ½ÁöX~pýô˾ðÄ?Ù–<4ê2Ÿ<3IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/zap.png0000644000175000017500000000155112650773437022146 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<æIDAT8mSKhQ=ï½™4“&iú±ÅVÓ´I[¤â‡*hüW[èÆ… B®üB .‡j»qQA7n\H‚ XPñ¢¢‚  ñmSS­1µ5i§Ÿd&ó® mlÐ.‡{ÜË9Œˆ°^wgH%o— g€Ãé‚Á²ç6ËÄ,6Õ75}!ºpžÍ xŠs•|z]UøÐÖë–U‹QU£AQ†£s|gàéËW£Ñøû+KëÆÌ%™ðŸà*»iÚÙ×Q«:Šþ‡œE¸Þ?h=|yÿ±É~¶3%UúôÕÕ["»ÛWªNG¤µ³3ãI+_MÍ,8±«m…ºuÍ®ˆ*}:p¯v2¤ÑòŽpدþ³0ž4QV©b{{Rã&’jê]6º`Y„‰¤…††%ª[Tuxµ“!á{zÊåúvŽÁ2 “©ˆ€µ›¼˜–ûnbÿá%øü)ƒ3G†5!%0•ðú kTU89 _‡3x@JÞÄÕÛ ×|}hX_‹Ï?ž!=Y‚Ý­{ñu$ÕÁÏ;œ9Š Í?ÿ$ƒž`ΩaNTâèé4®^…LŽ£ÿÎe ¥JAn7,ãA^@æW ?îÐá¨ÞƒÚÆPßrpΜG:úô¯ÀÀmÊ&®jnþgÊ•c[ÛÎΦl‚K2c;O&FâÈårÿõÁ—á‘|O°!ÉŒ Ûð  ö"Vᛢ‡˜˜50øáˆ®bˆ$Þ¾z»7nãÅ£çà™(*øòc Z@IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_header_h.png0000644000175000017500000000020512650773437023556 0ustar tobiastobias‰PNG  IHDRí•tÇLIDAT×mޱ €@ /Þ4V` š<$˜æy ‰Æ’ï\Ü»Uu œÈÈ$âNùΗy ¯Î×¹!(DƒbÕ¨Ö=¿×4AÑ {Æüqýy£áÂn.,°MeqIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/info-win-b-l.png0000644000175000017500000000152312650773437023551 0ustar tobiastobias‰PNG  IHDR0bKGDÿÿÿ ½§“ pHYs  šœtIME×.ªÎÑ‘àIDATxÚíÝQnÔ0ÐëtÚìEì‚}@Û™á#vç%)¨4E s$ËÇv¤þúö¹eÖJß’LI®’\'¹Ir›äc’»$wÇý·¯þ íB?õ¶Ë¸ííSz@ Éç$_z[?ßõ¹Ÿúº›¾×UÙ{ýMàíG¿+íÌ„Co™öät¸?ª œ;ä?ô=ÆÚ‡Ì!ƒ]NÁ€ÁØÚS8ài óý8ØO’}æýûœökŸœù¥¯Á€›,Ãu€lã˜Ì‡õu`]=`òïûØ}«×ÊÜaŸ9ðØ×\—Ö2WH`kÏ*$Ï«´œÂY†F `Z­á€û$·½írþZx[õüóÒµëëju€©¬©ö¥¿Oò=ɇþëÌ®V{ÀvÎVxz™ç–¹"@Êï17}Þ!Ë`ÀMæ`À.s0`Ê2\lè¥kêóÔê)ãã]½NàGæëF0`„’åu*À†.U¨CNÿé?#0Pç3“Bð—µdOà•&ø¿ýíÀ|4µ-·ŽIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/info-win-m-r.png0000644000175000017500000000027012650773437023570 0ustar tobiastobias‰PNG  IHDRÀ[¾–bKGDÿÿÿ ½§“ pHYs  šœtIME×4ó€ŽEIDAT×]Ê» €0Ñl\!µ»¹‚›:ØÁ*¨h“ʃ㚠e¬{?Ž®‰¡¨ZìØ0cB›0bÁšßn=ŸM2¥vIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_header_r.png0000644000175000017500000000027312650773437023575 0ustar tobiastobias‰PNG  IHDRé`¤ú‚IDATÓбÂ0DѶLDêÌÅÐÅÐ ýÀЂia!/™u4ƒ²7»œ ú”G.×-€¥øPèzŽç×`Óû.€n3D\&ÙƒO|²ÞÈ×äk>A±‚4= šo¹ XvÀêµUòï¦Òm'åQ˾h¬=ô`ðÒÂ>Í%«÷‘IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/logo.png0000644000175000017500000003323512650773437022320 0ustar tobiastobias‰PNG  IHDRªDžZ9' IDATxÚÕ½w¸eWu'ø[kïsν÷åXY•%•¤’X€@`‚0ÑÆÆn àØÆ6n·»§¦=3žùÚapüÀÛß·68€"Y(ç ª^¨—n¾çœ½÷Zóǹ/¿*•Ýsµëé~÷¤½WN{zÅ[ÿôµ¯}UOo¯1Š*´O~òÓ“øà³yó¦ýWîÛºuëÐÐ@¥ÒÅQ)‰ÙXÃLL¼rö€¨«Õ A|ðÞ‰>ϳ´“uÒN£Þ¬Õj³³s““óó 7Üpð–—ÞR)—Ù03[ËD†‰A "ˆŠo@U‹o  8¨ªªB à€ŠóP@¥8¦ÅqQ $„‚Î{—»z½>77?===q~¢Ùl=;X½úŽÛï|ÓÌ„N»ýÉO|êäÉSëO³?úã?<¼iÀ ÔKÐÓbIØýØ{ßõ[û­¤·‡¾çøçœæîÖÛo{×ýО}ãy€ ªPÂ2¬—fŽs-¾-Ë€D`‚µ°3ææò8²Q¢.d”…+À ûeÅ'ÈÆ¾(¬hÅ¿âV(‡`&°ˆpîôÌwï¹ÿë_»{òÔŠ“(²Ìü´pK;ßþC#ýÎyŃ·ÞöÒC‡—J¥µè_XXèïëðÝ<`—'Ûnw®?°»Òדû`ùž!^à½OÓƒ/~ÑOüÔ{7ïKæª^,ãcÃÏÊ£añ Añ+Qc4õ,]¾Fî|ž*\ÒbŽFLbUE ÔºÕ0 ^C @íz`b=•.ÓÁâ™ÅÍ| ÄÜ;0tç[Þøƒ?øÆ£‡Oþõ_ýí=bJ%k-Ñ%™1ˆøT°|IPV@ŒÚ¥>§Ùh¤’h Ò¥¤5(ô—…æKÍsù±)ˆ:ßNÝÐÐÈë_DZcǧ&§Øš‹¡Ãgùëî|åHCeÍÏž>7ÿÈã§×3°­×ë÷ßûеWíϽÛPÿjØ>ÚÙ¼cëÌìBdÍ û,ÏÇGG~ã×?%½íF›U+m©⡲^YSÔ:±\öíY²-ŽÇÅ3œÉåÌ\/f*¬EHÞ{Õ_þè‡ÿÏÿò‡=öx’$SA]WÖ‡àr OÃØ¾›ªµÚ+n{™Ë:"¼ž6‰ß9)ÚûØãGmd_P}Ÿ;7<4ô¿þ§1÷ø´C] +BåiYùbCÂ%ä6fJ„`ƒ·¤ið5¢~ÕU>#iô4Rê2†Š@á²Öm·Üúà£Wk5c m$üïxík’(" PÖìÌ™óµÇŸ<³÷xôÁ‡›Õq(œ”u¤d‚K^vÓÏ|æD•_0ù¼¬ùµ_þ‘’Ïš–Tðscý%3PV›î*r }yõâ$Þ #Ùi[Þ¶Š“ ¨¸sá*ëÅ,~\Ú (X±ÒD+Ì|i×A›e>üïÿ÷¿ùÛ!ld’‘„àC Á»àt#¯¨07 ßýÍo¾ú/S'+lÒ¥{)d¤§taÿU{Oœ9Ë/Œ¨ª>Ïæ¬Ø,m³úpÑs™ˆˆ˜ OÄL¡Kð&¯‹”¥(à}1"#j´ä}ÊÄYý´±ý ªB "ÂPQeRÊ"A¡´ìùoH^D›q?© ^ä1Q¥'™ÿá7ßù7Ÿû{SfZŸ‰·A$‡, i–kÇe!€1ÄEY&оúo¼þ·ç® Ž]ö—¤øWé´j·Ý|ð©ã'­µ/ûû6oÙò’ƒ×W«™:²J‰ˆÁF|Ëå§|˜Á‘Š@¬1Ì BÁ—¨CR&£`€™ `¨EJ‰¥!‘e #k‰ŸÐõˆU-õºì²ÓКl˜Ð 81@D¦ð[”!03‹34B .â(~3d…çòÜ Gñ½T*ÞÆª8ËðÊ—øò]w7Z­µ€ ÎiÈÕ HóNúšï»áÍßÿÃEd/ùß>þñ“gO³±€5æÂÔÔ©3gƆÊê¹Ë~YRDBÏ‹ üY¡Ëˆ<kƒ÷»ÿõPb­Y’n¦@²Á€@kMÙ(¢ˆ9)%å²é+S_/«œoײé‰íNc´0/–€N+ÿ/–¼›ž]ˆþø/ˆˆTEADU‚ž‰jaj@TCX\ ‚x‰¨92I¥\èÙ¾uøÀÞ­öY—J‘Ý b@V¨¬%EHû³ö‰·¾æñÙXg…ÀNT„ÈGö`«ÑÓndÄK•Ö=»:e l—]âøëßùÖûÞþÆv§SñbÜM uÃ4,rêÅ×îyøð‰øùF¿ˆ$åÒK¯=Ðhd‘MUhõRØ’­7ª7N[³µ¿rG9$öLÍ6Ûÿüÿ~‡×ųVéU톺ú¡(Q´kÛ–›îù¾k8“yI¢=Ìñ¢R(P¥Ä¤¢,1sïãk®Üõ±qL+éc¥Ô1˜aO§› i¦z»~üüù»ïy(ŠJo¼ýæ×ßvC–6¼ƒ9¦u2ÀDìCrëõ[ÿæ’ bV#…Õ±:U%pOœ€<à  â<;ŽÐ –‚R‘µßzàÁ÷¼õõª É™£“MSwÛ‹®|ðñ£=Ïòßyÿ†—¿4Ïš’zÒU_ÅÎÖîk´'Ê×ôî"“ªÖ4d:ÙlÖn#±QœÐ36KÇ™© 'ÏMü×úö/»ñ­w¼¤Ó9EÖVÎÇfyçGï¼í'Ž †Ÿ³'LÅdŒ" A¾ðÕï6:>ÔïŠB)/QqHÇ{¾zïUyíQ iöÁw¾Mmû ^–GÔ'kõS½•{ûÆ\¼¨U4Ú³ívvÏcÇŒ‰è|qfk-:~fâÛ>¸ÿšR,EDDWA ¨Ñ8Ïgû‡=rÒXóürÌÄÆÌ×>yìå/¹9ψã "*ÅG‚HÐÈ´ÛsQ\yð‰£+:&gçúæªÍÙùV½‘×¾Þpõ†«6ò™yÿõ{Ÿp^ˆÉ.=ÕDÑ]÷Üwý=®Ý^O'êP­uö¦ûî}ü°yþä²k÷½ý}­VJTÁ€$€ “¦³s‡£øÊRy8÷©ª2u¹‘YœC–ËsEfNâvšþïŸø›¼óÍ{¶Aç ÷oh®± Ñ WíüâÝ•<ËyžUaáÛ$‘YXøóÏ~ù½ïx]'o¥Â91… P)«¤ÞŽôÚl ÖÚ'Oœ|üè1@hÝìŒa"ÃÆ.s!ffæn>xQðÂADºü'AÄ‹(q»Õèï¿ÿñCÆFÏ Õ+àr÷†Û_640šû¦Ýgù AED§/œÉ]>6~ HÇ$,MIT[Íz+í¶g×!óŠf×®G?®°/P$œˆªõ¦ ”{Y'%fQ5!t¬­[ˆá]?ð–;vˆ %‰ý§¯ÝõØ‘C¼‚oíZýÙüÎM··3ë–M$j{"¤#ƒcõVÍðsZµˆ ŽŒ¶}p~Ñ«Y4¯:6…Úñ3nxÓþÌù‹S‚€ ¹H¾._'J>«þÔ»·ÝzË­GŸ:åÃÇDEÑ/þÒøÐ‡~¶=ÿñèÛ9ÛPQdíÝ÷|w÷î½m—ƼAŸH`Ê•^-%½AÑ %¢Øv|p Vå„ !SÝÀ¸Ñâro½ÕNaÙÕëI\Q\ ýŒ1GŸxåË_¼€V-[…@jM¹ÓœÚ³o÷ƒ>ð…^þÀþ«Û™d¹[¡ðT”ˆ¸Ñœ€«œ»P½^IDÖæE™4$k¨T•÷nÛ¶uß‘£ÇWÚ(…v¬T*×]wý½÷ÞÐÀmdû7Œ«²1­vûÈÉÓ[7mö¢ë3³¡¸7kÚºuÇé3Çù…É„«ÈààH+Ó;c¢S==½33J¥R–eû¯ºê-oyëÑ#GÿìOÿxI¨¯ª¤dz.šŠUœ½pftûŽ¢æ¨ ‰h1%Fq%Iªq)Ö x^+!T58wõK^ÖŽLðŽL(Ð¥9‰ 6F'kÁ‰¤Dåõ,5jY„8Äì=Ëåë|ÆØGŸÜ{ëâ2¬7j,\Þ3²ƒø»üì俊˜(Ø·¹å2æÌ"n-iž&¨ž=çDc5È'Ⱥy”•îHl$sù:³,øÀ§þò/ÇÆ6ý›ý‘x`xxä>þ‡"ú–xsuaîoÿöo§Ñd¸x5 saúÜàþm>Ï׋™˜[õžÁþÆlõy,„TÑàüØžc7ìk{Ï’.ãªx <…˜{jS3³j7>JYœ‡HUÌl¬¬qÖ6¶ÝŒ1SG޹²¸8Ï"WŒ<ÊG§Óß'Qmx÷& Ï&è!AƯÙÅÞÙÎÒý»#’Ÿj™dzª2JšÇY‡îѲËÊ.-û´ìÓÈg6xëÖ,IUïxÕ­½‰yêÐ#ùð¿ð¶·½9mUíW?vôÐ#?ÿs?½âT¯š_¢°‚™f\ÉåQ–Ç~º#«pŽvi°yÞ˜^|¹»nïÎ×ÝÚ±>çzVγò •]¹vEó0J˜ž¨ªny$EžH–H¹,ÊSöžÃÓs7ô‘æS§Ïîò€®d;SÅP懮Ü4lϰþSUÕ…ÁvvØ«ÍVn.0 ÷Èä̬jê#²È‡°Q*«µp8evËøèç>ÿ¹Ï|îKŸûÔï]‘àÅ{Æ>ÿ_þÆ=÷ïØ:öëû芅#áÒ~wg¡Ñ)± Ä6ˆ§n5„-ä*“Flú,A.ÆK—€Ã¢^- ޵¨´îݹiü¥×”¶ŒtTCÞ¦B×2Ê„Å} ±+Ï›OÍ\blà‚²ã4Wcœ$ä×j.Z¹ÅÖÌ>t²oËfÉ"&öªpÚ¦Á¾±œãXõ&]DË›ãÁAŸ9ñ´jCµªÁÉô™¶¨-ì,ŸCòE{À‚¼*Hcˆ‡xYí¹+™Ê¿~÷žW¾úû¯tO\[ýëÓßüMÌ~üž'ÿtîÜÍ·¼ä±'¯´dÑÍ•\$H\£ƒ ÁA=Ô®ÞòÁÁ9&kB–ÁùK zÕM 3³!k(2&‰m9±}¥ÑÁÞc6©@ɧ.ÇÚ:`îþ@ŒFUí©“i©ž)Û iWœ¢­**†´#N—‰~2Ü<3™µrö‚ˆá€+þ ù>×<5°gsõ©sôL€„0tÕn×ðê<<”»xçÀ\;×H“Ö…Y% :ªË)­|ÑÍ4dêÚkIZ©tâôÔ+ãGòO~Ûo…óè½ýºÑÓ-’/ýÚ'ϯŸÑÅw Œ¼šÇ…UtVÔ@X«Ïmy|`÷»ßÂKû‰ˆ01˜Óù@D$Üåõˆ— I¯jŠjsÃ**âAÉ_B5ƒ˜ro.ª¦q61¥ëŒ¾%î—êXUÀ¬mB®—~"2fáÑÓÃWî’L@Œ| ú@°Ñ<éÝT^xêÌ¥À·^â1õmÙ.M¿z69©ªWk³Ì"B†|‹—æ`–ª@„9·®ö „?ÿ©­W_{dµ¯@D6c¿ùÑèÓÿ\:SK»ñçM2¹ºDRQä+ÔqÈ L¾“7l+²2÷ÓMéêú’°>z±|ºd—JOJ(ÔnQ^˜]8ªè¯™ð’\tŒÐ"-“u.rZ<ºTÙ.®?1°{_ÈS2¶kXÀ§bBèe“F¥rpî2忊ômÙâóâ4#Ä@µÏÄ&Ïf¸S©OÎ5DEÖ_CC@¤R8¾@PA]Ê!5kY_Ý´‰ÁNqœâcéã,”¢¾ª1•™÷4_UÊs&ò5G¡¤¢+w?h¤ .UvÎr®N–qg‚ú%+a-ÈW9«ÔUjzÔë¢$ bwªÇ4 íé*ÚmÑøb€'fßÈDéüTîqÄÒñÊ„ËE?³k·[çæãž^†×ÕtKpDýY³Ö3º¹vþ4]^@%ônÚ£ÐqÁšB–rálþåj²†C‰–s*ð"–—°¤eœXƒ,²Õ EŒ0ýÖß8·ðò›“±éÐé,T¹Ô)]u>==z§ƒwd¤ÒѪÊÊòÆõb!’qZ¨üÐ /Äê%BkÕ2^ÃÊ­x@"îb˜N÷&Ë~–—`¶8Çòò€)jʼ ®];lZ³ ÔçrM.ÁtdÌ…û¾]Ù  à‚´« ºÚH|š¢}²¦5q²gß <^TX]BŒLÏàhõüIÅÓW=¨Š-•{û7IÛ³Âæ‚%K†ò¶mµ;­Ì­ðb"ˆÍEAÅ%KÑŸ¸¼¬¨±$"2È; ¶ÿ³}çÿ¾«?Ž äÇÊÕóÿ%ºö=ÂÙ›ßôš/þã—º÷ÈÎÙÒ.Dƒ—ؽŹšŒv¾r&°p°Bf1·dƒ,B©RH¤û‹]Ü"bsñj#ò",ƒ¢¸ÿÒ9”8RˆFyg6¯ž°R©-ÌJ«š‡äÒš‹˜5„ÖôùE%GJk«àŸýÄ™ó[·ß‚°1k•!A¿H£Tî˳6ž.ë%*#C;m'yøU͈LVŸ²¶Ü^˜µÅ$µP²m]£D‹å)‚"—f»•ôDažlݵ£=ö G^Ëò5 Wð¶wÛÝ£@&οë‡Þ¶ŒþüœËÎ3WÌEB¿ DqîUVN@—DCÔ‘ †ÓõWëºÐŠ®ŽyfÕëƒú â<Ïkg NaæÏ‡ùà2ÒíE?ŠKXO‹~hcîü`ßf]™rV |°Ü×iO ôoš¾pÜ\ý ‘‘á+LZÚÃSøDÆ Ù˜ËÕ0» ñR—ÄAƒ*ÜâdÛPiœz¨_ªí"›û¯¾ýåy«Úie²ãå WAš£5E€wékîxÕ2"sãÕtß‘Y.o^ѬcÕB9‡1ºì¦¯Ø»O¬HÕr0™ªÑeψV@É­€´_}šÒ"ÊAÄ|'ËfB{Ú‹e ‘¶|>ï\"ˆ.^à´¸qiu÷©Šñÿ®‡ÍLüô;¶ˆÍü…c¥í>8¶¼LäaZ6QÐΡ#ÓµÐjãío}óììl±åb%[QÚi÷”“yç;>ó_? waÇöÁSçNΦå¸4XÜkMð,ÒÈz³\Ô–'ODÆåd“(z ™®¢€uW­“1a™Û‚ëx_wyÝû&r1IÅû¨‘ÕsW J"åK;+"at`gOyª0”§í©ù£`£ª†£í#W%áÙÚ©NÖ¸ ôµÒjè´#…dx’ƒÎÍõ$ƒí¬~ û_4lîÛirÑàV68Q€™[ÍI Ö…¦`uÙVPë7Ž,Ñ¢¼§Â§ßò†}¿û{_pç߸°P%cÖWÀ9çBмÿ}ú|ös_ø¥~äw~ïËÞÜj£Òì+y2ðjf°÷,VP¤,`f5–ƒFá• @€E.\¿"i×Z­Ó¥¤—ÄTóV']`JÄ*QqÂ¥÷ŠF&Ú?r£ƒ5JŠ$ï¤õZgZTvëßíCQ£•÷›á'&ï¾ ôƒ˜Mµyz÷ð~Eµ†@îå¾N6±¥gÓSi•/"ÿÊd¶÷m‘XQ‡Á†BêjéúÊ À2õ²Q^`xé¡EÒÉ ˆPÈ«?ýÁ«>ñ‰Oø7ÝÀ­4!Xcã$&"ç‚sYÆ’íÛåþ}ûž:v캃ì±ûî{èu¯Úö/ß:n¯&2+Õ¸6±vU1U±I¯¸› Á$Ôþ“MÇ`ŽÄ@ˆÄCËNž™JeKktu·€ 0†¨ÛPïæÜµcŽSÿäB£n8¡ËŽªúàcVj ‚T·÷n™oMa{ßv‚4ˆlšž“@DzYÛu™Ìùú™ã×åÒ´‹¦Ì¢£§ÄðIÏ(Ùãst1ù/¶ \QŠŒ N „e?‘Öd•jÍ™°.vÍcE‚Æfù¡Ú=$Ì€² xÙÁÖáÇzûçjïÿàêÖàðèØøx¥Ò³ç ïCuanbb"ͲZ½õ‘|øç>ôá–-[¿~÷7~é£?ÿCWíŒÆåñ•1`U­$‘ªzYZjwÀ’“ÕÛîHëL׉!“‚Œ pˆŠ¦‘ÊpÌ&MÅv°”lRE蟺KS@˜aK}ìº-×÷%ýGgŸ4l/§˜Œ¯2Û>·¹<"¤ „Ì$³©ŒöF6aKÁwr71×rt™Y ùO·'I Y!³4q”ŒúЮŒÉF2M aûðnO]u¹U¶íôB; ³)”×\¨ "^ù8!£d”Œ¡@É©[_´mú™ӧ÷îÝ{õU×ìÝ·ûö‘òlé“ñƒC®980×ðâä™8÷âBè¸NÛe —5òN=oWóæBÞœï´ç;ùNc>­Ï§µÙvõÐÌáû'Ÿh¢ Ž«­ÓŠVÄ '²}hÇM×ñryM ›sµÓj*B*°Q<šûêXedËÀŽœ) (Çδji!­«^v"³9[=ͶZýaÀšž ²y`lÃöQªÒ÷ –G$ðÚk™3©Á´ò¦³¡Ú ²†Aë>LĆƒ¸—]Oÿò•»’$ð3?÷¡Í[¶ª¢Ýî¤i–ey–¹îHóN'MÓζ-[KIO½Ñüè/ý2€o|ãîW½ú5O<ñd¹Ò72Ôlz©xGUû“~‚.6ô[;U ¹äÝWãá XIDATù`ÅèšÝ+ÖJlØf>}ròÑC³O•+cig^9c¢n¦XYÇúǯÜt0ÈÚ°ÛÅ µ…ÆE^(Rkbe»epÓhï¸1‘! ùTKr±E‹ƒËD?ñLcÒCDYˆ„HH˜HˆQ “þÞ¸ÂdÖÏR4lÞ“…XL¶x-1‰ Û´sžMßB§¥²q¹´,$L²ôè⹞¸Z»o玱á‘Mßþö7{{ûßñ¶·IðY–¹‹|ò<Ïó|óæñ,M_÷ú7”*å………ƒ×^àðá£{woõ­cÚÝ-Ý*•ÑÀËs^úK9 h©ãsÒË”£`bËv¾5óð¹¸g0ÏkZ‚jw’@d¨Ll¶ôoÝ5zeOO"æ³µ3Fc%!RGà ¨°içU§f¡ÝÞâòÑ_ô18»pŠ"RCÌd= CÄ@”lÊ|c¼Óš @ •ÍC»TI¡Åù`x6`’N»ÚÌ<³»X÷ %ãÙ0YÏF‰À%"C¬¶§ïäOÙµ{·ˆ¾ÿýï3l²´¼»ØpÞåyYc ipïþ±ÓMý0Ÿ>}ºTî…ŸP¿€nSPê÷‚@†# †’Ã3ˆ)µ8‰ZyGŸIÊ›@†M+«?qæ(s~V‹ô Œ¥5‚Õ³’)‰ñ»Æv l ô2 µs §Mœ8ˆ#Kƒ¹T½Ø l›óˆ£j§­`<£ &s~áD—"¬º(…!¬‘‰•id` ºªCˆŒõm)Çå@ºtþ¢44í|ÕÎZwuåIñ8^¾Ìv¡y´¿Ÿ&&¦ÇF†üÐÛß–¥-ï}¼ï]Y’ÿоÀüüÜUW]U«ÕV)ñÁÍ©æE0r´,ˆ]zèšùg®–Š°ÉŸiUOáOÕ:ó‡'NJCA˜»š‚×j:D¶Ïùüšm×—ãž§ÝSFÄ­´ÖÎÛƒ‰ [ŽzDÕB–/´òÌDîRÅ^»o;kη„Iˆ‰¨° Z* öÄ%k“•N­hØ6º§™V"Û)T!L÷BaÓiŸ%-×%ÆžªA×*ÇârcâÙÙû¢(©T*ÖvîÜž¥mYµCÜ‹x kFÈÒ¶a†Ê•ûöèëë+—JY–-,,0CÝ$W•ѾMÊq€ðº™…àòFÛ¹ Ϧ޵Óµsg«ç"SqÒ ÄaT—¾(* ¥yýÀöëEäÒ*€fsnáS¤$žGWD‰a2íl*ŽíB«¹ÄlÏý€a{nþD\Š`²†Ô²±RQ.yWÝ2´y‰BUŰÝ2´UŒÑj†ˆÈ"Ë0Þ嵆Oõâ1LsD1 )³Z.ž(–4Ž#iê¼;¯Ø~ýu×D|¦!×àW Y5 >ë´bËIdÊ%û—ŸüãŸþÀ{ª !„¹¹yDµ¥’ñÛ7í¸œ eVf‚!µ"iÒÎÛÐg¹Ý© €£çmù&0yc† ³5¤Ì†9Xƒ$(YÞ<¸íi÷×2ñäüI*•kÐÛSЬ—Ø´Óó"ÆÞŸYyOÏCZ„“ Ê$ Š"åòHÿ&Y”ÿ¢²etg&½Öd -ÎìcZó¶Ô7ר¹øÊ"¬ÜM¢£ØÃœçsÕZýÂôô-7½èàÁkÔ;Ëä²*Ðp‘!Á¥¤[îë)ýÑýÉÇÿä/>üó¿øï÷/|ägzž¨WI-ÛMƒÛ‰FaÓ?†Mš]0¥¾z»}ö{<˜Ø0=zê;–‡œ´E¨€Rñ¬â¡D$“Td÷Ö« $—TDì|6߸`¬Qf56Rñ.tªíŽ ÑÓTú^2$ gÅBÄ #J4˜$‰#S¨(‚ømcWfY¯‰ó€’…,žÌ¥Nz.Í è\bJ¤°°V¨T<«xh Ûò@½ZoçògŸúþÓÇ~…X£Èz ùÅЯ!—࢈MRêIøŸ¿úÍ—¿ò/¾é–/üóW?ûù/üÇ_ùÅn _p;·\Ûjš¸‰„¢bÚÝÉk,œ´ÚS.àTŸ[…7‘É\zèìƒq4"Ò. %KP]“T¶¹îÚr\Ò$€ÙžŸ=Á¦/Í/4ZÓÍÆÙêÂá8î­µªºBV=ãMz†Í¹©£L½$yàX%R‰TX…=Ù¸´%ÏëãC;мS9éíïÝœ+©U£ŽTˆ|^Ë]¨e­ì%–¥‚°TY5Z¼CäBÙeú?w`æ®nüîu§¿öé/|ù®žr¥§Ç– KØp ±å(ЬkŽ|åCgO>õðÃ<ùäýýý§Ïœ;un €æD\ºbËÁNè‹£ÌS¬©²*«°*+Ç>¯eª iËKô‹» 0l¦æN̶汄¼€U÷‰‹Ã“%Ì•­#;Jq¯^²N‰‰gæÏ´³,Ž7«¸ýÛ?]¯ÎÍÎ\xéuWLñßmÛÛÓ3ŽÏ¤w8 µ&Ƕƒ®Ü2I°*FB¢!o§ZyJôyÚÛÃdBðGN|‹y3qUÕªÚ% ‘’ ÄÄñ¦ž¤wp`›Ê¥€13`F”ƒ$kÂêöÙMtjöО]¯™Sº| ¬ mê4ÎŒ îryZékvDØ®¬4aÃiû™R£1'réÆJ c9w2AMªö#׿]×|=Àþ Ù(]±íÀÖŸ~ÅäsâÚ›ï8úà×·oÝÔN³‹–ü¨o×e=þ—È2DŠŽÃ©§à&0ä¯é}üq¿CøJÕUÕd7›ƒ†j§¼<ŸØØ™ùcc£†û{”q¼ÒÂ+€¬@Tn5OîÜvó#µ¿'•Kgƒ.==~V¦ ;—ÎÖÏ*'ˆ-¬UŽ`»_ÔŽû{û6ŽHuÀ&âЊQÎZǽö-„LžÖf&î^è9yÛžoüøK¿õ0öþ£S…k «#«aøêßþá…˜~Õ›~¤\*•bÚh° mÀw¨W±°€FsÎU$ÿšýççj“žQwi0Ö‚KN}má|+ÍÅóÙÕ@ÆDOüJ°c &l -Ám Ȱl{vù-›ÊF@$xŸæy3[7ò¼åC&‹vóìÏlØNM=Ú7ôƒšÚŠ.z¢l„MÏžNíô¦m·v¤\‰D£¥âbNÛh¤Í–w¥ŠŸ6×$ƒä’\5p Ð d-0AØ?–ÛK›¸=ó Ø±¹™£¢1žï“ >;qü®{_Oa†íPa]±ÁJDÇ夓VÆ·Ý<3{D5¬¬T.šTß|Ë+=#k,³‚ug.yòñÿÆÖ¨AM/go!Ï1ÇÇ‘‰£s­mˆRôæ0'ÑþÌ<̨ _ƒ«ÁŒo}ð·n›:ü›^þR@-ÓšYc“’L<žŒAk@ Ôµ!SÐ $‚Ä!òà°ç•S/éûFÇ͉±œD6Š[.ªNý«hua‡èkçÄÆÄÇ}+ÛÔ×Lss¼[c9Ž(²qd5ÚÜ7|e\Y%P¼õ†âh®lç^(™zOÜ쉛¥r“hba~â9éþ%;eâìý¦4Ôki©¸šÚdÅ‹ÈwÃk+Zõ{~r¦–ï”Öãz™ŠS¡B†­· E,}ÿþê‹ÃŽFž‘¤R çá3ψ‰Ýµ½ Íò»¿õÝ5wÝ>RAÅ!œGÔ‡p˜E¢¨8ûùßßô¿JÛÑÐØž7¿¬gô†šnùt ›¥vʦ§¡¬ßƒ×ÙuU€M[3SÇþ¾o÷;½NÚdT×½JL˜ûÆ÷ÌÌ.ôouãüÝ0¥n¨4ЉcJ†^|7U@dÒó§çSÖÅ=Vö9R($ÌNÞß·éÊØ*óbÇØ¼h}ƒ•¯Ã06ÒÚ=ä~ʨ¹ÌFXjÈ™ÈrÄåXþzîm_øˆ»žîº¢¿±oKö¢ë:^ÜÂU³`A+Ff J0ÉW4&ªŒ”ËIÛÌ^¤“¹V;¯ú@'àF JÄŸûƒñwþE6²õº=;n+ _o+[OŸ®†Æç3ìuÕÇ’ìhê*ß3Ü/Ê×xöÄ×w¼²m¢^Sbèšw]`pØÌ͹☼G5@¡„` Œ¡´Å'Nœ±Q2"Ü«‡C:d™ÂsG?âhîøWÆ®¸Þæg…û™5‹à¢YÑ‘Êr§ÉÁ‹³9 ÎSér ð15àëÌd‰â^ß¿åë3½­3§:O.äÿXãú¿½uû‡ß;Y:¸€ÍáÂàŸýø·g·oÛW*÷ŠPLè9ÒÔ{îJ_úÎyD”zþîFüÓñ­×íº½gøÊ¹&»sŸÑ¼Bv LÞûjÊøâ~‰Á”£³ÿÉÕ¯þ%éœ(%cÞ«áå6ˆ؈öì¢ó“‡’+ßpáÐßG¤R6 —7XEDµúyb\‹JšñÂE¤à¹£ß6fO¡sV)·¶U.ZŽ-6Lén‡ È-<Çõé'¼FÏ`ù$17…:Ý>,L½#=•—„mWKÖ𮞶þïSSÿ×GNÞ:8}íhÇÀ=v!ûÚ‰Fßà¶Ñ=&é-Þ¬&()›þèý_ìü/sÑ;_3Åe<øPü;GwDƯxñøÎWf¡2sæîTaÌXhOÕ[‡"ç2-Ñ÷þÖ‹J3­MÍŸø—Áí7I:Å=Km¹ˆ;” ”¼ö쯞ÊÓA šJmC³ô—¢h`_Rê+ÂG–íá=QÔŸ3ú‰˜£ Ç¿³ãê[(ÔxãMƒd(HõQ’~ö5ÕÊ3¥†ÈµÚ+êH#‰mY“XB_OߨàðölËþcÉÇæ¦ò´jÈoÙ_©ôŽÆq¨xÝš.ÕÁ*™˜l®æßwìgþáXÞšñ¢å¾¡-{ÆÊ¥þæü“j™{C­:¿ð° ÎJ$dÿ;¡~QØøÌã_Ù¼e/i-òªfmƒORÚ4šÌM<µýÚW»÷ï‰ÐÚÒWâúþ÷ôõ&±@Çgý¶•”ó´‚}^,”Éãï»öu5–åhËMX(ïLï:Í >DϨý%A8ÊØçËÉM]¤;åDlDq¥\Ü¡!“‹x¨A¥èV˜ Ì …‰Œ&ñà@oOÚžõù(Jz†Éd­N}®Ú¨Ÿ1TCLÿ1¿"Æ È‘¾xý÷½MÃDcE“®¢×{+½*Sƒc"Á ÍX@D{zÏ€º[fJXh-T©Û;èùA?çy6?uxl¼·>{O–6»›X9,½áJó¬Ô;Ð8u\4z%fu1wêÕ£ÖLðiQS°²?M·€’’ÂtßšF„ ^‹ÑÊ¢J^¤Î‰XŽ˜[îí±CYÚÛhæõ‰Z£1ÅpªVa<1½}ZŸ‹“µ0s~vê‰-[‡›“ßÍòFdí6¥'"ެårÿðØèìÔù˜;µôDÚ˜ ¡…Å–÷‘úwAHE‹åCTÙ(Hœ;sòt«Ñfò”wZÁ‰’JL½Ñš¿°6PiËO>¯³T"lØz\•ä9”F0)ѳ™¯®˜ÔâæMRüÿòs ¥å7^l´•ˆøÿXÊðún.aIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_line.png0000644000175000017500000000012012650773437022742 0ustar tobiastobias‰PNG  IHDRrcfIDAT×cà”)bbb€`fÍÈÄÀ=¿ÜIEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/bg_line_top.png0000644000175000017500000000012612650773437023632 0ustar tobiastobias‰PNG  IHDRrcfIDAT×cÒÝÅôÿߦ>0ýûûBÿù¨¢‚£‘ IEND®B`‚vdr-plugin-live/live/themes/orange-blue/img/tv.jpg0000644000175000017500000035636412650773437022020 0ustar tobiastobiasÿØÿàJFIFHHÿá&DExifII*2:(BHH˜( œ%HHÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ‹Ä"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?¯àÛmM¾«¦C2Ç7™÷HùFs޵Ô>›áü­þeóÕå\nú|µÉø[þ@˜ã˜âàçÑ}9­½âv\-¼¨[>b)büõõäIôü®r—3ר’V/ ‡(tUÜ©7P2{v§¼ ä,çC'$+”|1Î8ùyæ±ÅÜVö× ¼¤D–Ïåîþ¹Á'¦*(®õkIÑ"ƒ6êùóe· « 8?9þÆzô©æ}Çdo¼ °¿öí$”~ž¿vŸ$>‚EŽ]cb2ÆãÅ}Åd¼"âi ‘K,Îã(QBŒä cnOןZš;=:Ù-ü£‰¥%ü¿3OûضzŽ2(æ—p²5·‚~Î×à§i*Lé÷j9!8}%;wàÄý3ŒýÚ¥9h¯'söi‘»’ß/±=óÉ ©°”eŸ™62’@È|)ݲHúÑÍ.ádk¨ð+™vøz3åcÌ>D˜LôÉÛÅ67ð$¸øz&ÏLA'?øísÆöüG¼Y‰ÞËh2W!OÝ9zºòÉv!–ì3°ˆ…X#Fyúþ£š]ÂÆ£7’1ðâ˜à?ÙäÁ9Ç÷}i<ßöðìG'Hs×ýŸcYñØiðA,ó…‚U äc× øëš}í´í%´ép‘ÛÀ˜òe '«xÀúv£š]ÂÄ£RðåB€nû¤ÛÈéÐíÇqO†÷À73$1h<’VÞO˜O—šÅŠI"³ Z)mríoVbÇ•ÎFAüûwrß›{eYB>ÿ™Km' œcác¡uðD@<9ÝŒ"LœŒôÛéB'äRñør7P ,HÀc¯!k›û>7[ê3ÄŽwL{—å]ØÜ ÆÉúÕÙÚ;ì‘],†%C$ÑáNåA ƒùñך9Ÿp²5ð@:C'êd³ýÞ)vøþÁóåIŽ:ó¶ªE¾hV“ʺ YÑf#ÌAÉ\.NrrO×ÔU™u R)•m :ÈðºNS»$玧 w£š]ÂÆ„“|?Œú,kƒ‚|¹0>¿/E1®>âS®G=9Ûî?:ÈŽYãžI –bà7“ vEÁô9Óœb™osqʰÚyÕAŒ†Gwäöô£™÷ #¤–ËÁq!y4 Š$²¸ÿÙ}ê$´ðTÌR=»‚UG,3Ó#nGãX/%ÌqK%ËÅs+#´r«¬qðl#ŒäàúU¨§Š{h˹ž6r’˜¿vGAœžAè}1G3îEö·ðJ“ ‚3ÁWìp†—ƒ%‘cDVféËc¿|{«m¡#I%»¶Ø&óvÄ:Ø8=ñI-ÅËꖱʆ(ãvUb§÷£a8Ës× s>ádp¾ †Ôk3-½¤PÄ5\€>½è§ëƒ:´ÇÞŠÞ2vZÒ¹£ Éåh18Þ3ŸÀWA ü±,1MpÉ?ºvx°W¸Æ yÀö®{BE“EòÝ‚£Á³À…æ´4ûk‚ÖÐùƒnÂÄü¯»¦ppAù‡CýküOÔ¥±}VIîZE… @#3˜H%p[×°ÁõéÆi‚Õ¤½{åˆÈØ(»c!AÈ'o#‡·ã-„ ö’} \ %ŠBÒrxHíϽKoñÉ$qÛ²/VXFyÆHÎG 9ÉÎ*F>9Ò$i;…IY¶Žw1î3’*}I•¥YfŽWÛ†mÛP–Î »›’8ýhEšc¸²É™IÜxã‚W“ïŸñ«pLp5ŵ©;å|‡8_áp:éÀá½–•„­ömÄHUãP¬>\’9>ÃùžK¹bû:¥ÃœáÌ`ûy—€Žýýi\ÚéñÝd¸¸2ogW$ƒœ‘Ù'õ9ý ¹§‰.o7ˆ#lÈžR± Ü/~ü÷>´—6kw41l,¶åK$Pœã#<íàç¿çfÅݵÑêÀFÌã°ŸåÉ=©‹ Žxü˜A*æ7’Ü$¼àà ýÞ½AI¥—í,òÅ=’´mó$­”SÓ€8ÀìG~ô‡Q—íƒuÄnKEFÙ³K3$ò3øRµÒK,Ž÷qEg.æhÐ…gî¸b1Î1Èç5Ë23q6nR£ÌCËqÈè8É?…GÄe†8çób“€ÒHÍÜð«œg ð0:ðh­ÌVñbìOpŒT •v+€¦FqZKt`-0C-²ªì,Œ`ñÜœ‘‘1UTn§{ŒÄ›V³‡$TŒ/CÏ&¢™·Èm£0ÄÍ™*´d¬™$œœž ã? ®ü›:ÍBÄ1Íœ·;¶çŒãÎ)‘ÝÉ ñ’HdBI>bÀŽÿx}1N»v¸²i`™ÒõAÚÈ<¤+ž»ûØÈÎ=…NþL"•.fã˜á—ÌfÈàü„eG¾O_ÀÙy<ÍAGI0żâåO)Á9>™÷ÅI˜B½¼âتÆg߸½ƒØœ{c#Ž(…¤ãÌŠLIî!}Ò|Ý dàŸ¥#OökGm«`IJŽ„ß1$uëúhµÕ½”ÊÒ¥ÔñÇ;FË!víã ’qÏÖ¬ZNÍ-i—-æFîÇæ†9À§8Ï>§ˆ¦ ר¡Ö;x“vZÂL“‘Œd™ã<õÈI-Ú%…c¶‘åòã‘á!Wo 78ì1žsÚ€-}±%x糌yã÷§~äÆßáÛŸn§#Ú’ææy®PìIwíÈ’,€¤úwê?1NµØÖ‹m+ñݘ—ÊÃdä1# ¹\ãÛ¡¢Ý^-(=ä“<¥¶¶Éò[”1‘Ç\h¹˜ên—PBÿ»\yo9*t$rbÇ^µZÕ½“˜8v,Ï!;¾B9SÐqéVwÿÄÉeO‘r&-—ÉÉã׌ƒÆ@ [˜¿såf_›rà’Qž1ì;Ð%«s©J}è¥ÔÆoäúÑ[ÇdKÜÐÐw ! nÝäýs…é]-³ÙÎÑ ã#*è[Ó;yÀÊŸ\óÒ°4›X(ò¡ùáyè•t6÷F h ¶šC3¶lôPW ǃïô¬§ñ?Q­ŠðÍq(ÛvÑNÌHVzd}ì`ú¿–iÞEÚÜÆó6'‰üц^8tä ½IëÍ# —¦àÅåOBDÌW9Ë0#Ž1בKg7’„G (×ÿ°ù[¹$‚O=1ž*FNðÜL¯*\Ê¢!¼ù30>¸äŸ¨Èã ’I¦½°%dûB?ÞÙuäç8ÓŠ…¼ùn ²¼Ë*S¸aN 9sŒätÇjIö›øž;X!…P‚¢wHnTwÇo¯½Ei¼R‹}“G4Hò)Q÷F3ÈÂã·]f$uó­W%Q¹eç'9=yn‡ð«)y-qpœ:†Xш±^qÆ0F2GN*+äk‰¾Y<´ŠULøÏ œç¶ô x&)½ÀhÀ¨Y$ŽØ#Ž„qžœÕ•†êà¤yÁÊR?),AçÜÕTþ×,ždbfU.—  gå9àn$>¦§•å¹xÑÚamñ²®åÇ<œ’}9ã>¼p5¥ÍÁá[¡$±6½³ú(8ävçéTd´û¬²Ák/3ê’8l/ õ©å•žÞ(Þ/9L³²,;g9=GR{uÆ*Y.m¢šPÖ…åD"VÌg nàu$’r8è8õ§k îáÙò.×ÁùÆO\Ó=ÆsùTö2\\Ü™e7Û¸–A«Ë8Àêzô#ŠŠîWŠÍc‚/!b.Å_am¹Ê©m»¶óß¿N1R<óÏ›Ûl›I…Ù²ä+2°þè-’ þ¾õžÖo5Ô«j!…DcçVÃãïüÇqÁÏà:SâÔÝæ•f,[:Éâ8ÆI$dqõÍúƒ£䌻ààQAÀe;RFúP‘ù‹&Ámå#ýö…p`^NOQǹ¢{Ak,+¨O._-Ý”«œ#㎀cüŽÙb>Ï*­Ý»¢m$Œ/psŒdäžOªº;ÝÛJ·¯,~k±\¶Òv²çž2p:Ýh›Ô¿ãúO­íCþ?ëEo‘/rîŠq£ÆrÃEÊŒ‘Âô®Šçj´b&y£*’0]™\rvý9ì:çt >‘.S÷q àd¯ Î;×O°M^T‰m26ï,Z.]àŸ˜ãä Êõ)lfÁ[º¬«m*l]Ó…ÇȦâ}8žÜT÷Pi±Áå$Ã,‘÷GëÏåR¶'™¤Êò@ dFÊH#¨ ½xÎ95^JÏl0ÜÕZC™7FOMÙê1ŒŸçR§ bY'0‡÷¸çŽU¿<àœ dÒIRÙD2F Ø‘ 9ÎÈï“íÇ­+­ÓÖŠŒØWwÎAä\g§¿CN]>í•þË; ©Œ÷É8,ǯðõ={Ð(QhÛ%±g`Uºp­·‘Àžqš¤c+8˜Eo iAX±¸ÆJã;°çŒsÆ:ñŠÐج–Þp†e;bœÙ•v=¾nê})²âæqk+»©e`ETœ¨ÚÍÐg<àô ŽË#½¶…rà(‘q†l`ôǸéøfknñÛyfFÛ±v]åÁ<“òä׎01š¬5xâ’)þÚ¦G-ç–F21œ'b=jÛ³4»ì‚´Y§}¤ƒ§Üñœs‚(9+Kq5¿ÙÖ€.› lG¡ç,=ÖòܼP4+>N|çÝqŒãˆíJ–7ÎÎÖêÄ…óWsœœï'9û 3ô¨®n?³î¼¤šhÐf+ÊŒãtÈó  9Œ|·`-wL¡¨ ÁÏæ~´±Gsg¾X¿|ó90Ò0.Axã=H2gÆÀÏ‘.0¤ü»—©çi㑎üdTö‹mh‘vZBŒ<¢›Õ‰(Äs·ŸJŠAqngŠçË-'.’[xC9là.?»éŽÆž“›wxbµ‰Cÿ«’6bpO'«pxý9«ê"AÕ’ˆ€ÞðD‡hl㡊qÔ÷íÍC¼£»g2û¦Ýð9`_豪]ÇyÁÏh‚Þ5Y^mA‘ˆUVHÀÁœ®=;’yÉŠ9ÞÑßæÜHF8¯ËÁ‘ërÆX®n™á¸x÷“!9ÎO …ÀŽœò8õ'öaya­ÉhÙ™Ìä縿¿¿¨)µ9¡¸¹,-ŒS|‹N¡]sÙÀnÄ?Zš §¿•å– Ù @xüÀð9ÉýOZdŽþÖà3BZ7ΉÉó[8†Ï'Ÿ¯4«²_÷ÞFÎêÛr@8Âcæ#ü;Ð{¤ÔÔ°(& ó>çRbǃsžNqÍÚÛªÆ.T§š3¸Ï¸`HÇ'ú8ÁlàÇ2Z6ùdbd’P*XðX`ä/QÇ~¸§F#°€4¤ÉoÐE¼‚zœç¯Lúœš‘ì`³x®eHEEÞù¾™H·`zûŸèZÉ»8I$ŒïÜÄä€^yî:ã³ì­H±I"7 ëä•NyCŒ·ÉÑj¿m´K°óµUsò{Œg¶xìOàbòðZÜ[}í0`´‰";ÁÆ0ª.þsÛ܈áF–B_c1còcæ= ô?ãV£Qm¨®šÍm+6B°“q‹'ïc#¯>£ðªMQ48ç2-°IÆÖêO®z‚Gá@¦¡·KŸZ)úˆÿMz+xü(—¹¥¡º$ ¹Ï—8ôïÚµÛOx¢yZXÎÒ¬.¨Á ÏgV~‡ŸÛïPÊb‹*zÅnY7‘§32IûÇÁ†)¶äœÃÛ‘ïǵe?‰úlAo{iso @#Æ|ÐÌrBç#ƒN¼v¥‚ý$¸y 06‘æm xzEãŠnÙú–-$d”XŒ`9öÏzš)„­º‰ °†%‡Ì6àF é´dã“Ö¤b4¾D¸†Å¢ÉÜR0\è$ý ôëNÔ läHüøI`}ªTuèFàŽŸŸ4­:&ä†Ì­¬ª ¯˜Kd7röéÐô§ ¼‘éép÷lóE¼!n$7\çóâ€) —tóM“uÂŽ½È>„qëÍ-¥å¼žl%T #¾æÛ2Ë‚;çù÷«v{må¼PÆŠÄìŽM›×8ÇÔcš­p“¼ñ,;Ï*çÌã¿Íœã<~&€o£k¤H&1p褪“× uàëÔúf¥’Pd†ËÊ’\èÅ=wõëü$÷Î(¬Î°¼[¢2Ì$ ‚ 뜀1À§µÊE‰m,×nHs¹_Š[ŽçŽ£ßŠ{´Úîònaܤ”uKÉÔsü«.šÞ主W@±ÙÐdaºýF2O¥h&Å#Ë,¢à–’Ø©”ñÔ[8è9ü{T·i)¼öÅ•Aƒ{¼G‚ÀcûßÔæ€3¬òöò~õ$‰ o(LB䛫sÏý*h`s{*ÀV7ù%Äß,›FWc~lqž:PÕ.evò­^WU+,¥YNNpÞ<äà8ª¿h]IÖYÈhU˜)¤*>øÆÐOùÇ­O.X|µ†LJHtxKtêG_× óTneû'aÚƒ—‰Kõ'<~J²gP‘ÆÀÆÌ ¨£ž‰¸cqÏ¡ëÖª›Y–O%n¢û4q€èŠ¡ÉÎO'‚HÍ\‰Q,¤¸H!œÀ£q‚r3·$·¯LãÔQw‰âŠÚe‰ÌÎãøþ÷n1é@-å3Þ¯—r«½v²m,˜ÏPÄsÉõäÔÏ’æÕb€‰âg‘dŠ\•cÁìW“ש©ŒV¶q¼’ìs)ˆE!lg€ œH'µU_°¤BîÝAÕL޲3;—# Œïœ}(Ó¤¢|YXÈì²âVI•zœØºû ­=Ì„êá#ó$Û“œŒ”-´}ÏãÅ^K¸&¹{…þè „/;ŽGLçŽýj;ÈÚÄùÆÔ„•Á,ðŽ_ Î~ óϽ6/"8ËÉç†j)ôÝNà‰$kyfWÊ’ØÀúí-œ`g=¨)àt%›rVUšYƒí×—úª‘h¥‘ñä"ÊË%Ò~…rØ9éùŒp*ÿöf¨bÛ$RØŒÌyá=Ïj–ëOÔ¥HŠÌŠÇrÉpÅ6ú·˜4TB-~ÒÓÜÆÈãpòÔ++ù“€pr0;ÓíÇš qn‰>ݲÏNÓŽ¹ã¯ÝÓÅK>Ÿ¨N-C[[ñ›–.Üz„õã)²¾0É‚݃Œeæ,ã$‡+œqÓé@cTµ“÷òFg.dhÈ … ÎxóÓ¯ZcÀ’X&·”ÎŘ,ŒÇÎOËò|€r9©î4ÝRâI~Îê#>@ q’PœdgŒu©`³Ô#”K$pÈá €f` 8péÖ€)Êð´»ÁŒpÛf$~^Ç <ö=1Kí°’;òÛUÜ—ÜF7tÆ×§8ëé1±ÔÚØ[„¶† ²–=ýW9_Ê¥k=JFfxm]Ï˹¥|2Ž›€ž ö  kf‰-¶„ž)÷m $EÖ@O’üŒÛ§¥Z·û-»4ƒnV^cXÙU˜ö98ã­O>“©M— JNCy¤…é€ÑÇ|úÑý‘x—PÜGmh¬ó‡™0ç®B ~søä±‡7‘yolpÐD¬ó“ŸîœÉµJío=̳$È`JÌÄŸA´îô¯6;H‡ì°Ôga˜• O8]˜Ç§®hŸO¾‘°<¿$V?0®rºc½RUHË"16w¶%ÀÁÉ;‡ÞN˜éÒ›fÒ¥Ñ?ñ”Án‡$“¹G·©ëÓÓFK]GíSK6ª$R ù¬HêAR Î3ôJ…4ýA!H˜A".X+)VÆ00:uþ”—ºÏûBVEaa”•TÈ€'»:œz|Io,Êò0Wd$2ÂUÈÎK1Î7€zž¼sZi×Ò`<6ÛFp«+('9Ë|¤“øûÕvÐïÓd‹o%ÂåNÇ•Çü>Iÿ.gCqijáï[,£û¿Þü:äûPŽ«senÒHóïrK9 Œ1$8䊾ln­o Hp®Rv—9?ÜçðŒT©c*ÉnʱD±±.±ðÁp¨ ?ZLjýßêh«ZôxÔ¿àùš+xì‰{œ…‡õ­:Î+X¯—]Ñdà õ`üL×ÉÎÛ?ûôƸê+Øú½'öQÍÏ.çcÿ /^þíŸýú?ã@ø—¯ƒÒÓþýñ®:Š>¯KùPs˹ÙÂÍñ¥ŸýùÿëÑÿ 7Äôéÿ~úõÆÑGÕé*yw;#ñ7Ä˧ýùÿëÒÂÌñý:߯þ½qÔQõz_ʃž]ÎÇþgˆ?éÓþüÿõéáføƒþ?ïÏÿ^¸Þ§¯iáZí‚Ñ¢ˆÿËIÎÁúò ‰R¡y$†¥7³6ÿágxƒþ?ïÏÿ^¦·ø¯ÎdËZ.ÈËÿ¨ÎqøÖjøZÖ›ÍZ5aÕaŒ·êH¦^ÚèÖ6S›)®dЧï àg¯W-Z˜e •ý "§}M;‰:ìîë¾ÐmFoõ€Ÿ_jŒ|MñÿŸOûóÿ×®KHŠ!~Ÿifœ‡ÚpH#ºs hWýR¸„öóP8ý1XáêQ³ö«ð*q—Ù&ÿ…âútÿ¿?ýz?áføƒþ?ïÏÿ^¨MàËý¥ì§¶¼_D}­ù6?CX—vv»¶š=ˆW?Lõ®øC ?…&bÜÖçSÿ 3Äôéÿ~úôÂÌñåÓþýõ뎢´ú½/åBç—s²ÿ…›âútÿ¿?ýz?áføƒÒÓþüÿõ뢫ÒþTòîv_ð³|Aégÿ~úôÂÎñ¥Ÿýù?ã\m}^—ò ç—s³?µòÛgÉÉýÑÿOøYºÿ÷lùÿ¦Gük¢«ÒþTòît~1Õogóeò7c,xþ´W?EŸ`æ—p¢Š+RBŠ( Š( Š( ›ÂÒCLÑG߃òÆí¸þ÷úsOÔõKör&©ô`ErÕv-_PV1u#'M®wÈ×#êIÍ3XT²µ‚IæsË®áÛ©5ÒC‹ˆ7Ê‘³zìù ÛÀWýL÷ȯ9ÒiØß˜åBx©ãyW¡5ÐyŒâÿï‘RˆãH÷,QgýÁþ{&Æe¥ýÔl'ÚºëKû™t÷þÔ…>ÀÎn€ øg©ús\eγ ´qOå¯OÝ¢©üÀÍfÍsqrCO<’‘ÝÜ·ó®ºx;IÈÊURÒÂ\4Os+@†8K’ˆNJ®xúTtQ^ªÐÀ(¢Š(¢Š(¢Š(¢ŠÿÙÿÛC  !"$"$ÿÛCÿÀ±`"ÿÄÿÄ_ !"1AQ2a#BRq$3‘³ÒÓ4CETUbt“”¡56druƒ²Ñ%&DS‚„£±ceÁ…’¢ÂÃáðWs¤´òÿÄÿÄ/Q‘1Rq23±Ñ!4Aa"bá¡ÿÚ ?ã;Š–}2¦Y³â-s t•-IB@Vp’ Ï/sèZél|fCHz=KN¶±”©.»ƒÿëkŸì/ù¡ß`Ù/¯û´kè_‚›ºe;Á2a(ôÚ¿@ýAö×¥½[Sy®)®b1׳DLßãüÊö¯KYÉÇüŒöK_M éøþMz7¥ùþMdÎ^:çytáQ£æ3ð9?ædµ{úZôüOù‘?í]þ–¾œÎ¼ÇòkѼ¡‘§ù4Î^:çy8Thù‹ûG$úR§ý«ßÒ×£àh?â@?ïþ–¾žü´„?öDÿ&²Fô†£ýèœ~Í3—޹ÞN>`þщ'þDþõßéë1ð)'üHýó¿Ò×ÔyÃÿ$ɬÿ,¡ÿ’ 3—޹ÞN>^þÑ(ÿ2õ]þ–½OÀt+Ò“÷ŽÿK_PþYÂÿ$שÞPò?‚ 3—޹ÞN>^þÐÉ?âP?ï]þ–½þÐÍÿ™qÿzçôµõÞp½âj~YÂÿ%g/s¼œ*4|¾>´ÄÄß;ý-eý šÏüÿÕwúZú{òÎ/´Qz7”oòQ¦rñ×;É£GÌ?Ú³þ&ÿê»ý-eýÏÍ™¿úÎK_NþYÆÿ%Ô;Ò?ù.™ËÇ\ï' 1sãgüOûç?§¬¿¹éæ|~Çœþ–¾œü³þJ5?-û.™ËÇ\ï' 2sÂø¡CþõÏékßîvAÿŸö®K_M~Z3þM©ùhÏù0Ó9xëäáQ£æQýŽƒüÖ¿ö«þ–²?Øæƒþ,Xý/úZúcòÑŸòmOËFɆ™ËÇ\ï'3ŸìtIÿ¯ÿÓ_þz‡ûQþotÞ¯ÿ=},­èÿ³ cùlŸòQüºg/s¼œ:4|×ýÍé?û¿íWÿž½þæáþowý¢õôåºÉGòëÓ½Çù2—Låã®w“‡Fù´cr­{¿íW¬¿¹µäµ_þzú?òÜcûØ.§å¸ÿ&˦rñ×;ÉãGÎûÛÿ7»þÑùêìoFä÷?Ú/úZú?òÜ’å׊ßôd霼uÎòpèÑóˆþÆöÏø½Ïö‹ÿÏ^ìno=ׯýªÿó×Ñ_—ü™:ƒ|Ÿòd霼uÎòpèÒ;ss_æõ´súZôcs9î½Ïö«þ–¾†;íACø2uâ·Ò³ýî3—޹ÞN>z?ØÜǯÈ/ýªÇÿµ¬¿¹º>3öz¿Ú¹ý-}­òá0`­òïþág/s¼œ:4pýÑ¿ÈþÑÏékÏîmc=@WûUÿK]ÿòåÜÿd7Ùþ!:g/s¼œ:4|ü±¹ó{Ÿíÿž±ØÜ×ù½íý-} 7Ò¿ÉÓ¬ŽûVðd霼uÎòpèÑó¹þÆö¿Íëÿj¿ékÏîn@Þ ÿj¿üõôXß'ÞÉשß'ÞÉÓ9xëäáѤ>rþæô/ý¢ÿó׿ÜÞó{Ÿíý-}7Çý:ËòÜ“åÓ9xëäáÑ£æÿînGù½ßö«ÿÏPÿczø½ßö‹ÿÏ_H~[òQüºŸ–ã?ÞÃùtÎ^:çy8thù´czÈÿh½Oîoü^çûUëé/ËqþLŸå׿–ãü”.™ËÇ\ï'5ìpOùŸíWÿž²þç$›œÿh¿éké1½ÒöQüº÷òÕÿ{ 3—޹ÞN>jØäþ-pþ×Wý-x±Ñ#üX¿ö«þ–¾™Í¿xÃSòÑŸòm3—޹ÞNCæ_îvHõ«?í\þ–¼?Øðþ)WûW?¥¯¦ÿ-ÿ&Ÿ–Œÿ“iœ¼uÎòpèÑó'÷<£üÐÛ9ý-yýÏZaþÙßékéÏËV?Éu?,ãÿ’3—޹ÞN>bþçö¿Ìßýg?§¬ÀÇø”ÿµwúZú|ïHùþõÔü´þK¦rñ×;É£GËçàCüKÿÕwúZŸÚ ¡þ%Ïýë¿Ò×ÓçyFÿ%óòÎ7ù(Ó9xëäáQ£åãð äLÿÞ»ý-yý¡[ÿ2õþ–¾¢ü³…þJ5ó…þI¦rñ×;É£GËŸÚÖµ{úZÇûD#üÉŸûÇ¿¥¯©ò‡ïA¬Nó…ŸïM3—޹ÞN>[þÑHÿ1çþõßékð1#üF?Ú½ý-}Jw”?òA¬U¼áÿ’äÓ9xëäáQ£å¿íœÈiÿhïôµöŽÖ?íþ–¾£^ó†="'ù5¯òÖÿÙüšg/s¼œ*4|Ãý£Ûÿ2#ý«¿ÒןÚA?æVÿÚ»ý=}c“þeGûG¿¥¯?´ò#í^þ–¾œ;Ò¼1üšóòÒ´1üšg/s¼œ*4|Æ~„úÒ#ý«¿ÓÒ–÷Ù›~,¸îCkç“×Pã™l„(ƒ‚³èG¸×Õ{×~-šw[­Œ†ŸX#Å#î { |³¼qæìž}en®4‚¥ŸR|%jöW»ÇùÄMsÎ?³ª*²£ üìùŸÿç%ÿ6uýÒS®CðÿþhùÉÍ£]{ct©ñÚ¯¿ÑcíÁynÐ3\₯™òܦKTv›üË®òRÒÛ„„ú‘ž×»iÍí~ò¯¬Ú¶mÔn7‡’ J›Š {»B~ ÖªêV×®M{>-Ñ?,û«e·x”¬)hJ”]ùOòjüÊýþ¨lxo~C°…&=|¢àÀ-HŒK‰?‚^µ‰ÔNâ'Ä:êÙþÁÛrÛ•,Gº’²@õÆaû½Oã¥ÚmÕ}cáæ6ЂúЗfâu§–¿#ÛÔÞ˜œ ¸Ü²Þ¨ÜЬaÆ ‰²|B¬Î!e‘ç?¬;ÇYÐX”¬UüIa–¯•H§c®-rvë’¸w‘ÅÖ9zçƒôÆ­‚¸³Ü××{reY¹²BTŒ 5%ÎGÙi…Á*>ÁJûgUö–æÝÛ–žÂâݧLj)iÕÙÊWÎ "8D5‘ŒcÎ:Ô¶7ÞÚnr¯k-÷G[Ïu‹umƒPÐq*N;Jæ3­wïE³ÚQ_«Û.ËÇP†í…\µ%*  ¬¸ŒÅ`‚{ƃ^ßÞ»¦æ#óÛôСÇp3!ù¶’Y 8}Š OßôRGG¾´WÅ›önZÞÓŒðSÅ‘%3%&8_,:â$wìG±ìé¿gØ¢-""¦=M ¬wùºýÕ“ gˆä[m¦‡JÁ÷O¯cB7’LXLÛÄŸ¸Ú• ÉS,*cð–Ø>œ›_‡Ï#!JǶ1 ?ZçÅ Iuù6–¾H.Roá© dð(Œ¢®¾€Ÿ¼·<8h}U›]÷\*ã‹Çœ| „Sb.R¶p£ôÓfË®ªoMw.¹éÎ*<*ûçÖ¶Û¢”0.A s@ïv­ß3¸÷ÝTª·Qò¬}ŽÄh®È8Ê–„'’ȃëüšuÛÃ~Ù$ˆ;:å”òKh¾*p§Ï8ý¿ \^âø„€ËÒ6mtV]d<\‘dûE¡î•E ë¬á$} Ónï¥ÛÖ°\•me´‡Ë§¹Ÿg0“À2ðqîkåÞ8ιEݲ¢9a%öÛ®Ž˜éFÜj!E^T©‡€R³È+ˆq`u t‹o¾¦CDȔԊˆ°¥™>3\Gé—^‚„øŸÃZ _|C°´v ½·¥´Þ9ʉpô†p}-GQPúà{ã×K³Ü®ŸElûË Ñ¤Fùg!6ô#@w<‚ÜŠ¤6ØX'¼,œ“œèUd¶„>~Â|×ã-ÉŒÑ̃(JN¥ “ø… ¯¾ƒ¤Þ9ñö›‘bøn!kS§s’Þy°’Oân–aoíÙ&j[5ÛI¨eÒÊ츋Ñм $©¦V U‘Ç:_Ø53÷+ö¶U;‚éR_YLMl¾#·Þx¼ëo(¤Œå)Pôóh»û:—nÈÜWæ4ÙÕá¢R¾Ü†ì¬cÌôvPÉ!=NqÖse™q¾Ù‹-è°öTçc˜ìß<‡œWê¥FAÈìq×ìÕj­Ë¼íŸ­cdJAt2VÝûª ¨ä€´ˆü“œ{¤gUþÊÛVqd]ª˜ÎE_%XŇJB°0¸(W}ž<í÷ÕÈ{yVV»WOAk°Ò}‰y÷’H䜮2–Ú³“æþ8Ϊ±‰ú¿Ší<[Û-ÇBy&ÖZ•õ”ÿøw¤¶7®ôûAès í*•4ÿ€¥ØÛ¼Ê¼1üþßw>º=òr:©3¡nfs,?)Ù!n5Ø-¸îŸEtq ÛãhTíæ ø 4uìID‰FeëéO’G†—R0Qxãê:ÕðTJE®÷V»)>¢2qž2ÞWÖàÜU+Sއ®4joÝëº7 ¨£¯ÚÒ’†Öãó›°’¨Ì$z­1ɱå89ÎÛíOˆÝÜ•¶3·WŸ’ °y´§)³ÁM¥Ô«±•}::­ ULšëzù›:éµ2ÑKÑçGšòàP% Xq^7%–€ɨ‘¼¾!;º¤mÆvõ æÇ*R”ä‰l6¦ÓŒ­+v:B“ïï Bw7Å ÝF´¶Ý55¹-%y®rs¡ úåF2@)Çc>ýgF¶…W¿)Û~w¤2¯•\•1_·Pœ–|BRéÒÑ=ÊüÅVN²™pm–SŽß™*RJϧ/A|F;ý¿MM·uñspÇ.«hmç¢HHPl\ ¶?Òüß—×ÐŒþRÛpoê׿µ) &!âB­d…:¿O ´©€¥¨zœ {çV¾~NÎmP#¢ßiµPÂW":¥» ËQõÉp->¹ÀRIôƉï=¤Ô÷guîz¡ÏIy÷ S0ÒÔÈãÇXR”qêrG×@•}|D”ám»¶I§/Y¸ÙR†: Z¯Þ§ñÑÝü_KN){.™¢Óá—ãòR@!AJk‚†N<¤ŸÃßNÕ5´6;J%wÌlùPÙðb5^ÚT¶RqÍ¥¼êRFJˆzë›n'öü=¶£[V»ÌK©·Ñ4´¥#¨¸‚S‘æ Fr1 1ëâ]}0ë6Ëαåy-¢ÕÀ…þ¯4Å(ÏãËÔëDËߊ-Ïf¾=NÈ%Ò¤©˜W yL‘ì°”ù? þÁßZâµqcI®¼¼‹¸—›¯GÉWJœÒz<ÊR]A$:Àí^‡AámÚÚy²o¢Ùxh2Rk"Áv­©g™ó6TÚ”èÇc$ Ðt>.ŦJ‡°Ó’aë)18$‡Ú@°~€éVÓx|F‰`ä"lK $­ÄA»ñ”€”6rN4 ‘º7ÓL‹MÑ ˆ^<9Ž*rw'?+m +ÃwÞšä|;qÍÉQ:ÖE´Û¸¾3ή¶î)o>…†Ý$§£• ÿ(Ð\‹?â´ÇTK_†KD„øˆqVsAH{+e ޱ‘P‡uñIõ-.ÖmˆêK…µ'øsàÑʘaiXÉÉÈüqSdJÚ÷{¹U“´¥Jjæ9ÅX žn¹ÐJ{<ÃÇ×ÛLûÎÒ¢¥Æm¶ìÓ*æZ“ lÁƒõúcÌúY{cްЃmñNDI¯É®ÚUf“Öç»5‚¥ã>U¸({zûz{è#»û~7s"¡Æöbf±Ða¹r[ËÇÜBBŠ”=úÀúè½Ϋ²y¶´Ë¾“E¿ »å•¥Mü¦Vr9(röÉõþ!KÞ5–tXL¡€XX\‚Òd¶ë §ˆlHC!ä‚=[J±×ã ÖñøÌ¨Nͱ¸íåoJ𾄭IRìÿɬ£ïýüÛ(zâÕ F–«%Ìl6'‹JõÈìûàôQQ6äíuÔERÛCieÙuË^tž„èåøžC¾º>„–ö¨«¸ y4»_kÅrYmQœ‡FÚRŒqPIs P>™I èd½ŸÄ}Ûp؇+áõ¤©Š ¢4;GŠÒ³Œ!\Ð?nxô{Õ™{Ïâ´ Ç'Xíý ¥Ô²Û_2]yGõBAÇíéa¸c¦•¡7}@NãŽúÜn¾¶|#ÂZŠ”°„z*V ;ëLŸ6Ò(¶¢l«öþÛ®—æ1GË R”£Ñ>?2qƒŽ÷‚[k|Gß»‚WËÅ«Úñ–ð‡ÌÉØzp*á×y$ {ç­?»â³SâAñþ­R2REÌ€Ï" YãûýÚW°÷™ÜJ½£¨Û,:ðÝùZiQ0xúð%£Ñ#‘ï8Õ‰×mÇÂÇl4íì¦\ðfȘ§”®! ¶ß gÁ@8ýºÛø Ëñ›ÚýäÈ !öçM,7Ç×›¿/Áû è=¶âø‰È×E‹²läœF°’„ŸÀ8ë(A>˜ úzh-DÇ7äI·è«à»&_Ù|>eµ'¾|ËN)µ:( *×:^Ù·›E”ÈUË•“çÀyOT˵[ï>éåô[í%²Àé$zàèâîíûáËU“[¤Ä@SÍɽqkÁè4…’sì;ú}uºëÞöQ•";"Ͷ֔>¦¥Oh1ÈãΧ£!)ìzŸÀêÄ[}½y¢á­°™.|¤<ÒcLˆ¶W.’Ž8‚p=ëOÄÀ­Ÿ&ª½º81Cj‘T¥\$‘Ò—äc'ì3Þ‚ýtïŠÓwiÛ¦ØüT’¤Ìþ+*!$”„)Âz=hIÞœ¾OYµvýº+H…bâÚÄã.•6Øý£ñèèŽÒ*´«N椻ÝRœi!(S.6Øã÷T¢=uže_·ß4KÜ–7ÔZW[nöæFR¢"å¨Î¡…œ¡ÖÀ(>ØRRë ¯¸÷6ÿ Ž§."l˜J/¥–[‘rë+HÏ&ÂÙHXÏYN³ë¡;ƒâö¤q‘*»g¸•<ZºR•'–Ùl8SÖr”¯ ta­ª(*ænJݨîåÜ2[Ë…É1™ùpr<ž \J‘Œ(,¸{$§:%±÷2öí ›%ÓÞÊq„€äI“_yÁ‘“ÃÄq~Dýx€ôXÝûÁÀµ'òD6ÛœqOY'¾Š•òxH?S{#voå&4y?æ:çM".âZÜwëÅ¿™ úŽ9Ó,7©ä[FbNɵ‘í–ã“£ ‘šsÌ´„¶³–Èôʇiֻݺfî}Ýu[eWµ)2ÑX´DZ³è§x¸‡Tœ0;ñ¹¾%&aŒþÛÛèPAZKV/È+ÇÞHK,-YÏàqº6àøˆõÈ­û‰¶ÕRš˜ô‰ÈŽã`€|Æ&SÿÆ¡ïÓGwm®Ì²€õÃ([ÐJŸ‡ü·ÖQåò¥ÖÊÑæO¨Q'£œyB¾"M.\J±UšB%.Ö––‡hPã—c‚ Aú{è,^|EÝ4Ó"ǰ‡³ÐÜ’|9ý|GªÎåŒþ϶¼o|J“-Æ |9f[HBVd›Æd ’¹>ÓxÛ8ÕÝÛ_»¤møðX‹IU++D_›Š§\e>ªQJ£„!]d8„m§¶Îî§²™:î«ò‡·Ë’äm=®H s¡‘Ç¡ŸÃA¶?Ä}ôK©›³ ×%·ß7縦ÜRH϶“Žþöqè ”¿Šs¬zÁ»=…! RÛWÒŽ꤅Å®Æ:=4j¡;Nu.Vl­¬Óq’¶–†©™ÿ!ȸZ)IìR£ÙÒ”}»mU·ÂîTÚöì6ЦW&’Ì–¼NIãö­~š½óñdq)Í¥·aÁSBeIÝÐÙF3ž!%`Ÿ`R1ï¡~/îIV)‚­³XÃÅÎFÙn7ÃÔ¬)¶àO¯¡Õ…›v†ësY_@Ù›f²¼Nf¶‰Á 8¡°âƒjÈûÃ$wœô4ǺvŽæÝwBTz¸¹‚ãNši-¾´(ö]I_C zèt=4~c}}†‹o“ØþÀ(i[™iYÉèw žŽ3Ÿß‘«6 ßÐâ¹#äötµ4͘wR¤8 D¥¸GÓÜú®‚|JnÞ—hµc½¶ìk/‘qrùLf¥ /åþo’Õž†GZS§Þ÷Ý£5é©©++m Hyå´G¢Páp+# =g¡ sÜ{¶•¦Äˆ»FCÎbÞIu@ý¯“àŸØT1ï¡ÌîÍìg3~ÞÚÕž1W†ì­Ôß`g8KJ?ðþM!8îÛ©ß2i÷œ~©`7*=Ì—Ö˜n”!> ÿD¤ÓµVë¢rªr¥ÃRÇlCŒÅD–[BÑŒpT‡ R*ˆÐZ…¼mì&9_[ù)a=<‚cG³ž¥¹Œçо@$§¢9cñƶH¾ß­±æ¶ÎÙ™ÎÝmGåN%Mü?ðÕ«ÅÀÚ4s6ëôJšÐðŸœÜRóí„EFq¿/dN}:ÒæÁ²½R¶‘mm[ SŽC§ž—Râ€ûÉñ¼U€zè¨'@_{_ï}³5pFØ£¸œ‚àu·n8ú¹zqJã «öŒMZ•a¾ Á­¶îݪcåÔó®M¿q´5FÖ¿–╞ð3ìs޳®êçuÄ•Éî›8{“U1¸²c¼œãÎÞy÷œäÿ dÞÇ.ñÛ;}¬•= Õ4Œ®2²¬ô₼¾WÚ}ã@ýñ¸ÓL›Fê6´„¸‚ã-Ò”©ôŒƒÁKe(WÝ'ïke.ö¹¶øÕô%O3â†~zzÖ“ØR*‚;âHúÙ–vIÜȵÛ×Òù©$«7܆ž8ÀBBÛo‘ô õøŒº"[ƒ»±ïÞ~3ꄨ͞mñ<‹/Š `ñ9ÇGLˆ ­ÍlÌfßù‚R~ðsu-…6O R]Šƒ’zƧïÖÚmÃxîâ‹QsK_ 3!¿.;ñ¬ŒŽIh´’ KH)ÅÈW¿Ž»ÑýáµU·¬¬Ûâ² ÈÏC†Ô7Rž– ÑYH@ÎrAú¶DîþÛ5´²l]v %€Ô×”óÌ©NCò©JZ”U”«=œuÞ“+{¨ÿPü¸ŽíÁ¬?Õ_þiZí•Y„f¸Öîþö°ÿTù¥jÖ^º{ÇÌ"®R ðÿþg«þÒWóh×\ØÿuäŸæz¿í%4uŽ®“økOˆþÕ}þ”±öàWyØ*®ÏkOE+—JjÝX‚„%EÜÁ–; RA,È)BІˆ …ŸÃ‘³Tj§WÖ[CfÆ^àD*â¦!™ìGž€Vrµ#ÀmJJ¹‚çX?wBîöÆôº¿*ÛUPDÅQ«¦Cl‚ ž+jtc¤ù¬t@ëYI½¯Û2ëêïwŒËÖ¢¦eGŽó¡‘Äc¼²³Þy°=1‹Tt·3‘g¬8ÌiJ%Ó)öTéPÉäÙh'®ÿÑé¡0áÒmÍÙNý<Û«˜Q[p53#,4âÉ+û̧Ÿ}ýý0ÊšºzõöSQ)×B—)Vî „˜èdxÀ¤œ‚´úö4—;â.Õ«š½±Ú¯Æ}-CzÚ“ÆBÆÂÚŠIÏè­?®ÂÇp?1ëDL“2¢ XŠP>“Å'Ê€¾ ã¼Àã–ï™Ö——5–P>TUJdWó.0e%åP, äp¯CŸ~µÑ¶ SØhÝQçÇa‡Ô"ÁÚŠŠŸˆ•¿–Ò®¿K£hw}m fáÞGjµØaQ”jVê™`ýãåShÏÔ…çë  C¸-þavß‘,B•PÚ¼q #ÁÈÂ]mhZÐ=R¯ÇÎ=úã!ץ׳·cHRÁç'ÀQÈ øˆieDòè‚£øL¬ëS·5ô{ üºS=w€ÛìòKó5äÉ>¥C9ôë#]Öìƒ*ìi6óÕKrAWQ8øÇð ¡Ü6ⱎÐIÁÀ:èZVÜ)›ržîRŠ," )ÂónvpC•‡gÇCJ)gr:ô¸Œì¡2)çÐõl—\¯*–TR¥zŒ‚G ÀÖ0ã|L…g+ì¥6Ÿ\xªŠc4ç ].vÔ¶@> äÞö %ªfUa'’Þ‹&Ébk JÈHJ›fPSIç™=ÐOc@æýöô²f-},f©\ù_ ImÇ”Ë ë(`ÚSÐÂÒ=²q®sa²7t³*æüNsrˆÔ–R¬žAKZÇ@cˆJ¿ò>çgìù2*éçp€Ò ÕUÝüãnrm2Ú_s÷xwØ>º]Ø­míÙu¸e_mºtRÔ¨¹(ÉñÝ–ÿ—ʰ´4’ )úýtþ&×"-<=ß·öûÏϱ–¤,ÂRP¤wÅHKg ôÿ¯Ø5Z–.ê—uÛ’ ŠôÆRf$¥¨Ï¥å§ Ò… ¢pBUéƒYÙõ[‹rIµVÍÛ÷q¨¨’'@k1£•¯ÁuN6…‚N À9ät ¿á†ì`ìkzÔ)ˆòCOG‹ÌxHÂKéC‰q ï-ø™W§Ó@éUº7Äé)ݼ۔TëQfcÈ}bKm‚J- ¥÷þŽŽ¿BÄh•öZU¾í.ÅÇ>}Ùên%o—·TRœ'¿¨ ò8Z¢UÚ¥¦nS}RxªAIÎs…ôNtl»¸¶íÙnJ)tõ\Äø‹mØ-½9Ó߉ԖÊ:!<œ?\ûï‡eaó•W¥M¹qçÜá_;p!)‚Áš+±÷uuì[[xæmíÈܰ°Ýïð(HF1á&áŸÄò*ôÐUÛÌî†÷tªºdÆ›,ž•µ(©„:\’ÜoB3œòèÖ±ék¤þGG¿±‡-Ɇ‰ŒЀ‡ÊÈàŽ cë®G ûâ“»Ö{+²±´¬›æcN….ÄŠp¥êÖÞöyœuÄj­Å@Ã"o2Гdý"Q=áË¿3¥ÃØ#ÕIOXë@ÿyOqF—$ÓÖ¿Y Å aùM«æ[aœt¾-©ÅGʤ çÐiEê{ú-Æ]fiºL`žNˆ³UÈœýÿÏáj÷é@'àjõ,è;nEД‹ëXË 8ó•ÈSñ°;m2aô<¾—cmÆï…f"n™2C‘/-ÎZˆ…)…5N}}T„ŽòN‚ÝM5¤MÍÉëi‰ˆëÜ"µa^•Ç XÏ8‡ÒTRHÆyPIõÕOŠhÚw“륚z7®+ •5É-½Kð”9pPp ¨dà-kN}ôcò"¾,”?·M w£OƪPx/‰yKTÖ°JŠ%>„«Dö‹ŽZ|¬É²ìœmõFŒÊ¦†ß’ T;A.q ô>„¼;Ð/ÄÝ WT»†º4hÿ0§¢0óᅵõ)/)$’x^š¸,·•Å*b«C9rYunMŠãÎ@ˆÐÈ%Î%kY)ý^ñïLŸÝÃ3ßkÀbBìvÞ¬a2]i)'#“Ð’sŒ¥À1ØP:B£ÛFª]¦ä’Å3à7ª˜›9û4¶„BÊò ¼õØQÁ÷÷ÐnÜÔq#ÒRmݽ¼§¶a…|œ6KŽ´âV¥-~BIÉ'¼î©µþÌiç,Ù•¶[rcѦÝÉB^K™'¾IduéW°¦Å£"ÁÊTLŽì¤?*6YJ’µej.¸Ì°µ(g”‚xö:Çtìí­hÔ»‰+Ýqô%Çܳmè`3Í–Î3ߨXÉ õÐs­Î™.ï˜7pî]œ˜í·Â3NE\"““æ”…§ÃÿGöN@Ñ17qmÊ‹Á³ÜöK}Õ²Ò,†Ð*$™BZPp€Uëœä$ç¢v›g`Ψ…6L}—]Dguða÷@ÀNCŒd’<Ê wßZ­{h×mz窦ÓYÙ70ˆ²Ë– ì(4¥ÍG†œ`Ž»ÀÐ "UÍ+ˆÜõ1&\UÊþú5î&4†}’ [~lä…¡×Ýö Û¹.:ÌFë¶Ì I†k´ÈB§)m`šiA%'=¶qû;­¶ö}·åR©Ÿ¿iðX±ƒM’•Ù*[ﺃ€TžJAÕIÓ·E¼&§µ·&¦¥j\IÖ²æ×Èq”r%MCˆò*rl ÆH›¹©díF%KÚu7•.Îñ¶óËn;aG¥ÚH+€9#99)â÷Äh—­0ºªcO)Kq‘,9óÚH’Û/$x„žÒ{>º ¹¹žº‘\׌ò¼¦Sð*"²[˦Û[¡KWx6F;9Æ{;žÕYˆÛ)·}ÇL7‘%\Þ8¨–Z9÷î€;é8Õšó]¸·³u»«rn ­!˜Î":>DÑÅãªCê.ו\Sé¡»ïr|LnöºE>òFé…hT©T •¥€TŽiK«G‰Î@Aì’}4I¤'oP¶Ÿe2—pݹ%1$%¿õã‘âéðÉI>èúM¹Û¯G ¹Úõ’,Ÿ„Kˆ’Ü–T·'°´ ”” h,}tyañ)¹Rž‰—ä‰Ål;mH‡šrCjISd‚A<IÈ9ô×› ŽúæI{u^&ÞÇÀT„Á—°Ž@qñx‡Ðy[+y}ôî:;é fÝêç¿5庸ÿ+5 `‚yèà„{)I=wÞ‰®¾òsP­>rÖµ²ÉL¦Y®æÚ|5a*Ãø‚*öp5”8ÏY¸WzÛ×ДUݸðf+0×߇…!N†ÀÁIQÃØ³)ãÀa,#hÖÛ¥)æëÒá}\Çñ~²Ò¤_:ÖydùRt÷÷äÔý ªøt“¥¼~½ÅÃ}¶P…T‡T±êrB’sž®ìûJš(©b¾©¨N&!‡5uÒœY*l’ V¯:B‰ÑÈ/É«»Mtýϵâ°YL‡Ø²’–žCßy+P=öUÖGXL{éëIáçkíÙÐS[r:Œ•=’p´¤Áq¼çÈë@Šþèݳ"Kq;b‚弡 C©}Ã!jQ9çÍj ÇDŽ ýékjQ®¯â4)ócUǵË盂§ÂP¤= R^ ˆ%#XÔm[i—r¸X£®Œó³){ySdÎ_<†|ã J2òŒèD¨Žoj0Ë‹L:«$ ª‘[É*v"‚DgBI'-Ÿ1Q*ú¤2îCü þÍq½Ú?ƒXÿª?üҵط*¿ŸÙqíÔsÇýNGóJÕ¬½t÷˜*å ¿æRÿí3üÚuÔ¶:¼Éýºå¿¿æSŸö’¿™NºnÊ8ZGã­>#ûU÷úRÇÛƒèÜk½¨ë–®ÙÑó+Ì c9 ëŒpN}µeLôµíÛ¸†·Âþe„HäÚy…¥”µëÑ*)zèþKOÉÛl¾êÛevŽ”«#/)þ-ΧÜ>§´ýànìÈó˜BU¼S5‰˜cÝ›'Ò‚¬¨¥¥ÄâØìMd]Ö­Ø­—cö¨i¸³–·Uóe×pùx<„8® yRx÷ª•Á«†Mu}i~!æâ,ߌÿŠ{感 |™ý4³COC&©©Ðë…ð$ðL‰4o©‡ŠSÙyô£ƒÉqíƒéë»j¡çÅžÓÛwÌ:îKó¡×CŸ¼FÜp8A'>~Jú´gíÈ6²ZÛVb×p¸‰).ª3ª@hû)){Õ@¨åHPÈë½ £Ûv¶ñó-+à_}å>Ì3ß>R´èuÝ•û³l ˆ7 F‘-´¡oDR^=…%¨T¡€0Vr3‘¥ë—>&X¸‰û·|íÊéªcÁd.;Œ>ÒxŸÎ´Ä[£ ñ½Fƒ-ô¹s©¯ L‹!Ô‡“-Ç"9õÍ @8ÀÏI÷ÓMVÞ´Ûp,àO‘ 5)†¾Î•™*}—Ým+IÂ9A!Ĥ\ãIÍo ÷ý˜æ÷–‰QCn­éqd½ ô£ÙI¡Ð\ë ^1Ú‘¦ ç¶Ë©›¿„åó²Ç9r˜ùˆ‹ ò—Ô§Pß›¬©c®ôŸ“ñQÀ§võ•㵕-)·¼gÛp™$yƒœä Ö–¤õé¬6Ô½û»ëX¹˜™o©ž$—¢ÏZTÃDág“O„ô1ÐÊG¶‚Û.Æí7E½CpIIvbPyEæT–€W§†Ð¯ß¦êú›O²ç/³Ú¸‡§KŸ Œ8¥`µ’ç]‘ËöHð6äw IÛ¶ko¸ìh1äMy¶–3€¾D÷ìV¡Ÿ©Ð‹kê5¶_†Ôµ¤%r:ù?0Ÿ¼°âRŒç¤ñެÖ"Æníû][„¼ë­6’hÝS| óxÊ’ÙRÔA-Ÿ7º4Çö®ÅÚŵâf¢€¤D_‡1n£¬)µ¥e`¬“ža(Æ}€λÚU3Ñöáœüg’TšZé¯A>eòma¼~$ }tò—mžÕ}‹…mHäã (.p…±ë¡·÷›ZÒŽ¶U –6é©LÍÑâÑÄOO°VsÚU$ï8WÑaØK­Û+MœÖƒ«ZDÉ*’޹„Æa°AÁâIÜ}A“yÇÙpj\ ‹ ’[¯%ùöÑüG–ò”2§k%@t2}4²ßÂφ“® BkrÀ6²Ô•GŒ›ƒ½Dl#°:${}{hØPÙÞ[~µÛ÷·, Ÿ›²‚ÚxÉ{Èp²¦ß² HJ|LŽÉ©¸öÁj:'.K[‰÷Ø{‚'—Ò§c<¯º¥³+‡2}ð•göàèÞÞÛ’®Áp$Rn)—hQaÉieå´†ÖÞT€¬9p9Ï·©ÞÍÍl¤3|± qR‚¢O¨@Àœe”Œž?t6Iúêñøo5É­[í_v¥ÈÁ#ÁeAXÊÊÛóõo¯ß¡b\Ü1ojöÖØDhÿÀÞ±­‰5J•akµ…Ð#-,zõí )_;m¥–ëìªæ?µå #¬\FáÙGq›H'®Ï,§©;ãkÊ•¶.×°ª‚—‡¥<ÒX2A!(q¤¡Õ$«ÈŒ õ¬ö¬8¬m™[qÕî+™%)Wㄆ…xI8Ï2qê‹Mý+v¡6ÖPle0’û•BÇìÊèlp¤¬9â•$à 6¬NqÞ†‰­Å&-…^æ•ëÚSc¸–å%–sŸ2œ*+c¢ {ûº¸hSª}½U¸›‘Ä¿%Šö_ŽÀ?tx~ YÉòãÓ´ŒhÅ\êÃ$ÔÞÏÚ¶HœÊŸnr]ªÓ,t…—••„t<¡÷ªõ®XÙ¡šHˆŠRôŠÊY (`žÙS(RZ8ó$¥D÷ Y°°‰¢4­Å¶Ó@ÔÖÛ®m-ÂðƒÁ9! §²zZаzìÙ[_eîû;zål÷"µ m§Å“ÉÇYJÁ ~*Æ1Öusv1««…ÃXqúYÑ aµ”Ûn²Ò\hFPG¯e]hÜÝŽ9GBžÛ›n̖䆙\¹?=%Ô¥-´Úš£’:RÀÀ?´cløtõBª¯gü¥g"ûîÙMqyj?à‡%`ž]‡`õª4ûÚ´n·TÎü¦)§K$»gÐÈ(ò„”†€)$ǫ̃®t¿/vÀ•`–á]üJ“5æÒOÕ‡D‚”…*B–@ÇݾǠ5wMœHpζڵձæ>— J³3Ý”“‘–ÃŽW¬žý“ï×`nU³S' å¶ OmçSq‰}mç’¦–¤¯L»¦Ê¶Í¬.¬+"Zñ”¾ŠÜuMæSËs=€|ÉIÈsj-Á.É÷œ©goØÈ°ufF¢°”ã Èœx;I€Œùu×§ðáÇm}eŒeáL&iio/àØSèÏ}y–Gʃs|LÛ³7¼:Èí¤“ß[Š“ÒŠ ûÇ´¡$kÚzFvæòVæ©n¹ö^{œwZƒÌ>RO µ¤rGÞõ'* tÉñ Q7b— Ù06í”nI]u„¨¯8´”“â´#…)KÆ0¬ìGE{mXÐQm‡ÆÖßõ0že²˜æA‘!¶ÜegŠyõåC$wåÁï@Iýï´Ø?3z"UŠÙäÛ­¸–˜ZÔy%¬²T¢3åìà^Ž«·»›Ým‡-[Û'E¦£Fyø*A)’’¾A)Æq…œu¡´õóaÓYÚüóÖ®¥kRÛ­¦2É(mèÏ;â ÈàNFp0tû»fm QâPÔm[ç$ (>âhW’<~O°P•g9õ=z{hlU3q(9Q*]{ì–¾BºÅ´`‘–£B‰œýâJ‡®‰nm·ž²›–àbçó…†0¯ ””¨Œ”ƒ+ßTØ2äYNW¹jì0–cÙ—&)iZ€P)m¨ADr$ræ¸ã÷t'ázÚí]ÆÝÆßšó‹z„Åâ‚e,%Hx§ žRž¿w+_†_dÊ–å´]Íc!,rr$™®´¾(n*{Š8\x‡¼ãé¥(›“sÔÇ›³.,,RIQcF}¤'´¶·PÒÐqêâNû†„î«i ¿7p0c1À)æmjR[’ŸÓã–[è`áJR±M[;mV¼ä¡Tãà2!ĦR!Ÿ6â¤- Ÿýà_C]ú‹z­ÝWplºzˆÏ¹ÎÂTæ Ø6ÛJÎÀ%•Ⱥ} õôѯ‡uÛ~]¤‡œÞ[~ÅÚåºbÃ\ãlBʺ_„–ÀpŒ*NNO˜è3nßeÀ‚ôM³´ì\„sE‚£°¶˜YíJ.- à J½T§Z7V­n&¢ÂRbm > Bœ}o®K¸õò¢ŽÿÑè­.î«Oˆ„± UÃ5±sÁ… vvR·ÖãÉ ú”ŽÇÔà¶z½ôN¹´ë‚\LWàªæU¸S'¥¶†×Å)QÇÞÂÇcAÆße z\8õ;ŠÉ—Ò"E„Â\%?¤ãY)pqõ%?,év¯@¯}û ® k¿>ä¶*’Ç¥)àç“÷JG¶F™¥È/•_AjÓÃ͸.Ä6$¼Ö2¤RÚÜÇI!ÁƒØÕ©—•{J’M|ÉÀ%*i ΊãLËpw…I~?™õGç¬çÛ£ PÛ,l»ëšzäíµHM˜%ë»%¤©*Q=‘ƒÇÞé凵nÆböîÌ”d¿üR$Hq¸­´Hpœôrxô:E¥Þ¯X̶™·vÖÚÙÈj*"Ï´²–¶BU÷Š<ÅOc$'¡õÕË]çF–Ú#|o–Ü3>¦Àeœ”†dJ*NF=Aï=ú ;kêªYðéžÜõ{qÆP\K Ú>ÙYZ»%Hl«Ÿ©8Põ÷ïVï“».¼G7vÑCEm¨Ï&YwæR|‚Û)s9õRO`hSV¸¯ÙLÙ³Ÿ¯ŽÁn\Ðô¹+°¦ßâÔgZ¸­XÉ$uÚÞÛÝp¤9 ÊÔm»4ÃAKp¾Ë=Ð…@¡-EŽ:8ÊO¿›AÒvtR+¦_K‡¸Ý¨àqÓJóÎú¶–@@)Hë[)ëÛ@~&üIÚ‚cPZÛ숡åüÄQ_*(ZÊzçäm$‚}´뵓&>ÏnKèÄÖ|FPv@=!o$þ’{ýÚ¼-+åÔ&Š_ƒHÃÍŸ”´c Ç–GèŸ;ÏœŽÁÏ~Ý 5›Q]ºnê†kÞ[Mr’SÈv6J’°TqìœdôÛ+w´ÜøR.÷#QRÈChƒ(AŽŸ¾¢¥)ÁË$ãˆ#ðÈÒþÕ‡µöýôÆ]Ýõ‘ìÊË’Ù’¦”ò€ÈSHàžˆR”¥`÷‘ë•jì§î×7TÍåU4ÆJÛeU­8ʧú„—XS+H†ÙÇyÆBõ_ÄooMa&ˆÓ©¥8Ýœ©l;â6•+)’ÊÏúiúè]$Ú÷¾&×E[QKS•"L0®NEà¥|¤`t;ÆNj,6½.ÁÇnÞ\[)n6ý[­ÉüùY8o,„ÀÎLéeºó_¿©T–^„ÛÕ¶Kj¹n>D!ŸšZmç¤ò#¬¨äh îubõô÷×"ÜñÿS‘üÒµÖwJ¿‚}1®M¸¼¬Ô¤4½ZË×Oxù‚®RððêK¿ö’¿™NºFÎéÁûuÎ>ýIpÿøÌÿ45Ñv†‰ëßZ|Gö«ïô¥· _[aøô-¾ãOÚkP[ÎøHJÄ)E—$àòo\zú§EN뮉_E¸DweG*¶®ôtÇ×mñ+Bˆìa)ö?ލüdJWD—$&2>Ö9p¼¶€þ #¥-`“èx÷‚t#oN¹ÚÕ°m£ÕÔÍ®Z.—Ó 0Z&RŸüòSŸUŒþȼ˜'|=®£¤6BkéŸ\´¶ÅœÂËæ¯L°R”¤zàà‘둦:‰6[ÄÞZ*|0#K°š•ÕK}cƒË+=÷¿“\²ÓtËwu¶™öäÉ Ÿà‚¹ó¼S‘Ö—Gdæ9Ó%>ØEÌk7èí·ºn#¾¥,6òUübBÃ_â”ýÇzS&á· öæà›\[ZUb+å­.õâò.«Ã8#îIï: åìÝúÌé,C—J‡ ¥[(R{Imn¥aC°IJ•ë“eðãí²yÚ|U®‹yó‘\½ÂÔöËJëø¥£ÅL+ö'Vvå¤9›‰Q[·žµŠ§™¸ŠdÉ.p$–’„!0…O}zã+jιoe†d¹Ý ´ãÎvh–Y‚œvIÚ©k{³þ^ãR!N›8¸¨‘’[iN8´‡RÒ >ŠVÿm·Üòe® qå4ïæ$m9Had'*ÞNqŒéze^î™K5šÊùBxi(ˆðÛÞ (åвU‘è„%M©V‚êw-­¥m£uó­´uMݺìPÐ)HZ¦€ëÙ\¾„hke¼˜Ñ`¿Ëqn%åMndgšÉ% ó¥YÕ@)^“«tÛ¯rÒÓM‰g±ÚKÈy¸®;>K rZF†JÎR¬†üÿ\iÙônéµ°ž‡³®Xù)ÖkH0Â? âNR¬ý ?á ç²‹VÒø5G%¨N¶áhÎ4†ÝGé|égÛÊ]>¾ƒ[öí…ªÒfÙLe”»ü˜p™u—¸‚2¯ œ•zvI'ýéª~åqÏ‚D©ôR¬ ùF爉mK?x%M¾ž}Œ }}´¿s"ª%]Äß½ÆZ––¤-Á °ÌsÅõ8ãÉQ8>ˆV3 ÂêêÃw;_ pSÞíÔJ3fºÊ¿8B Ý @g?ŠB†3Ö½zãá½m„›+q¬X‚ÉŒ˜¢ñ.<Ç~ƒÂY[„ŸÖQ: ¹~!Ú=%1U2B[WÐ…eH[Oœg™ÂÓã#ØðÁÆ£wû â¿t)ØûfîûI„µ%é .*R2§ðqd!#®+HÆ1 ¿n© YÇ“µ¡=·´ÇtüäV$¶9x‰! 8¤þóï¢[Sfì9ñœ²™¸vô¤6D–\ˆÃRJHï€+.eYöO›½/ÕYløÛº4+ú6kÑ) m3 ^Yi ä€ÚÔQË¿7“—¾˜~,ìe"žÑ6rÚoÃmß—a]Æ8ÎR9!.~)FO©Ðyó;SrÞB´öÒ4•9óÙ.Ëeµ€ |@ã¡-t}HgBk]ƒö$ªºëåVZµ$Ç­¥Ç ˜ÒÏñ@¸¥xˆH8+ãÐzjîÖ»ÚlN‡·wžë•VÜX­–£¹] ¦_AHè¸JÂñë•%_]"m¸¶lüìúh¬î²ò|f~S¤%$‰+x¼‚Ú²x‘Ǭç­•ˆjL„ÝJ‹`¹<人÷ò`¨y””´”$,úôN=±í¯`ÖÛ^WÓÁŠQ`aÈ2qHkZŽÐV  ôÀ õÒ~óÞÓlcEvk=È’8©m@RÐèw´¨-ÞÜÆrJ°ps¢”5õÛšÒ#6wUT—áð@¨’Û‘Ñ$„©*ùfüÅXí²™C@õ¸Ÿ™Idçäí}¾åŠ÷‡—a¢LöÙI m*pq9Æ ’x÷Ö–7ujá*-Ó#® o8ôˆ6ˆ,©·` >â9'Ô`+€ÁôÕZªËÊÝÌì]Õñm˜Í·Î“º€ykÎR\hà–ÈÇj Î}O¦Žn[–Fán-Ó;{zJ˜Û&ÊZÒˆaÁƒù¨ì8 ˆ «¼ûtžûGqÚÁÝŽD*Zi¿ךaFHäâ[€Œ$à/'XÚn}›}ÂÊÇr|ú+ø!É SŒ»$dáBµ¨PÆ>º)i¹m4šø0ìðÛ®FÚ’œkÔ*PRò?WÛðПþ]²ŒŠ^ :éRÙ…¶T[mih…;É “ŽK-¨cÙ'AXîÙÒ"dž­§5Ú¥º¦«•Orê™<âÛ>*Rr=qõúkMˆY“:oÙ[¥¶”0¡Ù§“áTâ @ÆD’q„úc³ìwÖÕµðïö«“])vP%ÖÐÔugM¶µ2ˆœð4å¶gn-÷_LM‘)¶æ² çÙÓ!Æ.: üãnä=óçúdèì~b#(¯v–c“#”|òÅzÝ/%gÐòK¨kÔy›à;ûÇZáªÊ®Â\8²äWV +’ᡉ6ÐJ”ZS…>dÀ éÇpn+·QVà‡yRJY‘!×àHm@}§´`’;Èñ:Ñ8Ærù•½"¤ß’T¬¥1ËE#<ÛZ¤”œ’;9ë—[²íTò*Ó·o¤±¡0­J ~-!]vJ²¤äûÆ«¸ÆÆ¯j\«Ö$$,Mu™wm¶©'$ýÒ¢ã\rG„ âÕô E®—º¶‹ŽºíTFu!=Z ¶…«Ô $ôW«®í›kí¡M¼QWÒ®¸Ô9Tëihi'îÿT…¯×šýÚw^âØó6ÐÜ[ZŠ\IÜq-Y±ó‰[$¨ øéd“éç#öjŽÐ¤Û{®Z%ÞîM»&K€¢c+XðYý%‡V¬zàóH=ÝŽVíé![‹aWBðÝKÏĸâ›[˜<AW5.%³Œç]nÖ¡´§iµ­äÇD âPú˜ëŸ1ì“Á@-ë  zM-È­šc=¶ê_¸±“L”²Ë5þ"CŒ«9)ŒÚ…'*õJ{Ί6öÔ¤’òªQ2 “©ÆZª/ò$yƒ­¶þõâ !lùQöSuÛ§pXÔD›=ÄÉ”š˜ê!ÁŽE_1º>Þ©ú9¦o™{¡Úêú»»…9Éa3N·!Ò )O?9þ‰  Ð1-ت¶yæEL¹éHަ¨¥C%â}TP”…‘žKë뤭Y¹£nû…õí…k¬‘C^Ž6„ 3õ=+9ÈîÃyQï…}\‹úG|$9â²ìÅ)ô¨¥(-‡¡P’4Rš§qíØsîÜ·Ï/åáÅ™=ÑTV8-3R>ýžºúêY»¯oÜK‰AD-ƒ\¶W"I EP ¸µžjõÉ PM ‘e1úš½Ñu2©¶Øh­p…¬Gpc´%µ £Ÿ§yIõÉÑI›w|­{aÖqp¥Éñ’ÜPàs*C‹SimI=Í¡'Ë¥«ýƒuâ ½Nͨ‡­T¯³%že#ôSá ¥$žÊ”œgîžô~nI,"[»‚;j‰h¥:ìæRÚÓÚZRV“„“ÒZ~š³ºkf¸üeíêUÙX.S)m ¥.4ÆVêÑ=Œþ–Gã骳ª%PÖÎeúú¨¶¬:dD‰aqåÛl|!‡BÁ¤¬¥JÈPï[6–òjTqa]öãh¶i1Òä¦>…+! EJc *È ûÙ΃væ‚ìM¶›¦¤~y©ÄÅy÷¦ÒÔ’ñ€JŽœ‘î1«4?ز–ÖÝe¼ùh« T¨‰RœõÊÈS.8@W×Wì£Û7´¤C™S1ÛV%‘cÄ‘ aiT¥ø™'ž'ÓÓßT>PnMÙÒ\ωU³Úa"ÛUZ‘ÅÕ•%Ä8”óØ+Æt¸ô¨2î-´´‚ä¸Hâòã-•–F å¶RŸN*$„žµŽüfÉ>6ä`î7a‡¤ºÊ•&Z›Ï$yÔËžúí#¼ç&ÛÛ)틸Óqº¯ì,6ÜhK)„ùuöŸP$¨ãœ8ÀHZ–·ÓZööåÛû™¶æSѱx”…"4gŠÛ&RƒŸ+Ià‡P‘œ]dè Û*Ê3m·|úc·¨OMqǰóœrVOUŒàå#zûignÎWÚsëh›!ÂÈy…\·’ã'*eÅ#óDõ÷r2HhúåS~B†ª?( 1*ÐÇ?i)é3V0xð—Ì6qØJŽprž³¯!TÁ¶q¹ôµ›Ž<8˜-¼i}m’9å÷‹ ¢ŸO}-·a¸ã^Y0º'A~*X’ùæZ|Öµ]JB½{JJŽ=4ºíE_åc ~ÂÐÀu`î.DxÌÙJT¹iRÈýÜ; iæeÆÚÛ²¬¬¥Ø9lâÔ\›*œK0ÛWI i¼ö¢àP^´³b½•<=.¶š’~ÑŽgÜOZ¤©iŽ!+P ŸP¡œ´»¸elz—`ÃÝ×k¸Q,·=švTQî•Êž#‰+QÉ'£‚½64žEµ5~à­fl…"<…¦R`¤}ä¶Ñ[im@à$ÞƒMì]Á+{@´£ÜVrÛqð÷ÿåãä·BÝ+>ƒ¥‚=ñìO]¢ò§pFz¦¾}Ôéó-q&€¥º1Žj)Ym¤ä¼Ÿ·BivVä…n×¼7j"EenÈ[o;¯PZ¤8^ø*ÞßÝ[’º]ôFª„÷Ý.µ» ZÞcÝHy–P×,ç%|ý=ŽƒM½–æÜÎ߯¹r¶™lKƒVÌ´F?I %>ƒŠ²œ -VniÊÞj´„à ­‚ ")e.…ž ”ýáŸ8)P±«{§áÍܺgNÝ„‹•œQv?®ç#ÄBZ!JÁý‰õR{Æp¶ìØ?-;pmÚú(Òa!¿%œ8 8î© u.,Qˉǡï@[r"²Ö³ë`øÈR\q–a:ܧpQJ㟢Éýº§OGg2Æn£Â¬œŠÀ\ŽëË>~­¥ ©¼%jô%T1ß¾ƒm­Ô–ìË2u3¨äÊEw5Uàe.ò䥎øäÇÝèéÖÛ9.Ég[.Ö¾ÆÓE§VJÉé+nK J}’“èÝ=h(~%7Oš·l7š_šò ‚ØQi¡ß††Ì†ÔpG²@õe±\‰7õ¶J•l†aÌQBäW­mÃ÷JŠc$( ÷ÉC¡ë¥í¡_ºo7£;|oækGçÓY.™*q¨éÁà¿€”úI{êX÷WÂÛèå»hÛ¾r ®r_òFBšðò|©e.«š}B’@ÎAÐi˜ª;-¤¹›ƒsÇ‘5™ên¹V+2‡Á%\cêV¢¼Üp1Çß=¥º&CÛÌѱy>SìIuÿ×ÞgåšH âK(m^oT…œºÖ“¼¶M•ÜÊZˆÕa¸n'Ç5Ô@nS€ñ+fCY>"½R¾ŠÀÉѺY'\©;qÑÙF¬Rž‹g<ʈ”’þÅjÀÈVõå V±´tÅ’Ëò.¦Êp¥Å7["KL…$a4€[Wd`ç—®u,fnŠýÛ÷k'¾ëR‹ŒJùy퀔Û|g 8Ñ:Ø×[¯‡qMœ¿ÏJœ†€à— ADÇÜF@Á'êyÕÛjë¦Â]…¤”KŠÑ´/åä¾ sÉkiDà'Ð6çgÛÐIøƒ 3&Òó\ù˃r ,¨ú­o*B[JN{õã'LP©vÈUw°¥Xµ O­³)o:µHZ’¬œ'9ïÐu¡Ö·û9ì7#Tq"G¾&ºU„ù³ mqPSh–—„ú)I'çUcn†u$ÕJó ØPn)êjJNI]i( ã µ1 5rßå5ª¹ ÕX¬%¤¡ˆÇ¸ãÙ×[®Ü¬ÚíšIÑ>VÙ¦x ~Cr›x4yWñ™ÁnjJóíÖ”Ù§º®‚%=¶^}‹<&Õ½C im¤ö<JBÉ>©*JÒs‚3 « _ÈŸ¶ªª)žBœjÊÀúHÁu CiR'°x’@9Q΄ÀûY¿‰P`a©„ÖNÔóŽ7âÅó/`œ2NFN½–à=Ý´šÇ)gòHÜ(n6Ÿ*’¦›d-$wÇÃXAýqé¢öõòkþ#ОU®Ö¿K1ê×"·,)l—"q+2XôÆ¿¨ÐmÜÇø)ýšå·ãø—ú”æ—®Ÿ¹±òǬôuÌ/† XúŸæW«Yzéï0UÊB¾Ì—íCüÈ×DÚÆøëü9úŽéÿñ¡þhk¡íB9Û­>#ûU÷úRÇÛ…ýõÚÎf؃HËÏØ9n|$5À¨IVÁOÝ =\ÚÿŒ›Xó˜¦|:§<‘$¸Ê–¬„1Î['Ü8’;ú ytÌ9;‹h±86c.ä……ÆSéþ󕌡#'¿o\€ ·óë_:¢ïoWVÒD5®Ãm¥–VpêÐHm-“îH=úd^Aw¤4lí¾eï3h–ëËðʹgxmE´  èæIõÑʶj¢*5Ìö²Ýz;m!¦ª¼(¼æä¤¡ Uéê9 ‘€4ŸTôåÔØB‰¼k‹ðXmåÄÛ„´àÁ}Åø´¾ð ‚ñøQvÏíyˆÛ»ÂLèÈIJÑ:Ù”%³º´© ÀpPŸÇ@z[oIÝn˪nÊl×\æë¬U«“|È S¾8ô °O§z5W4–FýÖíù»EüñqYh-ÁØI ^r{`þ¿¦¹úv½dy)Ýsܤ|«¡˜6•(úŒ¶ O?^+Á=’‘¦=·7gíÙUð¡í­ã=qâ©‚ó”ÁÄ4¥Dä!E‘ÄññÐ:KFãbLΠøŒ·™s I¨€Û-…Ó-¥å«‰WOÓIq¦Óü6¶vòõ{ÅR¦©É"Õ ´htJÔëŠ9Q9J¹gך=6Þ>Õb‡pÔ×|«Ï¯À50è£!÷Òq€Q̨÷ú¤œ‘«ãy\î]ÀÓ\ÐÐÇŽ¥4¨–ÊK\pýæ–”ºIúEí §³¾&X\BŸ6Ú™¹`»¿ èÐZoÎz)y9()ýìŒõå:Õ]´wÔY5·5´ô°\».èr… à -²„r ôxßëª(,b¡Ñ¸÷#îHqàb±^¹#ÄÄ©%öÂCM¸ø8Ï)9ÀôVp>îƒ:­iáÃ3¶õŽõi<ë†3\ÛQö¹eY÷%m磓¡ˆØÓ$ø7USbÞÇ u ’ät¶³ƒØ Žæ¦Gcß8ÕÊËæ·dÙtТMHlÄ\ϵÐâq*ÀnBÓ;³€=ºÉÓeŠ\§¯ŠÅ>Ùª“G=’«‘åß})Iò%£ç+ô±úº–ÛV];r¬lè\JÔV¸É8ãdœòuL¶Ð)YÏè;ÀÐ]–½µBż9’›bRJ¢Õ¡/¸´ ñ[‰o¿ ‚»ìŸMÛòMËqªwet{ÜD6ÐÈE“‰#Ë“ )A$}Õ(Fr3V}qX g÷êé-ŸZZu¦ŽpR§ò¸«‡¸N>š]ìògɇ#妌#1à5Rë‹ÕJBVØJŽ=FqïŸ}[­+«“ó÷ª;­´+ÓmÒÂ:Ç” ½”¬ÐôÒd}¡¶s}~êâ˜ÈñÛ0`­HîóF\òž]¤wæïÙHÞÍ©€ü¥ÁÝ»†Lé¿0¢Åiu—€Wk%hŸg±Èõí é‘k.©¡=ºÝíuR[äÛµÑYñÖߺK¥ÕïüZ4¡ZÜ[4nÝÄ¿ˆpXˆÚ#¡¹tüßyj8Hæ·T’  Ç0ûO¡Ù²ª¬)­ïâ×'£-2“2Š;R\Pã€ãŠÉÇYPïê ײþ$Þn ¸uí–vçŠÒ\‹¸ÍÄäÐ?ƵùÜŒŸlqõ9ÐT øÄ,·3f†²}¤5º"Ì‚!2™LõŒ¡m•IÏŒ»Ûi·7^è‘ci_µëöóÊ”ÄûR¤ŒøŒœ|©»Rþ¦ÞM‹–Ó·„Ò.9(‘PûÉqRäÂÊ äe°O}t&+7ÏýŠüç¤@¯pHr¸^+$~YñG`ò*ìžÀšw“wål¯—Ÿ-3Ó"¨›"GÏDuιÛR\W˜ŒÇúb¦ð­dÇ‹º"Û7.²"lHKU«s¡µ! PÆ8ŒcðJÝŒíèÛ|ÜD‡@˸K”„Çùˆï@_†èK™#=¯°s€:ÒŽÚÚ‘Ø¿UƒÈn01™ârf2’OJiE«'ñ ö8#AÖäîInÝ×M—E¸¯>MðÔ/³á:|Î)$6Ø â=Ôqøj ­Ñj›g¶DݸÏÌ:bKz;Ï<•z—\)´¤à÷âuôÕðùÉ+j{Z¦¢¢JPæA 'Êqé¢w4£hmÄ* ƒõÒX)ù5N²˜êU˵acKƒ>ÉXõòú ©~×ݳ^MuÓL„›gkÝ}—PSÒB¼B@ @ðÔO¦1“¡;ª®¬ÌæÛÙ’ã¶Pò%Ôç,žn4â9ò g¤wž hßÙs¦F»m"ƸûjÈ4µ /lô[ZP‚½—®•IW»ç'—älטò›)4ÑÛCCÕmµ­ 9Y QúkGÂö×ÙÏ'íꙑæÄui¬kš¨‚ÚR– ÈÎÊŠu½›¯‡ÕM¦¦¯uGfž|‘ dhŽaÔ ùââ ž»èg®ÉÐ[R¤@±v¾º–=¤zÇÛì•I0šKØí—P–\ (ÎO˜Æ­îá*âÈʉld¼„¸ËŽTÄBBJ°¥%jy po\û§ØÚpoïïÕtÌ¥UFŽê«~Òµl©È¡8C•yHô$ PÐO‰?æTÚ§mÁƒî,f³6\Bò⊱ç-ž½èþßM¨»“zGDèþ5Ä6&Éz'Í̉ÂSOKINWâ Ä#D+÷sõäÇí\¬–ÇL0ð[Ó$¶NÅl%(Gd+Ãì}}2J5ºÚq,l ßÇó ³Oç'Oíýß[)¸rRú«_¯ù©v3’UÞòÊK¨>ƒ> ‚@΀mnÍ­NêL›O†¢}jŸðK•ÐYù@âºZ–µù””“êG®ӆ骕 Øôp6ÜËf›ƒÆ#FÉT”ç>ÂG#ô WŽF¹ŽåºglÓù!(²i´½e9¦ÌwmJ›!m6Gxô $gÓT¥üF¼D5ɺbØ‚ ³]5.0áV2§ yZÔGÑ]zq]æÝ”Ëæc™×Nth¢B ©¬xcGP‡8תJFJ¿ cðb¨9lã7-еdèrÂÐÐãRÃYQ%|†H8èp3ûJùuñê÷œëI[mÉ­¬?§e-õ«>^j +€$“Ú”鯆×dí¨ƒo["\©Ì²RÌÙNºñÇ>o—oý„N΃Vçû>öB¾!Wý¨§ã¸XuøL¼‚Èû®%ÔDB” 8åÖ}¬Æjé«Ù•© ›æ":‘&RÛløN©JzP ö9Õ}»]"²ÆÊ¦†+h#“ uºÞ 2ÚrR¬¹…rß/ôFµP;ºî.‘Éèæ»ˆejy›v„„þ’¹Ã@c qú‘ h¬».)'º¯‡Rܕ朽·5NZÌ{nÎi¢¦âFËiiòÚÔ8´QÉ\¹'¼'¥j‹i§a4{­¹6C’¥¥1~,3••8Ñóc³€>¿R ôf uOÝ.ºóoÇ•ËÅfÂÁõþH j?%¿N¹'£ërÛÚÍéaey6\„PC!´)×[)PÇ( -8õ•(cÜc]áŠÂn'Okn"D‡—y²ûΗâžÈÆ{#­—75›{IùU¦8·DéµËr0” 96·¢•8®QÑÐ4ÏÞ²âQA¯W1˜‘³ ˜Aïˆù…–”}ùûþБ6ûvÔݪMk7…ˆ°¾e*n‡T¬qW™`#ï$ó9õ÷ÓÄÍÝe²+ÛD Åobê‡+2’2R ÜÏ×ÚP·Û5.ïG³¤ÆšßÏbC„'>: #¹á¯!~e8’=ˆï@íá½{Á‹èh¶¨«k‚š%ÉJ/ò­‰‰ÊF О¦„ßlö&JŒ¨ÿ¡Ëa 8Õ;-J|0>àS«!J9è«×½VÛß5°Se «K‡•aòâ=Œ—ÖƒäøëSO8N?Àh]ଥœ§SÎä[Þ ¸Ê¼Dœøke\OYç}ÔŠ˜4ûV4Š=¯")ï´ëÕŠ}¸í4¾#Ìê’ʸ¨R•g£ØÒŽðfÊ=zùÕWÛ;ǘZbL{/™qÕ“´„+Ο§0U‚}“)þ%Ý3‡®S}à>µ3"]\指“÷;‚A %9öV†ÂÙ·¿~ÓÝŽO¨~í­›ÎJ\‡ìR€Ù$„û‚`õФ®}½â—7ÛzÚ°xp ™ÐÝ%Ç» £‘PJûó¡žòè¸ü`† x"ûæ,¶ìWÛi)Tf$¥g* е¶JO¯3ëê4‘í«·dªfâ›>ò%£ˆl¿2[‚;¡‘ã™@õ ÷õ=S—ò¶>êÛTóò‡Í¶†êÝ.­Ì‘…‚O'{h.D›³êw´èà¥ĆֲßË¿ŽÓD%*XÈÊO,õ…ô¹[‘íóLÝükFÚb²Ç圗¦°]ˆHG„â€3œ‘ëíbåíâÅʪâÉ`°ñVïÊX”0Ïà¨ð½qúD÷ï­3¡ˆ?+Û*Êœ¥–óíE.)Ô8§"òSªpò8JÀ)âr;Ð^ÜŸÞß»\ÒûgÙ©Hþezé;ˆ–ýÞÚæ÷ƒÿGØÿ¨Éþezµ—®žñó\¤áÇüÇ{þÒ?Í']jö°? |6ÙÚgù¡§ý©÷ÇíÖŸýªûý)cíÀ†ðƒÊ~Ùƒe"Dàòüx¼Ú¶ÉÚ!»92*¢xEƒà\h„ŒôÚ”ž!\½C‰üuBãc'uQJÔX$ÁiŽX¶‚ô” ”J’¯SÒJÐg@b¹äŸ7œ­½Zc-o¸¶˜˜ã)Yã„òB³Ùyˆë~Õ¿­Ú¼"WXL´B]BžMÂÄwWŽIñ”ü²F:eCw\öÒÞt«ú÷Ÿ¾Ü² ÙläHhi\°V–rè’±ì4j»vþPØS,`ÎxÅeؕΩ¤p#’‹¡¤¸Rì/ÄÎ}4/m¾crÖ^Öìz¶ç¶ë’œÈen‰ IJ”ï«ç8Ó]vì¨Ü•ó(îŸu†Úl—`7׊H…$%!JâQJëÔ§Bk÷LyP݉k)â7ÉùR$RÊa¾MôÞ9CCc=vxŸÛ¥Å]×mµ*ù[™)•xT“%ÊÉ©—yAଂƒœ÷éÉ57L^BCEÜ5°™ñß~"Ÿ€ó‡‰ ´ã)ñÖ¤úy°¡õ)Ó„ ÖÖ®¦–Ü­ª§³Ã‰LYˆ`Äy#²0Ën’= 'ùuÏ©¶Ä…ÐHi—j\æKk—`™•Ê9WIsó)i]ž¹$«Ü`Ä:½¿L—nª$Ù»X£ÁÛ’ÜPc˜É[ÁE ŽG*ä};Ðuíµi·“ ÊTÉ£K +øTšù†ZF3•¡<Ô£Þ?ëw¥gaÜNm×j«¶E $>¯+ DÇ×— ¥^øVR>ºP)¨Ÿ T¹pû4°ÓëLk«x!z©‚|%÷—8zzêÔÖ¦Åy(øU2}ŒW —·i.6•,ä–œ[ˆÉÇD}ˆÈÐnÜb ;´­*[’%pUÜe”V¶r‚–Þ*_4•z”‘ŒM7@­±¹SQä]íiÑ+ÀiRåT,¦:@ÊáóD9ŸR¯Lý5Îá[ÁnålýË¥ÇhÔô© ÏDÖÓŒ•°’p’~âímmÛ[ð8N¢±‚ã>:ߙǖ“‘ç ¶lªŠAö'@ï?kØÉ‚üuϳ °¥†åÕÁ†ó`¨‚4BÖXâpp `väÁN˜ $.FþaÈóöË!m¼€´sCm¡.@Ïzw=DKTΩžÓ3 ù§hKGÁò©.%#Ëëéûµ¶öå¡VÈÛ–â<µ¯.ÕK[.¨ô•pmàÎ='߯M0bÿâ¦ÂƒO¸*·$ë¦%ÖÑ^êCÑbùºJ™+'‘ëTcØœé–ÖŠ’.æ­¯§°›j^BÒüÛrQŒñWn)´Çu) *ÀíGWnêÓámîL¡o´XŠÒáÊ¥<{ (-§ :ÁÕêvìu8õ^ú±²šúü(VM¡ @ìºiHÈ'/¬z•VÐXÍ ·6íkñPò_²x#Å %´©"”’?W)9éÚÖ%½µ/7Ôðµ íza»‡ƒÅ(%´¯– è¨?Lêå˽¯¯—ЉUQÒ ÷É·= ¼ò½Ö]dàûè8‡B©6Œê×6ë2Þ²âó²}Ûè’Ã¥_¦œ¥ÇÒG"<ÈHëïè7m¸»Žæ™èïm÷àG}¶a:ÿ„¤½ß.e¥‚Ÿ¼9dàu¢Q¬6å~àvÛœ«”¸ìgjåª@AÃ-EH÷õñp’ëÞnY³¤¢NÏ•}¼âeà<¸©Žê'9_gd„§ØãEkw“Òj½¦›ö˜ät*£s9áN¯9RRYË€ÿø N;ütý±-¹*‡liÑm<ÅÌ„+?ż¥¨’}TýØÆ‡ÔQÌm™‘%O~\…–Ü]®Ùl"SKéHYm¤޲¥/é ó÷Ì%÷ÛíØ°¢iËì«'™á%IhàúçßéÐÑ{’%¥5ƒŠ¿²­·O•3'H§Š©ÕH[Œ»À¿Hƒëߦƒnšóµí7 ³¸¬+X¤v?è 5IÀ%¤, ¤už)Y>àdêæ×ÝÎöÉ[»rÔ5=ÁréºéQC˜ïF.bÚ=[ÒýM³!×]Aqô“×4ðK­8¢=ÐNH89'Q±°¤vÁ›)”µ®ÉñáJD6c3á§´¥@¶e•g³Ç>ÞÚr“]O6fæ¼ø–öáfD%¥ŠÙ1m*Z@ƒn8ùXNsçA¬«kÜõ¶аYD›»l]¬(©>"c¨àòᢰœ°ÚŸÕΈØ[Ý7& QoZ„Â[ÒPâØgŠA?Iñq*ú… ÃC¦\O*ºòÂÊž3ÑØP]t+²mG7r¤$vž¸ãþºmÛGüª…¯nÚAEéN²–™NrëÍ$¯Ä ŽšZ{ôúeÄ>Ýk’.êmëf¾ñÏÊ73M%¥¼e˜éZT£…G¾‰: gQ}¹G#wTÌ2æ¶KkоŸG‡Í°J {ûÑòÇYΘ]¬Ü1ªäÉ­¡±³ˆã¥ f¦GË„«¬¦Z|b{ïãÐè2v¯dÛGLѻ؄©¨Ó!ªÖ™yiÁH ,óuúx„úzj†÷cáŒë ¹÷rq—Ðüî×Ç sÓ.))mEG¢p@u«ô{æ÷ðìX°LÖY øóe‡d )$¨³Ám¯ˆÍÑõôÒ5~ßD»i-ÒÌSÀr±­–Ón0÷Û B‹‡8% ŸLñÐ7m}·º oYËszK¹ Ï[ÍZJ}rÚSk>QåqÑœãŽ1¦¦Í:o¬\™ñ"s’Ž\‡@Zdñâ\ ¤¡*ï°8òÇé*×mñº R6üר€…6óp%¡†]p‘ëã>ÖGX)϶¼Ýp++ øÕ5Ûeèò×sbÇ„µ1‡OóO¯”ºqô Û¾†fÚÚu)BûR$¸´”²¾KÁ<’Ÿ¤]'¾É:¢ä½ÐÝ%YE“dФ%*…åßo>_ )YzŒ¤ŽÇ¶nZ+æœ/=sE)بš˜ÊR j_¨mrc)¼žûAëÓV6">1XÍr×qÕÌèkJj[*B‚=R–üd7ĤŸT«8ë@U«Õ;Àº¨»î8†ÐëªK ÇŠ NÆu³ƒƒÛ|ˆô:Ùo».§SJi¸Ue*b§SK:ÜP8¤¡h}°á8Ió §¾¶¢»`ÕmhÖØ€ÄÉ%‰.½\ôeEtô–×à7â#× `¡~Ý`é)Û ÊàøNôÛ³B¤ˆëEŒ DÉd„çŠJZ)R²TzþÝzëË)OÄü¸bEsPPË(ž†Ùh­²O€êWKYòöFA'ïgF׺l-ëê“]µ«"‡Ÿ.JuŠØñƒ­$¤–ÓÉZÝë¾IH Üö°~V†³m]mù6¯(ºr ‘м¥¯ø9@$•sÙü\ÞPjʼG£¦±ˆ±xMÚbIä’Ú‹rrŸ1`,w÷½ôë$Îø‡m“•jHIi¸²œ[¿€É!?ui#ßÃòûµV¦›k8ìÙJGÊÞqåÅ…#çБÒRDe»Å^Ä’qUÛOÀ±ÙRìväÙݱã:ûŒÈ–úT†yq JÔê‚GégÄÇ~ƒ^ʸ6œl=µ’¢uk½}\R@ñ9ã5Ëa(qÌc%=öjî6Ý›WÂÚÏ’¯S(LhñV y6ë‘ØàS”yç²u£fØÇ€ê`C¦ckK³<Ø•å•ËZa<ãÇ@â¯|8Uõ'Ljd¦/[ªÛ{ªÎJ☳žî[ •¨¶ úôµ'ÎŒZK¥‚Í…æáØÒ`)Ò¦æE ¨¨ô’¥gÕ ç#8i6ÿ~[îBkN뮥—˜zDWßRK€)ÎrÛR «”ô3€Œ[2ÝÔ˜—2~-K „¸ô?b[ $‚ë’Ö¥éå÷ÞŒÀÚ¯__J•_YgVÒ#™J!E4¥€ZRy*IImAE,ò#88=k\Ãyµé¾Ë£¾ªÜÊD–˜LiA9y$³!ÖÒRG`¡$~hØo9T|_rLê´Üø)£Ÿ—Ho–Tp–]Ns”©.dåG:¡½î«¢9hÛFqkG(ìÁ˪û¨h£‚’“ŽÔ”cÛ š¸²iY21vöÏ@1á¢Ê$‡W#Ña !xO˜úO¡ÁïUol¡Ì¨•2ò ²jØ’†Zy§šK©âA_·Å•žþëÁ+c­¨Í3%Qd½eèˆ ù¢´ô•=Ù »ÄZ@õq ìŸRMȯAÜ-­ûËÆvŠÒÞ=¤W­2èIuÆJ›YÍ05ít':‹-™[-QLd¾Ë ¸¶e­µÚÜ’ƒÿð‚AÎ…̪•#ì¤^R\ÄnS«q1-ì\vøg‡$yÔ}8«Ôƒ‘Ëêÿƒ‰Ùbš ós!!ÃÒ!šÑ,$§#Ïá 'ÑD‚I= ÍíûEJÛÖÕ¶âuSMxQ¡=u! @À¨Å[„vŸD¥{‘¬~!møÌïµF‡c=»2Zq¿˜ƒ,°—”2–Ü|øˆdv_­Þ®WÑÊ“ Í®åHvJ–‡ºÅ*:€’’K«e#¼ŽYV~§@édÄfdÔµ¸>'NŒ†?1% ­ÖÚ’N8¶]çÍÌt Rןtƒª¶´ª‡sn˜R(lâË@mKr¡ã ´…}аµsÆà{“¡òöL8ÎCNÑ~m…º™³¬c-´¤•-Iù ^½€Äé>EUŽ4g“{´¬¡Í&8f:œ}”%9ŠÚd$9œãÄo^º›hn•Á]cGÁ‰)^;l1á´·–›“o¥+öŒžúÖ0®ï.#Õì½Nü˱-.ÂþS€· R‡21ú¥ö“¥ª$ü_fÄ:Öž¶ÛõòQýï2+a ' ä#8ÚT¡“ÖG ÈõÓôJM·"uÌÍÓ ÞD%ÏUjâÒ y+l+ÅÇ©(QZAÉ>š ·–ê†Ð7[Òå4ØCiûHwÅsʙãÄ‚ŸQŽþªí]nXáØ*rýÚY™O1)µ!Ä §ÌèrB<2 ñ ¿ÑÕ=ß6·àYWï*ÙTuÊf „[G#)9À)p6Žðyß¾ŽÉ¿ÛÍl«êÜ}sd% 4Ú*ä åŵ<Ón(z‘ç~Ýû®;ÖP6îÒ¤2ÜGÙ„Ê<52ú¥:„6¥dçˆo$êí5ÕÍÔ¨»R-3Œ9]9dÉOË3bT*JÙ $Èc¹cÓZöÕôêºHtÁ~ñOáA²K¡Q%.L¾Cè VÇIúÊ‹­•º·½°rU ¤>óhªrC’xþ`(cõP|ó õͳDÎàMZA‡)²¥98¢ì2á=§‹Ì-\€õéëë¡V[a›ÙÛv¿`ÔÏBÒ’ì÷*Ú x§­\ ¥>bGé€9¢U6Ö‰1÷2¶ºlÐó¬>Üua±Ÿ&‰Åžø‚TãG¬g'd;kÄ{¹©ëžRÔ'5îqá÷Pž<¥Å$ŽñåYRUnY7¶ }LXÊðü›˜k 9Œ~m ²êSê\u€1Õ‰Kœ¿‰•Š™}aj“O7ÃL©ÎHà’¸§å÷T¬÷‚~ê}05Ð¥1*\Ȱ÷nÕ]¢ÖÑ–ô”ÈJ<`UÅ3!$`c>Pq¤)VöÛòšÒžŽelk,[mR\aAť؜’Ò”H)óg¼úœÃýîOá®ssÿ'Ù¨ÉþezèÛ‡¸Ç×Ðúë\ýgþ£'ù…êÖ^º{ÇÌrŸ†Ÿó!ÿûLÿ44ÿµþøýº@øhä;ç?ã3öCOÛdþp~Ýjñ/Ú¯¿Ò–Ü-ï‹•mù[ná.ز¨öª!uèioŒÃ’Ÿ(s)ÁÎG¦Hï»~n³[–²ÃsÍ•hÊÝKoT¡õÁò ­o‚rO$=Ž5eïš^ìÚ©‡ 3/© © PQó¢ëØÕ;´Wû•§ß—[BõR “!³ q÷•)Ïu…޳÷}µs¶Ô‡¾æ!¤^€¹ˆð’™6%Å,Œ–Øq!QÏö>„6ò¡¶D…¹¹.)—Zó¸u”T< éÉE¡0¡d÷”2>šoÑÖݰüûš¤FžÙ\xRÛb;/¨ãÎia¥„œùBF~‡L‡b±:ç%5¦$yëæiaiRIRN~à»Ð"ÌÙ›7{:¶výÎݰ’ÌcÆ8ޏû(B€ò4ëÊIPÎJˆÓE*6üý±X&ˆÛð¾]Æ&ÆŠü¨ì8Œ”Ÿž+Gdçg8Ö­Ýu4§Ä¦¡Jz<*%‚6ÏÙÌ€µ$˜î O¨R²>éÕÍ,iV{ž4·ñ[˜ˆLîƒ`]sÃÂPÂVÉ # Ç024é§ï›½³;t1lÜZJ#¦aR_ZR Z!ÆJ°p õôêý¦ÀÞ7Á‰wOšyžLä7SK`ã‘QIPl«¿¼¤ãßBö“Û’óz»®EËЛŽ^S4šå2ÚþîAKg ù|Täçöº³žK–ÍmÙÌÄùwK6ŽÿÉÆ…2 rFH+?õ®€cûV(»³”Âg3 yeN¯˜·Ÿ)@é*R]uÄ uþ¡î4^ºuԈŊzmï\ÏÈ)µ¿±´¡Åòó qy?yJJ>ÔÛ+o‡Í¶ÆÔ¾ÛÒì"šS S¬‡8ùÒŒ-´û”€ǩЪ]‹¸jf6涬ƒ5´È’ôYHk­#‰äNp ò?Tç7BŸñ¨PÚ½ƒ2KÁ©2eÃûM ò§ó<ÄNy-Y=‘ª²lö~ë°[0ŒÝš‰sÁƒW-E*Tt´}ä•gÓ³—´ö¾írnªöé¨éjAøŽ²GøYAä)'¿2r\}õOyĨط¬A¥™¸à¡ðû’íKg6û­©ÇgÎ^‡Aí5˰h¯ ?qe$DBVãU•/@ŸôÚÊ’q[H÷ä}ê¢ïá¤Zd"/Ù3Ë3UòÑ%N+¿ñ$òàå»Gk·ý}Œ uj2Ãs>@ËzÛåä:âˆD¦'™C¼àõæ×?Þ{–¦Þ#ÛŽÒ|©²¼¥·%ÂÜE$Œ£Â+8_©#³÷tu61÷ÖºæEl—ž%¦œµ’ëo¥'þ RÁ'õŠô*šâª µD£»¤X©3#:Âqü<®©¤-%G#˜R€Ç§xÑ­¾¶üë—›RÃÇu7 %NŸðf9ŽÙW¯ñœT? E!õÞF—'pKû) )Ñ^©(q!ÒH%3ÎÁ{nî-fݰ“#ƒr܉Ç IRIBPJ3úÃÿÒúý®>!ÏxÈ™q"/Ê;â´$7 ¤dôÛ±ÚR”s“ÙÁôïD·•î-Ÿ½¬e”5•­È’ ©mY< ¢o5€ârë:O›¶éÒËVˆÜq¢DˆâX‘1Q¢­+ÁU¸Ã™l«Ì<åxãMµ›NÃÎ"® " ÈŒ‡Fe3Þ?ÁùPx¯<ù,“;Ô› Ù¸ôI¼Ú±ç­ô(Ã~ ¢—ÞYâBSœ=}Ðr;>ºÛAðæÏo¬¬û:DgC±ì™fÊ#îú¯ÄXe8r ôGg:+}·ÕO-©«š‡%¶‚Û[9qßaHPWâàI$œc®²4¿Y« ¶½ZX†|xÁø»‘ ¡håçÄòÊJr€â•è{Ц³Ý“xIªÛö±áG‚ò¦"\…10>éíÀÓ)D~ˆ$úäëdm¹½·E1~ÁKMsI\å¤OJYOæ{^Iþ,n´²åÓö2ªbl±s_瓈dÊkÄ(=ÈྊA#óHã’ ë:n¾ªe›$Í¿¹]Jfk7O6x‚0¿ |€Áóa9'îR­v(„ýE|ÕªÖÆ#EL¿óNx­¨ôV†]Ú’¯A÷Tz¶¯Ô½>¹Ñ_QU¼gLnkgçÚ®Þ>d8·ÙmM`gÊ„¯$zécî)3›´˜æÉÜŒ¶Ô€Ð°Kár‡@ó))ñöPŒz ‹²w3sÞÜQ-,˜™ó.0’ÛJCèøe¾K8µ‘í‘êÍ|¯ˆñD¦7,ø – Øqëi9*RØ@æ•ã %KB{ô'XZn-±!,ÓîC]Í´xE TÊ„ó…^‰â–Ü*ÇÓ–3Þ4bE LÊ—öõžàÜ‚RœÌµ¼‡e­©  _J™lúyTAÈó aº6†ÛÙ;f-µ[;žÐTR ù°Ï/¼\x7^úϸÐWÛ½·÷D¥ÙÉ¿Z”‚ÕÃTòIþ,r(_g®‰Ñ±ñ,YMW=*¦ÑÇ¡™KU­ÂŽ„¨ç/"9GZ^ß»WhÛV«wF§•i~XL´Â…báAJŽ…_›ñH÷à‘ŽZWsmÉ.Y³Xý…,6ÚObc)•ÎZðü>¸$-GÛ½l¸‹aI¶×*ãp×ɯa%¥'À›%aÂ’A[N«$(}RSŸº”úé½öhü&eÍÛ™uœÊ§BKœ³Å²§RO—¼‚qês£ˆÞõnƯ°̶ã}º˜ç‡TèQg “ù òˆôÆ€ W¯«£»M{ˆjq’˜‘äÅ%L“÷PâÔ¢¯bP'¡‘žçÇ¥R>Ó:Âm…‚J[Dø.Ïy°GÜZ”€=ÉO¾5»rîJUꮘ’…IŽÓc¥n žD¶VÞAÏÝ÷ÎO®—¥îª±"M1Ú´²’èy)› á1 yz¡ m¬Oœ%$ö? Û¦Êt†!|­…¬+$8–]zlz¹Í¤¨àqG2¸Íÿ/¦tÑ_Wgi+î Û U±L·"G’–"€Œ§$´êGyÉÂpIcF#íšt¥0`R&¶ld— ÅsÆ”ãшÔ?8Ê'®\—œ ,˜ûzüÚêm©™a–~sqEŽ· ˜é º‡±ÇõŸ}z9ò«7 Rnklf‰¯ ÑW2JÊ_ý-fcˆVí>mtvÿ晉m¹U-jÃõ Êr$bU÷¿8élàwž9# dœlØ4ïÁÛ‘h>!%ê¸jMc¬ò|¨žk) RŽÇ$Ž¿á­6›v=®Í†õ…Ä ‡Œv[ûQÇpdžn6Y‡£ÉØ‚F ­Ý²v€ƒ"±Ë›w$x¯>·íž(´” ñó€I ©¢r¶í·Sº*Ý™ 4,K†«_´b\Bj&qÉ[+…¹’1Ï$¯®›¢í÷dÖ×ɾرÚb )H«—rÚJILj†Œ1åÇ· zÑ9›j&¢|=·62‰r±·jž`3Ç*Kî6¼d)ÆXÐ`ûª¼TÕmÆööáˆÔ†–©œÂ稨eM‚b–T¡ŸFÈV Õ]ǰïã½uc4Òägg)R¸¦j2|‰ x)äŽût«ÿÈpøV©Z‰7”?`©ä©˜ìIžèšÉJ|î¥+BRê}ø¥¼€~š#ºic×½Woqc9õ)ÅðrNäj'ˆ‘èPÙdž$c)l¤Ÿq §µ÷Å,‰2#®ªpÚðÑÆK•ã>“åRR‡\CnŒ9‰>ú'"É6ÕUµTó‘ºíå¡2c‡ZÔ…ž"¥(Wâ² öÏ®…Äc˜v{tXMiØåLbí ÇeÄ+ÓÃ)A{ìç×ðÈÕõo•ÒUÛ×ÚEfîainÅRì—C\•……¸ÓD³Ø'õø€Tø‹ms_[qLí-¬ZÙ Hjè×4ûî:2‚Ÿ¥¬BPWŽóØÕm½µ*ëS.=Fß¹³±mBSV̸ГÄ)KJÚu§VsÑǧ Îš]¨›c^â î‹Ó*"äJEÛ™-{/ŠñölõŽ'¬çC6õ‚©ö›Tö•ÖŠ!ïéŒ%²¯Íåj’„ I ÁtxèæWF’¢G½S0fUWµ}RÍ4i–µ±*;QÝzB{æÒˆÂB°<á¿Ý¢Pwt©t–,í×÷Duq!O8ÚYq'!`/Ä@8ë‚QœëGåRw"«ÜñŸˆÓ(QŽì©SkHí‚ç—H'$•çðÐiÝ÷Ü ˆ?ví´y ®Ùo¿'Áx£Ž0m W±RR0A<‰:#ðÍÅlÚ{ðì§ÄE‡ŠãirJb½Öþ÷†Û‹RQIÏj>§SÕògƾÚÕ2¯Ó hÁf•¸Ž%JSo­-6A¶•ËÓ—xÕúdC±vctÛyÈR™’”Ȇ¹k²i ®Üñ#·àøCõrp¾$u óroiÎmʆ“6M³öO¥I„ãÌøŽ`…,:Q-§ˆ ´Ÿ©Çcu ]<ËË a*Õ6?"¯,7[m¸`Ÿ2ü/M¸F~÷›ï/¦™®·MÖ­0êbVM[+ J–¦ªÐ‚2´4ðwŽqŒñP¼´7lÒTÓí8{‹uIY:JÔú¦Å™ã–R¥ aÑÌ«=”„Žñ µ›Ûóv³S&YÚ)Êç)b_ˆôg]Qä*BœŒ'ß4½»¦¾†¬ H]ËN“âC…¦œg& ê qxè ý™·&òª‡có†šù§P†ðü–˜x%*À[Š* ä.³k…S·§%Ù“(>A«W”]šõ‹³’¹<ÿ4È6õâÞ Ð,ìè¶×ÍÝj°q eªÄ3¯ÄO\Áu ”†IPÏy:º¾Ö§°"|YnC†± æÑ:C’ÜlÓSÖ–óœä„÷íÖ˜w=mMÌ1k¶›rÅà¢ô©6M×±ÉBd-Yý?:F=‡¦‹·5{]2$Ðn6U¸d¶êž§°Šú„ä%-º”+—]÷Þ3ÈÒvëÕíI‘cº¶Ô…°Úc4ÊÝñ–ØHàq_›Ø(¯Û²ªîô{gÖVι–íò­’†›ù^8ãmsì-kI*=å)[˜ ôú4ÖÖ½oé›*ˆá ßŽãs¬ÖéRA@h +¼qZ€> u‘4{VCÕ“hÙS«*&+ż´LUK÷(X0ÕÉLç¡ë BMÅ.à…ùH¸æœŠâô;v#ËaGK[‹‹âð¾¸ÀÇâz㲩äLM¶m¶Þäy¶]`³g!%†Ð:ZÄRØ#·F:õõÖUuXu©îì÷ Êi¢ÌèlÖ;5+^x¶Rê[ðú gŠgT®‹} sªáÚ¬Áßés,]j<´œpCKKM¡ Uzàûh±w¢©$ì]dy´KSÈo䔬­A–›sЇ@!IIèè.ÜÜѨ%À¡~§5“1丷œJJ|áM¶ú–ãg P g¿®œ·½ 'ÖØÍzÆÁÊöR…%µÜ5 –T}PT¶T…‘…-'ê4´ÛLNŽ·¨ž±¸o2b&ãBT´ã•%MÞ0èœûh§tW5ÊÇo´Ìc ¦’û*ëNGixà”FZÊ3‚¡ßdh5Ë·›U¸nĨ°ÜHr2Õ6[±[˜˜¨t¥¡ÃZ»è‚JG@Œ®ÜÖ;vÚ3»•PÄEñޏ,>䙊HQàCm¥E¢2 Èú{‡&våñl©g]PÏ“,²í}˜ä$7Èà¶·G„¢GdRpŸ}ÐÛôrßycöÖMy·@ ¶yä!m•$²œ“Å)VU¦šDËÚd˜Õßly˜Ëu5‹‘$F 䵞?«äc#YQ¦VÕ½¼yÆímZSˆB\‹^C%þD: ú® VO 0z㺧uFNàM5 wi6Ö·ž®}·˜lðÊO?@à+’ýÀæ= v-•p¸uX–ÝŒÂR휸Œ)…GYµÍ¾)R“œ$yóS­;²%S»"¾¾ƒfÒîÁZ¥),?=Å© ²-¡'$ •úƒ«ßVÁ§ên°• ׊_–©ƒŠ\ â®_Ã@[@@¤ô:ÎCÛ^DUÑÔ­2%C|8†™˜Ùù‚£”¥¶™ÉJ=`rW¦xœômV“O¾U¼Ž*\K  ´ÚX! /’TžúÉOtw–y›î\X7ó$niëD%–òô˜Î-IõO…áÅXRI!9pãñ½ jtkKæÛ±Ú·2p„›¢ãÏñ>UÚKç?xäNN4ÝK6¶lØ¿q¶c®SEµ¼¿‘5ÌsW!nºâç#$ç=}Þô•kw ¢ü fmSˆu²¸Q$¡¥ÊWªBC‰'9ÁB’_QÐÐ{N-üt[^$çй\¾d£óCÅ„a#õ”NSÞ}^ö­jwUÖäÜ!3 2PÄEñnRAô m(B {ÂK\²=zÒî鵩¿6û4ÖÓ-c1Q<—åyœR”ä1‚® '@ïÓ÷ ÷ÿÞøü5Ïn¿äË?õ?Ì/]pÇÏᤠ¡š»3ÿA“üÂõk/]=ãæ ¹H?ÃL~CHúý¦}þ­ >m£ùÄçë¤O†óÿûLÿ44ù·>øëZ¼Jq½WßéÎÃÛKÃÿ¦¶Ù*J?ô‹Àê[˜ð •Сބ¦›uÔS ñ!Eð¥6ê„gäø¯%dù²BF;#Êsé£ë†ý†ïÚpãXª¹×mB¤–ÇÈK$å$L޾ˆØÑ ¯*Es·ÌÎvC©uoOyù Iñ@[Ecý%œ}uŽ {Z½ÇeâîšþÚ”¢äÊû'[Šr¢ê=F>êsë®}¼­7FÜ~é”Oyæd:YnÁ뛆žhŒ)+o8Î3ë뢗7”Õ$QÈ›EeñÎ5|:ÙqÔ_V%Å *'ñ´j¦ÙeçgOܳ\Ý5fÇÊÄy¹,…¤"›Zd)|±Ú”ŸLw ¾ææ¡´Êá"ÂDp•I®n,™8¼~H%]•{ã­/n˜{šMõƒ64[‚‘v T´ªS«ptAL†ÒÙïxúXÕ׿#5L¸qow¬²?+;jeDvËeÖÙPõ'Rÿ}²Ú4V¶`Y1slò#¬(ÙºÊÒÙ)%+í qµú}ÒÇ¡ÐZ¥­Þ¿”íÛ‚|f¤´ÓIuñÖGÞËn¼¥7Äzð.~º¿aWîK´Zͼۣz:Ó¶Aò[ÆI*q8B²: ý5MÝÛ·¦3ŠönïŠÜÖÓs`­ »×­ô ·ÕK`œz‘«ŽÞEøm K~ªÚÞÛš!À§ƒ€àRŠ–¯¼J@O¦‚îÜ‘3s2¦v¶ßºû:3 BrcY„•HSråÈœ¥õï[iblÅ\G±}¨ö %¶B[~bÒƒ÷<þZg9®¼‡[ap›+{Y1i+,«‚Ò Æäú•–ŸIŽyŸRxž@úg[~9·]Ù.Z0噜ëavÒ–ÒN>è@o)Pû½Ø#A­ý×±Y²{fˆ.@ŠÂâײ”’ïø:Ó‰ZF;àr¡=h-Žå•ö\jÊï´bÔ>â@”ýû’’¾ þ+¾Ê™@VIΠƉ¹º¯)©æZØ&ÑÐéCQªÂüY.€•Ìå?N9ëïc£¹?]5±"@vlË™Q¹ÌbËÁæô J£$c°AÉüN€&ã»§¡…6¿pì÷* ;—+B˜ˆÌ®cÌG…â)vHPÎp{~øycW·aASuÛ›Â܌嘘ØG¯4¡ÇïìõíÞµ·r'g7º§Ôã­ )Z&ÂB”¯@”¥´”uß`’}ÉÐYæïmKfTzû(²,¡güÂÓ ¸ær ܤ´Ÿ_t èþ!ÜLÚTJÜu^# Ú¾ùiŒû•:–Ȫœ~:D^æ½–Ý´è•òÀB_püˬ·-! ’ŸàÀäà©»¡wŠî’ÇÈL®‹1n¡Ù’ìÔpѵ©\])8=¶µƒžÔub‚Ÿjι‹Pão¾•šWÁO.ÕÉ&Atò9§ßÕ9΃¤U›} -­”˜”ò-"¡ ˜“d#ó‰í(\–Ëd„œyH#ß\Ò†úv䲟XÅimÄ©,ÍvBÝ^R‰üÚ‚Jˆè>ºaÝMÃííµå_Ê\ôÇŽŠ”; 6Ày)tñ@¥Xü5{síw¨m?u*ÉǤæË’¦1Ù) p=0T‘é×¾‚ŽÆb^èÛ‘`­Em-Âv¶ÁäHå’TVãjúÍgðÕï‰M]m½Ée\©ÖÙŒ1¦Ü[6¦³ÖP¦Jù`ý@üuA‹H;v+&óo4Ifj>Ç”·žm'îòdãñ#ÿÒõ ëÙoq\Ë å=kKrc «ž^k¿6¥à d! gÆ‚ÖØÝÕ“öâ¡\MU¥«®¸¥— *h†T¬…6ûÁ·â;9>ÙëXî…nÚ©°olîëY ˆ'>ÿÌÇ(Q!N%´:9ÊW!‘颛Ú-X’¨¶»±§›B㸡ZÂŒêe> òRO¡èè»,mö·d ]ð/’ŸPzÂk¯•à)kp¥$úuªÔ–Ö;êemõMkTµñfŽ6ÚDà•}çZRYZ@'èûýu–É‹µ›ßWÕ²íîìþF)r8{1¢‚U’UÁ))$u’Ž'¼Më ݰS,fiÉN(.{Pì—Úý$¶¢°;ûù`cT¥n8Ôë°^Ñ‹p[åÉÒ»×ÏË…‚ Ìg]Å'#%.”÷Ÿ]~Öéü¢© W²ÉQZ㮲Øô–qæÇÞâG]¥^ô*>'2¸¬¥}± I’­‡86¶T¸K»Á.cðЉbÍM\KIÛqÉõ’-Y]±ò䤃”óqO:·ß`œž½´Sá¦Ùe‰;¶¥Œ8d”µê—jÏÜðÔ['9ãå{ŒèþÏVäžÔëwj¹*Cž¸Ê†Ú[ÈíY ydKYà ™_}_7UZ3c_8*#ÎHC쥡Ñ <Ò½ýT• Pšú¥S.ùwŽÙQ‹!kCNd©M²ñJ‡ í$þåÐ÷ÅþáA¯¥ù¼ºß&y)ŒrR¥**}ô1Ñìýh[n,`<Üć,ÈXŽÔ˜ì€”¬rñ·Tãcõâ%C9 ΄EƒFÄVÚÜ.S_™ H˜k$ÆRÊ“÷9©ù'Ô‘ïÄúè:>α¨º¬_å4ÊY4³UÍqd½!Äû„¡Mg8 G¯mlFלÖí\ˆw¶svƒˆOÊ!»‡ƒ-GEõLK™Ï"SČ߶¨Í¦M}ÆìàÖZm˜•)†)ˤ:éÍ¥KiDœzŸØt¿¸M¾Ä®«Ù»krQ­å!ÇS(ÅkÁo>n-©}O@Û t¹øte-ëÕî½Ò˜Q(…%Ç•e*ASžžÀŒ {ÝNߪ7åìå?ö²dµ%Ù›_O:¯o_Dþ¶4 <—MgRý§Û °€Ú¶ñPÄä”â;IÏD§3jzUÝá¨M#.΄ÊÄØ)±X’‡ŸF‰eåð' $uœh:,}ó¼lÕ½„:iì¸ÚbÃK>”§Ëžo— |Š‘ìuÊo¯·2®D±µY(fEĆ@‚Ù[ÜR¯2p!ÁÞ@á§+kÍù½6ü¶ãÑYFæ°l­´ÎüZ|iþÏxIÒè­Ü•tW1Û&ŽÑ +i ±C y¤ðKM¥<@NI)J°¯@ë7¶Ü^ØAVò—]=Ù…³`¸™‰%žø%a]cõ”б²!HµnÊD[—eÖØu ‚ØHì(?Ö–SŸ@{9Æ—6öàÜÖ”èì·¥m…ŒY ­Ä6ë—˜áÚRú|,$‘‡3€sh¡Ù‘·„§\¶|ZDp­L×µ5×°àô))}ô¨¡üƒÉ®`¨7b–i!Ì{›0ïÖ•Òµ*B•Ÿ¢””«é“¶‰iQ²šœ‹ÆmjZyÖX«Ž¥-K#-*@O¶‰ï­¶Ø1ªÞŸ9i}¹Uì6ëS‹ !¸jæ8¡i`x£?¬OÕI:«UJÝ—*vÛ¯jCŒš¶¥d(tã¥ùl¥¥rëʲ}ûöÐ4EÞ.ÈZÙÃUöm$VEv{"ÂIò-¤(,+¢¾_Di†}œÄ±öh’¶Â½ihJa°Ôâ}J\@R3ÙOIÀN‘ÔÖÔÛ_TXïOTÙHlÚe1œY#Lø(oñO œã½o®ûÊÁ»i›n¿¼¶ô‰òŒ³Œ­\™#=ú­I'=(èZ\@û2÷ µ}ŵ„…´ÌV! ¯! ¸ôbµ´Œ0zÿï¤Å¹#Öm‡Û¸«ˆì¯Jƒ0må9 ø_à‚üE¼‚\ÛÜéïrnݯ´-ÑJœ¹1à!*­u”F’ ~9y‘êènηn_‹"P8ý.º£”äVÒÄ×>\%µ8¾ey¬q'ðϨ-Yn‰° Gº©{pÙ(‰r,gJ¢x$c‚Üyü‚;ʈ'¯¯¡­â4ú(/¹½l´•½lY»"RV;n!Å))8>ŽwŒ)VS×Ç•ùEc)N<犷 »áÍJO¡Ld$dãÎ?èŽÎ€ÞìǤB‡¹¦ª—dÏŠàkì¹ S톂¹¤'Äp$…}Óƒ}3 éTîW½»œƒjÁÜ.Y8†ßeÖü7á£$­J<TÐÇ ®Èèg56»q¼¿µvZfÖÖ9,1=©,ð“4$¥ÖÔ—J€O\PRŸsøëœWî6kllo¶ÞÕJ+–K0ã"*‰xç— HÉ Æ~„õ®‡·/\gaÕ¸™•°æ(%-.6£”Ÿ\¢K R{ýÛ JšÍ¼à­­»÷U¥md…¸Zše³â4R®¼p§BTœþ·3ßG@m6üv,¥m´ÖJ¶®†Év’Â\ùKnQÀ'óhK–ÓŸº¥62}týºjv–èm­Ã¹­'ÝÛ5òQü&ù¥ ù9"2°’FNBF=ÏZÃpm *ÚiU5¢EuzÏ7ë"²Úå!!|²œÅä¤ÞTIüIÐTØÛvÊÃbíé»bÚDU&Cââ {ž H¯Ã>d4Ó((Ç™ž\ˆR‰%îwÃÿÊ&£E‡¹·\aÁéˆD·¥´ñOªJÔòV`¨‘޾:žVØSslm}ƉC µ4aå©’JžðÊŠO$ÿêǹ ´E¶ß~$;+k ÞIyúùIXa¼äp%¨«þP°ž½}´ Ò~¶õe¡ûnÒ?ÙÏÇCsŸ['†pW’= ý]YÙ;›sÒ"–²Cˆ© Dw<½ó=Œå©µ´Ø J}ZE3å*žÂ¢“Ä^]TiíE}EG#žHkÇ*Æ=J‘û>šh Ü;åˆÌíF¶òÐôÁ¦¾U DiLãûà¤6;yF}ý4 ûûsî™rÒì¥íɤ0bº]}¤.jýP…aAÀ¡„ãˆ8ó oÙ{ƪ:'3¹/Ö™‘á«“•pØ,@HõmÇO2²Dôìúê½-⬹eëªÙp’êT`©¬´yd©-)l ¨“Ä98žÇ~¤WÚû“xV»kSy¾!FDÂûq™â¤¹áŒsPoʾŽr œzc×@Éù? wW50ÙMܱR/í­)qIV  ¥m«rÊúêŽè«µ«·—"¾ êZÈé,¹2|£.*Ò 2ß%È|Œ ÞG±ã¤Ò˼»D ¶Ì²–ZmÚM£Îøà€T&)i'>éÇíôí>ÕÅŸ Tó>EÙj½ °3ârp!Åëøûz'µj­®™&“sÓ!Ç%lÇöR„Œ‘•xeÒ {'DçChw‹MÉd3 ûõ*åc‡åRTàñ3 Hý|i~&$yÕ•±¢%l.J#Ù;)Ö» ²GÅ¢…Ñòý WCÚ¼7 ¢¼dUé—:´G*K …c¥òšX7>ÎOÚBòa·JßfÎZT()ïŠ ÐSæÈ>¾œUª­Ûñ…9ýѹ˜\qÓá2ªöL•…q$8§²Oï ó¤æeT_Fi„lÊë „¥à«yÂHC^¡!m­÷”2}8œ{¤i¾ÎÛhím¿S>¡Ú8¤Ø& Œ¾Ìg#ÍÁÄ‚¬ä~ýØ:ƒy ‰3dVÔ1Rä%=&ò\…ðtcÅH\u”º2< íéªûGq33fµeíÓª×Ìw"E”ãêz‡ã<Œ%C°³×Ou!ª¥©>]- ¾x>„Æa% '‹€)À#Ý=uûF¹¤´Èß“]Ü;‚ÆDWÿANGÇ6Âü©†ãž"üPôÆ¿¦“·Öow›&Íe~Ú¬iAø–êyÔë@)?›ó…C#°ØIäj­#õ¬Æ¥„½¼ÝÜè/$;oO„¦V;,©RÐ$”Œ“’1 ëÓª,¤²ÚtŽmÇÌøŽ²•Ƨ•0“â#*V{XB±“é¥ ù;Ú¦s’'YÚ·K-&SfXBÛ*è– p(^¹$p}tgáîê›h­Écu {†RüŒ¡Ö¥4¤ùP+BÙYÀdÃSw»QaK ßyoØ©qQ0 ¥(`v˜Ü‰P“û®çmÔíÿ“nžÂÏvÓZ¸E¤£bëH†säå|Qâ`€HAôÆ{:´!ýñUp“$$7U$! EJËŸó¿<×ñ£qëÂl~°è«÷{¤¾9¤ƒÿ¢í2?ö?Ì/O·ŸÞç¯m"]ÉvŸê˜^­eë§¼|ÁW)øcÿ1¤Úgù¡§­¼<ÃöéáoüÇ‘ÿi憞¶ÿßÓâ?µ_¥,}¸nÞQŸ—;lÇen%k¸ÿY Pd’‘ãŽÆG˜ã¾Áèâí¤={"^ÜŸZëhRšÝå,4?jï™RÈ.“ƒºœ}Ýy»æ& ݹ)Q¬ä¥6n5\•Ö“ H!T•g¼LúúhÄk«hÛ~kíH¶Ë‘ʇuµf($Òà$ã™åé묋‰]mhéùê˜P®Žßˆí„Â]ZF2¤Œ+ÐúÚ µ&ÌÿÒeä4%¾CS®½”ò>ª{•žóæ?ˆÖª»vaøIÙ»=Æäµ†¾ÏµTá)è ´¥-G{g:¿·(b5µ×ÕµXTUã7>“%•§¥+Ç‘åÂ@JÓ@b½í­e•NÞ¸Ü{Æ\p †y>Ìsúé[ (÷÷zÇ} ÎßÖíä‰ n© ù—jä2êQ‚B˜m•qôûäŸ~'X±âòj’^ߤZn Ã/Mb+jAÿÊ@Y¼%I>ºk‰[¢6â1(±ÇÚq¤¼û·å*C€žD`ræN‚¾ßÝÏ×mŠë¨qå4‹à\Y2™T¤äe$¥²£žK ëöh<ïˆ{¾,×öÜøÏ;1 Ÿ˜ (!*ï‘”4N1²qŽôß¹ã]#zB„‹=³:¥‡Ë%ˆ‹lŸºZiò•‘é‚uYí’‰wmîé™~|猚õK.'®!"28rÎ ,íï ³m74{ r}GY=R‚¦6ûÌuȪx)¥!µz Ǯ²ß´óv=”kÖ_ƒdͺ֠©Õ2fZÀÏ_uâ‚F;â?f²“ Øè;’Ž¢%j–Pâ£6Ú]’ Êpòc¶ëi®!Ÿuw£›¦eµ­tµÑsQ9*¯¯B%´égŠ@Xe X^iZ»ìó 6¤ÚWè#%É„vpÓoÈ쟸‘œzõ­Ò¶ÓÖÏN»Ý®hˆ¤¡·Øw‚R2”9â8B½Ec=u¥‰rí'fZÜ]^ØBŠC 5Zô¤°á>b¶RúЕ ãûµo}UÞÜT&u‹wL@Yšàù7Ò}üGG ÐzãÔtuŽÏÛt¶–UÒ I™M%Ö È%M'™)ò\F×Ðï‰Ïòè™uYYNÛÛ­7 ðÙ®œ‡ÉVT´€Ò’ŒœyKjý£WÚvž “!´Ø®byE/Y2Ó‰ä@Hq¢Og®#ÓÛ@'pSGû8LØÕÕL:•>g¶ôi*X%>'ˆµÿÕI=zcK³¶Ë2^™¹½CIqqmªá<Ää¤ò>à” z•ò_ë;Xü?·•lÔyóÎC M|ió¹2É#‰! ¥Ò@ÎHú}¡¼°zÉS`;¼+T‡|O—²Û²æ!Åz8 ¤©_{#Ê޽4ÎÏU®ÛrªÏ¶í•#l×T&§í­Ì6*T…‰­W¼ÛêÀ)éô„ t Ny ^™i¹p‰±þ̲–®M4\¹L—–£‘á¸>a~\÷ž ‘Ñï@'á½äy“u"\jà¨ù†]fSHsè‡úð”ààyÒ 1ØR±°”íäk誘ìv¢‰Pa,¥g²…º\âœõÚ”I>¾Úƾ]m[2¥í%¾àù• ‰K‹(‹e9éØ}5…mTíÅ»ÏÈ®FY[&²Â€A)`ã×¾ý=Nƒ}¤*K”¿>ŸnÖH¼G$ÊrÆ3啜µsR›IÈ쀟oQ¥Hô‰ákmo.,˜ï!&c5Í­§0³”<ˆíx‹GDré'—ZoºÙVOW¡ûrýeAx¶-eîG )Àã© Ú;ÏDkE®ÖÝ”q¬OħOÅ*zD33 )$–¿?†Ö±ëç㑟Bs ¡*òU•.áŠ!µ3Ê)i˜°S®+V>`%Õ¤úz ãê0‡íè›>-LzH»fÍøÐ%©Çlž¨ù‡HÈZ]`% ¤¢ ;=Ñ=ÁµwÕ„O¶öÍ›s"6‘!¹Šüû vx†ËjIg(ïØŒëm<=å\¹RÛÛÖ )°û1•!†”ç\œiÔ²¡Äc8qYü4¦›D.%—îÊ-^e½‰ ´€sÉ\[à„ûgúÁUmŤX¦b-u­ƒŸ$§ËÛ yŠÐJ8œÉüF­¯unÝɲ"È¢¥¾‘bÒ¼"4gÄ9©Jl¨§ñ ãø] ¶Ûûâ¥0&XA ’ñeçoó '¾htxn§–0C‰)ÇÓAƒ·õÝ}¥[RÙíÈormoÙ=xÀòâœc¡Å@÷ÑÖÏ…(ü¢Ÿ6M¾Ñ(㢥¥"I’qä.-j$9%\ Vºy¹Ðìê]ÜWô2L´©.ÚDThò3È#!œ{ŸP~šS[]XÊ÷ç‘gM:O€\Eœ¨èjJ|É[…R Rp|¥NÆÞÆŽ“pY5зLK¸Éxd§Ä[xJR[HϨÐMû´¦}¶º×oàW= ¥”ü½ëèykV<Á¾áXQÁ ïÐ2E{Ľ²–ßÄv©Œ7b¸®.R¸Œ:CN¡x°’NN„nûÈ(Ûªv©êÝÓ¸|@ЕLä¦C„Ž(m¤¥|—ß|VŽ»:ퟶ^ÛR/jk~*Š¿ Õ%õR‡_$yÉZÝl/ŸÎ(¤õË[×9‹mÃ"5üg-†YjÚ’¸å8iÇœðœR©O,ç×­ ØûáÕ1TùvWÔó£8]’ÛQYÛK*âSùÄ:¾Éô Œ{¤k¨ÌÝ› eµCö¤ép'ÇZâY±FŽEÄ}â€Ï ~ðHÓ#@©³7[-XUî›æÜLIå"?ÙKpE‘8 (…dcÌ€R1Þ}…6æÁ°ø†Ýôç¦ý˜—Ô²úŒX‘G Vµ!µ(ò¦²¬zñ«µ VͶ“}DÕÓm­åÆq0›nD”)JíKa *h’ž” ¼om§«ÙûMä²-nÐ’ò^‰&¹¯>âGˆð{PÇÜ$úºÙ‘äYÝK»†$šéx‚H²L‰¨a>t:âROXH@öõÓ­/ƒ‰Ån gÜŠ£òñ˜­ñÖWž²”3Í+ô”?ë¡»znÉü‘*=Å–Ù^¥3ØIl´âˆ\^x)Mx¬äv}A$ú¨'ÚÛÍÝvOȯ»`ÆjCR]j:|5q*‚®Þ‡2ÕǶüû»[¦Ö§B«Û–ÄqËø°äâz#Õ`ú“ø’ó”•ë—Mg`ÍW¥u鈀 ±åãòü÷#ë‚r~ºÓG¶·•\¨ñ^§]rÚZ¤*T!Ƥ4UÈ%Å¥ŽadõÉ)Hï'Eê·vâ”õÖÞ•E{k)KÈm³R™Ê:m*q°=c—ãÖ€m}<(Ž;>säKŠÀ˜ÌÆãÀd¡ÕÄ x|ŠÁÆKŠýÚ¥MUñù2éoªdõ„g•òÈlœ@Çu'Cë¾óUÄiÔŽÝÝS¸ÉñÛq¾Æ ˜IÂÂÙJ€8Ê @‘‘`ŃÑ~I«¹[’µn@[nJf¤Å‡ÌæüÚB@öë g8Ð ¢›gy½¨NÓ…`ÆÚò ¯d2•¥´ó©ZqþŽyd}í=nˆ;WÅù$Vîoò¯A“9ÞL‘ßク§©Ï¾1®m[@W9SÙÜ Þ?PÁ‘3å¦IiÇ'+â´Ë) HG¨ì:ÖH¬˜Íj÷_äÔ$4÷€ó³£>Ädg¶S…·TOëwê¬{è5îÍ™*šŠ¼9k  J”܉¶óbº–ä9xÒ2…c9G¸Ê)t;²¶Å¿ˆª¯›aN&D‡Ãªaò¥.•¶‘ê|ªYçêAë]mµ:-«×Kºd6×(¨jD˜©Š©qH/'Ž;Iöìg\®¢×l¿¸Töð‹mMg!(K †Ùp:Éφ¾2²@ãæÏûuŽ´ ·¶q™¿ŠÎ{n¸ë¬NA—J–¬ ðt¶ØOê-@Þ5²šÛì ÐÔ]ñ} ¸²bV†kZKs¤žÿ0¾#ƒ…y•޾ºgþØ?elÑe®nìm‡Ûj{ïR°Ûj<Y-6’O]’~h&èon\îÁž œiPYCá§šC8CQÔ¤­Ð1ÚÇ΀_Ä9[NòDX­Ê5Øi: Án:çèKíHÈ ôÎs]Üj§”ôv-í{ì3å<­™‘à€; m©¬©E :'öÞfCÛ‚ÂúÉ‹‘BŸ‹oZ†Éa  JRFF9ò®¯ÔÎÙ[²Ê3MÜQ™M&L©m8ÔV‘„Œ„ ’åÄŸª»Ðc² HŠêãÚÞÍï 8¥6Ê_+I9r×'~ˆåéê5JÖmSódÉ.ß9 "JX¬•·K(’œzË[@ÿ¤±ëëîuÈÎOnÚ¶ž—zÐ?-B<çŒÒB|¥žOÇP–~áÁÖsvûö-óT2)#D|¾ÛQ¬Ê>`‘‚2ÃaÌF9ñ?Ž€.æ‘KòUZ‡=¯udYnITu(àÅǤàûŒèm†êgp" = ôD€Ò᤮)eKO~u§ !_ŠV€:Ê}tØ…Y»¡ºí7,¸r_p)¶ä>ˆ(^•¡%²Ð=€•ã¾óï7-,¹Wö•ý·VÅŒ¢°¶ã—ÊšÎS—‘ãsW_R0}»ÐU¡ÛJ ¥?#¸&MZ/0Ë‘Yƒ!Ľ ´ŽÒRðãì@äVœˆÖEÇîÍä% ø†SPüÔtCù™Èe]+Â<1ÇËÖ N:ôÒ{sw/ÚW6•›v={M:@f3þ"›Aûêà´€¢{*À?·D =„ÂUd¹;Æœ¶¬D†ÛJºA©8Éó@ßxÕèûb.önmFÞÛ¬Ú8‚Y~¾Ê;Œa~EÌmcÛŸ¦€S»;xî×—¹‹-¶•×5ókC®Œ©¾ç"ÿó¡×´ÍR×±a",e1&EDÃã¬rÉ ²PV¯@¢@úsq:Ùrkëíƒ0É}÷¥%ÈÁG °Î!vH ©@‰ÕmÅYi ç]…¾·Sñž&DÀÌv¼L[cÇm$ãHÇü46ëqìb|Œw ë‡(1\ÇQm$“êZ'™8é(AúŸ\é»yH}uñíälù¶³òÎE•€ÚÒXq°¤ùGºý‡CAw6ò2¶ÔBû‘÷ ÑÒ܆ç°Ä—Ýs8‡…œ€GE³ž=œé¯áÕ”Ù•Þ°ÜëÒ£),A:㡳„¥*ކ™C@{r ?‰Ð/˾iÃ#h&n×TÇ+U=Qà×xÍ6¤þŠ@W$ûä¶úàè õ}¶â´¨yêæ¢³ Dv!"l%>¢|Î T=sÞp:eø°Û‘j¬º®§™ Ë¡¥JÔ¡E­Ò:É<•õTöF×Dä9;âÒ—n–âª(ñ¤?Qà SêR@ üHÈÐibuµrãVËžÛ LiÕ;Wz‡_¤ð§k¿l”Žñ«[n¿hÙxT“¢Ì•óÒVïÊ"+e1Ç`xŠJ…¡GHPX¤mE¿ÄHSTÜ_‰¦Ñ¨ /Ø uá÷ØÉÊb~oÊ|Ù'¿|z´UßWî—¡^ÏÚtv V¶rk¦3oÃõâ´sZN}Ïý4¥†65kUklWJñ#¦K0‹i$tþ¾ §¡î3ŽŽ¬®²HÛh®Û²'¸×3&T„–O IHi‰EСøu×ïÒ†áÚ5®\Í•´é«Zµ“’äi!·ÙmÎÎPZ•õXX>™:¿EEÒ–•;¸jY ‡ Æ€Ç>Ñ´!µ{­!K#õtæ×šÝU{ñ&LQÃ¥+ÎRÛerK¼²}¹{ziV%|ZŠi(ÜpYÝÉëf?Žäè )8²¤%G¯º:Ó<Ý×q!˯«¡³}¥8Û=s*Iy*ì¶¢¨ê+?AŸ@4½y.ïplHUtª”ÛR”Ðz"ÙoŽO+ðù2 sõÐ]aÝÉrÁ·5²P¤#Á•eÊ[a -¤Ÿ Ÿôs§Í›¹ªÕŽnÃÚÍαBÁ[Î (mäv´$¡¿Î,$ƒÇW×ë U»¥íµ-ÙÕRn¬‘>*¢µ1qÖ[PG9ºµ: CiJGCލCooìÙéWدÐB‹)ÖÝiO-·e-IÊ\SDã£Ái>™@×}&Õõ.Ú{±½¶J§Fˆdáá.;òÊ’3éƒì=tg"êUÝ[45ðíi ¸åܘ2ô—£Ç)_?Dägé­±m Z5*Æ ýýÈí…±2;…,{þmöÊ’>UëîurÿlÖÏ…]wq·vŒ‰¤©ÄÔ9Àzãƒó(䮇ÞV×AEuûãvGz<É‘[¡bS¬Ku”¡C#å ”äûpõµ¢Ûl+nÐXÁm ±94èB'-Ú 4¤¶¾Hï—œLúèÖç´¼zÕ4É®¸vÍImG奣ÃBz$- Ì<†?IJPôÈ÷Ö»èvÓE³«qĘ’²ô¶­F‰ È tºÏ„“ž{Ïg@±PÅ|+')~kzX|ÌQ"C¶•²ò¸“¤–ø'ß+¬{yŒÎv€ƒ¹(l^¦Urjá8”Éä3À—š<†@$Ž>ž§Aê7$È»v^ÝVâ]”‡¤x©r#X´Ç™´`ç‰èŒ=5ŸÂûåYÝ•d­±PÌ„¦,%ØçÅ$dølÅmOúc9Pǯ}è0ƒº—E$»xûSo˰š!ýŸdÈO2A*âAm@ûa`ç±Þ43qÄ´E+n7µ˜¦ØøóX…29)u²´3ŽG²zO “t]ä›Hð”ð§–ÔþXYd°°Ùìÿò8õ JF¹×/Ù»Z<†žºØ½Qx¹|¦øø‹C|ŽWÈ”ä äIÁìÞ‚üSu¶kÕ)¹v4²¦Ú¦»"Lw”¥`È28û gÓ³\iÊ&í&K²CAÕ³òëfª+~ÇNK\|U6Aì•å>À½™ñ=€]ñF[³f)-ƃi¸ühð¾]Î}Ç Æs‘í¢UÛšf悽¯mOQºç!ÐÓŒÎŒË }@vœ,7…$zœõÞƒc{v¿iÕu·èÐb²„HV+Ýñ õu@Ó‹è„àcÓÙSaO*;֮ĭœÝ›ŠCù1-à}÷$€ N~è¬uî'Pm«“£mʇf0+/X-¤ókÐ%L%`%?ª…÷îsª[&’Ú¦åù“šµjSˆWŽóxS/òÁO~Q t§Ø:¼tUé ³c¶Û~3N9MãØÉL†âDmÕGiH?|‰qŒn=úgK€•î9ÛâUTXŽ*˜–™ rH#l6P”Ug>Ýhéܰ\¯ 盵q°ó¶Û†C¯!Ä+!d 9ûÁ †…Y Ê+û\чa×”ìpìv_)Š’ñŠ•<²°¯oMšYW6¼*Ù ¨ðÖ\aû‰Ä!õd‚´¶’ ô!XÑÚ]Á½«þϧa•[…°¨étÌŠ¨ë¼‘†›u]~$qªjΚ®®ºÓk͵b=kõD‚ãέkÏçPD‚†Ð¢¡ÙðÊ”1…jåÒÆô´TùÛ>cöŸZcM°+iŠöN<©â âý‡¡úãA£nìv,Fë±Ü5IÜPÕÉ5ÍOüÝz3åà üæ 9$ÀÀÑÂûö©«¦ŒÄˆ§,¬ØÀ˜§Ü8ä¥x¯þe³‘êï9Õ‡›vóìÙuµ÷\r<ÖY2ÖÔuƒèC²¼?sÒqÐ{j|HÛ»nÆŽ §U"¢9q‡*‡ „´  XI=Œ©'¯.€uL½Í¸¨,*õUD‘7pÇz3 lOŸø2F@Šø‰Î¨ßÜÛT½›àÝ4 1[iÙ7s%-.¥r\t4 ôp}tÏLäjXMJx$ÚL2–Ò&:Ç•¤/åBRyJF03ë­»¿â3/Lj¤›™A, .=(A'$xe²R 9÷$]·S6nÝA¾ƒ¸X™L¢b[ÒH=rR©)Hú)Ìäú]i“BÍkȘÃ6€—¶. Èq¹H˨È%Ôä”úãXÑo‡˜»‹3ò¥Äþd6]yr1Á$ ´ÏŠÛž©À“éÙÓø™umhÖ3wc­!2ke”0K·â ¨ýr8úôtO©Ü{E+/c¾§ÚJ³‹)M)#¨‰KAæŽ'ÿv¬~k™FÝ,¢îe\Å9ǘ[p²®°mqÚQ÷.<þ®^¤#t4îvÞÞµÞ³®«÷)'EˆseÂ× :¼8ÉJTp;Aë¿OM4ÓYWE«D‰»Çr|¬<©„>ÔU¸ê>¡ä¶µ(d,­8Î:Æ4þfÃ…uµeÎEꥨB“>L‰+y×AÄ)Š¥¡Màu”¤þ£iö%d(hUmn¦ŒÚäÇ[HNx¯>”þ*BO±Æˆ^¢èÜ07&Ë¡Üw²PéE„§íg6ìP3Å!m))ïJ³ŸM^ûˆp­\¥‘s³«šl¿!”K üËÇœyRŠœBÿŒœ{ôé+ £:ªÐÔ¢LÒD"Ò¦(u‚²^W HPÂSÞ}ºý›54[Õ1ÑeRË(²p:2 XÉÆS…€:ηíÔÔèÌÁ‡ ^#¥Õ)õ¦X°p9’¦Úyâ°1ÒF:ôÓ[›}{ž©Ùmmª=¡c 'Â}Š•‡e•tAh±Ì¤Ž²R¦4ݾ.½Pfn*«x5¸ì¹I*þ)°]e àyE!ÃCªt*spV.fàstíq!·\vÑpâDÔŽ%N)¡Ž<’1œt´?2ÏkÞ1;l5^SIC±#ÅeDÈ´”)¢°F1úiÿl.²æÉç"æ%EbRêäJ. sKŠ !ÎrÄö?-ä›ið`ÓÀ¶¶“$p‰"Ò–Ûm_ΈW¶G¿@éštË‹X³è]øtüyPÚñä¥1˜­#ݰ¹. c×°3Z˜o¬,þcn0»Ç¡Ïmæ¬Yþ#¶FKl8–É §' ¤ç‘¡»ÃfÛ_Zž1m¥K%2È`˜­¸•d‡c²ÿ$#|½=´+W]:ªäHºšâCß'9.´êH⢖›æ8ûž OX>¹ÕmíGy=M´¨dÉ}ġ׷ /¥¸èÿÂ4倞J9öÓi©ˆÊ %¿‡µqæÍœw£¸YB1•)1”T”)Jhëñ:‹†ªÚi3åvÓ  ´ÒbÁŽóÎÐmA(ñJSŒœßŽ´£½º¶CÅ‚ó[&,9QÓDùVmEä(aÌF1è=›µ_ß›†C;ÒÆ²‰$¡ÈÕé˜ä×JA%i•ÀŒß®u²~èü³¨ŠÅ¥]†õ¯‰ŠKQÌxÒÞ éj*PàÒpOãÓXmm»q]º”šYÕ•ö/xr;“Š–Ùè•J:É­#Ðw 5pÙSO}lKx#>$ˆ¶c%(8JÃjNG|ý·®ƒÔØïè[‘t1jZ›k)!n·Åoå2 l˜ø$ú€§G¦::f¾ÛµmÐYÑß\2¶ìåruºêø¿2—Ž@*[Šp«`ò m+ìªÊjˆKo˜Í{Ž7 ™Ï¢hiî]¸¤&9±“È­Dzg×AVÅVûjJ­Þ3eÇ‹9kU”û'&Ô må2Ê@u+ÈÇ!ëÖ´U7öÛÐlë·ÆÙÜ‹‹$™Œ‰Ÿ0Ó„r)i%Å­j' (ÔiÖëâ*ë6ëM?2Æ|™/x9j hàß>›l…N==3&MÞ¿áǸ±a É D9Š~2òr]iŽú?wŠ?¢=4oéE“ïÚM¸Ü4ò¤©¦Á’e\†q S™ ô¿O@ckD²³¯–Ü;Š»¡¸®™iÑòø %A?,¼‘Ë¿lêú73[®†lY›©©M4ß5r—ħño©~>½z(þHsmíkªÍ»O+p!Km÷'¿0&J—Ë-·ÅIu$%@ ­D=ý4/íåí›èµW—òí_Zœ˜û-"SKÎ’¶P„ƒž¸ç¯S£ûvŠê_Ï “÷<¨í|ó)™8ñŽÁ´Ú¡¸Uâzz¡CñõÓ*[‡.esÛór8‚²%IZ!ÉkÅñGæ”[=Á-€G×ÒÏĉÛkxG“QSqn[è *7e¾–\è…-(`%#c†:ôÐ-Ĩۻ;nÊE­O-ðãp| ¼ž[„qlxÎ69÷ú Y÷ÈÕ­³YK–Vkeý¯`Äsâ‹(}•¬¥ )oàyG|)=dö4f·nºäØ"®ïmî•j&¾ûÉhcóhT· klŒuØõôÒ¼{¶)ïí’™Š²”‚6oÏ*Lt(ö„%I)J +Š3‘צ‚oºø-Æ‚§­éÐõÃ<”ü¤Ç* ÄóðŠsÒ|áÎúèã:1]¹ã uÐÅ6M&8‰)BSŽ”§/™Ž„)x=eiÏY×E)Ðä„WÏØûe–¤§Éuök­–ÀO\Vìd«¡ž)#¿]-ÞÕÌ£e·¢Ì¯rê4€ã²Ì40ì˜äRó9ôÈAÎ=t²y³µ‘-ìML"†cI‚ü8KmÉZÖàðüE(¨„¤ÐÁ:ÂeÅ}4É•°l·í@äO‡bË+°:i´¥I'‚ÏâFš(l$ïÆcE°˜Þܲ‚´™¯­A1#ŠÂ)> £ütks¾Ý””Vнp4ä50ˆ1Ö$²‡óñ$w ¡eI&±˜ò6Ý·ÉÃBþNøYŒÚJsæe/dúèÛ¢z¦öŽS±éÐ&WXžUcó*R]‡Ëî­I$dߟn‹•Bj³IA·FÎMn dxjÆ|FÐã`ƒåçñ×I+¾]§Ä8UëÜÆëä`X)(5æ:㇉ë9qöütïˆ?³H·ò]¦= Iþezy¾þ$ú~í$[É6¿ö|¯æW«Yzéï0UÊ@¾/†Ê{þÒ?ͧ] m7âss‡‡ÿSïüb¿æÑ®“´ÕÐ:Óâ?µißéKnüB•½[zTä<óµ!m´†Ô¥æ$K‰ROdÁõë½t]‘CG-–å_ÐáJ@Êg–bIâ¦|%Œc) c9¥ H®ÎÜÛJ33%CqVË(z3aÇPD)GÊ•!`ž±ÚO¯·¨Û&‹oÞOr=Í­–쳌¿ŽOò®¥îñPŠBV>d+Û³¬xº›7]~ÇÚ”Öv”îÆ¨WjH ‡‘©)mGýr® ô4¡²l¡Ï¼ŠÔ«+Òä5ó‡À•È9 žû‡ýÉïsÛ5±•k6C{ŽÅQjØmj$ä%*GËŒý02sÞ‡]Öăº†â¾§³‘]-*mùOÄˆÛ '´„ùÙCØètœúà}J­—ÛÓnÔ¡÷ö¼Feȯ 2ØU¬&ü•*Sd’´gùÒAôè ˜ÎèiÛMçj=)ÔÒWC+t0éG0[iÐrx‘뀣ְU]vÍYgiïI0~^'ͱMdµE^Om©ÀÚ@¬ Óê=5ºÂVêÜÛz׉,¿b®%Õ<„2¯P·aA`úåxÀÐRøO]»*ã?!S®"ÿR~A°Æ ‚ûñÁm z ž°N†néñºÍ‡l.iÍK3xˆê“\²€¼à¡É c—GÓ¥ ;WB°ÛûeÚ«é¸P•ȼkY+ HÇ?~ PÀÎ8çè4¿>ÖZ݉fÉZÔÒ~ÑëÎÈ#Ù$†›[kF1ï@z¿nĸ²Ÿ:Óâ"­äYF!ºÈKm¹ ‚0J#@'Øôq¥»÷¦Öµ ¶Æ6ò›c2@ µjˉgÊ6†Ð °0 …#FöFùÚ׋kr¶ä ‰î¨Ø9VÛ°Ém$qSŠQJÊsú¡yÔ˜æÅ§¸v=vÜžì§Ûoìù>2úY=óC®œ§'9 ÉÀýÚ%LÝUÕ¢ªÄÊ£«ÄmØ´ ,ñû¹g’\r¤úºc ÚÖÚ\:zL@çÙ©%¦ä¬(ýÄ–Ûï9Âxc¼é÷uËÛif?g{­´‚‰œ´ñ\p„å+mFH,ŽÉJTN05ÈQ"]‘û~–þDx¨MÊcÍu (ô¡!%Ì’1Éj=Ÿq ~¹—Uâ·º·,•ö›ñ•¹È–ÓyÂÊx  Ž–£~ó¥šáC¸ï¯%[YºÅL×ì=ÀÊ ­ÃÇ )^ €>éP8ýjn­¸õŸh1µj£B‘šù/. W~l•Hq·’?/Р꼪åu}T}‰CJ—âÜ—ª£­R”•à§ uÞd+Û³¨ÅcVô«ø·êä^Cn±Rx¾X‡²•Á²”¤ÿïÄg®ô¥AgpYÆ‹*ÒÍs_‰ã%ÊÙpD$§—™*ùsèŒúãÛN{f¶2­fÈoqت-B[ ¢`mA䜄¥HùqŸ¦N{ÐëºØwPÜWÔör+¥¥M¿)ø‘a„öŸ;({“Ÿ\ï©UŽãÝ›n¾µñ·c·:|Љ®.Ò .´¼€•)¿ºSœÄ ƒèª›åî¬üMÞËl¿+ø]uqqJ $­¦ÝÆO¹ƒÅG#TUW]³VYÚ{ÒL—‰ólD“Y-QW“Ûjp6ë‚´úMn°•º·6Þ…µä"K/Ø«‰DuO! «Ô-ÇPX>¹^04¶&ß½3ß½R¬éåˆmAƒà¥µ‚V’Æ=z)>n½Nu[uÕóÔ©wÕlÔ8ùeÖ2,‰Š±â†Ûd†9”õì4é] Ãoí—j¯¦áBW"vñ­d¬%#üEøC8㟠ÒüûYkv$m›%kSIûFC¯; ÛgÉñ”‡ÒÉïštå99ÈNNîÐa\öàÛ Diq^©SíÒótN¸ƒ‘žöJœW`]{8ƨ^Ä’ìj„Ý[>·Ü`>†˜Œôwä¨ ü&Ô¬äŽ% P$Ÿ]?n¹{r ,ÇìâOu¶Q"3–ž+Žœ¥m¨É€1Ù)J‰Æ¹ $K±²"¿oÒßÈ)¹Ly®¡¥”$!ä¹€’F9-G³î4WŽÒþHFfþ¶-¥: Ý[që>ÐcjÕF…#5ò^\®üØ#* ão$~*_ Õx;UÊêú¨û† •.;Ź/UGZ¥)+ÁNë¼xã¥('öûè ·SðŠ=Êäì¥Èšéebc°R' +eJx2Ò•ŽI'ÛAê·ÍzçØVNaÙ1#:õ$¨-Çš9¤ëšüOª€ ëô@Ƈí}½O*u“;Ö¢º­›«S®ŸÎ>xä”$)·#ê‚IÏxÓTX•î 36SP~vÇ-ÀŒÎ߉KèláÎR IÁ^2 w Övå,êWöõnÝÝU”¨²$m”!‚æIQS†;Y=sƒZ“R§¶ßÚ(›ªj hÉ‚LD©äv¶Dt•y@(Yëé«_ªîi*¤¹¹)ê⸒b+ŽÖʘO])^Àç‘ý½éâíÛîš±f†šR™R׸ÉT‰næJ€K©@ ÷É ®çhn6ð]¢­]œûÊ£•%Q#º¢´aÂÊQžÆC¬äçI_1><+ÊÛñvÌ‚ÐW…%ça±!$ž f+ +|ûƒÇþ:`ª™³æRªÂ’ñªHÌÄgÑKhPé-¨FʺN8öOÓÐè°~ϱ¬Ü»TÙÚǵxµ%*¹f x$d%m¸ÒWîŒ%=ã: Fänæ/äýÌi¶/„.K6¼©-©ž‰*|ø¯d²@#ë×V¬÷ «wInÇlo:µÙµåLk£´†Ò Ö”É *ÙXI÷V›æ=gq ”uSâ5$r±ŽÓÑ–ãiã!mK8õì$““Žó•Y¬ÔîÛˆ-7)GÀ*CN8™!¢µÒãÜç°¥( ôAвß0)÷<¹ª¬“·šf M¦Òlwí î§,HKJQÉ>!õÈë:ß_ uWºÑ´àÞÞ8Ü@¹&ÓmøH–r„4JÌ’€;òõHÕ™•÷ðÖÆÑÛ3•o; É¥å; `¨-mŽCPHësŽšËfÑ·¡Z_71µÈ\§æD/))ʸ(*~$§÷ ð®é×`ô›†^Ú[Rf2Ì’\ºð”$+“xÁ>Rôâ::»´+~νµ•CöûˆBDo ‡‡0z©#šÔ—Së‚€εm*]ºÿÊÙÔï­Á-oÚ#x¶3“⃅§ŽQÖOés¤oˆ·¿!ßY–vÒáCum·â  <:B@ÏÓ'š…"ïeÒΕoÊónW<<F+ëaqO™*2Zm@Žü>jõïÒ«3«wŽãœU!÷’â©—Rëñžk¬·# “z$ŸSžõ^ÃoM²ØnÙÁ¦‘vü¦Ä…±.T„òý0÷‚¤‚œ* 2Œ]¦ùƒ·áTÞG¿€ã J^&ߊÑô kæP]A z Ü੬z¯Ù÷6m¥×½˜éŒ¢r R‰Wc '¯\]:EmȶR«Eºb<‡Ù~c B‡IðR“éå!Gß>ÚÃmî¤JrÊÕyŠàC‰dФH_3߇Ì>¥§ :Š’=Î’·D}åNä[Hñ®«–ó‚K&Ù©qŸo¬soæŸNýõúhªvN×·~ÊÞcìï#É#¤b%å’IñãÎ%jÉí¾»Öuñï+÷§ngÅ­¤yjTHPé<`ó¥$¨¸úëcÓÑ '¡åÖ§ m·6Œ[vam Ú×χ!/×6&N…c"1ÍÔip$ °p¢žHQáƒì{õâ}€¶Û˜µ[½omî35 q2"O3>æB§\e(O¸Àw‘Æ«S[S[nyU0àšÛT-n8Í“l³!Â{>>9Yèã¾#ß>Úg¯wr¸åƒo\mÿòÛ\ƒâ!M!J*ÂÐÙ#% wÅ9Ð]ùhþI³½m¸–MØ¥~Ïu.±åäç.+vHIìh*ɨ†^ íý§6-LåòŒÛ•Ez;˜â òÛi„©]ùОó’=«?s_±w:µ”ªÊ´EK,{9¥Ö_9ee „¸¥ Ÿ7éØäžú²£ƒXºÙ44så­…9B؈ˆÍ»ÇÌBšRHïõ€:æ{ulY“ƒtÕx—?öŠ*Ò¶”÷@*1PJO~ªÎr“ï hÞÈDê{êÍ›fãO%È\F‹RË@ ë¡ß$絬„Γ9wðÜ5h‚!GŽýÓ‰$ä¡8|%0F=ýN¯îZŠ+{»V~æ—6t–ƒDŒòZŒ„Ÿ¸¯—Km“ŒqR€ìjæÅ3fíIð/©§ºt¥™î\Ã’´ðQ'%1ïß`=ÚthrÕUu%¶Tµ12ª–Ê ’òáÇ’Z#$^Æ0h½º«ÝÚŸk½²w,ùL>gE7>+¨á…!.¡Õ£9Ç— ÈèötÕ2þÂ=dv·7Í50óDTº•-§RN<­´…‚pNIQPÎ{ë@+¶´:ú¸×”î.E«[מmâùVx­¥€¢GXÀi$c×¼8v©Ý{¡Sº¾—k¤Ér¢¿h-óÞ#€õ­ WÅ9ÔhÆäÝʳp˹6ûU­qB›˜–Ÿa§V%¸ìp³×i*ǧл:Læ\‘¹÷¥­Ä˜{^ÓœRòz<ÌuºF=ó鱧¥:½v;ÊÞ·KŠ€¶mæ ©`ýÒÒRBz莳ž± ß»ëþćÞÙvÑw4§Ò¶>Iþnr2¯·{H‘|{{Š6ÒŽÔ5RGºbÙÇãKen)΋…^ n…(zðRB /îô\RlGÙû–æz¼T4ìYˆSý‚¤üïõè~éiHÝ»‰ê]Ï"áÏø[ qµ:Ñg‰š×ƒŒ}»IΧï-«2; 1}uk&1üúßšøÊˆ9e”xŠÁ8‘ 'U]¢¢KlÊù2Õ|†ƒÎüŒ5$$¡Ÿ™ãŠVIÈãŸnµQ»ÓnoÙVU[VÁi?2kÊ`55î­`%’?WÏ¿¾ˆRîMÄÔ©ÉAbEħCàÚ©2T”T¹k õõRO·c:›2âE•í¡m_¾nÄ—k! DI8% Žœ(€<‰^qŸ] ÜÕ;ksÆü‹6y•|»ë\v”s’ÓE2“Ã$þ>§ñËà*æ-}5JûNŠ&ëR*~UIËÜ„ø§9ó ©>ºQØ “ip)÷µYp„»ÊB†|¹WžÇ¶Š!»¥Ï¯©Ü”ÓuòËu1ݾrs*R”Û!§|§JŒcÛX3a¸¶;[î«ó2½JV,Ù€êO#÷ÐÊR”'×>\ŸNÁÕÚ Ýº7=+ò"ßm³fÒÓ!.MŒ¶Â¢B I ”ä“÷T“Œå: »«qVµ[p^l½É­¤´ãÒc¶¤c%>u:¶‹}öy¤g¬¥Û6 »½¨®¡¦µhÓÎR¤Ã(_Œì0œJ•ÌŒž±’W®ºæ¬u[1–1K#‚ãF1Þ”€âë‰)Éä:!Y÷×;ºß1·gÄêú¦b4Ãô•¶Û[iqjv ò…ñòuŸ¯©ÒG»„aœéÑi5vÉ÷û:Wó+ÓÖã?˜ýÚç7 )‹`>°eþ‚õk/]=ãæ ¹H.ÀWþ©ýlþmé›Oî rí†OäÒÿNwù¶µÔ¶¨ÂF´øíZwúRÇÛ…½É"Þ5ÆÙzŽR"Ø‹U]Twã˜rB¼­³å$uèpIÀ:±kµw“{Žeë»Êݹìf*V¤%µ `¤†^%\ˆƒŽ‰Îuìæä½¹ö¢a=%™ ´um®:Ò…å0e+ZT0rÁ:c¼÷ɉZÎÙ©˜Ì’„ 3æ6ŸJ8æám «¿d¶~ºÉ ȺÜ/WpûJdù>ãs#Eb\€—“•'“\PžŽR•”ÕΊm)6×|+;Ö^Ž…§Æ‰_9+”z¨!’éYï O×[\—;jµ›oÓ²‰¢C‘åZT”xJt§9+)BR¿¢ywëÐ;ÉÛ¾LøS'ÛE1b”²ý‹¯xÈS@•­-ºN<À`UMTÛ Ídjá*,J×kœùWŠIQâ…, ‚¯®=sí¥Æ~wkÍeë‰͹Í*³zk 6S‘Éa>ÈÇd^α©]}:,çn qãW-îÙZ¦gXI£[çÅbÅOWÂv[ óD)) JBGŽÉ>˜µ·l7 ø8ï‡9W“زvòÇæ BNO‡êø4NÎr}ö‰4é¾Ü(·ª¿«¶S1\~M—Èä¦Óá4Ÿ9ÇÜ üIÕz3 i‰IÞKÛ’H&™†¾m6‚x¥./ƒ­0 !.`eYÇxm§ø\Íæ×ˆÝ†ü¡e󦽪©®¾•(€JšqÇÒN()À‰ ÏÃú ‰H'\ÝW–ÜHiØ­Z±ã9-rt>ZÊ‹%DöF3 ±¶§­™cm¸Ü·Ý¶Ãh‰mu·j>wP…ºp“ž‰ÉǾ™f7U'v.®+ÏI§oSVl¸J_‚¤q#¬$ž@w¯vä}—>SŸs!ÈkOÍ8ä—kÚtáT‚ËAÕO×~™÷ ·¡ZÓÆ´û}ÓÆ‡_5Fk±#Ìt4ê½–¢é>ØsÒF›r½]uXC^ή¬ŠKŒ:æÖKy‡Ì/Šz÷9H'¡Þ©FSuVqíX©Ùó#Îp1Æð`éÚ à¯tá zÐÈ[OeîV· ·s¯Ø2ç91‘(4&!9 @bsÊX=Œ¬¯c²sëí6ÃíMÙûQ±\ÏÌ|ÅÿƒÏ– +ÃÏ4âg¤ OmäVì%ÅM”Ô= 1$©1b°†ä%mù¸Ï%dŽ;#ÓK‹ˆê¯k·%&Ëf„––ÚäOÛ­²H9S™BÖGÕC>ÚÓo¸6ÆÝ¦‰ ¾Ò…¸É9u0o˜i2V¥ \ øÈÊ~šV•»ï¦nŸÉúzQ>é--°ÞðLŸ(Np•© qè©$ÿ&ÊLÙ&¶Æþ²c¨uH@‡!Uޤ4¢ò¬´•x¸âJAÀàçÒU®ÕÞMî9—®ï+v籘©Z–Ö€B’x•r :'9Ó=m=m4¡ º®]%£©Z¢8­ÌóòJpám}²… ò$ Ö·žñ¹1+YÛ53’P&|ÆÓà)GÜ-¤wì–Àï×H$]n«¸}¥2|ÇŸq¹‘¢±.@KˆIʓɮ(OG)JÊGêçE6”›kˆ>ë/GBÓãD¯œ•ÈJ=TÉt¬÷„Ž'ë­®KµZ‰M·éÙDÑ!Èò­*J<%:Sœ•”¡)_Ñ<ŠŽ;õèäíß&|)“í¢˜±JY~Åׄ¼d) JÖ–Ý'`0Gª‡¦€ªm†æƒ25ð•%kŽ5‰Î|«Å$¨ñB–A××¹öÒã?;µæ²õ‡Ä‹fÜæÙ½5†›)Èä°Ÿäc²G¯gXÔ®¾s·¸ñ«ž)ŒÔhËrK,©j'ÇðÃÎ,d…¿¢O@à€.RYn-Á¸U}³ÒÑÀ#H©°C #—–LJÙåâXú“®Ò»¶ì›Íɸ'È¥[¡ô? G4òNËI GØæïÒ Ùµ6Ðçm®jyQÖËkDY¥N6¥EÅ•xiÈ?£„sí¢Ÿ÷ì­S3¬$Ñ­óâ±b§«á;-…ù¢”%!#ŽGdŸLZÛ¶„üwÜ‹«É‹lY;ycóP!''ÃÈu|'g9>ÀûÇÄštßn[Õ_ÕÀÛ ©˜®?&¿‚KärSiðšOˆœãî~$꽆´Ä¤o%íÉ$ LÃ_6›AËŸ)O¹ä5§æœrKµí:p*Ae ê€'ë‚?Lû„ÛЭiãZ}¾éãC¯š£5Ø‘æ:u^ËQtŸl¹é#@͹^®º¬!¯gWVE ¥Æsk%„¼ÃæÅ={œ¤ÐïT£)º«8ö¬Tìù‘ç8ˆcx0 ˆôáÍÀðWºpH=hd-§²÷ «[…[¹×ìsœ˜È”œ… 19å,ÆVWƒŒ€1Ù9õö›aö¦ìý¨ÇØ®gæ>bÿÁçË•áçšq³Ò§¶ò+vâ¦Êj†˜’T˜±XCr¶‚|Üg’²GH‘é¥ÅÄuWµÛ’“e³BKKmr'íÖÙ$©Ì¡ k#ꡟmi·ÜcnÓD…_iBÜdœº˜7Ì4™+RP.üdŒe H?M+JÝ÷Ó7Oäý=(Ÿ t––Øox&O”'8JÔ…¸ŒŒôT’“@ÿ\Õíãv6_#&å—£,GŽ!xjä!k ㎼ÀÚ ”ÈÙ-D3o+ãJÙiS¾ LÕ:ìŸ(Žœ¤(þˆZG Îžëaí}®û̪…Jã¬>–Wq¸äJK€¤ß„÷¬d å@ zêý•t:4Jµ¬©`ü°T‡h]ˆ°Wå™K²~‰ãߦGZ´¼ kˆö7‰±%÷ÝrÏ”R@óÔü;Æ5í-íäíiÒTÅ何*àøo;óô¼ÜqÑG˜´]tŒtæIÀ=µÔ­w•Mì9ò[ÞVºÊ“ó¯ÃZ:l-1èžNi­ÙŸ6}¦é‹OX7-‹ë޶)gÆ æuðAõç€c@›e"C6q7-]Ša-¿³¢¼Ë±P -–p¾iôˆï#M“en™•ÍßQXË5s¤™ ŽÉZ—1m’V–>aд'Ôá ò‘Ö·1 íÑ.ÎSi;o&<pÌ!+>eŸRÊúì¥8õ=ã@o]Þ‚ú%M²ÚqŽ)‰Â6Ò‘4.8Rµ¾x1É9 ÷žC jÉNUnh¨W6ž¶ŒõÌ›ry2òú%øïñeXë·KÉ#’T Ú@Ô´ŸÀ÷£pl£-ê¸ëUô!j·sOFzKxâê¾`—ØÊRxžñ뀦½Ý¸œdH•2Âb”…²äšæÝŒÛ€T²ÛÁ Z{ÇކºŸÃ:-Ïe°äIÖsåÈZ¼&.›.x}“ÉN¡*S˜ÈÀ$2¸®ÿøw»ç3æ6®ÔÛmÁpHr$qå¯ô–ãì²°¶»ò€°Ÿl ÞS7–ô\fŸ6У>m‰5ò§´á!¦ÖâXKϯJÏé¾ðøghå9f™ )éHi¿–…ã‚As! ³‘Þ ’? Ù›=‰P×>»qíÉ•x³×[-,¸µ(á:âä–º RˆÏxÏZçÈÞÕXg#X<•­‡“s6Ñ™Où!hCÜG É\èݾüØ–;:¹«­³Oq m³NꚊ„~/ ä©C>¡@«ß:¿„4.T¼Þå¹ÜKù@‡\W-¾q¤+ .åòŒUŽý3Þ‹7:„«¹›òuN½àÅŸ"¤6ëHsJˉpŒž”’1®?´¾Íjuâê¢ÅR$3&¶R-*Z@ÉWŠŽ*d'Ì0 ó`O¥•ü!r}´«éÖ n/’K¯>É·+SHÎz Xu@Q'>àèÅU%Í㯋/µéñÉ.µã×¥§Rçyà%Õ“×?û*WI©§»v¾]¼—":\D¨N;>pZÈBRörrI =tÍeWSe©”ETê ÊS"º@”¤¨p†ùJ ­äýCªô>AÖöcv/TÇ’™[ÇìÊÀäz–«¢Éa1À)Àq§ÀÏ™å)À ÷Ã×(ªã,R¸Ón¼hé‰:d`ë¨=6ãn:¦@:úÔ®(JÖ¼jIìŸÛª±™g|Ý„ý×u:¶3êK›C±”ÚR“ÈÉyÖŠ]9Sƒ$á#ÓE7^̲½ùuBÜ‘Zš•yeŸX#¡âYe•IK“ƒœj»ÔËÙrà7·¶ ØÖÂå“vv»ã,’§>Um9OJzŒuŠ»E»vëa^lùF3Œ¶Ún—)¸þñÚ ‰R”’};É÷%E0ÛRßûWyZWɉſ²ÙrÁ,´2ŠÚ8¡èŸ|éñ» )+«K:\L– ]=’’¤¥AÓŠ@ë ¤o]³¹¨)~1ç|úc‚ãTRJ†}jeIR½<ªåžóËAÇ÷Ńs-„‹ž £ ÍM|™ˆq í*OÌGJ9ž°¼’púêÊÑLŠçS´•AË«ó´U+R‘ à–Ýq.©HQìñ8Áë¬>-m ÚÈHµ{x3.;N¶ºôøìòB@SIð[òõ€ du«¶[²áØ´ê£6W/£L]Òâ©Â“ê[nZµy°r‘Œœh6D™seÖZ»5Ç%™e¹R$‘‘æq<P0G(£'gWŸ«ùÙ»V6óëÖ»ùmÉ1a)Äùxf9Q IHÀJsÞy¿sSº)#˰ÛM8ÚkåeWNù»%>×En¡+ZÚR¹åý¹=éZºšîþµ»gìÖÃPŸâåZö“Ð ±“ÃÆm Hä|­->ä‚I$fníÍh1t×¹28‡ É¾`¾ÙQ˜|«Äq88ÂÖG] K­Ó»Û‘ ¹ &ä°žP×9(ñu% KŒ)*ór¬èM@´¿EÂklž˜°åçq„ÁJT¯Î)Eõ—¸àŒº¿B}G¥¶é﯑c‹a»e>¾:‰/V© 0d$û6=ÒÆ‚ÖÈÛ«xV2,·l%ÃTµ8·ÛP áN²ëŠä}qôÀÈ×VµÚ··öQÙ±‡ê&’ïDE.ax#‰+k‚}1î>„ëƒü=¯ßWÕ-³ù7t¶¥­g¬º@= Þ‡)ˆtõ쉷²#°•Çm.2ë…äd”©hinsY>«)O_É ²÷Ö¥ÝìÆ{òÖbÜe%ÅU¡×cÊåÌ>óœ@OªT¬ŽŽgO{ºË Š7$Ãøm˜ñ¬ÃiG>U§åVrûåËœè9‡ÚWO±âïÏÌÈDE vž••ÉiJ º䓧¶´1û¦’9›k1ÿ³l”·lž+u@¿ â¤!m‚B‘ŒtFŠ×|8œ—uk^Ï_ r3å3"ÕÐq´ÇKœÒ¬ä©! w¡h‘j4÷ÒÛ 'ô£´¥)ï>!TÖ¸æãjî5/mýã\ûÎ6ë­ ¦Á¶T{ -q>ª úðï@Ïz2Í-mOÎXMioº¤ÚÀa|\ˆCËgï)]ö®(ïÜèæØÝ4¯AˆÅ-Ì7„÷ÔW-"Î[™íÄ¥ì;$¯}heçβ•^o Éâ+ž€Ô:¸IB}Sá¡äyù P¥g¿LŒ_·ø¤Ê˜bCî‰H Dhð(dÆq‡ â Üñ–ß’Hô'Ðè7\ÍÚŒÜØ¼ú¤Ou<ƒm q–©i@!kK|Sè2pœçODÙÛ›iíó]'kÉKŒ-FC°‘9žã‚Øi‚äzhõõÕ½õ½"È¿—ÆÆ¥ÈL©´®eü=Àd)¤«>bGòÐZú]Ÿ¾\›*9‰y¸ø,¢×xL9¨c°^P#°¥%`ó wV𬻔Ö~~\ÿKˆã\aX#ÑI[ ÇúŒô3œkFØÞ\Øš—¯­YRy4Û,Ö¸òk–BÜQǪ>š[¢ÞÖѦºð,¥ùWƇ&gŽËhN¦\ #Ã)ý  g®°VýØ÷SL ïÉXŠm qñiY)·ÝOA*Læ\ ¬à1>¾©ë@R=zžÓ 3[SPËà‡/Yu'ÿâÏA$ŒŸs · `íÝïè·bª äÞëJÉ*/! JP?ÒÇC×Z÷eÓùG¬ö´ÆÚ«„iŸ#"m ((¸µÂuÀƒëË8è¥J½“´_±f¥n}Åg.72¦ç6¦\c‰ò8ëÌ %£’’žYÆ1 h¿«·moÁ²¹¨›O!°ÚD;ÃÀ¥@ ¤§™=2ž†2tVJ(vÛ3•[1ëmµâ‡$¹§>ðSM(ypOwïë¥ ¿Qsc~íí¡91ã.;é·z+©qÅ¥2ÂÙážÉJÔ£èS¦;Ã*®]=ELXŸ6À[SáX£æ—(‚¾KXuDYRÂ’[@Ÿ¸v{Û‰û{Çl°¨q›~<†’¤r¢¯%]ùX?†«ü*ù8ë‰>û¥ÿ™DgÒê“)QÊ@CŠBR{*#¯S«v›N\©kEË{vm¬_½õ u—Ÿ:ÊUy¼7$ ˆ¬~zPêá% õO†‡‘çä0IB•žý21~ßâ“*a‰ R7º% %£À¡“Æ'ˆ+sÆ[|FI#ПC ÙxæÞrÞÉ Kuéžd°äI?6†Áæ Ê’‘éË´ä¡Õí»}³Þ­€ÜuÖÉp4ãRa”Iy(óD¤„¤+UÄ}4xn£i¹äW.潦ZR9ÆŽZ–´¸”µx~Àã £=}îô¡¸6žçÝLG³¡¸fÝtŽe© ÈKá)%ÈhˆÚ3ŒýsÞ€îóݰ‘z‰»Çã¸ãŸ,äÈ ö@-”à`: q|;Þ1ï)öýM\Øñƒ°ä|²K¹Pè˜ì7Ö}ìGí锳*bÑ*îÃmÓ&Êk µ>=‰->â›$$¡ l„ ЀŒ':¼7 ôJy²6ÆÒ¹Û „>ãke/CzJÈy%Dœ›Cé åh°Þ;™¥=*uDØ˶–ãÈy r#‡p€‘ì~¿]3ÖØÛÅCµmì›!È º—m[u¨í§ôÀqÖT‘ƒ€”§½4½ðÑ2"λۗQ«—bý†Ôµ8ÿèeç³øç¯ÖÒ”jXðèX©´ÛÖû©ê¹îÉ—*§ËFkÏŸ’Üi¢œxð8Çï-ŠîíùÛÔ5SëŸQ ¨KˆŠ¼òP<ÙlõRA÷'×WL›yFê¯qn]¿O.\T¦DÚÙŒ¥¨©A8@ò¬çÓ ã=g[7ÝÁAYöl‹jH‹ŠPIÎŽr t¡¤„¤ç IXúé[h|½S’‹­Ã·c¶y?_#M!m¡Góï;)N`’qÄÎ=»è E¤¬Ûµ ØSÝOQYq©PÙuÅ<Éè¹â àûyT¬õë¡›Š–Ùûˆ¯RnJÔ½))z&ù9!´¥@VÛa|Àï*ôô V¯AÜm¸Í†ßf~âÛþ4„L2nãLiNòT¶]mÔðP=6:>¸ÑŠú;ˆÑüøÒdÍH‹k=§ƒÀdöXަü21脟rbé;ÓgÜ[©qöš†§Ók( 8¤ù¹%¦‰@*>UgÝ^˜vÚ’Švd6÷MÝ$;‰¦RM„¶ÑÉ¥ýÅ€8õë’¡“®wm¿®rvÏnßnKНy‡åE,º¶ú%— ›Z*Û$zêÅ”éJ‰J7Vâµ’x5mq1€TÙmÆ`-”8ÞTNxŒëï lÜW Ç­“h½ñ æK¨s„zÉÑPʰ ¡+$úÞ¾¸ôÒÅ%³v^¥^Ùß4_1KCÍ.8ehHʸ­ „œ÷Ž$çßÒ¿ÊHL³W±vÐeÕ|ô–erÉâ°”8ïÎÙô#öܧr)ïÇM–⩊Ïð{$ÚW´…#¬6É~Xì~l‚=rzzº£"]eõ} ×Ú)_•ëI-Æ% )Ĭ7ç=äC¼÷¦‹+ÕQ½»¶áC˜ã$–Û7äÊP'%œeg' ²~„if®;‘¢]î-Ç!½³ÇÖw|™Ž‡Æ?4âR” †ygÑù¶œÇÝb‡tG©’ÅOIi2™QOªÒd$uî•z~ý=•º·=%™ƒñ¾sPmÖÔßΗ™ÑÈðk(gØCçk·x#çƒ7*”ÚŽB”©#þª½2pu¾Cpï«dî˜{JÚM…o¤¡$e9’èkÏÁ}ç+Îqø¯^î ½}¢ª½ÉTˆ/=`o”Ã,ø€òio¨- «8Ãa û‘ ³eo}'m×&’ú¨ò_[‘lb9´ç‹jAtrQë?œ`ý5~ÆÊÑ™\f«w舂«bÇ I$¤RéJJpq’¥zëvÛI uV¹³kkl[©ò–K/¸’¤—W!˜Î(+ó-ăœe^º?iqg¹o‹¸œ«n¦2Òô:t0Ú¤‚O—U)´“ß$$“ì­H6=›ø¢CíJƒ1²"»"Gu9¼GYí`+>e)$}=tVßs¥ºEÌ£‚à ;$‡æE °‡R„%AÄ`0 £Ÿ®“L·,J ;‰55Ò…a—=‹èáG6]D‡J<5†ÉQã4YA·w+s NÛ»vñ63Œ6Ó%ñí'åÂo#¯p×ê •ño`-ç—M2ÆÁ¤·öT))ZJNp†*Qè`¨ƒŸMzÂâÎÖ$È›z5Ë®@Kª)|§)+i1y#9=ò¿S«»‡dÙmMÑY6Ãp"Öº¶HS¬³ºç$¼ ABÃ)JÇžÀÎuáó4µws¡¹²®ê,%¡ç‚æÛ'Å}¢IQÏl$ð™äH'AzöFø]CM­Úô5/7á¾$%†ä8GD7‚€°HÇß¾žÚ͸íÜohw®Û}ªò£»LÄ„Iù6Ò0VR“çúã‡/¡ÒféÛqÙ™kóm§-J-"S¨“%š–»#ÂJœ@䌓Ú#ß0ÊÜ ÅhHrÛ{î9‘VÔ⧤±!¬à8ò Plõåpþý5Fª³2“@ÿç-Ûq¶<æäâ‚‚|¾êAévöî4Ó®+æÇº?1 –¹bK¸O'ymyà ã¤3£êM†è´rÊ ÍÌê×Þå&™ÒÍ· {ˆuªDª;wœã9»bÃakPφ¡ 299×aC—~¿@ê[>=½Z‰t0ŠÅkŽ|º$^”$¡¦èCxýÚ¿¥¯ˆ;ƒâ›Á»¨UÁЍ{zâºCŒ¸©ÓPG‡°HáBJ¾¡KOìöÕ˦ﬥ@~chšÆ‘$îÉ)qµ)8JUâ$à‘‘Ò’{èçKÕÛn¿v7c·â\U-ï!*jLÙÇRI䥧ʕJÖÚ¥~:4‘¾!ÌCŽ7zÍÅdVQ%3XÓ®¸àÈK|CJJ—éØp‘økÕí[§UQÉUQ!o²™0DYaü’r[q<‰>žUã²~šÆ>ÓøMK*;7ÏJމILDÆ­H(¤•¤­y¨ã̄Y0š¹›Þ® ð‘àLÚ*âè|‚R÷gþŽíÍÙ2ÙVöí×4óÍ=C®IK’HO üëˆïŸXô_ ¦L'\qª¬ y®’óJì’Ók+'´ò>ùÓ’£\HÜQ”Ý\KŠinü¼«*XËgÀP«þsÑ%9ô>šbÌû-©à@\›4IDuC !ÿ©yù+i‘Ðéy'é ÖýðŠå?å—ØÖuñ2£ŽâAÎ(BR}r “øª>'È¥¹º“QCh.IKŽü“fJGÿ„K«'Ô$“ž±¿ªÝ‹µžÊk!>"¥@›h²äà¿4æX$`2Ÿ.›Ÿ®¨“¹D‰LFœPäQÄȸÓ@rÇ—$gëï¦ -Ñðî\éV”ï*CMÜi5§C˜é|«)Aè…IǦµG™¿(.¡Z:Ä›Ê2¹ªKP´µè\KÎw×i? møÁ+aÝ×?ÝÕø¯ør"¥Ë¿Í¶÷DµÅ-­)Aõ<†?v‚¾æ¶¾´£n=ÁNi+ÄU¥Ç懅ôÛ+šÄ•¤yÊr3€£„‘5lïÁIurQ!ˆj"\Hì—g <&TTpx`úþÝ ’ˆðùTGÙ5“~f;%o]à¦LgÅJà²1Ä„•àŸMQ¯U´XIv†ÿq²àJ±€Òä®S®r<ÝK¤†R£ßACû£½ ;nzí±€mÈô¢gÌ-±W[eÖ8%Dåir;`©C‰Îr`Ö[fßiÖî?¶-÷"r*׊è3¹²¾?y.*QOiôÂT{Úç2bn%^8äI7Å’¥sÐæ¯%G¥!ÆÎê•Ξ6þÛ‡l‰ôÖ›f‚¢{¨Ä9b¡–P“ÛØ $)JÉ Â@Ÿ¥ -Qîãp5oî½­:#m:¨nêCÒlwŇ¹Ê°HЇÑ2£8ÎÜ6¾ì”|üD¶êâ´®>r]ñÑÇ\’O·ZÓ´êö•<×¶ÝžÝܶ’›–…»düx-4„¬ÁJKŠüÑÈõ'Dè–Þ±²Œãð$]IkiÓ¼¶cÁ7ÑšWŠTx ó®ÂãïÉy[r¶EÅ} —©ž£XÜDÄSN$ ž‡XÎ:õΩMÜ{ƒìª‡·®+¤8ËŠ5xp[þ$«ê´þÏm\ºnúÊTæ9‰ \iNì’—R“„¥^"N )'¾Žt½]¶ë÷cv;~%ÅRÞò¦¤Íìu$žI Z|©Y­m© Wã 3IâÄ8ãw¬ÜVEeS1U:ëŽ „·Ä4¤©~‡ †½^ÕºuUl•U‰Òû)“E–É'%·È“éå^;'é¬cí?‰ÔÔ²£³|ô¨è””ÄLjÔ‚€0zIZJÑÑZŽ>é,ÈE“ «™½êáJ Í¢®!`~‡Ì(% pá îÜÝ“-•onÝsO<ÓÑä:䔹$„úηøŽùõA¥ú dÂuÇ¡jÁñ §šá)/4®À -6²°r{O 3ï9*5ÄÅMÕĸ¦–ïËʲ¥Œ¶|ê¿á@'=SŸCé¡Ö,ϱrÚžɳD”GT0ÒñQê—’¶™—’~š oÑo®SþY}g_*1јî$à!²„!Å'×* ?€¡3â|Š[›©56‚á””¸ïÉ0†d¤øDº²p=BI9ëÐKú­Ø»Y즲â*P$ ¶‹.@ŽëóNaµ‚F € òé¹úê‰;“ÆÙ»ÎNÚjßÚI_[[aHÔ8 ‰S]‰]`XOa uÌ<£ÇÝ œg9Ç  ŸòÓqç75Óq8J5k}M3Ÿ:”\ JºõÈñ:»ç×ND˜ûn-ä™PÒeÍNÝAm åW$”B°2y uƒ£Õ>[nõÈÚ;ÂÁÛ9ì¼Û .•ùpÆ뜠|¼qЃ‚1FͬMŒ©Õ»¦|*i5ÿ%%„QºZy@yжP0súdœûŒãA·h]* Umç§"d(-Kn4rÂÑR\*CK9û¡#ñY®_:ÞãMÕM}TV‹-Æiörl…`øk>H8>€ö:ÀõÖ»:ÝÓ5uµ»=«+ Jö‡ åFf9p¹¤¼ÒdžIèà+†{È9Ñjw#WEpߨ¬Ý…B”ã-Eqg!OÐÔW‚Ãîõ‚’Û|Ú½‡ÝúõªU³¦7CÛÆŸgÖó–„øë[HBòŸiy8ìƒ×¦‰üIÛ2®¶µ[öÑ`Ø×Gl%„4fC‹Oº\[ dù‰V~§ÓG6–ÓøoQ°+¤M‹6f%rä%6ò%´—~á*ðÕŽC=;Ï]èè^ä¨+à³pÜi¾…Ô>%%¦Õú›B•çõÛ#dëFò¶¥{{»7o± ø2¼GUg6"Xo¤ºB‘„(’“ÒýÇ®¶_IgáûW´;‰›÷åHKRëmÖ܈ÇM%^€xiYÀì X—ñÆ—h;hܵ£m_@Ú[ŒÆ¼âa½^Ì9N % I)Rœ}ôó=w‘רϮ‹Vï['¥×RÐPϧ§uÄÇ,ýš€§Ñ )[e¢•{¨Fr­“mþ"WÛXA}ÈÞàmâ˜rc\Á,<„ç4¦@Kx÷ô>º ڽǿ´ì$=áEô[³9²Q “T^T€§”@³Äa RGÐë^ßøºÎânMšë¨kãGpÉE[MBöS‰D’T>ŠJ0 Ñ0,wÜøÑ¯®àÞ5Bä9Ö©Æ­¨~lñð›*XÆyË JÛ”7òU9­å³Z«{ “6JêŠT¤“äi…¨œ¬ö8íë­‹cmÊ€ÎÞ­qлJt¦|Xèu@“”4¥’T’¯L’@ôÕ{¨¬E—oÞÇOØÍ—³•K7æ -+üÚ[í­+lãî•qáIûÚrØUÒl*eÖøû¶ª#ˆñ¡Ënå0YR‘€Zm²•d•Ò: )ÜS¶Ýs–4¥K%d¡”Îm”…¼G ‚ÿD §ñÖ¸;ÿoÕØAT» –­b­|a*êZlN y•'®XôÕj½õdæÙŽ­¥ðÊ¢Ž%;¢E°•>SŒe¥ ô¢sƒ€;õΊok»¢®¶zpµ:ô8¦TÏè( °é.g×—éÞb}~ÚÜ[š%»6ÔµÒ\{Ç–ô«<—!ù†Ö·‡,~)÷gLÛ²¢{[† ¹+£’ˉ¹qëå%–1×Ð2zÏ ¤úú§¨ølÅÓ’nƒZÁ Žòù¸ °R–y´#Ÿ,~’:Övl캃_ºw;°çÚ«æÚùjvÐꇄ۩ë8RÎ>£h)Λ\Ļ軪ÓqÚWã4Dã³úÍø™Qï'±××Ak¥NFᑸrMImM³<ÚÄÃqH)µ3ËzI_«¦w¶þÛÜ;Jpw©‚¨”’·ËI—|¦œŒvp:)ÏV`ÕýжìÜ6Ó™®ùY.»BK­0²‚ü‡Û!#'sût§I;™ âS 6ÓŠ„x­º² ¸6µ…{Œ“û¼¦¡‹žU-…»·ïÁˆBÕÆ^?0GÜà–ù 6Ièòr°êZˆ°ã*ÕU/J©ŠïÌÕ[Odóàó PB{Wª@úg=3mˆ ”Ó±§¥V`©D”ä‰(eÃ÷–‘äRr?H«Ôœè :w¼Xpc§¶ŸŠâ’ëμê]ydŸ¼¤¸Ž9=}®‹É›·SoóoHÚqäE”¦ÝŽÅƒM=çõ!&:O/½Œ)'$kFÈøy¶ø˜–/¨òàRåªL;eÅiO·Þh,©J'ÛÐö}Úw–Ýølä[¶ãîȨ’ÔÇbÈzIqå)DÌrpœ’4q‘ØÁMr™ƒ°¦Å°Ú6ªjlïa˜ñÃc%º®]àc<½G¸Ý7 ½·è~B"Zñ,dµ]c/:jâÚA â|ÅIÆ1ûu”}õ¸%îÉ’'ÕÊÛì´”¦¾Æ"˜ik@PJRð¾.Êyž’{žøªÌ+{Ú[ýÉM5øÑ‹mσLU¼ú‰Â\R\RžÿK×@"M‹²­c³·#Bðê—4‹u¸§ @æ´x ¸±õ$+¼±­öUöð-á;sG‡[!Ó%!vÒhtÜlr¹ƒÿo¬Ý´w"RZ[m&*Á X8õ€ñ™×G¦p3û‰èê՞檨›Ø4VÏð bÙµY$1:ŽAm+ Z9–1Ž´ Û²RçYXÄf`—iHÀ~ÂdÇä­ÒÆ-%io8#•éß#é¢Ñ·ÖÈ´¬®iSSˆKn,™vÈB~`+óI*à}ò’¡ÐV{ñ×j.ñºû@‘3å¬ëã¼ÄJ0JV—]`8¶ÕúÊ(##Økïï\—‹?Tø?$íý¬5®3…|7*I8ÊŠÕƒŽ´áT]GÃw’[h–Ú‡Äô]o‰qJ9ÁH)âGgK;±­Ç-Èñé¶Å¥îÝ„ávc²(ˆxû”!i ëÛËÖ|ºn‡½÷ÔÔñ$nɱå0”»fÒê Œ çºßŒ; q_4 c)ö4.v‹´P¯ås³Þqõ?> \¹ ˜œ¡2È)Rz‚SÖAšr QÑK‡u{IjÌô5â­4uè,Dä“ù·R¼$õœå9ÉõÐbÆc@—ÕéÌˬš´¡A †‹„'Ã9ÎÏ/}YÛm5"Ly•õ¶QwËå6¶–;qDu0rJâR¡ê’=–=4Á¾á·ýÏ[<'ÓMtÆjì± ~,>M /îO¨'—ס¤w½³ÃHhþ bè2˜^ŸîÇæ³øiðbúŒ¯æ«Yzéï0UÊ@~÷·@ÿ¦;üÛZé›Û\Óá¿{sÿwù¶µÓvøé:Óâ?µißéÎÇÛ†½ÛYâÇm×Ë”ˆ¬;j®Nª*äÆ$•Í (1Ðë9ôo·+kY¬¼¼ð༉3)º…/²Šl0§±\¤'Kv³Y­Ü{Ztˆ¯Ée›e©m³âó)ù99)ð’¥’=pxõ$ZÞ[²¹*¶v.êFã‰0¢*ëÞi^IRI†^•) cgXáÒ[÷ŠSµJ«%Önƒ"B”±d¦ê‚Ôµr+Zm ñ Ÿ6}që«Óì¢ÐÖÅœä¿Vû©a·mkyð“úm´¬ úÉ:IÚ‡oÜM—¶ê¢Û;`ìt¦¶“|vÝS)i·áóÛ¼:ì]Ey¶®[…iSU+ÃóL×?à8¼’ S¡)_”’âc×½HÒ«ª[[yO&UE[püGå91É*ZÉÌÊR†TVHrìv´Í´¬êlS²-%TŠ©¬)çÜ9.;¼yã+èàôWÔlͨˆfL8? —"d´–Ò#>ë©[h÷R’…¶xú2Nz#µäîé—mU튇‘Õ…2¸ß2¶¤¸‚%`(œú”„ãñÐ0VÑÝMJ+©Ö’’“á¢ÞŠÕ.¥œä¼÷'sìŒ Ükwl¹-¿A²ö|Ë9,·fxï,•Œ 4u8V3æäAOMiÝJ¸Lý½YŽïDÕ0™RaÍÚPNT«WÐg)$+š ºËxÎ~SïVwÆ_Þ§š”Çl“ÓÁ |¸O©â0:ã \Ú×›¦º<×$^míµl`ƒkÆJêŽÅjüá씥Xå:).Ž‚ª]KwÅü;¨í‡™z¥™+ˆêÉÊO† FrüOz©&Õ¢R[‚6EƒÂCr,%Œ¶‚TÓ–¼U’O_Q¢Ô´2væÜ{r=·Ý¨˜LwK«\T g¥7È)(wØ?¤zIñëØ¸­Çci%|Ûv*‚í|t¸}¤)…©j'éæÁëL>'mÙÛNa—&’ÆÅÉ(u®Ç)pƒü` ósþ·#ßZw.ݵÜQkdíÚ¹’jØ.J }¤0¤¸N„%—æ=W¨Ö{†Ê­oHM&õi·¥g´òPÒè-“’ê‘ ²ÝÖú%Uus«êdžËÖµVqng˜p²ÓI=cð{V7[´ûN šÍá¼Ø{pˆÉz,¶Vâä!â=ÊcðJ Šæ ;ôÖ¶öœŸ‰h7ÏFSʸ®p©>å+xÄ)lœzs¾¾ú×}²«9–̗óQ”ìf_¯U‰BUÒJÀëÛ±¯zP%í·"ƶy* ‹QRä¶£Û­ùrUœÊÁÇ~&Àž w ÛOŠ.mèú › Ú[@dg̵¥.6µ/‰Ç"“ëÑú?Ç]…}#U>1#¢:‹r©â¦|dý䆃’Jg>‡ÓC,ë+cnûê½àå³èùƬejq²{J²…ãï.GA¡F‘ê—iàn:šÈˆm¥ÌˆÓ2¥•É$”Iqq׆n°H!nVÖ³YyyáÁyfSt! _dØaO!c¹H8NƒímÑvô£ag.,Ú¸¹Ås2ìÀÂJuB:‹éP'°–Ž} •'å»+’«gbî¤n8“ "®½æ•á´•$ž(@¥à0IR’0Ft%¿x¡U;Tª²]fè2$)KJn¨-KW"µ¡ÖÚ óg׺½>Ê- lYÎAÛõoº–qöÖ·Ÿ ? ÛJÀȬ3¤¨výÄÙ{nª-³¶ÇJa»i7ÇmÐ…2–›q>ï=»Ã®ÉÕØôW›jå¸V•0%R¼?4Ísþ‹É  …:•ùI!>&={ÐiUÕ-­¼§“*¢­¸~#òœ˜ä•-dƒæe)C*+$¹v;ZfÚVu6)Y’ªETÖó‹n—ÇÞ<ñ•ôp ú+ê6fÔD3&†Ë‘2ZKiŸuÔ­´{©IBÛ<}™'= Úòwt˶ªöÅ?ÃÈêŒÂ™\o™[R\A’°N}JBqøè+hÔ‡kIIIðÑoEj—RÎr^{“‰9ö Æ„î µ»¶\–ß Ù{>eœ[³‰RÂÔµôó`õ¦¶ìí§0Ë“IcbäÀ” º×c”¸Aþ0ù¹ÿ[‡ï­;—nÚî(µ²ví\É5l%¾ÒR\' BË‹s Š «Ôk=‡CeV·¤&“z´ÛÒ?³Úy(it ÉÉõHÐYnë}F’ªº¹ÕõNÈcÃeëZ«8· ³Ì8Yi¤€ž±ø½«­Ú}§MfðÞl=¸Dd½[+qrñå1ø%EsPúk@Û{NÏÄ´‚gŠ£)å\W8TŸr•¼b¶N=9__}k¾ÙUœáKfK‰ù¨Êv3/תġ*é ¥àuíØÇ×½¨öÛ‘c[@¼•Ũ©r[QíÖü¹*Îe`ã¿“`O;Ðm'Å6ôFýM†m- 23æZÒ—Z—Äã‘Iõèýã®Â¾‘ªŸ˜‘ÑE¹TñS >2~òCAŽI%G³ÈŸCé¡–u‰±·}õ^ðrÙô|ŠcV2µ8Ù=¥YBñƒ÷—?£ ÛGW¼í½ÕGKòm¶ä˜àKx:£€I Éq.O +°zÁ×——Õuèzt{¹ºhwÃóUÎÆ1Ô¬ó uÄ4Ûiãõ^­]Š­Ã½í~Ê—aY&È[H€LI2)-(}· zÈOYÉμcNår,ÏC¥ITw¢[ÙÇ‹ÅI$sq*#§#ôTzÇìÐlÙö77µMî)ד6ãRˆ}„ЭùÑû4qD¥Xʇ0}s ¬!Û@L&£î‡ aÁçYeÔ¶V¢ y¶ë P÷RR=Õé¢ÛbEõò•KE%º“,¸ÔÚ‹I)n?|ËÈu-« 8Éý.ú_ø”åe¤ÕM‹U»íŒêY°~$Èéa·TO‘o’´cL$þ''Z×gÆ­†ÜʹîFÛ2ØLÜu§ÃfAm(K^( ÷R@IôÓÕe E}½Õý„IˆKPkXfKe ¶Êœ k×–ߪµ£lîJ–jìÙ¢Û ÎžÁÊÖÞŽÜ–›Ê¢Ûm¯>…JÉôÕgÞÜ–­UYðîÊeD 6í˜)zÂ@ !•8Þ<ÇØh6í¡}*;’™¶ùŸ õEváµá ðe×Òwˆ¨pö3 û¶5Á­™ášî¶L42܇ŠV~ë„´û7‘ÿ ¥¢£¡Lvn+¯'î9É|Á„Ô—8¸Ùía$-´’zä@9ÏmsØ·?ø†ûw–QoÄù‡k7´¶„F$q.¥þ 'é'#wêŠÝ}ËÎ}—.Á„0¶Ø‰°ÊHÁyä»É>&1çXÁÏ@éäÇÞ1ÄZ é_”z]”VëùÀSM¡IA g¿ºžðGÔ° e^Ò&6ÈoeMº-ɲ#%—P>óhd’ò°¢;Wƒõèh ;£âctvJµ´®ˆ h²jÝbÉN8IüÛ©A ë¡áŒ=Î4Ñ\Ù75(ûSgÐ[܃óã1T‚ãk ‘÷ ŠQÀûXçÜ…êö¥mT¹ ðÛqiÌB ýï$4ëÎŒ§¼qÓ#–;ŠsõqïØ…Ù>«nµ2â:èXò¤¸Ÿ!=•'Ëûub}|¿[gMÊÝ6r¤!- ¯|ÐKey-ÈüÚ@ôÈÐ øYkZ6øÛóUO¶‘áxs•>f ¬(ùÚð‹o”ú¸áúà}\-¤Q†ã4·SÚ­G'R!¾¹Šp09¸§‘õ(OïÐ?†ê좭¸—U3”ͪ•$G’™ BRH,0–8_T¬}5fm< ‹$@¸ã[ȳ±Å5KÖ¨d°Ò³†Ð‡Z+ô3Žúìh |6¹—ܰ¹ ~–H?1âU¾Ì•½É' 2RTâ@8Ξ±K瞥D©OüC¤¡‡OŽ#ýà[XëÃm°—RïúE$àúk›îˆ{âÇxÁy†mcJCÏEDX°Ï‘i¥)MñAÏú<}yÕelÿ‰·_!Y"¢KlÉ+TÔÖ^y'©ÓᬿIÁ^΂œÉûGtÀµ¸D¨Qæ2¬Z±v$…°HO%6~ú}€!~ÃúèÔó(!ü?Q"ÔÅŒûpãL˜Âg¾ÂÒB…§Ð‘‚Rx è åÄÛû‘èñë…‡Ì8_Í4êÀt’‘a# ô'þ¼wžë²¥û:çgܘ‹ñ›ùˆUÏÇA>xHi•¬Ÿ©P@ìôtvÜËŠØR£AÛNQÍ–jBj: R5Op¦uÝ£ wqÀ¸®!¨¯ÎKÒž*Q<ˆLG¹ŒýåzïT,#*º¥èvÑm«¤%H\è>?sÚêeI+#AQÆtGlÖ6ÞÕ°•yul~y¥„‰»ˆ0§Õœž –Är”§Ð­8ÇÐè=!p¢ü…§Å€•¡Èÿ!]1ÿ,gƒ‹R^8?ªHô'ÛKRwcÇqÄÛûmØ´M*Ai‡Ü„²‰ t¶Ë%|Úä¥d)ÆÀ=àè½ÌtÔí8Ö®HU¥Â1l`²ÊWHqjK®¶¢GiXþ™Ð©¶ÓáèœÞáڢȼS!6¡×¤qí$9höußY2§§nC}ÅÍûf–´ÌE5;ñ"¸¥t߆ëLW‚;ñéë®[I¶!ßÞÛ!´î/”Ú[«XyRÑÂÒÈ#¢§¿yõ×A±sävì‰Û’-œ(îyÞ#®:ù—C*+QÆJІ<Ø#HÛaÚJ;)­^mûºð$!¥¿}*NI#Ìœ°NGE*W^¹Î€¶ËÛÓ¦[ʧ‹¹«+­KŽÈbOˆÉhಅ¤!°2I% úèÍ«Qa&²=5¬&Rô•Å™>,Bão¯Ĉï¥år*ïÄ Œ”N¯n›éÖ qˆ­žCŒ'ä§Ãq ˆ¥âËŠ)oCPAôìhdÍ»o}|äÅ@½½M°"CL®SjjR@+p-!L!ÐGöwв»£2Û‰MdÕFwÂzUSNØõim2p}äW_‡\ßrÖâ\ÛtI j4ha.-Ú×Ô~`«%Ô©N¬%Ó€9•§gÕƒâu•Œm§ÿ‡‘·%MS©nLëY,¼Ìu69#'¼€àugážãDæœÞSvןiE´É•Ë HPOó+H9ñxœN´¶tÛ˜¼6ýsÒÛ\¤Êe’Ó|æ¸=VúœoB»Ï5¥'>\ú}tü{I¿hv´jøÏ‡]R+˜ZÁ¶œ+>RHEà}::¹lþ%ÓKE†ßwkD«ÈroZÆ y û­òò¥õ$’ž#Óã²wøVã³€¦bØÅŽÂdLz­Np'Kjd„¬eC¡‚rt ¶•ÛU5Ö¿fü9­@x-oImƒ;‰ìV¤çôB‰õëÓ?iÚEbù™îíØoVÅ.°ÜxIi–bätâÐ¥ÈvãÊZk¨Â©ræ¨Üɾ°Œ¨³ žm‹9hbP>¬†•çãŽÁ$ƒû4?s@¸·t9–_fQV&Á¶`¿1è‘W0pí •4â׌ eHcÞ}Ú$­µ`Sm7pSκâ‚ËU¶€„ŒŒ)({Âq@žÔ”’4Õ+´»ŠË;ˆ¿,(:ƒkTóіꎔ¥„–‚Súê*öï×G->.SoCÜÍQJTõITÖ]v8D`<írZB~ðóe#èzZ±qÉo½³ƒ?fÌš¸.ÜDžÄÚGe<ÚU“ëåQõ:Ëg~rª,†î¨™¹ˆZ\ùqãÇI@á©ÔŸ|eyý¹‡Ä]ÍM övÍîó£ÝfLÀ—c¦ ŽÂW˜©×*B•îT=À={®íª‰ V×ɃBõ‹ º°ˆ–Ô'ÁJy`: ºïÔ?XèµíkcñÔä¹ tDI 䌸Ç2=†9\}tö»tû½Ë*YÖNˆ‹f*k«íŒ´!…þ‘Jò¥úJI wÅ#:aßʦŸ»Ôv¤V— KC)&µ( âA CëŽAöRýA¿Jq?E%‡¶~Ô}Õ>ùE„h°!àŸ(ma†’ßãÈ“Žð}õÜ?y{-7*ÛwpfÇo]\ ŽîNŽÐyã(ë¼~:›‚úDYrST“\%…2%0‘5^…ÇrP¾=œg+ààé5q¯Þ°‰õÒX0lHò› W‹ ¨òykJòUŽMœyN}µqpÓkº~N–fâD5:q¶eˈweCäÖÁûÜÜc½YÜí@OÄúµC°ùõý‡%·žûV<Ä’—c}ßô=|ÊJ »ëÊt‘í×ñ?»H—¿Þ'þƒ'ù…éöà~g÷ipu]cþ£#ù¥êÖ^º{ÇÌ"¯èÃ0NÛüç›o]6€yF¹¯Âäçm+ýyÏü k§Q§îãZ|Gö­;ý+cíÃËôÁ7›]VPÑ2*mSŒ­ÿ *Ä)$eYdŒö0sƒ¥×¯“qnÔV¶ügÒ•4ˆsÞ\¼’2Ö<5+)=”c¬÷MTë«=¹YZÍSÒŸ³q-¢Í°äe”O4”¨€q×®==CÝ.Ò´™·^îÌ£¤B0¥UFD”J á\ÒÙm9åè@ë>úÇ É%r«TÂï7{×0üKËöP™¡=xjmÇ __ yc'£¬wd-ƒ˜®¦ZŸCnÀ› #‘”ÈP ~y¥¡<ýþÿúO“ö½Ljy1…ä9òü¢Â“ùW”â’„}Rç"}Žƒ^Ví™4“¿)®k€„G^Ý`)Å%=-,4·\Z~«Cƒû£R6Æ‹I¶ëª£[J‘¹l׬4©Òd’p¢¾*% ÈòW®r­û_tmÚ—* ]T”­1Ü0ÙÀ í%¤”©\»‡9ûšãWV´õVñ$ØUVUº†Sá?•çë|Îz}À¤,ãG8÷N™~]ÙnA"ÖµÚtM¥¹aTÿáÆ22òÞ8©ÇŸ˜úçZØ¢ÜÑÙrzkâKš¨Í¾–7„¥ò†žt:c¿ Îq¡;Þ½»ëaö„4ìW܆u¨L¾‰+ï-©IÏ¢#ÔeC½Ù®xÒ^‘¶¾Å´qL«fí¦¿*D€‚PJÂÖ¤4 2BR®ÿ iÊŠ®¥L?9Æ7cUL((±ÒrÓ ©=,¬<®}ôúi-š‹eIå/o͹§‹Uà©¢ÃyRÀòÚ¤(%³“ß}‚íunVV,ãmÝņ‚‹©/Ã_Š [} ’æ~¸JGëE‰¶ö½üÉô°àÓY¸Ž_Àm 8]ï=ÉDŸ.s€r==u”}µNôeµy®©ÆÙ1ÛŽÓÒ‰  *?¾è?xò$ Vólm!"D¸PeC„O‰ùAcÌ!g±$°QÙ_Ù¯7>ЇX̪ÄÁ±ŽP´)«™ZKŸt/ŒÒ¦GCƒÖÆolÝ¿S¸6ìï—fk̉ ºeO+‹žU”~x9Ä$+NN<½ ·^v¾MÅ»QZÛñŸJTÒ ]ÏyròIüËXðÔ¬¤ôJR=ŽŠØmçfZ3Ê™V¬¸ÔuÚKmØéJ;q^ÙæáÊH)茅cM4»JÒdÝ{»2Ž‘•UQ(ƒ…sKe´ç—¡¬ûèW*µL.ów½sOļ¿e ê׆¦Üp•õú–2z:ÇvBØ1YˆúêaU©ô6ì °¢9L…çšZÏßïñï 4ù?kÔÆ§“^CŸ Ê,!q9?•yI)(@Õ.r'Øè5ånÙ“I;ò‘ÚèÖ¸DuíÖœRSÒÒÃKuŧê´81Ÿº4cE¤ÛuÕQ­¥HܶkŒVTˆé2I8Q_äy+×9Vˆ}¯º6íK•P®ªJV˜îlàö’ÒJT®GÝÜýÍq««Zz«x’l*«*ÝC)ðŸJóŠu¾g=>àRq€£œ{§L¿.ì· ‘kZí:&ÈRܰ*ðã?‚"ˆNpR¢1÷t ·Õ[ògÊÊ~t¶[…†Ýep’ʼG•ág×ÓŠS×ÓW¶Vã´—wgTýK6Ó"!Ä_;ŵá>`¥¶‚QèNr¾ýÓª•l^V2âlh#. Vòfñ \ 6£ÎhÈä?M?ˆÒŽè¸ƒI –“O rd¼bY´­Æ†ÊÈ…:1Aº+X³¯¸´ÞîÉ6¬©2ìPeÔ[lœ‘úzäinŽ^Ðn$¶õü¨ ¥Í‹WjÚØDaCÆŽ†‰Éór¬i‚ÇWA)íªZtµ‚™›Ÿ€CñŽ3à¸8Ø Âúìã@Ëâ-Uj¤½lÝÃMÅRTÙ ²’øRp†Ò„ŒúùOú]h48´»Í¥XM¿´º[n¸ãHbÍÆ[ÀyHoTcÏÌ}s­lQnhì¹=5ñ%ÍTfßKƒÂRùCO:±ß…Œç8Ðï^Ýõ°ûBv+îC ºÔ&_D‡÷ˆ–Ô€¤çÑ@‘ê2¡Þƒl×ú}4–ÍE²¤ò—·æÜÓŪðT‹ Qa¼©`y mRÙÉï>‡Avº·++q¶îâ€ÃAEÔÆ—á¯ÅŽ-¾†És?\%#õŽƒ¢ÄÛ{^þdúXpi¬ÜG/à6.÷Žä¢O—9À9žºÊ>Ú§z2Ú¼ƒWTãl˜íÇiéD…ŽÐ‹_t¼y@Ð+y¶6‘"\(2¡Â'Äü ±f³ØÈX(쀇¯ì×›hC¬fUb`ØÇ(GÚÕÌ­ ¥ÏºÆiS#¡‚ ÁëãAÈ·.Éj¾¶®FÜ”¶nÓÏí'S«VJ¼¼B•Œgî¥)WíÆº;*¨ŒQßΗ}i/7^ogÀmœa$êµ{ÆUëÖ5~|ÐíYy‰5¶i±eÆ"UãqÒN8•­¼ƒGG¼õ¢ñvþÅf®;Õ5ÍÚ®0K(²¥Œªô $ŽEo¯Yìž`vF€$í¾ª‰Uû_o|7™²E›rd8ìôu¨'¾.;âðÆ rVƒžò5¶ºnú–ýë1+ëšj4‡<¯¶ ÛoØòm*ålj#.c둪Î7{Úª¯v\í›1)-ý’h7œx¨}éE±’0HXë¼{j…ÏØ1ìå¬!CqÅ´©ÙKŠû¡ QüáR$Œ’¬xg=d$è+m{›,l“u`‰µì«Âj! óäSåjC™ p*ãõüZÑoÙòvôxÔï!Ä¡1Bd§ÑeáÒ3ŒðϦ2“ªt{¾dË›¨=]&3ÑDÅX±bÚ'”‚‘ã¡*Y§%¤öHÑ+”pbb·îÏMjÒ\”Ĉ ; «†SÉá•8sÙ*NqØÆ‚Wnÿ†»m.½á…X•(D©ñàÃm t«²Ïˆ¾Jå!^žºÕæÙÜw*C›V,h‡QóðªÂ%(}ì)Æž ÆNJ½p·ÓÞS¿°.#¢Só’¤B„·ÚGˆ¥œ-´Ç.€zðòHë:³*âÚ|ĺ”Iox®À‰)ICX øÊ°•«°R°’}‰ÐÚó¶.ÚeÊiÓœŸò‹(‹Z쌰ÒWê§Û@g‰—nŽUNÚ6TgmþGÜÑÀaÒêñäGâÖçOŸ‰ÉtŸ µNÝ„V\²UŸËXJüòœVÙ˜ù$º/¤+ €1סÒ}—äÝýÅ+sUk)rЯºˆâáÄœ-…6‰)Éž§=ë ³¹ µºw»õôö¶oBi”ŸœzK“êy¾ HÇ» ôÕ xó«ëSa¶¬+$„¹àY³.üÂ;À Åt•'£œÿ.…î†N]W³òŸj¸êÖ¿Z›–JTº|5·êAh‡ø{éž«áå–ͤFæ‡|ãÒÐìh3z2–ž!KBOˆ¯ Yþ,žý4 ö©mjt§¯}¶Ì&æL~ˤ+§YS¡kö’pAúëæn*¥@ªŽ¯³¢¼ž߸8)(õðB‚‡2r2POc£¦Ï‰{ž ldÚm™‘6ì¸j}-¹?å›%' ) ù9Ò¸”Ö Æ¹Îϼ‚‰mÇf‡s."â´úkäî´Èh¤¨e-´c)ů¿º;õúè`±¸vÃRöü43[Ë¥a,ÁXiJÉiOxiuX=§Ž}ÀÑ}ÀÖï«TÍì›j¥În+q[ÉiM´Ò°€éRÜQé~eë­N‹dï'7"éwU8Í|ÌxpÊTħ!Hr8u´¥* uîyöçtngª+[¹veÛ¦\2…½ÆBr°…þÃRˆ?u²“„‘Īw+šÙ‰}«få-¤á¨ÖÌhθ>*#yöI€ÇZ{>»níåý™_EY¹e¶„¹(·"\löž(,¹”ŸPGòêŽæß´{޲5ükMëLý,Ô76ñ›yx‚Vx·“ßD©^üNšà7y¸Q æ®^å³®SE?.ÕÔP‡†|E¼€VœýÂÏ^œÞÐOå¬Í§#ÃÜ›x¹(´ÜàÄzééàøem#Ëé‚Ú²ïÕ*—1¹õ—QgÎL%¶]|V’´g´¶ÐHA=á@þn©«¶¥+SÏ]мÃ.*½Ù’ĤÉYûÊSqFFFBœëÛTÞÞ–+Yƒ[¹(&CaÅ‹™oU®½Â¢9¨üÊ”¥œ“Ö2Fƒ|;Úû²=£ß+¹%Ö3 iq§Y3ZHʼ‰m%´$`…Œÿ÷×HSS¸Xos?²'^XÄu°ó;‘ù/8¼‚0…"ÏÞõÇ[’k!<çÇy¶”®`œ)│S×”6G_·7n’©‘mU¼o§Y$)-¤Hj%k-%)þ5h2CŠÈ9í>¹èkû…ªêû'"]P©ç]Cë®S±ÒÊÚl’ãIsÃ^{Á mxÏ”ç@ÅPÍ=´¦‘T‹{–[):G€SžÔ©ðÒ¶Õœù F}‡zŹÛ^,ÞÔ°7tf¦áFvgå²IÈBx« o×$çë‘¢?s!¹WÔôÒ]†Ì”"KÍK€…(›Œ´%±êBÕì3~Öš®}zfï=µ.RµÍ~¶#l8“ØoŠ‚ÐRŸL€¢z L;ïˆ;IöIáõLwYZP˜NA„ó äœâÝâ>îI zõÖ…v¿Wº¹=·¦ÆRP"2ÂIãù ày) pHÉǘk‰3(æo%¶ôe-…ÛüÌ´øncÌëeÖTÒTGæO×ÓLÔ6ÃU¨“;ì§Ò‰HSÑžžWÇW„ׄ¬’!GßÔè6£rì§BŸWµg^˜* KB[éB¾óŽ©_¢O`)E>¸Vw<͹†æÚ;—U–³€u0E„²·ÅIÁÉ$¨¬ïìCŒ×Z[GT™t°…mß”ð–»(ºÓdãQo'ߨ¦Ñízkª¸OV ÐÓÒœZ_/ÌŽÑu!?Å!-6¦^ïÃÀQÈÁÐY¬Û1âÇ‹*æÖ4DO-¦w†â[XÏÂq@þ(ècTš~ݹs*w$»V£&E3sËa‚“ÉiQYB[Çbž»:©³þ Û=¸M´ Ù[u¶möã9R¨è##’Amì##>^A]ö‘®‰·’¸?kE‹Sé÷Ÿ]l¯iYK†<ÍÆãŒâÅS&Äuš9äÀuK®q'¢“Ö{O®´Ö|OTY®Û-.áu-E[Së‘8œ-\2µg<|¡(^}Žtm#ѽtôiÕÔ¶TЛP•ÄŠäŒvµ9êÚ;s¥Ãymoº$Å«¶Ûp(›JZm“6$c NXAèw€±Ø=ëvͶðo-6œ-Ñ»gXÜ[NLyˆ«(_§êÒµ)<‰ãÍ¢3û‰÷vÖêKåVë³—-)}˸™£ªRÜxä~¨äzõöÐ,î—·¤ y÷í=îb1j¾–½%ÆñŒ©ì¼µ$Œ'ðÆt>txÍ|F­q˜.ÇS•ÊŠÛJ:ñ"a# „äú“êq>=¸šÛÖ‡·³-WÏË‹(¿™*è©n´J²ô}p4™iemg¿ë\¾zµ6i­ž\‰‚[è„:¢q$¯¾‚Ž8z÷¤ÖÃó:DÜ`ŠË/ 敧ÛTþhir§gþƒ#ù¥jÖ^º{ÇÌr…Iå¶×þºçþµÔiÐë\Çá(ÎÛsðš¿ü ë©Ò§Ê5§ÄjÓ¿Ò–>Üox¶“$íèÔÕ0í§®Ñ~ IlxÍ8D9$å ¡ô S›å—áQØUB§Lô­o<Å’S-ä@$%a*ÇI^½ ½ôÉ`ÛjÜ›Y+˜ˆ@ØÈüúÑÌ'ÿGËýrp=®¨B·Û÷?7u ›'+’"ÁœòS’£ÇÉÃæ[JÎq÷øçwk$/& ¤ÞЯKLK¼¼‹7¸î2Ì¡)ÀÂIuÌû£ß¯]w }¿º¬dx~ó-É!G)<œí_€Àú`âö¾×Þ‘ ®+Pmä2[p39˜«Ž’¦]óžH'÷é…–¶+Ñ&¦Æûn[ÈaaÆ#;¸ŠYlŒñQdqÈï´džûÐ-¨×[ÎU}þÒÝ{vT¨®<—gÊÜy¸)ç €VFsØìjŒÛ á%rwå$蘡Ë6J py’úÚRõ#8Õß¶dT¸üjˆ.Bª›)d™ó]2®$)—ßàÚÆ3–Ô¬¡ÕöÎmF¬S_2¥¼E%?&ddByc$)l#Ì}ABÓìHV‚½×­‘¶¥Ì»·ˆÌ²~XªÕˆ-†ùgi%!H=ñ]O²,æµY;{+pX†:RäY:ʲœ`4KJñ}=–žZð²‚Vîø.dyÙu¨©yß•’'©Á÷pûkq´ô0C‰ÀÇÂîô´Ü{}äÕØ|’¦qLvso)Ô…€é/ÔýÓ µ‚ö–Žî;;]†cøAQ„Û'çBx{òK ŒI!>˜ä}Ó¡üd®áTÓÓQ›„%ÆàÊÒp’Я“†–[B¯-÷׎mQõû*Rt%í‹§ÜŸ*¿müåáe…h¿™lòW%c´©åæôÀ#—|F€ÍrËð¨ì*¡S¦zV‹7žbÉ)–ò °•c¤/^…^úèQ¥97uX&t4Q¿á3äÂ`)öÔÚ”)+*9ʃÈ{Ž9Ò”+}¿qsówPÙ²r¹",Ï%1Ù*<|œ>e´¬çŽq÷qÖƒi7´+ÒÓï/"Íî;Œ³èJB0†°’]s>À(÷ë×GÃoÁŤî«™†üËd2HQÊO';Wà0>£X8½¯µ÷¤H+ŠÔy –Ü Îf*ã‚$©—d|Àg’ ýúae­ŠôI©±¾Û–òXqˆÎ[#ÚÜm= âp1Çð»½-7ßy5v$©œS‡\ÛÊu!DàåTIÆ09òüIïAjm9’Ý„éGr¾33j¯ <Šrž”㈠õÉ€r=F„REzþ;ó¦Øü½{è/Ã{î½Ë_Qa¸#&Zc|â#ʤ†ÔWÁþ-([osÎFBR”“Žó Ó¶—¹¶ýÍ•}•­9¨aÄ+®9Jqjôk›ªXA#>^$w«Ö{Êž=«ð[¢¢bZÀmúªÖÛ–f«˜ûîžAûÄå¿bAÏ£ÖÎø„ãsí,ªö*ÏŒ·Zë¤<3Ò‘”¿ž¾ú21éªÛ¢-•¥šk+nvÜyQà·"D§(Ž’{æòêOÏ®Fƒ˜oÉ»¾d×½Pì*8ËrS /4ÄS”òJÒHž‡Ý3í dÔ¢ÆFâÚl²ì¤š×Ѷàà ‹ÄöT¤ óïÔg]?W7m·›Š·]´qÐDØÏÕÆa'ˆRW€òœôA#=¤íûtÕ£"[ú]oBî 5`…«æJðTUóQ²qú*G,ýt6”WîG°•¸§ºaƦ1aòÒ•µd„!ÀÂ==9N?Hè%‹T´È;nîÉv—m!Æœj½Ä²ÁIsóe–Ã4ô*A=žñÞMí©˜Ú褸zÆÞ+í7!—äD™ QíöÖ”=8©(Û[·+N@Üž]\™‚Ä4¦i 0‡†FSãññ?rðG®tè÷è~¢C4Õä„ü¶_¹iN¤ $4¯ © ƒÙ9ÁìhµÍS¬gMÜf&cÖK´~2˜.-JB’@H¼¬ýuY[eÅ9=ìß‹‰ ÌHqâ©%I ¡.œ1õZHõ#νŒæü—ò;~%mdʨ-×`ØØ²ãócãʧC ´ž‚£ßGðKºËjûÊw·EUå{ SÌOCj¶RIB<VZB1Ö@âpN4ȃw[I\"ßÓRð‘–âÀmèmÈ È#œwÏ—ß’‚FGªF«ï-½¶Y®r‰n”ùAQرšè‰*óÐp…L`$§³×¸ÊÓsÞG‘ ’*¹+mÊèÒ\wÀx rpÉ‘Žº(AÏ^„è<±Ù;‰èîϹÝÛjM²$…T‡¤­Ò…©G!JyÕ”’“ÐH'Ì|ÞšÛö‡äöõTw’©68o”¨.0ú¿Óe¥:¥†GE@Ãê6L{µmh·*²ÛЬQ%Öeʃ,¥¦²J㈒ߛ¼ òÉè•u«È´Ý•1^MÄdM¶a z2‰3€•¶©ÉBÈÎTPƒõ9=è-[‚Àneo·7-Z@R«äKã,/9--(WçêIâP=0rC2hbRÕW"êY-q—©í²…Î%kZ“ëÖ@Ü gÇs¾é´©°“Uå«ÅcNµ©ò”’qãx¬²Ñ$„”) ÷饑9ÚJÍÍ.ÎU–Ǧت°º¿¥¸ÜR–ˆÙ–ãî„åM-Z¤¦Qr$GI[®+:‡¢—x=)X$úê|gݱ߻[¸÷" 3ã4Z‘$'8æµ/ÆFN<ØAú [Ý_ö|Y覤®…¸äüZz 5Éu”„§ÍÓkR’¯PsøØ.*¢…uÏm·TV’Ü'Ùqåž*9¸Œ%žÒ‚® `:×4Ü®Áo«‹·¬c‚%„×;,6÷^Oš.¡À»<‘øé®uý¼9\6ÆäXôd¡—‘ó5¨âÞJƒA¢´õÄöVžA_Mcr6ÝkVûž¦Æ9R£.;s"4áñè1ø’:üƒìÖ¶Df('Ö²…¼óAÒìwæ´Ç,iK©áæ ‚áú^¼‰sóö‰ùÕËm ³&\˜qG\¹**Èë‰ Èš)º÷k5³£Ç¯ÜäÄ‹Ǥ®$f¬%†+T—RèõÁÃØýÚr¤Û›Ž×dUÈÛ26ÕôkS"qŸXÐR•ƒÄ:†ÞðH=„䌎€4­ÄÌJgW¹¡lë‡QÄI|Ø´Q Ÿº–º9VAs°}Gz¸·„é.ÖËoÔ³6CIe·-‘ ºãgʘ¥$ §2G¦[«¹Û-Ý«p¥‡â…@¥ aÓè— ð9ùr29/ ž“ƒšt{nÅçɶº€"Im‹MC!¬~ždEIúzŸm)¥±ÝV±V©P^7ɘؓý±PT)ä’¦Fr¯P;Éë½t·w$ëFàį¶ÙñIu.½ 0cxèWHBÙKng×€ÿKL6›²ßoÃm몘ò×[ü»˜Óe.¼¶ØŽ¦’žÂ³Œôq¤M²Úáî—œ¨ßí^WBJåBbœGPNT¾µ r ¬dòá¶VÚ] mâ¢ÛRK£ii-7 KlHrAíh 9Ç <‰©^žº«}¸,'m(ìQnéû4!ïÌá°•ž€a-µ…(úåK$wœ]yí_:k0§¶üjõð•^‡\[Èl/!e"o&”¡œ©#¾µ~Må„É?cE¯”Û.ˆ­­æÓϲ§žbcŽxc'9ÈÏE= ˜Î»Oº—e:w-ÀÛ )™ÂK«’ñ8 ­×B\o®‚T¤úàõsåç;[¸Ÿ­ÙéyÇ^?(W2$¥Xljɵø¤)@ô@ú«4³·\‹¨tö–ñì¾e—Èuu,Cm°œÿ¯ ´2R¤öTGdižåŽßÛvÑ¡_Õ8¨Á¾r>Õ3ç•(Êp6×@àrõ4 õ=·.j*÷:"Ø]Að–•)ŽjŠ’:W‚—0B}r”¡CØÐMÁ["/ÅÆ§¦ L­š¦$C Èp;¸¡Ä“úiéDœ“õÑo‡ÛÛb×GÜW74Rúœ@°ŠËE”ôJøGÊ•{¯.ÀÐG7\Û¿)¥WmõÓDnšhi(¦[s.Äí (JV:ýàœhY§ó:FÝ)Å5™ÿ ÈþiZ²FÒ&?ô7ÿšV­eë§¼|ÁW)ø@ž[iïõ×?ð7®©N0¹wÁ±´÷úòÿð7®­Pž†´øíZwúRÇÛ†ÀnvÊ\ShI²xsqM„¶~B^ ñ”uëÙžþš¾ÌÚušmá>ÖtY ©¡jœCexæ<œÁ9´Œttnãì¤îm£öÐqP>×sÅ òä€ÊâòUŒc[­Ûª²r¿kÓîPp—XkðZ;R—ü²D•¯¿\ë$/'m•håVÛbMݼgë#º´¼äªçļ’r0œq8æP F¹Æãb}¥•NÑÜVZ°p­tñ.™RA9v:‰ÆAú jå¾à±‰p¨´;u0ôÄ%‚ôË/2Ñ y’Ë„?ëƒømÛõ_‡souSQo`ƒ~樴§sÅÄ8ú\$Œ%´¤zO¦€‚çr3Ûõ[v RP•¹7“l;ïâ º„qòö‚3ú¸Çi×Íø¶n<öê­Üpå3…®¦4æÙŒçë­1Ôœ#ßÌyzŽXï^ß}­q×"ìÝ‘9HZD¤€ÛÙtÜYAd¥=c²æ=Áë [r½TqãÛÖíú¦#ÆS4"² Ÿ ¯ÇgÊè\mºj¦mànJ»JðÚRË¥Ô`ùŒ§ÁO#Ð.óÀúêªcÒï 'WÑË·[øˆjý÷ˆQ 8K‰ >½€xë †÷œµ¥²vÍå+¸ˆ­Ø¡•©-¨ ¸Ñ¦”1Ÿ7Cӽܴ?i"•´"T·"kb<Èó–Ùe8>AÉ×Bz@#××AR­Å9ÛW·$È[q´GiÇ™S¤¾P„€§Vë^§<}3«ÛGy•qW6 ìyĶۦѥ—“åÊZJ@ècY=Œ÷­[omWÏ•`ý—¸mÕ MÏ….S„Hl¨µäÀ$œzƒ¬>î7Ñ“¶êëã±=©o­ßɶğ v]R‰O·a@ž¼ è- ½ôæìvCr$¨-±òÂkÒE-ñôi){#¼‚µgçÓC.ª7äïéÎ;òÍ/ÅzK-–TRàq—Ùuå%^c޵M¨× jTz V…jË,ÚÍJÓ++q.e)ÈϪBý½3œl&î –«öÓ±`Ñ8Ô~OL© Jpú‚ˆÎ´Iœýs ³z×Ä ¨òçV·â$‚ÛBz”?ZRÕÉ ¥Æšvžâ±T†j©äm¸à°—ì˱R„þª¼'Uß.üÿlèeC4ök쨦Cl8Ó»kÀB]ý%æJ‰áJõÕT¾õlyUM¿²:cJ[%ÁHA?}L¥à—sçO pø»}`vÉMmÄ–'¥/¿·Xl©]á.<•µ…{I>Ç\Õ»©o°ûíÞîR%6U^Z†‡ B@)qB.Nqî =uÙÊK'pí¸WrãJn¥—üÒ+…ÈuÔäxJZdùFyóÏë3lÐôéX¯²FÞ.ønºóÖtY ©¡jœCexæ<œÁ9´ŒttéOoJë¡¢ÂÎæ‘sÜU„™lIS 6 †ÛsÂo¶8…Ÿ§®†Z?·Udå~×§Ü2¡:á.°×á:´v¥/ø7d‰+_~¹Ò¶Ê´r«m±&îÞ3õ‘ÝZ^rUsâ^I9N8œs(P#\ãq±>ÎÒʧhî+ -X8Vºx—L© œ‚„;D‚c ý5rßpXĸTZ¿º˜zbÁzeŒ—™h<ÉeÆÂHõÁüF¶íú‰/ù·º©¨·°aA„?sTZS9ââ}.ÆÚR=H'Ó@As¹F™íú­»)(Jܛɶ÷ñ]B8ù{Aý\c´ëæü[7{uVî8r™Â×SslÆsõÖ˜êNïæ<½G,w¯o¾Ö¸Œë‘vnÈœ¤-"R@mìºn, ²Rž±Ùsàõ†­¹^ª ¸ñíëvýSã)¿šYŠÐO†‡×Èc³å?Èt®6Ý5 S6ð7%]‚¥xm) eÒê0|ÇÆSà§‘èyà}uU1éw„‰«èåÛ­€|D5~ûŒÄ(džœ%Ä…^À ™Õí£¼ƒÊ¸«›v ¼â[mÓhÒË‹Iòå-% t1€¬žÆ{Ö­·¶«çʰ~ËÀÜ6ꄦç—)€Â$6TZò` ’N=AÖ ÷‡hÉÛuuñØžÔ·ÖïäÛbO†‚;.©ħ۰ O^Pt…Þúsv;!¹TØùa5颖øú4”½‘ÞAZ³‚sƒé¡—Uòw‚ôçùf—â½ %–Ë*)p8Ë쇺ò’¯1ÇZ¦Ôk…5*=„« µe–mf¥iŠ•ƒ•¸—2”ägÕ!~Þ™Î6wKUûiذhœj?'¦T„¥¸}ADgZ $Œ‚N~¹ÐY½kâTys«[‰qaAm¡ ½J­)jä… ƒÒ‡cM;OqXªC5Tò6Ü pXKöeØ© BU^‰*ï—~aß¶t2¡š{ µöT ÀÓ!¶ œiݵà!.þ’Ès%Dp¥zêª_z¶<ª‹¦ß‰Y1¥-ˆ’ठŸ¾¦RðKƒ9ó§ˆÐ8|]¾°;d¦¶âK‚җ߂۬6T®ð—JÚ½$Ÿc®jÝÔ·Ø}öïw)›*¯-CCÎ…¡ ¸¡'8÷Pºìå%“¸vÜ+¹q¥7RËþiŠBä:êr<@¥-2|£<ùçõŽ™¶hztƒ,WÙ#o|7]yž3šÀômåKä;ì„¥IV}2q h…ñ%JÖ÷[+ 7ã†&ºÃ©qÖr;QCÃFsèx¨]VÛŒm˜Û•h·aqm¿ —“#ÃW, :¥¼¡œzðH˜×@Eí’*XkbÎ7n /ù‘%:Ûm¤vØXldö<¼ÈÐí㹜³²‰[i*¾3ˆM;«ŒHNpàJüUô‘ŽýFö¯áÅ[°"³¦§:ã’¥»óJÊH!+!9ú¨þ‰Õ jÔIÞ°ªvÆêùRÝV[— üËC—•*ZT•d_8Ϧ“7‰»GjÖLŸ Øì)ÑáÃ@møÜ\éD²Êcž^˜NIüs­1áÜ1rüŠíÁaYvëi\u≮ȓG§‚†ODXN?~Žþ;Õ»r²¥ç,"JK¡3+Ö$8÷,+‚^p«Üž$zûi¦–b™†ˆÏN¸a—¼²¬ãÅBÝ=‡ŽiN•NN:ÓžåÙ³'µÛ{ä¹(!Jm†(äÏLrFÉq䔃êB#ô†–÷NÞq´k$Ø}¬¨°¦ˆ¯:Ýj"—ú üêm¬‚Ñöë­]óñ[´|l¹Xâ`òLÄ»0Äô[ñ’â€ë*Zҽ˵à׿·6¾è¡ƒ2rаÝ=D×YQÇ™n]úuŒgöècí¢¶ŸÇzDÊ™¦¹¸Þ{–e™LyT/5ƒ×¾ÁѺZý®Ýõ–è,(&C¢æ;ÁœŸ N…:ôût unlÓo.¶Jl¬Yd—$© –#HP#‘txåC9ÀZŠ»ÈëD÷ Õ1¦"^ÐeÕ%pVôô½Å¥1„ùKj$¢Rž±•j´»-¿ ºÔíýÅU{n¾ìUVY3ø­‚V\¥À{=qÿª}uUº¶¾ºÀ ý¿yáÊÆîŽ—CÂ*KnDzN<«m¤áõzv¬þ–zÖvû‹æÊ/á;"Á•†ä;]Ya¥/—•#‘@Î3’¯¯ïÖI¹º•_ݽ*š %ØyQšR]ååmƼvJFN0¯.˜v%ÕœyÞ4Ë‹‹š÷R¤Ë[qÙz#~SËlã‰ÀÂ^X?èè5Ý3¹çI•·öí.á ­C ĸ͠üëøO‘EÔ¸ƒÈö…ûw VÑ>&VH…fŠ©†ŠA‹$ɉã˜êûèBYCk!$“ê¢rur¿t|TnÉ¥ÆU*‚VvÁpU—˜Ïñ|µ(¨cÐç$c­-nmǹ7•×7U3ÑOH’‡+¯ ¤ñвH#¬ ž¼Àœè^Û&tµ"žò%MS%µ»U_!o­$ùJÂßcÔúõÖ™«.6ÔuËM÷¼Üã/.Ä•WŠé )RTo‰G¸ìúŽÎ©6‡WlËOÉÕÙʬ˜œ|ÀÂYJ •žúñ‰÷'YYl¹{ª%¾Õ£·N䊜°L†™h¸¡çqm$,­9$„dd{Œèö­âhìl!¸ìZhÉK0ªlà/C‹éyKa|ìžGý"1¢×? ~Öv}”YÊ—. ÚPyQÔðÉäÚáâpHÇ.8×Ó\¾Bw45E‰.d*¿ÌJ™±·*ŸxœO¬¬,dgŠ‘ßᮊm*w&àD•U—ÉÇ˲fK¸Ïktµ•ö1å8ü40,6e*—sS®ñ–œS5r•kv:‚x+¤»’Ø'J;#×B7Enàcg&¿qÏ•5×^Zâ­Æ ~ic l0‡BSœùÜ?€#]·pmšëÙ°•¶¶þÖŠÔp–¤>Äe)ô¸H ¤2µ +'9V¦©‹-šåŠlhÙÏ8ËëaqæN‚Ó‰Y¬‚Ñ O·c¼ûhgØmŸˆ†¾W‡6žU ‡ÃL”Ê-­)¾+iJWYód}AјêØ{¼Ç—p!Ú¦Táy/Øä”©]v@ʉü=‚LíǺ•WoñšÓä8ˆÎŠ)<Ó Ïñ…eoÐz€;ëBö¦Ïv®tQÒ²¥"7Ì†Ó ‘ÙÛS‘–Hü³ÿ[@í;9í¹igÒªºZ"HA§Š’‚£”xn¨“ì2ÇèQÛtöÍ [׬]µ…ò®)ŠÕ<†Ó'Ý[*Q8'%³ê5Ï×9Û‘qTʧð«wøJÕ_!պǩ.¼ÛªCÐϧZkÛU{ŽkJŽÆñS”l´Ÿ“zJ¥;!†±Ÿ—)ñQõ>nýÈÆVú;³-áIu}B¦"ƒá¶Ë!^ªCËu)#$e)}ÆìhW•µöÎAÙõ×õéiÄÉ—:ŇߒèÆTÏ) ¤ä×]äçUêvëtw±Ä©“˜¢Áe­°ãKQ$/Åq²ž”)KΘûÛ›V5UÝìo”Ÿ-jñãÙ—ìbÀðÑ× ¬ÇX`Ÿ^ô 0§|;bŸogRHe!ß [bKÍ,/<¨ï©+Ƕ Iнó¸)o ÷ÍÅ*Út& ÔÎbB•å8Ò)#>ÚºÂ+å^ø’%î –+Zh´ìoà„€=Ú}ÀGÔ ãÔÜ)Øñ÷9Î\íˆÓZœyé,c‹ ¡IËjI=Ž“û•ªŸízýsÆ|{6ß~?Ž©.4ã«s P¸ªJPyp'#°46›q]WNK!¬A2¸Ç¥ï"[2AkPƒŸªÆª×_ü£eWn6Ñ …8ä(Ïn˜æ;EyJ”ˆÄñÿAJ¡×]Û;¶¢UŠbÔªî\2Ñ,xÁ* âU=FÌ µ‚Ü"ÛrùY8‡ÙVÏ©÷Æ—ökiþÛ²%4ã¡ê¹?Ÿq+ Y°HÉ #8JG^ƒ].Óql) ±c#n¡Ì!†PÊbFùU¨ ©l¤ò®ñ~éz+°Îõ¦‡ ¶–£UØ ;K%‡[pøñ;!´$§ëæ*ÎN=ô,‡æ´‹¼S¿jè/ÿàVŸ¬Sù­#o4ão[¨½üÚµk/]=ãæ ¹Isà°ÎÙýyø×W©OC\«àŠs¶¤ÿ®«ÿ5ÖªSŒu­>#ûU÷ús°öàD‡*NÙfs‘Œ-Ôã‹”€¶’Jò¤• (y}9 úwèm3³*®eMºvºÕ4Øù…Ñ8§›Œ‚”ABFBp}ΫüD“aý²ýRbüên‚$¥Õ6TaÉ!¯9õëøö΋GÙ{»ìGä³¶#ÁšãJ*~¾æ|~džE\ÀO.Yégúë$:KváNÞ~©›§CôÌV²RŠÉT( i@q›ÉÀ*9ñy®•6H‡2$™Ð!½iFä‚ÛÒ¢ùÄz †Ü-9ÁÁÈÛLÕû±ŸÏ=¿m#5!¿ %é]SyH JÒ^p§ÊÙWg:ÛP˜ïBz¾éÆäMe¥|–\a²x«ÃZ(ñï’AƃÔnè"ÂÊ&ϯ١40ü¨JŽü¶Çè”!‡pØï³ÇÛ¡®~Êw„é'mmH•v¼—ׇÚ.4¤’án:y ¼HO·«ö°£lÝëGy»²ÈÉ]k–¨ížË' R“‘×&ÕôÓ7 s-C{ík6a8’¥3bôfÞu”+ȯ,‡;öZ†ƒáîêý¿Z—«Ì}·ÄÆaÖ¶[*$ññP‚‚¼Œ ¨g¿®‘/bJ©–ŠT¡`ôæ¼d×VˆËtú¨-–Zpp?9ß¾4ýv½+tÕÚVÛ[3Püâc©3šyG¢—R·¼z“ôÑçêàíù³kÔꔕüä$Emø¡Üžia—9$×.G#´ç½…=y§Kÿl5½ÔÌI(˜‰¡N×F õà©-${ûêϦ˜þ.mž(uB©+}ÆÕ:Ëô‚¤#ˆRy‡ ›#ЀÓZEcE-­Ï 6vmÅuE”9^†‹!gÌBC(JÎ{+ð¹wê:ÕméaVóIEµ”m¿7q-Hu2ëÐÙSHô.-°´~»@Od_·µ VrŠ,Ýqjf5{ñ¥K9óãJÁôIÇ××Vg±²öÄkY¶ÌÞK’ÙÒ2žm$yÖ‘âri#¿Ó×J»_lD¡oyµ¾É´šòCnƒk-@²“æ(KkuŤžð¢“ߦµn:úy[q«7Ü``)|!¼ûeŞʤx=ù¿á #mk6mSj^Úµ>7†òª®¤'ÙçŠÐ¢¥’®’Hã×#ÙëB`îÁdԅѼ†íÐꙜ¸öÚ›ó\ÛeJNuޱ¦ý§¸ì®b™1è'–˜‚PÜ-mù°W(#Ôg)ôÕk[€ä'åJspF¯lã­þtñÿåyÎ#ý/.qæÎƒÏ…ŒØMÛHÝ‘­CÒ¦8© [®©Jh+\â[_XÀ%]k)ÔT’"vÜcX†òÞÅ\G¥§%%+[ÁmzuíÞ=ëJÜ꯲¾×žÓÑ’äuKL?”ð¢PO$öâyuÖ5r¢Ãd²÷ËTn¥ÅrB@–bU•GeXq ×Ð_m¶Æ§s®—[ŽĽòr"°ømH²ò“ ž8+ïÓ¼àÑgfU\Ê›tíuªi±ó ¢qO7:9(‚„Œ „àû݈®¦qÅíÛ8WWªaµ¦KŒ-Æ’JÀJW‚·Qåè%¥ œrg5£ì½Ýö#òYÛàÍq¥?_s>?2O"® `'—,ô³Žýt· vóõLÝ:¦bµ’”VJ¡@[Jˆ<ÞNPÏ‹Èýt©²D9‘$Î ëJ7$ÞõÎ#Ðd6àqiÎ@>Ø:`¦¯ÝŒþyíûi© øa/L‚ê›Ê@RV’ó…8ÀVÊ»9ÖÚ„ÇzÕ÷N7"k-+æ²ãu£Å^ÐÐ!G|’4£wAPé6}~Ì… ¡‡åBTwå¶?D¡ ;†Ç}ž>Ý söS¼ ïI;kj@¬«°u侸Ðä>Ñq¥$· qÓÈ`ýâB}¸_µ…fïX ;ÍØµ–@&JëXŒµGlöY8R”œŽ¹6¯¦˜Ñ¸k™jßkY³ Ä•)›£6ó¬¡^Ex©d8±ß²Ô47wWíúÔ½^c&3µ²ÙQ'Š„ä``¥C=ýt‰{UL´P𥠧5ã&º´F[§ÕAl´‚Ó€ùÎýñ§ëµìé[¦®Ò¶ÚÙ˜²‡çIœÓÊ=º•¸…ãÐà$Ÿ¦?WoÍ›^§T줯ç!"+oÅä óK ¹É ¹r9§=è)ëÍ:_ûa­î¦bIDÄM vº1¯Ii ßßV}4ÇñslñD ªI[î6©Ö\ï¤!B“Ì8TÙ>„~šÐº+)mnxi³³n+ª,¡Êô4Y >bBVsÙ_…Ë¿QÖ«oK ·šJ-¬£mù»‰jC©—^†ÊšG¡qm€µ ãðpuØ{"ý»ý­³”Qfë‹S1«ß*YÈǘ‡PÆ¢N>¾º³=—¶#ZͶfò\–ÈpFñ”ói#δ“Iþ˜¸UÚûb% {Í­öM¤×’tYj”Ÿ1B[[®-$÷…œý5«q×ÓÊÛY¾ä Ká íçÛ.,öP• óÁïÍÿ kY³hÚ›RöÕ©ñ¼7•Uu!>ÈçW\óoNI8útÍ_p^Ã÷}˜òZCKŒÌ¥„°GÝâà %$ñƒ@ö4n×¼¹˜Õ'ÅfÕ8ãíªÁ ð[R‰¥6b”«¿§¦®Zm;ªÍ°ÙÚÒë^qOr&FRr…x_šâ=‚ÏíÐm“²eB“1¶ë(uêTTº ¤öã‘À èñÁVu^ÞŠŸsLmsjå;/ -æ.Vs’§P¤ñÇxN?qխϲå[ÞRHÜ—›~‰Róå*VO:è0Ý/Ä ‰E bBR$,œµ&0cŒ´çùÊóøã­nÝ `šªÁ¶åWZ:Ÿ›—u3m7M…+›ƒÏÉ>\c$y´ŸÆ‹ì÷þ$U¾—>GëaÆmjXícóJR†3ŽIOíÐW…¼«é#MSlˆ;N‹"¶n>Ûs='rÒ¿§ç½(Ôî颳íµ<µ3ãÛÎj¡‚‡„rVHï–r¦;×OƒGµŸ{ìûj¸³âÆâÑ[ôþÇ’Ú õì ~$è¢dí`ìZt×n*•©oølCXaÕ¤‘–]V}qáàç¼ô ¿ vläî Û?³¥À”¶¤0ê’C Ry'Žßc'ŠGüNM©¶m„Z%Ê»IQT…I„­º§Ü’•¯À£Þ=P’psŒh%+ˆ¸‘¸ªÖ©mO•(PH>eÆWè8¬ŒÜV¬âD©tMB^–Y”ûP[Ó ’ ¶¡5“ë6YÈÐÚÛ"³pÜ®]L6üU». ¶ÃΠR¥aH@t¼©G¡Žõºs ËªPi¸t‘[Tx±]²rcM:‚|É!8 8#¿GÂØ›¦—í7)îçÏäÔRÔO*£æNÙi*Èõ%@lœ¾±vµ{ˆsr¦¦•|º¼5-Õc€ðÜ’GÔ¨àw ÓµÜºK޵C[WJJþzÂTw¡¾ó¼óËÆÖF}ò3×XÆŽÜíŽ]ÂÛuî[ %+-º•·‘èµ>y:îR '±îiÔlX5¸»¢²æ*?…CiÖ›Ùug!-„¶BSœ€ûµ¾oïIVU²Íe…sÁ*L¹TÜãüpTP„¤= ˆÏCë Ô+aíôKŒÝAl¿Š[5Õ¸ò“…•¹œ¬}SŸ¦†AØ4Q%2¦n¯v̤CSŽª;늩ó´]0sÖ@ýšö§`Ó °µþ[méörd8ØJ§-ˆjHZKEûá‚=uE¤µJºØ_gí;XF:á¼–e-×ÔFSÉ+-¥´ûy–@8ÎsŒ€ZkĽñ¸ø‰ =t^kçœ`½/ÃVCo%› 88Y_"×\›¸,­Ø‹öBiª³B¤Çù—þQ „ã’T ËŠ p}:9æñ#Ô×X=Éu3+šW6nU%.:Ce ÈR9Ÿ¼8œ÷ôÓC-Ä´ÖŸl999qS[ft‡üù(•òá]©²¢S‚B~螈õëêá½5ÂĘq¢Äø®ºÓížJâ–ÝW‹‘Ø%`û}t&оï˯¥“b‹(éJPô—c*‹ÊJá Y$äç)=ãW(¾3K´Ø«VÜ¢Û[}Úùi?&€§½§€¥áþqÖ²¢z<³\«:d ¹»™g:}žÕª›FÜd¼êcCC‹ç ¥JQ#‘ÀÆx¨~=h(íÊŠÚK0úv˶¤ (°ˆ {‚¾öS,Ÿ c×8Yï¢4Öɸ–'qMÛ;f®Ö\Ÿ—¬žy·šx*x®;~!ϺŠozFŠôˆ»‚²òFÐ2¤ªS•“«ãIq²Á.‚âPƒ‚qËßEj¤®ÆVàƒx¶Ôcr[Cƒ‘”´¡¤-)$~Š¿yÐ(îÍóËzšÙ’ä*ú\,¾Ö_ʳ!ÂrBµ8¼uœäÿ&ª×¦ÓxÍ‹ý«i $e)€ë22ÛM¸4á V;û¨Pœu*úý—VQ9¢Uh£Ì¹]ƒ­”§ï¢Ù‘ƒÅJÏ¿âxC«Ü0¥ÁNè²²uåÊ”ÚñÖJ \£ˆë ?‡®€>Þ°®ÙÔqU"<8,Gq²ÓÐVúPP¼øH>ì«ÔŸ®–ß…6³âEuLÆa­,VO,ÍT˜)’…9„§ ã^J>nÀ÷¸óé­f¾tÍÅ";•")S.<Ó>¹ ®—Þ3އYÉÒ¦ÐS2¾#·iö¤™2dWÏC‘߆XSHKÑ8(þm°¢®GÑ a#ß:ká½#otÿêÝ¿ú“ÿø§ë–ý4¾Sÿ«6ÿê/ÿ6­ZË×Oxù‚®RYøœí™?ëÊÿÀuÚ¦ò¹?ÀdçlJÿ_WþõØ*“ÐÖŸýªûý)aíÁ_⥉£jÛøb“è)I‰/º¤ü¬œ¥(Pâr2;ö$éÒ‡w~PÈfëÓ¸0‘U vŒÄaâ¼òæƒR°Sø«@·ªT,¶Ç6•ý¦÷9 r‚Uö|¼ ²¢=GÛC­¯nc¢Â#”­ÞN˜ËNO‹,¡eå¤tÂÂXè(ƒËžXÖH^Dí!m—f‰´õvWR&I1ÛÚ°<Þ(Ò¤”ò†OᑤøNXÝn»(’·5ÊoCËOÎAl<¤©@ëÓ$Û£»|.Ù¦QSPºfÃÙ‰†'Ã)sô¸ñO”‘æÏá¦g3"ùP«/-TÊO‡)´Ë—1Ö=Й-¨gõ”1øhPlÚ!91äîùRíf5猩&GÊ„‚T—·V®>ÙH)ü4.꾚z«Qó4S V(üÌYó«ÝŒÊytz¥ ýä•'ñ#Ek©7mÔ¥9"CHŽÑSqcˆŽ!ÇBˆ[eXôZÁ œœèÄ ½·k,˜/ÐA¯~JÌvcÆ¥‹2C®!$-n;ù¿)Ï¢süh6BÛ»–qU lä Fo!ç2Ò²AO‚CiìBTN éŠò«sȦb޾ßoŹmŽoNK©U¯Ë'Ì”$8„::ëÍŒgÐiJ¾5þè¡ ÚUhDŠæ XÁµ2Ë*lKB’T¶ÕÒ•’QïÐgOnÌÛÔiçméAùIQvKSZJµ‡òí%nz’ûN7pÈz¿æ2¶ýT?f¯Æ²“8©ÅÉ¥†ZñR:äê}¨íH)ß²¡ØBÜ"jÛ€†£ªe’x4„œq)•þ$r¨í¦OŠ!p×>mÔÉ*®e.-¹/ h(ÉE÷Äú$òå’~èÕw©v̉®®MB%4߆ºêV×5 ¥ÖÐÆ8(Ž”¬\wì˜Ø[™\‹D÷@p½:’Ø!yüÚT†Üh`ŸO(HÝVÅÆß¼­­²Ù4'ÈS’&õºÚÔI !%• äºV gKÊø_J§:Õ~¥LfÝ–Ëžâ°¢„ °YNx¤¬zuŸ\²RîûÇÒ‹»Ù5–qZN*L_RÉÈJpI䟨 ô'@+pïJ†&±[Mj&<…½âÀ–%:#ÆBž !ÓôÙýRtÕMjÅ…X¯—54mµùǵ×>Ú°y<ì’àA'¬£=÷ ›Ñ•Z^/mÙXZV?aÅç#¡˜ëD¯eD¤PAúäèKÉ«Úûrá‡#Ñ8ä )ù¦«ëš[Iy )ñ°zRŠ“Ÿ@4.˜fD”A¡vc±\mb†&?)Oû-EÄ>rsåâ£ë¤›+ í§·¤í9uû‚R”¸äë_¸î¸—ÂŒâ@ïÑC'E«·•Æî¥DªKÆ—Ôº ÐJ«öìÍË&êâÒmJÛvWÙŽF}¥%n!<|âòp¾%b3¶%µ`y¼P#¥I)ä9 ŸÃ#I𜱺ÝvQ%nk”Þ<‡— Ÿœ‚Ø yIRצH·Gvø]³L¢¦¡t͇³ O†Rçép!âŸ(#ÍŸÃLÎfEò¡V^Z©”ŸSi—.b#¬z¡2[PÏë(cðРٴBrcÉÝò¥ÚÌkÏRL• ©.!n­\}²Søh]Õ}4õV£æh§@¬Qù˜³çW»”òèô JAûÉ*OâFŠ×RnÛ©JrD†‘¢¦âÇCŽ…09:¶Ê±èµ‚A99Ðÿˆ{nÖY0_ ƒ^ü•˜ìÇKd‡\BHZÜwó~SŸDçù:Ðl…·w, â«:Ø0%É@ŒþÞCÎe¥d‚Ÿ:†ÓØ$„¨œþÓåVç‘LÅ}¾ß‹rÛÞœ—R«_–O™(HqtuכϠҕ|kýÑB´ªÐ‰Ì±ƒje–TØ<–…$©m«¥+$£ß Ξ6&Ý™·¨ ÓÎÛÒƒò’¢ì–¦´•!k åÚJÜ8õ$#önáõÌ"emú¨~Í_e&qS‹’K µâ¤uÈ6ÔúQÚS¿eC°…¸DÕ· GTË$ði 8âS*0+üHäQÛLŸBá®|*Û©’U\Ê\[r^ÐQ’‹î+‰ôIåË$ýѪïRí™!]\š„Ji¿ u!Ô­®jK­¡ŒpQ)X¸ïØ/1°·2, ¹,‰î€ázu%°Bóù´© ¸ÐÁ>žP25º­‹¿y[[e³hO§$L5ëuµ¨’@BK*Ét¬Η•ð¾•N*t=ªýJ"˜Í»-–=ÅaE A`8²œñIXôë>¹d¥Ýö5¥w²k,â´œT˜¾2¥“”à:“É?P1èN€VáÞ• Mb¶šÔLy {Å,Jt GŒ…<C§é‡3ú¤éªšÕ‹ ±^/.jhÛkóŽ-k®}µ`ò*yÙ%À‚OYFz9ïA7£*´¼^Û²°´¬~ËÎGC1Ö‰…^Ê:‰H> ƒõÉЗ“WµöåÃG¢qÈSóMW×4¶’ò@(!:Sã`ô¥'>€h]0̉(ƒBìÇb¸ÚÄ) L~RŸöZ‹ˆ|ä$çËÅG×I6VÛOoIÚrë÷¥!)qÉÖ¾3qÝp/…Äߢ†N‹Wo+ÝJ‰T—;!/¨x숀0²3œˆç >ø9É:߸#n·_JŸ*Öh’Ü•×ÃŽ—›–ß eNˆœ”¼€NSÖ}tí¦wUl–e[O¶‡ùIþPv+mn)8OYGàé~lÈ×sYa¼LvÜl:Üa*ɸ­P³ŒåG9õÓ¥Ë6qž¯¬\+IñÕNØF’ì‚Âó„%XâßЄ ‚2q¬¤½&LsWm¸ )‰œ:ú¢ì0‚‚9óZˆ$œà’S-<]ššº©{f½ØáåZŽÄ†d¸·Tº¾YõWx=«H»ª–+;’¢óqN•À-º«)nËKç$òI”ÂZJSŒò )ÊqÖž¢@Ú‘h›°°°²¶2\KÍÁlý‹íž'²[täŒHÇK7svmä˜ò“E·…I--H‹I- öèxœþ‡"hÐ_Ú›eÝ4‰qFä³\”ˆr—PËI€RJ‚¼E ™8Çæ’sê¶„ËÛs(÷GÙ×;{q؉.a¦«÷€ÙµöóbÍ­¡—Î$y 2cX_-RÙXôËl€Àâ¾Dc×è Ö.گݟg¹\ÛvÊZ)º[–T$% eÔ°¤ñ c lè~ؼpE™0C²]l)2ÍÓ ˆ.8á>"JÀúåÕ{à 78–pïàѾ[†VLÕÇùdÇxƒÉÄx« _GƒqÞ€%Òvf⌫j»YrܯPm¨è-¶¶$¸2Ûó<>?÷eϡК§¼XŒÃÏfÕø1_es<#á?Ë)ñrg˜rxc#ßFÐÞЇ¶Žà“µa»=TÉ•6YiVUâ5Ç#¼tA~Üî»écíÏœÙ?mM—âü›Î±-iÈâPG4Œ ¥+¯m[½Ù´ä–¦Fßñ_5¨ù—aªÕl) ¸­ ÊÔâ³ô:«k{¸§GÙÓA èÆ‹e!RDÅ) )jJß.!C>QæGiNtÛ·cnË{W÷•fé¬BCi¥LÜ¥•$y‘”6X耄“õ:Kß6ó¿7<[=Òü¥8ü¨uí¿'Ëê¥)KÉÆ8ã১·eF°¶w‘ž¯J–⢸â×È!EÕ€OÅmõ÷Ï<¨qÈŠ”‰Ûcv´·…`ÓõÑ›p ¨”p%¢±ÐÂ;8ÑݽùYcvñ‚ô¨s9'ưZ“Ä$eòyK>½'8õÓmµ,yU0w-‚¥YÞCKι9o†ËˆIó6„ø$«#8 RO^½èþʼ¹ÙÎXí͵*´8¡óO[­..+(P!¦ÜO¡ ï’R„(êó•®½RûmÑí-Ã|ÑJ™™š F¢$ôµ¼ëÅj[X#ÌP“ž½t¯¶%ˉ¼äÚì—$™-•OÚ«¼êiGÌ‚Èýuàû®Ç=]=#‚×Üoªä%ºž¯Ä㆖ÚÔB[Ϫr¿Euß@›³ööî“acç m÷*ã— ""f–œG/2ø´ââsèQ=sŽ´.ÒùVèám¸kw]ÄEȪÛLqɲ§\ ¨æ V}2‘§y&uMkt[VWWF†¦Œ9=!}ÑÁ)((â´þÃé¡tuðl MËO¼© .;Å˜ï› ÜÁó)µ©KXp2<{÷:Õ‰fò'‰YW®$y!+ÿѲ\R\Rx€Lfßm9–ÉÎ hÍfű°Ü•j‘:î3 Qi¶’ãŒ2ÒÈä¥).%…žðÚ¿ëhÁzÎïí ìîG×! ,¥\V;æ´¡IVT{ÊÈü=4µ¼Ú§b•™Ð6¤íÁ)Ž.<û|â<®ð„! ä© z€Gì Ûãk~I@U²%HŒSN%ûQ,ä­X)¿8þ‘ë½jÎÈVɵÞO³wtîä²q(n;ºÄtCò‚T„¾®JY ù’“Œk©¶Ý Œ‰ìL§«j# ƒ áXúDvÁÏÐ|©V;9Yï=uÙ-¿_OgnÚ¹ì’Ô–[˜%HÜ+a¼Ï4•çŒ$Ï~š Û¾¿ÇÚ%ñ¼¯¦‚µ&d–fËŽV¼œ)eˆå.$ù%\Îq¥m½FÕžà‹nîFܬ±rz*›–¹à6ÒÙt¡?t­J)þ]9ÝÙlx.¹5,Nù·Ê\‘rË‹†÷¯%¶·\)*üR¬ú¦ƒíƒK‘W·™zt§W"P3×™¦Ö¤’šûúè-î/†ö0é_~—lȧ‚Ì¥¸#Á\8“9Åki|8¥¢,GòhUD §¢C²v5öÝÔ´2Ô‹ÞÔˆÒ—‚·ÓL•ˆðl“Å•%I=¶8¤©ÂzÇ>¾ÚP·ާvöÒ¸‡ulðL†žnõnFmkÁRù¼ŽüŸœsØ'×V¶ØU„›:‹×Q¹fµJCÕ,¨,«QT•%ðÙ à¢G×±¦È.Ä…[O¾ïªn)мŸfCrTŸ×NRžCÓGÛ'ëÌ…’Ôý£TÕ¯¦‘O!IŒjšLWÇ"±Ä”äàñ8÷Ðß°JNÕÝ銄(L\Z´¬ cóySãÜt)ëОõ®½Öì-¢ÖËÚÛ™RŸ‡d0a¤¶8§‹M#šWœ‡~‡×N{>ãyذ÷µ‚ªå•!ÊÅÊKΩA?ucå›B:ÀÁ?Ž‘þ#WPRÖ3H¶‰¥|ü0%¶„ä EM$$…{Qߦ€ˆ§ÜÐoç=¸Ú5¬8[Su³)Û–”7Œ%´2µ¥  `ä“ÏÍï¬/*ï"É•;kìêJˆMa¥ÆYÒ†Vøn|D¶{ •+é”èßè³- Ã¨Ý°,¬«à¡65‰e•0•6¢?6¥¨…qÏ|J#=ý¥ÓÛo £ö]M…BÑq•b„Û|RRÛkO% ddúƒå‹Õ]l¸ÕíÌø‡ßšÊuo¿-.xj’…¹#‹‡ý¥gÔ`à-E±«‹9Tp,U%Ô9 Ùª‹BG )itþ%9޵œù‹Ó€BÉÇ$Ÿ½ï­5[atƒns•bꞬ´ILçÃŽ$¡ø9' Xòë öÓ4êøql~WpÌ‘jÊc…ÆøÉïÊ\Â}T2O›8ìu¤M¸”³ñtAol¿L–êæ/™’·™|©Ø‡ •‘Ç!?¬3í v°oó~ºE߉ÿÕ[õ¿›VºôþkCø€Œm;“ÿA{ùµjÖ^º{ÇÌr’·À!­+ý}_Í·®ÇVކ¹ö=§;Vgúú¿›F»=c~Ÿ³Z|Gö­;ý9Ø{p½öœ Û]ùsâÒD†œ†â°¾ GªÐ¡Œ,ûg8ïB(ö¥ŠˆÕ»Ït²Ê”b©9ŸEG8ì“ï§ÒÞS鯃Î Çú9Ǧ‚3ð~­›³›Ý;¯æ"()‡%…xdw 8õ×Q)Mbצ˜£Ò(îÓ Èü¹¿Sê<¼G#ÀZ“Þp ŒHôöÕ[ý©i{•Xïk²°µ¸Äh,-du…)¸é$A$ptßÇÓ­Bœz 10s)_*¤<—Må£N¦I–,&WâŸ~H`Ÿpzü5m? ™Gñ{’Ñ'ÅdC‚ˆB³òÿŽºR¯ï×§ëݦ&sák0ç½:>æ¶ù‡ ZãB^sêp¦»YFøf"D\h{¾úkp8¡¸AÈí ƒû³tRõÔH VƘ˜FÊšªÇª×¼îžˆþ,æ÷žâùˆŠ ޵x*ðÈÁè`ÿü5ÖJHñ'¼i‰A;kr¢I~"Ý-âsâ.¾ Ô;ÏELå=éª÷Û6ò÷*²ßÖåjXZœb¾ Q2›e$‚È'Ü<‘Þ¡N4ÄÁÉå|…!Ôº­É=—$Êñ®†Ê˧ÕYC@÷ô'†­7ð±H›Ý³Ò|PöEl yƒžYðºï:é¸Î¼ãÖ˜˜9„?…&×§GÝö0ø<ÖºèkÎ}zSdÝgá|ˆ±W÷¸†ÚÜKŠùhqY*P9¡°qøgé|5êS¦&#±.XõZ÷å³ßLj۵ЗËRZ$ë}vÒ¿9¹‘7ìæ¤4 }^¢î;gNÅ:ô i‰ì­Æ«Óuý³7˜TT@b8h“œå  úŸÑ÷Ö16¼[—.#ï‹ç¸RVðª‚JŠAãŸÍ`ÿ&º‡¨ÓZv¾èK¨püE´uHZœBŸ©‚éA>¸äÑÇìžÚsðòÚÚRÌß×?gòìAŠÂI9üÛc'>þ¿·]‡z…¼10sh߬"ÊfS[êÅo° ¦œv®‹J€À<”Ù>™ëñÕû ¥¸ç:§$|FµJ*_…S  é8ûÁ €¡ø}þºxðÿ yáäé‰J 6ô¸Qþ(ÜQPKÕP*$’rVÙ'³ï ‡±÷8Ò™‹ñ7p´‰R%Ð"Ç'Ä_Þ ñÊAýQû5ÐK†±-÷¦&kQðÞΧp£pVüD¼‰b¨qÁPë!IãÅ_tzƒôúêÌ}ƒpÌæg7¿íó2L¤‘[œç¼ëå §¿Ý®€Öa¿ÃLL V´{ºÚÈØüI±‘³ášJð2sœa®ÿ϶†mM‰qµîÝßÖ«’_,ÔBÉ8 ·õ÷×@-÷©ÃðÓ?°ï¡Ø¹>7ÄÃó8qKÀµuê• ƒéèF5·ò'q¦Ñë6þ%îe¾ž.8ÌhÍùqŒyPöiù-õ©ÃLLà|9²¬Ù«}[9)¦K [•ðÖ 0~òTÞ|Êí@ŸÇ¡«5›+pU‡Sâ=ë ¼‡ùXªm`zrAo‰Æ~š-õ¯<=10s‰ßì&<óîo{Ý}|ÝSp™*W§e 'W¿$7¤n”|D¸ù&ÕͤýŸ›gýø\Ò?aÓǯ8÷¦&}?`ÜKœ©î|DÜM>¤„•Gb39c°ÚÏC¿S­ ü3Óo6ébr7¤/ˆIÆÑºÿ³ßÿÀuÑf£óc­ üGGþ§ÞúÿøºYzéï0­\¥Ê>oúM§I" œ[vQxèAx$`òPï ûk£×üuØí'óÐ7?èÅe_þôkæÝM}}¯…Ýíkšê‰ÆÛͦ޺c}<>>l?¼w/û›×ë!ñû`îo÷6?¯×Ëúšçä×]'u³V¦]øñ°‰Ê!nOبl]¬Óñçá÷ *æÏá ëõó¦žMuÒw3V§ñãáðûÐ÷9ý˜þ¿^9ñãáù#Œ=Î>¹†Çõúù“SO&ºé;™«GÓiøñðü'ûÏs“þ¦ÇõúÄüxØ~Ð÷'û›?×kæmM<šë¤îf­M+ãÆÂÇP·&ÔÙþ»Q¿; '&ä'Ûø#?×kæ]M<šë¤îf­Nÿoí‰þA¹?Ýþ»^ÿtÅÇüŸ¸ÿÝ™þ»_0êiä×]'s5húq_¶)ÿî?÷f®Ô¶0ÿî3õþ Èÿ÷ÚùSO&ºé;™«GÓŸÛûc›·û³?ÖêoíþoÜîÍ]¯˜õ4òk®“¹š´}9ý¿¶7ùâÿugúí{ý¿ö?ùãÏú³?×kæ-M<šë¤îf­Nûò~âÏú³?×kYø÷±óŸ³÷û³?×kæ}M<šë¤îf­Kÿo½“ž n!ÿË5ýv²þßÛ+ÐÀÜ8ÿVkúí|Í©§“]tÌÕ£é¯íû²r1_¸Gÿ,×õÚðü}Ùÿ“÷û³_×kæmM<šë¤îf­L»'ò~áÿvkúíz>?lŸóvàÿvkúí|Ë©§“]tÌÕ£é¿íÿ±É®Ü?î¬ÿ]¯OÇýÖ+·ãü“ÿïuó¦žMuÒw3V¦ÇÇí?Åû‡ýÙŸëµþÈ ù;qÙŸëµó¦žMuÒw3V§ºc›·û«?×kÏîÙæíÃþìÏõÚùSO&ºé;™«GÓgãþÈÿ7n÷v¿®×‡ãöÈÿ7n÷v¿®×̺ñG 'Q> uäîfmNû#Þ»pÿ»µýv¡øý±ÿÍ»‡ýÝ¯ëµÆ~ÓÉùß0âž+x²¥aÅ ±’ßÓIî:€zJ“ÿá¯Òn4W4ÿ…_ûãLE¬Æ8ÆÏ¥ÿ·öÇÿ6î÷v¿®ÔþßûüݸÝÚþ»_3%Ôç´§ù4×´‹"²è½;ªn¹å¶¥´“ÁA$‚3œº#ÓU¦«UDpêüÿÛÿ ‹XŒq·ûlŸóváÿwkúíAñûd›·û»_×kæ]M{žMuÒwfÍZ>œþßû#üݸÝ™þ»^ì€ØÿæíÅþêÏõÚù‹SO&ºé;™«GÓßݱÿÍÛ‹ýٟ뵉øÿ²ø»pþYŸëµó¦žMuÒw3V¦ÇÇýŽÿÑÛ‹ýÝŸëµ?·öÇÎEvâü³?ÖëæMM<šë¤îf­MŸÛ úWîÿʳýv±?vAõ¯Ü?îÌÿ]¯™µ4òk®“¹š´}2>>lzýÃþêÏõÚôü~ÙæýÃþì×õÚù—SO&ºé;™«GÓCãîÉÿ7î÷f¿®Ö'ãæÉ'ûÃq»3ýv¾gÔÓÉ®ºNæjÑôÇöûØùÿ“÷û³_×k4ü~ØàÉÛ‡ýÙŸëµó&¦žMuÒw3V§Oö@loó~âÿvgúíyý¿¶7¼ Æùf®×Ìzšy5×IÜÍZ>œþßÛü߸¿Ýšþ»P|~ØÃü_¸¿Ý™þ»_1êiä×]'s5húsûlR0k÷îŒÏõºð|}ØÞð7ǧðV®×Ìššy5×IÜÍZ>žÙ±ÍûýÙŸëµçöþØyÏÙûò¬]¯˜µ4òk®“¹š´}=ý¿6 ûÕûŒ÷Ÿï6?®ÖÉ?Ù±$9â9r?±ïëþÜëåÝM<šë¤îf­Oµñÿb4âÖÜ=È Ò¿1Þ3ðÿ‰þ]xÒ“ràuýäÇõúù‡SO&ºé;™«GÔ*øûðýii ‡¹Šû€AŽ1×þèHýúõ¿ì€Ø-¼‡š‰¹Ðâ>ê¾Mƒþß_.êiä×]'s5hú€ü}ø|T¥˜;™KZ²¢a±ßÿ_ÿçÁ¶™S?'¹KJW2“?ÞÎsŸëÿß_1jiä×]'s5húƒû|?Ç÷Žæÿscúýyý¿vùåÿscúý|Á©§“]tÌÕ£é‰_6"Û)nã*=ù¢2yú?û¿~•7޳m·làE…n‡¥Fq”Zl$!@…’;>Ùë:âZñ_tþÍ<¢í˜‰ü´MæÒ¯u555ê¸&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjkÌ®ƒÝx¯ºu3­‘c½-ôÇŽ€§ž ¨ àgÔõªÕ1˜ƒ¬¡…4«=Èú­sÇ^óõÒw4GéþSר ³)!å–ªB–¢ ¿özk•­Jåøëá¯3kTƲõhôÂÊÉÓ–Äø%ÒÇ:É?ðlé ´Ýðø-ë„ÁPRQ1¥Åæxø‰(*ÇYÆss³˜ŠâgXùLþ`>š÷E%í»øeaê{$xŸ,ç`ú‚G¡Áе•¨‘êÁ×ÝÑiMQø—“10ššó#ë¯uÑ ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© ššš+·6Õîá|5Q\óã8.cOíQèj•ÚSDcTà˜‰žAZó?NõØ(þ ¸CûŠé˜¼“’ÄaÍi9÷>˜ÇɧZí¯°vã|bU5-ÁêüÓâ¬ÿû#÷ yvþ1agø§óÙÞ‹µusü>§Û·–êÅ}d—Ǻ‚ïÓ¥GÁû×È]¤ÈÕíû‚y+ùº„íÐÓCƒ<Hì\²Ý¶èÁ‡^]¯[UèŒ)ºÓÚáü'ÚqT6Òd¼z¥ ¶vxhšx§ÝçJ‰ý£:Q•¸å(œ¼1¡Rn\Y%O(þÃ]öñ_:åÖ,¨ã°ÃÞ)ñ¥ˆð›úGH@È5ªÃ<ãJJæ8 S‚ :â®[¨v“T‘láý3¬Ó33Œºrø“b›7 Ô¢¢'>ùÿÏ\ÑôyÎÏ”^ûÊзR ΪJ›(ʀƞv Ú1·”2¤(üšRBR#E H,㉙!ô=~ö|4‘ó*jÐÜ•3¹1:º¾Oyþ*Éýã\&-³‰r:¾Íº•ê¬þ:˜™ŽFºÌ½¹ðþÈ¿¶á´T{\UÏü4¹kðwmL*]=ä˜E_u©$¦F–¢Þ:’ ^PŽ‹CÜ’RGçF5¦Îûx³ô×?.uYQW8·ø3ºb#{Э~VÂÿ‘Xÿ†‘­©n*,ÙÖKˆàï´Sûõݪ·K©p-ÇìÓD]ÚÌ–<M¶ójè¡Ä…?aÖû/µ§×ÿñÆ«­3Ê_){¯¥-ö?ÃýÄ¿È&½óê¸j ÞŸM)]ü’XSûný‰Êõä7á+‚ Ÿä׫câ÷{OÅS„ÿ· îÕÒãš'¸6õÖßš¸–õïFq’z?°ú zT×MQŒK„ÄÃÝMMM] ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©­‘œ HmÅ ¥*ÃQ3„é›áô ™û…À±Ž9ì¯áí®Žõ´8[‰ ¦ãÇh†ÛHÒÙäÝ[x /Âq°TG|;Î—çØ©DžXø{åâÖÚÒÎy­•ÓƒEŽäq|‰YÒäûµ¨Ÿ>€JœI>oøèd‰G¿ÇYbEåÚ)Dùô.E‚¹Ðç^QÕu¬@¸ìÕ|Ú¬©*?]WV± êʶ)å}u©n}u↱ã À“¬zØS©ÇA€Í êqס: ¨qC[Û|ýNuT z΀‹r”©þ]Zfr†;:?~¶ è#Y)$yòè´+u÷ºÒ[k úêÓ/”Ÿ}T‡F®¼ZHóé²›s8ÙNF¸ìiD òÿŽ‹C°P#ÌGïÔÌ&%ÝyÚ/Ê[Eb[*!Äk™|DøU Kj±Úm–ˆIR˜R¼¤aŸ»ûúýš¯_j°¤§—gÓ½4Ún7v–ÙûfIÃÄb#+ëÄ_¨ëõAÖ»½µ¤Eœóþ9ÚÑLÇüŸ9A ‚8 ûjkÀIÉ>ç^ëíâq‡”šššš‘5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSS@çðç~?µ‹'FTú‰x9µßjFz=gÊqœÇzèÖìÍ΂öÞ¸mc%±”‘ûR ýÚášõµ-¥…´µ6¡èRpuäß<*ÎñTׄ´YÞ&ˆÂ]>ßd\Æ$·á¾ßÔ,Φ³Œ~©ý­TÛïrÕ´DÁ%~ããŸîÉïL-üS+N%д¯ÿ´ñOÿpuãZxEâ‰ü~Zi¼Q%´ pAOàFµ–Õ“ÖÎèÚ6g°äEýãyOü?òÖÿ–Ú’8¥™°{΄øëwkj=TˤWLò—>-þÝxQøk ¿¶ªÞ8„¶Þ^>ë?qÕ3µ@t¥ÆÞoþ²H?ñ׉Žk’J5o­> žÙå‰$ãöj–=ƒéŸM@Bᯠ;ÓÒöhþ®ÿ b­ëùåuøiŠp$õï‡øiÙ½ ?ŽPýÚËòAÖBÇîÑCgY†ÿ :§i³ëã¬þÑ«1ös=sqÌ~ìÇ@ˆÖA£Ÿä×@;Z­„)×)BFT¥”o|kku{b:BŸ—¼Œ…-ð3ÿLS5r„LÄ9òQôI:³—•ù¦sþªs§VîvLnƒÌ­CÛÃQÏïÆ³sâÙ†ßðx/ItzpGò«Z,îWŠùQ*M¥ý¯Úw’8‘IIô+Pi²áÌ÷Ô“)ð”ç°(Íø­~§¯‹£ù¿Ê®¿á ¶{ëuØ+2.dú­žù·Qà¶õz¦!Êo4G'n•'c|>‹ãÏy¹S’<Œ$‡'özÚuÅþ&ï™ûÞÙºÂbÂ`qñUrÄ«¼ã:§^ZœZŽJ”rN±×¯sðË;¼ÿ–8Ë=¥¼×øx:׺ššõSSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554^MMD5нGíÔÔ×E©Z‰übn°¶þþ?°jjkûí–”ëÝMMmqži©©© šššš ¬Çñ_¿SSAûúñϾu54þ½ÔÔ×X䬦¦¦¦¬&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh?ÿÙvdr-plugin-live/live/themes/redwine/0000755000175000017500000000000012650773437017325 5ustar tobiastobiasvdr-plugin-live/live/themes/redwine/css/0000755000175000017500000000000012650773437020115 5ustar tobiastobiasvdr-plugin-live/live/themes/redwine/css/theme.css0000644000175000017500000001131712650773437021734 0ustar tobiastobias/* ###################### # Globals ###################### */ input { border: 1px solid #963B5F; } select { border: 1px solid #963B5F; } /* ###################### # Tooltip style for hints ###################### */ .hint-tip { color: white; } .hint-tip .hint-tip-top { background: transparent url(/img/rounded-box-redwine-tl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-top .hint-tip-c { background: transparent url(/img/rounded-box-redwine-tr.png) no-repeat right 0px; } .hint-tip .hint-tip-bdy { background: transparent url(/img/rounded-box-redwine-ml.png) repeat-y 0px 0px; } .hint-tip .hint-tip-bdy .hint-tip-c { background: transparent url(/img/rounded-box-redwine-mr.png) repeat-y right 0px; } .hint-tip .hint-tip-bot { background: transparent url(/img/rounded-box-redwine-bl.png) no-repeat 0px 0px; } .hint-tip .hint-tip-bot .hint-tip-c { background: transparent url(/img/rounded-box-redwine-br.png) no-repeat right 0px; } /* ############################## # Tooltip style for epg infos ############################## */ .domTTepg div.epg_content { background: white url(../img/bg_tools.png) top left repeat-y; } /* ####################### # Menue ####################### */ div.menu { background: #000057 url(../img/menu_line_bg.png) repeat-x; color: #FFE9FA; } div#pagemenu { background: #FFFFFF url(../img/bg_line.png) top repeat-x; } div#pagemenu div { background: #FFFFFF url(../img/bg_line_top.png) bottom repeat-x; } div#pagemenu div div { background: #FFE9FA; border-top: 1px solid #DA8DA8; border-bottom: 1px solid #DA8DA8; } div#pagemenu a.active { color: #984E79; } div#pagemenu span.sep { color: #DA8DA8; } div#pagemenu span.active { color: #984E79; } /* ####################### # Info Box (near logo) ####################### */ div#infobox { border: 1px solid #DA8DA8; } div#infobox div.st_header { background: #FFE9FA; border-bottom: 1px solid #DA8DA8; } div#infobox div.st_content { background: white url(../img/bg_line_top.png) top left repeat-x; } div#infobox div.st_controls div.st_update { border-right: 1px solid #DA8DA8; } /* ####################### # Head Box ####################### */ div.head_box_l { background-image: url(../img/bg_header_l.png); } div.head_box_m { background-image: url(../img/bg_header_h.png); } div.head_box_r { background-image: url(../img/bg_header_r.png); } button.smallbutton { background-image: url(../img/button_blue.png); } button.green { background-image: url(../img/button_green.png); } button.red { background-image: url(../img/button_red.png); } button.blue { background-image: url(../img/button_blue.png); } /* ################ # Event ################ */ div.station div { background: url(../img/bg_box_l.png) top left no-repeat; } div.station div div { background: url(../img/bg_box_r.png) top right no-repeat; } div.station div div div { background: url(../img/bg_box_h.png) repeat-x; } div.content { background: white url(../img/bg_tools.png) top left repeat-y; } div.__progress { border: 1px solid #DA8DA8; } div.__progress div.__elapsed { background-color: #FFE9FA; } /* ############################## # Blue Background Thingy ############################## */ div.boxheader { background: url(../img/bg_box_l.png) top left no-repeat; } div.boxheader div { background: url(../img/bg_box_r.png) top right no-repeat; } div.boxheader div div { background: url(../img/bg_box_h.png) repeat-x; } /* ############################## # Recordings ############################## */ div.recording_item { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #DA8DA8; } /* ############################## # Remote Control Keypad ############################## */ div.screenshot { background-image: url(../img/tv.jpg); } /* ############################## # Edit Tables ############################## */ table.formular tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #DA8DA8; } /* ############################## # Search results ############################## */ table.listing tr td.head { background: #963B5F; } table.listing tr td { background: url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #DA8DA8; } /* ############################## # About box ############################## */ .about_box div.about_content div.about_head { background: #FFFFFF url(../img/bg_line.png) top repeat-x; } .about_box div.about_content div.about_head div { background: #FFFFFF url(../img/bg_line_top.png) bottom repeat-x; } .about_box div.about_content div.about_head div div { background: #FFE9FA; border-top: 1px solid #DA8DA8; border-bottom: 1px solid #DA8DA8; } vdr-plugin-live/live/themes/redwine/img/0000755000175000017500000000000012650773437020101 5ustar tobiastobiasvdr-plugin-live/live/themes/redwine/img/bg_tools.png0000644000175000017500000000021712650773437022417 0ustar tobiastobias‰PNG  IHDR!ß*PbKGDÿÿÿ ½§“ pHYs  šœtIME×  9uRbIDAT×cüÿòõÀí%ëTc‚XˆU®ÿ©dIEND®B`‚vdr-plugin-live/live/themes/redwine/img/bg_box_l.png0000644000175000017500000000032512650773437022362 0ustar tobiastobias‰PNG  IHDRÎoõ2bKGDÿÿÿ ½§“ pHYs  šœtIME× 'ôÁRbIDATÓuл €0 EÑÄXLÄ 4ŒAÁ HŒ…Ÿ©¢<„âÊGÏvah”¹ÒìóŠl›z€BÅsÜšDE’±óªÈ^Æ¢ÿ°‘¡&Ð)²Pä/’Ât'6’‚N?òŒ©/:Â/,IEND®B`‚vdr-plugin-live/live/themes/redwine/img/bg_box_r.png0000644000175000017500000000033512650773437022371 0ustar tobiastobias‰PNG  IHDRÎoõ2bKGDÿÿÿ ½§“ pHYs  šœtIME× óB˜åjIDATÓuÐ1 €0 ÐOéÙ]\ààî$.ÞÀ«ˆ¨MÓ8ö+4SùÉàWÖ´óÓMuo œJÄXu`^EÞ¼¿¶3C%2”bû‘‘ÅbÂuX2ÇHt€‘¾P†ñN,LŽ?s© 5‘Z½¹IEND®B`‚vdr-plugin-live/live/themes/redwine/img/bg_header_l.png0000644000175000017500000000036512650773437023026 0ustar tobiastobias‰PNG  IHDRé`¤úbKGDÿÿÿ ½§“ pHYs  šœtIME× #_Ùˆ‚IDATÓŽ½ Â0FŸÁ%}vÈÙ#žAh"!¤Œ‚,e¯ø'Gc”‹„ëÞ}ïN|û8Ÿa¸ù?<Äò¼NX€ã)d•,QkICÖ75m é‡f¹ÐpÐí-jW`U¯‘*ì´üßÍÍ”&âhß­ú# %q8¿­œ?MÙ‰iIEND®B`‚vdr-plugin-live/live/themes/redwine/img/bg_box_h.png0000644000175000017500000000027412650773437022361 0ustar tobiastobias‰PNG  IHDRÊš%bKGDÿÿÿ ½§“ pHYs  šœtIME×1æ>~üIIDAT×=‰Á € ÀšÎåDNãîàRÆ(r>0|š6èÛŽ­ÆDÅr>3–ëÆ|ã­c°²tA„Ä 1&ƒø-éðK_1ž!ÿ&IEND®B`‚vdr-plugin-live/live/themes/redwine/img/zap.png0000644000175000017500000000155112650773437021403 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<æIDAT8mSKhQ=ï½™4“&iú±ÅVÓ´I[¤â‡*hüW[èÆ… B®üB .‡j»qQA7n\H‚ XPñ¢¢‚  ñmSS­1µ5i§Ÿd&ó® mlÐ.‡{ÜË9Œˆ°^wgH%o— g€Ãé‚Á²ç6ËÄ,6Õ75}!ºpžÍ xŠs•|z]UøÐÖë–U‹QU£AQ†£s|gàéËW£Ñøû+KëÆÌ%™ðŸà*»iÚÙ×Q«:Šþ‡œE¸Þ?h=|yÿ±É~¶3%UúôÕÕ["»ÛWªNG¤µ³3ãI+_MÍ,8±«m…ºuÍ®ˆ*}:p¯v2¤ÑòŽpدþ³0ž4QV©b{{Rã&’jê]6º`Y„‰¤…††%ª[Tuxµ“!á{zÊåúvŽÁ2 “©ˆ€µ›¼˜–ûnbÿá%øü)ƒ3G†5!%0•ðú kTU89 _‡3x@JÞÄÕÛ ×|}hX_‹Ï?ž!=Y‚Ý­{ñu$ÕÁÏ;œ9Š Í?ÿ$ƒž`ΩaNTâèé4®^…LŽ£ÿÎe ¥JAn7,ãA^@æW ?îÐá¨ÞƒÚÆPßrpΜG:úô¯ÀÀmÊ&®jnþgÊ•c[ÛÎΦl‚K2c;O&FâÈårÿõÁ—á‘|O°!ÉŒ Ûð  ö"Vᛢ‡˜˜50øáˆ®bˆ$Þ¾z»7nãÅ£çà™(*øòc Z@IEND®B`‚vdr-plugin-live/live/themes/redwine/img/bg_header_h.png0000644000175000017500000000027112650773437023016 0ustar tobiastobias‰PNG  IHDRí•tÇbKGDÿÿÿ ½§“ pHYs  šœtIME× 6ú·kFIDAT×UŽ» €PìÌÅDLÃìÀ^Ü—N¼–ì*ð®u'J£°Dyû´DaŸ–ÅOÙÙZ!(Tô P‘k[t¾ Z@IEND®B`‚vdr-plugin-live/live/js/0000755000175000017500000000000012650773437015017 5ustar tobiastobiasvdr-plugin-live/live/js/live/0000755000175000017500000000000012650773437015756 5ustar tobiastobiasvdr-plugin-live/live/js/live/vlc.js0000644000175000017500000001226412650773437017105 0ustar tobiastobias/* * This is part of the live vdr plugin. See COPYING for license information. * * VLC class. * * This class adds convenience methods to a embeded vlc media player * object and allows control of the player and provides an event interface. */ /* Class: VLC A VLC plugin wrapper. Arguments: id - The id of the embedded vlc plugin. options - optional arguments, helping to tweak this class to your html. Options: autoresize - if true, the player will be resized with the browser window. controlsContainer - the id of the DOM element that contains the controls. controls - an array describing which controls are provided by the html page. Current supported types: play, mute, screen, close. for each type your page wants to provide an inline object is expected with with the following properties: type - one of the types above to map to the class internal functions for that type. id - the DOM id of the control. classes - on: class to add when toggled on. - off: class to add when toggled off. Events: ontoggle - event fired after the toggling of one property took place. */ var VLC = new Class({ options: { autoresize: true, controlsContainer: "vlcControls", // select by type the actions should be performed by a // instanciated object of class VLC. Possible types you find // below in the 'actions' definition. controls: [ { type: 'play', id: "TogglePlay", classes: { on: "red", off: "green" }}, { type: 'mute', id: "ToggleMute", classes: { on: "green", off: "red" }}, { type: 'screen', id: "FullScreen", classes: { on: "blue", off: "blue" }}, { type: 'close', id: "Close", classes: { on: "yellow", off: "yellow" }}, ], offset: 5, playRecording: false }, initialize: function(id, options){ this.setOptions(options); this.id = id; window.addEvent('domready', this.playerSetup.bind(this)); }, playerSetup: function(){ this.vlc = $(this.id); this.newVlcApi = (this.vlc.VersionInfo != null); // add here new actions these class might support: var actions = { play: { check: this.isPlaying, toggle: this.togglePlay }, mute: { check: this.isMuted, toggle: this.toggleMute }, screen: { check: Class.empty, toggle: this.toggleScreen }, close: { check: Class.empty, toggle: this.close }}; $each(this.options.controls, function(item, idx){ var elem = $(item.id); if (elem && actions[item.type]) { item.fns = actions[item.type]; } }, this); this.setStates(); var idx = 0; $each(this.options.controls, function(item){ if (item.fns && item.fns.toggle) $(item.id).addEvent('click', function (event, item){ var toggle = item.fns.toggle.bind(this); var check = item.fns.check.bind(this); toggle(); this.fireEvent('toggle', [item.id, check()]); }.bindWithEvent(this, item)); }, this); if (this.options.autoresize) { window.addEvent('resize', this.playerResize.bind(this)); } }, enableDeinterlace: function(){ if (this.newVlcApi) { this.vlc.video.deinterlace.enable("yadif"); } }, disableDeinterlace: function(){ if (this.newVlcApi) { this.vlc.video.deinterlace.disable(); } }, playerResize: function(el){ var winwidth = window.getWidth(); var winheight = window.getHeight(); winheight -= $(this.options.controlsContainer).getSize().size.y; winheight -= this.options.offset; this.vlc.setStyle('width', winwidth); this.vlc.setStyle('height', winheight); }, isPlaying: function(){ if (this.newVlcApi) return this.vlc.playlist && this.vlc.playlist.isPlaying; else return this.vlc.isplaying(); }, isMuted: function(){ if (this.newVlcApi) return this.vlc.audio && this.vlc.audio.mute; else { var res = this.vlc.get_volume(); return 0 == res; } }, togglePlay: function(){ if (this.newVlcApi) if (!this.options.playRecording) this.vlc.playlist.togglePause(); else { if (this.vlc.playlist.isPlaying) { clearTimeout(this.deint); this.disableDeinterlace(); this.vlc.playlist.stop(); else { this.vlc.playlist.play(); this.deint = setTimeout(this.enableDeinterlace, 500); } } else { if (this.isPlaying()) this.vlc.stop(); else this.vlc.play(); } this.setStates(); }, toggleMute: function(){ if (this.newVlcApi) this.vlc.audio.toggleMute(); else this.vlc.mute(); this.setStates(); }, toggleScreen: function(){ if (this.newVlcApi) this.vlc.video.toggleFullscreen(); else this.vlc.fullscreen(); this.setStates(); }, close: function(){ window.close(); }, setStates: function(){ $each(this.options.controls, function(item, idx){ if (item.fns && (Class.empty != item.fns.check)) { var fn = item.fns.check.bind(this); if (fn()) { $(item.id).removeClass(item.classes.off); $(item.id).addClass(item.classes.on); } else { $(item.id).removeClass(item.classes.on); $(item.id).addClass(item.classes.off); } } }, this); } }); VLC.implement(new Events, new Options); vdr-plugin-live/live/js/live/infowin.js0000644000175000017500000002422612650773437017773 0ustar tobiastobias/* * This is part of the live vdr plugin. See COPYING for license information. * * InfoWin.js * * InfoWin class, InfoWin.Manager class, InfoWin.Ajax class. * * Extension of mootools to display a popup window with some html * code. */ /* Class: InfoWin Create an information window as overlay to current page. Arguments: Options: Note: A window consists of a frame-element. This is the overall containing element used to control the display and size of the window. It is accesable through the 'winFrame' property. The InfoWin class provides the followin properties to fill the window with content: - titleBox: the element meant to place the title of the window into. - buttonBox: here the default window buttons are created. You might clear this and create your own kind of window controls. - winBody: this is where your window contents goes. */ var InfoWin = new Class({ options: { timeout: 0, onShow: Class.empty, onHide: Class.empty, onDomExtend: Class.empty, destroyOnHide: false, className: 'info', wm: false, // overide default window manager. draggable: true, resizable: true, buttonimg: 'transparent.png', bodyselect: 'div.content', titleselect: 'div.caption', classSuffix: '-win', idSuffix: '-id', offsets: {'x': -16, 'y': -16} }, initialize: function(id, options){ this.setOptions(options); this.wm = this.options.wm || InfoWin.$wm; this.winFrame = $(id + this.options.classSuffix + this.options.idSuffix); if (!$defined(this.winFrame)){ this.buildFrame(id); this.build(id); this.wm.register(this); } }, // internal: build new window element. // // build sets up a frame for a new InfoWin. The parent element // of the window frame has the id '-win-id'. The function // must return true if the body of the InfoWin has been filled // with the user data, false otherwise. build: function(id){ // header of window: upper shadows, corners title and controls var top = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-top' }).inject(this.winFrame); if (this.options.draggable) this.winFrame.makeDraggable({'handle': top}); top = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(top); this.titleBox = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-t' }).inject(top); this.buttonBox = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-b' }).inject(top); var cls = new Element('div', { 'class': 'close' }).inject(this.buttonBox); cls.addEvent('click', function(event){ var event = new Event(event); event.stop(); return this.hide(); }.bind(this)); cls = new Element('img', { 'src': this.options.buttonimg, 'alt': 'close', 'width': '16px', 'height': '16px' }).inject(cls); // body of window: user content. var bdy = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-body' }).inject(this.winFrame); bdy = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bdy); this.winBody = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-s' }).inject(bdy); // bottom border of window: lower shadows and corners, optional // resize handle. var bot = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-bot' }).inject(this.winFrame); bot = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bot); if (this.options.resizable) { this.winFrame.makeResizable({'handle': bot}); } if (!this.fillTitle(id)) { // todo: add generic title } return this.fillBody(id); }, buildFrame: function(id){ this.winFrame = new Element('div', { 'id': id + this.options.classSuffix + this.options.idSuffix, 'class': this.options.className + this.options.classSuffix, 'styles': { 'position': 'absolute', 'top': '0', 'left': '0' } }); }, show: function(event){ this.position(event); this.fireEvent('onShow', [this.winFrame]); this.wm.raise(this); if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this); return false; }, hide: function(){ this.fireEvent('onHide', [this.winFrame]); if (this.options.destroyOnHide) { this.wm.unregister(this); for (var z in this) this[z] = null; this.destroyed = true; } else { this.wm.bury(this); } return false; }, fillBody: function(id){ var bodyElems = $$('#'+ id + ' ' + this.options.bodyselect); if ($defined(bodyElems) && bodyElems.length > 0) { this.winBody.empty(); this.fireEvent('onDomExtend', [id, bodyElems]); this.winBody.adopt(bodyElems); return true; } return false; }, fillTitle: function(id){ var titleElems = $$('#' + id + ' ' + this.options.titleselect); if ($defined(titleElems) && titleElems.length > 0) { this.titleBox.empty().adopt(titleElems); return true; } return false; }, position: function(event){ var prop = {'x': 'left', 'y': 'top'}; for (var z in prop) { var pos = event.page[z] + this.options.offsets[z]; this.winFrame.setStyle(prop[z], pos); } } }); InfoWin.implement(new Events, new Options); /* Class: InfoWin.Manager Provide an container and events for the created info win instances. Closed info-wins are preserved in a hidden dom element and used again if a window with a closed id is openend again. */ InfoWin.Manager = new Class({ options: { closedContainer: 'infowin-closed', openedContainer: 'infowin-opened', onRegister: Class.empty, onUnregister: Class.empty, onRaise: Class.empty, onBury: Class.empty }, initialize: function(options){ this.setOptions(options); // initialize properties this.closedWins and this.openedWins: ['closed', 'opened'].each(function(kind){ var wins = kind + 'Wins'; var opts = this.options[kind + 'Container']; this[wins] = $(opts); if (!$defined(this[wins])){ this[wins] = new Element('div', { 'id': opts, 'styles' : { 'display' : (kind == 'closed') ? 'none' : 'block' } }); this[wins].inject(document.body); } }, this); }, register: function(infoWin){ this.fireEvent('onRegister', [infoWin]); infoWin.winFrame.addEvent('click', function(){ this.raise(infoWin); }.bind(this)); infoWin.winFrame.inject(this.closedWins); }, unregister: function(infoWin){ this.fireEvent('onUnregister', [infoWin]); infoWin.winFrame.remove(); }, raise: function(infoWin){ this.fireEvent('onRaise', [infoWin]); infoWin.winFrame.inject(this.openedWins); }, bury: function(infoWin){ this.fireEvent('onBury', [infoWin]); infoWin.winFrame.inject(this.closedWins); } }); InfoWin.Manager.implement(new Events, new Options); InfoWin.$wm = null; window.addEvent('domready', function(){ InfoWin.$wm = new InfoWin.Manager(); }); /* Class: InfoWin.Ajax Use an instance of mootools Ajax class to asynchronously request the content of an info win. */ InfoWin.Ajax = InfoWin.extend({ options: { loadingMsg: 'loading', errorMsg: 'an error occured!', onError: Class.empty }, initialize: function(id, url, options){ this.parent(id, options); if ($defined(this.ajaxResponse)) { this.addEvent('onError', function(){ this.hide.delay(1000, this); }.bind(this)); var ajax = new Ajax(url, { update: this.ajaxResponse, onComplete: function(text, xmldoc){ this.fillTitle(id); this.fillBody(id); this.ajaxResponse.remove(); }.bind(this), onFailure: function(transport){ this.titleBox.setHTML(this.options.errorMsg); this.fireEvent('onError', [id, url]); }.bind(this) }).request('async=1'); } }, // this function gets called when no previous instance for 'id' // created a dom subtree for an infowin. build: function(id){ if (!this.parent(id)) { this.titleBox.setHTML(this.options.loadingMsg); this.ajaxResponse = new Element('div', { 'styles' : { 'display': 'none' } }).inject(this.winFrame); } } }); /* Class: Infowin.Notifier Creates a notification popup that disappears automaticaly. Usefull for a confirmation message after a AJAX action request. */ InfoWin.Notifier = InfoWin.extend({ options: { timeout: 2500, destroyOnHide: true, className: 'ok', classSuffix: '-info', message: '', offsets: {'x': 16, 'y': 16} }, initialize: function(id, options){ this.parent(id, options); }, build: function(id){ /* top border of hint */ var top = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-top' }).inject(this.winFrame); top = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(top); /* body of tip: some helper divs and content */ var bdy = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-body' }).inject(this.winFrame); bdy = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bdy); this.winBody = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-s' }).inject(bdy); /* bottom border of tip */ var bot = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-bot' }).inject(this.winFrame); bot = new Element('div', { 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bot); return this.fillBody(id); }, fillBody: function(id){ this.winFrame.setStyle('position', 'fixed'); this.winBody.empty().setHTML(this.options.message); return true; }, position: function(event){ var prop = {'x': 'left', 'y': 'top'}; for (var z in prop) { var pos = this.options.offsets[z]; this.winFrame.setStyle(prop[z], pos); } } }); vdr-plugin-live/live/js/live/vdr_status.js0000644000175000017500000001323212650773437020513 0ustar tobiastobias/* * Javascript functions for the status update box. * This file needs mootools.js to be included on the pages. */ var LiveVdrInfo = Ajax.extend({ options: { autoCancel: true }, initialize: function(url, boxId) { this.parent(url, null); this.addEvent('onComplete', this.showInfo); this.addEvent('onFailure', this.reportError); this.boxId = boxId; this.reload = true; this.timer = null; }, request: function(update) { this.parent({update: update ? "1" : "0"}); }, showInfo: function(text, xmldoc) { try { this.selectInfoElems(xmldoc); this.setEpgInfo(xmldoc); this.setInfoMessage(xmldoc); this.setUpdate(xmldoc); } catch (e) { this.reportError(null); } }, reportError: function(transport) { this.setTextContent('caption', 'ERROR'); var message; if (transport != null) { message = $("__infobox_request_err").firstChild.nodeValue; } else { message = $("__infobox_update_err").firstChild.nodeValue; } this.setTextContent('name', message); }, // private function to switch visibility of controls. selectInfoElems: function(xmldoc) { var infoType = xmldoc.getElementsByTagName('type').item(0); var channel = $(this.boxId + '_channel_buttons'); var playback = $(this.boxId + '_recording_buttons'); if (infoType.firstChild.nodeValue != "channel") { channel.style.display = 'none'; playback.style.display = 'block'; this.setTextContent('pause', infoType.firstChild.nodeValue); this.setTextContent('play', infoType.firstChild.nodeValue); this.setTextContent('rwd', infoType.firstChild.nodeValue); this.setTextContent('ffw', infoType.firstChild.nodeValue); this.setTextContent('stop', infoType.firstChild.nodeValue); } else { playback.style.display = 'none'; channel.style.display = 'block'; } }, // private function to activate the info message display if the // corresponding element is found in the current page. setInfoMessage: function(xmldoc) { var info = xmldoc.getElementsByTagName('info').item(0); if (! $defined(info)) return; var messagebar = $('messagebar'); if (! $defined(messagebar)) return; var message = xmldoc.getElementsByTagName('message').item(0); var url = xmldoc.getElementsByTagName('url').item(0); if (message.firstChild.nodeValue != "") { $('mbmessage').setText(message.firstChild.nodeValue); if ($defined(url.firstChild)) { $('mbdelimiter').removeClass('notpresent'); $('mbreact').setProperty('href', url.firstChild.nodeValue); } else { $('mbdelimiter').addClass('notpresent'); $('mbreact').addClass('notpresent'); } messagebar.removeClass('notpresent'); } }, // private function to display information from epg info. setEpgInfo: function(xmldoc) { var epgInfo = xmldoc.getElementsByTagName('epginfo').item(0); for (var i = 0; i < epgInfo.childNodes.length; i++) { var node = epgInfo.childNodes.item(i); if (node.nodeType == 1) { var textContent = ""; if (node.firstChild != null) textContent = node.firstChild.nodeValue; this.setTextContent(node.nodeName, textContent); } } }, // private function to update text contents. setTextContent: function(nodeName, textContent) { var docNode = $(this.boxId + '_' + nodeName); if (docNode != null) { switch (nodeName) { case "caption": case "timenow": case "name": case "duration": { if (docNode.innerHTML != textContent) docNode.innerHTML = textContent; break; } case "elapsed": { var width = textContent + "px"; if (docNode.style.width != width) docNode.style.width = width; break; } case "nextchan": case "prevchan": { if (textContent != "") { // docNode.href = "javascript:LiveSimpleAjaxRequest('switch_channel.xml', 'param', '" + textContent + "');"; docNode.href = "vdr_request/switch_channel?param=" + textContent; docNode.style.visibility = "visible"; } else { docNode.style.visibility = "hidden"; } break; } case "pause": case "play": case "rwd": case "ffw": case "stop": { if (textContent != "") { // docNode.href = "javascript:LiveSimpleAjaxRequest('" + nodeName + "_recording.xml', 'param', '" + textContent + "');"; docNode.href = "vdr_request/" + nodeName + "_recording?param=" + textContent; docNode.style.visibility = "visible"; } else { docNode.style.visibility = "hidden"; } break; } default: break; } } }, // private function to determine update status and to trigger // the next update. setUpdate: function(xmldoc) { /* check if we still need to update the status */ var upd = xmldoc.getElementsByTagName('update').item(0); var rel = (upd.firstChild.nodeValue == "1"); if (rel != this.reload) { this.reload = rel; var img = $('statusReloadBtn'); if (img != null) { // change image according to state. img.src = this.reload ? 'img/stop_update.png' : 'img/reload.png'; } } if (this.reload) this.timer = this.request.delay(1000, this, true); }, toggleUpdate: function() { if (this.reload) { if (this.timer != null) { this.timer = $clear(this.timer); } } this.request(!this.reload); }, pageFinished: function() { if (this.reload) { if (this.timer != null) { this.timer = $clear(this.timer); } } this.cancel(); } }); vdr-plugin-live/live/js/live/pageenhance.js0000644000175000017500000001321512650773437020554 0ustar tobiastobias/* * This is part of the live vdr plugin. See COPYING for license information. * * PageEnhance class. * * This class applies several functions to the page based on * selectors. This class is project dependent and not a general * purpose class. */ var PageEnhance = new Class({ options: { epgLinkSelector: 'a[href^="epginfo.html?epgid"]', actionLinkSelector: 'a[href^="vdr_request/"]', vlcLinkSelector: 'a[href^="vlc.html?"]', vlcWinOptions: { size: { width: 720, height: 640 } }, editTimerSelector: 'a[href^="edit_timer.html?timerid"]', hintTipSelector: '*[title]', hintClassName: 'hint', infoWinOptions: { bodyselect: 'div.epg_content', loadingMsg: 'loading', errorMsg: 'an error occured!' }, notifyIdPrefix: 'notify', notifyStrings: { successMsg: ' Success!', errorMsg: ' failed!' }, datePickerSelector: 'input.DatePicker', datePickerOptions: '' }, initialize: function(options){ this.setOptions(options); this.$notifyCount = 0; window.addEvent('domready', this.domReadySetup.bind(this)); window.addEvent('mousedown', this.mouseDownSetup.bind(this)); }, // actions applied on domready to the page. domReadySetup: function(){ $$(this.options.epgLinkSelector).each(this.epgPopup.bind(this)); this.addHintTips($$(this.options.hintTipSelector)); $$(this.options.actionLinkSelector).each(this.vdrRequest.bind(this)); $$(this.options.vlcLinkSelector).each(this.vlcRequest.bind(this)); $$(this.options.datePickerSelector).each(this.datePicker.bind(this)); // the following line activates timer editing in popup window. // but it does not yet work like expected. So we leave it deactivated currently. // $$(this.options.editTimerSelector).each(this.editTimer.bind(this)); }, // actions applied on mouse down. mouseDownSetup: function(){ $$('.' + this.options.hintClassName + '-tip').setStyle('visibility', 'hidden'); }, // registered as 'onDomExtend' event for InfoWin. Takes care to // enhance the new dom elements too. domExtend: function(id, elems){ var sel = '#' + id + ' ' + this.options.hintTipSelector; elems = $$(sel); this.addHintTips(elems); $$('#' + id + ' ' + this.options.actionLinkSelector).each(this.vdrRequest.bind(this)); $$('#' + id + ' ' + this.options.vlcLinkSelector).each(this.vlcRequest.bind(this)); }, // Epg Popup function. Apply to all elements that should // pop up an Epg InfoWin window. epgPopup: function(el){ var href = el.href; var epgid = $pick(href, ""); if (epgid != "") { var extractId = /epgid=(\w+)/; var found = extractId.exec(epgid); if ($defined(found) && found.length > 1) { epgid = found[1]; el.addEvent('click', function(event){ var event = new Event(event); new InfoWin.Ajax(epgid, href, $merge(this.options.infoWinOptions, { onDomExtend: this.domExtend.bind(this) })).show(event); event.stop(); return false; }.bind(this)); } } }, // Edit Timer Popup function. Apply to all elements that should // pop up a timer edit windows based on InfoWin window. editTimer: function(el){ var href = el.href; var timerid = $pick(href, ""); if (timerid != "") { var extractId = /timerid=(.+)/; var found = extractId.exec(timerid); if ($defined(found) && found.length > 1) { timerid = found[1]; el.addEvent('click', function(event){ var event = new Event(event); new InfoWin.Ajax(timerid, href, $merge(this.options.infoWinOptions, { bodyselect: '', modal: true, onDomExtend: this.domExtend.bind(this) })).show(event); event.stop(); return false; }.bind(this)); } } }, // function that requests an action from the server vdr. vdrRequest: function(el){ el.addEvent('click', function(event, element){ var href = $pick(element.href, ""); if (href != "") { this.$notifyCount++; var req = new Ajax(href, { method: 'post', onComplete: function(text, xmldoc) { try { var success = xmldoc.getElementsByTagName('response').item(0).firstChild.nodeValue; new InfoWin.Notifier(this.options.notifyIdPrefix + this.$notifyCount, { className: success == '1' ? 'ok' : 'err', message: success == '1' ? this.options.notifyStrings.successMsg : this.options.notifyStrings.errorMsg }).show(event); } catch(e) { } }.bind(this) }); req.request('async=1'); event.stop(); return false; } return true; }.bindWithEvent(this, el)); }, // function that opens a window for streaming of tv data. vlcRequest: function(el){ el.addEvent('click', function(event, element){ var href = $pick(element.href, ""); if (href != "") { href += "&async=1"; var bw = new BrowserWin("vlcstream", href, this.options.vlcWinOptions); event.stop(); return false; } return true; }.bindWithEvent(this, el)); }, // change normal 'title'-Attributes into enhanced hinttips // usesd by domExtend and domReadySetup functions. addHintTips: function(elems){ if (!$defined(this.tips)) { this.tips = new HintTips(elems, { maxTitleChars: 100, className: this.options.hintClassName }); } else { $$(elems).each(this.tips.build, this.tips); } }, // add datepicker to input element datePicker: function(el){ el.alt = this.options.datePickerOptions; new DatePicker(el); } }); PageEnhance.implement(new Events, new Options); vdr-plugin-live/live/js/live/liveajax.js0000644000175000017500000000041212650773437020114 0ustar tobiastobias/* * Javascript function for quick ajax requests. * This file needs mootools.js to be included on the pages. */ function LiveSimpleAjaxRequest(url, param, value) { var req = new Ajax(url, { method : 'post' }).request(param + '=' + value + '&async=1'); }; vdr-plugin-live/live/js/live/browserwin.js0000644000175000017500000000465412650773437020526 0ustar tobiastobias/* * This is part of the live vdr plugin. See COPYING for license information. * * browserwin.js * * BrowserWin class, BrowserWin.Manager class * * Extension of mootools to create and manage browser windows. */ /* Class: BrowserWin Create and browswer window pointing at an specific URL. Arguments: Options: Note: */ var BrowserWin = new Class({ options: { size: { width: 720, height: 640 }, toolbar: false, location: false, directories: false, statusbar: false, menubar: false, scrollbar: false, resizable: true, wm: false // overide default window manager. }, initialize: function(id, url, options){ this.setOptions(options); this.id = id; this.wm = this.options.wm || BrowserWin.$wm; this.wm.register(this, url); }, create: function(url){ winOpts = "height=" + this.options.size.height; winOpts += ",width=" + this.options.size.width; winOpts += ",toolbar=" + this.options.toolbar; winOpts += ",location=" + this.options.toolbar; winOpts += ",directories=" + this.options.directories; winOpts += ",statusbar=" + this.options.statusbar; winOpts += ",menubar=" + this.options.menubar; winOpts += ",scrollbars=" + this.options.scrollbars; winOpts += ",resizable=" + this.options.resizable; if ($defined(this.options.top)) { winOpts += ",top=" + this.options.top; } if ($defined(this.options.left)) { winOpts += ",left=" + this.options.left; } this.$winRef = window.open(url, this.id, winOpts); }, close: function(){ this.wm.unregister(this); } }); BrowserWin.implement(new Events, new Options); BrowserWin.Manager = new Class({ options: { onRegister: Class.empty, onUnregister: Class.empty }, initialize: function(options){ this.setOptions(options); this.hashTab = new Hash(); }, register: function(browserWin, url){ this.unregister(browserWin); browserWin.create(url); this.hashTab.set(browserWin.id, browserWin); this.fireEvent('onRegister', [browserWin]); }, unregister: function(browserWin){ if (this.hashTab.hasKey(browserWin.id)) { winRef = this.hashTab.get(browserWin.id); winRef.$winRef.close(); this.fireEvent('onUnregister', [winRef]); this.hashTab.remove(browserWin.id); } } }); BrowserWin.Manager.implement(new Events, new Options); BrowserWin.$wm = null; window.addEvent('domready', function(){ BrowserWin.$wm = new BrowserWin.Manager(); }); vdr-plugin-live/live/js/live/hinttips.js0000644000175000017500000000220312650773437020153 0ustar tobiastobias/* * This is part of the live vdr plugin. See COPYING for license information. * * HintTips class. * * Extension of mootools Tips class for rounded corner tooltips of * variable size up to some maximum. */ var HintTips = Tips.extend({ initialize: function(elements, options){ this.parent(elements, options); this.toolTip.empty(); /* top border of tip */ var hd = new Element('div', {'class': this.options.className + '-tip-top'}).inject(this.toolTip); hd = new Element('div', {'class': this.options.className + '-tip-c'}).inject(hd); /* body of tip: some helper divs and content */ this.wrapper = new Element('div', {'class': this.options.className + '-tip-bdy'}).inject(this.toolTip); this.wrapper = new Element('div', {'class': this.options.className + '-tip-c'}).inject(this.wrapper); this.wrapper = new Element('div', {'class': this.options.className + '-tip-s'}).inject(this.wrapper); /* bottom border of tip */ var bt = new Element('div', {'class': this.options.className + '-tip-bot'}).inject(this.toolTip); bt = new Element('div', {'class': this.options.className + '-tip-c'}).inject(bt); } }); vdr-plugin-live/live/js/mootools/0000755000175000017500000000000012650773437016672 5ustar tobiastobiasvdr-plugin-live/live/js/mootools/DatePicker.js0000644000175000017500000002067312650773437021253 0ustar tobiastobias/* * DatePicker * @author Rick Hopkins * @modified by Micah Nolte and Martin Va�ina * @version 0.3.2 * @classDescription A date picker object. Created with the help of MooTools v1.11 * MIT-style License. -- start it up by doing this in your domready: $$('input.DatePicker').each( function(el){ new DatePicker(el); }); */ var DatePicker = new Class({ /* set and create the date picker text box */ initialize: function(dp){ // Options defaults this.dayChars = 1; // number of characters in day names abbreviation this.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; this.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; this.format = 'mm/dd/yyyy'; this.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; this.startDay = 7; // 1 = week starts on Monday, 7 = week starts on Sunday this.yearOrder = 'asc'; this.yearRange = 10; this.yearStart = (new Date().getFullYear()); // Finds the entered date, or uses the current date if(dp.value != '') { dp.then = new Date(dp.value); dp.today = new Date(); } else { dp.then = dp.today = new Date(); } // Set beginning time and today, remember the original dp.oldYear = dp.year = dp.then.getFullYear(); dp.oldMonth = dp.month = dp.then.getMonth(); dp.oldDay = dp.then.getDate(); dp.nowYear = dp.today.getFullYear(); dp.nowMonth = dp.today.getMonth(); dp.nowDay = dp.today.getDate(); // Pull the rest of the options from the alt attr if(dp.alt) { options = Json.evaluate(dp.alt); } else { options = []; } dp.options = { monthNames: (options.monthNames && options.monthNames.length == 12 ? options.monthNames : this.monthNames) || this.monthNames, daysInMonth: (options.daysInMonth && options.daysInMonth.length == 12 ? options.daysInMonth : this.daysInMonth) || this.daysInMonth, dayNames: (options.dayNames && options.dayNames.length == 7 ? options.dayNames : this.dayNames) || this.dayNames, startDay : options.startDay || this.startDay, dayChars : options.dayChars || this.dayChars, format: options.format || this.format, yearStart: options.yearStart || this.yearStart, yearRange: options.yearRange || this.yearRange, yearOrder: options.yearOrder || this.yearOrder }; dp.setProperties({'id':dp.getProperty('name'), 'readonly':true}); dp.container = false; dp.calendar = false; dp.interval = null; dp.active = false; dp.onclick = dp.onfocus = this.create.pass(dp, this); }, /* create the calendar */ create: function(dp){ if (dp.calendar) return false; // Hide select boxes while calendar is up if(window.ie6){ $$('select').addClass('dp_hide'); } /* create the outer container */ dp.container = new Element('div', {'class':'dp_container'}).injectBefore(dp); /* create timers */ dp.container.onmouseover = dp.onmouseover = function(){ $clear(dp.interval); }; dp.container.onmouseout = dp.onmouseout = function(){ dp.interval = setInterval(function(){ if (!dp.active) this.remove(dp); }.bind(this), 500); }.bind(this); /* create the calendar */ dp.calendar = new Element('div', {'class':'dp_cal'}).injectInside(dp.container); /* create the date object */ var date = new Date(); /* create the date object */ if (dp.month && dp.year) { date.setFullYear(dp.year, dp.month, 1); } else { dp.month = date.getMonth(); dp.year = date.getFullYear(); date.setDate(1); } dp.year % 4 == 0 ? dp.options.daysInMonth[1] = 29 : dp.options.daysInMonth[1] = 28; /* set the day to first of the month */ var firstDay = (1-(7+date.getDay()-dp.options.startDay)%7); /* create the month select box */ monthSel = new Element('select', {'id':dp.id + '_monthSelect'}); for (var m = 0; m < dp.options.monthNames.length; m++){ monthSel.options[m] = new Option(dp.options.monthNames[m], m); if (dp.month == m) monthSel.options[m].selected = true; } /* create the year select box */ yearSel = new Element('select', {'id':dp.id + '_yearSelect'}); i = 0; dp.options.yearStart ? dp.options.yearStart : dp.options.yearStart = date.getFullYear(); if (dp.options.yearOrder == 'desc'){ for (var y = dp.options.yearStart; y > (dp.options.yearStart - dp.options.yearRange - 1); y--){ yearSel.options[i] = new Option(y, y); if (dp.year == y) yearSel.options[i].selected = true; i++; } } else { for (var y = dp.options.yearStart; y < (dp.options.yearStart + dp.options.yearRange + 1); y++){ yearSel.options[i] = new Option(y, y); if (dp.year == y) yearSel.options[i].selected = true; i++; } } /* start creating calendar */ calTable = new Element('table'); calTableThead = new Element('thead'); calSelRow = new Element('tr'); calSelCell = new Element('th', {'colspan':'7'}); monthSel.injectInside(calSelCell); yearSel.injectInside(calSelCell); calSelCell.injectInside(calSelRow); calSelRow.injectInside(calTableThead); calTableTbody = new Element('tbody'); /* create day names */ calDayNameRow = new Element('tr'); for (var i = 0; i < dp.options.dayNames.length; i++) { calDayNameCell = new Element('th'); calDayNameCell.appendText(dp.options.dayNames[(dp.options.startDay+i)%7].substr(0, dp.options.dayChars)); calDayNameCell.injectInside(calDayNameRow); } calDayNameRow.injectInside(calTableTbody); /* create the day cells */ while (firstDay <= dp.options.daysInMonth[dp.month]){ calDayRow = new Element('tr'); for (i = 0; i < 7; i++){ if ((firstDay <= dp.options.daysInMonth[dp.month]) && (firstDay > 0)){ calDayCell = new Element('td', {'class':dp.id + '_calDay', 'axis':dp.year + '|' + (parseInt(dp.month) + 1) + '|' + firstDay}).appendText(firstDay).injectInside(calDayRow); } else { calDayCell = new Element('td', {'class':'dp_empty'}).appendText(' ').injectInside(calDayRow); } // Show the previous day if ( (firstDay == dp.oldDay) && (dp.month == dp.oldMonth ) && (dp.year == dp.oldYear) ) { calDayCell.addClass('dp_selected'); } // Show today if ( (firstDay == dp.nowDay) && (dp.month == dp.nowMonth ) && (dp.year == dp.nowYear) ) { calDayCell.addClass('dp_today'); } firstDay++; } calDayRow.injectInside(calTableTbody); } /* table into the calendar div */ calTableThead.injectInside(calTable); calTableTbody.injectInside(calTable); calTable.injectInside(dp.calendar); /* set the onmouseover events for all calendar days */ $$('td.' + dp.id + '_calDay').each(function(el){ el.onmouseover = function(){ el.addClass('dp_roll'); }.bind(this); }.bind(this)); /* set the onmouseout events for all calendar days */ $$('td.' + dp.id + '_calDay').each(function(el){ el.onmouseout = function(){ el.removeClass('dp_roll'); }.bind(this); }.bind(this)); /* set the onclick events for all calendar days */ $$('td.' + dp.id + '_calDay').each(function(el){ el.onclick = function(){ ds = el.axis.split('|'); dp.value = this.formatValue(dp, ds[0], ds[1], ds[2]); this.remove(dp); }.bind(this); }.bind(this)); /* set the onchange event for the month & year select boxes */ monthSel.onfocus = function(){ dp.active = true; }; monthSel.onchange = function(){ dp.month = monthSel.value; dp.year = yearSel.value; this.remove(dp); this.create(dp); }.bind(this); yearSel.onfocus = function(){ dp.active = true; }; yearSel.onchange = function(){ dp.month = monthSel.value; dp.year = yearSel.value; this.remove(dp); this.create(dp); }.bind(this); }, /* Format the returning date value according to the selected formation */ formatValue: function(dp, year, month, day){ /* setup the date string variable */ var dateStr = ''; /* check the length of day */ if (day < 10) day = '0' + day; if (month < 10) month = '0' + month; /* check the format & replace parts // thanks O'Rey */ dateStr = dp.options.format.replace( /dd/i, day ).replace( /mm/i, month ).replace( /yyyy/i, year ); dp.month = dp.oldMonth = '' + (month - 1) + ''; dp.year = dp.oldYear = year; dp.oldDay = day; /* return the date string value */ return dateStr; }, /* Remove the calendar from the page */ remove: function(dp){ $clear(dp.interval); dp.active = false; if (window.opera) dp.container.empty(); else if (dp.container) dp.container.remove(); dp.calendar = false; dp.container = false; $$('select.dp_hide').removeClass('dp_hide'); } }); vdr-plugin-live/live/js/mootools/readme.mootools.config0000644000175000017500000000247712650773437023202 0ustar tobiastobiasThis file documents the configuration of mootools! The otherwise cool feature of mootools to select only needed functionality can be a nightmare when trying to add additional features in a distributed development situation. Because the configured mootools download does not document in a central position which options have been selected to optain a specific version of mootools. Therefore this file, which documents the minimal selections needed to get a valid mootools configuration for the features of mootools used in live. In order to obtain the right mootools configuration follow these steps: - Go to mootools download page: http://mootools.net/download - Usualy 'Core' is preselected. This is OK :) but you can unselect it to have a 'clean' starting base. - Scroll down to the bottom of the page and select the following options towards the top of the download page in this order: 1. Tips 2. Hash 3. Json 4. Ajax 5. Drag.Move 6. Window.DomReady 7. Element.Selectors - Then open 'Choose compression type' and select 'No Compression' to have fully documented mootools source. This helps when developing own functionality and when trying do debug errors with Firebug. If mootools is extended by additional modules, please document this here in this file, by updating the selection scheme above. vdr-plugin-live/live/js/mootools/mootools.v1.11.js0000644000175000017500000036604312650773437021664 0ustar tobiastobias/* Script: Core.js Mootools - My Object Oriented javascript. License: MIT-style license. MooTools Copyright: copyright (c) 2007 Valerio Proietti, MooTools Credits: - Class is slightly based on Base.js (c) 2006 Dean Edwards, License - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. */ var MooTools = { version: '1.11' }; /* Section: Core Functions */ /* Function: $defined Returns true if the passed in value/object is defined, that means is not null or undefined. Arguments: obj - object to inspect */ function $defined(obj){ return (obj != undefined); }; /* Function: $type Returns the type of object that matches the element passed in. Arguments: obj - the object to inspect. Example: >var myString = 'hello'; >$type(myString); //returns "string" Returns: 'element' - if obj is a DOM element node 'textnode' - if obj is a DOM text node 'whitespace' - if obj is a DOM whitespace node 'arguments' - if obj is an arguments object 'object' - if obj is an object 'string' - if obj is a string 'number' - if obj is a number 'boolean' - if obj is a boolean 'function' - if obj is a function 'regexp' - if obj is a regular expression 'class' - if obj is a Class. (created with new Class, or the extend of another class). 'collection' - if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc. false - (boolean) if the object is not defined or none of the above. */ function $type(obj){ if (!$defined(obj)) return false; if (obj.htmlElement) return 'element'; var type = typeof obj; if (type == 'object' && obj.nodeName){ switch(obj.nodeType){ case 1: return 'element'; case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; } } if (type == 'object' || type == 'function'){ switch(obj.constructor){ case Array: return 'array'; case RegExp: return 'regexp'; case Class: return 'class'; } if (typeof obj.length == 'number'){ if (obj.item) return 'collection'; if (obj.callee) return 'arguments'; } } return type; }; /* Function: $merge merges a number of objects recursively without referencing them or their sub-objects. Arguments: any number of objects. Example: >var mergedObj = $merge(obj1, obj2, obj3); >//obj1, obj2, and obj3 are unaltered */ function $merge(){ var mix = {}; for (var i = 0; i < arguments.length; i++){ for (var property in arguments[i]){ var ap = arguments[i][property]; var mp = mix[property]; if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap); else mix[property] = ap; } } return mix; }; /* Function: $extend Copies all the properties from the second passed object to the first passed Object. If you do myWhatever.extend = $extend the first parameter will become myWhatever, and your extend function will only need one parameter. Example: (start code) var firstOb = { 'name': 'John', 'lastName': 'Doe' }; var secondOb = { 'age': '20', 'sex': 'male', 'lastName': 'Dorian' }; $extend(firstOb, secondOb); //firstOb will become: { 'name': 'John', 'lastName': 'Dorian', 'age': '20', 'sex': 'male' }; (end) Returns: The first object, extended. */ var $extend = function(){ var args = arguments; if (!args[1]) args = [this, args[0]]; for (var property in args[1]) args[0][property] = args[1][property]; return args[0]; }; /* Function: $native Will add a .extend method to the objects passed as a parameter, but the property passed in will be copied to the object's prototype only if non previously existent. Its handy if you dont want the .extend method of an object to overwrite existing methods. Used automatically in MooTools to implement Array/String/Function/Number methods to browser that dont support them whitout manual checking. Arguments: a number of classes/native javascript objects */ var $native = function(){ for (var i = 0, l = arguments.length; i < l; i++){ arguments[i].extend = function(props){ for (var prop in props){ if (!this.prototype[prop]) this.prototype[prop] = props[prop]; if (!this[prop]) this[prop] = $native.generic(prop); } }; } }; $native.generic = function(prop){ return function(bind){ return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1)); }; }; $native(Function, Array, String, Number); /* Function: $chk Returns true if the passed in value/object exists or is 0, otherwise returns false. Useful to accept zeroes. Arguments: obj - object to inspect */ function $chk(obj){ return !!(obj || obj === 0); }; /* Function: $pick Returns the first object if defined, otherwise returns the second. Arguments: obj - object to test picked - the default to return Example: (start code) function say(msg){ alert($pick(msg, 'no meessage supplied')); } (end) */ function $pick(obj, picked){ return $defined(obj) ? obj : picked; }; /* Function: $random Returns a random integer number between the two passed in values. Arguments: min - integer, the minimum value (inclusive). max - integer, the maximum value (inclusive). Returns: a random integer between min and max. */ function $random(min, max){ return Math.floor(Math.random() * (max - min + 1) + min); }; /* Function: $time Returns the current timestamp Returns: a timestamp integer. */ function $time(){ return new Date().getTime(); }; /* Function: $clear clears a timeout or an Interval. Returns: null Arguments: timer - the setInterval or setTimeout to clear. Example: >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. >myTimer = $clear(myTimer); //nevermind See also: , */ function $clear(timer){ clearTimeout(timer); clearInterval(timer); return null; }; /* Class: Abstract Abstract class, to be used as singleton. Will add .extend to any object Arguments: an object Returns: the object with an .extend property, equivalent to <$extend>. */ var Abstract = function(obj){ obj = obj || {}; obj.extend = $extend; return obj; }; //window, document var Window = new Abstract(window); var Document = new Abstract(document); document.head = document.getElementsByTagName('head')[0]; /* Class: window Some properties are attached to the window object by the browser detection. Note: browser detection is entirely object-based. We dont sniff. Properties: window.ie - will be set to true if the current browser is internet explorer (any). window.ie6 - will be set to true if the current browser is internet explorer 6. window.ie7 - will be set to true if the current browser is internet explorer 7. window.gecko - will be set to true if the current browser is Mozilla/Gecko. window.webkit - will be set to true if the current browser is Safari/Konqueror. window.webkit419 - will be set to true if the current browser is Safari2 / webkit till version 419. window.webkit420 - will be set to true if the current browser is Safari3 (Webkit SVN Build) / webkit over version 419. window.opera - is set to true by opera itself. */ window.xpath = !!(document.evaluate); if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true; else if (document.getBoxObjectFor != null) window.gecko = true; /*compatibility*/ window.khtml = window.webkit; Object.extend = $extend; /*end compatibility*/ //htmlelement if (typeof HTMLElement == 'undefined'){ var HTMLElement = function(){}; if (window.webkit) document.createElement("iframe"); //fixes safari HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {}; } HTMLElement.prototype.htmlElement = function(){}; //enables background image cache for internet explorer 6 if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){}; /* Script: Class.js Contains the Class Function, aims to ease the creation of reusable Classes. License: MIT-style license. */ /* Class: Class The base class object of the framework. Creates a new class, its initialize method will fire upon class instantiation. Initialize wont fire on instantiation when you pass *null*. Arguments: properties - the collection of properties that apply to the class. Example: (start code) var Cat = new Class({ initialize: function(name){ this.name = name; } }); var myCat = new Cat('Micia'); alert(myCat.name); //alerts 'Micia' (end) */ var Class = function(properties){ var klass = function(){ return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this; }; $extend(klass, this); klass.prototype = properties; klass.constructor = Class; return klass; }; /* Property: empty Returns an empty function */ Class.empty = function(){}; Class.prototype = { /* Property: extend Returns the copy of the Class extended with the passed in properties. Arguments: properties - the properties to add to the base class in this new Class. Example: (start code) var Animal = new Class({ initialize: function(age){ this.age = age; } }); var Cat = Animal.extend({ initialize: function(name, age){ this.parent(age); //will call the previous initialize; this.name = name; } }); var myCat = new Cat('Micia', 20); alert(myCat.name); //alerts 'Micia' alert(myCat.age); //alerts 20 (end) */ extend: function(properties){ var proto = new this(null); for (var property in properties){ var pp = proto[property]; proto[property] = Class.Merge(pp, properties[property]); } return new Class(proto); }, /* Property: implement Implements the passed in properties to the base Class prototypes, altering the base class, unlike . Arguments: properties - the properties to add to the base class. Example: (start code) var Animal = new Class({ initialize: function(age){ this.age = age; } }); Animal.implement({ setName: function(name){ this.name = name } }); var myAnimal = new Animal(20); myAnimal.setName('Micia'); alert(myAnimal.name); //alerts 'Micia' (end) */ implement: function(){ for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]); } }; //internal Class.Merge = function(previous, current){ if (previous && previous != current){ var type = $type(current); if (type != $type(previous)) return current; switch(type){ case 'function': var merged = function(){ this.parent = arguments.callee.parent; return current.apply(this, arguments); }; merged.parent = previous; return merged; case 'object': return $merge(previous, current); } } return current; }; /* Script: Class.Extras.js Contains common implementations for custom classes. In Mootools is implemented in , and and many more. License: MIT-style license. */ /* Class: Chain An "Utility" Class. Its methods can be implemented with into any . Currently implemented in , and . In for example, is used to execute a list of function, one after another, once the effect is completed. The functions will not be fired all togheter, but one every completion, to create custom complex animations. Example: (start code) var myFx = new Fx.Style('element', 'opacity'); myFx.start(1,0).chain(function(){ myFx.start(0,1); }).chain(function(){ myFx.start(1,0); }).chain(function(){ myFx.start(0,1); }); //the element will appear and disappear three times (end) */ var Chain = new Class({ /* Property: chain adds a function to the Chain instance stack. Arguments: fn - the function to append. */ chain: function(fn){ this.chains = this.chains || []; this.chains.push(fn); return this; }, /* Property: callChain Executes the first function of the Chain instance stack, then removes it. The first function will then become the second. */ callChain: function(){ if (this.chains && this.chains.length) this.chains.shift().delay(10, this); }, /* Property: clearChain Clears the stack of a Chain instance. */ clearChain: function(){ this.chains = []; } }); /* Class: Events An "Utility" Class. Its methods can be implemented with into any . In Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel. Events in a Class that implements can be either added as an option, or with addEvent. Never with .options.onEventName. Example: (start code) var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){ alert('the effect is completed'); }).addEvent('onComplete', function(){ alert('I told you the effect is completed'); }); myFx.start(0,1); //upon completion it will display the 2 alerts, in order. (end) Implementing: This class can be implemented into other classes to add the functionality to them. Goes well with the class. Example: (start code) var Widget = new Class({ initialize: function(){}, finish: function(){ this.fireEvent('onComplete'); } }); Widget.implement(new Events); //later... var myWidget = new Widget(); myWidget.addEvent('onComplete', myfunction); (end) */ var Events = new Class({ /* Property: addEvent adds an event to the stack of events of the Class instance. Arguments: type - string; the event name (e.g. 'onComplete') fn - function to execute */ addEvent: function(type, fn){ if (fn != Class.empty){ this.$events = this.$events || {}; this.$events[type] = this.$events[type] || []; this.$events[type].include(fn); } return this; }, /* Property: fireEvent fires all events of the specified type in the Class instance. Arguments: type - string; the event name (e.g. 'onComplete') args - array or single object; arguments to pass to the function; if more than one argument, must be an array delay - (integer) delay (in ms) to wait to execute the event Example: (start code) var Widget = new Class({ initialize: function(arg1, arg2){ ... this.fireEvent("onInitialize", [arg1, arg2], 50); } }); Widget.implement(new Events); (end) */ fireEvent: function(type, args, delay){ if (this.$events && this.$events[type]){ this.$events[type].each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); } return this; }, /* Property: removeEvent removes an event from the stack of events of the Class instance. Arguments: type - string; the event name (e.g. 'onComplete') fn - function that was added */ removeEvent: function(type, fn){ if (this.$events && this.$events[type]) this.$events[type].remove(fn); return this; } }); /* Class: Options An "Utility" Class. Its methods can be implemented with into any . Used to automate the options settings, also adding Class when the option begins with on. Example: (start code) var Widget = new Class({ options: { color: '#fff', size: { width: 100 height: 100 } }, initialize: function(options){ this.setOptions(options); } }); Widget.implement(new Options); //later... var myWidget = new Widget({ color: '#f00', size: { width: 200 } }); //myWidget.options = {color: #f00, size: {width: 200, height: 100}} (end) */ var Options = new Class({ /* Property: setOptions sets this.options Arguments: defaults - object; the default set of options options - object; the user entered options. can be empty too. Note: if your Class has implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event. */ setOptions: function(){ this.options = $merge.apply(null, [this.options].extend(arguments)); if (this.addEvent){ for (var option in this.options){ if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]); } } return this; } }); /* Script: Array.js Contains Array prototypes, <$A>, <$each> License: MIT-style license. */ /* Class: Array A collection of The Array Object prototype methods. */ //custom methods Array.extend({ /* Property: forEach Iterates through an array; This method is only available for browsers without native *forEach* support. For more info see *forEach* executes the provided function (callback) once for each element present in the array. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - the object to bind "this" to (see ) Example: >['apple','banana','lemon'].each(function(item, index){ > alert(index + " = " + item); //alerts "0 = apple" etc. >}, bindObj); //optional second arg for binding, not used here */ forEach: function(fn, bind){ for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this); }, /* Property: filter This method is provided only for browsers without native *filter* support. For more info see *filter* calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array. Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - the object to bind "this" to (see ) Example: >var biggerThanTwenty = [10,3,25,100].filter(function(item, index){ > return item > 20; >}); >//biggerThanTwenty = [25,100] */ filter: function(fn, bind){ var results = []; for (var i = 0, j = this.length; i < j; i++){ if (fn.call(bind, this[i], i, this)) results.push(this[i]); } return results; }, /* Property: map This method is provided only for browsers without native *map* support. For more info see *map* calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - the object to bind "this" to (see ) Example: >var timesTwo = [1,2,3].map(function(item, index){ > return item*2; >}); >//timesTwo = [2,4,6]; */ map: function(fn, bind){ var results = []; for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this); return results; }, /* Property: every This method is provided only for browsers without native *every* support. For more info see *every* executes the provided callback function once for each element present in the array until it finds one where callback returns a false value. If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - the object to bind "this" to (see ) Example: >var areAllBigEnough = [10,4,25,100].every(function(item, index){ > return item > 20; >}); >//areAllBigEnough = false */ every: function(fn, bind){ for (var i = 0, j = this.length; i < j; i++){ if (!fn.call(bind, this[i], i, this)) return false; } return true; }, /* Property: some This method is provided only for browsers without native *some* support. For more info see *some* executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - the object to bind "this" to (see ) Example: >var isAnyBigEnough = [10,4,25,100].some(function(item, index){ > return item > 20; >}); >//isAnyBigEnough = true */ some: function(fn, bind){ for (var i = 0, j = this.length; i < j; i++){ if (fn.call(bind, this[i], i, this)) return true; } return false; }, /* Property: indexOf This method is provided only for browsers without native *indexOf* support. For more info see *indexOf* compares a search element to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator). Arguments: item - any type of object; element to locate in the array from - integer; optional; the index of the array at which to begin the search (defaults to 0) Example: >['apple','lemon','banana'].indexOf('lemon'); //returns 1 >['apple','lemon'].indexOf('banana'); //returns -1 */ indexOf: function(item, from){ var len = this.length; for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ if (this[i] === item) return i; } return -1; }, /* Property: each Same as . Arguments: fn - function to execute with each item in the array; passed the item and the index of that item in the array bind - optional, the object that the "this" of the function will refer to. Example: >var Animals = ['Cat', 'Dog', 'Coala']; >Animals.each(function(animal){ > document.write(animal) >}); */ /* Property: copy returns a copy of the array. Returns: a new array which is a copy of the current one. Arguments: start - integer; optional; the index where to start the copy, default is 0. If negative, it is taken as the offset from the end of the array. length - integer; optional; the number of elements to copy. By default, copies all elements from start to the end of the array. Example: >var letters = ["a","b","c"]; >var copy = letters.copy(); // ["a","b","c"] (new instance) */ copy: function(start, length){ start = start || 0; if (start < 0) start = this.length + start; length = length || (this.length - start); var newArray = []; for (var i = 0; i < length; i++) newArray[i] = this[start++]; return newArray; }, /* Property: remove Removes all occurrences of an item from the array. Arguments: item - the item to remove Returns: the Array with all occurrences of the item removed. Example: >["1","2","3","2"].remove("2") // ["1","3"]; */ remove: function(item){ var i = 0; var len = this.length; while (i < len){ if (this[i] === item){ this.splice(i, 1); len--; } else { i++; } } return this; }, /* Property: contains Tests an array for the presence of an item. Arguments: item - the item to search for in the array. from - integer; optional; the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array. Returns: true - the item was found false - it wasn't Example: >["a","b","c"].contains("a"); // true >["a","b","c"].contains("d"); // false */ contains: function(item, from){ return this.indexOf(item, from) != -1; }, /* Property: associate Creates an object with key-value pairs based on the array of keywords passed in and the current content of the array. Arguments: keys - the array of keywords. Example: (start code) var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; var Speeches = Animals.associate(Speech); //Speeches['Miao'] is now Cat. //Speeches['Bau'] is now Dog. //... (end) */ associate: function(keys){ var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; }, /* Property: extend Extends an array with another one. Arguments: array - the array to extend ours with Example: >var Animals = ['Cat', 'Dog', 'Coala']; >Animals.extend(['Lizard']); >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; */ extend: function(array){ for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); return this; }, /* Property: merge merges an array in another array, without duplicates. (case- and type-sensitive) Arguments: array - the array to merge from. Example: >['Cat','Dog'].merge(['Dog','Coala']); //returns ['Cat','Dog','Coala'] */ merge: function(array){ for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); return this; }, /* Property: include includes the passed in element in the array, only if its not already present. (case- and type-sensitive) Arguments: item - item to add to the array (if not present) Example: >['Cat','Dog'].include('Dog'); //returns ['Cat','Dog'] >['Cat','Dog'].include('Coala'); //returns ['Cat','Dog','Coala'] */ include: function(item){ if (!this.contains(item)) this.push(item); return this; }, /* Property: getRandom returns a random item in the Array */ getRandom: function(){ return this[$random(0, this.length - 1)] || null; }, /* Property: getLast returns the last item in the Array */ getLast: function(){ return this[this.length - 1] || null; } }); //copies Array.prototype.each = Array.prototype.forEach; Array.each = Array.forEach; /* Section: Utility Functions */ /* Function: $A() Same as , but as function. Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. Example: (start code) function myFunction(){ $A(arguments).each(argument, function(){ alert(argument); }); }; //the above will alert all the arguments passed to the function myFunction. (end) */ function $A(array){ return Array.copy(array); }; /* Function: $each Use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, arguments of a function, or an object. Arguments: iterable - an iterable element or an objct. function - function to apply to the iterable. bind - optional, the 'this' of the function will refer to this object. Function argument: The function argument will be passed the following arguments. item - the current item in the iterator being procesed index - integer; the index of the item, or key in case of an object. Examples: (start code) $each(['Sun','Mon','Tue'], function(day, index){ alert('name:' + day + ', index: ' + index); }); //alerts "name: Sun, index: 0", "name: Mon, index: 1", etc. //over an object $each({first: "Sunday", second: "Monday", third: "Tuesday"}, function(value, key){ alert("the " + key + " day of the week is " + value); }); //alerts "the first day of the week is Sunday", //"the second day of the week is Monday", etc. (end) */ function $each(iterable, fn, bind){ if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){ Array.forEach(iterable, fn, bind); } else { for (var name in iterable) fn.call(bind || iterable, iterable[name], name); } }; /*compatibility*/ Array.prototype.test = Array.prototype.contains; /*end compatibility*/ /* Script: String.js Contains String prototypes. License: MIT-style license. */ /* Class: String A collection of The String Object prototype methods. */ String.extend({ /* Property: test Tests a string with a regular expression. Arguments: regex - a string or regular expression object, the regular expression you want to match the string with params - optional, if first parameter is a string, any parameters you want to pass to the regex ('g' has no effect) Returns: true if a match for the regular expression is found in the string, false if not. See Example: >"I like cookies".test("cookie"); // returns true >"I like cookies".test("COOKIE", "i") // ignore case, returns true >"I like cookies".test("cake"); // returns false */ test: function(regex, params){ return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this); }, /* Property: toInt parses a string to an integer. Returns: either an int or "NaN" if the string is not a number. Example: >var value = "10px".toInt(); // value is 10 */ toInt: function(){ return parseInt(this, 10); }, /* Property: toFloat parses a string to an float. Returns: either a float or "NaN" if the string is not a number. Example: >var value = "10.848".toFloat(); // value is 10.848 */ toFloat: function(){ return parseFloat(this); }, /* Property: camelCase Converts a hiphenated string to a camelcase string. Example: >"I-like-cookies".camelCase(); //"ILikeCookies" Returns: the camel cased string */ camelCase: function(){ return this.replace(/-\D/g, function(match){ return match.charAt(1).toUpperCase(); }); }, /* Property: hyphenate Converts a camelCased string to a hyphen-ated string. Example: >"ILikeCookies".hyphenate(); //"I-like-cookies" */ hyphenate: function(){ return this.replace(/\w[A-Z]/g, function(match){ return (match.charAt(0) + '-' + match.charAt(1).toLowerCase()); }); }, /* Property: capitalize Converts the first letter in each word of a string to Uppercase. Example: >"i like cookies".capitalize(); //"I Like Cookies" Returns: the capitalized string */ capitalize: function(){ return this.replace(/\b[a-z]/g, function(match){ return match.toUpperCase(); }); }, /* Property: trim Trims the leading and trailing spaces off a string. Example: >" i like cookies ".trim() //"i like cookies" Returns: the trimmed string */ trim: function(){ return this.replace(/^\s+|\s+$/g, ''); }, /* Property: clean trims () a string AND removes all the double spaces in a string. Returns: the cleaned string Example: >" i like cookies \n\n".clean() //"i like cookies" */ clean: function(){ return this.replace(/\s{2,}/g, ' ').trim(); }, /* Property: rgbToHex Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255,255,255)" or "rgba(255,255,255,1)"; Arguments: array - boolean value, defaults to false. Use true if you want the array ['FF','33','00'] as output instead of "#FF3300" Returns: hex string or array. returns "transparent" if the output is set as string and the fourth value of rgba in input string is 0. Example: >"rgb(17,34,51)".rgbToHex(); //"#112233" >"rgba(17,34,51,0)".rgbToHex(); //"transparent" >"rgb(17,34,51)".rgbToHex(true); //['11','22','33'] */ rgbToHex: function(array){ var rgb = this.match(/\d{1,3}/g); return (rgb) ? rgb.rgbToHex(array) : false; }, /* Property: hexToRgb Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); Arguments: array - boolean value, defaults to false. Use true if you want the array [255,255,255] as output instead of "rgb(255,255,255)"; Returns: rgb string or array. Example: >"#112233".hexToRgb(); //"rgb(17,34,51)" >"#112233".hexToRgb(true); //[17,34,51] */ hexToRgb: function(array){ var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); return (hex) ? hex.slice(1).hexToRgb(array) : false; }, /* Property: contains checks if the passed in string is contained in the String. also accepts an optional second parameter, to check if the string is contained in a list of separated values. Example: >'a b c'.contains('c', ' '); //true >'a bc'.contains('bc'); //true >'a bc'.contains('b', ' '); //false */ contains: function(string, s){ return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1; }, /* Property: escapeRegExp Returns string with escaped regular expression characters Example: >var search = 'animals.sheeps[1]'.escapeRegExp(); // search is now 'animals\.sheeps\[1\]' Returns: Escaped string */ escapeRegExp: function(){ return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); } }); Array.extend({ /* Property: rgbToHex see , but as an array method. */ rgbToHex: function(array){ if (this.length < 3) return false; if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; var hex = []; for (var i = 0; i < 3; i++){ var bit = (this[i] - 0).toString(16); hex.push((bit.length == 1) ? '0' + bit : bit); } return array ? hex : '#' + hex.join(''); }, /* Property: hexToRgb same as , but as an array method. */ hexToRgb: function(array){ if (this.length != 3) return false; var rgb = []; for (var i = 0; i < 3; i++){ rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16)); } return array ? rgb : 'rgb(' + rgb.join(',') + ')'; } }); /* Script: Function.js Contains Function prototypes and utility functions . License: MIT-style license. Credits: - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license */ /* Class: Function A collection of The Function Object prototype methods. */ Function.extend({ /* Property: create Main function to create closures. Returns: a function. Arguments: options - An Options object. Options: bind - The object that the "this" of the function will refer to. Default is the current function. event - If set to true, the function will act as an event listener and receive an event as first argument. If set to a class name, the function will receive a new instance of this class (with the event passed as argument's constructor) as first argument. Default is false. arguments - A single argument or array of arguments that will be passed to the function when called. If both the event and arguments options are set, the event is passed as first argument and the arguments array will follow. Default is no custom arguments, the function will receive the standard arguments when called. delay - Numeric value: if set, the returned function will delay the actual execution by this amount of milliseconds and return a timer handle when called. Default is no delay. periodical - Numeric value: if set, the returned function will periodically perform the actual execution with this specified interval and return a timer handle when called. Default is no periodical execution. attempt - If set to true, the returned function will try to execute and return either the results or false on error. Default is false. */ create: function(options){ var fn = this; options = $merge({ 'bind': fn, 'event': false, 'arguments': null, 'delay': false, 'periodical': false, 'attempt': false }, options); if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments]; return function(event){ var args; if (options.event){ event = event || window.event; args = [(options.event === true) ? event : new options.event(event)]; if (options.arguments) args.extend(options.arguments); } else args = options.arguments || arguments; var returns = function(){ return fn.apply($pick(options.bind, fn), args); }; if (options.delay) return setTimeout(returns, options.delay); if (options.periodical) return setInterval(returns, options.periodical); if (options.attempt) try {return returns();} catch(err){return false;}; return returns(); }; }, /* Property: pass Shortcut to create closures with arguments and bind. Returns: a function. Arguments: args - the arguments passed. must be an array if arguments > 1 bind - optional, the object that the "this" of the function will refer to. Example: >myFunction.pass([arg1, arg2], myElement); */ pass: function(args, bind){ return this.create({'arguments': args, 'bind': bind}); }, /* Property: attempt Tries to execute the function, returns either the result of the function or false on error. Arguments: args - the arguments passed. must be an array if arguments > 1 bind - optional, the object that the "this" of the function will refer to. Example: >myFunction.attempt([arg1, arg2], myElement); */ attempt: function(args, bind){ return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); }, /* Property: bind method to easily create closures with "this" altered. Arguments: bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Returns: a function. Example: >function myFunction(){ > this.setStyle('color', 'red'); > // note that 'this' here refers to myFunction, not an element > // we'll need to bind this function to the element we want to alter >}; >var myBoundFunction = myFunction.bind(myElement); >myBoundFunction(); // this will make the element myElement red. */ bind: function(bind, args){ return this.create({'bind': bind, 'arguments': args}); }, /* Property: bindAsEventListener cross browser method to pass event firer Arguments: bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Returns: a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. Example: >function myFunction(event){ > alert(event.clientx) //returns the coordinates of the mouse.. >}; >myElement.onclick = myFunction.bindAsEventListener(myElement); */ bindAsEventListener: function(bind, args){ return this.create({'bind': bind, 'event': true, 'arguments': args}); }, /* Property: delay Delays the execution of a function by a specified duration. Arguments: delay - the duration to wait in milliseconds. bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Example: >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it >(function(){alert('one second later...')}).delay(1000); //wait a second and alert */ delay: function(delay, bind, args){ return this.create({'delay': delay, 'bind': bind, 'arguments': args})(); }, /* Property: periodical Executes a function in the specified intervals of time Arguments: interval - the duration of the intervals between executions. bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 */ periodical: function(interval, bind, args){ return this.create({'periodical': interval, 'bind': bind, 'arguments': args})(); } }); /* Script: Number.js Contains the Number prototypes. License: MIT-style license. */ /* Class: Number A collection of The Number Object prototype methods. */ Number.extend({ /* Property: toInt Returns this number; useful because toInt must work on both Strings and Numbers. */ toInt: function(){ return parseInt(this); }, /* Property: toFloat Returns this number as a float; useful because toFloat must work on both Strings and Numbers. */ toFloat: function(){ return parseFloat(this); }, /* Property: limit Limits the number. Arguments: min - number, minimum value max - number, maximum value Returns: the number in the given limits. Example: >(12).limit(2, 6.5) // returns 6.5 >(-4).limit(2, 6.5) // returns 2 >(4.3).limit(2, 6.5) // returns 4.3 */ limit: function(min, max){ return Math.min(max, Math.max(min, this)); }, /* Property: round Returns the number rounded to specified precision. Arguments: precision - integer, number of digits after the decimal point. Can also be negative or zero (default). Example: >12.45.round() // returns 12 >12.45.round(1) // returns 12.5 >12.45.round(-1) // returns 10 Returns: The rounded number. */ round: function(precision){ precision = Math.pow(10, precision || 0); return Math.round(this * precision) / precision; }, /* Property: times Executes a passed in function the specified number of times Arguments: function - the function to be executed on each iteration of the loop Example: >(4).times(alert); */ times: function(fn){ for (var i = 0; i < this; i++) fn(i); } }); /* Script: Element.js Contains useful Element prototypes, to be used with the dollar function <$>. License: MIT-style license. Credits: - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license */ /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ var Element = new Class({ /* Property: initialize Creates a new element of the type passed in. Arguments: el - string; the tag name for the element you wish to create. you can also pass in an element reference, in which case it will be extended. props - object; the properties you want to add to your element. Accepts the same keys as , but also allows events and styles Props: the key styles will be used as setStyles, the key events will be used as addEvents. any other key is used as setProperty. Example: (start code) new Element('a', { 'styles': { 'display': 'block', 'border': '1px solid black' }, 'events': { 'click': function(){ //aaa }, 'mousedown': function(){ //aaa } }, 'class': 'myClassSuperClass', 'href': 'http://mad4milk.net' }); (end) */ initialize: function(el, props){ if ($type(el) == 'string'){ if (window.ie && props && (props.name || props.type)){ var name = (props.name) ? ' name="' + props.name + '"' : ''; var type = (props.type) ? ' type="' + props.type + '"' : ''; delete props.name; delete props.type; el = '<' + el + name + type + '>'; } el = document.createElement(el); } el = $(el); return (!props || !el) ? el : el.set(props); } }); /* Class: Elements - Every dom function such as <$$>, or in general every function that returns a collection of nodes in mootools, returns them as an Elements class. - The purpose of the Elements class is to allow methods to work also on array. - Elements is also an Array, so it accepts all the methods. - Every node of the Elements instance is already extended with <$>. Example: >$$('myselector').each(function(el){ > //... >}); some iterations here, $$('myselector') is also an array. >$$('myselector').setStyle('color', 'red'); every element returned by $$('myselector') also accepts methods, in this example every element will be made red. */ var Elements = new Class({ initialize: function(elements){ return (elements) ? $extend(elements, this) : this; } }); Elements.extend = function(props){ for (var prop in props){ this.prototype[prop] = props[prop]; this[prop] = $native.generic(prop); } }; /* Section: Utility Functions Function: $ returns the element passed in with all the Element prototypes applied. Arguments: el - a reference to an actual element or a string representing the id of an element Example: >$('myElement') // gets a DOM element by id with all the Element prototypes applied. >var div = document.getElementById('myElement'); >$(div) //returns an Element also with all the mootools extentions applied. You'll use this when you aren't sure if a variable is an actual element or an id, as well as just shorthand for document.getElementById(). Returns: a DOM element or false (if no id was found). Note: you need to call $ on an element only once to get all the prototypes. But its no harm to call it multiple times, as it will detect if it has been already extended. */ function $(el){ if (!el) return null; if (el.htmlElement) return Garbage.collect(el); if ([window, document].contains(el)) return el; var type = $type(el); if (type == 'string'){ el = document.getElementById(el); type = (el) ? 'element' : false; } if (type != 'element') return null; if (el.htmlElement) return Garbage.collect(el); if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el; $extend(el, Element.prototype); el.htmlElement = function(){}; return Garbage.collect(el); }; /* Function: $$ Selects, and extends DOM elements. Elements arrays returned with $$ will also accept all the methods. The return type of element methods run through $$ is always an array. If the return array is only made by elements, $$ will be applied automatically. Arguments: HTML Collections, arrays of elements, arrays of strings as element ids, elements, strings as selectors. Any number of the above as arguments are accepted. Note: if you load , $$ will also accept CSS Selectors, otherwise the only selectors supported are tag names. Example: >$$('a') //an array of all anchor tags on the page >$$('a', 'b') //an array of all anchor and bold tags on the page >$$('#myElement') //array containing only the element with id = myElement. (only with ) >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" >//within the DOM element with id "myElement" (only with ) >$$(myelement, myelement2, 'a', ['myid', myid2, 'myid3'], document.getElementsByTagName('div')) //an array containing: >// the element referenced as myelement if existing, >// the element referenced as myelement2 if existing, >// all the elements with a as tag in the page, >// the element with id = myid if existing >// the element with id = myid2 if existing >// the element with id = myid3 if existing >// all the elements with div as tag in the page Returns: array - array of all the dom elements matched, extended with <$>. Returns as . */ document.getElementsBySelector = document.getElementsByTagName; function $$(){ var elements = []; for (var i = 0, j = arguments.length; i < j; i++){ var selector = arguments[i]; switch($type(selector)){ case 'element': elements.push(selector); case 'boolean': break; case false: break; case 'string': selector = document.getElementsBySelector(selector, true); default: elements.extend(selector); } } return $$.unique(elements); }; $$.unique = function(array){ var elements = []; for (var i = 0, l = array.length; i < l; i++){ if (array[i].$included) continue; var element = $(array[i]); if (element && !element.$included){ element.$included = true; elements.push(element); } } for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null; return new Elements(elements); }; Elements.Multi = function(property){ return function(){ var args = arguments; var items = []; var elements = true; for (var i = 0, j = this.length, returns; i < j; i++){ returns = this[i][property].apply(this[i], args); if ($type(returns) != 'element') elements = false; items.push(returns); }; return (elements) ? $$.unique(items) : items; }; }; Element.extend = function(properties){ for (var property in properties){ HTMLElement.prototype[property] = properties[property]; Element.prototype[property] = properties[property]; Element[property] = $native.generic(property); var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property; Elements.prototype[elementsProperty] = Elements.Multi(property); } }; /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.extend({ /* Property: set you can set events, styles and properties with this shortcut. same as calling new Element. */ set: function(props){ for (var prop in props){ var val = props[prop]; switch(prop){ case 'styles': this.setStyles(val); break; case 'events': if (this.addEvents) this.addEvents(val); break; case 'properties': this.setProperties(val); break; default: this.setProperty(prop, val); } } return this; }, inject: function(el, where){ el = $(el); switch(where){ case 'before': el.parentNode.insertBefore(this, el); break; case 'after': var next = el.getNext(); if (!next) el.parentNode.appendChild(this); else el.parentNode.insertBefore(this, next); break; case 'top': var first = el.firstChild; if (first){ el.insertBefore(this, first); break; } default: el.appendChild(this); } return this; }, /* Property: injectBefore Inserts the Element before the passed element. Arguments: el - an element reference or the id of the element to be injected in. Example: >html: >
>
>js: >$('mySecondElement').injectBefore('myElement'); >resulting html: >
>
*/ injectBefore: function(el){ return this.inject(el, 'before'); }, /* Property: injectAfter Same as , but inserts the element after. */ injectAfter: function(el){ return this.inject(el, 'after'); }, /* Property: injectInside Same as , but inserts the element inside. */ injectInside: function(el){ return this.inject(el, 'bottom'); }, /* Property: injectTop Same as , but inserts the element inside, at the top. */ injectTop: function(el){ return this.inject(el, 'top'); }, /* Property: adopt Inserts the passed elements inside the Element. Arguments: accepts elements references, element ids as string, selectors ($$('stuff')) / array of elements, array of ids as strings and collections. */ adopt: function(){ var elements = []; $each(arguments, function(argument){ elements = elements.concat(argument); }); $$(elements).inject(this); return this; }, /* Property: remove Removes the Element from the DOM. Example: >$('myElement').remove() //bye bye */ remove: function(){ return this.parentNode.removeChild(this); }, /* Property: clone Clones the Element and returns the cloned one. Arguments: contents - boolean, when true the Element is cloned with childNodes, default true Returns: the cloned element Example: >var clone = $('myElement').clone().injectAfter('myElement'); >//clones the Element and append the clone after the Element. */ clone: function(contents){ var el = $(this.cloneNode(contents !== false)); if (!el.$events) return el; el.$events = {}; for (var type in this.$events) el.$events[type] = { 'keys': $A(this.$events[type].keys), 'values': $A(this.$events[type].values) }; return el.removeEvents(); }, /* Property: replaceWith Replaces the Element with an element passed. Arguments: el - a string representing the element to be injected in (myElementId, or div), or an element reference. If you pass div or another tag, the element will be created. Returns: the passed in element Example: >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. */ replaceWith: function(el){ el = $(el); this.parentNode.replaceChild(el, this); return el; }, /* Property: appendText Appends text node to a DOM element. Arguments: text - the text to append. Example: >
hey
>$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" */ appendText: function(text){ this.appendChild(document.createTextNode(text)); return this; }, /* Property: hasClass Tests the Element to see if it has the passed in className. Returns: true - the Element has the class false - it doesn't Arguments: className - string; the class name to test. Example: >
>$('myElement').hasClass('testClass'); //returns true */ hasClass: function(className){ return this.className.contains(className, ' '); }, /* Property: addClass Adds the passed in class to the Element, if the element doesnt already have it. Arguments: className - string; the class name to add Example: >
>$('myElement').addClass('newClass'); //
*/ addClass: function(className){ if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); return this; }, /* Property: removeClass Works like , but removes the class from the element. */ removeClass: function(className){ this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean(); return this; }, /* Property: toggleClass Adds or removes the passed in class name to the element, depending on if it's present or not. Arguments: className - the class to add or remove Example: >
>$('myElement').toggleClass('myClass'); >
>$('myElement').toggleClass('myClass'); >
*/ toggleClass: function(className){ return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); }, /* Property: setStyle Sets a css property to the Element. Arguments: property - the property to set value - the value to which to set it; for numeric values that require "px" you can pass an integer Example: >$('myElement').setStyle('width', '300px'); //the width is now 300px >$('myElement').setStyle('width', 300); //the width is now 300px */ setStyle: function(property, value){ switch(property){ case 'opacity': return this.setOpacity(parseFloat(value)); case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat'; } property = property.camelCase(); switch($type(value)){ case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break; case 'array': value = 'rgb(' + value.join(',') + ')'; } this.style[property] = value; return this; }, /* Property: setStyles Applies a collection of styles to the Element. Arguments: source - an object or string containing all the styles to apply. When its a string it overrides old style. Examples: >$('myElement').setStyles({ > border: '1px solid #000', > width: 300, > height: 400 >}); OR >$('myElement').setStyles('border: 1px solid #000; width: 300px; height: 400px;'); */ setStyles: function(source){ switch($type(source)){ case 'object': Element.setMany(this, 'setStyle', source); break; case 'string': this.style.cssText = source; } return this; }, /* Property: setOpacity Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity > 0. Arguments: opacity - float; Accepts values from 0 to 1. Example: >$('myElement').setOpacity(0.5) //make it 50% transparent */ setOpacity: function(opacity){ if (opacity == 0){ if (this.style.visibility != "hidden") this.style.visibility = "hidden"; } else { if (this.style.visibility != "visible") this.style.visibility = "visible"; } if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")"; this.style.opacity = this.$tmp.opacity = opacity; return this; }, /* Property: getStyle Returns the style of the Element given the property passed in. Arguments: property - the css style property you want to retrieve Example: >$('myElement').getStyle('width'); //returns "400px" >//but you can also use >$('myElement').getStyle('width').toInt(); //returns 400 Returns: the style as a string */ getStyle: function(property){ property = property.camelCase(); var result = this.style[property]; if (!$chk(result)){ if (property == 'opacity') return this.$tmp.opacity; result = []; for (var style in Element.Styles){ if (property == style){ Element.Styles[style].each(function(s){ var style = this.getStyle(s); result.push(parseInt(style) ? style : '0px'); }, this); if (property == 'border'){ var every = result.every(function(bit){ return (bit == result[0]); }); return (every) ? result[0] : false; } return result.join(' '); } } if (property.contains('border')){ if (Element.Styles.border.contains(property)){ return ['Width', 'Style', 'Color'].map(function(p){ return this.getStyle(property + p); }, this).join(' '); } else if (Element.borderShort.contains(property)){ return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){ return this.getStyle('border' + p + property.replace('border', '')); }, this).join(' '); } } if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); else if (this.currentStyle) result = this.currentStyle[property]; } if (window.ie) result = Element.fixStyle(property, result, this); if (result && property.test(/color/i) && result.contains('rgb')){ return result.split('rgb').splice(1,4).map(function(color){ return color.rgbToHex(); }).join(' '); } return result; }, /* Property: getStyles Returns an object of styles of the Element for each argument passed in. Arguments: properties - strings; any number of style properties Example: >$('myElement').getStyles('width','height','padding'); >//returns an object like: >{width: "10px", height: "10px", padding: "10px 0px 10px 0px"} */ getStyles: function(){ return Element.getMany(this, 'getStyle', arguments); }, walk: function(brother, start){ brother += 'Sibling'; var el = (start) ? this[start] : this[brother]; while (el && $type(el) != 'element') el = el[brother]; return $(el); }, /* Property: getPrevious Returns the previousSibling of the Element, excluding text nodes. Example: >$('myElement').getPrevious(); //get the previous DOM element from myElement Returns: the sibling element or undefined if none found. */ getPrevious: function(){ return this.walk('previous'); }, /* Property: getNext Works as Element.getPrevious, but tries to find the nextSibling. */ getNext: function(){ return this.walk('next'); }, /* Property: getFirst Works as , but tries to find the firstChild. */ getFirst: function(){ return this.walk('next', 'firstChild'); }, /* Property: getLast Works as , but tries to find the lastChild. */ getLast: function(){ return this.walk('previous', 'lastChild'); }, /* Property: getParent returns the $(element.parentNode) */ getParent: function(){ return $(this.parentNode); }, /* Property: getChildren returns all the $(element.childNodes), excluding text nodes. Returns as . */ getChildren: function(){ return $$(this.childNodes); }, /* Property: hasChild returns true if the passed in element is a child of the $(element). */ hasChild: function(el){ return !!$A(this.getElementsByTagName('*')).contains(el); }, /* Property: getProperty Gets the an attribute of the Element. Arguments: property - string; the attribute to retrieve Example: >$('myImage').getProperty('src') // returns whatever.gif Returns: the value, or an empty string */ getProperty: function(property){ var index = Element.Properties[property]; if (index) return this[index]; var flag = Element.PropertiesIFlag[property] || 0; if (!window.ie || flag) return this.getAttribute(property, flag); var node = this.attributes[property]; return (node) ? node.nodeValue : null; }, /* Property: removeProperty Removes an attribute from the Element Arguments: property - string; the attribute to remove */ removeProperty: function(property){ var index = Element.Properties[property]; if (index) this[index] = ''; else this.removeAttribute(property); return this; }, /* Property: getProperties same as , but for properties */ getProperties: function(){ return Element.getMany(this, 'getProperty', arguments); }, /* Property: setProperty Sets an attribute for the Element. Arguments: property - string; the property to assign the value passed in value - the value to assign to the property passed in Example: >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source */ setProperty: function(property, value){ var index = Element.Properties[property]; if (index) this[index] = value; else this.setAttribute(property, value); return this; }, /* Property: setProperties Sets numerous attributes for the Element. Arguments: source - an object with key/value pairs. Example: (start code) $('myElement').setProperties({ src: 'whatever.gif', alt: 'whatever dude' }); whatever dude (end) */ setProperties: function(source){ return Element.setMany(this, 'setProperty', source); }, /* Property: setHTML Sets the innerHTML of the Element. Arguments: html - string; the new innerHTML for the element. Example: >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML */ setHTML: function(){ this.innerHTML = $A(arguments).join(''); return this; }, /* Property: setText Sets the inner text of the Element. Arguments: text - string; the new text content for the element. Example: >$('myElement').setText('some text') //the text of myElement is now = 'some text' */ setText: function(text){ var tag = this.getTag(); if (['style', 'script'].contains(tag)){ if (window.ie){ if (tag == 'style') this.styleSheet.cssText = text; else if (tag == 'script') this.setProperty('text', text); return this; } else { this.removeChild(this.firstChild); return this.appendText(text); } } this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text; return this; }, /* Property: getText Gets the inner text of the Element. */ getText: function(){ var tag = this.getTag(); if (['style', 'script'].contains(tag)){ if (window.ie){ if (tag == 'style') return this.styleSheet.cssText; else if (tag == 'script') return this.getProperty('text'); } else { return this.innerHTML; } } return ($pick(this.innerText, this.textContent)); }, /* Property: getTag Returns the tagName of the element in lower case. Example: >$('myImage').getTag() // returns 'img' Returns: The tag name in lower case */ getTag: function(){ return this.tagName.toLowerCase(); }, /* Property: empty Empties an element of all its children. Example: >$('myDiv').empty() // empties the Div and returns it Returns: The element. */ empty: function(){ Garbage.trash(this.getElementsByTagName('*')); return this.setHTML(''); } }); Element.fixStyle = function(property, result, element){ if ($chk(parseInt(result))) return result; if (['height', 'width'].contains(property)){ var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom']; var size = 0; values.each(function(value){ size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt(); }); return element['offset' + property.capitalize()] - size + 'px'; } else if (property.test(/border(.+)Width|margin|padding/)){ return '0px'; } return result; }; Element.Styles = {'border': [], 'padding': [], 'margin': []}; ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ for (var style in Element.Styles) Element.Styles[style].push(style + direction); }); Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor']; Element.getMany = function(el, method, keys){ var result = {}; $each(keys, function(key){ result[key] = el[method](key); }); return result; }; Element.setMany = function(el, method, pairs){ for (var key in pairs) el[method](key, pairs[key]); return el; }; Element.Properties = new Abstract({ 'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan', 'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength', 'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value', 'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected' }); Element.PropertiesIFlag = { 'href': 2, 'src': 2 }; Element.Methods = { Listeners: { addListener: function(type, fn){ if (this.addEventListener) this.addEventListener(type, fn, false); else this.attachEvent('on' + type, fn); return this; }, removeListener: function(type, fn){ if (this.removeEventListener) this.removeEventListener(type, fn, false); else this.detachEvent('on' + type, fn); return this; } } }; window.extend(Element.Methods.Listeners); document.extend(Element.Methods.Listeners); Element.extend(Element.Methods.Listeners); var Garbage = { elements: [], collect: function(el){ if (!el.$tmp){ Garbage.elements.push(el); el.$tmp = {'opacity': 1}; } return el; }, trash: function(elements){ for (var i = 0, j = elements.length, el; i < j; i++){ if (!(el = elements[i]) || !el.$tmp) continue; if (el.$events) el.fireEvent('trash').removeEvents(); for (var p in el.$tmp) el.$tmp[p] = null; for (var d in Element.prototype) el[d] = null; Garbage.elements[Garbage.elements.indexOf(el)] = null; el.htmlElement = el.$tmp = el = null; } Garbage.elements.remove(null); }, empty: function(){ Garbage.collect(window); Garbage.collect(document); Garbage.trash(Garbage.elements); } }; window.addListener('beforeunload', function(){ window.addListener('unload', Garbage.empty); if (window.ie) window.addListener('unload', CollectGarbage); }); /* Script: Element.Event.js Contains the Event Class, Element methods to deal with Element events, custom Events, and the Function prototype bindWithEvent. License: MIT-style license. */ /* Class: Event Cross browser methods to manage events. Arguments: event - the event Properties: shift - true if the user pressed the shift control - true if the user pressed the control alt - true if the user pressed the alt meta - true if the user pressed the meta key wheel - the amount of third button scrolling code - the keycode of the key pressed page.x - the x position of the mouse, relative to the full window page.y - the y position of the mouse, relative to the full window client.x - the x position of the mouse, relative to the viewport client.y - the y position of the mouse, relative to the viewport key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys. target - the event target relatedTarget - the event related target Example: (start code) $('myLink').onkeydown = function(event){ var event = new Event(event); //event is now the Event class. alert(event.key); //returns the lowercase letter pressed alert(event.shift); //returns true if the key pressed is shift if (event.key == 's' && event.control) alert('document saved'); }; (end) */ var Event = new Class({ initialize: function(event){ if (event && event.$extended) return event; this.$extended = true; event = event || window.event; this.event = event; this.type = event.type; this.target = event.target || event.srcElement; if (this.target.nodeType == 3) this.target = this.target.parentNode; this.shift = event.shiftKey; this.control = event.ctrlKey; this.alt = event.altKey; this.meta = event.metaKey; if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){ this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; } else if (this.type.contains('key')){ this.code = event.which || event.keyCode; for (var name in Event.keys){ if (Event.keys[name] == this.code){ this.key = name; break; } } if (this.type == 'keydown'){ var fKey = this.code - 111; if (fKey > 0 && fKey < 13) this.key = 'f' + fKey; } this.key = this.key || String.fromCharCode(this.code).toLowerCase(); } else if (this.type.test(/(click|mouse|menu)/)){ this.page = { 'x': event.pageX || event.clientX + document.documentElement.scrollLeft, 'y': event.pageY || event.clientY + document.documentElement.scrollTop }; this.client = { 'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX, 'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY }; this.rightClick = (event.which == 3) || (event.button == 2); switch(this.type){ case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break; case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement; } this.fixRelatedTarget(); } return this; }, /* Property: stop cross browser method to stop an event */ stop: function(){ return this.stopPropagation().preventDefault(); }, /* Property: stopPropagation cross browser method to stop the propagation of an event */ stopPropagation: function(){ if (this.event.stopPropagation) this.event.stopPropagation(); else this.event.cancelBubble = true; return this; }, /* Property: preventDefault cross browser method to prevent the default action of the event */ preventDefault: function(){ if (this.event.preventDefault) this.event.preventDefault(); else this.event.returnValue = false; return this; } }); Event.fix = { relatedTarget: function(){ if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode; }, relatedTargetGecko: function(){ try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;} } }; Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget; /* Property: keys you can add additional Event keys codes this way: Example: (start code) Event.keys.whatever = 80; $(myelement).addEvent(keydown, function(event){ event = new Event(event); if (event.key == 'whatever') console.log(whatever key clicked). }); (end) */ Event.keys = new Abstract({ 'enter': 13, 'up': 38, 'down': 40, 'left': 37, 'right': 39, 'esc': 27, 'space': 32, 'backspace': 8, 'tab': 9, 'delete': 46 }); /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.Methods.Events = { /* Property: addEvent Attaches an event listener to a DOM element. Arguments: type - the event to monitor ('click', 'load', etc) without the prefix 'on'. fn - the function to execute Example: >$('myElement').addEvent('click', function(){alert('clicked!')}); */ addEvent: function(type, fn){ this.$events = this.$events || {}; this.$events[type] = this.$events[type] || {'keys': [], 'values': []}; if (this.$events[type].keys.contains(fn)) return this; this.$events[type].keys.push(fn); var realType = type; var custom = Element.Events[type]; if (custom){ if (custom.add) custom.add.call(this, fn); if (custom.map) fn = custom.map; if (custom.type) realType = custom.type; } if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true}); this.$events[type].values.push(fn); return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this; }, /* Property: removeEvent Works as Element.addEvent, but instead removes the previously added event listener. */ removeEvent: function(type, fn){ if (!this.$events || !this.$events[type]) return this; var pos = this.$events[type].keys.indexOf(fn); if (pos == -1) return this; var key = this.$events[type].keys.splice(pos,1)[0]; var value = this.$events[type].values.splice(pos,1)[0]; var custom = Element.Events[type]; if (custom){ if (custom.remove) custom.remove.call(this, fn); if (custom.type) type = custom.type; } return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this; }, /* Property: addEvents As , but accepts an object and add multiple events at once. */ addEvents: function(source){ return Element.setMany(this, 'addEvent', source); }, /* Property: removeEvents removes all events of a certain type from an element. if no argument is passed in, removes all events. Arguments: type - string; the event name (e.g. 'click') */ removeEvents: function(type){ if (!this.$events) return this; if (!type){ for (var evType in this.$events) this.removeEvents(evType); this.$events = null; } else if (this.$events[type]){ this.$events[type].keys.each(function(fn){ this.removeEvent(type, fn); }, this); this.$events[type] = null; } return this; }, /* Property: fireEvent executes all events of the specified type present in the element. Arguments: type - string; the event name (e.g. 'click') args - array or single object; arguments to pass to the function; if more than one argument, must be an array delay - (integer) delay (in ms) to wait to execute the event */ fireEvent: function(type, args, delay){ if (this.$events && this.$events[type]){ this.$events[type].keys.each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); } return this; }, /* Property: cloneEvents Clones all events from an element to this element. Arguments: from - element, copy all events from this element type - optional, copies only events of this type */ cloneEvents: function(from, type){ if (!from.$events) return this; if (!type){ for (var evType in from.$events) this.cloneEvents(from, evType); } else if (from.$events[type]){ from.$events[type].keys.each(function(fn){ this.addEvent(type, fn); }, this); } return this; } }; window.extend(Element.Methods.Events); document.extend(Element.Methods.Events); Element.extend(Element.Methods.Events); /* Section: Custom Events */ Element.Events = new Abstract({ /* Event: mouseenter In addition to the standard javascript events (load, mouseover, mouseout, click, etc.) contains two custom events this event fires when the mouse enters the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseover) Example: >$(myElement).addEvent('mouseenter', myFunction); */ 'mouseenter': { type: 'mouseover', map: function(event){ event = new Event(event); if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event); } }, /* Event: mouseleave this event fires when the mouse exits the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseout) Example: >$(myElement).addEvent('mouseleave', myFunction); */ 'mouseleave': { type: 'mouseout', map: function(event){ event = new Event(event); if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event); } }, 'mousewheel': { type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel' } }); Element.NativeEvents = [ 'click', 'dblclick', 'mouseup', 'mousedown', //mouse buttons 'mousewheel', 'DOMMouseScroll', //mouse wheel 'mouseover', 'mouseout', 'mousemove', //mouse movement 'keydown', 'keypress', 'keyup', //keys 'load', 'unload', 'beforeunload', 'resize', 'move', //window 'focus', 'blur', 'change', 'submit', 'reset', 'select', //forms elements 'error', 'abort', 'contextmenu', 'scroll' //misc ]; /* Class: Function A collection of The Function Object prototype methods. */ Function.extend({ /* Property: bindWithEvent automatically passes MooTools Event Class. Arguments: bind - optional, the object that the "this" of the function will refer to. args - optional, an argument to pass to the function; if more than one argument, it must be an array of arguments. Returns: a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. Example: >function myFunction(event){ > alert(event.client.x) //returns the coordinates of the mouse.. >}; >myElement.addEvent('click', myFunction.bindWithEvent(myElement)); */ bindWithEvent: function(bind, args){ return this.create({'bind': bind, 'arguments': args, 'event': Event}); } }); /* Script: Element.Filters.js add Filters capability to . License: MIT-style license. */ /* Class: Elements A collection of methods to be used with <$$> elements collections. */ Elements.extend({ /* Property: filterByTag Filters the collection by a specified tag name. Returns a new Elements collection, while the original remains untouched. */ filterByTag: function(tag){ return new Elements(this.filter(function(el){ return (Element.getTag(el) == tag); })); }, /* Property: filterByClass Filters the collection by a specified class name. Returns a new Elements collection, while the original remains untouched. */ filterByClass: function(className, nocash){ var elements = this.filter(function(el){ return (el.className && el.className.contains(className, ' ')); }); return (nocash) ? elements : new Elements(elements); }, /* Property: filterById Filters the collection by a specified ID. Returns a new Elements collection, while the original remains untouched. */ filterById: function(id, nocash){ var elements = this.filter(function(el){ return (el.id == id); }); return (nocash) ? elements : new Elements(elements); }, /* Property: filterByAttribute Filters the collection by a specified attribute. Returns a new Elements collection, while the original remains untouched. Arguments: name - the attribute name. operator - optional, the attribute operator. value - optional, the attribute value, only valid if the operator is specified. */ filterByAttribute: function(name, operator, value, nocash){ var elements = this.filter(function(el){ var current = Element.getProperty(el, name); if (!current) return false; if (!operator) return true; switch(operator){ case '=': return (current == value); case '*=': return (current.contains(value)); case '^=': return (current.substr(0, value.length) == value); case '$=': return (current.substr(current.length - value.length) == value); case '!=': return (current != value); case '~=': return current.contains(value, ' '); } return false; }); return (nocash) ? elements : new Elements(elements); } }); /* Script: Element.Selectors.js Css Query related functions and extensions License: MIT-style license. */ /* Section: Utility Functions */ /* Function: $E Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. Returns as . Arguments: selector - string; the css selector to match filter - optional; a DOM element to limit the scope of the selector match; defaults to document. Example: >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' Returns: a DOM element - the first element that matches the selector */ function $E(selector, filter){ return ($(filter) || document).getElement(selector); }; /* Function: $ES Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. See Also: for an alternate syntax. Returns as . Returns: an array of dom elements that match the selector within the filter Arguments: selector - string; css selector to match filter - optional; a DOM element to limit the scope of the selector match; defaults to document. Examples: >$ES("a") //gets all the anchor tags; synonymous with $$("a") >$ES('a','myElement') //get all the anchor tags within $('myElement') */ function $ES(selector, filter){ return ($(filter) || document).getElementsBySelector(selector); }; $$.shared = { 'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/, 'xpath': { getParam: function(items, context, param, i){ var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]]; if (param[2]) temp.push('[@id="', param[2], '"]'); if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]'); if (param[4]){ if (param[5] && param[6]){ switch(param[5]){ case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break; case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break; case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break; case '=': temp.push('[@', param[4], '="', param[6], '"]'); break; case '!=': temp.push('[@', param[4], '!="', param[6], '"]'); } } else { temp.push('[@', param[4], ']'); } } items.push(temp.join('')); return items; }, getItems: function(items, context, nocash){ var elements = []; var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i)); return (nocash) ? elements : new Elements(elements.map($)); } }, 'normal': { getParam: function(items, context, param, i){ if (i == 0){ if (param[2]){ var el = context.getElementById(param[2]); if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false; items = [el]; } else { items = $A(context.getElementsByTagName(param[1])); } } else { items = $$.shared.getElementsByTagName(items, param[1]); if (param[2]) items = Elements.filterById(items, param[2], true); } if (param[3]) items = Elements.filterByClass(items, param[3], true); if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true); return items; }, getItems: function(items, context, nocash){ return (nocash) ? items : $$.unique(items); } }, resolver: function(prefix){ return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false; }, getElementsByTagName: function(context, tagName){ var found = []; for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName)); return found; } }; $$.shared.method = (window.xpath) ? 'xpath' : 'normal'; /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.Methods.Dom = { /* Property: getElements Gets all the elements within an element that match the given (single) selector. Returns as . Arguments: selector - string; the css selector to match Examples: >$('myElement').getElements('a'); // get all anchors within myElement >$('myElement').getElements('input[name=dialog]') //get all input tags with name 'dialog' >$('myElement').getElements('input[name$=log]') //get all input tags with names ending with 'log' Notes: Supports these operators in attribute selectors: - = : is equal to - ^= : starts-with - $= : ends-with - != : is not equal to Xpath is used automatically for compliant browsers. */ getElements: function(selector, nocash){ var items = []; selector = selector.trim().split(' '); for (var i = 0, j = selector.length; i < j; i++){ var sel = selector[i]; var param = sel.match($$.shared.regexp); if (!param) break; param[1] = param[1] || '*'; var temp = $$.shared[$$.shared.method].getParam(items, this, param, i); if (!temp) break; items = temp; } return $$.shared[$$.shared.method].getItems(items, this, nocash); }, /* Property: getElement Same as , but returns only the first. Alternate syntax for <$E>, where filter is the Element. Returns as . Arguments: selector - string; css selector */ getElement: function(selector){ return $(this.getElements(selector, true)[0] || false); }, /* Property: getElementsBySelector Same as , but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. Returns as . Arguments: selector - string; css selector */ getElementsBySelector: function(selector, nocash){ var elements = []; selector = selector.split(','); for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true)); return (nocash) ? elements : $$.unique(elements); } }; Element.extend({ /* Property: getElementById Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. Arguments: id - string; the id of the element to find. */ getElementById: function(id){ var el = document.getElementById(id); if (!el) return false; for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ if (!parent) return false; } return el; }/*compatibility*/, getElementsByClassName: function(className){ return this.getElements('.' + className); } /*end compatibility*/ }); document.extend(Element.Methods.Dom); Element.extend(Element.Methods.Dom); /* Script: Element.Form.js Contains Element prototypes to deal with Forms and their elements. License: MIT-style license. */ /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.extend({ /* Property: getValue Returns the value of the Element, if its tag is textarea, select or input. getValue called on a multiple select will return an array. */ getValue: function(){ switch(this.getTag()){ case 'select': var values = []; $each(this.options, function(option){ if (option.selected) values.push($pick(option.value, option.text)); }); return (this.multiple) ? values : values[0]; case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break; case 'textarea': return this.value; } return false; }, getFormElements: function(){ return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea')); }, /* Property: toQueryString Reads the children inputs of the Element and generates a query string, based on their values. Used internally in Example: (start code)
(end) Returns: email=bob@bob.com&zipCode=90210 */ toQueryString: function(){ var queryString = []; this.getFormElements().each(function(el){ var name = el.name; var value = el.getValue(); if (value === false || !name || el.disabled) return; var qs = function(val){ queryString.push(name + '=' + encodeURIComponent(val)); }; if ($type(value) == 'array') value.each(qs); else qs(value); }); return queryString.join('&'); } }); /* Script: Element.Dimensions.js Contains Element prototypes to deal with Element size and position in space. Note: The functions in this script require n XHTML doctype. License: MIT-style license. */ /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.extend({ /* Property: scrollTo Scrolls the element to the specified coordinated (if the element has an overflow) Arguments: x - the x coordinate y - the y coordinate Example: >$('myElement').scrollTo(0, 100) */ scrollTo: function(x, y){ this.scrollLeft = x; this.scrollTop = y; }, /* Property: getSize Return an Object representing the size/scroll values of the element. Example: (start code) $('myElement').getSize(); (end) Returns: (start code) { 'scroll': {'x': 100, 'y': 100}, 'size': {'x': 200, 'y': 400}, 'scrollSize': {'x': 300, 'y': 500} } (end) */ getSize: function(){ return { 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} }; }, /* Property: getPosition Returns the real offsets of the element. Arguments: overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars Example: >$('element').getPosition(); Returns: >{x: 100, y:500}; */ getPosition: function(overflown){ overflown = overflown || []; var el = this, left = 0, top = 0; do { left += el.offsetLeft || 0; top += el.offsetTop || 0; el = el.offsetParent; } while (el); overflown.each(function(element){ left -= element.scrollLeft || 0; top -= element.scrollTop || 0; }); return {'x': left, 'y': top}; }, /* Property: getTop Returns the distance from the top of the window to the Element. Arguments: overflown - optional, an array of nested scrolling containers, see Element::getPosition */ getTop: function(overflown){ return this.getPosition(overflown).y; }, /* Property: getLeft Returns the distance from the left of the window to the Element. Arguments: overflown - optional, an array of nested scrolling containers, see Element::getPosition */ getLeft: function(overflown){ return this.getPosition(overflown).x; }, /* Property: getCoordinates Returns an object with width, height, left, right, top, and bottom, representing the values of the Element Arguments: overflown - optional, an array of nested scrolling containers, see Element::getPosition Example: (start code) var myValues = $('myElement').getCoordinates(); (end) Returns: (start code) { width: 200, height: 300, left: 100, top: 50, right: 300, bottom: 350 } (end) */ getCoordinates: function(overflown){ var position = this.getPosition(overflown); var obj = { 'width': this.offsetWidth, 'height': this.offsetHeight, 'left': position.x, 'top': position.y }; obj.right = obj.left + obj.width; obj.bottom = obj.top + obj.height; return obj; } }); /* Script: Window.DomReady.js Contains the custom event domready, for window. License: MIT-style license. */ /* Section: Custom Events */ /* Event: domready executes a function when the dom tree is loaded, without waiting for images. Only works when called from window. Credits: (c) Dean Edwards/Matthias Miller/John Resig, remastered for MooTools. Arguments: fn - the function to execute when the DOM is ready Example: > window.addEvent('domready', function(){ > alert('the dom is ready'); > }); */ Element.Events.domready = { add: function(fn){ if (window.loaded){ fn.call(this); return; } var domReady = function(){ if (window.loaded) return; window.loaded = true; window.timer = $clear(window.timer); this.fireEvent('domready'); }.bind(this); if (document.readyState && window.webkit){ window.timer = function(){ if (['loaded','complete'].contains(document.readyState)) domReady(); }.periodical(50); } else if (document.readyState && window.ie){ if (!$('ie_ready')){ var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)'; document.write(' (end) */ send: function(options){ return new Ajax(this.getProperty('action'), $merge({data: this.toQueryString()}, options, {method: 'post'})).request(); } }); /* Script: Json.js Simple Json parser and Stringyfier, See: License: MIT-style license. */ /* Class: Json Simple Json parser and Stringyfier, See: */ var Json = { /* Property: toString Converts an object to a string, to be passed in server-side scripts as a parameter. Although its not normal usage for this class, this method can also be used to convert functions and arrays to strings. Arguments: obj - the object to convert to string Returns: A json string Example: (start code) Json.toString({apple: 'red', lemon: 'yellow'}); '{"apple":"red","lemon":"yellow"}' (end) */ toString: function(obj){ switch($type(obj)){ case 'string': return '"' + obj.replace(/(["\\])/g, '\\$1') + '"'; case 'array': return '[' + obj.map(Json.toString).join(',') + ']'; case 'object': var string = []; for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property])); return '{' + string.join(',') + '}'; case 'number': if (isFinite(obj)) break; case false: return 'null'; } return String(obj); }, /* Property: evaluate converts a json string to an javascript Object. Arguments: str - the string to evaluate. if its not a string, it returns false. secure - optionally, performs syntax check on json string. Defaults to false. Credits: Json test regexp is by Douglas Crockford . Example: >var myObject = Json.evaluate('{"apple":"red","lemon":"yellow"}'); >//myObject will become {apple: 'red', lemon: 'yellow'} */ evaluate: function(str, secure){ return (($type(str) != 'string') || (secure && !str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/))) ? null : eval('(' + str + ')'); } }; /* Script: Hash.js Contains the class Hash. License: MIT-style license. */ /* Class: Hash It wraps an object that it uses internally as a map. The user must use set(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. null/undefined values are allowed. Note: Each hash instance has the length property. Arguments: obj - an object to convert into a Hash instance. Example: (start code) var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'}); hash.remove('b'); // b is removed. hash.set('c', 'hello'); hash.get('c'); // returns 'hello' hash.length // returns 2 (a and c) (end) */ var Hash = new Class({ length: 0, initialize: function(object){ this.obj = object || {}; this.setLength(); }, /* Property: get Retrieves a value from the hash. Arguments: key - The key Returns: The value */ get: function(key){ return (this.hasKey(key)) ? this.obj[key] : null; }, /* Property: hasKey Check the presence of a specified key-value pair in the hash. Arguments: key - The key Returns: True if the Hash contains a value for the specified key, otherwise false */ hasKey: function(key){ return (key in this.obj); }, /* Property: set Adds a key-value pair to the hash or replaces a previous value associated with the key. Arguments: key - The key value - The value */ set: function(key, value){ if (!this.hasKey(key)) this.length++; this.obj[key] = value; return this; }, setLength: function(){ this.length = 0; for (var p in this.obj) this.length++; return this; }, /* Property: remove Removes a key-value pair from the hash. Arguments: key - The key */ remove: function(key){ if (this.hasKey(key)){ delete this.obj[key]; this.length--; } return this; }, /* Property: each Calls a function for each key-value pair. The first argument passed to the function will be the value, the second one will be the key, like $each. Arguments: fn - The function to call for each key-value pair bind - Optional, the object that will be referred to as "this" in the function */ each: function(fn, bind){ $each(this.obj, fn, bind); }, /* Property: extend Extends the current hash with an object containing key-value pairs. Values for duplicate keys will be replaced by the new ones. Arguments: obj - An object containing key-value pairs */ extend: function(obj){ $extend(this.obj, obj); return this.setLength(); }, /* Property: merge Merges the current hash with multiple objects. */ merge: function(){ this.obj = $merge.apply(null, [this.obj].extend(arguments)); return this.setLength(); }, /* Property: empty Empties all hash values properties and values. */ empty: function(){ this.obj = {}; this.length = 0; return this; }, /* Property: keys Returns an array containing all the keys, in the same order as the values returned by . Returns: An array containing all the keys of the hash */ keys: function(){ var keys = []; for (var property in this.obj) keys.push(property); return keys; }, /* Property: values Returns an array containing all the values, in the same order as the keys returned by . Returns: An array containing all the values of the hash */ values: function(){ var values = []; for (var property in this.obj) values.push(this.obj[property]); return values; } }); /* Section: Utility Functions */ /* Function: $H Shortcut to create a Hash from an Object. */ function $H(obj){ return new Hash(obj); }; /* Script: Tips.js Tooltips, BubbleTips, whatever they are, they will appear on mouseover License: MIT-style license. Credits: The idea behind Tips.js is based on Bubble Tooltips () by Alessandro Fulcitiniti */ /* Class: Tips Display a tip on any element with a title and/or href. Note: Tips requires an XHTML doctype. Arguments: elements - a collection of elements to apply the tooltips to on mouseover. options - an object. See options Below. Options: maxTitleChars - the maximum number of characters to display in the title of the tip. defaults to 30. showDelay - the delay the onShow method is called. (defaults to 100 ms) hideDelay - the delay the onHide method is called. (defaults to 100 ms) className - the prefix for your tooltip classNames. defaults to 'tool'. the whole tooltip will have as classname: tool-tip the title will have as classname: tool-title the text will have as classname: tool-text offsets - the distance of your tooltip from the mouse. an Object with x/y properties. fixed - if set to true, the toolTip will not follow the mouse. Events: onShow - optionally you can alter the default onShow behaviour with this option (like displaying a fade in effect); onHide - optionally you can alter the default onHide behaviour with this option (like displaying a fade out effect); Example: (start code) (end) Note: The title of the element will always be used as the tooltip body. If you put :: on your title, the text before :: will become the tooltip title. */ var Tips = new Class({ options: { onShow: function(tip){ tip.setStyle('visibility', 'visible'); }, onHide: function(tip){ tip.setStyle('visibility', 'hidden'); }, maxTitleChars: 30, showDelay: 100, hideDelay: 100, className: 'tool', offsets: {'x': 16, 'y': 16}, fixed: false }, initialize: function(elements, options){ this.setOptions(options); this.toolTip = new Element('div', { 'class': this.options.className + '-tip', 'styles': { 'position': 'absolute', 'top': '0', 'left': '0', 'visibility': 'hidden' } }).inject(document.body); this.wrapper = new Element('div').inject(this.toolTip); $$(elements).each(this.build, this); if (this.options.initialize) this.options.initialize.call(this); }, build: function(el){ el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false); if (el.title){ var dual = el.title.split('::'); if (dual.length > 1){ el.$tmp.myTitle = dual[0].trim(); el.$tmp.myText = dual[1].trim(); } else { el.$tmp.myText = el.title; } el.removeAttribute('title'); } else { el.$tmp.myText = false; } if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "…"; el.addEvent('mouseenter', function(event){ this.start(el); if (!this.options.fixed) this.locate(event); else this.position(el); }.bind(this)); if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this)); var end = this.end.bind(this); el.addEvent('mouseleave', end); el.addEvent('trash', end); }, start: function(el){ this.wrapper.empty(); if (el.$tmp.myTitle){ this.title = new Element('span').inject(new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)).setHTML(el.$tmp.myTitle); } if (el.$tmp.myText){ this.text = new Element('span').inject(new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)).setHTML(el.$tmp.myText); } $clear(this.timer); this.timer = this.show.delay(this.options.showDelay, this); }, end: function(event){ $clear(this.timer); this.timer = this.hide.delay(this.options.hideDelay, this); }, position: function(element){ var pos = element.getPosition(); this.toolTip.setStyles({ 'left': pos.x + this.options.offsets.x, 'top': pos.y + this.options.offsets.y }); }, locate: function(event){ var win = {'x': window.getWidth(), 'y': window.getHeight()}; var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()}; var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight}; var prop = {'x': 'left', 'y': 'top'}; for (var z in prop){ var pos = event.page[z] + this.options.offsets[z]; if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z]; this.toolTip.setStyle(prop[z], pos); }; }, show: function(){ if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this); this.fireEvent('onShow', [this.toolTip]); }, hide: function(){ this.fireEvent('onHide', [this.toolTip]); } }); Tips.implement(new Events, new Options);vdr-plugin-live/live/img/0000755000175000017500000000000012650773437015157 5ustar tobiastobiasvdr-plugin-live/live/img/rounded-box-orange-tl.png0000644000175000017500000000100312650773437021773 0ustar tobiastobias‰PNG  IHDRãîZÄžbKGDÿÿÿ ½§“ pHYs  šœtIME×/­ÿÑåIDATxÚíÜMNÂ@@ñ×Pi… Ñû™è<¥k¯àÆRê™8ÖV@¾_2i )‹n^þÐ’$éOe¿ÂOBÈÓIEND®B`‚vdr-plugin-live/live/img/german.png0000644000175000017500000000134212650773437017136 0ustar tobiastobias‰PNG  IHDR‘h6sRGB®ÎéœIDAT(Ï5’»O“Q‡ß÷œó][[ZJµ\Œñ.&†xMŒ!Þ•.Æ@]XÝŒº”IŒ Ñ­îb*‘DA£bK©½}í×syŸá™ží÷C"€ž1DT©TÊå²”2“É !zð"*‹ÓÓÓaær9ÏóªÕjù|žsÞËÐRÊÙÙÙB¡0999<<,¥$"!„”r~~¾T*MMM%“IÆ£àÅ‹—>~öô‰&E]©pÎÃxlÛó¹¹Z½öðÁÆ™PF7j›÷ïÝ¿p±Õ¿ÕFØ’2âH–eÙ®'Ž=yçî­üÕ+g/_šÚ¿ÞfÎø}é_Ûëßdsj›ÔÝ"K?É!-»Õ7çô‡×tî¼@iáÊò ôæ²ZxÕ‡‚:©‘°ÑM ¾}eÖ6–‚VCF«°B©~ô„”µ-гc„Jj]¥êº‹+kD('h¶×L£}³ã(8"iFƒÒ|‹ñÐm‡àh&,‹¶²ƒ•¨˜Lp:Œ3DFZ0 ¡» ÛaX®í:˜‚ °¢Wéí‹ÌG†¬7+ ¡! 0‰ ô¢×b±4³˜=2zjù÷xC¦ŒmoÀ—è:| qC>´»°šËî»î¸®àÀ²©ÄÎÃ7ÞK'Žm Œ86¶ ‚Ò–QN´>.6yâöž;G4Ê(¦ÛΗ+K 3ÙÁµÑýV:Öd‡Ýï«jík,»ïæØé“©T¿0¼w $Ò]®ÿ¬¯|~¿¾¶¤¢F[ÜÎdrGöÛ»{Äs|Î" I$ Ȉ"Ùm¶Z[6ËqY<î¹®Ï9ÐÀùÌ?X‡!NOmIEND®B`‚vdr-plugin-live/live/img/record.png0000644000175000017500000000145712650773437017152 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<¬IDAT8“MkTg†¯óžóΙ“sœÐI6“!˜ƒ˜`ºSH–í¦¿ ‹ Ý Í(ƒ º©¸É¢n%+¡¶«ÚlqP¬`ÒÆ v’±™¼ó~œ9]˜HRJÛ žÝs_‹çáö²,ã$oÞlՌѫΥUç\Éó<|ßoßÌåµ³gg_ŸÜ÷Ž[[M¡µ®[k¿ñ}QŽã˜$IBÐëõèõzŒFÙ[)åz†õÙÙêè£àÕ«×BëáOƘåryJŠ,Ã0:8@Œ# 2ßgww×ü% óŸŸ;WƒÁ ®µZ.—˲¿³Ã Ñ`"M9“¦ô}Ÿ–ÄssLNMÉv»½ì\Z¾õ?~Z;<ìÿX(œ™¡ÝÆžJ} &Ã_ïßgbi ß·Uáœ-¨—/©-¢¼ÎÇð1ÓZ£ œ³%áœûðOÏã#Ä‘À!œK[ùóçù-Šþ3û{ÎÏ Ò–0Æ6Æx‘ËÑý—px‘Ï3¾°€1¶)´6kJéí I˜ºz•»Iò’.p7Ž)­¬$ Jém­Íš¿±qoÿÉ“gE)ƒÅ¸Rñ³J…Ÿ þô<´sü<"~ˆc&VV(..b­3½žúîòå¯î‡‡ªîœû¬X,,}rñb®pçûÏŸ³stíüü<µ ðãc¬étº›ÆØ:œ(ÓÍ›·E.'ëq}],fþþ•,ËètºÛƒúÞ[¿~ýÊè”à˜[·nפ”«AàW}_”ÒtÔr.mZk×®]»rªÎünFÒx IEND®B`‚vdr-plugin-live/live/img/help.png0000644000175000017500000000146212650773437016620 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYsššzƒ ’tEXtSoftwarewww.inkscape.org›î<¯IDAT8u“;ˆœe†Ÿs¾ï¿ÌLfHHd5bHlVÈFÓ¨`“`á*D-$ˆ(Xi±é̵La¶ì,4 Úx)$ED,• Ž¢† Æ7ËÎοÿåû¿“bY%žêÀ{Î{8¼U:E–¦?œúêà€ÎŽ/õÈuÅA€çOËÇàØ]‘{DÞ:!œZ ´Ý€^wô,}ra89 O¯íÉ%ù©kifë‘z®æÂRÎùJÞ»¸‚ã™Gvòô¡.¿¹ÊßßåP&”;š¶´æ6žË5ÉpÛ^àBÁ™/Öy÷£k%ÁJ.ý:`îv%Ö! tZuÀIuèýÑGŒ€I‹ÑðÍ¥ "jÅî}ž—ØNÝßÿ¸†Iƒ 6 5ú”:/wG183h1 Di8zäÞ>¾SxöâŸ4k妮|‹ÝåM N>ü,`XWÞÉ—L8ýþÏ0u(ù¦n`I„VUcc_×IÜÌÀ %qÊkß®bEœ&3}³ ÄUm‰Ÿ»V): æb?Î~µÂoW Ä2ÔÄüLwÔ^hÍÞPàuÝPfF•9ÄÔìððî.‹ó»Ð˜!1™$T©£‰D༎Gý«M^È7Tg‘&I¹pYè÷*>»ÒPgÛN ^ÈJ!NäñhÛ‹7…)MürÛ‹Ú$ñ_”¦µ ¥„¦Š¯l…IþçGêq§2obEÛr5Æø1°ü_œoN«AÐlÏÅØIEND®B`‚vdr-plugin-live/live/img/rounded-box-orange-tr.png0000644000175000017500000000061012650773437022004 0ustar tobiastobias‰PNG  IHDR;mGúbKGDÿýÝvY2 pHYs  šœtIME×!.+9æIDAT8Ë­ÓÏJÃ@Çñïn¶ImŒ•ÿ‚7½{ô|Žb=÷U|©ž y…<%]NË861ˆ Ë.ý0Ùý üÓð2ÿ|߃/³Öâ6''§³JÉ&‘©Q…1ÇqºB8mÏó[33£Ûól,8=ms)e¬µ~ã8¼†!&''Á9Çp8Äp8DQØ®ë~ð}?n4êÅàððˆK™QJ-V«O\Çqð'Š¢ÀÙÙ™ÂýêûžÏÏÏÒ4¥Ì«Õª›¦)ˆÆŒÓý>BLOO»———‹D&°Îöö¾ÏŽFן£èq̓ÝÝ]A€û)Œ1Ȳ KKK˜˜˜ÀÕÕÏN„/DžgÍ4½®Y[ Iôû}LMMÝYVJa0àààsssh4Èó¬Æo ¥tÝZ‹4MÑét°³³ƒ……xžÆ¤”PJŽq~~Ž0 Ž£ë‚HWî?K)u³ôDºÂ‰èŸƒ8‘éþ¿Àt¹Rºý¿¥t[H©ZŒÙ—Aàׂ ÀÅÅö÷÷!„c `­¡ßï#@–ÉŽ”ºÅ¬µØÞþô®T ߺ®ð’$Ažç "EàœCß÷Q*• 5©Á }¿¼üj]Àh”ÅDô´\ŽžEQäEQôPlÕë%ß”Ò1p«L[ÜóÜ8 ƒ×årTÇc­E¯—tÒ4û¨”Ž×ÖVŠ;‚1››[³®ë6…pêŽÃ+`LÑ%2m­ukuuåNk\:Úè“þIEND®B`‚vdr-plugin-live/live/img/rounded-box-green-tr.png0000644000175000017500000000056212650773437021637 0ustar tobiastobias‰PNG  IHDR;mGúbKGDÿÿÿ ½§“'IDATxÚ­“ÁJÃ@†¿Í¦M›¥1T”¶ zPñT=Ä«'A¼øBßÏçÈôàTÁƒ"­]/“2]šÄa†ýøwg~ø§ˆ$ÿq`Ýb®€Œ|3€—Zõ¿B2©FÁ* o²ÀèHïP…ÖB΀D@öuè=¥(„4‚,p8 UjLZ7bàøÞWàM]/ ƽ’>Ò+`yœ>3ÎnX|ÎùZ:õ¸^~üª¯hMqò`òþÄ\Œ®º‚—Å\I^KÉ Råfô•Ü(Íñî.gÀ8ö\Þ,Q*£Ð7:J3Àíù 8È@ ½¶6Š²Ô‰Š=™\¢rë|½{¯žÄNö¨«|¶¥¦R’;DAªq§ëÑéXIEND®B`‚vdr-plugin-live/live/img/record_timer.png0000644000175000017500000000150112650773437020340 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<¾IDAT8“ÏOAÅßÌî´]¶ÔP)56-H%€ÆÈÜÔ«Æ›1B¼y’¼šþÈEn¼™<˜Å‹ÊÁLü-ò«„ŠPZ¥»ÛéÎÌv=¾ó÷}’÷}yÄ÷}ìÕââRZ7£”—RJÅ!Ð4mM×µ\ éèhŸÛ{OvKK9êºnVJyCÓhÜ4M„ÃaPJaY,ËB­æ¯2ÆîƒÁl{{ªö0;;G]·:)„ˆÇÛ˜O€²¬Àöl@X3a&(òù¼Ôuö* ]èêJ×tp'ëº| ³¼µY{Æ f œø†tc‡››Y¡PPÊ˸C¦§ß¤+ûY$Ò˜(ù6>ðhëþ=PÛ÷%(V?·âDCÚ‚ÍØÜ,®†yQ¯VyÆqì„£8®?Gßù",Þ®Y‚c‹¬c3±…—“§q»gÕ*OB3º2åû>^{9ã1p 0„B }áó:)|—ñôKúuCÓdŠ*%c°à,#/Ö3ûŽÿN­´kÞVcÛÌ;‹õXJƨRªÞ'þW„Ðm€UÊ[€cfÖêÁš­|:Ú·ÞBæ ·)‰Â| ¸Íþjæ6Ca¾½MÉzT!sÔuÅçJ\Æ»G'ÿá6ÃÛG'0tôLÝçîŠëŠmbb¼83ó6ʘÞ$Ü¢µÐžLYàåª( ä?Á‹N\k½‚¾æ.H©„eñ{ƒƒWÇu¨TxV)u&œ;MŽG2øôs_ß/Κ)ôô&Ñ ‡ „¥RyJ™öŒéîÝ1°¬i×£ÑH‚ý­ø¾R©¼â8ü2;<|³¶°£Ñѱ4c,£ëZJÓh <¯¶¦”—“RŽÜºusßœ ½YÃhÊIEND®B`‚vdr-plugin-live/live/img/rwd.png0000644000175000017500000000153712650773437016467 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<ÜIDAT8m“ÍkSAÅÏ›yïÅôÅTÓZ¨ I4Š"El‹YÚAwnÔþ?ÀU[ðÑ­t!((*X…R*uªM0ŠIµéW^&oÞÌdž MÕ³›¹—‡{Ï5‚ @«æçói!üa¥ ¥T·a ”–M“l;4’J%çZû& Ÿ/ß÷³Rʳ”’¸ã8ˆD" „Àu]¸® ­ƒo–eÝ …BÙd2¡ÿr¹9âûü©"o·(¥øŸ´Ö(•JÒ4­ÉPhÓ‘={Òšc,ËX-Óյ͒R‚sÎ9>ÖX\\»®c;,)E†1–czúMº^¯=‰F7÷´µµ”205Åêj»w¯!™äxû6‚JÅÖƒƒ?P©,ÃagÐäÜf¬ÖJ)|ùÅìl;Rébr¹5<{Å–­íØ™ãñÃ"2œ{=†A†M!d",/{¸ti+¸ßŽcÇ·AiŠ÷ïêx=‰S]p‚Õ5àÇ:”Ê„©”ìÎåÚ0>¾‡¶£÷`àûcöíÀqÈúÚŒõ¡*%»‰R –¥a Î5þŠÅ?j-+¥@”j”S)Ž+—óX^ü„»ã%¬¬¨?Mofj`L¯tÐh”‰²¶àüù2†ŽÎáþ¦§jtu~Çíë¼|Q…ÖÁ‡BÈñ}1ây~±ùyàÃÕ«ó(æñäQ½½U\»öË•?u<<­-/Í%&é Æ()^FEõ€?=ÿsDD‡?@š;;nGF€FFhON{JK¹9={NNë00ô..‡LLÐ:9yRPƒOR·B@¡HIÿ/.MOˆRP}UTQQq[YÌCD‘UTí=:¹KKô;=ŽWU‡YYÓEEö<8î>Aÿ;Bÿ<=€`a’\_˜[[‡`c‰`^{ec``«Y[—ad‘geÄYZ¬`_hkØUU–gg‹jkõONîQRÁ^]ýNRÕZZŸikÿPN›kk„rtìWS‘pqõUVŠtq³ig¤mo ooÂfeþWUšruÙeeÂlhó_^šxyû^b|¢xv©wwÿ`^•~{¤{~¸xw¨}{–ƒ†™„Ÿƒ‚¤‚ƒÎwxÉyxásrónqÛuvîppöol´ƒ‚›ŠŒ°…ƒ¯…ˆþpp¬‰Š«Ž¤‘“ɋЈ‰¡••´‘’é…„øÿ€~ሉӌŒõ„‚¸•–ô…ˆ¯™–§››Å”•®›þ†‡¹œ›Ù–•æ“‘ÁžóŽÓ™š·¡ž½ Ÿù¶¢¥°¤¤ÿ’Â¥¤½§¤µ©©Ð£ ö››Ý¢¤¿«®ç¡ þ›˜Ù¥¥»®¯È«ªÄ®«õ¡žÿž¡û  Ï±°Ç³¶Â¶¶Ë´±Ø³´Ô¶µÏ¹¶ã´±í±²õ°®ÿ­°É½½ü°°Ó¿ÂÎÂÂÖÂÅÍÈÇáÃÂèÂÃÔÈÈðÁ¿û¾¿öÀ¿÷ÁÀÜÈËýÀÁÞÉÌÚÍÎÖÐÏÝÐÐæÑÔÕ×ÔÜÖÕðÑÐûÎÑöÐÑãÖ×ÿÏÍçÚÚáÜÚÝàÜäßÝúÛÚÿÚÛèâáôßáößÜãåáïâãêäãþßÞÿàßíèæèêçôçèûæèþçãñìêìîëõïîïñîýððøòñòôðûõôõ÷óý÷ö÷ùöÿù÷ùû÷ÿûùûýúÿýûüÿûþÿüÿÿÿ!ÿ NETSCAPE2.0!þCreated with The GIMP!ù ÿ,Zý H° Áƒ*äf"ŸÂÓ¸÷Ðß´.Ì3(ʇ @Á]A8¨\‰ „tQ²dy€ASA*h¹ÀfBn\Â\༊é:Ô«È´©Ó€!ù ÿ,`ý H° Áƒ*äF$ŸÂÓ$¹÷Ðß´ jÌ3芅 9hh1!¼‚€6€XÉ’ä‰t ©lÉRÄ6‚¶häØIƒ%n&ä–a¡Ü$¸8ù0Ýz£J!ù ÿ,Zý H° Áƒ*&ŸÂÜbx¹÷Ð7:¦Ô3hKÊ–R~ áÑ^AK:†¨\9‰;‚(Y²Ì±à/ q R¤ÛÂ<\>cʼŠî¸P¬È´iÓ€!ù ÿ,Zý H° Áƒ*L(ŸÂÜžØqø›•.vê6§ãœ8XÊTQ3¯ ©*eRª,óE <‚'W®Žà1C~S3a:2-Ý=L'±äCxt(>\Ê´©À€!ù ÿ,Zý H° Áƒ*LG)ŸÂãäLrøpž>…î$¦¨cG=ƒöšWÐÖžA(SòCˆä@“*Uþ)GšÇŽ|PB§Ð]?…à=t'gäCóQ<Ê´)Ó€!ù ÿ,Zý H° Áƒ*tg*ŸÂé©rø0Ý£Ež(„ö‰”ÇOŽ.AòT¯à/I—Rª‰iAa(WªŒ„Ž µŽC^ÚÔN!¼GZ>„w(Tɇó>\Ê´)Á€!ù ÿ,\ý H° Áƒ*„gkŸÂîNÙÊ÷П»T¨jQ,¸–GZ·V±Êx¯à1T¬Rª «Ah(Wª|ÕŽà¶[C²’õêÂy­PÁš÷pÞ©Z%Ö›X±©Ó§!ù ÿ,Wý H° Áƒ*œGlŸÂðp Ë÷м]½&¬ã°`¼|ÓH0_(SŠ V¯äI•(åzGã°› Eê’·p°_-J¤ø°1¢“*M!ù ÿ,Vý H° Áƒ*œGL!Ax¸„åsèÞ®^ ‚ 6¬ã0^À0N$H­°“(O»GÒdJ”ºÞ,ç±#H`Áä-ÜLX=‡ó"ŽTxØPŠH“R !ù ÿ,\ý H° Áƒ*œ÷kŸÂîNýÊ÷мT±jQ,¸íV.]ºn­’5«Ö½‚ÐbÉZÉ’d­zS¶d9ëÕ;‚Ýn 9r­› çµ* sá)ëÙÚX±©Ó¦!ù ÿ,Xý H° Áƒ*„çjŸÂé*©Ê÷П»Lœ&¤Fê•GRšF*U¯ 0N£RªYjÁc(WªÜÔŽà6C‚"U3!¼N#].”x¯âtÇ…âçP£ !ù ÿ,\ý H° Áƒ*&ŸÂÜFLqø Dê´U„‰G%-d¨@¯ !2Rª”±Â‡;‚'W®œ±à/%™€dI£ÛB-Ó=7âȼ‡þÜ%¹‡´©Ó§!ù ÿ,bý H° Áƒ*ä–$ŸÂÓ$¹÷Ðß´ jÌ3èÊFŽ=^h±!¼‚€6€XÉÄ„éRÙ’¥ˆmmÑèÁ“JàL8.Ä1Ž“PãäÃt7(VœJ•j@!ù ÿ,Zý H° Áƒ*äv#ŸÂÓ ¸¸÷Ðß´ NÌ3hª‹%$`^Á: ¨\™€…tQ²\é 5‚®<‚éÀ¶…¼|ÈÍ@ÉŠéLÔ«È´©Ó€;vdr-plugin-live/live/img/logo_login.png0000644000175000017500000010115612650773437020021 0ustar tobiastobias‰PNG  IHDR,xÇwXw IDATxÚä}w¼e™ðó¼ïÌœz{z'tj‚AAš€H±»î*è~úù­ëê§»®bûÖ†e­«î*‚X@V\z ÒK(I(I©÷&·ß{Ι™÷}žçûcfΙSîÍM‚ìÎo8Ì3™ó–§W$âu›í q¼Â–4³@ŒÿˆA€\†]*óg:ð?òB§‘q=Z²åu‚€ÂˆÅ22£²  ¤P¢ÿ0þÄÔmPJQŠR P"h¥´£•—8®…LŽÅ«0ZLŒaA)àVËä!«n}$<ï„ÿHøÔúàŽÇ¥wP;Žv”8pr" €@pÀXê¡zÐVUTà„%L²zÑ+þ=®X"°WÊ l/Aï(<ºVƒ«)—í×ÕEШb&–¦ÈvõWª¨Tw³-’'T=þ(P ”jñ+éqjúðÎôF(,õ¿Ì€ J@À–!gã Ü·ˆ©˜ —,ÄcÖÌq§L`víX×§Ü Û ˆ£âa¡ 1ç·Mõc„™”¦ÈÖ¨µn^ bõðj<ïøTæ¿1ú=¹Î¿éAwr®XÍFÇX,šc¨VPËÒ&±¾”PZÇøÒÒ¦Á8úŒóHƒ' (P ĵ€JL¨”X3΢Îèìtåä"*É›Z±Ÿ6bã '‘âÇ(¹C1“«ÎB"Ÿ ½`¼pL¾n¡P"4”HâH¦Ï-R5V‰ ž!ƒ¿­!G›×„§½Öí,º/3|°ˆX•kl2|E•AÆjðE2‰|41.˜ŽO­eO¨¦½o%-H¤¥Òæç<¶F-[âN,ZíÃÇÚÍþuwÓÀ0f\t5­­ˆcÙ DU…%L/KÓºq=lÛdÒ|€“eW€‘ð‰IžXeŒi–•:¹í¤~“C!GDc;xŠí¸yÄG·Gæ KšeÇD$úõªÜ˜R_¥6dWW4½H2á#È lТ›ñ4&4N@”dfÐ,YayxÜ÷¤ØBÿ‚S2Ó»¼— H„‰CÖ.P´W ‘Ã1 7ƒ7}|´˜/Nß9¹¿zd iOÐ2*]·TòÀS3—-±Þ/äkn.?þxžÊ8:˜3¡‰¤A eç Ø@é))ª2ŒäªÑòªi,•”&$uÌRª²*(Hñw¬”"šŒ" ªCØåJ¯]­sóUñ`@@±Yko–f,‘„Ñ7LGb «ïÀW£1URi†Š(R¥.ÒŠô7ü(4I­VA(‘µ‘´€ƒÀ‚"A8çÈÚMðåŸUßß×™…læeФ„€…(‰'ˊ͸-o`vÆÇ1›ïQj',ÊÙž[tc”b‹Žš"}$Q=l]¿¡{h¸ÒÕù—’¹_ù£o0üáo*%_e\4 Ê BÍ‘á0ÆšÝaÑý%ˆáCt—ê~Lªì Ej&œ–ÖKu‘Fƒ:€6×A=] gË}2¶Îi[ªóóE¤j]i^³¬8PÚ€·ˆ õ–´=¥zÃ.Û®„©ªö‹X”C¸L®+è“R@ÕkùÓÿ:zñ›Ü×YÜcN(²¸/¢Bac8]±–¦¤º¾æP¼çqö4#ÛX™x¹aEtv[-ÞÐÃO;gœ$ÿ=ðágÊ¿½5ÔˆŽ#%q2d3`j¸ÇM6nÒgƒ¢öÅú ¤x´0›´VÜ&Щµ;œ Çõí4´~Fg1[$;Ž=‡¥ NÇkPe@(§l!EH‰ËÌÆ±ãÄZp×x%'‚ajþÕzá"õÉ @€–T…ÁaÒ ý§à™Ìeuî è “0³•*½ Å,Äl‘HdJÇ€ön»¿ädm€* å“hì±9Oy‚E4;~²íŒ“B€ì¾Ž7Þ1rÇC”ñ€”ã¿FÑ[JDÔ ¡ZÁX+;K£P&Á9œpZÃq&ç@¬rÊÔ¡­çjW{E2ýÁŽ{â•™‰Âiæ'üÈ„–Õ4ãji…‚ ôº lU-—«~º’Я –«I¸UÂ9hXGÛUÏ:_øþŽO°ÇuvS4e+lY!ATÂV˜HâT‘°³Ý›7}lG?j´à8 "Pûç–Iܬl•·€JÏ÷öÎÚ¸¹¼`Þ¾„W^?ôø*“õtÀ.0ä•/"d˜Òo&A’HJ¨·Ö`bÔ‹Üâ5i„̾²ÛnÝÀêD\%œWº^Ùw² •;°hÆž×Á°“?P@XÒr£´–u[°)Li¼‘j§#lj³‰«jFMÆß¸n;CìfTØ*åû˜Qã;ú³_üîöúðôŒ·;NEd"AE‰ïÉ “k¦Èaã~ýk2Wÿ¡’õDI¨¦&õ³J¢-X9sÙ<†ÎÐÌëÜwm¤?ýõÀSÏÚŒ‹%ã:Êf”!ÆÝÆÙ•?§ ðÖ¼n‰³"1¨NñuR/Ë9е«*¦ íXÆ)hw1…[¬Yé–*žˆ ¥_R¯=Ê„ZÌî.]³!µÀaÓý:ll·j¡0çUO†Úÿß÷v\þ±™ˆ» ÀÄÌ–YD'>Af²ÄŒ,»À àØ£òW_?Æä—Ñ)K•ü¡á EÊÕƒÔÿèo;o_•Hÿý×ý+W™Œc¦Õ'Ä”2Ò㤠Z&΃ ‚ˆSTvj·Ä<Ó ­ToD…:ƒDÃEd7ˆvH(«0Pùq¿’Óœ¹îFÏŽAž “Ttcr-ì¡Íf…†´”ta¢—©\×{c«2&|µFÏ8çjßÏjØÞ·£ûÛ?éýØesvÇ0qB‰ßŽHÌ3Ã]â„ê˜Ãœ'ž±®fdS]Ïjbm•«ÂªÑ™Evôñ3sÕš±%‡fö9óÌu7õ?ºÒÏeqÔ/äŠÃD¼[ /e¨L¢Y“ð®X¦Ru:¢L @íž¡¼Þ8!iH# ©Ê¨ž"庥J.«G”ž4Œ>îŽQQ,L,†7¯Åν5U ”L8ó´P5´ûŒvB±ÐÓ™0PJzW?;ý†›wœæô]EB1ÌZI[†¨ØÁ”!©&ŸzBþþGUÞA® Ê ÖïI½&“ˆã¢ôLfqèÏu/9´`_Šb»ÿ‘‘ÛïÏeôx%Ÿu*®z¦RÚesŠŠ}ˆ5 ¤ŠR͘^5™JKæ¢8rJ¦ÞÞðçDÙ³X§6¨¯À€ÈùŒ®TÚ5 T»£{ù£•·z]«X™IYÖN­&u‘U>–°@Ë_ܫ٥dB4FÔn)¯Ó°ýÆ›ùÈÃò‹v…ü1‹ª$"LÄÌH¼kâ(,œ_èiï/WP)ÀkA[Q/Q Õ, þ•Oõ¡Ÿñ û  W^3ñÔxÅsß…¨ö6xÈqb~/Ô‚C¶PªlÊŒÚþªÒæ­z½FÓô£ußïÔÒ§Ý<û#f G#z)— 6S ¬®N„­÷V–Ë&›LƒŽ'5ÝS °0CD&°ÕÌ f“, °ãÍKÏ êïÿ¾þÅvA ck5(IvÖ ‰“VÙ-;AB8qyá?oõ<¥t€à¶Žî«W“ëîgü&{ü‰¡ãÛgðß~¶M‡+ÌžS!³{‚´TDBˆRyS*7Â@ã\Ó×8¥ÍíDÄCIb1«Ð§´Þ‰|ØFE”d'»%èC]D쩌=¢0#bY‘…8Š‹yCœ¬%±CdT&€(*Ž¢p: †¨€ÄÊ´“F`…¨Qe³ =ĬÒÝÚíTzª<‰P5ºvJL²É¼¡Õl7nïÃÿÔ{ÞÙ³§Ê ­ˆeQÉ#“!fhpظ™ÀsT,”tvd&CÂSOn¿þ÷ƒG“-i§m*3`]À0°â¾î㛽OH¤^_û\ÍëѲ×Õ6 ”ˆk‘â[ã*’Vö@ªø¥5 ä‡v…½ÄÃ"!³/⃄ ˜”`ÇÇP5™`E™S@¡À ¢‹èjT 3ˆYTYDOa›ÒíZµ£ÎG .5‡ûNa®é)ô”EeQµ+˜aíd¶XPˆÅ7 4Æ?+Õ…øŽ’4D v”‰Ç‰©uA|A!#bA¬ÒmŽ·0›]¢õ @¶‰ÓÀcSÛÎ&Òª;äš{oøžqZwÆ›RZ‚0 ‘XIÙ¶DAÅ~ýŠAIH00óÂÞ—.?HkÕ ó9ïàýõ† V©@ 79%‰‚#ê¯p™í«Ÿé-u´·ïýHøÛßô9ŠË£ÙBv 3Ö–©¥Ñ%ÎSÀ]SñŸ ü•Öôj¥²¶ º(YÆ°Š Ì‘DKÍ™ÕÂÙ'`AŒÊBAŠÂÔ8ÎÛ1Â#f\g®ë๋Qe( ™²H•Ä{¢«:Âp`X넹Zå­#¶ @EŬ”Â(;"J>FÅÑWut ¨ut‰ •ÆèQ^Ü\u ¨¥9qÏDþ0kÁ2F‚|ßZKL‚š”2 aè÷•”*d³GzÞ‰Â5õ'QV«º‡uõþ•ða¦Ìï®ÝôÎw0EP, T-—ˆlCk­«Äu”§PG  ¢”¶›_ o¼qÛÌm„pÚiÝ?øÞÖ\ÖG•Ç”kª*ØDò†ª™T2î¢ xVxø¡ûûßtæÞŽ„;¶ûkV• ] •—„ãø«TÖ@³ Èºé„ãã+*þã¢TVë.Ä‚@'Øé¬Šb»²… dÕ¬ÙnG§#ˆ ´Š –ÑQ¸a”Y”Úb6†%2b,c‰…-Ëd%4ÌÌJ1k TÆÚКGʲÂuçf²Geœ™1ÆæH;H§1"Ôe° `ÆåûÏ Œhèxß™7ß©T (…Z#‚ÒŽŠ‘§Éð%¡Âä"¨TŒµ"ˆ ±)Ìer¶5àk©R1Ãæ·×ß°¾ôì³#½½e¥}€±Jù)¿üT!¼ãÌ”ÈîD±UªÉg×àhp0§±M ï¶[Ü·^8/›Ý¹Ë …… Yb¦ÍJ<} xË4‡B)Y @;N¯†ÜPyBqŽ9º+çlT¬Ffªa[ªÞ{ªê悎.(Éß¿bË›Î\´—{íÿôÇmÙ A˜iË–4C5i(–'"ÛdtWÅ.DåU‚Õã· X­rZÈì/r˜ëNs3ž“1Žg¬(À®“O™s 3â´ßVÀÚHP¥Ùh"""ÌÌÌÂLdÅ[ËåR8:jF†Mo¯ÿâ‹ãë× …Ú©°+ÞZQ…báXÏ™%À*ådTMز”bÞ[PòŸQ×ýÊù—+Žtm-#bÓ ÷&âZ"¼Rj·¨ˆÈÌ1›?_?\…ÙnÙ2vïݽ÷ܵ-ð§)g´Tz ë-Ìg—‚)@®)—“ù;P8ç- ïµT¼å¿6žÁA;’ÒbUR¸#Ò|3 ¼œ(îc-IÞ-Q:ÂÀ ªâÖ"TçøÚî_1ähA.#º±‰-W%ëÎ/û/¾¸®sûö‘3ºöjÏÄ=}¹œTœ|û°P, Õ2ΫÁÔk 00rs©¼R;­:ìÐò޶Œ—ŽÒóÉ ‘ÑÈó …¥ö4ÃKDRWÅUĪ…†ü \ùXÿŸWô®~º_à €Ñ‘±®ÓÕž?N©Œ4æbÔLG8AF¢Ê9ó*Á‹CCxÍ•ëÿꇺ/_6,âî;“µÖMw¼ òï~ïÌw¼ûkµö–›6ºªÝØÞñÒC…üÑc÷A´f-­Õµ˜qs s¤vÜö§ ç_pÀNÙ‰+²šu”bœ.Q *U1&’âm°ÝšáñRÆÊž[ˆ²œZ áOŸyÏm}nA39ª=b¦ªÎv )Ëž(@ÎyóÇÊOjýóÝ[.¸dïEÂ?ß³U1+Öž[6IëÄ–uÔ(vûÈMÿEí•Ls‚7vvLw³#"£`jž?P•`“X3>>Ûyj® ¯Í×pòùNê<á¤Åý£7ݰáž;7)ì¹µ-wDÆ›[M’à”Á_¥ qTA'V•n 1C²ãž;ð”7ÎZ¸ß^MX@«ÌÛßµäØãf}û+O•ÊžàŽRéñbî…",0©+1µà”󌕞(®YÝ{èa;‹¡ b™*ÆF¦òz¯JÊ:¨C3hëûã&4'ä„3g¦Ïr‡ 0@mƒ@]ý‘*ie‰- ˆžÂ–¡ûîÝtÁ%¸{çVÝrÓftÅǵ”^*‘¾-…Jï¾¹ì¯s6¹.ŸÝÑô‡¶Î4Õ˜tC3,”óC_XöwÃ_Ò3­ó½ï?êìsÿè{O?¿&§ÜÂpiM6(ædN»ý9ña+©YmcµTAe¼E#ã£8ÿöý§þß7^¿OxžÐó/ß>áò|¨ˆ Œ•Ör%Q­MÃuþo!­¦…¶¤aô¾{6í Eåû” mÉ7[³™lIZ{³æÄöd³˜ªRúòË/oE€é±G•Ã,VÀaa±"\;9ú$af&f‘J°yl${Ô²YÝ=m{ámÝ<~í¯×{Mì*³ƒ0#EˆNŠ/@Àtdü ¥ÛÌÊà›‹c,¡M–ÔšX-=ÆT<øÐyK–ÌwÝW§à@¾9ùÔÅvoåce¥Š–†Ó«"@ÂÑ%þdŽ¢>"å3ú“EHXD8Ù:8¨gÍn[°°cŸÀCÏÓo8}î½wõ•+AÉRXda¶ñ” ™S›Î :4½–+Cƒî¹ç8¹ËmÿÚîº}ãÀ  bC×R›PsS'SWt uu€í´¦½£³ë’w1sÖ ×õ"2Ý:}ãÔÓçþôÇÏ*EÊŽãLoªY@Ž3ËòcˆcwÝùÒÎÞ ·ç¦?mP.Òˆ£–­@ƒ®NûEtÈö ŽþY«¬‚§çÚ‡CKM:}**ˆ˜Œ0¿ê“=ýÌÅÒõÅ~¨ì#ÃŽ‘ñ§ ÙÃ9­Õ×¥·påêië®úùS'ž<_‰ vçs_>îï>|—¥.¢>À"¢ÀÑü'=‰‚ Q”šnìó[{û{{‡gÍš>)'Ìüðgoxià±ftdxlt$ÃÈ¢ÖBÔEQJ-\Ô3}ú4Ï«€š(‡Jµ¬{åý®gÄD•Ä ¶ 1£qšåá÷¾té—í…éÝ·oÖŽ²F£Kåë@«PaTJúGïQˆy‘rÅИPšä—úeVÄÌD"{Å|-êúæ÷Oý‡¿»gxÐé+¯ÉeLâl©NsÂ0(×]T_ÝÛ—¹õ–ÞtÆA°]ݹ~ìè/}áál¶;\g¦´(çØjAv‡4ÊvüÙUÛ'GÂèX¸¨˜{¬%‘È¡Ì-ÁC„µã8i=BãÏ›Ï[XªKN`Ç­%²d-%†¬±ÖR|²¡õ•;ÏÐàÀàÀcmÞ댢Þ\öCA$ð-EÕ¨“ñGL”Ü!–Reƒ_ÙÄâ1/Éå:‰J†¬%S]Šêiâ“M´­]С±“åÈ ¢R•±gH<s,9Íb’tUZ™Æ½D—ˆ-[)ÑΡ¡¡×½îuøÀ.\844DD-‰®ÖzÙ²eW\qÅÇ?þqc̹çž{Ýu×üñ]]]¹Ü®!CwWþo;üÊkžÈe4ñê|º6q–ä`åÍáÊC!o¿óÙsÎ:z_AÂÓrÆZ«)eqiR 2 £M†b¦0 ßX;E’úÞK30è{®ÂšïUYK·ßùÂ}w}0—uwGŽ3Nßß7†„HÂH‘­ Æg(:ƒà¡ÿãÍOí ÛpÛ]Ï;. *âJ”ƒY)NFÂÞÐ Xr÷_<˲f„ÄòdIˆÙ2[Ëqub ŠÊkSv"S*e}á…¾ç=ïikkëëëiu nÛ¶­­­í½ï}oô?ô¡=ýôÓAìªhzÙûÍeµa/4ãD­×¡qÙÐTªtÓ-OïCâ("²DLÙÏ¢}ŠJe3Ô6‘c…‚ˆˆÁ²S’kK7å Ž“™†îtåNSîtåvg²Úþù »Ï àmo=üwxJwhEeÄ,ƽYãH Çj‹VT(o–T6?õô†m½ý³gM{÷à¦[V6y•!.S̳& ù¨Tiìib•·|ùk^Üì° ˜É*Ǥ’ 1YÞ) ^}õÕ3gÎTJíØ±£a›[îúèèèÒ¥KDZÖö÷÷ÿøÇ?þÈG>â8ÎôéÓwáÝp¼ï=GýëîËeÑR1ƒÈÕ}M”`œÓ ("Ú›N•÷?ôœ +®·oH¤ÛûKÄb•ÒÌ­LM‹ÍÄ!YËl%IaÙ‰qE ±”í x®ö IDAT,@šKAq& +{„„û-ê™· £¿ÌÑ* eÖkº½¥(å΢±gK¸éÉ¿}ÿ_Å=øåµ¹. êÐŒ'CMVZa‡P!PÙ/¿Dœ]ºdîüùsC»9§Ü¤›úµÐ‡DaH ¸sÚù£ýhùòå“Úô·…BaΜ97n€n¸á”SNéèèÈçómmm»,þî·¿æ;ÿ¶Â°«¡¬”® i-Û‚Ö¦*¬Ü4¾.´í÷Ü÷üio8rŸ@ÂÖm 2À”ø’ ª¶!±!fÀ©f0b¶qŠQ¢Ýø•m&(ŒŽ§w àâ·,¹â{wçs¬ ˆês×)¸-vŸP¹¨‹ÊŽýá¦Ç^E$ÜÞ?úôš­íY"1-*£ÔÙœ ²žÉ„T8ù¤ÃÚÚ: I jµ€›y`ª-¯Ä>»Ó¸µçŸ¾¯¯olll7T3r†aHûމè¾ûî›7oÞôéÓóù¼ãìZ÷³N?è¦[We] ¹òô„Ûš'f…å»ï[½¯ ácOnRŽa#"ØÊ0#PG6Q)kLjØÉ€Š xìäˆ8Ð5$Dmüm¡í/ c\wð’·ý•ïÜnÅQ¶ŒN!Ý'¨U- *3GÌ /mܲúÙ—;dá«ÄÕŽ€v UD¸Us¤Z-CUYcÉioë8nÙ!¢ó‘ó½j•Ia/ÖX§:H 3Y¶Â2¹Jxíµ×f2™ááá©ø‚%¶ ïû5ðzì±åË—/\¸°§§'*ã2õ•yïÛ_ûÛ×®£Ù•­£%P“RUKãr¨ÛÁޝxèÙ]iáôjw¬XƒJ,‚Äé£2AÓ„$qZ±²fÜ’tä\Ï›’¨€,–¹©ÚÄØ[7 æ(w GŸøºE>ú¢«ÓÁiM0“0ÓmG*J•®»ñ‘ϾJHxÝw=d±%jš—Ôõ+Šç ØŒÙ`  öS^{àŒ™3‡Æ+–Ä*Ô Ü(Ä4·J@bŠjN>°{î¹gllldd$„“Ë¥J©±±1ß÷«w6nÜØ×××××·`Á‚l6»KHxÀâ³gGÆJ  ŠÓØ‚t"+)z¾¸yóÖ¾¾3gÎØË1ð¥½#=K±‹"ÕãFêc¹k;¬M8B,ùbFkgj +$dÅbœ^* Ä!kˆ‰E'Ì𞪠óÞK^{ûŠUEG¸ŒÊIzUëã71DDÝN0ãÿyÛ£Ÿýä[_ùÂ3>¶®o`¨³³È‡q}/hݯ ÑõGŸ5‚†Õi§ÝÞÞ1Z©X4‰M© ÍI)7£a&¶;µŽ®^½zÇŽsæÌ1ÆLÄýŒ1ÖfqÇqÏóV­Z•~Ƴ}ûöþþþR©ÔÙÙ¹ÓŽ° ÇÙgöï¿\‘Ï ¢é.p8q?6±éä‘’¡ÒÃO¬;÷̽ rͽž'¬¹$2Ð!©X K4vØ3wV‡vÜ)‰£ ĉ‡XsP1[6,—d­)7‘OHQÖ*}EcÁ0EœpçøÐ–Ï·2¼ù¶00?ûÅ/ó…\Ï̸À^¡£»P,üñæÛxðÁR¹tËm·w³YWõôt5ë–ÖZcLÕ‰¿KÇAûͱZ´Tãê5|Ki¦&‡s(™ Ù%\»q¯Ë-üÄ7¯ü«OÛqEç\ci,¦)õiÜ;ˆÙ U¬ ;ºÚO<öˆL&;õ@ AÄ S?d‰‰Ùʤ>UgW'yÑÇ]{Ë}W#BdˆýÒ2AïH!hë–á-œkþtׇÞ~Þ+°WÝt§ã*RÄÆW" DJs¨ØQ¡$·¥a_eN;éµÝÝ=Õü 0Z6Pms&Íô+ÝìQ€@¬ÐN­£Ù\nóæÍË<»æÙûxdöìÙjëÊOSúÊQ‡û† ôgܲpåÓk*ŸÃòÒÃ.d]í:ýýýÍž fެ2»§žMŸV ­q¢F)·D*!åÔILP¬C¸~Ó–½ÇeÃ]}üŠïÝ1œ/º:›%aKUßQm§ìjÕNâšËCáhYe.~ã Ý=Óv)YÌJh%D¥ªÞ`&ÂØvÙ´õ‘KÎ.•`qdŒb¤VºQD$Nm±$ÊqÙ\ý‡[_‘Íx°\´£…8ê2ÁV¢2“ Q½I°;^²‚œsN=±Xl«R>Af¡èaN}Æå*„™ ˜ã³µL;— {º{ÖmØáø‰'/6ø—S]çþËO<é ¥oyïkÎ>çЮ ¹‡>{ûçÒ pÒI':§2>ºá¥Í- ­‘,º{êÙŒ®NÚø\Ý8fŽ–(ªOÊÂqÖ0 ‹RÖnÞºvù_®cpxì?ÿý~g¾ÿmÿ—Á¡‘b>ãxmlCJIyÜh³¢…‚x+%½Q¯QQfósV0“+¼õÌS‹mí»àõ‰àŸ„-H¼t,$Q'ŸÉ—h—9áÒí?gÖŽÁ!AW»#@*Š-qÀ$mÛ… ßC½?±jÓÖÞùsfýEwå_¯¾1ç:W†@j¡êZ%l —yè~‹ægÒq'l…)jL&épf™ÈL ̵ZÚ BôôtoÙ²ù³Ÿ»âçßúÜßÎ_wúéÀâóÀí (ìÓŽm÷-ïxjÕ¯½ëñ¡CO_ `¿ô­Of"Gdæ]õ×ÀÂ=ë6l‘jw£ñ>î#UM·‹x *¿mGRøý呱u›zŸznýÃO½pÇÃO¾¸i›ç9Y×ë(¶)/ \‡ZI͹›ž]õ”nV¨ÚŽøà½ã´Sö[´°P(L}=,3 "%]L™,‰ ü²"!|ðâ7}úŠ_tä] m”ÂÔ\Ã1åMQ¹è{Ñq2W^Ûg>òž¿ v¬t÷ƒÏôt´‰!Û,)qj´Jiéã0 ${îé'wttzž—BB‰m½˜ /Ô‡XVg#I@1SÄ@&g®P€~þÃÿ{ÐS§Ÿ6žvÂ1L( =‹¡½6ÿש'gdèÊà××:O·°‚ìÖ5Š£]&´ÇI«ÍIöé]f&F…Ö­ßtÕïouÜÚ¢qTÓ›‰¢"6"d©*E÷‰ êên‰m$I“‘!&4&4Zã¶øãã•R9(A©T7´­\­=W»ŽÓÝVTN €py,Õo0 [’ú†çQÄÔï£(°A°y•ÕÖÙýî Ïé™6½¦ä£`±œÂ}`z¹9!\zÑYŸøêÏ-ƒæœŒˆˆJ´Œeo‘ä:š¼r ÓæØðÊkoþ‹"á÷®þcF;Z9š„GÞfŒ#è%Y%ô^2Œm]§¿¬j’I[%îùÜÔÝ£™˜>@TDžEvÀ=^±o]Úõ»Ï ;@M»ØÔ‘ŠHSȆ€ˆyÉ8å/|bFÎuþñ†µ ²è"dg[ %Íl1éP¬’nŒ•¦*aED7÷]öß¶ Ò ‰±š'–¢W©¿R½ £þâq¨ƒDϡ¨OOÔW4îQŒ€m¹,æsJ!hè ê¨û8ÃÁXjÜt'õô¤žª *Ó& vþÏ».Øñ~…bq×Ä{ŒZB ÔÚg!‚0Y`gr·ñî a.ç~üQ+~:ë¢EQñB5 ´iˆ(«²ÓphÃÚµëŸY³né¡ûÿ…ð'×ü)£4ŠÃÖ¯…ÒEô J¡bë‚â°lG·œ9û„×Μ9+“ɤ×]DØpÒ YꪰTå´Ø`AOl$a&ØYìèö¾Þ{¿°LA6B0N[}+_¦r(eËŽѹùãsV÷?ÞÐè'ŒÆi†»‡Å<[ï ˆÀDÅ.j" zLÖÕà¶µ£Î&ä_êÌ ØT$¾VõÛ!e&f”úƒ„I¬®$%* ¾ðÔ:#7èu¶C@JýÏý!xË–}ÑygNÛU6¡¨îjŽ;é‚bYd’­qvÖÿî½çÝ|Ç#^{ºN“ÍI¯€@Vg;ÅZÍ¿ÿú¦o}þ£ |ð‰g7nÞ1­»ƒŒ²©ŽðÉHRýâQ©ph“e Rœ}j[[»nÐÂ1^V@Ü™í!¡æŽïÔR±cÛF7;²þøÆ|qÑ(È6€íI^¸²ÑåMyU óóKP”µ[uccc‘—b· 3…\ŽBf› ’¤jBFñˆã›bc\àUP{$&{'ï§Ðmçöi/_c_µAFW:±>][ ±–U++e†6û½Ïp:º§æc—Î7/¿+Ú`"‡˜È¬EQ©¢ˆr¤+BÜòu÷S™šÓN:º˜ËZ+†àäR&m™08OP¹í:ô¯¹þŽ¿~û§È»‚#ÆÄËMÕíLÑÂHW7Z«í¿è¨¥‡f³M!ª€‡*@Nå×c©Ffb`ÆI¬\©Àw®ùÌ×¥xðàØÚÎü¢ñë+ ©ÒÆva,Ò.²°±ûÛ·5ÖSŽbÖÂ04Æ0ó®Ö¹€b.U]©gÝ\›v¶Bd8 mQ]±“”Î… ”Æ‘–íÈ¡unKÔ½^5ÿ‹Vœ”RèJÀ, R¹Q_ùTADG…#[Ë[W2hpò_øôÿ:üð%]î®·DÍf=`0!¡'˜*ä(Ú ž˜2ï¾ZÙ»Î*—øP±–¨vޱq=$ŽŠtXfËd,æzÄT¶oÚ|ÏýOü%ð·7Üã:ZD±5‘¥äd#ÉÀ„-3‰4•Q å¼3_ßÙÝíe2Í6g0Ì›ž…DLÒV‹DŒˆ©½_,‹e1ÌD‘•l’qÞuçðÏ7®ýå×3rÛ1‚awt}G0’±ö‡²£ë;Ç7²‹†‹GôBç(8##+ÛG²ÿ¼ôM-b¸×¯_?>>>>>¾{þúB.+$jdR›,T/"J”Ü!`Yá•D„¢“@XPâLˆÎÈ @É3\{>z1¹HÝA¬¿S{´ø‡‚ŒÀˆ $9P #¢Få„C›Ê[ž`ÑÙþäßžþ†×Ïœ9s*­ê›öBî’·ž6>066Îeß ÂŒ¥‚µyë»= õÆã# ÷åGà£ï;ÿëßùmÞÉY Ðñ€Y)`P¬zÚ'é“ÚífTö'WÝøú×½Ì5ó~òËÿ®„66NR]®Š9!*å¾Èà€—Ë™§ä󭢓$Ùl N i9§‘š#cô¯& ¯¹æšèâW[÷sùòÈ—:Oz0c 8Ît?{`?he¨FŸ\LúsÈùº»çü³g_þ…/4¼måÊ•guÖðð°ïû jíTGk`AQ±…¢šD_³ñ!Öùí4ºUÀµwâç°ÞíŸba©­‘É‚›Sµ‹Òï”–‡Ò˜cŽÕ¸¬ dIˆè @eûd=ƒ ˜ûäß_zÉçÌ™37—Ëïv4ìo~øé_öÖ—6÷V*åÑ‘áJ¹ÄÌ…|îìÓŽŸ9cÆ$.ÇÝGÂys¦-;ò ç_ØäjR‚€$*d£Ò’ V (èæz¤2þ»ï¹ú‡/sÌwrc1—ÓÊb­¢F(êÚ³ ‘-oq^·üè æe³Ùf£&YqJ´n2paƒø$(ÕnÉ8$Ü¿ÙÙe癯ë¿ãmÓÎxÈYTqDÇb´å±û§ùÁ'roøP®XdSܶîÀÅ‹¦÷tïL¿ÍóÀqÄ£££…BaWE)Gk­jˆ€Øx e” aP¢DTÓc Fl0¿´z¸Ó¤é-¿ëR¡PˆõS–[…è•Ç{·þ ³ nñ³ÿ÷o/¾àìùó‹ÅÝçÓDZG|ìÑGfrk- 3‹ÖZ)=É›÷ þÏ¥ç—} € ’S¡ bÁñ…BQÈ’)ÌQìû##×ßxïˈ/¾Ôûôª=ÇU Q$  ¨xÑ ”)mc"°ê¢óOokkŸpTúUµéÔÞV½V‚(I"ÙÄÒèOúÓêõÑG,q­¦Ïʼá?·ßþ¡ÑþZë¿`GïéÙþÇ¿¡Å+ §\eƒòòm~^|ÑùÍï¼í¶ÛÖ¬YÓ××W©Tv5~ÅÕÑŠ!¶œ×7UDx’ukž~Òëõ/ ¢õ` u6¿<þTM›¥P¡FÐþð‹£/ÞVFÉf»¦ÍýþÿôÎKΟ¿`a±­m1°žJ(Çõâ™Ü¹?Ô3çXØßkŒÕÊ+—ü·_|akiü'?Y¿~ýàà`†»´tÄ‚”Ì.Ú5†x£É2Ô‹À€" €Â(ˆ”€{õ™4þPš4«ÚJ2Ôã&$_U`U{'#rõ%Õ:Ø«^Ljª”h ®- Œn¼»ÜÿŒ-Æ=þuÇÿâß¾|ö§Í™;oÏyàžÎþûKÎ?ùúïÓžR(ªVÀ2〄”pèeg€?xó-T*~.—}Y¦ñ‹_Ý™ó²ºDaâ ÆÄÞŽõ®#eMÉCLÙ³N;aÚ´iy„@‰ŽÈmâM¿ c!;ÒˆA‰Ža"Wýå—_>6§’´·µÍž=«âWÈZ€°ž‚¹ £ÎòTHG#¢%ë³ä°CçÌž½uÛ¶†7/Y²äg?ûÙìÙ³ …Bww÷ÔAŠ,)H8[¢:Ä>¿x]Pâ8L* )&±A%(‚UÞ©®ñâ×ï~Ra8ù*)Q”r[ ÆJ(‚$ªL¼›ñ€„ã+aˆG)I!5IB` BÁ°Ü[yÖÃ$®P¦ÐÑó‘½ã¢ Ïš;gngg×®ÖÈzÙ=ÕÊþîo/ðKÁ2Un£” TªJYã Èfçd+×üæ¶—eºõ‘Ñá’çxÈ‚ ªú[±dR÷ë(*y D»^pZ±Ø6a¤¼€Q‘˨"Ñ4EéUbˆ‹&ÍT@@”j%®ZµêóŸÿ|õÏ7¿ùŒñr9ð+Æ„& M¿b*%ã—LP6¡oÂЄ¡1ñúK\öƒ¿þ«w6¿|dd÷»ßmÙ²¥T*M½‘“(AUãùÕLVR@ "'ŸŠØ ¦¤†ø%Õ¥VÕµªqHP ŠAU côÚH"˜©q㘹Å,Qů‚ê3ÉóX]% Dit•x`Leè…·Œô=úãÖf•j¿èâ·üþ7ß¹ôýï8ð€§M›žËå^õ¼ä=å„G±xÑÜ™C㨠]]×û]ê8GµÎœãäÍ]ù‹›ßÿ¾s÷|ßÿÁÅLÖÑY±!F†”™!eØ‹¨¦òK›H܃;xÉaf³“ì")dTUOSRtê˜<&<ŸPIkkB©Tºà‚ ,XÕÏ€·žw~¥ì;ž r&Œ OÕ„®°T*þ;Þvñ—¿rEÃ÷ßÿW¿úÕüà‹/ÎçóóæÍ›"x™Ð*Ö(ÕÇXoéÄÄõ[3±!j± Ö¸€UÝ|SÖ–”ѱUˆ ¤¯µ•¬k€ kÒ`û‹˜§B¥˜Ì˜_Ù”·˜`P ;d N¶xÞ¹¯ÿ«÷œ{È!N›6="¾{y»W !|èÒs>ÿÅ_ЉP;Qí~©šé›¡‹ ëÍâʶ|j{ßÀŒ™={òë~%¼ýŽ'º»Ûµ8Ä~µmRZÛb”w0ùb çžóú(b{BÕ°ÁÙ9!¢ˆJÄZŒp*-ì2o~ó›/½ôÒO}êS±w.Ÿ{Ík–—ÆÑR&“ilÔÔ* ‚ Mgg×ëO:ážnø‰+¯¼òÃþð—¿üågΜéº;/×7>æ+D%*NøªR–†HN³T‘_!R·j-Ǥ&2¦¬Æ‘ìÉ)Ôú³TéÝø·Q%-âJ}t«Dá² M8ø}¡ß† +â2„°{úÌ·œêÅž¾xñ¢Îήb±-“ÉL±®öDÇãO¬ýÍoï¥T­ÇzÔoZÖüð³Ïmúù/n—$¯ˆyÙ1½íâ“_6$üà¥g}î³WeBÜH)B˜¸H6;»\Ú 8¸ê—·~üïß±'¿þƒý1ãzžÊ‚%äaÒšIúB)§2¾^Às½¶7Ÿsr>_œ,a,‘Äbe&Ñ{0Ö]ÍBŸxÔT½ ñcûØ 'œpóÍ7W¥Ä·]r1 [K Ì\™ D€)ò¦#€”JåË.ý@3®^½º¿¿ÿ´ÓNûÜç>÷Ýï~×ó¼îîîz,Jã¾DÆý¤¾,` S³  0¡(¥…ãÒ{)¬ƒ(<=ÕŠÃCÊ›—f(u_5NBa)²£ßþÖïðË_úuwg{{{·‚DÅnYÆ ÙÑk~y÷ˆ„ðÑŸ»âî§óWEÌDâÖyK%n{Q9„BnÎØøÆ5«ž_¿~óâÅóvïwŸzrýÖM;º{ÚD7H•ªÇÔv!‚(¥GK˜ÅyË[NÌ=˜ˆ£ÑQµø8íñ¯v#aXa-Ö÷ýÏ|æ3ý×ýÅ/~±úÏŽ8âð…‹ DA½Ì Žv2¹B&+*L6Bß/1‚BU z"¶~^véû?ÿÅ/ÀþxÔQGßtÓ`Û¶m<òÈ;ßùί}íkGuTä»/ “КÒhÅQ1™þÿì½w˜Å•6þžSÕᆹ“¥åœ# ’"H"À0ެÃz½Ÿ×im¯?ïzý[0΀‰Æ'N`‚M4ˆ` ’ #iòÝ]u¾?ºoIäywõÔsŸž™;ÝUÕuêœóžTâid†Üºæ›„Ÿ°‚))HP)l1¦P©ì M‘™•â\Ây,îëû"İJgš2Ó3é)¬YÄZ1ûpí¨“S$D¹-ºO.7‡Q^«\ß§­eÂ9çœj…L$Ì<ê¶W+‡ÉÚA‘"Ç>÷؊ÕÁàw¿}`ÕêD(Œ½ýëšš|O© ÜC"¸”ß̪E³ŠOÞÑ9V­9¨-—b(ØÀ!r‰]‚CÐMä¹Dš9þ"Ò¦t7£â;öò®}ÙÏýη~M{)"šH%÷‡"v šÈ%8DšÈ!¥¡Š…$nט®£Vì=¸¿wî*RDšÄ!Ò ‡Xéd^ˆ¯Åß!‡ÄUÌ„XÛˆßý…^xòÉ'¯]»V)ÝÚš¤izï{ÞSÈ—¢Ð„QH¬ºº»çÌ_¸pÉÒY³gOž2uÂÄI&Nž—ö»}[ŸfÖʉL%žï€GG¤*r›¨h-æ/˜öþœg-ç ÕJ)¨„ñɆaP1aF‘5QW7q½‘$Ô\D€(ŠîùóßöìpÑÚÞılNñÞPÃ…M š[;/ƒÉ£f'?¾}ñÒia‹»Ð“Ô?'+’J2Z‡W\ñr²°}çÒßx¾ç¨”1å’÷Ý*>"DÄ,dóÅ-"΂ù³çÎîû©T$±nYP#Ô_Sý„º±ŠbÕ×÷ýÏ|æ_æÏŸÿä“OnÞ¼ùe‡nذ€ãèÓN?Si=súLU‚ Œ¢È˜½{4¢‡¡ è\”Ò³fÍRZ‡‘©!±þÀÅÿP5`ÖÿíÐCP*•Ö¯_ÏÌsæÌ¹âŠ+6mÚÔ××÷\…·ïè'­¡¢Q÷zŠÑ¦dUI"¡1µÜÜÜdll*ÐZ»Z»ŽãÅŸŽã»nÊóÒ®ë{n*¾®w7w×M9NÊóRg³êÞ‡¾ÍO¿8mÚ|1Z.<Ó7ü8„ˆ«ª*°øÕì”@A XXfßurÊ­ôööuø?n{vϨáÛ/<¡\ ˜+A²D´“Sì)'úÉå·¸òÇp=ÇÑ^h#!±Š¢|)è5¿jYs®%¶!¦±ò‹Nª” ±gl"‘8ÙšÕÏ*‘ÄKȾÛÁ\¹éçw/Íí¸wÏà_|Ê÷<ˆnx œœ75.˜À§XÚildŒ>锣š[Z½}¢÷Ë I¸J[ñȫөR;®Ž$DéhgÏž¾›nº©««ë7¿ùÍi§Ÿñ³®O@Ñ·œïxîĉãCAíÕÂjŽˆL™:ÕXS(–Î:çÍ5xéÚk¯¹èÝï¯yä‘r¹¶*q k?åµi§R,VóÏ[G›-šÚÝÝa,[kì±™Ì8Pé¾û36ºöªÛ|ÏU*-Ä@ž&h1Î)§É4i­G™ßtîJå(€ –%¡@ª±©x)™„%›™`¥Ô×·çw¿½ÿ¥Z&|ßU:e$õ’jñ+Ôð øC©Á¡'‰œTªéÄ“–gÒ/Ú[—)±ºÔ6K¼ë½¶,`hí|ç²oÏ›7oûöí}}}‡yäÓ7&šóù´µ4‹PîËþÌ‹iaºZw´·CÄD‘«õù¼­6Þ§ŸÞ8oÞ|»ví²ÖŽ?þ׿þõæÍ›{{{÷­…øÐ_ŸVZ±ÒBD$UvX[:ªÚGª?TÁJ„ÆvwòéÓ§“thÝÔ?¼AÈyä²W‡D<ò”g„Ùõýv¥ Ã…¡ŽýøžÞ¡ÑäùT""¶0‰ŒÀȤNj”•O|ì»›6÷hÏ­ZšcAÃùÍ€3mÆ”%Kæ¦Óéx޲ÛÎé§„ñZX&¦¸Ç{³ö#1LB¾?†X´c®¼ü¥I¤W^q{*å1Ò"‘JnX»yص1¥R¥ÇZçÈåK'L÷¢#_Ä ÄÒƒbì³zÿê5ÀLÌÄ Eq ¶´´ÞsÏ=‡¼ìþ{ïowÚi§·67gR©( ãœ/¯EQÔÚÚoÊ0 ÞòÖzöº_þ⦷Vi2æ~S¦L¹÷Þ{7mÚ´cÇŽ}þò—õŽç29€€F¾¦øZâe$13ë0ˆQÒÓ'(~U‚:;[ïºç¿–¾DL‹ÖÍCùMÉ»ˆÇ€äupu/¡ñ¥ƒ ,Å^Ú£TixxhͱŸ*+£)‘¾sM¥bˆ|+bb(•quNéð§×ßîyŽV)kƒX±.Wv‡¦EzÍ Ë“hŒ2¾ë½'–J!³g¥Òè¦ëJ{u !ê—~ù«?[y±µÓî»÷Éž]ÚñM£ªE‹¤z(ÆOé¡üf™È=õ´•¹\ËK {¥K`í†õ¹T…ÞÄå8þÚpaÛì¹³ŠÅÒÆßtî›o½õ–äµ½ým c"kÍËîÆDZ)G+bµ··~øáU)tÝáG™ .==år9ÆŸî¿ÿþmÛ¶ î•ãÏwmp]‡È±b'¯^«A`H<ÕU¥ÒÑmmííÍ£+Lí~ÿê3Kšc£¬RÙ|a“$Þãõ¥¶ cnÜZH¿öü¨bOÏî×üË(Ž­­½iñA3"kAI‚ØTz|d‹V*Ä"H ‰…UÒCà ®¢Ô)§¬ÈdêâØ(¯à’%S»ÇµËÆšºNQý뽪勤Ó­ðpÃõw¾XHæ;kS)—(Qz5ºyÖõu"~ p»ÆŽY¾|i*•~ ¶£ªÀc«ðRï‰gµ§ÇÛ ®È:ÔÞÖÑÛÛ `úô…|>ök™3k–ˆy,°Þ ¢)&Eƒò›Ï­{9ŽnnnÏçËår©Tjkk{ðÁ·oß¾gÏžX«¬}ùOw<ª]Çø^ z¡j K]“H„@b”ƒ>O›>þyÝßG§ýfíç¦LŸhmäKÏs‚!ÕtCÚK1LNɪzh•õýÖù'žØröY_ű½ã«ƒJDìX ãÇY±™ÌcŠ‘)TQ] "°˜áâV wÉAó¦OŸÔ¸t£Œ½ë¢ƒÀi±‘ŠÉ€’ÏZO~ À÷Z»Ž¯¼òÅF6Ý|óžï 2 0–E«÷¤½îϬ+a Hä¬ZsDGGÇKHãSd|Çš„Fõñ˜”"p;Ç´A¸sçΉ“&õ$©(N;õ+FFä2b_f·Ö0H3)&EǬ8ª6êüpaÆŒ™±³NL„ÙlvóæÍ;wîìééi„g¶>³;_¨hå[›×¾ËH o˜•µaå­ÑsçLu]ï5ˆ…]»öóm­m VkM¹ÒÇ\ÅñºG¼úø¯qÀ£ë¶;NÆqJ·ßþ×ÏöšÑØÙçfklÀ¤l9×÷Û¢0q‰c]‰«BñY‘Èuò)ËsU\ôÕ" Þv|&רr 5|î.–Ju •îºëáÁ¼ÿ5W߈V¢Ê>¬uïNì ®'ö¬8§Ÿ±2“ɾ4Â: çxP㟄EÑP[[[©Têëë[²xñ®;ã;xÂê( ÅZEÕb2¶Z@ç¥u@ –xÓ‰H&“:ø $q–ãêöövƘJ¥R*•b:Ùºuë®]»òù|͉ü77?èùšÈEû[½Æ‰×æ¨Ê•>ˆXQK–Ît÷5ÆkÊù¿øÕ§ÅjVmaØE%0í³øûíĉ3¯M¥»XÃu+ßúöMk×>0*SŠ_µÈ„$6AH`²ÙIA4`% ª I!®‡†6yétóªU‡× ™W‹›šü•Ç, M-ìGa¦Ì V¬Íf'[[Œ¢Òu×½pâ™Ë.»Õ÷]‹fPÐu AŒOÖ´ˆÉ6‰¸ Ìž7wÆ‹2Ž\çD·ÁA\3¬5üI‰ ¾Ÿ.•JÅbqÊäI5ûèܹsÅ‚„A€ZÕž—ÛËå¢fVœH¤&ŒŽ9feü ®1µÑ‹ÅR©[c¨vhh¨†‘Þxã=žëd akiÍ*Çõ‰¹TÞIÊQÊ[¼x¦R굉ˆ2uÌw¾ûþ Çé(–¶A,XÕÍÂõWà ¯£æ8ÎqaŠtf² ¢à}ï»´TªŒ’Dº¦T‰}+•ä$ø~—1V;žÄ_¤Â¨P*í²Æ=ꨃ»»ÇzÞˆXþWE«~×»V—˱ÙJœèàºOFm'þ&¢¬vR¬*×\}ÛóßyÇŽþÇßêz¾µNU?¯Ú!✄T? ¥ Å­Æcôɧ,ÑæÁ>kJ±·VÝÌYÇìëÞb2¶ÿg¹\Ïuº»»Ì3+í»€UŠÂ  T3x¾ˆ.ûvkघ“FÁ¡‡ {Üøl&³cÇvÌ\©TâzÚúúúòù|L„•JøðÛWº̪Z'bã2Õ&^kº\ÜNÖéê3qb·Ö^«vòÉ¿ç½'W*Úq[ Åg©†2Ä/„ˆ˜÷bàï½:ÒÄÙìd‘¡RiàƒüjåÊùÙlJD[4@*›]ª4buŒY? bkSNYÞÔÔ¼—·Ö«B„«V-ÎæÒ GlÀJ%¶ƒª¥›b™>Á½ô;“™HT¼ÿ¯Û¶}×óÜùŠ+nóS$§tž»@U[cBõ†`+Åzph‘›ÊäV¯>â%˜k4Ȫjœç b0'sI&’+].ïA¹\ÖŽ³{Ïžƒ/0{Öl£˜´â(¬ØZEÇѰW‡•"ªÊ ]¥riÿÄU+‹}Û¾÷ö¦‹a Ÿ¢}ÌãÁ1c¼îú»•fp#ˆ'ÕØ« 0Õ&fRZ$,}zÉÒÙ/ âö/ÿr΢%ÓŒI3»åÊV:~ñ{5qU­MæBU£Dë”ë61çöó;þúÐÆQÕYç,"!Ò€$¤µ¥›UL VCÃO^WW×G,ÞwÝ^-|ùÜsW!V6<£ÅÔÿ“ÃW²Ù)Æ”W_õÇç¹íU×Ü‘J9‘4+.¸~Ø1Õ}ˆˆÀÄ‘)”Š;wùK&MÿRãÖx¨IÔQ¢s4èOªìPÓÄÖ­{tÊä‰]]c'NkkÒc”“ôÔ/½Û(ŠÂ@«ª,ʔ˦Ö=úÈ‘+×´›vôq'üÇ|íW?½êÆë¯œñä–üpRÍœÑ5eÚ±,0«$²™õÀàz&×XïÔSWÄ®j¯Žß¶pác•@lâÒÉ’àu”ä,dÓM“EJ7>»aý–ýÞóG—ßžÎxbÛ”Tí±÷m‘9ƒƒëÁÞ˜±c—/_ò‚уûç…Ì öSõŒi€—xäÀÆZ;ö öôú†J‘åÿü¯o½þŒSN;å1¦ GŠXl(bDi…½ºìÝÅZ)&NîÃÊñS}øÑq'çr¹ÁÁÁ®®®·¿ímgŸ}ö5?½qÆ‚e«[yñ{“01Ïóâ‡tÚýæ·Öf²~d:µ)!J¼š_Ä–qŠ³Ì‘"V"È矱â.X8cܸ1Žãâ@´ã_ø¦sŽBG;Í¥òN!g䎪w!Õø§ØsB©tkWéÒþõºRyš·œ·²\!"ÇHTÝ™¤‰´ ? ñfΚ>þŒýZV_Å“ì /U ‘/R(©ù¯Å©[’Ngܤӓ¬”ˆƒ+¯Ú?3üù÷;®˜V¥ŠJ’0Év‘úmIH—Ë»ƒ`ÈFΚÕG´¿ˆèÁýº­Õ£HcGª=´:a…ÂÅÈÜÊÿ~úøËÏòñã:&¶§¾ñÍKï¹ïÁñÝã[c_ÌÄÄ0ÆØÕcµ7ᨊ\Ïßù×gùïÂzÛ¶mÛ·oߺuëæÍ›•R§œr €×sÁùçžO!›Í2s:åíÚ=tÝõ÷ºŽDc•¶PñDÐÕ2ž&Å,QœRy»1µÎqÇ.K§d¶Ü¯ýÇùãº;­d­•È TÃŽª÷ª ×_Ø lsó\kK¥ú§¾åèÈX¢”µe"r’Î^©´Ã˜0²îI'ÞÒÒºßÄbúÕ[©7sÄÇ?y-ˆŒÖÜ””)#jHŠXÕ½aÇ÷ýÎ0,ýìçþÂç/Øën·ÜúHâ6¥Š UM#$õêµ€a€”;8ø³!uê©Ë_TôàþeQ®zT6Ž: ã­>Vd!¥Þ¿r쿞p¤ßD€I丮]ýÄi¯;ç–_ݰdñ¼r©,&Ú§Ø ”­Ø{Ëk—¶Ü›~ø’ÉÍÃÛw÷ôôT*•jjvˆ‡2.·é¥³©tªµ5÷µÿ\ë¸ÑG÷ǹq«f42Ç5¦wb¥zgò¡Ò«?äµGeö‹~øÞã×|)•ê(—wd³Y°‚µû˪ؘ«2Iû&­³^ª3ò×^ç>pòœÙ^É`ZšÓËñè#[rïžÛ‚ / €Ÿ¨T“vr'xÄþ뽪œÀ)'/Ãx+G -±rÅ#åºÚ¡kmºiª5…g·í¸÷¾õûÈ¢wø)7Œ:´3,¢¼$¾!±ƒ“ÃH‹˜üÐ&þÜ™óæ¼ ó`ƒ°Q/X!cä[ q9r—OØó…5;ýVÁÌ5X|>¦œi¾}þÌ í8áÔ×_öýË››²žïkVºŠ©T;^¨ÓÞ]k¶¡~๬XqXy°gÛ¶m»wïÞµk×®]»zzzÖ­[O`ùð-¿xï‚Ïœ17ëéT6·³§øó›ô}·Tžì¹½B,¤$ JPÐ8ö´qÊDÚšJ~ø!oñâ9S§M|mÌôÏÓæÌ÷‹O(JëŽrùYŠßh?FãÚ‹‹Ÿd¿ISn¶Ø¢R¥~d˜á'ÿùŒþR¹Ò¬ÝÙ¬¦êê´Ò„ͧzÌŒÓ|?µ_H¿ª+õ®w®ºá¦‡[¼¬H‘¸-9ö)ºZ=s)™Ô¿çAEÁ•?¹ãÐesj÷1Vþtç“MM~9ò}ªHµF’4€‹¥jvu'_ØÙÈX邏Žhni~‰æÁÚ-)~gqšÍ:Ó¶#ʃ ¡bT›|eÕ㩜Á¬sй¢uZf9ëréÛܳùîOöK×\÷³+ðÍÉ“&–Š¥¸„ëËoÚÁSwdÔ0ÚçæV\¾gO=t5rõ¥7;mJ!@Hɸ1rÈÆ;ÿq]vü˜IùÒ¸1-Ú$LvoÃLcòëªX®ú{R­m«Ž=8•ÊXY´Ö~ü½‹ŽXùÅ”?¦RÙªt³$ܯžhÄγ©þɦÒS ùmZ—>ñéë^!˜6µóc=A`ŒÈZ RŽã8Ï ¾êóÛÞ¶<¨X ”QÇ3T"6p-%–%$››aÂáÁþßþ~]í&?¹æ?íVl§£ªÐ37z“UWŸÀÚFC…üv+Þ‘G.˜0¾ûxú@–¸&çTëÿ°ˆªXg8r[œè]‹Ÿ^û¦?1½šs˜z ¢LQ Á0Æ,E¦eþdïâc'%ÒÁûÿñ3_üj.›u]gÐò:3½›]ÏAÓ†Z6ëîŸ|zÁÌ Šyñ¬ ßùä› ÷ýÇžt,ÚD%µ<›Ì²‰Áô¶¾žÞÎlê1Kèò[jJ~YPpJ¥M•ò µÞÉ'>vìØ—QŠôUj“'·}ôÃ'–+ŠuWPÙ’¢Ú6Ò‘0"V ›kä[ IDAToLooï®ý·›Fo\ÚuÓ©TS*•Ídr™LÓ~б¿–DøÎ Ž "²œƒ ‚uìË®Âú¬ªŸ RBpÓ“ˆ­R•«®¹;¾C©ÝsÿÇq#›R*éDUc•ÜªÊ +fwxø1À1Ö?õÔ广ÖW 8’páÒ­ÀJÀeÑc²•ËN¹ÿŽwþñS«Ÿœ>©¬'ÌÁì·‚A¦ ª *Á”Ñu8y•OŸ6µv߯~ý’|â³ÍMiÇqT=ß‹îÌlCªôQ:0‚†óG,›ýÈï¾mºü¡[þõ¢óV"¨`hN34CEP,*#GNäR°UñÎ$}\m^#.®•fÇíÝu7«¬v›ÞøÆ•M²h­}䃫gÌì66k-‹í‡R ³ˆwZÝv®n9R1¦êxc\¯Eñð7/ùí®]ƒd ¯:f2ÞŠ£fšDâ|°j„Ex/¢SÙ  üÍ·>hLàúÐÛîêáê‚&ÚZƒj¬y+bì{L(ÕÙ9vÅ‘ S©ô+2('U(‘`?Ä¢;üðú×ßuòÂ>¿ÃQ>Ðu(&­Xy˜ ¡À˜+dÆÃkîlá>aJíÆßþîå_ÿæ÷šš2Ìü"€™½;‡¶œ L6DTA!=ýØÝ‹=}È#(ÁV€T%ÐÊ ®˜jÅ>„%#g³«Ov*ö˜È-—¶‹»ŒxÇsðÌS8.ºoûþ%„† º‚òN©Úøë°_]¢©¥#Š/LSëB+ƒb‡ÿñ×ýÏ$Bï~ÇŠbE"j ‹(h TƒI'¾PVÎÍ”h¸XþÕ͸üšû=Ï-„]®;`E T H"¾Hn¢ 8•ÒöJyHÄ_³zYÛË4ÖIP ã H1~µ98ä‰ c#ø à4Æ.EGT„©ìÓˈŠh› ?øðš)wÿ§Oéé§7§RÞKG•â Ïl¡]˜6„ aCØ6„   õƒ+ÐÚ@[dÃcf0Ûr9(‹5’èµl¼Ð"Jà9½;ÿHÈçÎ;wUkkûËC¹^Õ6czÇÅï=®8P]a¸YÈè†ÕpQUŸ]õÚ 1gR™Ébsó_ï¹oãÿL"\}üìl.c$K(‚µR’\4vGXYãOTŠ×ýü~kÍCìÔnÚÂ'6Éÿ’#\½ ;ñ?Šr¡ÒÃý’ÊXÊžvêaûuzIð¨v…!%¤„´°ŽÈ9rÂ.x€ =˜Q9a}¦Ê“ëQ™qÐþ˜6úȪÉ#D©O~ÁÏøL´#Äsw­˜‚ÅÎÁu ŒÉ/â^B”Ÿ( eÀÚŒo^·‡‹åÐFˆW’H kaÕð.”° å• Oäó» ÒÇsð³^ Êõª¶ÿãê ;B´š°Â.’­¢…´ ºaj³K®•¶Ä©ÜP‘uñCÿ|Ãk?xýÚ<æœ×ô£«p8ͺ,È&@8íÃ%Š˜…N7MÉî¼kÃ7/»3•öËvŒë ¹#jûŒ¬ÂÄ@04ø„•æ9s¦ÏŸ;í˜ãŠ„©›˜ª´)ÚQn+ˆ€J*} [u7“ª>¾+´- èO2势ìØOòÒÿzí`„ÓKÉøHJQXdE# `CˆD@ÜCPEi3ŠB°€ž4ôí³[Ž¿´°³TÔN³R.ˆë /hDFfµgÇ- ,sîíç¯îèè| y ^óö½o½iõéßerTÙ 3m.`Fn­†V/nÃõª©uá`ÿëŸzæŠkï{ë9Ë^üssËú¾þÒó§ÚIàt+§ž0·µ5u`ˆðÝo?ü’=à§:|ì2h™Rª'³®å—÷róo®Åo\v—ç;ƒåqm™',4j…”k…:«9Ñ-yaþÈÀJú”ini{…‚“@J b—€z¡>rv ¥§è!ÀB”AïŸÑ± b 6qËF•üâ øÍh×fvÞøþ%Ë¿roÃΰš_ŒÓLÃhe‡w+ÍÐ>¤ ªäW%BD Ai+TJ%°®² A*³xàê7·®øÞ@)lËh¤F`÷"qõA¥SÃ}kK¥’¡Ž3N:ráÂ9¹\Ë+’,^å¶h^×;ÞzØ®~œ‰*Ú(Î|ˆjØ\¨Ö5D\ù»F"$ š©‡6òŸþâÍç¾ñ`¥^”xÔ‰ß}lÃN×%•TÓâ¸\3¦ÄæÊI¡2ïþè¯þô« Y2îµGLšØhT'[X ¦‘Ò`Þ8Ð ±ðx!R‚p3ò@•Á% )Öa*ˆÂºr–Ð4)ÿÈ9™¯Ÿ53¾ÿ%ÿñYh¥^ª8ª°çIÏ'øÍ°åDø¤jµA) ¼ŠYT( m@‚ö‚Åù÷/Û3”߆%famI bñÌNÛ¨gÏö;À¹\s×;ß¶º½ýïš ÆíËŸYÓÖÞHg…ŒaaG’I)!eɱµ-‹©6ʼn…i;ÔšÞÁÁþOñE%à|lÃîG7ô5·ŽÿèÐ?Ú¦V˜Ôrë/7©å&µ"ô—¹ñ—‡Þrã.7îŠTnrs.ó­ïßt¸]tÁ²b…CiWÔ/ˆWGЕäuK”jšV†¬)çÃ1)oÀ’'Ð õÆñú«…|Dý…¡g-Ò‡6oâ„q¯<®Pu¨¤cÆÈ¤žj†µðCx¼)Aù1U Êà¸*‚ ¢ ¢2¢Â2rS‘–w;î±k>c‡·¼ç.D¹ÛAFä~îÎLDl}ÄÏéH ¨4èP¡¼*„cH¦†Í°¦÷]¸¬R)î Âa±Và)AUÁ&—Xï~æjcÓ¡äÞqÁêY³¦çrÍ'Å¥Ÿ¿]öõÓŠñ,SYÖ`“ì4›¼Íêg¼£+Ì^·—jSÔéÿ²cç ›+ÂPÀŽÒ6í>Óäl̺››ÜÍYws“ûLSòY뛳޳\¹d‡ åF„矽@)Ø–~›@z€Øt£…”òsó¢ 7І†ƒ®´ÛgÅ©«ÔÕ³MHƒ”‚ò ý6È“>ã”eÍÍ-£aË"ûÝ×ÞY•÷#OÈ «Ý %ˆžD鯠ržŸÊ¼òc[ˆ®°[•Hc1ƉÄ_ÜÙKÍ8Ü^7„Á¨å€=Ðe¨"Tª0F.@åAyx\ÝÖaû~ýïÖV.„¬ÅówÒÚᦦ ŸýþW>“mSH·&<dQ @eTžL„ŒL. Ü^„]Ùu[l¾X0a1²¡µÊkɱä‚2aiÝîmjó3c?ö¡ÓÆO˜Í6ý· ÀDÈÿʪT&S¡‰a0 .GäÇ»+îVb4Þ?Éñj¡…-*ë7Í„Ýóë?løóÛ^@[„u¼n"®káA¥¡rÐ-Ð9«Û­n…nÕ"ª9¬äË…-…B_” 'ð¾ó–ì8E=†´M,~*ÖF,i -V[RBʰç¤'—¸)Yvê_ e“®…•%eáÚò“¥r>’̪ãµµµ¿2ó`š¦bmA[$ÊgDŽb:~Ê&tç«%üÐ áY8eƒÙ‡*VI1_%È<¸€Œë¶PÆé½ãÛŸzbËvË9®+DûKê$Bäx®Óœ³Vþù£ŸŸ³teKaKªUj‚”ö¦@Py\#uòK`/‚g°¥ýÙۻν¢—âB±`a%¬,´¨´˜»žúáöˆZÿáÝ'´dAkkûß•‹Ì #þš¿ö¹•…ŠSÑóTåAJäe‘è‡õ Ö¶ŽM( ¶€Ó|aØUCÿð~÷œP”%%¤ ) %ì@*CÛ¾7¸õû}›¿Ûûô%½›.éÝtYßæK÷<}éPïúâðîb!_®ŒHÁüš‚]Ë–ŒוÒxFHÊVQI2åÃV»™jžÛStÒî1n\„L’j‡qÕ²¤*7©Laçm–Z@-gž´4Û”O+Ž…SMô‘è™Í}mcРàÀ2,ÁÒÈ ÀìFÔÕ •‘j¸<Á–6jšÄ ‹[',=úozÃç?þiófÁX„¡ÄŒZÁq xüáǾñ]úƒ«»ë¢.d{áx $Åph2w½pjÓ,ÐŽ¶6Öw\qgù#¿ØQ2Nº©•Ü6¨¬ÀÑP®ƒ¡Ý¾˜œ¡¶3NY~Ö™GÓýßEmlo8yÚ®{ê/ö0w§èÉ2æ‘4˜(¨VÅ=)ó“lB1©të!C}{tCû¯ü‚³æ=·¬DU¨B+@MvhÏ3w.Yv\瘉a„zKÔtáæcWĬxç›æ~á[¥ôXW÷–¤‹Äƈ4”Ø’¤ 'Qj¡ßÙ"2pj¶ T+V2”ƒR¾÷1KÝ3gO^4ÊèùU‘k‘d| X!6ÄcÓdC8!±§$¿gÃJ¡ŽÐºxÉ¢¼ï¤ 'g³§ÖùlW|}å´cn,Ðl]¼²ãCÛNdªDüVâBÌM¤B²™¥ÎðãVú>ñ•¿\pÖœç#r-i$"L13„wå¿<þ¢ç5€8"|ï[gò?ÿVLOlÇ£šJ6XL«q4õ¨§-Dð„F„·%Æ—ÄãÓðo+[ʶfQsKÛhå>"«Ë h©Ùb™¶s(id*€E¨GО4Òdüi`CX®Ò!ÁRâ.&ŒÖâšùc¿|ëÏnÛñÝ˯Åå×>ÿ¨ŽË¡”¥«DÁ#z&qŒ»8!†ÒÁC㮽3øôÚ[z¡üTº¥E{ÊŸ 2“”×%:K*E’xâÿJ‘Açäi³¿ô©3¦Ï˜ÙÜÜòß”´µxŸÿðAûê:vh)ߦβVÀvogìÇFKD^Ç1•í·õöùÔ¿ÿõ‹=ø9d%eÉ1äCÄ€a&Ytä{šÃ©qL^5NJ»éõ¿{㸱í¬ô#¦Œ>öÈqy¸?ÔSŠÏdam•ÈX` ˆ9„¥Z°‚¸.}ìmÃq!uæli×­Fµ‘Û~ÚšéLÓ(î›®QìH™dFÇ»ïzxæò‰ÃX² ª‚P#bD £ Ba ‰©1–HUòWiç¥߯ä<¸”EÔw8"˜>D;à4¤ÚÑ®‘§;6ÜÙ~áu=wm ßÏ4·*¯ƒ½±ìw‘ÛEºÕêt–ÍöÁÇ?Z¨hCcº'Îø÷Ï¿aÁüùíí‡n¢/©ýÃ3OßoïRJÍË™{x%£"4'¶æ E 3´†ˆ¸³½ÌÃ&ØõÕï­ûÐÛçu¶§ö¯°k¡C€(ëLñfþ’©“¨H€•ÚæûÞÝŸ.”SjdÒäàqñÓÿpñCCÞôœûLÅ,DP W«•ßKÿ­óI©³Db9®ìèÜ*<ûÈÃfNœÐõ\^–NÈ`GB®•ª[‰Š”cßpËë?Û“:gÁ³­“Šh+"[A&@&@¦ Ï bUÊܼj“  zlÏʘ\­´VŠÈX #cm}Q •$pӃȂ2;\•BclÏȆ±·ÝÒtæžÍ‡*›kUnùã”ßEîqZˆš ›¬Î9•ûûÿ|Yr–;»'Íü¯Ï~ÈÒEcºþ»S`Ü~þÍÃÚŽü]>šªüÎÉ T¤ƒ5nª*냕‘û àö“yëODu¿ç³ÞðåûÓWØÂ±¬ \•d{ Éplâú¡B€JɆâà6`Z”\#ÿ=Dxú1cÓ¿`ƶڧ yd!a±`À²e ¹ŒÕY ÀRcÍrÔR,1¥Ã=—‡Ô iyý‰ó›r-£ˆã p òÊ,­£‚m{ß+>øÛ‡fe6Ïmñ§µÈ¤šÖÆs»U÷XqÆ Ñ”=˜ÐÃÔþIQòDÓ/Ù¬´×’ö}×õÅÕÊ^$$L‹ÀŠk£(*fÓƒa BÀì€àÔQ,´…kðLÛ·çNýÁŽÐzéL›ò»É›H~—èv茥 é&è¬ÞýãÞÍW†möœÿø—“–.^Ô9fìG0f¿ßûü³>ü§Vv(;o5¤ ª †Á’b+6©»!Hw¹-sÂüΟ­Ýtﺹ‡.jÛ—‚\ 6ðHˆ`Á WÀHHÜ’ãÚ\iàwtŸØ6bç@!€ ^7þ’ë{ ¶=¥÷¹“`-+X@KByINW±Âõ3Ã&ü)ñÆÓLÄ•]´Ü–m{Ì‘3Òéì¨zu  ±£XˆØñÓÍ4&òæ=™Ï<þL}j¸ÇTlÉØc¦:ç.šzòÁS3‡lÅ¬Ý A¨2ŒJÔxÇÞqnßlÇ´ÑZ 8$h&&0C’ú"Ö’ríƒ;å¾ÇiÙ$Í%%Âg u,<ƒ';×ý¾ã”ïí,‹—Îv¨ÔdxSØ §ÅR œ"ÝÄÒløØààf£¦€:–½äó^5köìöŽ1ÿc(0no\3ö¸å=·= ûíô=ÐLJ3ájš †…ŠJm\ìIjB­'¹ùoDÔûöO¯{ì¦cö#+Á1L°,ÌBL RQ¿°Ã¨e@ó®|>oŒÕŒL„:wü·®ÚXöº;háCFKqÕ]iHƒ$ñºÄâ:ˆâR ŠÀ®[þËΠt÷‰ÇÎììètÜÑL»@dÁe—Áª$qQèjšE‹”ë:í’R¶J˜‡)–%*™¨tó³åŸ*ÎþcðÑåÎY6±iÖ&õ¢cé v5aC÷Ýw;ç]ñ )‡TÚê4³RL qòÏ8êTþO‚Wu>x³½u|{öðÈ”a „Ä'Ƶ•½gòîpϾbÛPèd3-:ÝÍ©nö›ÉqY‰!h-Ñ6]R›q&Á{á¹G½ë­+&MœÚÒÚö÷ï ú2Úõ_7~ÕKjZsymSnBD’H¤ž3HF‚3TKìŮ۾8ê}òñõé«3åÍ'OÁfÉB\RäDD† ÂZ;¶ßužp6N«K½Ü§¤f€‹š­1¶Q+<0D8cbjéLڲÈ)zºB‰]".<2¨@â¢H1]ǽÁLœ®ì¼Éê¨Ôë×ÌÉîSìæ›ê­£†R fH,]08!¬¡säºb›a*ÖV ™JÚMTê)çß÷ÛÁOünè¤éé53šžèŒmf­e¸Ho­\ñ@ÿ/r\'å§Émf%å8©,Åù²k z’.%í`ý=ïêÂ¥¥ñÝ û1a©†Òx¶e÷ßš¿pKÿ7ïÞã:^6ݪ3]:Õ¥R-¤=RšW Ý?ðô••RÙ:ã r&OûÔÅ«^¾¤«küß[ÞŠÑDJ›õW?4õŸ¾öа»¸¥tK1½° Ó¹WeÓ <@ËìÌÀš6ìÿÞùæ“'7nM‚q¸à°CTbŠOˆnké^p衇…†I¸®w²×Ù5~ÙÒIJëäí@"pñyS?üo ¼¶´Ý\¦ Œ(Þlõжø§d¨ gF!PZн»™=kÜ¢…SýÑN»@l.hr8>)ãçJ|j  ÆìŠUPž’b`C‘À1—*§³…°òþ7Œ;ntòGŸê;ò¬ë;Û…ûýŽG@"6)ØÅ!¶‚lh¢’„% Û¨`LI¢rvÈŠÁžÒ¾ÒiV)] >Ld!AU-vYM0gÅA©PÈçû%–¨Ç{®çºöZŒ“îrRL&¿ë/Ã;î Ê9m¥EeW±è=ç·dÑœÎ1]qÑÿIJàsµ'6qÖu)7Ì÷IóQ"jo±KFš£©j/V^þÙ›Ë6ëdgl¼ýÙL"±?ü·=GŸwC{Îc&âteŽöl¼ûKªi>efë´+S« œSŸõ³ov€Mµöºã'¬ýÓÓ‘r\éµâW³êî»Ñ¥æÜ–ìK"VÜ¿ãÒY×ÏœºfI&›u³2Á:(hñ‰eŸsAP³`J5x7ÎeÅ$Ä0BPŠÙÉJˆ­ˆ DLì•FÄÄšHóˆàZrS©1@4ú‰}õ|å»n:—i¢‚ Ë"†Ø!q¼fí·j¥ÊCO÷m½±Ø¿…tt“x¾áÌòþíÍ+Y2·sÌØ\®%•JýÏf€mÖ”–œ7ç;W=ê‰~ñ›Y 5ä!mÈ'MÕõ…[i»$Øòǰ”þø¿ÝúÍ/œ^GQÔl‰@bk‹I“ìLNM"·p’bQYy¼ »íî Àß ¾ç¼%¿¸eÉåü`{äŒoHþÜ@‡5Ö×”–¡ô÷?+ºëˆCfÅу£¾™¢Pf‰ìw0Ô <ǾOÕSà bgEOÄ…kD¬XC°" »£z >ª6%Ùëªk†u®¨éÉË(+.L’ö˜–v—‡ŸÞ¾¥8¼‹•Ϻ éI‘¸éL˱G->çÌå‹ÌloïÌ6åR©Ôßs˜ü«Ô>÷¡£qË#ýƒÙ0ÜæE;,µÔ*FŒ´<ŒÌámI+7“m/•·ÿä†;?þ¾º[ã¯0ÊÉˈw¯€ˆæLq ›! +U?=©neT£¢u€‰ð…ã&t¹CÃ%‹¢BE¤1E~#V\e5±L¹ƒ;ï{ôé'ü*ee'XB™…ˆ„2ò%1AíÛ±'ic·`©òLŽ©¯vž$9ÙÁUò³n8ޏæpÌ$¥ˆÁBĤ‰Èšb%¿§Øÿtahk%¿Û@”Îò•?ÞkÈ_8oÚ Ç|âqO˜0¾)לÍf]×û_H~µvÉO9óÂ8þø(ÿ„Î-Bl_—ýX“Ú D¸©snyÓï\þÄ—~vÅ7ÞsBF‰‰ RA¶N½#|Kˆ"cŠÃO„&V ÊIý]!€ Þ°ä?¿û{ë¸:ìÑ~LjR•ÒXU'ÆŽÄlw=ÊìéìXqÄâÔ(›믂©¬ÈaFœf†ª†»½OÍ}õ©ø÷ª6@bÎg7©Ò¡…ÔÑF¡ÈJUèX‚±¦™RT*‰­TŠý&*—z+…=aP"v”“!å°ßiÅ Ó馅ó§¯8|Áq+O™<>Û”K§3¾ŸzžLìÿ{ÚáM9ëäy¿ºõaæf”6;ÙÉê¨Ø^èC]9"·¹}ÊðàîßÜúç§66Ù[uÝ‹bÿÄJ{Ὲ®ÃHD ˆ…0þ´±…‘„›rÙIºfL?gæ¤EógÌš>±µµÙ÷Ó®ë:®§ªíÿ§½}›Rü¥O¼þ¢¼ÄwÛ¼f%Ã;MyÐÚ"õÜ“Ü UF`ÀŒ%!ÈÁIDATöSá¤qÍÍ›4¶Í.x-3©ÐÚí"ƒÖDû㤱ɉŒuŽ>l®çº"É4QÔÚM7ßóëßÞT …ár)o­i(>Æ  ƒ“„÷ ÉdRç¼î¸Ã—-nm{sBïèéû¿ßøùž=ýAP(†‚ '®æEFžz4’5Rõ»\%23×K&f•`¾D¢ˆ”Ö®£µ£ÇqÇ÷\Ïs³¿µ9“kÊ6·4Mß™JùŽë:Ž«´VJkí0³RŠÿ_{׎Ó0DgÖ»æ¸UrDEI ‰†ëÐq:*n@“‚ p‡‚°ìw†ÂkÇŽABX)<ÝŽ%k×ófç³³!Åû Í^^ŸÉ?–‹Užùળ{­q IEND®B`‚vdr-plugin-live/live/img/bg_tools.png0000644000175000017500000000022712650773437017476 0ustar tobiastobias‰PNG  IHDR!ß*PbKGDÿÿÿ ½§“ pHYs  šœtIME×;kË–D$IDAT×c|ùþ?õÀõK·5õT™™X˜XYX˜X™R¾ýPY{†IEND®B`‚vdr-plugin-live/live/img/bg_box_l.png0000644000175000017500000000024312650773437017437 0ustar tobiastobias‰PNG  IHDRÎoõ2jIDATÓÐ] ‚`…á硽¶.B ÍB«Ò‹ü´éBÈ!š»—óÃpø½Ûý ¡ëˆ®¢ .×h¡ÎëãôJJMÊœa:¶å¶ZPNg"4ßKÙl"öŒX2¼ÿƒÃŒ­ºÉÃ|Ž®5[V}4þIEND®B`‚vdr-plugin-live/live/img/close_red.png0000644000175000017500000000111312650773437017620 0ustar tobiastobias‰PNG  IHDRóÿaIDAT8ËÅ“MHqÆ3û_wfwY·´ mdÍ]+1Ò›{X„ jƒÂ%:„uð`]ÂNAx+‚ŠÂƒ¹ÚDwA$£”$(ì,A¹­‹³n³óïPŠäÖÅCÏñýxÞ÷yy^Ås]v•]BT >âÔ‘dòr´»;îFù¾°ðáÓÔÔÍ“ŽóòÏZe»„i!Âß`¼'“I›¶­ø"¿\—ÜÌ Kcc“¯r¹ ×]w½¢„÷0~(‘8]ÝÚªxÅ⯠A0Çêë;{Ôï¿[ñY!΄!mÄb¸…‹Ãèá0ŠÏÇ—lUÓ0::Ø×Ù™¹%Äñ-Ïuñ\—ǹdÛòH@ÞùB×¥òM2)¿NLÈò™¢ÜÙìÛÚ XU¯mlä‡ãpÕ¶©.iÇ¡¨íêÂÍç YµMMm;$øu]ÖXH£½Ì臘IymÜüx›J=ÚßßÞ[_§´²‚ªixÅ"n¡@À4†/Øö•ŠN,åóWgg‹ÑÞÞ~aêvrUOÕ´QgyùÚ_¸‰Ïƒƒ={Óé²\>&76<ൠ>©N¥æÿiåÿò?'9»×‰PÓBIEND®B`‚vdr-plugin-live/live/img/button_green.png0000644000175000017500000000070412650773437020361 0ustar tobiastobias‰PNG  IHDRd{À˜•bKGDÿÿÿ ½§“ pHYs  šœtIME× 4!ê$*tEXtCommentCreated with The GIMPïd%n(IDATXÃí˜=JCAFÏÜÌÈDH#DIÐ=DI {Ý€,¬,“RìÄÊ ¸  ÚXÙí´0¾wÝEÞSîYÂwøæc®SUyz»Óó«N– û¨K1f‡ÓÕù{›i­ïà^oN®w?—ZŒ–PüŒœÞd8ĵ/644øè,™\¥(Óû$öMFðÑ‘ ûˆmFqP—"C±0!&Ä0!iܲT!³0ŠP ðý‘2ù2#y2·(ödÙ†&Ä„&ä_ qY v\Ì]Dp¸¬„TËuÄæ$?ˆ‡j¹Žì·º•¤7&V –Íì›±"$½1‡[ÇâT5<'œ]MÞG/L¦¨ýgS àKq•v³+͵m~Twzµ ¢IEND®B`‚vdr-plugin-live/live/img/bg_box_r.png0000644000175000017500000000024012650773437017442 0ustar tobiastobias‰PNG  IHDRÎoõ2gIDATÓ1 €0'!_·A¢ øߢ…9ãYˆæ·Úáv·8xI›vº\U (€’(Ê@ƒÄôäònDÌ%ZX¿cvMdÏÐõ38€¿ @@ÕÂnáøŸò´·Ÿ9´à5HôðþIEND®B`‚vdr-plugin-live/live/img/info-win-m-l.png0000644000175000017500000000026412650773437020100 0ustar tobiastobias‰PNG  IHDR¨ÈU‹bKGDÿÿÿ ½§“ pHYs  šœtIME×"NšÏãAIDAThÞíÃÁ ƒ@Á9¢ ý$åÛŸe\ZD;0Ãm<_X°bÃ;|ðÅ9ç¼$I’$I’$I’$I’¿÷!¿å®K IEND®B`‚vdr-plugin-live/live/img/info-win-t-l.png0000644000175000017500000000215312650773437020106 0ustar tobiastobias‰PNG  IHDR%4õ«bKGDÿÿÿ ½§“ pHYs  šœtIME×8 ŠP½øIDATxÚíÝÍŠUà÷T×dF£w•­äDBÖtá ¸A„,E$»€ Ñ ‚ᵘ…==S.ºžÔTOϯv…çsŠªêÅ™e½ó}%w§88åÀ~¸cåÞ€Ã1\÷C~Ùs}Õ{Àýêæ:ðËŽ}½.Wx¸C»¿ÊÇûrɾ­DHþOÃÌ~o8`î tãu—‹Aáø¯MÃCö„æ:´A€nReæ~r1(ÜŸ8Ïžp@™Y竱Úëö¹4kû{ÀÝ™'p>ÖÐϼPf®ëÿU³öc­šë®Y»\ tþp熙µ†ÎúK^l?ì·]VI޲ Mö500í" cÜ¿ hÛ¹.í:ÐŒuÜìòvˆ APWPîÎt¤@ œu¾¯s@ýÏÿ¨¡€ã$'Mµ¶‹@;^`ZÀíµ£꾆6I6m8 Ì¬íHÚ1 &yo¬“$¯œ7ž]ÚŽÝø\Ÿmg€“$ïõð‡¯Ÿ}òñG’äÛç8Q80e²¯×m( v 8ζKÀ‡Ùv ø ɯõ寿ùÝiÀªæB5 °Ê¿cN2†¾ûþçgOŸ<Η_ý–$YŸž9M8@—hu¬@í"pòôÉãGIrº €C6(ÍZ«$šz•$ŸñSþzó·S€Ö†vX5ëQ¶á€|úÙ95JÞ®ÎÓê'•µ`,Bɽ¶{@[GIòÆ8X„i8 4ë4°«Ob¤,Ä®±í¾ ¬Æ5ëµp,AŸ·ÃS%» tIrzºqz°ýŸkƒ%I~yý§Ó€Ø˜Žè.Ü+ÅéÀô×|¾K ƒÓ€èoüæ°qz°7 lç çNà„` . ”Ô.s„`nÑ9`ãô`Œ€wÜÍÜ,@çàÝv‹Î/,À?\.p Ïë1uIEND®B`‚vdr-plugin-live/live/img/reload.png0000644000175000017500000000131112650773437017127 0ustar tobiastobias‰PNG  IHDRóÿaIDAT8Ë“]H“QÇÿï»×Ô0­9-ÁOJ"íÃt%AI¾h›ÎUŠ }¡»¨ÐåÅ’³"ô¦ üÚ*õ ÒQ&Iˆ[S *§9LûÐ 7Ó³w]ˆæ6AŸËó?<ç9Ïÿÿc!XªxåÍ B)i,ðÖX,£6Ä%ÈS“·÷ò2MŽ·Æù¼–§Ë°¬$+bvn‹ º ñÛ_¥©ãù²s„”ÜñiÀçé$l`ôC¾àbæDj:Ø€àžÕoGÉáË Ï ·e|É×g¤¬Þ£õ8Cu%½uØè –ù?ý3† ¿•Ø,‰å1Ÿ§SðÊéí!Ç.‡ CÝ?]g( .fmXçúÓÌ^{5ž×VW‰€ ¯/°iÎÀ(ˆGlŽ[a¨kà‰^eœ»¤ºT?¾­XÝl0ªõD}m‘%Ä:ÌOhu£õÕX?Ñ«Œ¼¢œ#õEú­–ÁÖéü&¢iYÔR{2×à Ey&\4ëõ´´‰hh¾¢Ò"MŽÜ$b\è2™õ5äj®¯Jm©<[¡¶|š˜;k"*ãK2 ·RŽ#9T€`’ÚSy¬°Ý±nKÚBe BŒÛ…ž_C`ú_"{c0ÞÜ¿÷¢†h=s_v+BÖ„ajò;$«Âç%7Ç@Œ¸&tÝhi™tŽ™ÏÏB˜ø,Í™=i)·±r†{W;Óg¶8fœ@]Ôý­Wúº†h wÆxӘūs’¶& LüX;A ËëéIEND®B`‚vdr-plugin-live/live/img/bg_header_l.png0000644000175000017500000000026612650773437020104 0ustar tobiastobias‰PNG  IHDRé`¤ú}IDATÓ…Î1‚` †áçWâäàîÁä ÞÃÁ/cBâÁø‘:€ÚííÛ¯-?ëv9"ªº‰„¸\ €Ü¾&hs7ƒ¹Éy167m·f™å¶!“vg°ù¶ÄÒ1-ý ôkfþfÒx?(?¿œ¶ˆÑ”o¤f>®üO’IEND®B`‚vdr-plugin-live/live/img/active.png0000644000175000017500000000152612650773437017144 0ustar tobiastobias‰PNG  IHDRóÿaIDAT8Ë]“MlU…¿{ïü¼y¿}m±Ö¶PbjªMP4jبFŒ ã‚E#H AeabâNâB!¦º01²€¤²2*Áh$&D…• øSyX)mmû^gæÝ™{çº0ê·:‹sÎêÁÿxòÝàv_ˆÉ¨&ñ}7"ÈsZi[|"Œ=òÁsÙkýâºØ~Œ Ô 5Õîñ±ºhVB_"dÖ±’ä\¼´ì®ÍÚúª÷ßAv£`û1‚rZ:uÛD´u|¤ïýÛ›‰s)¾W`,\ú³ÍçãÏKÝîÃS“ä@©Szkt"Ø:¾¾¯:÷‰“^p!…3$”J«ŒÔ°Eñà…sîuÐûÅΩ`¢ÿõýÆÑ¦l–1¦¶_E(á`]NfS´]iT §¿+ZnL*¡öô „BŠˆøïA\2@É«Söš”ý>Ê~‘פ$jl©ïáñáO ÓÍl­Hå¹I/êq*©h¸[yúŽ.ãÔÌ+øuA Ë€#íÆÜ½nƒ•ÍŒVŸ`Öž!¬‰Ç¤0` ž Uƒ6¼†Ð%"¿ÏÔ¹ÝáÅôgÎ\;ŒÎAà†¤s®èf9m5Ã×­7ˆ¼>î¹élÇcKÿ^êÁzfWÏòñåçɽ6™-p¤ÍÅ_í´KQ~ÒÓ\X˜  sßÐK„ªÀ/KŸñåü«/¡pk-y.ædºä¦•”\]™Ç8Í7Ko3ÛùnÍÖ箾ÏÙÎ ]ò¢‹-4í8%é¸jÓ6ï×0bolµPÂQŽ"þX9ÍÍÑD~“¯Z™±'Él‚6´Ye¾³ÀÊ’vY̳à™÷ÂC=žÜôVë õÉ:¬`D‚uc5IÖfvyç,þ^¼ñá.ý¢к¢_–^iScD>´¸Úf)îP‹*T‚2B‚±†X'ÄZ(Iû²8™Õô0óEó.sTU­Tä½*"ÑšN7¦“Æ$:²ëŠå+L«é®ã;°ÿyãužz'‚ÉrSlSA1,À-[é †©£»»¿­õÿhåiúœªj¹IEND®B`‚vdr-plugin-live/live/img/button_blue.png0000644000175000017500000000062612650773437020213 0ustar tobiastobias‰PNG  IHDRd{À˜•bKGDÿÿÿ ½§“ pHYs  šœtIME× 2i/ÂH#IDATXÃí–±JQEï̾â¬dIñ"‚MÐ"Ù4ùÓ˜‰ L#V V"ØØ‰u$ð°L–€¾}c±…°o•9ŸpsïˆÐÙô™onœµ¼0”ò`òH’ƒ~wc<ê;39ÂéŽët°³[Ó„ ù7¦W_ Þ¢ýîHÚí=P¤2BKY,^ÁÖf*£PTƒµX7£:xa¨ª¼F Bòw0ÅÏ%‰¦ôï¥_!oïÈýZC HÄ ­,ÝE…¨E…ü+!LÌF“.€Ƀ[I\Š×P‚ዲj%18M6WË9L½ 6XéÃÔ›X-ç{L"—³\Ïîrû¹†sz.åM¸1ÉvƒôOŽ{ø)íTð.šBIEND®B`‚vdr-plugin-live/live/img/stop_update.png0000644000175000017500000000135412650773437020217 0ustar tobiastobias‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  d_‘tIMEÓ  à?•yIDATxÚm“±KaÆßÝw—äP«ÔjîªqpPTª$þ n‚ƒPt°Rtsë àà:\2ëªH M÷Vt¨¨ˆƒÅóªF/¹»—¨‘¾ðð½¼|ÏÃû¾¯H&“¼Œ ô ˜ðð_¼aý ìAí¿x)Þˆaä¬ññ¸PÕ:áŠçq°¶võçáaô+ü®‰È:r,–ëZ\Œëýýü/ûúZ+KK›ŸŠÅÑoUÕ4Í‰äºæçãzg'¸.ÜÜ@¡ðŒR ò®»ÛxÜÞëð¼Üœ«YÓìèz®kr2®··C[ôô@>pw‘ Âí-òþž¶DÂ(íí½÷¼œLXq]Óàò PUH¥ B¤Ra-‘À?>FñáÍ›V¦¥ˆBNOÃAWWaj ad$¬II`Û<ÎÏã†Û\Ðàö6l9Ÿ‡Ý]XY w ë ë¶Mifæ‰LÕ^MÀuŸ×ÝÒÎ]‹X ¥¹ï•+>vðð@à8! X^†h”À¶ laèé4úв꽬 xŠB@c#"Àëk˜ q}0 d:ÖÔ„¦(Š ÜÀú\•ª ™ 8,, QÍqÈdªJ©¡ŸàìCV$“Iñ†û4m3eY­º”B©T?pµV¬TØ:;s6Êå¹Ȫ¦iò Î;|?ç>>ŽÅ-ËÑ(ÄbõÐ4ŠªÊÖɉ³áºs;lÕ4M¶áܪTr¥Baì­ež®S–’²”¸RR‚ïûûÎF±øDñêœÅG6`Úͯú];çÈnÃà&¾ã§¯IEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-bl.png0000644000175000017500000000102012650773437021424 0ustar tobiastobias‰PNG  IHDRãîZÄž×IDATxÚíÛMnÓ@‡ñÇã¡¡mÚ¦ T‰ âÍE8DÅ¡¸ÁVÝU|¥Äuºð˜ŒÜÐ&ànàùI¯b[v³ùë‚FH`8žÏ _¾*âÁ[$IR¯ÂŠguª9ð¸.©?œ:d’$ÝO×YUÀ,Õ˜_™¾yípI’tÿqÈWÀÏÔ.X|›,fŸìŽ%IêY™]YµkÈ%ð Udþñ=åÓqQO€s‡O’¤þÃxÑ ån8ÃüÃ;Âá¸(G'€¡,IÒ_*:÷ù®ê-`—fgõ#àxB³Ëúˆbo—íñaDII’z cRwy”Bù1p˜®÷iŽB=Lï–,§·Wý¿$Iÿ³Eú½b¹Gk;/Õ)LÛ]Õy@ç»&4»†Àv ãvm9d߯’$Ý ãüñ<®x±Î®+š³ÆùGSà{êˆw€Aª¶›nט bI’Vr~+ Š¿y±ÈdaÜž?ÐLMh¦¥#Ëiê¼£–$I73¶q®îê^C§bVe ãÈrØ –$iÃ@^g*9ÜÌÝgàô´$Iëøµ~¼np†[Â;bI’þ¼CÞ´‹ ÞK’¤žÃØà•$I’$ý[®½,]Ó }6IEND®B`‚vdr-plugin-live/live/img/rounded-box-orange-br.png0000644000175000017500000000060212650773437021763 0ustar tobiastobias‰PNG  IHDR;mGúbKGDòëW›CT pHYs  šœtIME× ŸÀ+IDAT8Ë­’ANAE_Ã,ܸñ $¬½7ò Nf‚l&2ŠÌ Ȍà “²§c%ô¢þë_¿Ú•ùÝ#‘º¾¹»áè˜s`¼° ÚA  ë^ç|áŠB\v;J`|µNkNrvÑmwÀÆØ¯€£Üøj{pÃÑÈ7`+7›ƒÕeAð ¬ÙR¥ ®;>uç ¾GÈxÑ}mÜÔ1&š¹”à]Ör›‡g¦ô?$(,‚ÍØõö2™k^ÿ'¼Ðo$ ´÷O2`©æÚˆªÀ~Tl!+5Öæ4‘×/B Ó”&~;W¦1&ºð,Ñü«ØBþ{F—‡ËJ¡IEND®B`‚vdr-plugin-live/live/img/button_red.png0000644000175000017500000000071712650773437020037 0ustar tobiastobias‰PNG  IHDRd{À˜•bKGDÿÿÿ ½§“ pHYs  šœtIME× 08ÌtEXtCommentCreated with The GIMPïd%n3IDATXÃí—?JAÆ¿7»C&ŒM%ˆAïÿÚÅ X[©i,bÀFðžCAPl<ÀÜd- ˆ6κ̌…ž`'ÊûáûñÞ÷9çÄðþ¶qyÖKtƒ¬SNP%¬ôª+Û;:|Š®ëWÝݤ=-¡êeNÈ:ᦿ÷F *wV];A‚“ñ)ÅXÜ•æ!t³Œ @:!¸3&²< a! ùC„`­…Í9 ¯“! yù4xÿ°œŠG¦Ê‚WwÃBXÃBþ•C$'áICD¥ÙBH?0ãë ¨4[ûý™hœ¡Fâ[ S¬ j$3l*rÎÍ=?>”.Nº‰ç9øE,®À¥”P ‹X?<ž]Þê¼~%’UI«!EñIEND®B`‚vdr-plugin-live/live/img/rounded-box-redwine-br.png0000644000175000017500000000066612650773437022157 0ustar tobiastobias‰PNG  IHDR½ù5TsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ">VB“tEXtCommentöÌ–¿"IDAT8Ë­’1NÃ@EŸ#œ†Æ—áhi©Ã5èÒPR)Ž^œµc ÍŸh1»FBŒ´Ýü·ÿÏLvÅå‘êŠî¯àX[À Ð0ÌHTCàõZàd"½s¥ …ãN@?LAXfÕ¨wà(û]ÌM R¬q4Ÿõ¨‚´À‡ÜX 1HQrà–ÕØ/À›Üø ηH¹‰Ö8<¥ • mRã ‡g™U EØ °örâ5p°gPÌ•¹–èUöraq Ò!¹Žé$pºÑf¢. ò¤¼v&´ŒúãNr`£æ.µ#ûQq)ÕØwÐG~Ÿ„¸ )%Ll;AcL4 0HžhþUBfþ{}‹é­­D¶¿7IEND®B`‚vdr-plugin-live/live/img/rounded-box-green-ml.png0000644000175000017500000000016012650773437021614 0ustar tobiastobias‰PNG  IHDRãíŒÆ7IDATxÚíá€0°¨A"+ʆc`vª€*?w)>ÛGÅ WyÆWDDD,5ÏÂiàî:€IEND®B`‚vdr-plugin-live/live/img/stream_button.png0000644000175000017500000000150012650773437020547 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<½IDAT8u“MkSA…ÏÌ››/SÒb¨¶˜ƒRp#(« ¨(¸DŠP,mÿAþAZ7ÝYèBAqaÁR¡¨àÇ¢Vš`P+1Jo&¹óqï¸(I‹f5sï;‡cЮµµBVJ1­µŸÑZ§ !°,«Â˜U …œüÐÐàjû{²(ŠT‘SJ[í‹ÅbˆÇã ”Âu]¸®‹ 0ßmÛ¾ç8Nnp0´++«ToQJ9ºG—mÖݺ» ¤#](—ËŠ1û…ã„Ï<˜ (pÎsœ×G{{{lQÿ ¿úîÇE4Ö¿Àó¼Ö‘R"•JÙJÉQÎyÈòò›l£Q–HìˆF£ïcødnUàÇšDÁö‰tµ’ø¾jõW)‰cž×œæ¼>`L­5üêw@ ìî¡H$ ÊŸ¾âÛÒ 6á–à 8AÞ>;Q;PÜYFÙ6:Ž1I‚’©&޹¾òç®^ø©½=u" àçÕ' ” –GÑ–ÂÝE% ´¦m ~Ø¡¾wÍÄPØYf¢4ö¸ê‘ï¨Oóì¹/Ój ¯ ”ë‹/Pœy3X$\^ËÂ9rˆÁÙ7 ó½ø¿.Ñ×ÛG£²¹ïQ|®uÉ÷Æ·MÚé4ÑîJo =4Œ¹§1&ŽÑZ“<ùÏõj•f½ŽHLJš#ï×Ó¯Lþß7Þ̉,#Rðjã¶…*"¡‰þ®†Íï4ÌÍøüy;ÿ™ N“Jù ŸIEND®B`‚vdr-plugin-live/live/img/search.png0000644000175000017500000000165412650773437017140 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs‹‹Fe³?tEXtSoftwarewww.inkscape.org›î<)IDAT8m“Kl”e…Ÿ÷ûçöÏ¥#½S*4m"¥X‹±Dš˜˜¸1!nŒQ‰+iH0ÊJã…°PÑ…]Ùˆ‘…k©C%±+¤T0ÐvzÚÎLçúÏ|¯ i‚g{NžÕyDUY›øÀu‡¢vkÚ>««¶P‰š¿¤Ñ|‹+¿e^ÛZ[»—µ€º“×vD³|Ñ£ÛšƒNûƒ!|Žp%Yä÷Û¥ê×û£Ø /e´]¹{óê‘ÍyçØÑ'ãë7®·4ÕûqayÅ#WðáºAR ïýNMEí‰Ü‡§îboMtèíÞXâ@w”-Å™Iå©x56µÄXÉ–úi0J¡dùäÜRêï¨=û cB¢G'|zÇž{:ìî!Ìc»š8¤@# åU=—@-|uv(Èõ©2_ßÌH½Ùg4«ûu®Öy;•fïî žI’\2Îpk~™[+eN N²ùs³iF&òx¢è|­K3ºß§Û§¸/¢8Žáôw)&—<¤RÆz5°J9_âþGˆ« ŸŸCüQäìACIÛĦ³UZ…B©Àj¾L>W%Ÿ­Ñöû™Y,‚É!®"®@IÛŒV\aÖ¸Œ_Nsüðv¢â¡´‚B˜÷ûw’[­ðëåEp*¨‚+hYÅG^“’»¼þÑŸ|ÿÙ>. >×ß\c5_åù¾Vöv'8ñésª˜ š·I =<ÖkvÏÊ:ã§Z¦u)Å»/¶Ó³§7äcl|ùÅ={ZØýÊ0³‘(fÝýè<{©Ò'Á–Q¿$œßS¡.4¿„f2°˜ÃT,Õ€ƒ:þ±ˆŸÞÏoR©‹Sý±8ª3µÇMiºÓcÞ¾j¯z³„ij@Zš ­»5ŽlŒÀ¦(‡ÎLR_¢Ã±Þ öåÒlWíî•Ým—Ž™6ßNwp¨‚ýÏc@ L‘Ò8©Ú ûqqâÑ“÷Èä¶^ì’f3àô·KÂñã— OÑT­Rû¹>ôEEôFFôGGôOOôSSôTTôWWô\\õ]]ô^^õ^^õ``õeeôffõhhörröttöuuöwwöxxö{{ö||ö~~öƒƒ÷„„ö‡‡ö‰‰øŠŠø‹‹ö‘‘ø‘‘ö““÷““÷••ø••ø˜˜ùššøœœøøŸŸø  ù¢¢ø¦¦ù§§ø¨¨ù««ù­­ù®®ù°°ú°°ú³³ú´´ùµµú··ù¸¸ú¸¸ù¹¹úººù»»ú»»ú¼¼ú½½ú¾¾úÃÃúÄÄûÅÅûÇÇúÈÈúÉÉûÉÉûÊÊûËËûÌÌüÍÍûÏÏûÑÑüÑÑûÒÒûÓÓüÓÓüÔÔûÕÕüÕÕýÕÕûÖÖüÖÖû××ü××ûØØüØØýØØûÙÙüÚÚüÛÛýÛÛüÜÜýÜÜüÝÝýÝÝûÞÞüÞÞûßßüßßýßßüààýààüááüââýââüããýããüääýääüååýååüææýææüççýççüèèýèèþèèýééýêêþêêýëëþëëüììýììþììüííýííýîîþîîýïïþïïýððþððýññþññýòòþòòýóóþóóýôôþôôýõõþõõþööþ÷÷ÿ÷÷þøøÿøøþùùÿùùþúúÿúúþûûÿûûþüüÿüüþýýÿýýþþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ÿ NETSCAPE2.0!ù ÿ,Kg H° Áƒ†!LÂXÀòP`‰m*Î:$ñÆPCiœ%@ÀÈYœlÐà$;#¯Eã‰=4¢"1‚ÔÉŸ !ù ÿ,Kg H° Áƒ²Ù°MÂbóP ‰x*Îb$‘‘ÆPCiœ…ÁÈY œ¼páä?#Á@`Fã‰H4¢j±‚ÔÉŸ !ù ÿ,Kg H° Áƒê)QBOÂq$HˆóPà ‰ƒ*Ϊ$±’ÆQGiœ5aÂÈY*œ1âd!D#ßH˜0G£‰Q4ªÒÕÉŸ !ù ÿ,Jg H° Áƒš1ÃPÂ}@€èóP`#‰*ÎÚ$q“ÆSOiœ"ÄÈY$HœŒã$$I##†¤Ñ‹D.Y!¢ê¤Ï„!ù ÿ,Hg H° ÁƒF $R‹bÄXôP %‰–*Î %1”ÆTSiœ%qä,4Lúða“¦‘‰$R¬(G⮨Lae²g€!ù ÿ,Hg H° Áƒj‚ES–€±ôP '‰ž*Î%q”ÆUWiœ%qä¬!CL>yb¨‘”$R¬HHb ®Î”qe²g€!ù ÿ,Hg H° Áƒ†:s&TŸ¨PùôPà(‰£*Î:%ñ”ÆV[iœ%qä,+VLŽc²T©‘©8¬(I¢$°úìe²g€!ù ÿ,Gg H° Áƒž$èTÂ¥Þ¼)õP`*‰©*ÎZ%q•ÆW_iœ%qä,9rLd2UF'jü$Ñ“FX‘"Á2É3a@!ù ÿ,Gg H° Áƒ®Ê”iU«9røpV+‰­*Îz%ñ•ÆXciœ%qä¬H‘LZ²d²UF'j<%ñ”FY¡BÉ2É3a@!ù ÿ,Eg H° Áƒ¾*UêU¯D‰røpVĉgÅ’+ãFQ3JÌ(pÔ(’³¢|E±âÅ– [Il•QVªT²PêL!ù ÿ,=g H° ÁƒÆzõ*V±ZµrøpVĉ-J¤øð"LJ3 d(rI‘±>&ô˜‘eEY e•œ™0 !ù ÿ,g H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å!ù ÿ,Fg H° Áƒ®š4iU© JõP¡D‡[IlUqV,‰±:Î’(r"D%#E*ÙŠcLj;Ž’8ª£¬Nd•Ü™0 !ù ÿ,Hg H° ÁƒŽ‚gT¢´hõP`)‰¥*ÎJ%1•ÆW_iœ%qä¬.]L¶icòÔ©‘¡$R¬xI¢%°‚e²g€!ù ÿ,Hg H° Áƒvºr¥SšŽÑôP`(‰¡*Î*%±”ÆV[iœ%qä¬%KLR¡bR”¨‘™$R¬ˆH""°Ú¬qe²g€!ù ÿ,Hg H° ÁƒVJ’¤R‘n܈ôP &‰š*Î%Q”ÆUWiœ%qä¬9L)b’S§‘Ž$JÒ¨G"®°`qe²g€!ù ÿ,Hg H° Áƒ2Ú±ƒQˆT¨@ôP %‰”*Îú$ñ“ÆTSiœ%qä,,LæÈaÒÒ¥‘†$&Ò¸F¢®œ4ae²g€!ù ÿ,Kg H° Áƒ’!ÃPÂ}ŸÿQÓ´—À×ýúd2ù·Õjý¶½½}9;¯ÌœŸŸÿdšæ ‚€ååe‚€^¯G¿ßﺮûûÖÖÖ»ÿ\\\ü•N§+õz]±, !–eaŽãp€¦iÒó¼¿777+àììì®ëÛ¶MÓ¦Dív€µµ5„ŒÇc%›Í~wzzú3€rttôºT*}¼½½Í¹® €a¬¬¬P(BP«ÕÃðÉ­¤”Ýjµúm2ŸÏ¹t:iš´Z-‚ ŽcªÕê#6Ï¥(Jniié )„x!¥d~~UUév»A@¹\Àq€é3B¼RÊ’¢(ÓF.—#“ÉP.—±mû‹mÛ_J¥½^Éd2KPJFQô-™L’Ïç§4êt:DQD*•šÖ¢(")¥üÇñê,ž®ë8ŽÃúúúWWWWhšÆh4âîî)%™L†8Ž?‹0 í8ŽŸP!PU•z½Žçy TUe0pssC£Ñ ŽcÂ0´E³Ù|?Ü瑎¢UU)‹ ²Ù,躎a ‡C·Ñh¼»»»—žçýÁ‡D"A±XÄ÷}|ßgnn€T*Åââ¢lµZ¿îíí]N£|||ü‡eYß«ªª<ÞcuuMÓh·ÛxžGE„a(›ÍæŸ;;;oà!Ê•JåM­V{ëû¾«( ¦iÇ1ÃáÉdBôû}÷úúúíã2<û‡‡‡¯ ÃøAÓ´W‰Dâ€0 ÿÇŸ:·ýýýO³óÿc I„#ÂD‹IEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-tl.png0000644000175000017500000000072612650773437021462 0ustar tobiastobias‰PNG  IHDRãîZÄžIDATxÚíÜKNÂP@ásÛòjƒ _7᜹]¬ò¼7^k« ¢Ï—Ü´@Ê ““¿´€$IúSá›ÇžBI’~7ÆÅޝ%IR¿õ.1.:ö‹Ö¾A–$iÇoãv|óUµ^uâ–$é¿Ù¤(Í®ø¦UÃ,ÈeϤ,I’º§â5ð¶ q ðc`mñó`%IÚ:Äà1lâáhâªI ò( v ²—ª%Izo“‡¸/Æíct` Ìãv–E9MÈe\ÁéX’¤ÞÉx<ÅõPu„˜ÖD<É"¼–ÀaÜ?Èb<äõwã2~Ó±$Io§bb„×q{_}0W¼\~nbˆWÀ1p¬Ó†ÉÅ5ÅœPÍ<½’$}QõÉT\Ç©xC| œR_Þ†áy:îÎÓ(IÒÏÄø£©x'â3š«›081Â’$ý¢ç½tãVºiëXQ_bI’öã4—¼>Ê4„i/MbI’öã®çŠÓÔ pÀäâÚÓ%IÒþ'ã<Ìé¶j ¦˜;K’´Ï×2&¼“—SIEND®B`‚vdr-plugin-live/live/img/bg_box_h.png0000644000175000017500000000017612650773437017440 0ustar tobiastobias‰PNG  IHDRÊš%EIDAT×UÈ» €0ÑñôJ7HôCU8àÎç%㓌4ÀÚöeŠ,”Qèì××ú»Q(sËjÑÂFx <ÿy #€Lø0¹*ÒIEND®B`‚vdr-plugin-live/live/img/transparent.png0000644000175000017500000000010612650773437020223 0ustar tobiastobias‰PNG  IHDRĉ IDAT×c````^ó*:IEND®B`‚vdr-plugin-live/live/img/plus.png0000644000175000017500000000074012650773437016651 0ustar tobiastobias‰PNG  IHDRóÿa§IDAT8ËÕS=‹Q=óå êàsLP´° D‘ØÁBR˜Ÿ°R° $.¬ÌH!ƒ+ ØO)‹,„Ø–Á™Ї&N3#“"̂˖Éíî=œâ\à¿á.Ð0Œ‚ªªQ˲®;ÎÏ{»ƒ7ËåòÇápðÇñ7›7›Í>÷z=õ6Wº}èv»J¥Òûd2På7I’DJécÎùó|>o˜¦éýá‹çâÑhô$¿ŠÅbeÃáý~žç! !“É_@2‘H`2™`<ƒ1†ív‹V«…Z­†r¹ ]×]L (Š¥iR©ªÕ* …Òé4²Ù,dY¥„ïH’tåºîëb±(ær9†ý~f³‰p8 B\×]LÐh4n8ç !PUõzívš¦! âx<~µ,«wg|ßæóù;ÆØÁ¶mß¶mŸ1vZ¯×Ÿ¦ÓéÃ{7q±XEQ|æºîÇq¾T*•oÿæ3ývš€–LvÁIEND®B`‚vdr-plugin-live/live/img/rounded-box-redwine-bl.png0000644000175000017500000000120512650773437022137 0ustar tobiastobias‰PNG  IHDRãhζ0sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ">VB“tEXtCommentöÌ–¿ñIDATxÚíÛ¿nÓ@€ñÏHŒI j‘``‰ ÑAbëóˆ!%iÜ„Áwä䆒€ËßO:9®ì^>ÝÙ—ÑÊÃ50î÷À×<9^!I’z•wÎWa4ÀXs`þ™¹OK’¤¿ã4ÈËâSàtÖÆø™L’¤~á¸Ç,Œ†QõÇlýáÓÇÀ{›$IýÇ8†8ΖË0®…1X²(&TÏ'Tw ²$IWã8â]Eäò³7GŒŽG ²$IWãu'ÊÝ8ó–O¯'TÇa†l”%IúCYç›B©>åÑ͵]:tqx.E_;^‡RDxíæäô&‘R«“K)tk—àK°’¡¨‹J‰FiBroî÷ݯCQ¤g>ÎáœC´ÖxŒÍÍͧããã_ÍÌÌ|411‘Bàöööââââ÷ÓÓÓVWW[ùä^`}}º®û:ŸÏ¹¸¸È… ”‚PJ¡ÕjÚíö÷¾[YYÑ@àøø˜ ƒ?J¥Ò×õzK)Ç1”RPJAJ ¥Ê岨Õjß&IòÛ½0€ÃÃÃ×ù|þƒ©©)(¥ì…aˆ(Š@)c ”Rär9LNN.lmm}F±X|ïîîîM¥RacccH¥RpWWWX[[C³ÙÄìì,<Ïc qƒ1†^¯÷áÁÁÁO,Žã®ëš£ÑŒ1˜¦ ¥†Ã!z½¢(BEÐZƒsÇqÍf›››Ï¥´æû>’$išè÷û0 q£Óé€1†Á`€~¿¥!àœc8Âó¼£”>ñ}étGGGØÝÝ…”QÁ4M\^^bccA ÌÍÍ¡P( “É@ký.BÀu]¤Ói´Z-œœœ¾¾¾~ÅrÎÁ9ÈÊ9c œóçü‹N§óéý ÉÿïÜl6ßI§ÓŸ9ŽóTký> AiH)w‚ øë1ÿ_TÛDö\&IEND®B`‚vdr-plugin-live/live/img/info-win-t-r.png0000644000175000017500000000131412650773437020112 0ustar tobiastobias‰PNG  IHDR%\fù¶bKGDÿÿÿ ½§“ pHYs  šœtIME×8 ŠP½YIDATHǽ—¿nAÆ»wvâ'éhè)y*^# 5"ñ)¢H%¢¤) ¤H¼ÏAœàûã¥`—L&»{wvÈI£µ÷NóÝ7óÍì€á.ë×ÿf2 î¶l€»­ÐYÅÊDþ¯}•‚‘SfľY—]l(6ÞµÙ•ÀØ¿éR˜ÌÚ;· £]•+£Æ™U€îû5˜íY)ŒðÀ‡°ˆ°V S÷Ü ‡¨ue"²O±r}#ÁªÈ´&—plúý¾ V¶GÇ œ}xûîô°ìS`Ø&¾ÖÆâe4ëN5š“ÙwwxðDîíçÀø\—Þ@4ÞdíI¦7Ûªn9:>ãèø €Ù›÷O=³©gw/Ã,æÌʺj¯m¼Ø |!qªSÄlÙ¥B{>_ìÕëOaæYíùÎòµ)X”Jm®{غn‘öüåi¸·«„±íÃ8IåQʪnS÷vTí,}ƒmü̉F¬Cý/”å|¾HM•󨽵~mÄ36WÔef’Ò^ Àrcó7tUhK1Y¿Åº)JAh¸²®›PpTyÇ~é•7RõT¨Còzè¾|ý1èBÈ{¬Ú‘É!%&©È‘p¸!l¬äm3¿RÎ忉‘°±ø˜„Õ$ÆáÌ5¹#¤€…ÈI)’o{,nÙT¨·/"­Ç&†×È('6a}™N "sD‘8ðr'¬Éå(6 ™>‰š£œÓÁå€ÑÌôü®Ê'CVò?ÞÅ',ˆ(Ũ¼£«¯IEND®B`‚vdr-plugin-live/live/img/folder_closed.png0000644000175000017500000000116112650773437020470 0ustar tobiastobias‰PNG  IHDRóÿa8IDAT8Ëí“=kSaÇ÷-I“4&µ/-­ÐŒ nΊC?€â¦¸8(8éì7pR—ŠXGq±bEŠR U¬¶RÁkµiÓØ$·É}Ésï}‡Ø'¿€g8çÿ;p^à¿i\x™C³Š ,M½æÓùWÕù#1Œf-éùáôÙù½”Y¸²8ymrüÉ`>m‘λâöЙëö‰±lq¸,fz¬cÉ„9v(›Jæ²)¦g>¼›ƒ“û€¤©LJ FB‡ fn¾Ú›Òð´CèDDÐàt@héQÀ"³V©Ùã…˜´¥#”† :qW,â.À áCº7ßGn´Ýò6€û®ý£æ36˜!Èñ^ô#hà Èd3ú‘s§Fú·žO™øõµrÕó׊@jÔ<¨yÝÎRB¬ ’à…J§1 qʲ$ž=·hòêrи´^q#-xöUÑŒ4rIÈ& ÇCïB‚:±NØj↫;jíѼ Ðr»¶«FîÌÆDIT¯hD|t ¤êÎCT¶0bIì9³€§lïxöÛåˆF]"Ú’ -i{Цuê~×·* Žó>Š[þü”?ë`q¹úeb¢„h)”„X(”Žn‚¡k¨HÐïÿbõ{аúÓi-ݱXÿ¸pkàb"Q*áï"¼6±ã©°±©:­o¢]·í [´ª6ΊMíM%ƒS(ÝÔ -&v7ÁyΊÔ¿~á7 '­$†?IEND®B`‚vdr-plugin-live/live/img/remotecontrol.jpg0000644000175000017500000004316612650773437020567 0ustar tobiastobiasÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀz¢"ÿÄÿÄZ  !1AQaq"2±5t‘¡²³#$%3BbrsÁ&4CERc’ÑDSdu‚¢ÂÒÓðT£Ãáñ'Ue„“•´ÿÄÿÄ'!1AQaq‘ð"¡±ÿÚ ?úöá>4ø¤9‚}T'u+À~óµ—|šúTcpGHä@ QùÆ=˜öÒËî’5õ§I)INvÀcß×DÛa}˜5ª¥ÉZÂËî)JH'Ò<ÈÍiçr1‚òÿ´¾¹:@á Ÿp¡÷‹´ LtH¸>¦[ZŠBƒK^á Y$$JI8I ó¹?å—ý£ýõçÈË(ûO÷Ô0û«´xIIÂÁÁûHÑÛ^.TTÉe%8$€NNà EZÓ.AþU9¯<éóü¢¾s\9W™ $yËÿåUóšôI{l¸¿œÔlÖgÛ@I2^ÿ(£âMjd½þPüõÇ5á ;ã×5çœ:G®k‘;VdPYÔ¼æwWÑ^œÆ2>jçšó4%:Uõ”‘à+“ϸÛKuµ8”’•$AÁÁn+ ®oœ°àê)>êÍ4î¾»±¥OKSFPáQÄ |àÓî˜Ô¶Ëû*T'°ò\aÌ£¿c¼{pvªNÞskG-“B›»Ê±]™»CQK±”ܧ­¸ŒƒãQÆÅŸMÖV-´‡PU´…YY)Tií¡4RGº˜x_¥ûñVÇ`Å0±ü]ªk`þÜ?³O¸P‹ížäÁLöÒódË*K¹iÆÊT3¸Ã„r0F –@ ?Õ§Ü*¯×ÚÑÖç.ÙÅ6Ú µ¡\+uIÇ7JHÉ `‘™IA[à룣=i¨A[a7ôZ‘tÀ a ¥l¤,¤(’r²²…•Œd¶‘½w‡ mìKL‡$ªJ‚£¸¥:•§,qðaf:} ‚IÉSS%©m¶ÈŽTêˆÚ3J’°T}¤žúlÒÞQ#Ï„°H·²0N2G!¹æ0X#$yã»Ó›®«¯àw::oS .Ry_¿K-âwÏ:ŠËï;yT–›BP‡”I*J‰€ ¤äo€AÎøEÔ¨ÍIaÀ¶HZ:ÁýýG¼‹u=±.ƒ è?Õ8@=ÀÔOPA¯Qñh"s’ õŽÊÑ×[e—yĶÓi+ZÔ@ d’O Nk´¢JÿåñÎÒ öŠx ”ü+RAWœ»Ò:‘Ì´Ù PÇ" ËH#¬,ÐÉÙ‰3¤7Ó¢"cÇQô%D8AäJôsÌsŽ`±vZA*T2;8ˆúw÷VCKo_%ÕDpÇeg~y³kWfVµ’Fç @HÉ…¢Òg¡ÄŸ7Ð4-N`²@ã¼gÎ$té%χŸ}pqJ…uЦO rÜSk@ØàXêP=¤ƒÕDä$‡IJO `u@8Dz‚ˆaé)ZBŒC“÷Ò’O`9©H ! RqÄqÏ#=õßPîR!FŠ£q(K %++ý‘º‰êO!šÚÌ%£NÄóЯ: ²â ’àlñî6$2Gh £[lÄÌ·DTßHôf_ZsÀ\m+õ쌜g®®«-¨wuG¶9ÇnG Óhuö›m B[ym.Mƒ¶;:«³§ÐW¡EaüTž³ŒRÖ¡?yx~‰÷S%³â”o¾–5 ûýg„ûªödúšÙñtoØ£Ü++ÛoÅÑ¿bp¬®fŠºÀAîåLl~A{mƒK–!†; M1±³ ð5²0=ÌŽ}~¨¯šoíæêÚ]ftÁYXJI [Z–R’¢3+†âzm#êxÌ6Û˜Î|wôµWûЇ¦Ûb )=AKt¨îTFäç¯#zém1Õi|8beÔ';‹f3ì5uãN2úÛ¹­0¤¤åÈó™[¤÷¡@÷Ž}¦¤[¡]uËíÚl$·m^‰n4[J‘Ö”‚Acgšù‘ÑœSGí5üŽÛCMÍÍãU}Ykø²/ìQõEemhø¦ìõEes4V6 q#qcG£Ÿ¼Ÿ _µspcùEûÍù%xVÌî$ñ·û4û©Nd”1å'N DWzc)\„Ò(ÿH²%ÝÄ)®ä}6ÿdž^¿zµÂ»Â\;‹3*PXE BÁÊV… T(A£’“•b¥]§©ëm©Å©D>@  ØÝÔ‹3M]–"ëmBÂ@À œ8êô–É'Ä’{I¨rš‡9ööOo›Ãÿ‘VÐÝœË 8ô—†’§T²BÜœíŒg9¥?%· 2ôó}1p¶Œ†JóÅÁ“ÂwÎ1ι"xKW­KwºGI ,˜’©.,•uúIR=i)ÆØ¦Â`4Ø ` _¹é{dÛŠ®m¹6ßqZnJƒ%L­ÄŽA`e+ÆN8Á#«ì p_qÇœm§ÛB‹d­ÐØtdeG`Hí#•f œ‡nî©§R´ð6J‚Â@!Ce`Œg¯_¿£'-Doª@=^pÉÿ˯¢ç$Œë]P@ê2ZæéhQ+_]ËBÕ:ó5sCˆH;„¨,žì”;)©‡c%KØ‘“óRýƒGÛmªY\™rÖA[òžS®+Q$àdà Ô1¬ È 7a Å~*>*÷šWÔ ûÛ¾ÝLÖ¿ŠÏë/«¼Ò½üýéßî¢#àúÊÎÃý‚>¨¬­lÄü äèú¢²¹›+;oå^ý²þ±£‘¿$|($‰cî}sF㟽Z[‘ôÐ?«Oºƒ\&ˆæ;ioÉ”ïG†ñÄâ°IÜI £=ÜGìÓî¤Û½Á«6»±Üç--[‹.Ú§Ôp†yL-¢£Èt+@'­iuQ‘ˆÃ¸àq9nm}iJÖ qáù…z»mÙ ¢Bœ‚Y)JÈXŽ`V:ïAÎh…Þå ûChŠìŽ$Ë=.% ¡°9vÛŸY'j´,é—:žqßBRà W™ #| ð{;V5-‰1›z;ˆq¥¤)*IÈ î¨7kä;,'.w b;‰JW2z€É'¹$Ε|“yðÓ‰M© }$´“’ìÊ5BÆWî=x[\DÌž½Ò9ѳ¢H u`8ˆ!)’A8&¦ß}[ˆm·­JP Hœ“°aè™”‹~¹Ôp%¨4ýÔF—j8¶ÛEµ´“ÖP VGc¹xk…,3qŽáq ð:•q­%IIH3ω$»N¦ˆ´¦I´7Æ OJ2€5ÅÙ2­á ¹·,-Aøï!*$S’@dgH•Ýø¨LT´a™\+ó…Dü™ô½âqœã»4•å.îÌ]#:"–*{* }%8¡€ 9á>±=\=¸¥`XØêÒ¡A°ÒüK­Òóu™MÛâ¿ʼn—ÒTÓ xKM!Jqiql ÆIWM*¹GT¢JÂFIæk‡’çDM$«Ê ¸Û&Ëó¶Éô–’ë¨xu´¬ydÌ 1lÕºiv¬ä„¤¾NÃ'«—}zí³TF|µ%Ëœœ<ã#‚:è½¢{LI—TÊzhÎ4‚öz0²8±ÔqƒãQnò£ªqóBßiÂÈ=p$qpg«<¾Š´,Œd¹昜–ZqÜôji¶׎`m@îÎ ®ËPP'$yAº…ªÝiаäß;Cå)9- %`“Ù’p3Ï~Êm†Vb6\õ¸F|hÐYí›Ú•úë÷šX¿þIÜvu4[>,_ë¯ëV¿þIÑÜ}ÔAŸYY~&…òvþ¨¬¯,‡ñ,“·õEes4VÑár‡d—GûfŒÇÙ³áB#m>`ì”ï×4^?äÏ…hn?”GìÓî¡"Ç™زãµ";É(q§P…¤óA°Ñ{ž8Ð?«OºO–òeÅ·Áe/M–TJÔB„Œ­Å H l2IHœÕFEÉ>O4³© j$بF¹Iiv%Àî ÿfºpx®ÿþâ_üÊt]¶f]õ@n[‚’{Y#ÚMw•§®qØSçQ0¦Ò°’[a¥àœ0Ø Z}»ÉÞ™%¹F²håµÊ’䂃ڒâŽ:Æ)©˜­F`6ÚR”°KWhl)øòÙ¹ô`©QŒn‰Çæ°²8±È‚vÈÎk{mÒÒÜÄè/%èï¶mc¬~cP.–È(¾kq„Ķ‚‚l(JäFNÁF€ÊÐÖ7Ü+ ¹·ž¤]$ó(œ‰w;…õvK!ŠÊã2‡çÍ”Ùq¸ÉYPm l•¸¾8€Nà­X/O¾Û,ê•)Ũ$%6ÆÀ$œ2³i F³èÈ»ø¬Ÿù•6Õ¢ìpä™iŒ§$Ž•çâÈçŽ%qÝš3/N_"–ÊõzT‡(Z-Í-*ÁÁÁ ê#¢Ì~áci2®3ã\-üiC7°ã”8Ô’HŒH#$\€’ÚB J@l >Õoœ´.TT8ë`†ÝKˆ˜  ÀjzC‰ A ‘cKÖiWO6k¶©Q­V(RWÏŽ^~kÈ8p4’BPÚ”•ž"H LY:.Úã…B]Ù œà\äcë×!¡í`ï"ì®ãs|ÿ¿MQtÕÂJœþJm ¸â× „¥) Ÿ@žd ç^ȰM‡$´þ©œ²œ¦4b•±m\€M—JÚ-d®4T¥j±±ŸÄ°~LßÕ•å‹âH&oêŠÊæh®XøÂot·~¹¢ñ½B;gkŒáÙ-ß®ª/Ô5 ¹¾ ÿVŸu)^f.£¨J¹¨Ò`ÍZRIއ”ÒÒñ~¦BI‚òv†ë‘ûâ?f=Ô;‡rAÁÏ:¨É ^í4—cÜ¡<ÒÆR´>•%@ò ƒ‚+µÆùl[£ÆM´Ñ[‡¤.¨ž,çžHÇ"ç¤4ÅÅÕ;;OZ_uG%k†ÙQ=¤‘’jÜIi{8#²ÝVÅõ°´XâLméòYp-ç×Ô”$’O_ 2IB¼”@ŸL²ÜìÊ’9w wdœQÛV”°[ÖWÏ)#²ÂPOŽ£a¤6× RÆÀQ»Ü¬X55ØÜ\LxW•0ôyK8m/6މL­Gd’œìIX€ ºñ=Ò3ïÈIi·B”PàÈç#¸­´©% JT• ‘Gat ^Òò.=§íjYæ|Ñ?E 2^ï0d&mLŽû!aÇGFÙYH8Áä€3ž¼f‘|¢ßâ ËgÑ"áqeQÒÃJ R±‚µÈIó8§}Âé1ËOÛÿl½7g·æ–èìuá 0¾…ô»O±fa2JŠ’‘œÐýp‹§mJÒ7GQ DI’œ†·”‰Œ<úÞJУ€T:B•'˜)Î0A-n €ÅGy¦ÞiM:ÒmC ƒâÕÖߨ-‘¤9ÓÜã´Ó)µn‡s‚’HÈÈê ì*=çRÚç\œ‰ñPß G¨I!)$’ ÀåœPY?M:áZ¬6ÒO2##û«š4fšNé±ÛÎÄF@ýÕl”Ö7ÆoJ‹f³>™jPóï2xØNpž!±Q';sŒŠx·%h†Ú\'ˆ$On+” T`#6Þ?¢4nÊ• öÃø¹ÁØâþ±¥›÷äÜð>êd·+N6éõ,ßÿ&àî>ê"3ëKÄp>LßÕ•îžWâ wÉZú‚²¹›+f~2Ÿò·¾º¨´mÐhK_Où[ßhª/Ô5¢tºÙ?äÅA#lœÁS.Þ³G¨6?}CqI@dš. ½ß-–•p|²Du¾POR´ „àn¢§’¡DBI±Kš…«âm±é`JKè,«!`z5RT¢;P)†4–@S.%`lJH5AÑ8Íxâ¸F9ŠÜ óÔ+‹ç'ª€{ÔÒ¬Ðç9nƒme§n™BKÎ-Ò¢Û ‚”ú(*Zˆ$€' Äm3T¶c72ô§X@⺼OYÁvì)x9'Oj{ÌÅ“*×wm$Æh¸äWÙ HYBAR›Z)¤ 0I˜ò‰¦­w6]Ñ ¦ (Z‚@æSqžª¨æé›DvØ}»áö èÖ.’S’“‚+ï¼yRlv×îqåJ~4d—$±%Ά†êZG@É ’ c¦ùFÑï1$;²RÄ`² Ej+ œá8À@õN¤n÷j‘f±¥ùKšÙeçú¡¶›PÂÎH$Á98ÆìP±â<Ʀ2—™PR2ì­ó¶ÛÐm5È6Æ£¬’P1E¨ YçµÕ:ŠDÆd8ÛÎ2”žŒ% Z–¬‘°Jp2N08eÕ$I’NÀ wœË{’å!ÃOœ4„€¤)| @ÎÇ8ã$`‚ª€ce\H ƒÈöצ¹DËÈ%§â{Rsó×u rúh+yüÝ¿”_Ö4µ~ü››õu2[ñ掎XqXÒå÷Ôs¯cZ!õŽ?ÁûwÉú‚²µÓJþ[>H×Ô•ÈÙ^7ñÃå}¢¨¬R„£ã[‡ËûEQhþ©­vN€—e–ʹtcŸ¶ª)÷+†´»Lf<· éØ.]u’’À%$¢"JlÍvçCb”ïN"«qÕ±ªÃC))ЖR‚üuIp ²ë«S‹ÏˆîÀU¨«$°n«.ŽR”Ø­j*º‰*ÜÃÇi*9ë©Å=y¥Ù² Rœ†¨Ò:fî­[Š}úLèßÔˆvå$cq@NE® 9KI<ëªmÍ …%8<êõ52kÎÞPq’ðqœRáe@5 `cr 9àð¤G™ ©q0êBÛXd[àFEªYr­\@$ãg$ò©4+V8ciÛƒàSx ÷@$Ë~V«’óÎÊz&ŸeÂÓ-²®&¨(ñsJÈÈÜœ€A˜ÏØ´Î:5i«¥Y‘ ·–¼µ¬ÞI4A*T{,FØh¸Z„‚–Ò@+Q@'s¶I$ç´ÐòÜ…ÜâÊ~K­6èm JЏ€É–Ï[HÃnÈ>k.Ƴ?IôŒ¸Ðâ]©OG’‘Í-…Ñ/³ ˆß"ÃÑ×øZšÀÅÚÞ²¦‚0¤+¬ÔA؃ÈíÕI*/†ƒ4¦T@JŽãßÛ¢‡ùšcëÍefiYŒ©h„õ!k@ZñÙ•)U$¨±mŽ?нûUýcK—ÝÐçVƘàÁ¤~ÕXÒÝód8{ }a¥ÕüµüŸ¨++4©þ Z¾DÏÔ•ÈÙ^#ãYÿ,{íE£îŠ®,{í ŒG ­vN„**#HÜÎ|Í^ãUàaV г>8">óÚÞ;!aÅÁ<‚в²ZÆxU‹Ê2:m=)œl¸Ä˜Ôw!DlT9±™•Ô€¶@ZŒ{¢*Åѱ Õ#ÎX}a|L,­ ‚qŒ¢„_.±-p×*cœ)%#u-G’R9’{)²ç¡#(n»Ý §©°ðtêV¡óлo“8-ÜS:d‡æ¾žNHp¬ŽÜgaà¯c>¹È+Èmšs·kΣ¸¶PüÒƒÃÌ d€œõà3׌ÕÄ‚Rj°Ô¶9!NVŠø¶­CX7g7ÆG>êGºÛ$A[ýeBqŸž…n0V¢¥€¤AQ$ä‚HÆ4ôyÐËíòËbKJ»Ü£Ã/BÕ—=ˆ@K=À¼JºmÍÀébÕd¹Jš§l=ÖZklT´§>ˆÉ=a³É¦›‘d†W-EÉ/-N¼²1ƵTqÕ’NÝ\¨œ=Q¥%Mn?Â<‡•ÂÒ&Çv*œ=ˆ¥Í5•æ‹#î:Ë·ó{fšÊäl@Þ.?-{ëš)Õ43ùæãÕøkßhhœoTÖˆøµ\Q2‘I :ÉA=€‚3ôÕA¤ßrwtÔ±ÑM¶8°ÚNÝ$r²¤)=¡<\³„‚†n»šxŠ?S÷šOÕZN ñM¼°ìym&d²x\lãwlA؈#j±tI+^”è¨oÚhmÊzŒä™’Zi%KZÕ€ä“Rçi dÒJaÝí2’6 “I_‰(Xø$ Éæí5§µ]á2ã¶°± +E¶I «$“Žx$º«^Æ=]œ<Õq½ÝuSÍ-¤Ïq)Ž• Ëc $ud ‘Õ“WO¢7¨ÖËlh1’Ó)JHä*VqšÉ´º–è,š~uز_TfJ›d\$#=\J)ï¥&£±¦˜~|é)‘y|„.$·Vy¶ßZZd `2rI%‡_Ç~F’–¨ÈSŽÆ[2Â2Wм‡Š@ë$6@ï"•5kbë*Šâ\I!öÔË`÷ƒš’mE¸«hﶆœõ£ GQo/éûß\˜‹ä³/Cq*}—C‘å6‡X ’®úJú«M÷îfSËv#ŒùŹÇT´ -’Nêà8Á;ái’ +K{­JÈ €3¹$c÷Ô)®ªo”‹cTOÁÑœé”À¼¤ŸÉ¤;k2œásTÏG’ÑÛèkúmåq¥ÝÓøµÏ_š/4­+@Rw¢Ý£&]¶DUœ%ÖÊOýõ½¼¨Bl+sŽÊíÂ'×CÀW±Üu¸ÈŒþS"*C. âß·5£’ßg–;³M·½=~KŠeôŒ%ÔlGqíÆ”.ºOU´…p¶8ž@¼Âø‡‰ Ÿ+JK³‹`ÛÝÕˆ0žp‘Àà *Z”yÙÚOP“\¼€['<õ×TÜ[.]$RÒ¹¥±²ïì­­þM¦\®¬ÊÕ7A9,¨-¸­#„¨r$s$w“Ž¢*ÖƒˆQ:BRåÊ£vXÆ…h“”?¯së^½z«ìÁ¦˜—ûg>±¥ëϪ¿ Ϫ4R¿¶M¿›ãýšk+m ¯àU‹ýìÓY\΂øæãòǾ¹¢±ñÁBAüsqùkß\ÑXçÐ>£,?·ú¿¼Ð»”¶-öù寣¥:걜$Iù…N¾¾¨ñûqÞ’¶™RÃ,à­Â2BS’N02@ÉçU4‹„íMvZS9Ô[q„È]Š„ŽQ!a+N BÂÐV'* .äd…¨g½zuÇã.-¹ S%2JdJߌ’O¤……ìA‘iÖÚbë50 Ýb;!Y)m/ ­XæBA'¯ c®—,Vµê¥²—P¦ôä,ˆÑx0%NVQœp’H ŒH@ …{®G- Lùvµ%Jiàx °ÛZ2Ç#‚ ¤¬ÍÐü¢ ANÏ<Ö¹Þ”<‘jºB['Ü[ –¶x„ã$lN:²AÚ›‰Æû{j6ÛzR¼ii-©nXdFCk%FC`“’P´‚P $à‚3ËbmþÙóÈé_Ùa%LjH${qK·)zr ªjDØ1ÜÑ*å¥ñ•h nV]vâŒV"Z­É'ðúä(g­)(@Ïa$ø=¡´SVt-kuõ’·^tån,ó$õ“ÿ ØVÌyTÒo…ìÜöÅÝ€}E>úd·Ëa/6µ%¥rwe¶×A)újÝ“D$$Ž@b¶ÝZ6´¸”© IÜ)$Gq­—Ÿ…ê Se±>Ó­´ë§… ñ€Tqœ ‘“ð7ÆøÅwy·J¶?paÕ>Ó-©kKCxHÉ äã¨o’Wš5HNªÕs%+Žð‰Éc‰^»Q‹HXìJ/gÊ>¨Žãé!„OµÉZ\CˆWI9C£˜È8ØdŒŒƒk}«5>}ÁN¹:h‰XGe.…¸$€TA)PPÁ%;”äšëêªÆÜßÃ2\¹Z#3î²"MeÆÁ,,à©Y$5é(ÖJRS“VL`êXi2•¼Š@ÂJ°2@êç¡«"z²ñÔûŸXÐ Ö0¿Gâí矷së^½…øUF_Ôú DèkÉø²7Ù&²¸è¸M?þŒöI¬®gA%ܺ¿ í Ž}BPÜþZÿÚ+Õ5£/€EÏe7úŸ¼Ò”-Å„#3sœ5m:ò@{Ê~ºI¿Ôýæ€_íQîðŒYI% …%@RG"Üù‚ê ïU ›½½áà˜ÑZ›o)ua!C‰ >¨ç!U É—_+ZÅqZqhÓЖúÒ¢D…²ëH9$ÔrNr3a_üœÜ.¬˜ßu2ÛŠ±‡@u@ó` Ú=昴¶š´èëb; ’¥$ŸaªÝ™J˜M³JX§–ˆñÙHHnN0rO !Üu>¡ÕwÍ=¶êËqãddœO¤µA 7¾ê¥Znv_åˆ×Éë‡ a4¶Ö––éOk¤ÇyH¸ ’i—Êm¡ùÂû¤Ûi«‚KS ‚ÍŤ %'©/$l…öz*È ‰y5XXѶ¤°›&ø sÐ,ù¼$žèè ÞáY=f‰ÇvßhޤÚíñ¡6„’ƒ-äÈ“Iw=}iSITW$K¼ –É‚ \Gær#bjIzâê ¸–Ëu¹³¸ó·òñÞÂðQ­Z\i²ÃjtÉÂIPpä8Ò(ß$ xñÕšîœÓîH2¢ÀM²_ýêÚ³Üö’Þüí‡1fòë¦^ž‘Ö[[3Ÿõ‚טÖï].b¨´=ihœ ‰p? œàeÐF¬JGy¥§É)¬„ã]5š*ë¦÷m@*uÖÚKrÙHÜ•¶œ!ðä !}€Õ‹nžÍÂ"_h¤…¤,`ä@ ŽíÇxÍRÊvá­îɳÛRëz}'ð¹IÊ|ûôGò]ª·!¶Iwre·ĊnI}s‰ AŠÊž{ÑS‰BA! sŒrÎ ti]d÷\éÇŸx_lªL{´`HQ…Ôó(X” ¸ ¸Á3äöÿ¤'iÔν®[rb¸ç D%i[.Œe%H8+lI‚H#ãH‰rˆÜØ/¶û¤­ ‚2î#ý©r~Š„ü÷çB*ÜëàtÁž‡äJTÈäãlà ÑoÈñ|¢ÛnÖø‰…ð‹ëŒìT(¦‚ ’OiIȘµs¤m*ê#4—fò{%Ð\æÎzá$[ ž¤€Æç4ì†ÂÚ&²)Æç7=O¹ÕÞizóùÞ˜#ŸNoÊ÷š_¼ïÅTƒéß'‹pwæ¨ßdšÊÓÉÒ¿ø}§6þj‹öI¬®GAA;^n.í ²hVGÃW.xóçùþÐÑXÄðšÑ–ºI¿Õýæ ΧÜòTßêŸy¨X¢€mË_ùaºÈD8öXK²¥¸'d¬!¤nœRr¢•žª°”puUÏ+á/+*ud)»sn¼œõ)´!¤žKÇÅõV;γZai1¥ä4&Áà"BœÙOºOÞ$nVJÁqŒ`a[O]®.jO¸ûÕÜÊa¦–îCΞ‡äè#|ˆßb¦=@ù+ «¬òÅU¾N‚®Oܵcå@ÌyJk‹b†RHm?0ω&«èÄ_%©ªï–¨ E¸Ñ¢02p€2O3ÚNô¥ó¨.-¥ë…f"†[“1ᵎ¢AZ‡aÁê&¢é_u‰WËšÖØô0£,e¾ œX;Œ€Û‹$î‘O¥¬©D¨“’NôH­Ð=÷W[Ô*Ãccr \ܹ.¡°}‡4ñ£5-«Q²ëQÜ=3~„˜¯¶PãDŽKB†FGhÁ‰¸¼Bƒ^àJ/7y³(3z„ Œ¼à>å…ö¡\·äH#–çјË4ǽmÁW…žRnˆSÇøÌt:qÚR úI£TÄr‰C cºµ=¼ÍnG}hv t'°~ù;å ÷š_¼þu`ýöoÊï4 óùÕQž¤<ž,}ÀiÝÿš£}’k*/“÷1 ôøÏó\o²Mes:ñøêåòçþÐÑXþ©¡D~;¹ü¹ÿ®h¤a±Çg:Ñž?Y¿Õ>óQ9Tˉô‘à}æ¢QpFstú&ª}6âÕ«uK¡!n†ÇF’q’dÉdòÏ7ð«aïPøUSaåå[&Sož³–@!Rú†´¹#à«„Æô­ÚKå"JcH)Jk w;õõ÷P  'É\5¶9Âhç·)§K³ ¿ÆËà©¥¤¡cµ$~ƒKþEÚT­'NË#Ïm®;ôã’HIÅ<$ú¯’G(ïäÏ ò{f ÆV‡V¿×SîçÚHöSœ#-˃Yšá˜†8+ Jx ŽH9V0 ;`ã}Âqv‰Ó4¬Ï½-;*߃-En w¡eG‹r8oƒ>t¥B”¶ ÈâáÆ pvÈÉÁæ2ph¸$žFCf·ÛmrÜŠÈ’óŠx”Imõ <¡È(Ød­XI#loš”&ÌF”ð+FË')^xÁí'=´¿«ï1¬6wf¹—²dzÏ:vBæI?0Éä+\#<¼ ÿà¾âݴꨠ~ý-,Ž@$¬œM }+N¾òŠ– À“ Ä`d $çnÓ“O>AtÄäµv!7 ª\ÉjQÆá*9=Ù¤-5$Ü-—}N¢xo÷WæÆ%$6@K,dÔ4;”+äé,!gÊF‚»ª_ ]6÷NÄ‚A#¨ä ¾V§“%©~OìjQ$˜€oØ@úªwÊœ /-œåÉn7¬ñ,q°}•xi(J·ikL% )ˆm%`õ+€>ri.D8 ª´VýÕº¹VŠë¨k¡5ÊÍùBýæ]Ǭhë?•ûuûÍ»óUTeð_º XÐÖÙlöI¬¨z!xÑv1ÿÓ£ýšk+™Ðà±øòæ?Ï^úæ‰G;P²¬Þîxÿ¿>?ñ¢‘ŽvîªÌ‚.'ÓFÝGÞj-J¹¾ wy¨Š8<ª®ªù®|¥A~5ÎòJqæÔžkZ8ˆ@êh[ÍzÜOeXJyœ´ÚNÕ åÚ °Üp¸1”Òy‚Qìªg\b\fåÇu.Gu°ën€¤>`Ò~Š–ä(õM¥9dq¤Eœà9A#§lct aYÁæš5zÑ3n*]†UípíŽ;ÒHŒÔ|-â¢J’ãôYÊŠBIÉRr4>»vˆµÂ¶Úíè—r}%¸[!| eJ8Â@ ©d` Ý™JŽÚ³FÁÔ‘’òB’òHq§ZYBбÉhPÜÚ;ÁÈÈ¥7m:ÖÛ–•5é´ìC‚;ä~’H(Qï¸T¦«mÏùÝ»T·*ZÉT˜sc0Y'Õd lW é‚” $&ù¢o ¬l]·§²{ǃ€x e 1+ÍõÜÅô04[8vÍžÒn+'Ãooòy䙯oljq=«¥ÉŒ˜ÑÛADh¹çÀ’I'ô‰$ÑDyIˆ}~Õ²<‚­‚0ö­õ ž†]ošºþÙjSìékz jâD÷axŽ®þ³Ø w¦XTƒþUEóW黯œÒE°à`¢Cªs£J†G^ Zrœà„ƒ“Uø¾@¸Ú‘ðtuÂj(Äp9 M€:§¨¤;Á‚ ±ky:I¦tÅéaëc«-Û.Ü!*$œ†$`þ‹˜`o…‘w˵ªDŸ2¸†æ¼éZu¬¸ŒŽ%‚}#~c Ä醭 Ð cå>ÙfJzK}©^u4Á^ =á.ŽÊú G|õ“šZò{£mš2Ì´úäË”zIÁZŽrrGéœlIì™:VHK¨$uq Ыfµ5îGQ‡–(hLg4ìïøBýôíÍTqIžT‡=ôíÍU£/‚äÑ«#HY†y@cìÓYQ4“€i[@Ïø‹?PVW"“QñÅÌÿŸÉûUQXý”)¿Ž.é ?jº*ÇV7/]ì>óC¦»ÐEyìÑ ¯náš#sõ‘à}æ¡©)X)ZB Õ@ª·¿|‚Ü›ƒ’%»,’–âøâ! !'s·X$€ J¹Ý|šê˜î="CÚjwK®—|ÕJõO$”žÒr ïV|47¦/¿ÜÛ.Ú&8£âxKeJÉh/óNNR{N7 À‘®mp.v—-×d7!·¢…𕨔'©*P Zy¥~’IÜVÌ…ã®úo!Á• ¶âw)ϼκHÔ0ov»ìÛ“1ÀMCm¼ØP–ÆYQ -¼å])VI9Y >IWsÓúÆFqçeCn2eDZÎTR”Ií*ù»êè[yž%Cp¡}• TöëÄ9Ëq¸²háÖV’‡š=‹m@)¸S5ÂÒÒÓ©mÒB”2ÆÄޱšn¾èë%ä O„ËſɩÔq©¯Ô^ËG±B—ey0‘PÞ!ޤùçLÿ™¦­™õø"µ=æb%R]ËË9àÀm¾:Éú1ÛP.W¶ã°·äHC eKqa)´’p*[žKnn«ïºÊêQØ 'Ú†AúEJ¶ùÓ HD«’¥]Gª¹N©Ò< Ê€öK¿%q>ópÕí¿aÓÕ\Ñ5—$¼Ñóp“±)ds`ÎÕyèËB´ö™‰îÌCc¥XÜñ`¢zÔzÏÍÌäªÝס¨é<øç²NçÚhf·ší¶Á6k(+S-){ öÿjœšª<¯ë¥Xa¦Ûiü&ó9]vw'·@vÿëB4Ž”Í±›­ÖD¹²Þ9vW,¬õ$%^€Ø€v*Ç^õÉf›jñ-½Y¨^/N¹GÇJ––ÛV  „e'%Dœ¶MZå±¥mh[Ž–Ã ² °ï§éô8äNTwÁáÁPê«_$9è—å3q›h’û´Óhu‚³•‘ºT{‰ñ8ÉÉ9¦s@4u®T8ïÜ.gŠç=aÉ Ò l ¸ œfF²i ÿ¸|¡Ï}»sUkøÌñþp¿}ºóUTGÁhig1¦-CâLýAYP´Ó˜Ó–ÁŸñF¾ ¬¬”do㋦9|!#íUE˜åBá{¦ù„Ÿ¶]`íF7/]Þj"¶5*æp¤ösóš„Tž|IÆ€‡|´Á½[]pd8ÓƒÀÊOhÏýst”ìYnªÝôÒ–äŲ²ž¤¹†Üâ#úG–xŽTl´g×N|kÀ´r´öó­¶ŽÓK·J•w¹žºM KŠJp–›NxZ@É<#$䜒¥³€Ò¢RÝb–Ž|c>5…m‘ë'ç¨S•yךõE9ÙIÇVâ¼ÿY?8¡L¬¬Û8âNç°¬ Oj?´( ­^e¹ -—P…¥i ¥[ä´ÏOÎ+Α±ùèÏë  › ëM§Ìm–è÷KsYóDªJØq„õ5è¶àZG ¯D„à`㊋Øtü·n(½ê‰sœEŠÞíEOvs•ly’êHK7JÐÇßP3úB¼/°9¼ßöÅ[²`Ü «Õlk‘“ ßkûb½mæ$4âFç„ç '¦\0Oñ…íí 7låT|œÏ¸ËÎ@nÇÖªŒ¾<¡ð»ñVºÿ@VT'À°p‡Hóvù ÿDVVJ>7ñÅÓý!#íUEYåB?Ž.Ÿé ?lº.Ç*0(ëV[’üòÒ3鸦ÉôVSž{Fü^).ýz²Ù‹m»jnL§r¦¢ÅŠÚÝP W¥Â”¤dzJPàoNº³{Œ$ÿR÷ÐER:é×áj)² Ëe„²ïæß-÷¥ׯ{+Ž´å9EYíñûxnw ORUßÙX}zÚØ2>â'Þ˜ÿ>½k^XRR&é—íìŸZK­Eq¶ÏjƒN)@vž3UD›¢‹‡ ;TG.‹h‡¼`íÚ{‡o‡]x–ïVø?Q/³Iÿ6ŸÝG°ˆ/ Îà†AóÊ”çëkRÔ4ýѤ¨¤Éb4d2¢9„V‚±ÞOa4ɯÂR4;–çÊÚ}pÝiŒœÊ‚¸z±‘¿u-^'¯ª:Ûóu6RÑOF!ŽîCª¾¤UŸÏwÛ™mëÑ]ßø:¯]ÛG=7yGþuÒú—MêވŹ0§4Ž5Ä—´­HÎ8Фq%ic…mÖS/Ü”áÀV+•–dÄêÛRà(©Ö+uIä–ÊHP'¼”í×ÙVQI]ž]¶ÿ[WUFQÁôÅVÈL¶¥[[óëè£Æ .<úðO P’HI¡»ðÊ„ù8–vϤý´|ÿ~;ømRlò:;¬;‹þŽ =8“RÖÒ½œAÏQë¢n%*#ˆæ¿-äüξ×YéÂ8®_×àý®ÃÆhî4½ç.~‹zâÀ.Hòy=,§u–Œ”oF‡J•ŽÄ‚{5>Þí¦|6fBbì>¦Ö˜éC°‚;w¯º›S®¼–Ôµ«„ÚI¤M#q“>ñ~r[0¥ÊyØŠÇ ’p®%å^Ü×£ÃùM}¤0•ÙÇÉxý´¡+¼ï>P4íºs±cÙ$Üú%8ôX̸‡4…¸¤qv% Ž{íPå>Ð=]q(‡ÿ6ªûšß‚± KJaØÍ¥¢Ò† 8F1¿VÜèk’”Iô«úñ{oUí&ßô~r:º­Þ~iMg`ÔR— ˆ ƒ9(é<Þ\vœ@ÆT… ©*##9åM°Ûs£-–šA/% •lFÕòÝžDϺbàØ–—J’=D`…ì'ƾÓ/­ß2S£ Sí}jøÛÍhê¸ÁÚ=¶³ÉÍ?Æçí¿œ/ß@®ÀåTu?Ç.Ûð…ûèßš«Î>}>´‹ ¼6Š×Ô•Ȥü qü]¾¿Ñ•’ŒÝdý²è¼~T%°”]®D«Ö!_;«4M§”’H 5dG¤J†ó!*-… 8’ ¡¶vìçÕšZ~É%æ–˰RëKÙHqm)'ÄS½ÓÄrõO¼Ô2`¥b™m§ŽJ¾g“+[ï)Ï€"‚£ËïxúõÚ“(œK­Yb¶ r-uòüê²°3ÈW7]èÖßjW ÖUêälOvqžÌç¶¢Šés“M7‘j‘-EÀl:Øÿz¹^4˜»µÑO·6ðÑ+SdöéÉu+Jm¶T¦ƒ¥¸B’ ! Œd(€Gæç•xe?‚¤Å%°ÈuJ*áÆVê9¸!¢AëºôsqMSVWßöYn âM±“¿ôÑÿO¶è6`Ÿ¼[šlg>‹ïþÕ<Ê[4ÒÚ\ue”¥c›…!pUá‘Ù½G\·Ð…q°€°¤¤%O¹ 9ëÆÉV:‰Û9§$PŠÊTEžjS„°06ÝÖú¿Ö¡3ô,yŽô®[™ã<ð´÷©µ¹‡Ñ.6”#¤ R¸Â¸µmÔ8síÈ僂S¼\+i¶Oß KŽ@HeIüÓé(<•c«sÚ°á;kþ3¢œ¢©?ÃSäæ?Ä89Á-Ÿ÷¨œm2ä0z(éóÈÿŠ™C¯©Ü !÷Ò ”A*.–õ}\àç°òÛxîLq/)¾… á(ô dóØË–ý¹UcI”IIÉÿ&ÿ±vë¥Ñsl7:ÞÌ€‘è— Þ*|˜ÚIÏÁ¾tÅVPI(APõ•c9ÆR+ÜÕ]¥ÓÇÜÍ!Ù âÂx…®¿D ~úa¶ÚbSKt²†ÛXpúyRŠwÕ3“ÈmEϲ´<Áꬶ۶Zø’? ¸ó…ûèßš¨ª¦GLùã¤2ËÆ‚ÝŸlñ¡UpeŒV‡±jˆ26a¢+*%ªDo‚âfC`ô(Ϥ?¢++&¬³õOâ­cpˆ¼¥.¯Îšý$¹¹?Û Êð‚J@âúiëÊF“^¤·6ôÅÚ&LgHJÒ}f×Í;oˆ÷ˆºÜæÚ§.ÝuaÛ|æývN ý y(v(lh²V0ÝæÏKÁÈ2ZÇ[n£ øA:†s#­|cµ‡ú¾–Íñ+%C5Ñ»²ùõQ›±™­QlVÏyÄsÖdãç65æ×#fnVOWJ3óRœÒ÷PIíØVŽ&ÃïŒ6GêÐXú—P­Ò¤œ÷ó­Š·Îë«ÞjºóxüSG¨¡e>êè–\F:+¤äxIW÷ÐY`g—w/Ýû«8¿KŸý @ã¹$zɃĤûÅxd^€Úý#ûÿ†–,°ùïÿ[ל]|ó¿=ó×Uê¥^Îs¨$õÿ qq몽}A0øpY[äÁù·­K‰NIPÚ¬L…~Vóp_„•qÈPWž™Ç^îqÕ+ßAe“2÷j‹üfå­¿9áìë¡uµ…¯E©I=Œ4¥Ÿ•%†mŒ~N;Iö Õsc7²ŽÊ åk™dA²¼¯Ò}Àó Ð{…ïSÏmITÖ ¶ AK å^G>áB¼6€p@¡’ï›ŵ –u*PRR”w$œ“ßC—6TÉ-ĈÊäI}Ä´ËHS‹QÂR;ÉÚ¸E+õÉ»m¢›„Ç¡;ek;îp9Òv¾•òägîUöõ.©èŸ¾pŸ7Œ‚Ü,Îy)Ìm‘°ÉÆyÖ[*V1iÿ$–¶|k‚:YŒÅi¹ @ôTàH #¸œÖUYPÕâ‡_lv{ôO4½["\”¢CAa$õ§;¤÷è•e V_!ÚQ&n–²wüb”3àï<=”±sò)9U§Vþ«ráç>+J¿Ý«Úµ¥“Õ3æyþG<¢BL&ÓqÕ唫æq)ç S´‡”+vÒôÔãüƒi‘öEUõ©å^Õ¶)N™s·mq·O‚G?9޶±ý *3z•ry³ŽxP¯¶Á=µçd²Ü8¼þÑo—ûxÈ_¼RÌÑñÇÃÈǯôÖª¾£,|õôV³ÑZ5–T¶´•µÿI6æAúµJê›-…« ´Àkõ# {…,”,¹}@ä±\¿¤~x¦-h´È|íp]üøéW¼Uß¡ô>ŠÒVþÓî«²í¬¨ý)¥Š>e{R4‘éH@=ê¤{¼™êà€Óóz˜l¸ÙÍ}·Niè¿0°Úâã—C´{…kvÆif½Oˆbi}q CÑÚ@òRà8Òµ` 9Èו[ЇIdoJ¿:dæ€ä ­^ÌWØ#u¨wW¦–ZGÌ–ŸðlÔoïzÕ–Ø}©‡r3Ý•ñãƒáOðtÐpJ\º»v½9Òüž‰¼÷‚Uì*>Ú¸*Ê…¤ Óšvæᘖ <c*Çc2”qžYQ*>9¢••”VVVPÿÙvdr-plugin-live/live/img/favicon.ico0000644000175000017500000000706612650773437017311 0ustar tobiastobiash& ¨Ž( Fgg+\"x&d0‚#/>/6†*3r6989‚43S7GFUL@N‚K!ŸO{RŠP2GMYOc›LD(Mi–S<šV<žRKWp(Sq=SjWlXjUS Uu/Wn¢WL¢WN¢XLdY_:XqK[e%]nZT¤ZNldCo]\‹]WŒaJ¢]RTab…`_>bte‚³s g…­v¥lE¦lE6hƒ,i†"m|´v0mm¤w?¥y;]tf¦y>QtrsŽt–Fxxu—:x‡)x¯~M¤~R¥P°€L±‚M—ˆK}ŸYƒu±†U€#™¦\‡vgŠoƒ¢„¥ „¨¶F…¬#‡¡]ˆ¬º’S‰±Š¨Š³Ã“S‹´ ‹±¹˜MŒµ—–c´Ž­ µ½˜UÅD±‘«¸‘±¼ŸRÆ¡IÈ¢H”¾•¿•¡¡d•Á—ÁÈ e˜Ä˜ÅǧRšÇÄ©W›ÉœÉÆ©\ÈÌžËÇ­ZŸÎ ÏȱZ£Ò¤ÓÔ°gË´^̶a˸`˸b̹c¬Þмj®á׸{Úº|¿÷âÓœãÓŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ%-2'ŸŸŸŸŸŸŸŸŸ,0(m4&"ŸŸŸŸŸŸ 5oJœ<=[ŸŸŸŸh{—…8t}k\ŸŸf# ƒ Œ$XAV_ 3LW] )Ÿ6€FyDPIi!ˆ~SŸŸ*;z>†ap.‰G`1+ŸfK:Qus‡jbd™e/ŸŸrMcYZ|“’‹RlTnŠŸHNE^„•”Ž–vBO@ŸŸŸŸ9qx˜‚wC ŸŸŸŸŸŸŸŸ7‘›žšUŸŸŸŸŸŸŸŸŸŸg?ŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸÿÿüðÀÀ€€€àðú?ÿÿ( @<N rV o%[H x !r ]alo$j,la z+f/{$ƒ}%i) }&&&/‚,q!3‚0<+/h,p0-91 €(0015y(;…-'O+DA,G<2:N0Et:n8!‹/673Is@ =C4L|56;C‰61@>G’86#;S<.>T™F>1…M@U&@SF@IŽO0BMX>Me=M|F'L?QGM‚C:”@>GZJBV`N*AHI˜CB’G7ƒN%J\&KVšG=FR?VJV{HQ™P/=PO™N9˜JGHQK*PZtX&Qf«_PjRhž_ U^7S[RO`BQ_†NSSn’RBPESETh%TgVm£\"šU>›cjQeVYWXp”]8Ÿ[;‚SaZq\m[us\Pªo$^g’c1›XS¥c,_wf\_^Fž`?B`b`¥]RŽ^Xax*boIgTd`e;bm›m(5fdc|d}\jO#goªcOŸr'¦dWm=¨k@g‡ i~Jl^¡hNei`i|¸y0jt§lF j„k†j‹«h[l†Cqdl¨qD_q]Ui}· o‹©m^p’ƒph¥rV®yBpvf‡xYªyJbvu¯;xœ§‚D°Q±‚Iš€X{ ÀŠ.šyy•€e¤²ŠCŒƒh·‡N®‹M´ŠO·<·R…«†­xŽnʘ7¼”NвÀ›:¶eÇ›?º—Y¹Â˜]ššjÍ E›k¿T”¾©Ÿe—ÂË¥NÆ¥QȨGÅ£ZÁ¦ZéQœÇÄ¥wǬ` ÌɯXÖ®_®®nδ]¦×ʵf̹^в{ªÞλ`ܹr®äÖ¹xf®Å׸ԿpÎÁm³êÛ¾}¹ñÝÅŠßÇŒÚË‚t½Õ¿øàΘæÛ æàªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ9ÿgWPÿ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK„«¢¢‘««¢¢‘Pÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘“““g„Ÿv¼„“¢„FÿÿÿÿÿÿÿÿÿÿÿÿÿÿP“‰c|PWdŽûîŠWKW…acÿÿÿÿÿÿÿÿÿÿÿÿÿÿjÆ¥S* CØûû t*FRØâ ÿÿÿÿÿÿÿÿÿÿCuËâû¬";ûûûØb@Çûûçuðÿÿÿÿÿÿÿÿµûûûû¬¡û¬Ëûi'¾ûßôö~ÿÿÿÿÿÿ[ÐûÇ[¬û¥ &Ëö_y¿èÛÚóÚ©ÙÌæÞM Úÿÿÿÿÿÿÿÿÿÿÿÿ#_yÎÎÎÓÎ÷ùóòÓʸ”BMMžÿÿÿÿÿÿÿÿÿÿÿÿÿ-œÎñííñøýþøïêàÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\ÉññõüþþüññÑ>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\»Ùõý÷äÓ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8}lÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú/ÿÿÀÿÿ€ÿüþ?ðøàà€€€€€€€Àø?ü?þÿÿÿÿà ÿÿü_ÿÿÿÿÿÿÿÿÿvdr-plugin-live/live/img/rounded-box-redwine-tr.png0000644000175000017500000000067012650773437022174 0ustar tobiastobias‰PNG  IHDR;mGúsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ"§_)tEXtCommentöÌ–¿$IDAT8Ë­“ÏJÃ@‡¿Í¦Íšhƒ´ˆ þ9x/o¾CßÏçÈxô(*z¤µëeV¦Kƒ80̲¿Ý™üS$’Ž´°ì ±ÀP@F¾ÀK ý¯‘T£`èû€,° ¤OרB[!G@& A‰û6ÈØœRC:A¸ WjLZvRàøÞàU]/‰Æ½>Ñ+`¯9¾¯).žšó©×Ë_Qõñí9“Û7>¡:-qÓGÞ”ä0— ?£r Ù£äŠƒ0j`¨äÍ2¥2‰}££©Ùä’ý°#-¸¾‚¢ÜŒ&¢¢”Éej!Wηº÷ÌWwb‰Böh¨|¶¢¦ Ò”8DA®q­ë¿ð<ânsaIIEND®B`‚vdr-plugin-live/live/img/info-win-b-r.png0000644000175000017500000000072212650773437020072 0ustar tobiastobias‰PNG  IHDRXþbKGDÿÿÿ ½§“ pHYs  šœtIME×8 ýW“_IDATHǽ•[rÂ0 EÅû_UwÐm„B_äAb÷Gž¹(²úQÍhÈ£#])âb{Fàø.À;pNö|>€o»;7`3/5~Þ€,~V`ñz¾J ,‰¶(É2© ‚&ûœ ´Øw7eªßY²²õò*AgàjÉŒ®:•'Á‹} M*™4IVI*÷ª© ³dU]«e(ju³ÈØ’p:ÙD -VÅÕ`£ônqƒáe+ äR‘¡¨Ò,N¾ ÒIô…Ò î‚Šê³ôhØê`Mé(hs㾈\-­é«=ò_¨„ÙɽO[ ]8Þ¸jp“¸ºêZ¢ù.%ÛcÑ´Û8:o®£dcYns0ed'ÝÔ[ÁËçîbMÖP:°(PÔ“ÒI–dzóŒNæ]À8Ò·òàyïÿˆ£Á±òäùô+Ïþà…²_‡Ó1Ã"%0IEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-ml.png0000644000175000017500000000015612650773437021450 0ustar tobiastobias‰PNG  IHDRãíŒÆ5IDAT8ËíဠÀÃ` h#d/]Ø:ñß{W|¶ÿŽŠ F9Ÿ¯ˆˆˆXj™N?S¢V*IEND®B`‚vdr-plugin-live/live/img/rounded-box-green-tl.png0000644000175000017500000000075412650773437021634 0ustar tobiastobias‰PNG  IHDRãîZÄžbKGDÿÿÿ ½§“¡IDATxÚíÜKNÂP@áÓ‡ mx &Ä¡‡®À‘!Ñź!àÀ{ãµ¶ *:ð|ÉM ¤ :9ùK H’¤?•}óøÜS(IÒïÆ8ßñµ$Iê¶Þ%ÆyË~ÞØ7È’$íâmcÜŒoºÊÆë¯NÜ’$ý7›åÏ¢Ù߸  —¹è˜”%IRûT¼ž²-CÜúÀ!plÂç™A–$iëo€ÇlËÇW@V… ÷“`Ç {©Z’¤÷6iˆ»bÜ ñaˆn €qØŽ’(Ç ¹+s:–$©s2ÞOa=”-!¦1%ž3`ö‡IŒ{¼þn\„ïq:–$éíTLˆð:lïË&ã’—ËÏuñ8Ž9êær¹b\“úž^I’¾¨üd*®ÂT< !^ ®Îo³³i<îÎÓ(IÒÏÄø£©x&âS®/n²ÅÀK’ôCòŽ÷â[ñ¦­ 0çêÜK’´çÇɸàõQ¦0eXÕáÒ´!–$i1n{®8ÞI]C.—+O—$IûŸŒÓ0Çت€ŠqíT,IÒ<ù '”©¹mðIEND®B`‚vdr-plugin-live/live/img/rounded-box-redwine-ml.png0000644000175000017500000000026512650773437022157 0ustar tobiastobias‰PNG  IHDRãíŒÆsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ%á¨ÉÅ5IDAT8ËíÁ¡ À ÀkC0•UX,³Tvéî„è È¿;üNT\¸ÑÐ10^óÁ'"""¶Z6TµÿR(IEND®B`‚vdr-plugin-live/live/img/zap.png0000644000175000017500000000104712650773437016461 0ustar tobiastobias‰PNG  IHDRóÿaîIDAT8ËRÏoA}óÍ-•XØÅ¢.F±FMŒ'&ÆÄxу/^¼ùÓÁ£7ãÙ›‰'/jµÑ˜’¡J©5J±»;;ãwåÇbüN3ï{ïÍ÷cX¼ /,u˜3b‹n--¯º£|¶pîþC¥õù€–£,abÌVZ‰‰±’PZ_ÊÉxg»‡ &ó€Pˆã@!¥4V+ ‚ÓíÊÖ†”Bp"X¶=:LÌÏíùSiôìñcEœ=c"æxþz /—ËR˜¤Týó¨xß|×®œ\¾x?º;xWªú)•ŸÛB:5ã'½0Ò‰ááƒR:Ø ûÓÂÿ`BP°Aõã:–Þ®û÷J} ï+Í!N$"À9Ï`::…FóZín¿_W!¢½Õñ9áŸüs™YLO…þ–Ê …½)$⻂¡´f±Xæþ9€ë*4¿tƈ†‘D:µBØNÿS*­HpN[íï<¢#]ü+éâÕ›€sZù 5¬êOßoÊIEND®B`‚vdr-plugin-live/live/img/english.png0000644000175000017500000000141012650773437017312 0ustar tobiastobias‰PNG  IHDR‘h6sRGB®ÎéÂIDAT(ÏÁÝoSeðçyÞ÷œÓCWÖ1Ú5H ,¸.Îjhü¸!dn 11Ñ o½'á†ðè®41šÑ #o& Xo¶±DÙt±l¥›´eí>Ú³¶ç}ßçñ÷Cæ…³ˆmmõšõ¤Ò™p8wµ(Lð5‚0 $ÿ]ÞúæÖoq?õü3C…æœÝY³‡†M¿{âì”DÖŽ»ìì n}÷íïWß»»¸Øªntÿ­´ûíž‹ömÔ\]›ÿþ‡^»³³Î°hü¼yë‹¿®]m$t·âο»ú¨¿ü'—Ëc––J33äDãÁN´weºtþÉéËùFs× @^žJ ¥”‡NÈs ÿ¬.sœ:ý‚âRi…èèÚ£¸¶ÑolÂÞ^7îÄùÒl:5HŽ„td”ZÛÞíË'Ž6£3÷ïU}ÿL£)³?ÕÂÄP{»Ýht/ݸ’É+ @$¶6÷ÎÅfyµ»½­û«ýDe½1’ÁjÕ«×›AeÓ‰•?éxŠž”o¢Í8ùì§Ÿk%RœÔ~p2ðƒ "»¬º ¤A„Ù>]Z2Ú׬µ÷ß²ýz„”±dMlœ à"T$~@ä°¬ûCϽõ¦N Î¾xv75zª8A$ ""(à!0 "Tš\«…¡v>&'î=XH”ïwŠ­@ V¤±®ñW‹/}ô¾(­)ÈeÆŠ_}øÕ—túÜX.ç£"`…Ž S§³ûËòböÌùñBQC ³r°×‰æÎÿ±87<0Òi@T\·¦–PG ão_x=›Ï01rÌFƒèõìje¥<·P™[د×c§Ò‡óSSã^)ŽŸ<8zÑCñа0:Ù¡¶Öv£¨µÕŠ:ûNzÉ0<|ht8• Ih @ÿƒ{wœ¬ì$[IEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-tr.png0000644000175000017500000000053212650773437021463 0ustar tobiastobias‰PNG  IHDR;mGú!IDAT8Ë­“=NÃ@Fßîú/^FÒÐ@C …)é‡@Êý8‡O† 1Yšq4YÅÆBŒ4š‘å}úvg>ø§°’Žd° q@& #ß ¤vý¯}©FÁ:`rÀ H¥Ov¨B{!@. 4‚ćC¤&@¡ÅAî”J‰@ë!PœŸÀð¼«ëÙhÜ­ôV¯€cïñ™äô†öu _^=n¿£â+:SÖÆUsS\^akV/K%¹V’¤ËÍè;¹ Иì üݘ'ÀPÉ›åJ¥}££1é ÊÛp,©@б6ŠÌÔ‹Š™\®rë|¿{'×Ob /{”)Ÿm©éƒ4Ø QPªEÜéúA :{1ð¸IEND®B`‚vdr-plugin-live/live/img/minus.png0000644000175000017500000000073012650773437017020 0ustar tobiastobias‰PNG  IHDRóÿaŸIDAT8ËÕ“?‹QÅÏ{Ο82úœLÐFlA$i”`eÄ|„|›HéB‚•ùéA0),\°·” e--ƒ3““7Å{;oR%¸KvÙ2¹å½çü¸\Îþû"· '“ÉÛ¶‹¾ïé÷û?ïLǯ·Ûíãñ˜Æqœî÷ûËåry6ìëÚÌõÆp8üÐn·ßU*Ã0 B@)¥Œ±‡Q=k4“Õjuù[OOÍÓéôQ©Tzéº.4MƒR I’r¹jµÚãB¡ðæÔ£]9!/<ÏÓ“$Ááp€¦i „ü1ÆP,ŸxÿW€a•r¹Œù|ŽÙl)%„B Õja0Àó¼7n ëºï8ªÕ*ºÝ.òù<”RàœÃ²,0ÆÀ9ÿ~# “É|’R¾j6›´^¯C¥t]G6›…išR.O=WŽØëõ¾FQôÑ4Mض Çqàº.c°, œó ß÷G·f MS²^¯ß†ax ‚ ‚ Ã0ÙívŸ‹Åý;'q³ÙX”Ò§RÊ{qŸw:oÿæ3ý!4ž_c—]lIEND®B`‚vdr-plugin-live/live/img/one_uparrow.png0000644000175000017500000000141512650773437020226 0ustar tobiastobias‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ŸIDATxÚbüÿÿ?% €˜(Ä"MgaÊüÿÏÉðãï.FFFÎÿìÌv LÌßQíû2‘ € "Œ¨øzó½ÒËFÖ&ÂSÙ˜áÝ·6NF> >I€Âî…Ì„…93»J­¢-xÄøS~ýva…2€Â4àß6†ï¿§7š‰0‰ 3\úÂË ãfÅÍÈÀ8(Ç Öøï/@A øÁ€nÿü³Íß]ÉÈ;@—aã5†/˜%UØåTÕþýëcààa`”e`Vë Tüþë.%Æ•S–oÅpì ÃùÛßnßÿÊpç5Ã/ =.Þd&–vnv^°€‚À ¸¿ÿ…˜ÿí¨È³dÿÀ'̰÷Æ?†ƒŽ1Ü=z‚‡éÃ?n&)M BÆ& óåþÿk ˆÎÿ½.È[Í@ÃRƒaïM†óGï0¼|ðâü¯+3þ¿:Á™eÚ¿IEND®B`‚vdr-plugin-live/live/img/rounded-box-orange-mr.png0000644000175000017500000000025512650773437022002 0ustar tobiastobias‰PNG  IHDR8»EabKGDÿýÝvY2 pHYs  šœtIME×*¥aU¹:IDAT×mÁ± € °g_ ñ%?òÎ"Ñ‘8áàà@xÀ6<÷^üˆë±…%eœ¸PÑÐñâÃÀ˜” ÿ€«wIEND®B`‚vdr-plugin-live/live/img/inactive.png0000644000175000017500000000144512650773437017473 0ustar tobiastobias‰PNG  IHDRóÿaìIDAT8Ë]“Mk3U†¯sÎÌd¦#i ¶MH¡ð.$দ‹v#TTY»pP\ˆ¢A¾ñ]øÜL£R(”J] Y*í¦µŸTlJÚ&M2ç̸±¡¯ÏêYÜ×ÍÏ} þ7Fã-)eËuÝ÷•Rs€cŒ¹Œ¢h+˲WívûÏçzñ´4›MGñrzzúÓjµ*|ßǶmŒ1ŒF#ÎÏÏó»»»ó<ÿ2 ÃdbÐl6¥ÔNµZ}·R© ” Ë2ò>¦\.ãû>ÛÛÛœœœÇ1QÇ1½^Á`'IòñS_Að…1†b±Èìì,žçá8ZkŒ1¤iÊh4¢Ûí’$ ½^ïû0 ¿²ºÝî×J©·‹ÅâêÃÃÁß÷ñ<!ZkÆã1ãñ˲è÷û¿ß(€³³³lffæg!Į뾣”Q1‡DQô”Ȭßï—eÙ'aš×Úø¬Î/„-Ïó>”RV„ùuþ5˲ŸÚíö_ÏõÿÖo’ùÞ¤§IEND®B`‚vdr-plugin-live/live/img/rounded-box-redwine-tl.png0000644000175000017500000000107012650773437022161 0ustar tobiastobias‰PNG  IHDRãîZÄžsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ"§_)tEXtCommentöÌ–¿¤IDATxÚíÜKNÂP@áÓ‡ˆE[Ä QcLÜcgîÁ=èbÝêÀ{ãµ¶ :ð|ÉM[HtròC H’¤?•ýðüÜK(IÒïÆ8_ñX’$ [¬ã¼g?ïìdI’V ñ²1îÆ7]eçø»·$IÿM£üU4ûâWŒ’ “²$IꟊÀs¶dˆc€GÀ60¶’íVx?3È’$-âxÊ– qŒpLª€äí$Ø1È~U-IÒGmâ¡wC<Ñ{À4l›$ÊqB.ÂÊœŽ%IœŒ[à9¬Ç²'Ät&â$Â3àØûuão¿ásœŽ%Iz?"¼Û‡ò“ɸäõëçIñ8y•Õ§—íô¦aLÍØË+IÒ7•_LÅU˜Šg!ÄÇÀñçwgmÏ»÷2J’´ž6„‰øäš‹ÛCv°$Ik’¼oÜŠ7míó+Î ±$IŽqœŒ Þej€Y•Õ§g4†X’¤ Ÿï¹âx'õ¨/Ûé—K’¤ÍOÆi˜ã?lU@Õ¼Þ1íT,IÒš½ñ2*&ïGw@IEND®B`‚vdr-plugin-live/live/img/menu_line_bg.png0000644000175000017500000000027112650773437020310 0ustar tobiastobias‰PNG  IHDR½XåtbKGDÿÿÿ ½§“ pHYs  šœtIME× ®ßƒFIDAT×]‰Á €0 ÄÜ{°+Û ±ƒåš†GU|,Ëæ8¯’(œÈ‘(ÜQDò}™ó¹Øö4DQ…¨`,{ñkÔÄ ÖÔ9ÀþÍÜIEND®B`‚vdr-plugin-live/live/img/rounded-box-green-bl.png0000644000175000017500000000104712650773437021606 0ustar tobiastobias‰PNG  IHDRãîZÄžbKGDÿÿÿ ½§“ÜIDATxÚíÛMNÛP†á׎K!$MEH vÐŒX{@,ª[j€Z1Bb€(4PÀ8øš\™j&íûHG±-;ƒ;ùtîOB) •+@Ø>ÛÀ{»I¿óI’Ô¨tƳ"Ô𠸮8¿øèI’ô:a\D•·¡®1pÁçïŸ.I’^¿3®ù¸ ]ñàŒ‹ñxr|jw,IRÃZÑuUµ†ÜÞ„Ê8:ýÊæp”ô–·€‡O’¤æÃxR åz8÷“C†«£dÐÝ eI’þRR»wU/]ÊÕC`xO¹Ëzµn—Ñö>ƒI¿ãHJ’Ô`¸ȃÊázò(Ôrx·Åtz{ÖÿK’ô?›„ß{¦{´n³ÚKEÓjWuÐñÆ®1寮U ¸Z[N£o cI’‡q|Œø.›ñb]ç”g㮟¡#^Ú¡ªnºZc6ˆ%IšÈEøÍ<ûËõ@& ãêüq›rjºM9-1¦Ž;jI’ô8c«çü¹î5­UU+„qÆtØ –$iÁ@žg*9}"˜ëÏÀéiI’æñ°~e |Iòµ·íóç>÷S_wÓ÷º*{o¿ ¼ÇÑÊ@;3áÔÛCæƒýY÷Gus‡ü§¾ÇX{Ÿ9dpÈ h €½=…ž2؃ý$9f>пËr°_ûd9ä,} Üd¨ë`É|X_¶ÕÆ!ÿ±Ýõ±z-À©ÌŽ™ƒ}Íui-sÅD0öö¬r@ò¼z@˸Ï:D0ÓfÍÜ%¹ííó× ÀÛªÿàŸ—®Ø^/P«LeM­ p,ý]’ïI>ôï\g®pµÙC8ös¶rÀÓË<´ÌR~¹éóNYn2™ƒSÖá`G/]+PŸG@ VHïêu?2_'0‚#¬¯P9vt©r@ œ²ü§ÿŒÀ@û˜9ðä>ë`À¸N`Š`¼«_]+,ÿ50pÌ:0*{•®ú7¦Òj8ØÙá7æŒÃÿZ=àTÞ×+F8à>Kµ€Q1`ʺb€€¼ƒöй­´qè_‡ ãíÌ>ÀÎÚ+çOå÷”uP`ÛÚ¦ï¨ýÁüm%éÂó¹P€¼“ö‡k¶Ï#PßµÖ;ko°îRU€ös€µ7^ßvúðJmç}„à/kÿÈžÀ+Mþðû °«y[Ëh'IEND®B`‚vdr-plugin-live/live/img/info-win-m-r.png0000644000175000017500000000026012650773437020102 0ustar tobiastobias‰PNG  IHDRÀ[¾–bKGDÿÿÿ ½§“ pHYs  šœtIME×#C€¢í=IDAT×]Ê» €@Ñ·eØO–`âøC•5ÙÈa’‰Ìœüˆˆ#NX± a®6tlØë½pãÁ‹,}os¾F"ÛIEND®B`‚vdr-plugin-live/live/img/movie.png0000644000175000017500000000141212650773437017002 0ustar tobiastobias‰PNG  IHDRóÿaÑIDAT8Ëe’]h[e€Ÿó“š„-[Ò$Ó™4뜥dl,ÛE[7” ,/v±¡ ×ÞJoõ»•!ˆw¢Macʬ£–6ët T344”¶Hñ¢ti~Ú““ó>oÚØ3ß«÷{¿ï{xÞ—Wb/&&&Îäóù÷‰D )ŠrHUÕ˜,ˇE9¬išµ±±ñxuuõãññqçcyyyÑ÷}a[–0 C˜†!ŒNGtt]èš&êÛÛÂ÷}Q©T‹Åb~ÿŸ¼Ÿ¨ªú¢eØ–…ë8¸Žƒçºøž‡‚z£$Iäóùó###3SSS—Ó4ÛBˆ€ÕƒP,. &[OŸvë™LæøÀÀÀ-õÀû–$I݃¦LNÎñɧ7øáû_i6ë4[Édœc©Š¢$Ó4;SÅG\¿>L_.M_.㸔æùg}±±—ÂÚ ´ì²h· Êå\Ïé^†B*W®±¶¶ÎÌÌžç»ÏÏÀÛÏggËœèOqúô+ܽSâaéw<ϧ\^¢Õj2˜!hZˆD"–èºÉä7?óÅ—‘è=B¶ï2õz‹éK,”~ãì¹Aúû3Ôë5;`àû¾ ðÝ·ó ¯²«uºú½½GÉf_¢Ùl0öîuAH}Ü(Š0?¿0“H$ÐÞÞÞ‹Õª{Hk·#ëqààFLO3Œ¼µàû¶´¥áºq÷CâÎíï V—/±i“€RÑ,B³ë´”/Ÿ/áó§_hÍÔ M¯^þÆç%œ9SÂöíÁЍ²HÂP A8S¿›ƒß]Àõk_‘Ë…x2ü^e W®Šƒ œ C1@‡‡/¼{÷!Í9Û·¸hÓÓ§tuU@)À9°gÏ"zzÊ äïxR*áºÁP_ß±Ç |?È+¥ö=jºl›Ûˉ»vyÿy#„årå2¬z¦7nÛæùd2q÷Æ«§zvôJ’D¶PÞZ˜ÿíîüÌõ+vucžçÓ¯>ûåWWo,Û¥Š!lÛÏR7„˜¾“°ŸýðkÀû?ñË“~Zz˜µš)’é¼x{*â›9‘/6D®P¹B]T«–XO7ÄäÔÅë€ „†¦.}ñù¥ó]a¸¿ç¯í"[Y ŸæÁ²[Tkµº‰ê–™¾s5J‰_e |ûãï^ìo÷®%ÖÙÕÊ p{4F»h6 J•†a¢( [f»´ïèêÒíòþÁÉ÷Û"GÞÛH®ãõ(V[´i*ïNŽìðâÕ44Õƒªª†i¶¨èõ=][ÝQü‘—Nõt°Ñ‰§Ê€„®ï‘-êDB°[ÐrdLËÁ´lrEµx!Üt÷Ž—O]xkrâà±W†Qe“åÕMÒ; þXNóûb‚ _c¨ÿz­‰mCl#Çôì}2Å=ò»¹²"M«ÕÂAâÄkc¬ÅŸðËüÛY3ó{Ú½LŒ#Èë|så6B8´T¶³EÇUÊmD[Ž +±$s‹I$IÅ´m\2ÄS»”+{M›«7‰¯'8v¤ŸÞN„YH)©Ä­²þÁG©ô×n.`?²,$ ß>•2Ü[Jòx³À­™(ûCa:üm¸U?Vy}VÔï|6ë¾~÷ϸµ ^ͦ*(² ÇÈ.»•¦eÑÓÄvô|,‘Y¾|JP}=gÆNò³)dŸê(.Õ­ +.`4-š–í8&ìdsŽûþÖÎ2@˪&Kùd*Ü3öæ@ß žÞN?a‘p‡—PÀG0àãzÉçwìÂÚµO#}ùß)ØFqEÏFç4µíÐ`ÿp_OW— … xÜ2½ÂãèÜòæÒç­ÆÓoÿéIϹ¥uŸ‰Þ«U23@ùÙðßx ¢{¨äîIEND®B`‚vdr-plugin-live/live/img/close.png0000644000175000017500000000107712650773437016777 0ustar tobiastobias‰PNG  IHDRóÿaIDAT8ËÅ“?¨Ú`ÅOò}1b¢1F "¸ˆââð‡âP(Ԃࣕ‘"tn×"nqÄEÊ›žRpéæ,b :Šã3¸ˆ4ÁüëP”j»¼¡g¼\ç\~—q]‹Š^v»Ý§étúm4M{<ì÷ûïëõúC½^ÿüç.ó{…~¿/êº~“Ë劉D‚¡”‚eY¸®‹Ýn‡Åbq»ÙljFãÇÅš¦Ýd³Ùg²,ò,Ü8ŽI’Éd® Ã0¼<»A¯×+ñ<_”e§Ó ³Ù ”R0 ƒív BB¡b±Ø‹V«õøÒ¯%Ib!‡¨Õj ǨT*X­Và8‘H„•e¹xVçù´$I0MåróùÍf”R”J%D"˜¦‰@ EQRg <+Ë2xž‡¢(( ðz½0 ªªBX–MÓ (Š}–€ã¸•Ïçˈ¢ˆÑh„Éd‚T*]×Ñn·Áqòù<ü~?(¥ß.ÜÚ¶ý\E&#™L¢Z­Â²,t:„B!ƒAø|>çp8L.r0N?&“ÉW¶mC×uBà8N§A¥”ÒŽªªï.r`Æ›»»;CUÕ×DZŽãA˲!¤s<ßÿ•Ä{-—ËG±Xì‰ëºWÎ/—/„Oápøë?Qþ/ßøxå¼…V­¶vIEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-br.png0000644000175000017500000000052012650773437021436 0ustar tobiastobias‰PNG  IHDR;mGúIDAT8Ë­’IN1E_G½`É]úB+(‡à\ âQ¤AM;CŽc³)GEc Q’wÿ?ÿŠâönN¢‚3‡‡{`,gà0@ 8À~Bº*|ƒˆ[ NÊø­rèæ3`°ò¼zYHì Âþ4*þœ%M,Ÿ‚Táô íãØÀ^ÒôzÚT^f»Š€`#F Cœ©ð5tO3ia+€7 –$½ÌCö*€©ô¼Ó§$¨%El'BÜRÊtÀA F€f´™dŠYJ¿ñ&¢1nd<ÐwRk[eFñ“f وЪ;p‰ß¯BŒåŒY@ÜΦLWRfÄ¿š5dòã¿×ý|¨3ºµ`÷IEND®B`‚vdr-plugin-live/live/img/play.png0000644000175000017500000000146412650773437016637 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYs†BŠýtEXtSoftwarewww.inkscape.org›î<±IDAT8m“ÏKTQÇ¿÷¾ûæÍ/'yÚ1q` D(táJÐeF´hÑfHj¥6ÿÁüæ*WA‚®t›Ô¢E®[D¡:%™ÓbÅñÎ{ïÞóÞm“ÃŒö…»:çû9_Îå0c Zµ»»7 TP$ óD”eŒÁ²¬ŠV9sæoÝêßiíg瀽½2‚ ¤µ~jYüf*•B:çõzõzQd~Û¶ýÊqœR>j¶·wxøï”Rã¿“voª½‰^0°¶tQáððP apœøÝÁÁˆ€”²$åÙøµkWíšWÃfcë¿Öñãä|ßo>¥º»»m­Õ¸”²ìãÇÍFãìm&Ó‘K&“X;\Cc¼ö® e0ꎢÓîl& ÃÕêÑ~"‘š¾ï¥<ˈpprßøÀuݾ_¿}Eu`¢k™Xñx¾ïåãE¡”Îc ¥„”«_V!ïKÄí8˜Åà zðnz`ï–7–ñàÆ<ìyÎ8,Kç9‘Îâ‚Ï`ët D:ˉ¨ÝÍ.âZää<òPÕUQX‚Ýn6™ÿ}ï+›W0”Âôð4Ò" ¢°"”Òe!b-Z"Ÿ€äû$z‹èKô5ËJé²5Ϙ¹—H89`üà' Þ¸US¹)ŒuµïÉ öƒ@ÏóBáñŽ”þ’֤Χ²U÷µ‹ILbqxñ’YkRRúK…Âã†W"¢Q×ÍŒù¡ù3‚Ù;³pcî¥u(¥U­vº¡”.-ÇôâÅK‹Ù%‘äO²]Wûkÿc jµÓ})½%¥téùóé¨ p®……—¶m…°ò–ų†Q…(,k­ççæ¦ÛÎù/µ Y´2Ò$nIEND®B`‚vdr-plugin-live/live/img/rounded-box-orange-bl.png0000644000175000017500000000107612650773437021763 0ustar tobiastobias‰PNG  IHDRãîZÄžbKGDÿýÝvY2 pHYs  šœtIME× (âYÿËIDATxÚíÛOnÓ@†ñÇÎ@JK-j•ØbÍ¥œp†J\ªk¤ž R+¡¥ulþLFnZälèó“>ùf¼ðæÕ7´Ê¨làx ¼Þ4ó“Ó³O_‘$Iƒ*—Ü«£®Kàg“½Ïo}e’$m&Œë¬*à*ê˜ß‹ôK’¤ÍwÆ] Ï_ÑÎh¦3»cI’6ÆdÝñetÅSà8-F¯ dI’†U, æ<¶h7ríÏCàpØÌO>v“ÜÔ%IÒpaÜr™òNÈûÊÀ>Åd§©Žßû %I>Œ»î¸ÈO#”Ÿ»qþ„öW¨­;ŠgŒny¾$I÷YÇ9‹=ZW©7¨Ž0í¾çoìšÑnìz <Š0~Ufs cI’n†qþñuZ2°Îλ\ù¤ àGtÄÛÀ8ªë¦‹cƒX’¤å\DZªtËÀ~ “…q÷ÿñ˜vizL»,X,Sçµ$Iº™±ÝŠsõ·îµìUÊjaœX|'6ˆ%IZ3WYJ.ïæþ=pyZ’¤Uüù~¼jp–w„3vÄ’$ý{‡¼n[®y-I’cƒW’$I’ôù ¼‡eÐmn žIEND®B`‚vdr-plugin-live/live/img/rounded-box-orange-ml.png0000644000175000017500000000025612650773437021775 0ustar tobiastobias‰PNG  IHDRãíŒÆbKGDÿýÝvY2 pHYs  šœtIME× nwá;IDAT8Ëíñ @@ÐG¡Ð(•W¸½n£J¬ Q #(ÿK^çÕŒ˜0£`A½¯½Çº‰ˆˆˆ_=5x|oIEND®B`‚vdr-plugin-live/live/img/bg_header_r.png0000644000175000017500000000027612650773437020113 0ustar tobiastobias‰PNG  IHDRé`¤ú…IDATÓ1 ƒ@EߊØæ0Þ Þ$EêA€7Ñ& x o‘„]ãØè:[¬8ÝãýÿŽNÞÍp ª{¤ªûÜ<_xÜ Rgÿ>ŸZ7)ÐÆ¹ ¦b&è„kªÓv£‡ÌÆì1D4Ì ˜c&§:@)€ÿü…[¶”Wà°ÜB®Ù'ʽIEND®B`‚vdr-plugin-live/live/img/rounded-box-blue-mr.png0000644000175000017500000000016012650773437021451 0ustar tobiastobias‰PNG  IHDR8»Ea7IDAT×mÁ1 €0À{xÁÖHS e`d,CÒ|1À]IJ?fŽÕsì¨8qáFCÇ‹D~·Í¥#˜IEND®B`‚vdr-plugin-live/live/img/folder_open.png0000644000175000017500000000137212650773437020164 0ustar tobiastobias‰PNG  IHDRóÿaÁIDAT8Ë•“Ík“YÆ7½É›·­I±Ð‰óUQJ]Xu6³Ýè¢] Œý ÜÌJgnf1Tp%¸\(U™Rm¡B¥Ò´ZǦ¶IÓ¦ÍG“æýºï½.ÒAP»ðçÀù8ð<‚}Ô××',Ë:Y,–^ÿãðµºråjo­¶kÞ¼™¯Ž>{pýú‹ýýý‡>Ýûyróܹ³—þŸµ6d³9½ºº6µ´´<41ñòáÜÜì¿_„"éôlÎì#­µÙÞ.›ÁÁK~}Ú†G1ÊâöÙñT*uº³óð!ß”6d‹>KT[”î”mÛ¼¿R‘]¿Ï\¼pæÇ›í [¬W4ׂ¡?·~HöÜ›ª¡©ãiA`"´µZL$¸36ÅåóÇÈçófttä¡´c²ëHGRHß'`ì¯Þ«6q»O¯ÁSP`ǃ²/)•vH§gW¦§§gäZ®”éùÆ„à(‚¦(&€@ƒ‚‚£\§R©’ɼ{ ²”/dòEK\âj¨»V¢7܃U®zà*в™õUîOÿýéÚ„4³°˜ßåè·I ¡lî6?„PCh½@k2ÁØÔ;*¦Çï¿”Tsk¹­]/Õž´Þni^¬Ú[ët´´Ä‰65¬¢öÞ#O_WðäÚ<Û¯$ã—ÃK¿,/nêî[Ï5ò@”œ¡¥jH69$bšÖĬ8¢IRX-‘óÛné %@µæ.<™TÝN¬=oê0‚k¦¨@8 ‡°åçß1»ÐÅòðà€H¿ÝœSö‘^¿f0!„¾Á·R6Ê-;tøu&'çU}yfÞýïî«Y8þÇÁçzÇU¤³Û˜„EUÞ0AuIÕK™j!›qÊë‹Ô26ÆVÐ~PŸ‡ ó‚ í„øšÔ~£•³IEND®B`‚vdr-plugin-live/live/img/logo.png0000644000175000017500000003333012650773437016627 0ustar tobiastobias‰PNG  IHDR¯F5»Sh IDATxÚÕ½wœ•E²?\Õý<ÏÉ“g`ÈIDA¢  ‚QŒ(† ¸¬nP÷þ®®ëªî^]wu]1¬qEq¯s\*APrÎ030䟧S½œ33çÌ`PðÞ·?=çsf¦ŸÕß§ººªº×l•KÖ`ÒC"$BÈIÄxÄáÿF2†jöššzhˆB4 h½ú¡+HsËÊG]â¼tÛÖê†ÆÒÒ’ï›=¬Ûâ=þjJ"·-r”*óaÛz ´OP'üÒ~&s 1$T¼X™ŽÍ*QM‰j+r2Ðk¦\@¤™Fq&wuéÔÚ7¸9€›·‹Ûô®» tÌÐÌ ÒB‹"S"©•Ê[Ò*.àƒ«hË6¾¼DÕÌêAÞš/–ô=ÿÌï _,M¼ðVl_À’Ì¡.½Wû›¡}1ÜgQà J,ÔÌoQ£×¸Ò ôåv±I¯Ù³›žìì¹?¸Îµ-`¸ïg[ë·0d)W>2§ñÊ ÌÉÇ…÷_µö”±˜–’(·,?ÊY³&É1•þµum΂_,ª9ÿÌnßÛb1Qlîq²ü!ã’$+ÀwšTêzÍtÀ¿v’ HDæÊ ™ŒW+;e9Ô&Fì«f“ZWbú–˜FŸ…®H=ý?©H°Çˆa¡ý­Bj‡A¦•cö‰†aC‚ 𼄰ìNÝE$nUÕÕlÚºcP¿Þ‘ï Ë×Äç¼ÜD,á)döCÊ]/²Y-Hò²úÖJ”L¨0ÓT£‘‚Y•fßm`Ç:± mB,¶n1[Ҏ쮡Á±Ú­yèIyïoìk¯AÚSÊÉlÁ¤ûã 0v”ï“Ï x¾WP3,G½øÓÏv÷»ò°£!‘P?¾G™P8Ô²“°ØS`ˆ ³æì@ä£v e¾¤¿Ò>Öt°… ƒJie\q»Š!šÖ]kFÈ4a döŒFP®JvªŒ#XÀ| 24P>̵¡ÑqÊâ-îÈþí­ƒö!7 ñ$ùÈ2Òʱah8}\ä½wlcV°sÛˆÆâÅ_~¹åš+îÅâ™çjÝS t>#"#°AÉZ%k %ɸƨօ׀i•³7Y”~ 2™€yÀÇYˆñbdaM¤÷ûÆЦ@«¸†–XÃBáî6FeX먄H‹âmïrîj”-h †€€€Ä¹cÙŽÓÝçdÙÝ4‘ÉÙ6çðAæ·ÊÖ­]»hqÉ Ç—æ!‘ö$yÞ'“ñ>üwó7˶""‡Ø?íkqlGCi©¯g«¯w}>;‡¤U:ŒÙ¬WCã×Ë—Õ8¦ÛáƒB<.Ù‚,ÄTŠMGæË-mÉäÂ[ d•1´‘¿Ï2Ú"cÐ&Ô"c¤!)Jj­$…({¶öû{üGq^D`2beM\f:‰1ntQ Ý»:òH™LzˆŒ1Î-Æ!" 2Î2DΑ1äœ3Æ‘1ÀV­dö””2BP,áµ4z»ª£Û·7¶4Íw ãszhÓi›®ˆAئijÿ\yÂñ§æUÜ‘'ÉDFŒFÕ×–Õ׃J×;gLîwXe©‹¯R^|ä¡EÚl{§e”ŠcDÃ좯¾Zih<Üi­èæg\5ìÕI±QÊ=”£A€PUëV1籉gõüø³mÄbŒùò±9¼ûîªÃ„†×_Ûª‘I•&K´†hIµ»©y±Ï9%î#t3)Óf$âR ¥ef1>o$¿åÖ_}©ä™§µ2Üy·Ø¦‰a<ùä‡ pêé½vUG_yùÀFιrhZ1*–E“ –SsìÈÞê…‰-Ñdsãñ‰d (GÝØUU•yÐ0xHQ lÇ“Q_½dfW¯¹U±dÉšDâŒP(pˆí1oÅŠ=‘BOŠV_Æ ¡é#‚žÿÑBG³ ÙizBJ¥ífgê´Á–c=<{¾6[ýþ*h³äè©·«öîýæÕWVM½ð¨Ã ˆ+¯öÑ¿··´4ø}vÚtÖ±7VºeõªÑ…Á‚àí[9iÒäªxRx2åI!¤ç)ÏK*á©òJ¡v¿óκC>ÔW_Ûh&î)/'kOíLº{,»Ÿ¤˜+]O ¡DúS(!¥PJ*­ºØ1¦‹%Ï;¿ÿùëDªÎ“ž'…'…§„§ëä±ý,\à¼];Ùn“DD›qóÁG_Ÿ֨ʆ¯—ïT¸Y¦,ÌÖÜ{^ÌöõØ—ÕNjW€¬d|]sc]—Ð0ãâ‘ÏþÏç¶g–C@,c•I¯Ôv„aò¹—çÿáö+™ê…ÜBÇ2£võF¬i…å+<笱ó—ÍÆb”@€`”–Òäá ¯½öÚñÇŸÞD¤5ÖZk­5Y¶­µNeÆ +V¬>|x$²O íÓF}ðérËŸä9[ÍŒ3£âNxþ‚¥?:¬h˜÷Î2îcÒ¸Œº™Þx©–¢`–N?‡Z‚\iB4B&¤]BCŸÞ¥U}#õu{}<HD˜vJ&D ²í`ÑËo}ôÝѰ»®å›[KK‹©v+QsZD7O8ýÌ’²*a\’@y‰`K#4å‘¢ÑèÊ•+B¡°žÏç×uO7¾ªªê½÷Þ]¹bEÛžsÓ¦MÍÍÍûAÃØãûK&RÊX–Mm @ˆHD |‘»Ö×ïm*/+>LPB½üÞâ`("ÈË#$!‰dª¡wïŠ}m®…q%ø4 VZÒ–ÒéêKOhñâ‚R’‚’RR‚Râ*jlØöÉ‚ïºR>6÷#+ÊÄ$%%¥$¤ÒŸŠy‰Øú¸'§M™‚RR­HHŠt—()0)§ŒÈ[ÿ” .|ë÷¦^4móæÍ›7o>çœsïøí]3f\óðÃf«©©innÞWO8®OJŤ$¥‰îj2MòûH7µ|Ãác ×üêQmÍbiRˆ4)(CI©TbgRÈãFÙÇB“‚‚R’ò Ð0cê)®ñR2*Èäæd“ÒŽÍmzêÅw¾ãŸš÷oæ(A©Ü&RD´~}¯>U'7ÎÊõúDd‘’TÍÖ¹o}xù9§»Aþmîv€K•ì¸ r.ê6+f_rþ$d¼u“íqcåâØR&­oȧ\ã¸jÙgÑ}›îòhxÿ'lÇbé‰n•å;vVg««•R­òQþ4¸oϤt M:ùH ã[wì8„ Hzîßæ¼qß?_MI*ÏØm;áA°Üš ž6?¸|ªíøò£H¡Œ C€¨´4]N÷‹†SŽZ,qÏñù(}^-Ëû™å³}?7ïÛ¡Á“òí/./-5Fç:³#Z,^³ủ'˜ÑîeŒ4¦]ŽÇôÑ FZj¥ò[^~~ŸÞküxðõÚµø±–êmqØøÎìÌɦÔþÝd (¢¤Ô:ݾεa!CdNýîüZaCd´ÑÆ"­µRÚ)c¤T“BʤçÅ’n<‘ÚÛÝU·wÃÖêËÖnØQðÁ`È"HyY#ÔYt@4*ݾîÌI“G㆙×úüþý´Ø­¬ kÙ¹b;@7`ÿ^= ðók.¸læÝ>îcŒwâʬX»hIum}Ïîå]GÃ_yÕç ‚€@:G6M5o€k®¼È²³ÜÚ@“ñ‹Ï: MÔÉÛþ•—þøì‚[/lö÷}B§ À_ߨ¬q¢Õ?QWO¼2·?‘.¼gÏžµkׯb±¢¢ýfäž6È1½p#èŒcCÔ`Ñ\3"¶Ÿµ¦#Sýœ¶Ã¬u!K%ˆÄMËÎ*V{î…—þåOw”–€þœóÆó–­ÜØÔܘˆÇ»U”LwâA£áÒ ÆÍ˜å'¡˜cåš ýŠnxä©×~wÛA(eç¼øQ$RÈÈ´¿H£[‰†­†Ž8ñ¸cs¨BÈ cÀ -²€iwÄìà­éž{þFã;ñ¢æÅCß=È’²z*UÞc7ÐÏ—¬qô°å+Wg4O=uÎ9çŒÚ/³µ™-aÈ:Ï-"gÄ€F;½üYÃl7E·­&˜óÇ\ëC®é:ùÃKìn®^ZÏœuÿ¹©²²GWÈ^\>íäc÷S KNÆ×\r¦—RÌpf3ŒlÍÀ‰ûÃeO>õjסð¯—?Ee9h1ƒÙrb&¯ùòK¦t†Z‹µ5ó+b.kxì±ÇÒÚ¤Ž‘LDaÈ,ÑgWªªÉù—Šø/Ù’Ly3®hW@UWW?õÔSuuûuQ€9ÃÏþŽhÒhàz‹ù~Å|ƒê\²õ_Ä9ØúTª¹aë'Í;æ—–õxâɇîýÓoº…®¤.¡á×Oõâš„d†1“QA8Ô³fÓ†•«»êüóÀC¯øÃ(U¦’¶:hÞP0ý²ó:,©iä寭†1BÌ:A_[[;sæLØ¿¿ÏvbÑÆdlO2¾ËMìLFk’±Æd2žL&¢-± /œÒn²®®nîܹÉdrŸ]dËiÚ´A­‘Zû©1ghÙ…uÎS9ô4þhqc[ä³ÀϤN6mÞ³éÝÆíYÈö‹›~þÚ5W_‰B G—NF =¢×þ}ëöìqθS†ýãóþvÿM¬ª®¾eÉâMå嘫KF†@,Ù¼í´ göëÛ·#f -ùf¥k Mî¼óÎH$‹Å.¿|ZCS”(|o ×+*.:{ò™o¿›Ñ¨®]»6Ì0$B“©í¶Ûn«««K/_tq<•RB™Œ§5 2D@$Äh|h$RˆØÕCD÷Þóò÷bqq9)é=öÈ;ñØké]|ñV®¬qüA H$›—.ÞøÉ'÷t 3¯?ç×ÿñéãíÇvMkšâHÕö]Ëæ¶ü”q#ö_ϳO¼_ 2¦XÛ9VäÌ®m*.ê=yò©y„yŽ>ÆÌóÂ2Æ-D›1xûí·c±Ø‡~'N°}þ¦ææ@ PTT †,ËÒF Ï‹F£ÍMM`4 =rØ€þý7oÙ2yòÙï¾ûö+¯¼röÙgÿþ÷¿¿ÿþû;ûKOú8"åaQÈxܸÚS-Û£‰mÑV¼ä Ÿ€Va¸OIÑ€]@`ˆ;R•JÓÅÃ\¯%ÖXxö¤³OsäÁrþ’¢PaÐ* INÄöìizå¥O/œ6>Ú’\õÍ–ÊŠ Èdª& ”ê*8ÃóÎ;ñãs_;ÀÛ\£þ¿ÃŸzòõý£áËÏWÇ£nYyÈ…}PZÇ€d¼Dªæ’K\Q‘g§Ä9c6ÃίPÚõÕq,3wîÜ¥_ݧwßÕkVÍœy½'õàACÂdÒšg€p¸ ´¼B+½cçöúúzMÜ|Ë-³fÍZ°à‹ÆŒY´`AKKˆ Þ|óÍéÓ§í:V­ÉáÌf–!Õ¶R´EwaŒ)•êݧûìGïEc©TJ%Òjg¡•VÆ£É!"@Ü]Ûðüœ÷«k—‡‚Á²â!¶n ’åp¦óÙÊd²åÜI·ýù¯?¹ú“Î~í¿ùϧ@+Û¶ý–ûÇ£/]8mü³Ï| …-n¸çµ´Ä7M<ý˜9ëÜwßý*`ç¾áí`AA÷—_zïɧ³Ÿ}äp¤Ðä”3£VSt#€=㪩œç‰-`2ÊpÈ6dšÝ2dÌçüñˆÅbeeeó?ûlàÀA#ŽÙ£²B¥\—Ú‚~´-è «zö¶lõ®ê±'ŸÒ§wßí;¶•—U0Æ>úè£óÎ;ïoûÛèÑ£9¦]í¿kg³B`¹ú Ì¡/W$**:õÔÑ]Uº¿ °ðœsÎVJ á)%•’J)¥U‡$¥B”–%&L˜ …ˆ¨ªªlذ¡ªÜ¦¡ã“IDATªjîܹ›6mjëÁÂE0­ÿI7Õ N¤ˆRƒõýûºgŸ»uÖ×¥\ˆ'kqÈ‚eŠƒâHaä®;Ÿ˜óì¿»^ùySNà< µ @nùáâ9sÞ†Š5gV"YM .½â|¿?ˆ]—N3‹ÅÌÉž`R»­f¥?#‘ï½÷™ù] ì} @¦Gk!2ƒ™Ýزž±’K.={_祱­¡Ì’ÑúÝ0nŒ©êQ°fÍÚ~ýúÀŒ«®"£„çi¥Ú³Î“•c ºôÒËÀíø}uu{`Ó¦MË–-kS?|úÉjÇ0mÝ€Ì2ËÖÑûþÿtõå—OI&UÊmÆ1 ¦C°`¨,ñÿüÆ>ÿbm×+¿`ÚXá©t<Ðp¤§TMŒÛDÌij^_XPuÖYãBûÔ–JË#ÇŸp„” vz]MaA_©šžþÃÎîÚU¿n}µíØÙCÆ45oš8q\¿~û~±0]YN» 2ƤŒìmh(//€)çŸë¹I­¤ÑªS–¹Y éÚ–e”¼`ʹ <Ù»ªw"‘ŒF£žç-]ºtïÞÌ¡ƒ5kw0î°œþ³tgçI· 0räßZóóÐÃ×=yL<×:‰ÛØnVsH‘‚î¾]vÉÝ{÷Æ»ºXüð O1CC¡ž× Èg"ßuι§wëÖíÛ ~÷ùÃÈ 2žýçNcãšÒ²Þ“'Ÿ²?ý9æ<•áŒ!cŒqÏÛ'’ÉäÑGQQQÎÈpá&‰t>@´g%<£”ÃYÀïp/>÷ä…çN<éøQƘݻ÷cššš`îÜÏœ@ ç¢Cÿ‘1dcñÝcÆŒ ¾S€UDxùåÛ‹‰=Œó|m1dÈ-^R\õ傯¼òekž>ãT! "!ƒâ¢~È r§±a]ß¾CÇŒupvŠé¢i' ¡ÒÞ:¹ ú ÆžóAvù… ×Gcʲ;ò>Æ,­SñxÍçO*/¯Ø?™yû³,Gœ$’õ Í WÄâñëfL×JÚœ“¤$½ï¬”LÚÚ¶ ú.¼âÚç^|㜠.kjnzâ‘û+ÊKÀ#„›J¹²Ú¶ƒ ¡ÓcV*µ€&žqRÞc-• ª¼ûw3ÆêÑ£ûرc#…¥?¸þ7ÿüð‚€óàƒï ¯°lèP¦óvk7lÆ}M͹Uræéc‰éèG?<}ìØãIO…èPÑZ©Í òâ’! ;}û³]©³{÷Â#‡õWʳ0lhڹ첳ùwBÃÁ=úöë)”HÏM»ú ‹ú®Z½zû¶vÓð›ï|c;!`ÐZž" h5ì]{ÔQÇŒ:öèñÐŒf¢5[i@xÆîID<îÙ;O\ô§á¿;!yÞEWyR†C~Ƕ-Æ‘˜ŽÉB²-æpf;~߯wí|tæ-Ë—¯X¹reuM-l^±¸2‘â2EöÿœÏìrn¹2ÇLO3È7L˜preå!‹–÷ܳ7úCñD1ˆmDk¥¶EÜõxè‘—jk›»$K^;¡¡ImÞòéÊåO­Xöp]í²ãO4í¯»·lžxõ]M±äO.>å7×O†Ío€Hê³þX°çìžåÍùîHBÎ[6<^PPþõ’»w¯‚Cš¦_ýø¿?þ¼¨¸b0ënÌ™LÕÕÕncÞŸ'œ:ô{òvÉãa±3Ï!„ÎYÀÒŸ0 EJmݶq݆]ðéç›,Ÿ8f·•Aîg ë'N<%­2:°Í 3MHðõ*‹~ôñK?Z4fb|9¤¢àFÁkcAAO^wü龿ß~÷FÂ>›[óg‹³èn;\ ©XeEhõ‡ÿ]³ðþßüô,Ь00…z|?¥õRƒ9ýÏŒÂò§RÛ“ñ†Wß­¢uzò±ëü¡ž‰Änä¬ÂØNjb<® ùÏn~üûó}Ê¿X\wJR„Œq l‡ÀJgCÌêgY©þõå;¬VbYÆPº€M˜þôÅ[Öƒ¶¯¸ül¿?tÀ¶ X€M`¹ÊùÝ©+{öÀCÐm¸1p›AÆAÄÀm†È 3O(P€{ïdáâ¥Á€csÌ›‹1¯…ùýà%!Þ °wÄö‚lªG%/8>5xÒØmc$° lDÿî]GŠú^{ÍŒúˆª>ûË=—%E‰ðê|éá¦;À l"FÄŠ*Flݺöï~ü=ù>åMãÆöV(³‡Û~9ËŸq(q {¿4oþ†íŠ|U¶o»ýºdÌ 4îýº¸[ÿIgvI'´ ³ ³Ð§YP6l0`t&à;p J{ªfÛG¿¸õÕÙ÷Më\Ã.øÕ œ@æ†A%`¤[þúð’%ÿþñw])àúkFŽ¢¸A¿AŸa>ƒ>ƒ>–„MIÇç×ü™1Ÿa¸e+¯8ƒó.Å&° :|†9ÎÖú"{P oƒÄçÀ›€7¶€ŽŠ‚‡pï{®êß´pÎÿûí€Ö ‘wÈŒY¶Í|kïr((Š$ãÀ vÕƒÀ‘à(@CgŒØ•ˆÕi° ó ®Ûù¢tíßÜúÃ~ýúÃáLû÷¿>»Å­4º6M^ƒNÖ§Ï0›X¸ lГs>ز½©s õ²°$XQ&ÊKEy©Ìä2Ù­T—†wÖÖ5¹ÊË‚£Gõwææ7èÓ,3åV°2æùl'¥Û €>Ãüd›ë qìè‘]uí2è˜tÍè—êÛ­Â){–`ïñ9ðjpÁn«Ø^€„ý|Éòv0‡˜%5MB“Ô@ha У<‚jDcÀ- 6@@g àP( é__õÄMH ^l^ÜT³æ¬)ç\~éä6%ÿáK?¼òèaÇ%’.qÔ,`0ývù[iâh´üÅ#mýÑ/óe`6 Œ!·;†Ù I¶@+žØÓX·À=+\ͱ?þUuy0)©8›!XNøˆ¤ô° ÚY»[»›¼¸wñÔ‰…E%]Fƒ­ÑÑè#›[§¿æ (z@8E $€aÑŒ¿p猕%“~÷«;奠4 ç¦%úøãs~~Û=Ç•x3¶æ ð6€å `k(.–WÜ2Û<ú…)ìÑ<@wFC¾Èø6¹+Ê~ÿ8ÞóqR²âpaþ’ÑÆª4î†êU÷Ї>1û¦#<¾¯Ô»GèæYcþ<;QfoSÖºÓ­}ÈÂÂÍ3o}{Û—×w|—  ÐB´‰ÙÃ=ùôÉÓÑò¡tüˆŒû o€KÎüúÛuvÈRäÇŒŒÓê÷ËAb°½ËÈ9ÇæÝßœ2ñÒ~ýz„²‹9’ ¦qÞ¼qS*>„r|’ÇÁµÀµ@2Ð $‚áàp@±I0Ûvìܶ£c”Ð^åØ  :à ÔvÀð5(ûíÙeÓoiÖ‘`ÉðHá0BÁ^*¶hϪ{xhÈ“Ý4ñ´“Ùa»§#oºëçÃÞü´aÛúO|EFAÛœ<ÛqÁý•¶oúøþ§×þâš¡Ùh, ÐàT2åå…þ† 1@‡ÄûW\4ê¹û*~qõÀ§^­îjrÙÀöóª”s‹ à~ÝøÈÂ—Ž ºÞ„†€†da²ý4uÞôcÞ.]¸q@©7°—=\ô‘„{HX , €ƒj¾2¬’ˆÏïsü¶Å˜e<¥…TÍI±s/£A®­Á2`5íïeSg·8Eý KŽáÁÁàï©íRSûÏæÍ/ù+Fþóﳦœ;ÁêÂá–CžÞx䤞§¥º‹oTà HGÑk5d$Q xí-ú솫†¶EûÔÌQ’̇Ș¿8ÒÓÂô½ÞhR›—zÉÊC ohKëú©¦<(°ã=;YÇR‘¡Eñº·ü={æÈƒ´üZš[€¸vYxSrìêÝårónú¼žŠu¥nßí×4ZG7@÷$B4h÷¸úÁÆâÒž¡PÐVÈ-f€²°~d)»a}ÒYÆ70Ðzõá’iÿˆú˄ʎgáh—’Ü]ý¯iï€cÏ|â¯?{Òñ–õ¿èQaÝqãÿõ÷ÝþUž=r7¥ïqÓáʱõ_u÷’ÇîÝþ:2mY˜%?oÞö6 Z8ßÒÒx4€J#áÐðº_]Yvç_d1Û  D¯gí2Óñúú Óð³òŠƒ3÷¬–kð[Í™XK¢å7áA¨z$•nôŽE w~Z;±gñÈî*0[÷Š—W6·§¨¨'ó#ðÌõ瀈€>?kxÚǹ‚ÄuK}w?/殈KúváDª€â-ÛŸk®^ Nï뮿öö[.ïׯ? ‡ÿ½t×õ}^|«´¹æ‹P±Àj½ ¡52r»¼¢ä‰g_»cÖЪn!px,d79÷%ÅÆ³ÇuûùÏfI¥@H6rø 64üäÒ·ÿ™[b³{šŽWH§{É|ñÚw]}é8~ï–q£ñö:93À-2A2>Ÿ?Ž”(Q¹ Ùðñª-¢¥îVì/°ý…ÈÒ÷|¶qKŸñg!‡oô û‹ß/k¤‹{ʉ””÷í*¤esó¦§[êÖ–Ž0å¶›¯?öøP¸þ¤þ|Ò¸K7âKXxenrÏÒý•÷M5¿÷ÓÛ^›÷Ät°(åƒf›Év)ùÙ’=Ûï]mx‰i£ö¶oÞ¸êP¢Á¶Ø9§T,Z¸ÕïD³oÍ1÷ÚY½`ðÑÃyТ¸ b6ñöM¬i3#qFd9¶Sîi´HsÑtì2LŸpjâ†iÇ-Bî )è¦õ@Ңĸ*Q—LlÙµãå*”ŸqöÅ?ýáÔq'..)‡ÿ3iø’k§ùÂK;Š}ÛÁ.Ê E€ÈË*ªÞÿ¯–;nD/ž1 /êq’SYÚ"¬td8t·ìÜ»›È¤]ª™T|ýôc?ùlAHîfN "@®o>zÉngÒ)Ó¦œ6p`ß`0ÿ÷Ò_o?óý%[¶”úZi’ZŒSR•hÜxóÏ|6ïv†®qmdÜAä-mĉ5 ë›JKK%Ɵп[©o÷®uɦM"Õ”sÎ-}}³,PzñÔ‰ßBj3/Þ´¥)º%«1Zíó.ÛöE4½ËÍ|ÉL7ÆPú4¤"0À´€9N°ðˆ#F7úèqcG‡ßÚ÷iŸæ%¢ô¡¶ÎÕ""çÜqœo}U¡RJñí:ÜÖ(vJm7Áÿ“1F‘oØy.8ç>Ÿ/™Dk¦^N>DιmÛé2ÿ7Zôq·IEND®B`‚vdr-plugin-live/live/img/arrow.png0000644000175000017500000000064312650773437017022 0ustar tobiastobias‰PNG  IHDRóÿasBIT|dˆ pHYsyy8µˆtEXtSoftwarewww.inkscape.org›î< IDAT8cüÿÿ?%€‰"Ý47€‘‘QIZZz####3¹.ಱ±uPWWßÊÈÈÈNŽÿ¤¥¥ÿWTT¸ijjîdddäÆp%,dddbååå3YXXþü‡þÿñãKHH°‘¦¦&çǺº:O\¾|Ùëÿÿÿï1 PPPhijj®Äéœoß¾2tvvž=þ¼×ÿÿÿ_¡x‘‘ñ/ï0ppp2 ò ‰`¸@^^>TRR*™™nÐß¿¿Y|}} ôôô¹ýúÅÐÛÛsåÊ•+!Ÿ>}º 7õÿÿÿ81ƒBffÖ›eË–ÿ700<ÃÀÀ ¡†aaáï´´´300ðcUCÀ1qqñ ¸ÔÀÀ\0ð™ €ñÊ ìòn¢vâÖî üq™2ÿ´ë_¿¡P,!ü³I%à›‚A±ßý=¦­ÐPG~+ýÄ'Ž.Fù’.i•(¯øºGE$Ll0Ö’:¦:÷Êï—ÉåJŠF¬c±‚OF-•fíÔûeZ¬¬ÎŸaÌ*f‘y áÁ_JïÖù Ñ&ô#;™pIEND®B`‚vdr-plugin-live/live/img/rounded-box-green-br.png0000644000175000017500000000054412650773437021615 0ustar tobiastobias‰PNG  IHDR;mGúbKGDÿÿÿ ½§“IDATxÚ­’MNÃ0…¿TYpŸ¬8·jÕ;pNPu„*U- Z0qÚ¤q1›q5»Hˆ‘¼{ïó›Ÿ,»¹^)o]Áír<+`¼h€€aB¼ Ê7@ |(ã·JA`±™P' “7¨—„~m jj Tñð)iB 1HáŸpw?öÀp4­žƒ6åç~mà Ø ¤ˆKB¼uæËí\ZØ à0’¤•yèÁžA0•ž+1½K#)B;Ò!¹ÜÁ 8ŠÁ ÐŽ6M +é7ÜD0†ŒúãNràQÄ2¹Qü¨YCv"ìÔô‘ß/B¬¥ŒI@ØÎ•ÆL’'Ä¿š5dòã¿×¶§…qÿ%IEND®B`‚vdr-plugin-live/live/img/file.png0000644000175000017500000000120412650773437016601 0ustar tobiastobias‰PNG  IHDRóÿaKIDAT8Ë¥“»kQ‡¿sçÞ™dÕD#ñŠA«ˆ(‚ø@„X©`%Z‰J´¶ðÑú'è_¡¢NÄ„¤‰øL²Ùd5»›qfvî½V‘èOõ;Îwœÿiò‡·çتg±E ë_ ­Ù„¬ó–ŸÇþ 9qŸã·î )t3è¦61oyëüc÷mêÚ߀`Uè‘£k‡.쨆šÈˆJÐGF÷ËØ¹‹&§§·øÖüóuýûNÞÜ6zjhCEÑW1ÄMh ¶+Œæ\¿t^^Ï郹5Úõñß…WEF2ÜŸ ƒ-r²ÌÐŽC¢Ðð}å O?x£WŸfo“+,ÎÜýô'lˆÑØÒç†j áç^?ãÕW‡]®CÚTôÕ.³ÈÝ¿:ÔÖ F)¬Õ¤Y@E+”ÙIqæ*K]CcÓnp%,Ì|ë¡…²µ*„P:E &¼ È÷À5;´;diD¹Þh£†O$‚Ïr¡A…S´ a¹’LÈJÀ+߈L C1Ĭ£ °Š•2¢/ª¹$ž¥L@ëÞLdd06FYÁyÏJM-T¢¨¢ÐA"ÁûuFk]Ÿ¡*t heBh@ P’âµè*µbøÁÌİýøK©ù‹nN``eta`aû Öý÷7óßÓÕt¤þó 3|øÂÈðúõ=^€{áÕ‹¯÷¹™˜B-dÒR  LdÌ>ÿ¯dàêðõOŽ‘ª€ƒ‰‘,Ã/f†¿_‚ôØ€wo¥5g¸õü++Рh~1Þ\†ŸŒþüSá(U7R`¸ôœ‰áÕ›? ï_¾g`øÿ¿¤ € (ijáî½ÏÓj§^aàøùŸARŠÁÜI‡á?ãtf†ÿs´ ¤…ïçfxú–áÓ»O ÿÿý[ÆÀļ¤ € °030r6®ÞýìÊú½O¤!ª¨.à ./jÆ'"`ÿ_P‚áÁk†Ï¿1üùþã3K=Ð `­1àß_ _ÿ¿úÏÎRݽðîŸW/¾1È 12(ê)3Hk(2<}ÏÈðîÆŸŸaÊÌÜÔq5 1€ˆÖ²±mzûñïô©«1Hñýcàábcøò—áí§ÿ ß?~©\ÌÀÈ´ˆ€^k ˆü2 |âÀæe`àe/?qñ㥃§Þ1èË30¼þŒ„OßQùû.PSzB ˆÿ^øÿ² hûÎÀÆ’½z÷Û~ýdЖúËð÷Ó× LL ÍÐ  ¨ÿ”úX˜Ž|ûñææƒ¾}úR1hòvlI €A™‰1ú.º0È%œÀD¾‘•ó?£=Pè#ºæÿs„ˆ‘ÒÜ@çF€^íå⃉Â{IEND®B`‚vdr-plugin-live/live/img/bg_line_top.png0000644000175000017500000000013212650773437020142 0ustar tobiastobias‰PNG  IHDRô1!IDAT×cxùþÿ&f&&f&V(‹áß¿ÿÿu›õf£u#IEND®B`‚vdr-plugin-live/live/img/rounded-box-green-mr.png0000644000175000017500000000016012650773437021622 0ustar tobiastobias‰PNG  IHDR8»Ea7IDATxÚmÁ± € °r“çpš Ç0x ŽŽ.˜ІŽËÆüg”Ë‰Š†^|è ¼eAÔTIEND®B`‚vdr-plugin-live/live/img/tv.jpg0000644000175000017500000035235012650773437016322 0ustar tobiastobiasÿØÿàJFIFHHÿá%8ExifII*2:(BHH˜( $HHÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ‹Ä"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ꎶc×µÔ¿ží ‚éöº‘.z`b­¾­c•æ&ª¾oú¼ÜÏó}+¿ÿ‘‡_sxÜÿÛšx†— o*ϘŠX¿=@=y$}?$Eý¿£*ͨî TµMÔ ŸÊÿ ‰ä,çûGÊrB¹¸Ÿ zqÇ<×&.â·¶¸˜Må" Ø|¶/wðÎ <}1QEw«ZN‰·WÏ›-¸eYÁùÏðž03×¥0;!¯èE íÔ6’LótõéN“]С‘cš+ôfæœqøq\³Â.&ɲÌî2…(Î@Æ6äýyõ©£³Ó­’ßÊ8šR_Ëó0äÿ½€{g¨ã"€:oíÛµÇÙoÌ*v—ó'À>*95ÿDq$jvïæIºgéX–Šòw?f™¹-òûß<ª‘K¹AQ ù“c)$ ‡Â‘íÛ$­u ¯ø}üݶ·måcÌ;§Âg¦N8¦Çâ/Ë€–·MžŸ4üþ•Æ›ÛóºâÁñf'{- `ÈI\…?tä~=êëË%؆[°ÎÂ"`Œ|tçëøb€:Gñ‡’3Y]ùLv‡ýþ Î==i§Ä>< ƒØ`Îs×ÛØÖv|K<á`•pƒyõèǾ:æŸ{m;Im:\$vð&<™d‚IêÇž0>¨Px³ÂÛ”Y†ïºOžéÐãÅIŠ|1q2C­ÃÈä„U3üÄzqÍr±I$VaKE-³®]£mêÌXà¹ÈÈ?Ÿnî[óoj¢+#(Gßó)m¤’ Æ3ÇgŒzs@‹ëºAKÙ]®ì`f|œŒôÇ¥*kº Š^;;Ç@ ,;޼\dßÙñIºßP•ž$sº`ÛØü¿*îÆàN0OÖ®ÎÑÜùŒ‘],†%C$ÑáNåA ƒùñךéGˆ|;>Ïv2q÷ç³éÅ;ûÃØÏ“yŽyOŽ:óŠÂŠ)|Э'•t³¢ÌG˜ƒ’¸\œä䞯¨«2ê¤R*Úu‘átœ§vIÏO@8ï@ž(ðÔD‡‹ƒ‚|Ùð>¼qÔSÅ~þòï€H¸˜ŽzsøÎ¹håž9äš av.y2d\Cp}9Æ)–÷1Ç« §˜TÀ8aÔpG~O`qŸJíäÕôˆP¼‘j( K\L1LMoH•ŠÄº›8 [‰Ë ôÈê?ãK˜ã–K—ŠæVGhåWXâ9àØ GÉÁô«QOöÐ —sbÀŽÿx}1N»v¸²i`™ÒõAÚè<¤+ž»ûØÈÎ=…NþL"•.fã˜á—ÌfÈàü„eG¾O_ÀÙy<ÍAGI0żâåO)Á9>™÷ÅI˜B½¼âتÆg߸½ƒØœ{c#Ž(…¤ãÌŠLIî!}Ò|Ý dàŸ¥#OökGm«`IJŽ„ß1$uëúhµÕ½”ÊÒ¥ÔñÇ;FË!víã ’qÏÖ¬ZNÍ-i—-æFîÇæ†9À§8Ï>§ˆ¦ ר¡Ö;x“vZÂL“‘Œd™8Ï=rgKv‰aXí¤y|¸äxHUÛÈ Î{ gœö  _lI^9ìãxýéß¹1·øvçÛ©Èö¤¹¹žk”;]ûw "È O§~£óë]h¶Ò¹Äf%ò°Ù9 HÃ.W8öèh·WJy$Ï)m­²|–Çe‡Œdqך.f:›¥Ô¿î×[ÎJ… Ø‚1×­Vµd/dÁ&‹3ÈNïŽTôzUøÔ–QðY!’bÙ|œ‘°î=qÈÀ8<`T+sî|¬Ëón\J1àÆ=‡z‚Ïæk“ÿMòSôåÊÜúl¢Ëæáâ}wfíßj8Û×;»P‹lös´BxÈʺÀôÎÞp2§×<ô¥ÖÎaÏCü©mîŒÑAm4†f'lÙè ®ßéLExf¸”m»h§f$+=2>ö0}_Ë4ï"íncy›È ÄþhÃ/ºr^¤õ摆ËÓpbò§!"f@«œå˜ÀÇëÈ¥³›ÉB# ë€ÿÇØ|­Ü’A'ž˜Ï;Ãq2¼©s*ˆ†òd™õÇ$ýFGT’M5í+'ÚþöÈpã¯'9ÀàœT-çËpe•æYP*à py©Èãœg#¦;T‚O´ßÄñÚÁ *„ƒ¸‚Cr£¾;}}è+H-â”[ìš9¢@‘Jº1žF¸ªë4é#¯˜j¹*Ë/99ÈëËt?…YKÈ!k‹€ìáÔ2ÆŒ@ŠðsŽ1‚1’8êqQ_#\HòÈÙå¤RªgÆx\ç=°ß¥Á1Mî³FBÈ !$vÁ檤ïö¹dó#2©pŒ½?)Ïq õ5<¯-ËÆŽÓƒo•w.9ää“éÏõ〠­.n o Ý %ˆÚöÌ¿ 9¹úU->Åk,°ZËçLä:„äŽ è=jyeg·Š·‹ÎFS,ìËÙÎOQÔžÝqŠ–K›h¦”5¡yQ•£sȸI$œŽ:=@)ÚÂc{‡xv|‹µð~q“×ôÏqœþU=Œ—7&YMØvÀ….%gjòÁŽ0:ž½⢻•â³Xà‹ÈX‹±WØ[nrª[ní¼÷ïÓŒT<óæöÛÅ&ÒavlƒÏ`~H¶¦îWž[™åh× ¡@9ðr9ÇÖ©ÛÚË)ûA…ZL b¤¹$¼ãž{ÔÖzŒræÈ<µ“!š•9Î9#ŸCÓž*+Äg¼ØŠûÜ…s<(™lî*2XÈÏ|c©  pC%ÖmÚÝÒ3‚«d†bwp½qÈëýÑÇ4hŠÜv‚6E&#%²[œðGa¸=é°È#¶ní.%\R ÁÈ{g=JŠßË‚|ÊÒ^d(…ZFPªÎ Fú žy†Ò)ꤶ+Îã!4gn1ž¼ãÐ÷õ©’Y&¹XÜÝ¥´@¨$Éå9la@#Áö翬Í0ò¦û, Hß+HUÎàyeÜ géÛ׊‚ e¾¶òcò̱ǻ(䑵‡%@ óߎ£¦hìÖòÝÞˆ¥º¸FGÜ‘åfVݲA?×Þ³ÚÍæº•cD0¨Œ|êØ|}ÿ˜à89üJ|Z›¼Ò¬Å‹`Y"ÜGÉ$ŒŽ>£ù¿Pta‘—|C¼ #8 §qêHÀÀJ’?1dØ-¼¤¾Ð®ŒëÉÉê8÷4Oh-e…cµ åË廲•s„|qÐ cߑӻ,GÙåU»·tM£d‘…ã®qŒœÂã“ÉàÕWG{»iVöIcó]Šå¶“µ—<ñ“Ðvè3@ic1Ü×cü…ý'ýLÿõØÿ!E!‹âëg,1ryQ’>nÞôûªÑˆ™æŒ`ªHÁveqÉÛôç±üê=`‰@Ý73éÀ<ö⧺€ÀMŽ)&`8àº8?^*•±<Í$†W’["6RA@mëÆqÈ9ªðêV{a†àÞ¬€‚Òɺ2znÏQŒ` ÿ:´áLK=Ó3ÄàFþ÷ñÊ·çœLšCi*[(†HÁ;"cÁ'9À9ò}¸õ¥uºc:ÀQ› îà¹È<ëŒô÷èi˧ݲ£?ÙcGbÁ#U1žû‰Áf=‡©ëÞ€ B‹FÙ,…‹8xƒ­Ó…m¼ŽóŒÕ#YÄÂ+yJ ÅÆ2WÝ€P8ˆço>”‚âÜÏÏ–ZN]$¶ ð†rÙÀ\wÓ='6îðÅk‡ÿW$l2ÄàžOVàñúsV.#ÔD‚+«%½à‰ÐÙÆxCžƒ·^Ʀ¼‰í‰àI"ˆbº7r¸ÚÃâ€*Ë Ì·xûNò€³giÀ9ª{ŒŽØúË,’Œ›…÷íHϘFÁêUGÌ3üªÊÊ?vóM+BC!öˆ×9l¨SÁ8ÇZ‚þö?³›˜!šgiŠÄ`69 €HÇçë@û4‘¼–¨±H\È#R}Cã©ïÛš† yGvÎd÷L7»àrÀ¿ÐcUx§»žY¦‘‘Ÿj²|»Ž# óƒž:Ѽj²¼Úƒ#ª¬‘‚99\zw$òx  §7âìÜÜ¢+ÌI›¼Œ™=s·ïsùT1N¶æ;…··‘YròwV<óÏÊ9'·CÏ¥éÚúX[;xŬ¬$Š<4 žAùxäuõ$v®–)‹XÖØ¾f‚A÷v÷UÚ õüøÅT‘#^úľcÞ»Û¯8ä!‡¹Îx4’,ûì×åŽÚ7lGÇk` B{öü*Ô3¼¾Ó*ˆ˜³À¯³$“žœt¥6öâÚI­#FyŽTb3µ¹Ý´dœã¨ -ˆŠ| þøÿ!EG¦K¶;Œþøÿ!E!ŽÔßËñ¹'÷oä=qÒJ¶·^Ä„»ò<ÐnrÌOF LwÀþt5¤y5ycûíy(_¯˜i¢Ènn®míÂ+1eU,Œ—ÎFypxÏÄK$Í%¢Éx›#¨S3•8ÈÀî9Áæ˜ñFú›IåCå€\NÑe‰$p¬Ç9é·t«:vËÈ$xv4ŒªŠP—`qØ®998 p=K(u‘Œ®–FѺô?Äãw|3Æhh¡ˆþþH¢6ü7–~b¤Œd(ÏnïíM†îÖâ5f¸Ä‡Ëä#=Hܤ{zóÍWf”!¶¸Š2ç ¨Ä²¶0FFBž¼œôëP”».%šiXbt”0dR2,@Ïpz~ ú;¥‘_Ì.I µÎ Gèè§ZtŽÚR¨÷Jv7Èãqáƒ<óתŸd¿ˆEïhïÎàB1À=~^Œ[–2ÅspäÍ ÃǼ™ Îrxl.tç‘Áâ€+Oh‹5¼"8åª-Äeöî0Éé»'­ià sê‘y@bE¼)'ªGp{vÅF»ažH®Úl`Ç£ðªMQ48ç2-°IÆÖêO®z‚Gá@ Ò™B\î\Ÿ<ÿ!EK¤í\dg÷Çù ) ]L®k ½~Üä`ãþZzö¦6žñDò´°;¥X\/Q‚8'ž8Ϋ:œjÚ®­½C)¼|©î<Δû&ò4æfI?xø0Å62NNáíÈ÷ãÚ˜ˆ-ïm.mäcxÏšŽAÈ\äpqé׎԰_¤—$£ÆÒ<Í¡O@O補qMÛ ¿RŤ‚ L’’ Œ>ÙïSE0•£7Q!–İù†ÜÈÁ=6ŒœrzÐ4¾D¸†Å¢ÉÜR0\è$ý ôëNÔ läHüøI`}ªTuèFàŽŸŸ4­:&ä†Ì­¬ª 0–É n åíÓ¡éNy#ÓÒáî"(æ‹xBÜHn¹ÏçÅR.éçš &ë…{}ãך[KËy<Ø2J¨G}Í· e—wÏóïVìöÛËy:¡‰Ù›7®p¨Ç5Zá'yâXwžUÏ™ & 9Ç›9ÆxüM*ßF×H$LbáÑIU'®@ëÀ#שôÍK$ 2É —•$¸Ñ‹zî9ë×øIïœP%Yax·Dd ˜.H×9cOk”‹ÚY®Ü0çr¾=·ÏG¿÷h%µÝäÜùI(ê–#’¨çùV\)5¼Éqv®b+³ ÈÃtúŒdŸJÐ>EŠF#–YEÁ-%±S!ã¨$¶qÐsøö©n,ÒR#yí‹*ƒ÷xŽ:Þþ§4g—·“÷©$JKyBb$|ÝXƒžxçéSC{›ÙV±?É.&ùdÚ0’¹ãŒcŽ}©e{(³¾}­#¬ u#’ÙäHúŠKilôùã[xÕ-ÙJmV}£óƒócŒôéÒ€©s+·•jðÚº©Ye*Êrs€~ñç'ÀÍUûBêN²ÎCB¬ÁHµ!T÷Æ6‚Î8ÍhÚyrÃå¬2bRC£Â[§R:þ¹š£s/ØA< Ô¼JX'©9à{ðzP” :„Ž60ždxeEôMÃÛŽ}^µTÚ̲y+uÙ£ŒDU HÈÎry<FjäJ‰e%ÂA à¹%½zg¢ˆ¤{¸OVУ,Nfwøà—Ç÷»qJ¡o)žõ|»•]ë´…“idÆz† sžO¯&¦xŒ—6«O<‹$Rä«b¼ž½MLbµ³ä—c˜™LB) c<à‚A=ªªý…"vê îªdu‘™Ø |¹`|ãé@%âÊÆGe—²HŒ«ÔäîÀÝרUiîd Ø—W ™ ŽÜœäd¡m óî*ò]Á5ËÜ,o÷A!xñÜr:g< wëQÞFÖ'Î6¤$® g„røÉsõž}è±yâÕÔ³ü¾R4[›iïž~èž1ÐT3[yÀIYœnERB8îIÆséøÔš•zÛÄ]Wâ1žr¹Îè8çµ2k¹%½†/°,QÉ;I¸ÂüÀùÉç;ºõºpÚ“ÿ×Sü…ûPTJüô?ÈQHe½QYoõV]û…Û‘°á³æv=W¸€Û˹Û\‚óL8eÁ¨~ì¼6²•#¥aåòü¾ƒÚ˜Œûp“ù¡‹~Ò±>E|\1ž¸$÷'&¥dkK)¦ŽI·“Õó©P2¯ýE\¹Óõ &Gƒ|d2ÜÄç¨%ðþté¬o¦½[Ÿ³[!TØ \¸os¸.}h1˜òhE¾õÿYJ³g§PúrsÖ›CjB™bIÓyiYJpIà@ÏÐ ²ö7ŒEoò¾U¼Âe‚dóÃ5 ún§pD’yfWÊ–l`}v–Î03žÔð:@’͹+*Í,ÁöëÇËŽ?ýUH´RÈøòeeŽé?B¹lôüÆ8û3T1mx,䱘 <óÂ{žÕ-ÖŸ©J‘™Žå’áŠmôn?0h¨„Zý¥§¹‘Æáå¨VV ò'àä`w§Û4@âÝ}»ež§sÇ^3»¦1Š–}?PmC[[ñµËn=B zñŠ”Ù_dŒÁnÁÆ2óq’ ÕÎ8éô  ±ªZÉûù#3—²4dƒÐg<yé×­1àI ¬[ÊgbÌFcŒç'åùG¾@9Ô÷n©q$¿gu hÏd”$ŒŒñ޵,z„r‰dŽ!P Ìôn:Ð9^÷x1ŽlÀä‚OËØôžÇ¦)`}¶G~[j»’ûˆÆî˜Àúôç}&6:›[ q´h0"RÇ¿ªç#ëùT­i©HÌÏ «¹ùw4¯†QÓp“ÔÔlÑ%¶Ð“Å>í¡dˆºÈ à_‘€{tô«Vÿe·fmÊËÌk*³Àg'u©çÒu)²á`IIÈa)!z`´`qß>´ "ñ.¡¸ŽÚÑXç3aÏ\„üçñÈc"o"òÞ(Øá ‰X9ç'?Ý8’;j•ÚÞ{™fI:6À&•™‰>ƒiÝè^m:v‘Ù`¨ÎÃ1*žp»1Nÿ\Ñ>Ÿ}#`y~H ¬~a\ä2;tÇz¤ª'–DblïlKƒ’w¼;1Ó¥6Í¥K¢!ã)‚ÝI'roS×§¦Œ–ÚÚ¦–(mTH¥AóX1Ô‚¤œgè>• iú‚B‘0‚D\°V]­Œ``tëý(/uŸö„¬‹:ÂÃ)*©+Ovt#8ôø’ÞY•ä`®ÈHe„«‘œ–cœn#õ=xæ´$Ó¯¤Àhm¶ŒáVVPNs–ùI'ñ÷ªÍ¡Þ=¦ÉÝî*v<®?à9ôêOø€4ùs8š‹KW?xêÙeÝþ÷á×'Ú„u[›+v’GŸ{’YÉa‰ Ç$~u|ØÜ<ZÞá\¤ì.r‡9Ïà©RÆU’Ý‚ÅÆÄºÇÀa‚àQ@!Ndÿ|ÿ!E[Ž/šO÷ÿŠC=,øcM3K)I JåÛçîNM)ðÆšN|¹?ïºØ¢˜ŒoøF4Ïùç'ýöhÓAÎÉ?ïºÙ¢€1ÿáÓ¿¹'ý÷Gü#Zw÷dÿ¾ëbŠÇ>Óˆû²ßtŸðŒéßÝ—þû­š(þ;û²ßtÂ5§vOûî¶+7P×´½-I»½‰þäþB€"ÿ„kNþìŸ÷Ýaøº?Âþ»Ö£Ü}œå¶g$¸>¾•SPø³¡ÚXRIˆî~Q\~(Åâ/ ^i0Û¼ý¹mÙ<0?Ò€,x[âFŸâOYi@kqs&Ï4^îÛølüë×áÓ¿»'ýõ_#øFøè¾'±ÔÏ?f”I\v¯ ¬¾2ió'´+î¯@¿ü#Zw÷dÿ¾é?áÓ¿»'ýõTôßh:.ÄL{H1ú×CÑÎâ‘]OB§"€2¿áÓ¿»'ý÷Gü#:v~ìŸ÷ÝlQ@ÿðißÝ“þû£þ;û²ßu±EdÂ5§rOûîøF´ïî?ý÷ZôPGü#zqyoÉÉùÍði¿Üûîµè  !á-,BËÉÏߢ·h Š( Š( Š( Š( 'â!ñX$š6÷€)$\>}}Å|ý«jZ—šËr³#÷ }oY׺•¨.ì —=IN1@É<ÎycUÜ3u&¾ñ‚¼91‹IN3ÔÿpwžÒc'eŒcó )Aâ§å^„פ[hZ[°Ýgüë©Ñ|% ÜJºlL>§ühÈ-/î£`±úW¥x*ëÅWWQ¥ŒSªäeß!@÷¯[ÓüáÛ4VƒI·ý [ù“[ÑC(Ò4FXHÁœ( Àc'¹§ÑEQEQEQEQEÿÙÿÛC  !"$"$ÿÛCÿÀ±`"ÿÄ ÿÄ^  !"1AQ#2aBRq$3Tb‘±Ñ4Crt”¡ÒDSV„’²Á%&'7EFd‚“Óá5Ucu¢³ð6eƒ•W¤ÂòÿÄÿÄAÿÚ ?îß>"ÛlyU1ë|ï2ã’[RÂqéè¡¥Ö7çÅI !èìR¸ÚÆR¤E^ÿ§ ÿáþ?·3Ø)w¯éðSwL§`Bx&L%›Wê¨>ÚŠm;ÏâßòzŸõE½¨7—ŬUþ¦¯÷´Ü7¤àcúµèÞ•ÿÈÇõjžwÅ¿ù:¿õ3þö¼;ÃâßìVÿªïÓÞp³þ&?«^å ù«BÿKþ.DשÿõÔ³â÷þÀ?èýtíúiÅýZÉÒø¢qû´!ô«âñ?Šÿ¡ï×£sü^?å!útö7œ?äƒúµŸé”?äƒB¿I~/ËEÿRN Ü_Õé&0ÿ¡'û´ýúg ù&½Nò‡‘ühG?7ßOüqÿBG÷j}»ñƒùs#þ„ß÷k¡ ç Þ&§éœ/ä£B9÷Û?þ’lКÿwSíoŒ9ÿíD©5þîºéœ_h£ôo(ßÉF„sïµ>1ý*Ÿõ&¿Ý׿hübÿïqþ¤Ïûºè?¦q¿’êéù.„sïŸøÆôÀô&ÝÔù¿Œ¿ýöGî„Çûšè_¦qÿ’OÓFüWB9ïÌüe?úucþ„Çûš÷ÆøÊôúÿÔ˜ÿs]ôџ亟¦Œÿ&|øÍÿßî©Gÿs^•|d?úÂèýÐãÿ¹®úhÏòmOÓF“ Ï¿òÉÿ8ßÿScýÍBŸŒó’@ÿ¢1ÿËÓú·¢üXkÓdÿ%×¢|/Œ‡ÿYdÿª±ÿËÔùŒŸó–Wú«?ü½>þœä£úõ÷É“ýz!ãõܲÿÕ™ÿåëß•øÃÿ9¥ÿ«³þæžÿMÆ?Ňõê~›äÃúôR‹ñƒþsLÿWkýÍba|_Ïÿ¼Óø-ÿ»§ïÓqü”^¼VøÿÙ“¢~GâñÿÖyßü&ÿÝןfü\'½Ï?þ¢?ÝÓïéÉþLx7ÉþLÙ¿çE‡ýTÿv¼û'âÁ=î‹?èâ?îÓÙßj Á“¯¾•Ÿñtè¤5RüV=Õkÿ\ xh¾)žÎê¶ÿâ=«|¸GL'X+|»ÿ 8¡ø¥íºíÿø§^ý‡ñW=n«_þ&ÿN]ÏñÖC|9Ÿâ Hûâ¸ôÝ6ŸÖ?»^Š¿‹_ó¢Çú“ýÚxé_ÉÓ¬ŽûVðdè~Íø¶=7<ÿú¨þí{öÅà?ýçÿÃoýÝ=òqþ,zòqþ,‡ò_ÿç<ßþ îë!âøÿÖi¿ü¿ÝÓØßû2u—é¸þL?¯@‡ò¿ç4ÏõvÜÔ1þ1ýe—þ¬Ïûš|ý7ÉGõê~›Œÿ‹ëÑHAŒó–Wú«?ü½{àüdúË'ýUŸþ^Ÿ?MÇòdÿ^½ý7ÉGõè‚>2ÎYêŒòõ–>1ÿÎ7ÿÔØÿsOƒ{¤ÿÅGõëßÓTþ,4B?þ±<|8ÿîj>2ý`sýJ?ûšèz7ïj~š3ü—Aϼ_Œ£ÖýêL¹¯ Œ£ÿO/ýI÷5пMþL5?MþM ç¿5ñ—ÿ¿þ¤ÇûšŸ;ñzÝþ?îk¡~š±ü—SôÎ?òQ ç¿hübÿïqþ¤ÏûºðÙübúT©5þîºÞ‘óþ+©úiù.„sÃmñ„éDÿ©5þî§ÛGþ“Aÿ¡5þîºÞQ¿’yúgù(ÐŽzo>0ÿÚ úîê}½ñ‡ùkêMÿvºéœ/ä£Pï8_É4#Ÿ Áñ€zÊŒèHþíOÒO‹ßòñOý :èyCÇø Ö'yÂÏø¦„ þ“|^ÿ•ˆèIÖ'tü^¯ ýLiüï(ɱVó‡üV„!~–|]ÇüCýOÿ®§éwÅÑê+ÿÔÿúéé{ÎôˆŸêÖ¿ÓXGþ(ŸêЄ¯Ó‹³[þ¨¿SôÇâßügú¡ÿ{N‡yBþFŸêÖ'yÂþF?«BÆòøµÿ#Uþ¦¯÷µçéŸÅÌÿ‹Ôÿª+ýí8éÞþ­yúiÚþ­Qý5ø´ŸXµþˆ¯÷õB7ÅýåxVRZ¢™ÅJ†m¨ëJ•g<Ïöhþõß‹fÖëc!§ÖñHüÃ_>í×\{â];Ï,­ÕضT³êO!¡cü1Çvçù®ÿhÒ6Àé)Ó×øaÿmÏó]þѤ]ÐN®†=ç¸@Ísˆj ¾vgËr™-QÚoî]w’––Ü#ø¬ 'ÔŒô½ÛNok÷Õ}fÐp-°ãn£q¸´8œJTÜUØþ ø…Z«©[Z¹5ìXø·Dü³î­–Ýã R°¥¡*Pwå?Õ«ó+÷ú¡±á½úÂP˜õòT±êJÉ׆ôzŸÏK´ÛªúÇÃÌm¡õ¡."<ÍÄëO,~.G·¨½19Aq¹e½Q¸+¡XÃŒ, dø…X?x…–GœþÐïgAbR±Wñ%†Z¾U"ޏµÈUÛ®JáÞGXärAëžÓÔf³Ü××{reY¹²BTŒ 5%ÎGÙi…Á*>ÁJûgUö–æÝû–žÂâݧLj)iÕÙÊWÎ "8D5‘ŒcÎ:Ô¶7ÞÚnr¯k-÷G[Ïu‹umƒPÐq*N;Jæ3­wïE³ÚQ_«Û.ËÇP†í…\µ%*  ¬¸ŒÅ`‚{ƃ^ßÞ»¦æ#óÛôСÇp3!ù¶’Y 8}Š OßõRGG¾´WÅ›önZÞÓŒðSÅ‘%3%&8_,:â$wìG±ìéÃgØ¢-"¦=M ¬wùºýÕ“ gˆä[m¦‡JÁ÷O¯cB7’LXLÛÄŸ¸Ú• ÉS,*cð–Ø>œ›_‡Ï#!JǶ1 ?ZçÅ Iuù6–¾H.Roá© dð(Œ¢®¾€Ÿ¼·<8ˆ}U›]÷\*ã‹Çœ| ”Sb.R¶p£ôÓfË®ªoMw.¹éÎ*<*ûçÖ¶Û¢”0.A s@ïv­ß3¸÷ÝTª·Qò¬}ŽÄh®È8Ê–„'’ȃëýZuÛÃY$ˆ;:å”òKh¾*p§Ï8ýR¿-\^âø†€ËÒ6mtV]d<\‘dûE¡î•E ë¬á$} Ónï¥ÛÖ°\•me´‡Ë§¹Ÿg0“À2ðqîkåÞ8ιEݲ¢9a%öÛ®Ž˜éFÜj!E^T©‡€R³È+ˆq`u t‹o¾æCDȔԊˆ°¥™>3\Gë—^‚„ùŸËZ _|C°´v ½·¥´Þ9ʉpô†p}-GQPúà{ã×K³Ü®ŸElûË Ñ¤Fùg!6ô#@w<‚ÜŠ¤6ØX'¼,œ“œèUd¶„>~Â|×ã-ÉŒÑ̃(JN¥ “ù… ¯¾ƒ¤Þ9ñö›‘bøn!kS§s’Þy°’Oæ~–aoíÛ&j[5ÛE¨eÒÊ츋Ñм $©¦V U‘Ç:_Ø53÷+ö¶U;‚éR_YLMl¾#·Þx¼ëo(¤Œå)Pôóh»û:—nÈÜWæ4ÙÕá¢R¾Ü†ì¬cÌôvPÉ!=NqÖse™q¾Ù‹-è°öTçc˜ìß<‡œWì¥FAÈìq×îÕj­Ë¼íŸ­cdJAt2VÝûª ¨ä€´ˆü“œ{¤gUþÊÛVqd]ª˜ÎE_%XŇJB°0¸(W}ž<ï÷ÕÈ{yVV»WOAk°Ò}‰y÷’H䜮2–Ú³“æþx΢˜Ÿ«ø®Óű]²Üt'‘Bme©_PùOþé-ë½~Ðzè;J¥M?à)v6ï2…/ L?·áÏ®D‡¼œ…ªLè[ÙœËÊvH[v n#À {§Ñ]h6øÚ;y¨>{Q"Q™zúSãd‘á¥ÆŒG8ú޵¨‚R-w¼zµÙH™ðõ“Œð¹–ò¸þ×â©Xúœt=q S~ï]ѸME~Ö””6·œÝ„•Fa#ЭiŽHå)ÁÎt~ßj|@FèFä­±¸â¸¤ü]ƒÍ¥9Håž m.¥]Œ¨“éÑÕhRªd×[×ÌÙ×M©–Š^:<ׇ(ZÊñ¹(t´þ­@9Ë⻪FÜgoP®lr¥)NH–Ãjm8ÊÒ·c¤)>þù4's|PÝôn%¶é©mÉi+Ís“ ×*1’N;÷ë:5°$*½ùH¾Ûð£½!•|ªä©Šø%¼‚„ä³â?XüíܯÌUdë)—Ù e1¸íù’¥$¬úrðÄc±ßôÐTÛ—_w xÒ궆Þz$„… ÅÀÛcùßwåõô#?‘Ô¶Üúµù­JFÃIˆx«Y!N¯ÓÃm*`)j§ùÕ¯†Ÿ£³›Tè·ÚmT0•ÈŽ©nÅ‚òÔ}r\ O®p’}1¢{Ïi5=ÆÙÝ{ž…¨sÒ^}èÌ4µ28ñÖ¥zœ‘õÐ%Dß_e8[gní’A)ËÖn6T¡Ž‚V€£ëø€)üôEwÒÓŠ^˦h´øeĸü”ƒPRšà¡“)'ò÷ÓµMm ŽÒ‰]ó>d6|W¶•-”œsio:”€‘’¢ºæÛ‰ý¿m¨ÖÕ®Á3êgmôE-)HÁ*. ”äy‚ÑœŒh @ºø—`_L:Ͳó¬y^Khµp!³Í1J3ùòãõ:Ñ2÷â‹sÙ¯S²'It©*fÂÞS${,%>OË?¸wÖ†À¸­\XÒk¯/"Æ.%æëÑòUÒ§4ž2†Ô—PI#ΰ;W¡Ðx[v¶žl›è¶^ ”šÈ°]«jYæ|Í•6¥:1Øä è4Á‹±i…’¡ì$ä€XzÊLgFN !öî$ :U´ÞâX9ˆ›ÆCI+qnüe %#Íœ“‚¤nôÓ"ÓtCb WcŠœ‡ÉãÏÄJÛB€Á ðǧ]÷¦¹ÜsrTNµ‘m6î/Œó«­»‡ BÏ¡Aa·I)èåC?Ö4"Ïø…-1Õ×á’Ñ!>"UœÆÐRâÊÙH#¬dgT!Ý|S}KKµ›b:’ámIþøõr¦Z@V2rr?󴨩q›m»4ʹ–¤Ã[0`À}~˜ó>–CžÃØã¬tàÛ|T‘kòk¶•Y‡$Æu¹îÍ`©xÏ•E® Þ¾Þžúîþß­ÜȨq½˜™¬tn\‡Öòñø†¢¥~°>º1G³ªìžFí­2ï¤ÇQoÃ.äyeiS)•„œŽJ½²}F¿ˆR÷eÝ(` ´™-ºè)âÈy VÒ¬uùèµ¼~3ª³FĬn;Ey[Ò¼/‡D!+RT£ûÿ»YGßûù¶PõÄ=«@Œ-VK˜Øl0O•ë1Ù÷À袢lÑÚ먊¥¶†Ò˲떼é= ÑËó<‡}t} -íQWq@òiv¾×Šä²Ú£9´¥â ’ç„ }2’ÐÉ{?ˆûº*¡±WÃëISDhv¥gB¹¡ ~üñè÷«2÷ŸÅhŽN±Ûû:K©e¶¾dºòì„,ƒÞÓ:ÃpÇM+Bnú€Çõ¸Ý|9løF3„µ)aô>T­@wÖ™>m¤QmDÙWíý·]/Ìb–¥)G¢|~dã2ï ¶Öø¿w¯—‹Wµã,9ᙓ!°ôàUîòH÷ÏZv/Åf¬"Añþ­R2REÌ€Ï" Yãûþ «Ø{Ìî%^ÑÔm–xnü­4¨˜<}x’Ñè‘È÷œj‡ÄëǶŽã‡ac¶vöS.x3dLSÊW[o„³à ~ýíüQeøÍø?y2ˆ}¹ÓK ñõæïËðG~ÅC: m¸¾"ò5Ñbì›9g¬$¡'ò:ÊO¦>žš Q1Íùmú*ãx.Ç —ö_™mIïŸ2ÓŠm@ŠŠõΗ¶mæÑe2rådùðSÕ2íVûϺy}ûIl‚0:I¸:8»»~ørÕdÖÀ©1óro\ZðFz !dœûþŸ]n…º÷½”eH§Nȳmµ¥©©SÚ r8ó©èÈJ{„çò:±ßo^F¨…¸kl&KŸ)4˜Ó"-†•ˤ€ãŽ ŸÍ\zÓñ+p+gʰª¯nŽ FPÚ¤U)A— $t¥Æy˜ÉÁû ÷ ¿[;â¼ÝÆšvé¶?$©3ÿŠÊˆI%! pžAw‡Ä÷/ãÓÖmM¿n§JÃ’!X¸¶£ñ8Ë¥M…6?xüú:%´Š­*Ó¹©.÷T§HJ#D”˶8þ(€O]g™Wï÷Í÷%Ãõ•ÖÛ½¹‘”¨ˆ¹j3¨a`g(u° ¶”ŸÌzè+î-Íñ‚:œ¸‰²a(¾–YnEˬ®A#<› e!c=d}:Ï®„îˆ{Ú‘ÆDªížâTðnAjéJTlœr[e°áOYÊR¾Ñ†¶¨ «™¹+v£»—pÉo.$ÆgåÁÈòx)q(RF0 ²áì’œè–ÇÜËÛ´2l—O{)Æ‘&M}çFOÅùõâü»Ð cwïÔŸÑÛnpqÅ=džú*WÉá ýN5ìÙ¼[”˜Ñäü;˜ë4ˆ»‰kq߯üdƒê8çL°Þ§‘m‰;&ÖDk´"[ŽNŒ&FiÏ2ÒÚÎ[#Ó( §Zïv雸i÷uÕm•\FÔ¤ËEbÑjÏ¢ââPrpHÀìh†æø–™†3ûoo¡Ai-X¿ ¯‰!,°µd`d`c?‘ÆøÛƒâ+×"·ì &ÛTUJjcÒ'";‚ó™Oþø‡¿Mݶ»2Ê× \¡oA*~ðXRßYG—Ê—[+G™>¡DžŽqålRBø‰4¹q*ÅVi”¸ ZXZZ¡CŒ\]Ž%éï ±yñtÓL‹ÂÏCrIðä õð «8g–3ùg>Úñ½ýñ*L·ðå™m! Y’lW’‚H äûMàlãWwm~î‘·ãÁb-%Th¬­~n*q”ú©E*Ž…uâ@:¶žÛ;ºžÊd뺯Òß.K‘ü!´ôr¹ )ΆG†-Øÿ÷ÙS©›³ ×%·ß7縦ÜRH϶“Žÿqè ”¿Šs¬zÁ»=…! RÛWÒŽ꤅Å®Æ:=4j¡;Nu.Vl­¬Óq’¶–†©™ÿ!ȸZ)IìR£ÙÒ”}»mU·ÂîTÚöì6ЦW&’Ì–¼NIã÷­~š½óñdq)Í¥·aÁSBeIÝÐÙF3ž!%`Ÿ`R1ï¡~/îYV)‚­³XÃÅÎFÙn7ÃÔ¬)¶äO¯¡Õ…›v†ësY_@Ù›f²¼Nf¶‰Á 8¡°âƒjÈüC$wœô4ǺvŽæÝwBTz¸¹‚ãNši-¾´(ö]I_C zèt=4~c}ý†‹o“ØþÀ(i[™iYÉèw žŽ3ŸéÈÕ›ïèq\‘ò{:ZšæÌ;©RG¢RÜ#éî}×A>%7oK´Z±ÞÛv5—ȸŽ9|¦3 R†òÿ7ÉjÏC#­)Óï {îÑšôÔÔ‰•Ε¶…$<òÚ#Ñ(p¸‘Œ…³ÐÐ9î ½ÛJÓbD]¡!ç1o$º ~ŠWÉðOî*÷Ðæwfö3™‹?omjÏ«ÃvVêo‚°3œ%¥öVœwmÔï™4ûN?T°•æKëL7ÈJŸ ÿ4¤ÓµNë¡rªr¦CRÇlCŒÅD–[BÑŒpT‡ R*˜ÐZ…¼mì&9_[ú)a=<‚cG³ž¥¹Œçо@$§¢9cóƶI¾ßͱæ¶ÎØ™ÎÝmGåN%Mü?ìÕ«ÅÀÚ4s6ëôJšÐðŸœÜRóí„EFq¿/dN}:ÒæÁ²½R¶‘mm[ SŽC§ž—Râ€üIñ¼U€zè¨'@_{_ï}³1pF×£¸œ‚àu·n8ú¹zqJã «÷ŒMZ•a¾àÁ­¶îݪcåÔó®M¿q´5FÖ¿–╞ð3ìs޳®êçuÄ•Éî›8{“U1¸²c¼œãÎÞy÷œäþÍdÞÇ.ñÛ;}¬•= Õ4Œ®2²¬ô₼¾WÚ}ã@ýñ¸ÓJ›Fê6´„¸‚ã-Ò”©ôŒƒÁKe(Wá'ñke.ö¹¶øÕô%O3â†~zzÖ“ØR*‚;âHúÙ–vIÜȵÛ×Òù©$«7܆ž8ÀBBÛo‘ô õùŒº"[ƒ»±ïÞ~3ꄨ͞mñ<‹/Š `ñ9ÇGH´Væ¶f3oüÆÁ)?ˆ9º–›'Ð).ÅAÉ=cÓúu¶›pÞ;¸¢Ô\Ò×ÂLÈoËŽük##’Z-$‚’Ò AñrïÄã®ôxmU_íÇk+6ø¬‡Ãr3Ðáµ Ô§¥¨4VR3œ„~‡A­§Q;¿öÅe,›]ƒI`$55å<ó*SüªR–¥e*Ïgw¦áW7Qþ¡ùsm®?òIÿæ Úè{•Y„v¹öÙÿÎ5'ú{_ö†²®³þã›wü×´icþiûü0ƶïîwûF¹þÇWIüµuw¥‚ªí6¬ôR¹t¦­Õˆ(BT]Ìc°¥$3Èö:Kzö&ôq[±6È`ùŒ‡Z’}#'‘K€£–2qœzéŸyq6ÛUJ‰br§̯ IL)j$ñJŽ@UvnOˆ;&hL‹3a8¥m³ —%&JÏ¢P‚€¢:õ(HëWC#î±)$Okn*Ke…–dŸ ed¡g>…$gÓ†­@¹•»i‘PÎß‹§ ‡Ìg™‘É$6ÒOžò¤ß¡‘ãm±4«Êøö2ÞynD¹Œ–ü7TŸÃ’Ú20}‰ãŸ^º©'t˜–1+ ÒKˆÛí#æëäÈr|FÐA˪ qÀ¦F1„¤}O¶€–ç«kŠ•hÒL°ŒÊá¿9•,¥-‚Hå‚•ô:IÁúçBv³û«*ëy[h<Ó*Kq_XóKFãJ8N;쎺ìê¯ÃXϰíìJ'߯†£ŸŽ1vJŽB”>¦BBO”)ÆÏ¾G`cui]y¹R&VCùˆËJ%›)nø« €2ÌÖPCªÏ•<ß¹ìèw2þ"nøS¢RØ·Ung/Èyh-`rB\ʙϿDuè’áÐXíˤXYÎûM§ ª3åêæJæÂT‡ œ—Çö°ŸéôÑ]éñ < hµ­R\ Û<@µjC)[@¨…¼ë —Y=õ‘ƒßKÕ¶·ü5¼ï6¼Ë’´·RÅCn‰­(Ô¥HqĨœ09u×ä÷½ÎÞÞ¬Ðl½¹d¶ä0…ø–Bƒžb@ð9à}?¤è„W/¾E‹ùq˜bÆ;b; ,¶Ày¦ÉIñò—'?…О‡^ºö>Ðß÷; OÕÑÉ3œ~X°ˆˆnKu qK¼ßŽ#8$¢Õ —±/«ž¹­K„ºÍ‹ÑDx΂™ð<Î •PNc£ p®º»ÜÏÏg}ïZJ:D5–SW!j[Ž/¯ AKZ[)d#ßõ´etSêïþJ"§30˜J·´å©3}Zm>’³ŽúOD÷H;bàK5j¢C³ybó϶ åÏÃC)*8ósÆXûƒÛŒn6ò'Y|;“{hóê v|@ðÀÂP–Ëç°2IÀ'œhî¢ÔÄzVÛm¹ ˆ”Ÿd¡ECDÂÏåÈݪ5S«ë-¡³c/p"qSÌö#Ï@+9Z‘à6¥%\ŽAs¬áw{czNÝ ß•mªˆŽ("bŒ(ÕÓ!¶Aϵ:1Ò@û¬t@ëYI½¯Û2ëêïwŒËÖ¢¦eGŽó¡‘Äc¼²³Þy°=1‹Tt·3‘g¬8ÌiJ%Ó)öTéPÉäÙh'®ÿšÓBaäۛ²úy·W0¢¶àj2fFXiÅ’Wø™O>ûüza•5tô1ë즢S®….R¬+Ü># 1ÐÈñI9iõìi.wÄ]«W5{b3´_ŒúZ†ô µ&!Œ…Œ9„%µ“ŸÕZ?]…Žà~cÖˆ™&eD± >}'Š:O•|AÇx#‘Æ-ß3­/.k, |>¨ª”È.¯æ\`ÊKÊ XÈá^‡>ýk£l:¦+°Ñº£ÏŽÃ¨Eƒµ?+-¥]~·G:ÐîúÚ4ÍüŽÕk°Â£(Ô­Õ2ÁüGʦџ¨ Ï×@‡p[üÂí¿BX…*¡µxâG‚‘„ºÚе  z¥_Ÿœz ô;ÆC¯K¯gnÆ¥ƒÎO€£2AñÒʉåÑGó˜;YÖ§nkèö Aùt¦ {:ï·Ùä —ækÉ’}J†séÖF»­ÙUØÒm窖ä‚"®¢qð%Ž9àC¸mÅc “ƒ€t'е­¸S6å=Ü¥XE@S…æÜìà‡;*Ï!ކ”RÎäuéqÙ;BdSÏ¡êÙ.¸^U,¨¥JõA¬`+Æø™ ÎV!ÙJm?:¸ñUÆh¼((Yt¹Ø RÙúƒC{Ú€–¨m™U„žKz,›%‰¬-+!!*m™AM$ždô?Q=›÷ÛÒɘµô±š¥så|5%·S,+®¡‚CiOC HöÉÆ¹Í†ÈÝÐVÌ«›ñ:tyÍÈXn#RYJ²y-kyŽ!*þãèÞpö~Ï“"®žw ÍU]ßÎ6àQÇ&Ó-¥ðg?‡‡}€së¥ÝŠÖÞÝ—[†UöÛ§E-J‹’ŒŸÙoù|¡ CI €H𒟯×A_âmr"ÓÃÝûo¼üûjBÌ%% AG|T„¶pŸOòŠýÃU©bî©q]¹ ȯLe&arJZŒú^Zp(Pðº'%^˜8ÕŸU¸·$›UlÝ¿w €Z‰"t³9PJüTãhX á°œžG@«þnÉÖÆ·­B˜$4ôx¼Ç„€ü$¾”8—žò߉•z}4•[£|N‘Û͹ENµf<‡Ö$¶Ø$©Ð€òаI*_ÍÑ×èX¾ÃkJ·Ý±¥Ø¸çÏ»=MÄ­òöêŠS„÷õGkTJ»T´ÍÊo JOGŽ+­œ†¥-8JZùo•' öFAþoÖ…å õvé Xí« øP˜(—Y„¸¬¬­×’¥ØIÂHúh^®,5+p\É›vÓ‘å½_&#l(û„Y`Þô詉¥DnVã0%”;-AØ’cÑÃaM%%Ò3œðþ£ÓXoMëºkã*·kíª¢…)˜6‘RWg‹nX$€O$6œc²@Ö¹¯=µêœ—g¾M›2B*º:ÌàÂúä Úy¡#=xH8)ïÛ@Ý)¿»QòõñLÙj‹óuI~i>ˆ d zŸ7¨ÉЭᷨbDuè–Q§>ã ]s\V” §ÆSÞN ½ÚvŒ/áØÌ“]1fy„¨$ùÏŒ¦áÇ‹²OâΗo7ÞÓÛo%SÛÛ‹fÖä´£j>˯:? ”áCž) ï’““ù p›¹¥Ê“[,9õqä-)ZœœÛ]ô<Á¥ à$wŒûûc\gâR/·‹•{©Ûˆ©w6Õ>Ž-J I,¥YA#Ш«­§½§>T›3¸!oHhMiå´§)×) xjq]©?LÄÖ˜efò±*Ýl=ÿ“rŠæ\rRT$´˜î`€1üc+PëAËö&Ó•µÝ:ÓiC¦Ž.6ì8“]q*)ºçAÆ”‘ôöÐúzÛÛÝÆ­Nå©1O*lø(mp'’Z’€µ¬2BN3ƒ§ûý›³iUr«¨”Úò} §S!eG´:ÙeiZsê’pÐûý£°bÜ8æÔ¬[RÚy†kä? ÑÐæ£ÆOjñ Ǧ{Æ€UÝÞô‡SªªeƒÒƒ%R-œaÕ43òên1Áö8 œ‘æšò{Õ²Z¸žÙQ¬‘¦T)Qþ]K|3ˆRÖ”äg|¿ˆžõ{vDÛfüWÑYRºÄÅʱ1œ~C(ÁÁSâw%’:è}4‹%ìŠÙ•¿¢öŒÍ´?1ö”'®nToT¤*JÝフqJ’¬+Û: În;’Úî±È3b·^ÜQL´Åtc<žC©,‘Ĥ­c¾ý5zïpmôß×þl¸äáž#Hð>C,<Ëx8æÒT®j8â}sÙ×6Ü+ñáÙ½UXîFþáP$Ö1!¸ I8uÅ"?mT†RŸnûkÙ[âeÃØÛ“[»xº™nM©1Òâʲy";mö ”¢Td #›u1ã[ÌÚ”ïP1ô€‹H))qÅ'üa¤)…­GÔÿ³@i•º,b©QbM\fŠÒÈEtX­¾þG%8”áÀާݨû­T¿~#8&À¾©­yØÉHJ©h˜³9yËrB@=ôN}4WcîêëØ¶¶ðþ%ÌÛÛ‘¹aa»ßàPŒcÂL/Ã?™äUé «·™Ý îéUtÉ6&Y…=+jQSt$¸%¸ß*>„g9ä5Ñ­cÒ×Iýc"Z+“ -¡ '• Á@Ç×\Ž÷Å'w¬öWeciY6;ÌÆ :]ˆÿáJÕ­¼ ìó8ëˆÕ[ІD Þe¡&ÉúD¢{×~gK‡°Gª’ž±Öþòžâ.I§­~²ŠÃò›W̶Ã8é|[SŠ•IAÏ Ò‹Ô÷ô[ŒºÌÓt˜Á<f«‘9ü…«ß¥œ«Ô³ í¹BR/­c,4ãÎW!OÆÀí´ Ê<:=„#Ðòú]·¼˜‰ºdÈqD¼·9j"p¦ÔI8YõõR;É: u4Ö‘77'­¦&#¯pŠÕ…zW)c)£iÞO®–ièÞ¸¬*T×$¶ôu/ÂPåÁAÀ‚¡“€µ­9÷ÑЊø²PþÝ45Þ?©Aà¼%å-SZÀ*(”ú­ØV.9iò²w&˲q·Õ3*š~JPí¹Ä+Ðúï@¿t1]RìZèÑ£üžˆÃϼbýç¨yIyI$ “Ä€:ôÐÁe¼®)SíZË’Ë«rlWrF†A.q+ZÉOìð?Ÿzdø.îžûû^§c¶õc ’ëII9ž„3œe.ŽÂÒØz5Jíw$¦)Ÿ¸­TÄÙÏÙ¥´ W•ç®ÂŽ¿¾ƒv棉’“nííàÍ=³ +äá²\u§µ)kðòêNI=àp}H=¯ðþcO9`ÖÈ„¨%²Û“0¾èÈæJò\É=òK$k¯J½…6-yR¢dwe!ùQ²ÊT•«+QuÆe…©C8$¤ǰÖ;§gmkF¥ÜH‰^ë¡.>å›oCžl„¶qžýBÆHÈW®ƒntÉw|Á¸£‡rìäÇm¸Öšr*ᜟ4¤->ópOdä wܨ±L=Ïd·Ý[-"ÉØm¢Aù”%¥^¹ÁÎBNz'i¶v êˆSdÇÙuÑäFq·_Æt áÄ8ÆI#Ì ×}õª×±¶v×®zªm5“qË,¹`P®ÂƒJ\ÔxiÆë¼ ¸ò%\Ò¸ÏSeÅ\¯ñ£^âcHgÙ •·æÎHQ*~ïb »’ã¬Än»lÀ¤˜f»L„*r–Ö馔rRsÛg»ºÑ›ogÛ~•*™ûö‹1Tщ)]’¥¾û¨8Iä¤9T;t[Âj{[rjjV¥Äk.m|‡G"TÐt8€ï"¡×&ÀÀdÉ»š–NÔbT½§SyRãÅqf9ó2ÛÊPòTJØPØ—]fc»ãÏ[À–”âV·[P)#$( }¹¯ÁÉe¶Õ¸¥_m[fìÃìïo<¶ã¶zPm¤‚°B3“1¢‘¾/|F‰zÓ ª¦4ò”·âß=¤Ù-²òGˆIí'°3ë °Ë›™ë©ÍxÏ+Êe?¢+%¸üºmµ¸Úµwøƒdc³‘¬g³¹á]U˜²›wÜqäÃyUÉ ãŠ‰iÕ£Ÿ~辑ƒY¡ß5Û‹{7[º·&àÚÒŒâ#£äMPá9:¤>¢àyUÅ>š¾÷'ÄÆïk¤Sï$n˜QV…J•@ÉZXA(攺°TxœäÉ'ÓAÔšBvõ +iöS)w ÐK’SB[ñ^9.Ÿ ”“ôÐkºôp«¯Y"ÉøD¸‰-ÉeKyÒ{ B I@ú‚Ç×H×–›•)èY~HœVöԈq19§$6¤•6H$Á´œƒŸMy°¨ï®d—·Uâmì|HLpäˆ}`•²±×—ßAî㣾¸ömÞ®{ó^[«ò³P¶'IŽI²”“×}èšëï'5 Óç-k[,”Êešîm§ÃV¬8ÿˆØ €r gYCŒõ›…w­½} EQÝÛb³ }ñxxRèlœ•ì=‹1ðòž<Â6mºR—þn½.ÕÌá;-*Aõó­g–O•'A¿~OÚ ¡¿‡I:[Á§ëÜ\7ÛeYeHuK§$)'9èúèÏ´©¢Š–+êš„âbsW])Å’¦É  ¡õa°:ó¤(‚üš»´×OÜû^+”È}‹))aØùä<1÷ï%j¾ÊºÈëé}=i<"¼í}»: c"KnGQ’§²N”˜.7ƒœã9h_ݶdIn'lP\·”!¨u/¸d-J'<ù­A8è‘Á_»½,íJ5ÕüG…>lj¸ö³ Ù|ópTøJ‡¢á*KÀaC‘¤`ëÊ«m2îS· UÑžvbe/o*l™Ëãǂϑ¼t F@Q¨•ÍíCˆ´Ãª²@º©¼’§b($Fp $’rÙó «C.ä?ÀÏîÒ×ùG¥ÿOkþÐÓîåWð3û³¤=¦sñ“ý=¿ûCYiÖ¿Ã øý½ÿó?´kœluy“ûõÑÿà øí¿û×3ÙG Hüõu [¢Cq®ö£®X"¸ gG̬ #0%Œä‚®2AÁ9öÕý” 3Ð>×·nâß ù–#“hIä–RׯD¨¤uë [ù-?'m²û«m•Ú8R¬d|Œ¼§ø·:>Ÿ€úžÓø€»³#Îa VñLÔ"&bAvlŸJ ²¢–—‹`c°9ý5QÖ­Ø­—cö¨i¸³–·Uóe×pùx<„8® yRx÷ª•Á«†Mu}i~!æâ,ߌÿŠ{感 |™ý4³COC&©©Ðë…ð$ðL‰4o©‡ŠSÙyô£ƒÉqíƒéë»j¡çÅžÓÛwÌ:îKó¡×CŸ¼FÜp8A'>~Jú´gíÈ6²ZÛVb×p¸‰).ª3ª@hû)){Õ@¨åHPÈë½ £Ûv¶ñó-+à_}å>Ì3ß>R´èuÝ•û³l ˆ7 F‘-´¡oDR^=…%¨T¡€0Vr3‘¥ë—>&X¸‰û·|íÊéªcÁd.;Œ>ÒxŸ½h.?ˆ·FAâ=z[ér7çS^@™C©7&[Žƒ@ g]í*™èûpÎ~3É*M-t׉ Ÿ2ù6°Þ?2>ºyK¶ÏHj¾Å¶¤rq„”88@ym’êRët~Š8ÕP6„z¤ÚPÖÙ)‰ c=dÉr xáœú¤¬þiö×<ßû«yîe;¿kÍ‘_5+eÆíû?ÆH9BœR(N?T%IWÕ9΀ä…ÙU®ÚU‹Wê”ãf¾]ü´¸·Oá!àX+ 8÷:5SUºD[+F,§Û3“ æíTä^C) ¥n©|€Î¤éF ee•%lÈÛkhF© ÃvÛ­Jp¯2úaIÎ}9ìgá…Lü9ÚuÐ'¶ÍÎÒ­…‰?<ÊãLYèd3%^"”H”’0¦ƒÝÛCöS]ví¨â ©˜«€¶ÖAï iK˜Îq‚zëTÏÍ}¹avÆæ‰u\OËÞ_˜8â;§=“’1Þ·ngῸœ‰G]dúˆN Kž*R8<“Ò³ælãÙCH^Ù…;pÊã½Ù­™,HÜ IyÀœ‚bˆiJÔ£èO “é ë—‰£º‚Ôd°¯ á˜ïMäû!CÑà ðÖ“Œ¿ËCš™3œŠÝ§³«³¶îÞ³éªY÷×qL­½;k㌠©‡Ö JX6R‚O±Æ‚öá§û5ÇbX=`øœÑKb[Î) #+uÂâœ(ùUëצ4«{°w^ÛTk žÝІ´!Æi\’SåÊËù¯A‚žôÖõ管y ×åøÈiø Õ«€)såâ¾®ú ÂñÑ!Y:X—/â}¥j£ÎÝ”¶ìy9VI!}œ!oÉŠ’Q“ø°§@wv[_°`ÅÝVRP‡ RòZCKTñJˆ=z}ª|7Ù¶uª»V‹:£ÅuZKo>Ú‡~p”AÀ$÷æg¢4 ½ßiZâhgo« }åø/W¡å4Á_£`-L¥M·y¤§)¨õ¦œ‡eÌ“w:êv>¶Ër€•­¶å­ANöNSÃò›µ;ð¾Õvͺܯ?9ï˜æì…ü˜=) uò¤’qžÐ®µR.áø­i}gMd§¬qŸ„”¡Ï˦d'8ós>ú©¸_dWI¶#M¥€ãaÆ"#R]uA$–›C%< I>w‰ÇˆÉo‡›_m[&r7D‹y2žHzÃ磻ͰµruÏ;^\HèzuTUôòÄåÌÞ0TÌfž±ŒÔÉ B_Î \‡5{d€Hú l¸ka[Á2¹lÈe‡cvÒšs´”$)~~ÏkIWå Ò&;¸™®r6á«\8²,5U%çå•ú ×Ú „ƒ‚R¤§¡@éѶèâø–×‹²”"!*³T§$­Õ+%i[d4¤$õÄ6¬çñFÞ³ÙQœjÆæs¹$E³qõÉ9%(äÇdõêŸËéj¸´~Ú1cnvëÞO„¦ÉRŽ”ÚV¢¬œ(éë:ÑQeðçt0öࢇ.o”—ÜTù-9J“-[RZ›B¥©­”å)Q}¶ÀlõëÈÞ5ŽÏŒâ«ß‘"öùèÑÜSÈa«tÌPå%ÕÄgж=t6þókZQÖÊ¡rÆÝ2ãµ)™²Ú?ˆòÞR†Tà-d¨‚†O¦–[øYðÒuÔMnXÖZ’¨ñ“`àPw R„vDo¯m ;ËoÖ»~öå"³îì ¶ž2^ò,©¤7Ŭ‚RŸ#²Fªn=…ðZŽ‰Ë’Öâ}öà‰åô©ØÏ+ð©lÊáÌŸ|%Yýø:÷·¶ä«°\ ›ŠeÚXrZYym!„õ„7• +\síêw³s[) Åß,C\GÔ ¨“ê$0à§e#'á ’~º¼~ÍrkVûWÄÝ©r0C€ðYPV2²…¶ã|Æ=[Áëút",BË›†-í^ÚÛøÖ5±&©R¬-aÖ° ze¥^½´+çm´²Ý}•\Çö¼¤a‹ˆÜ"{(î3iõÙå‘ôõ'aÜmyR¡ÖÅÚöPRâô§šKH „%4”:¤•`ù±žµžÕ‡³"ëoî:½Ås$¥"@‚êüp0  'æN=@BÑi¿¥nÔ&ÚÊ Œ¦_r¨Xý™] ’•‡\zv‘«Xdš›ÙûVÉ™SíÂ.KµZe޲ò²°Ž‡” õ^µË#"”3IJ^‘YK"Ä Û*e KGd€´¨žô 6!ÔF•¸¶ÚhšÛuÍ¥¸^x#$!´ã–OKQVC=ƒ›+kì½ßgo\­žäV¡ ­´ø²y8àë)C¸$ÍXÆ:ήnÝóCQ5b"µp¸k?K:"!¬6¡Ò›mÖZKÊõì«­Û›±Ç(âHSÛs`íÙ’ÜÓ+—'礸r”¥¶›S@4rGJX÷ƒlmŸž¨UUìÿ”¬ä_}Û)®!-Gü䬓ˡÐìµFŸ{VÖê™ß”Ñ¥4éoä—lúP’Ð$ž¹•õΗåîØ¬Ü+¿‰Rf¼ÚP)âZ°èAò¥HRÒü ÷Øô®é³‰nÖÛVº¶<ÇÒô Vf{²’r2ØqÊõ€sߢ²}úì Ê£³¶jdá¼¶Ô í¼ãên1/­£œòBÒÔ•àãɃøtÙBöÙ¢U…Õ…dKC>2—ÑBûŽ©°<Êyag°™)9£®mE¸%Ù>ó•,íû£ŒÈÔVœayï„ÒA #>]uéÆ<8páÛ_E™cxS šZ[ËÆx6ú3ß^e‘ßõ‡ Üß6ìÍį²;i¤ÄwÀ–Â"¤ô¢„¨?í(Iöž‘¹¼•¹ª[®}—žçÖ ó”“È-i‘ø½Iʈ2|CTMØ¥ÃvL »e’W]a*+Î-%$ø­áJRñŒ+ûÑ^ÛV4[añµ·ýL'™l¦9dHm·AYâž}yPÉùp{Ð{Á­6ÌÞˆ•b¶y6ën%¦µIk,•(Œù{8#×£ªíîæ÷FÛaËVöÄIÑd)¨Ñž~ÊJG$¤¯Jqœa@çhm=|ØtÖEv¿<õ«©ZàT¶ëiŒ€rJz3Îø€‚r8‘œ >îÙ›BTx”5FÖùÉ( ¸§Zä$“ì%YÎ}O^žÚ›LÜJTJ—G^û%¯®±Am$e¨ÀТA'?ˆ’¡ë¢[F­ç¬¦ÇE¥„…ø¹ûÂÃHW†J JTFJAÆ•ïªlr,§+ܵvK1ìË“´­@(¶Ô ¢99sÜqü:ð½wWQmv®ãnãoÍyŽ BbñA²–¤ÒÚ[[¨ ih8õq'?Úº­¤6üÝÀÁŒÇ§™µ©InJ_ŽYo¡ƒ…)JÆ=5n4íµZó’6…SŽ@K€È‡™HL„`|ÛŠ´‚åèzúïÔ[Õnê¸{ƒeÓÔF}Îv§5Á¶ÚVpž,¨@~èO¯¦|;®Ûòí$<æòÛö.×-ÓjçbUÒü$¶„`yRrr|ÇA›vû.¢m§`êä#š,…´ÂÏjQqhOUê }:Ѹ*µkq5“hYðRãë}r]Ǩ•wüÐ>ŠÒîê´øˆK¥\3[×<P !1`çe+}n<€¿ Q)Hì}N g«ßDë™ÛN¸%ÄÅ~ ®e[…2z[hm|R•~,,v4ÜmöP—¥ÃS¸¬™qm"$XL%ÂSúÎ5’—RSùòΗa:ô ÷ß°ØñªàÖ»óîKb©,qÊRž!®x?„¤{d`éš\ùUô¶­<9ÜÛ‚ìCaKÍc!*Ae-­Ìt’=Z™yW´©$×Ìì ÒR¦Ìè®4Ì·xT—ãùŸP}âÕœûtt e—}sO\¶© ³½`·d´•%J 碂r0xãÛÓ½<±ðö£mØÌ^ÝÙ’Œ—ÿƒªD‰7¶É³žŽAÁï‡H´»Õë–Ó6îÚÛ[9 EDYö–RÖÃHJ¿G‚x©ìdƒâ$ô>º¹k¼èÒÛDoàÛÆgÔØÌ S’̉EIÈǨ=ç¿A 'm}UK>3Ûž¯n8Ê ‰a›GÛ++Wd© •sõ' ¾ýêÝãrwe׈æîÚ(aÈ­µäË.üÊAï[e.g>ªIì jj×û)›6sõñØ-Ë‘º—%xVÛüZŒëC£×«$Ž»[Û[®…Âr¹nÍ0ÐRÜ/²çOt!G(KQc„ŽŽ2“ïæÐt§]Šé—Òáî7j$8tÒ¼ó~­¥ R:ÇÊzöЉ¿v ˜Ô¶û"(y1WÊŠ²ž¹ùI Ÿp­:ídɳÛ’ú15Ÿ†T„†AH[ÅI?—$žÿ£C7…¥|º„ÑKðiy³ò–“¬a˜òÈýSçyà“‘Ø9ïÛ¡ æ³j+·@­ÝPÍ{Ëi®RJbÆÉRRV Ž=€ÂSŒÞ›enö›Ÿ EÞäj*Ymb¥1ÂøÔT¥89dœq~Y_Ú°ö¾ß¾˜Ë»¾²=™YrR2TÒP iÑ R”¬ò=r­]”ýÚæê™¼ª¦˜É[lªµ§TÿP‚²ë eipÂ#8ï8È^«ø€Íâíé¬$Ñu4§³•-‡|FÒ¡Åe/òYYþzF~ºI6½ï‰µÑcVÔF’ÅTåH“ +“‘x)EŸ)ñ“§Z‹ ¯K°@±Û·—Ê[¿Vër~ü¬œ7–B `g‚G¦t²Ýy¯ßôªK/BmêÛ%µ\·Ÿ" χÍ-6sÒyÖTr4÷:± úú{é#fwñ“ý=¿ûCN{¥_Á>˜Ò^ÉÿÎ%'úsöµ–{ü0ÞP~çu˶wNß®§þ½¼7°k•m ×¾®¢×ÅÙ~= o¸ÂöšÔó¾± QAåÉ8<€Ç›×¾‡)ÑSºë¢WÑnÙQÊ­«¤=1ãõÃÆ[|JТ;J}çª?…ÕÑ%É ŒµŽ\/- ?‚ÈéKG˜$ú=àÛÓ®vµlhõu3k–€‹¥ôÂŒ£É‡T§þù)ϪÆ!TÓÔt†ÈM}3떖سƒY|ÂÕé– R”\=r4ÃGQ&Ëx›ËEB¯€†ivRº©o¬c‚yeg õk–Zn™nî¦Ó2Ü™!“üW>c·€£Ã r:Òèì€<Ç:d§Û¹fý¶÷MÄwԠ¥†ØvJ¿ŒHXa àB’Ÿ ï@ÊdÜ6á£^ÜÜk‹kJ¬E|µ¥Âž¼^EÕxg~ =çBá<½›¿Y%ˆréCä Ke Oi-­Ô¬(v )R½rq¬¾}£O;OеÑo>`²+—¸ZžÙi] ´x£é…~äêÎÜ´‡3q*"ëvóÖ±Tã³7L™%΂RÒP„#¢¡éï /\emYÓ·-ì£PÌ€·#[¡–œyÎÀ Ë SŽÉ#ÛU-ov˼jD)Óg#’Km)ÀOÞ-!Ô´‚O¢•ƒýš3o¹äË\(0ãÊh%߸‘´å!…œd¨~‰9Æ3¥é•{ºe,Ök+å ᤢ#Ãox4£—@ZÉVG¢•4~¥Z ©Ü¶¶–+9J°róýpq§gÑ»¦ÖÂzιcä¤X­ Ãlþ£‰9J³ô(ÿfƒžÊ-[KàÕ–¡:Û… c8Òu­ó6¥Ÿo)túú oÛ¶¨CI›e1–RïðvaÂeÖ^âʼ&rUéÙ$œ{÷¦©û•Æ7nô¿Ue³ãnèЯèÙ¯D¤)´Ìxe¤$c’kQG.üÞN^úaø³±”Š{DPÙËi¿ ·~]„Mt;ã9H䄹ù¥>§AçÌíMËy Ò4kÛHÒTçÏd»-–ÖñŽ„µÑõ  ­vØ’ªë¯•YjÔ“´B—&cK?Åâ•â! à¯@é«»Zïi±:ÝÞ{®U[qb¶ZŽåt&™}#¢àe+ Ç®T•}t‰¶âÙ³ó³é¢³¸ËÉñ˜aùN>”’$­âò jÉâBG³ž´Uÿ !©2u*-‚äó’êëßÉ‚¡æRRÒP³ëÑ8öǶ½ƒ[my_O)E‡ ÈbuÅ!­j;AX ,7Ð'×IûÏ{M±Ù¬l÷"H⥵KC¡ÞÒ ·x8sÉ*ÁÁΊP××nkHŒØMÝUR_‡Á¢KnGDd’¤«å›óc´rÈ>e Öâ~e%“Ÿ£µöû–+Þ]†‰3Ûe$)´¨=ÁÄç*IãßZXÝÕ«„¨·N@ޏ-¼ãÒ Ú ²¦Ü‚€ûˆäŸQ€®cÓUj«/+w3±wWÄQ¶c6ß8bNêå¯9Iq£‚[#¨'9õ>š9¹nY…¸·Lííé*cl˜o)kJ!‡ÝG`!ÀTA]àß ,÷Ú;ŽÖìr ‘RÓMø®¼Ó 0òG'ÚÜa'y:ÆÓsìÛè–V;“çÑ_ÁHRœeÙ#'Â…¬}B†1õÑKMÈ+i¤×Ày‡g€–Ýr6Ô”ã^ qR‚—1û>ß–„øòí”dRði×J–Ì-²¢ÛkHËD)ÞIœrYmCÉ: ÇvΑ<5m9®Õ-Õ5\ª{—TÉä¶ÙñR“‘裯ÓZlBÌ™Ó~ÊÜ -´¡…¶Í<˜¯ ‚§J3ú „“Œ'ÔëŸc¾¶­¯‡µ\šéK²„é.¶†£«8*mµ¬€<@¤àw§-³;qnºúbl‰M·5•>Ι1qÐOÞ6îAß>¦N.Çæ"2Š÷if929GÏ,W­ÒòV}$º†½G™¾¿Äu®¬ªì%Ë.Euj¹.óa]©E¥8SéÖ@ü€Îœwâ±Ûuenw•!´¥™~†Ôà*y F #¼€3­Œg/™[Ò!ÚMù%JÊS¸ôR3͵ªI HÉ#³ž± u».ÕO"­;vúKÊ Ñ0T ¡çâÐB×d«*NAï¼j»Œljö Uʽb@ ]f]ÛmªIÉ?„¨¸×‘Å! cBŸø€õ}k¥Çn­¢ã®»U‡]HOAÖƒm¡jõ‚‰=êë»fÚûhSoFUô€ë®5U:ÚZIü?Ç!kõ怠£AîëÜ[fÚ‹kQK‰"Ž%«6>q+d•Ÿ#Ì’}<ä~íQÚ›ovKD»ÝÉ·dÉpLek ?¬°êÕ\i'±¡û±Êݽ$+ql*è^©yø7\Sksƒ¨*æ²åĶqœë MÚÔ6”ð-6µ¼˜è”JCÓsæ=’x(£=a`Aé ¹³Lg¶ÝK÷2i’–Yf¿ÄHq•g%1›R¤å^©OyÑFÞÚ”’^UJ&A²u 8ËUEþD0u¶ßÂ~¼T³¤-Ÿ*>Ѫn»tî ˆ“g¸™2“SD81È«æ#—CgÛÕ?C§4ÍøS/t;]_Wwp§!ù, ÆiÖä:A%)âGÞ4Ðh–ì Õ[<ó"¦\ô¤GSTR¡’ñ>ª(JBÈÏ%õõÒVǬÜÑ·}ƒBúö嵅 H‰!¯ Ç›B …úž•ŒœäwNÇἨ÷¾®Eý#¾ñYvb”úT R”ŽCЄ(I)MS¸öì9÷î[ç‚—òðâÌžŠèª+H™©~Ï]}õ,Ý×·î%Ä ¢ŒÁ®[+‘$"¨\ZÏ5zä…(¦…Ȳ˜ýM^躙TÛl4V¸BÖ#Œ81ÚÚÐQÏÓ¼¤úäè¤Í‹»¾V½È0ë8¸RäøÉn(p9È!Å©´¶¤žÇÝ¡'×¥«ýƒuâ ½Nͨ‡­T¯³%že#õSá ¥$žÊ”œgðžô~nI,"[»‚;j‰h¥:ìæRÚÓÚZRV“„“ÒZ~š³ºkf¸üeíêUÙX.S)m ¥.4ÆVêÑ=Œþ¶Gç骳ª%PÖÎeúú¨¶¬:dD‰aqåÛl|!‡BÁ¤¬¥JÈPï[6–òjTqa]öãh¶i1Òä¦>…+! EJc *È üY΃væ‚ìM¶›¦¤}óSˆ ŠóïL.+¥©$7ã•%9#ÜcVh~#±e-­»Ëx9òÑV©Q¥9땦\p€¯®¯ÙG¶oiH‡2¦c¶¬K",Æ#‰"8ÂÒ©Kñ2N œTI =køÍ‡|mÈÁÜnÃIu•*Lµ7žHó©—<õÚF2yÎM·¶SÛq¦ãu_ØXm¸Ð–S òëí> IP!Ç84q€µ,o¦µííË·÷3m̧£bñ) Dh ϶L¥>V“Á¡#8º*ÉÐ;¶U”fÛnùôÇn;Pžšãaç8ä¬4ž «ÁÊFõöÒÎÝœ¯´çÖÐ76C…ò' ¹o%ÇNTËŠGÝ×áÈÉ u£ë•Mú ¨ý €Ä«Cý¤§¤ÌmXÁãÂ_0ÙÇa*9ÁÊzμ…SÙÆçÒÖn8ðâ`¶ðDu¥õ¶Hç—Þ.€~ˆZ}=ô¶Ý†ãydÂèø©bHç™ið;ZÔ]u) õí)*8ôÒëµ¥Œ)û CÕ€g¸¹ã2e)Rå¥K øp@ì§™—knʲ²—`峋Qrlxªq,Ãm]$)¦ðTsÚ‹@}zÒÍŠöTXðötºÚjHyûF9Ÿq=j’¥¤ñá!¶Òp=B”2ZˆqàÓØ»k´m+¥­¹…“ÁbGŒ—V¥:¾Hïñ¯@иu-g;bõe$›4¥Å É*ËYórZ¹¶ÓtŸ)èS¬ß›4¶gÇ?í¯™Dwâ¹%Uhï.O¾ß4”÷’ÙHï$zéû{É~Á©õµß cJ˜”ÙiÕ-JPÈHàSÏ %KIô'AÇÄ·'y Ä;¸ÔŠô†“ÉèœÔ§UÑJòÜKƒ¾ÀBÀõúéÅplóß7¸èßžÈH‹™lE’ÒÒZNoÛOl¹LݪDžcYg"E²bX³¶a&lgÝÉ I䜜%+÷ë4éjÒÕ§qLÚê¹Z¸²óϸ©*}C-qLd²¼¯75rù4+E,K-ÐÏÊ_%K̈ ‡É¼¡¢Ûˆ[€t ‚x‚öΘ É†üºÛë|Yk˜\µm™ º¤dú8„­@‚}B†pzÒîᕱê]ƒvC]®áD²ÜöiÙQDÂT*x Ž$­G$žŽnôØÐyÔÕû‚µ™²ˆò™Hu‚‘ø’ÛEm¥µ€TOz 7±w­íÒqYËmÇÃÞgü—Ý t¬ú–÷DZ=v‹ÊÁêšù÷S§ÌDµÄš–èÆ9¨¥e¶“zò~ý ¥Ù[’»^6ðݨ‰•»!m¼ìR¼aAjâ<>={àh«{unJéwѪßt|ºÖì)kyu!æYC\³œ•óôö: 6ö[›s;åÊÚe±,r [2ÑýêHQ)ôU”àij³sNVóU¤&Ul¨\yK)pŒ,ðd§ñ ùÁJ€=[Ý?nåÓ8êvì$XĬàꋱøÍw9"Ñ VêtOª“Þ3…·fÁùiÛƒn×ÑF“ ø1,áÀaÇp@uHS©qd€2Ž\N=zÛ‘–°ÝŸ[ÆB’㌳ Öå8s€’ˆêWýOïÕ:z;9”3udäVäw^Yð›õm(mMá+W¡(⡎ýômn¤·fYË©G &R+¹ª¨Ç)w—%,wÇ ?GN´îÙÉvLë:Ùvµö0̆š-:²VOI[r\JS씟@? ë@¡Cñ)ºx Õ»a¼Òü×T‹Mü46d6£‚=’¨ÀÓ-ŠäI¿­²T«d3bŠ"½hCnÂTS!@g¾J]/m ýÓy½Ûã3XÒ>ý5’é’§Žœ ðˆ O G±>¥u|-¾Ž[¶»ç" ç%ùß$d)¯'Ê–Rê¹§Ðd)$ 䙊£²ÚK™¸7Ä—_ñ]}æ~Y¤€ž$²†ÕæõHP9Áë­i;ËdÙ]Ì¥¨V†â|xÓ]Då8¶d5“â+Ø+è¬ ¥‘QuÊ“·÷”jÅ)è¶s̨‰@é!¿á’0]BÐÚT‡ ì$Ts¡0>Öoâ\Xja5“„E5$<ãø±|ËÀ'Œ“‘“¯e¸'Gwm&±ÊYà|’7 †ãM§Ê¤©¦Ù IñðÖlzh½½|šÿ‰'•kµ¯ÒÌzµÈ­Ë [%ÈœJ̇=1€ƒïê4w1þ v”ö0ÿÊ%'úsö´Ó¹±òǬôt¯°ÇþQ¨‡þÞßöë-:ÿø_ÿê÷ïwû¹FÓþ0Ï]cü/‡“o+ùÎÿ`×&Ú„s¿WQ}A¶³™¶ Ò2óö[Ÿ p* C’U€°SøBcW6¿Ãã&Ö<æ)Ÿ©ÏdI.2¥«áŒs–É÷$Žþƒ^]3NâÚ,N ˜Ë¹!aq”úÄåc(HÉïßÛ× AmüúãWΨ»ÛÕÕ´‘Mk°Ûie‡Uœ:´Kdû’~‡U4zCFÎÛæ^ñƒ6‰n¼¿ ¡K–pW€†Ô[J>Žd‘Ÿ]«fª"£\Àk-×£¶Òj«Â‹Á^nJJ^ž£ÉIõON]M„(›Æ¸¿†Þ\M¸KNŒÜ_ˆÛKï¨/‘Õlþט»¼$ÎŒ„”­­™B[8ü+J°çYüô¥¶ôÖ캦ì¦ÍuÎnºÅZ¹1ÇÌ€µ;ápJ úw£Uq#IaToÝnß›´_Ï–‚Ü„¥à''°FíúkŸ§kÐVA·’×9 ÊGʺ€ãiR¨Ë`¤óõâ¼Ù)cÛsv~Ý•_ ÚÞ3×*˜/9LCJPôNBQÙO=¤´n6!4ÌêˆËy—0Ôšˆ ²ØPýrÚ^Z¸‘‘åp$ý4—m?Ãkgo/W¼U*jœ’!½PÛA¶‡D­N¸ •”«–}qé£ÓmãíV(w MwʼúüSŠ2}'ʲAɾ7•ÎåÜ 8õÍ xêSJ‰l¤±%ÇâiiK¤Ÿ ôQ>Ú {;âe…Ä)ñ£m©›– ±ËðÞ¦ü碗“’‚OâÈÏ^S­UÛG}E“[s[OKÀ ²à>‡!HPÎ Û(G"G€þŸ]P™AcǹrCŠõÉ$~%I/¶â§9KBzï^VV@²Jweã­[´ÒS¯™€ РxòÙŸêÆ=O¾‚ÛÜZ&­KbžLY†[°¦·ó²]F?É­-8SÐÀóH5Á—\#MÝmƼ§µ/…¶‹ ‡–àãÁm)ÊGÔ”ç÷ë˜ïúêÆ$G¬¯‹TdÎäô¥Ö";ëz0?…B9 =’”ðsWØ;6¥´» stîÂ~x\xönKBV´Œ‡N[?Lž8Ð>¿¸ß`ÜH•±7MÌɱ1$ÇŽèŽIP k’ÔÙ*@õÆuí~Ù¶‹Sc~ºh,Äd¸äJ[}Šñ‹aa`Ò9gëªP6%Ñ—ö‹è «šÛ¾$y”0Úkë‘•àg¾_Óï¡_6~àÝÍÙÜ8ýÚ~]A·!Én?6‘øTK‡€ÉïÊ1Ÿct;¸gVDœ‹ ˪Åà ¾\…!¦¡#=·â¶_G$©KG ò Á›déË»ÝU!gÁ7§\C„ñG†žmëØQ8õõÓ¬ ZfiÑuöÎZ7-qïçÈwî–› ƒø@#±œªõ0eWW®×oßAÛ{jS'ø$‰òmÇÁÆx(¡I΢³øtÔmkO·¬w«Ià·\1šæÚ°-Ë*Ϲ+o= FÀ¶™'Áºª›ö8K¨\—#¥µœÀLw0°=2;ùÆ®V_5»&˦…hrCf"æ}®‡ëˆ VržmõœíÖN›,Rå=|V)öÍTš9ì•X¼ˆß.ûéJO‘-9X樓› mµ%Ó·*ÆÎÈ­EkŒãŽ6IÏ'TËm•œþ© ¼ ÙkÛWô,[Ñy)¶%)Ôª-Zû‹@ϸ–ûúÈ+¾ÉôÐm¿!„Ü·§vQWG°}ÄCm „Y8’<±ù0¢”GáR$g#9Õi××€Á¶qN®âÙñe¥§Zhç*q/+бÈq[„ãé eÞÏ&|˜r>Za˜Â3U.¸°}T¤%m„¨ãÔgù÷ÕºÒº¹??qaº£ºÛB¹ 6Ñm,!C¬qy@œ+ÙJÁýOM&GÚa1'×î®)Œ³ Ô€€?4eÏ!ÉåÚG~nñ­”ìÚ˜Ê\Û¸dΛó ,V—Yxv²V€yö{^Ú™®êšÐ[¬Þ×U%¾M»]Ÿmû¤º]Pq^ÿÅ¡CJõ­Å³FíÜKø‡ˆ¢:—OÍ÷–£„ŽkuI*œs?¼ú›*ªÂšÞþ-q¢z2Ó!©3(£µ%Å8n8¬œu•þ {/âMæà«‡^Ùgnx­!ÕÈ»ŒÜNMük_{‘“íŽ>§: ”…–ælÐÖO´†·DYD&S)ž±”-² I9ò×c[m6æëÝ,m+ö½~ÞyR˜ŸjBàT‚qŸ‚“‘ï•/ú5/êm䨹m;xAM"ã’‰¼— L,¡À®@ö[÷ÑBaR³|ÿدÎzD ÷‡!Ë…â¸GêŸv"®Éìé 'y7~VÊùyñâÓ=2 Љ²$|ôG\ë‘mµ%ÅyˆÈp1ï¦*o ÖLx»¢-³rë")Ä„µZ·1êR¥ cˆÆ?!¤­ØÎÞ·ÍÄHt »„± HL˜Žñ$øn„¹’3Úû8­(í­©‹õX<†ãiž'&c)$ô¦”PJ²0 ¯c‚4nNä–íÝtÙt[Šóäß Bû> ñÌâ’Cm€ž#ÝG–¨ÐÑÊÝ6©¶{cÍÛŒüæ$·£¼óÉW©uÀB›JN~'_MQœ’¶£Å©Ù¢‰¶˜æ¶9)^3•:¸î(~âAÆ:Ëzí­×o·cÒȺvÚ$|4ýÓíH…24G0ê|‹qqPO]ô3×dè-©R X»_]KÒ=cíÈvJ¤˜M%ìv˨K.g'ÌcV÷Fð•q?äeD¶2^B\eÇ*b!!%XR’µ<„¸·®}Óìm87÷÷êºfRª£GuU¿iZ¶TäPœ!Ɗʼ¤zÐ(h'ÄŸˆó*mS¶àÁ‰w3Y›.!yqEXó–Ï^€t¦ƒT]ɽ#¢tâd½ææD‰á)„'¥¤§+ñ â‘¢û¹úÈrcö®VKc¦x-é’[' â¶”#²áö>¾™%ƒa]m8–6P¯ãyƒYž†ç9Ä(´ÚYASã‘Àèàû¬¶§ÄúÈ3^¢‰³fG~aTtH¥6O“Å׸‘Å8ÀJ #éƒý­I³7Õ v ;ƒ•©¤®D7„w]ó(¤(Œ~i@Çûïª ¿¶öÚQ_½7<¼Üm¡oŒ(”yÁA9¿MeS}O:z»nî6l ´ _5ÄVAü.§˜ï9=qØÑUVXZ§äw$zF¶‹Í 5ÐÜ„]xVÚÕÌ'éæ çë æ? ¨v<Éï LÉSž2SsáN¥`ž)q-£Åw–r“Á#¯7±êÍ|;b™ÓZTå˳W`óÑЂäK…rlã¯D«?M"í ¿2ÞÍéÛeVŒÖ& L7ãÈq/sÉIcÆð™B‘È's“§‡vþï­”Ü9)}U¯×üÔ»ŽI*Šïye%ÔAŸPA g@6·fÖ§u&M§ÃQ>µOø%Êè,ü q]-KZüÊJIõ#×éÃtÕJ†ìz8ne³MÁã£dˆªJsŸ ƒá#‘ú+G#\ÇrÝ3¶aÉý‰Y4Ú^²œÓf;Œ6¥»!m6Gxô $gÓT¥üF¼D5ɺbØ‚ ³]5.0áV2§ yZÔGÑ]zq]æÝ”Ëæc™×Nth¢B ©¬xcGP‡8תJFJ¿-cðb¨9lã7-еdèrÂÐÐãRÃYQ%|†H8èp3ûÊùuñê÷œëI[mÉ­¬?§e-õ«>^j +€$“Ú¬éƆ×dí¨ƒo["\©Ì²RÌÙNºñÇ>o—oÃÅ„N΃Vçû>öB¾!Wý¨§ã¸XuøL¼‚Èü.%ÔDB” 8åÖ}¬Æjé«Ù•© ›æ":‘&RÛløN©JzP ö9Õ}»]"²ÆÊ¦†+h#“ uºÞ 2ÚrR¬¹…rß/æj wuÜ]"=“ÑÍwÊÔó6í ýer-†€Æ2@ãõ#@ÑYv\ROy_¥¹*xB,eØ ÇzC\p’ØmNy‚F<ªHþͱ²¤‚ìšÆÝcuJ©HdÀv$O#G²¼g>R@ü¿SîiËÛpSTå¬Ç¶ìæš*n$l¶–Ÿ-­C‹E•Á)+’{ÁRzPV¨¶švG¸ÚÛ“d0‰*ZQSçâÁs9Y S6;8ëõ ÏA¶`·TýÒë¯6üy\¼Vl,Qáô€¶£ðB[ôë’z>¸×-½¡¼Þ–W“eÁ¸E0âBu²• qRŠÓP R†=Æ5Ðî©Ü&âtö¶â$HsÆjÎʼÅuÎ í!Ç’„­#¯r{QôÒáNw3’“¹6¡³bSb:*Û@àç#æRóÆM¥C׿¨^Ù5{…Џ¬UìÉ3UZÓuÈR'.:·–P§ *A!:eu;±áЇ$ZZ´´½Ãn ñš#øÞl¥Ô„÷ǬœŸS¯n¬¶ÜÜtÛ‚-uâ¥>—y²ûΗâžÈÆ{#­—75›{IùU¦8·DéµËr0” 96·¢•8®QÑÐ4ÏÞ²âQA¯W1˜‘³ ˜Aïˆù…–”}ùûþð‘6ûvÔݪMk7…ˆ°¾e*n‡T¬qW™`#ñ$ó9õ÷ÓÄÍÝe²+ÛD Åobê‡+2’2R ÜÏ×ÚP·Û5NïG²Û¤ÆšßÏbC„'>: #¹á¯!~e8’=ˆï@íá½{Á‹èh¶¨«k‚š%ÉJ/ò­‰‰ÊF О¦„ßlö&JŒ¨ÿ¡Ëa 8Õ;-J|0?S«!J9è«×½VÛß5°Se «K‡•aòâ=Œ—ÖƒäøëSO8N?<Èh]ଥœ§SÎä[Þ ¸Ê¼Dœøke\OYç}ÔŠ˜4ûV4Š=¯")ï´ëÕŠ}¸í4¾#Ìê’ʸ¨R•g£ØÒŽðfÊ=zùÕWÛ;ǘZbL{/™qÕ“´„+Ο§0U‚}“)þ%Ý3‡®S}à>µ3"]\指“ø;‚A %9öV†ÂÙ·¿~ÓÝŽO¨~í­›ÎJ\‡ìR€Ù$„û‚põФ®}½â—7ÛzÚ°xp ™ÐÝ%Ç» £‘PJûó¡žòè¸ü`† x"ûæ,¶ìWÛi)Tf$¥g* е¶JO¯3ëê4‘í«·dªfâ›>ò%£ˆl¿2[‚;¡‘ã™@õ ÷õ=S—ô¶>êÛTóò‡Í¶†êÝ.­Ì‘…‚O'{h.D›³êw´èà¥ĆֲßË¿ŽÓD%*XÈÊO,õ…ô¹[‘íõLÝükFÚb²Ç圗¦°]ˆHG„â€3œ‘ëíbåíâÅʪâÉ`°ñVïÊX”0Ïà¨ð½qúÄ÷ï­3¡ˆ?kÛ*Êœ¥–óíE.)Ô8§"òSªpò8JÀ)âr;Ð^ÜŸâßѥ̓øG¢ÿOkûtøˆùoèöÒÿÃ៉#ÿooûu–wü/ÿŠÛÿç=ýƒ\jö°?=uïð¼gož÷ö r©øÇïÕÔÞ`ÙOÛ0l¤G Ûe–ôTÈO“”qá¨ñ$ã>„ƒƒŒ-VVªÆèDTÛ¸V‡‚ì*'0ˆ˜é<žñ€œ€H ú«ûýǺ«g]6N$&«QÌ)CÉ”¨zö“×.Ǩ8ŠÚŨ7Eë´™OXx1ÊOd`©,¥Ð2Aæ’~™Õ@ ·µ[‰WÛ~çmÖ8—³ųZÖÛG¥)ŠÓœû«˜è`hî鯺Pfl]ébãÑø©¤ÎLJIäFKe“áò'—çÄh…æÕ¶NÑ ÙÉ‘UÂ,àÃD$g¦Ô¤ñ åè2Oçª;ªˆÚV¢Á& HDrÅ´¤  d 8ÒT•zž”êT~ƒ:È—&, Á¼åmèÓk}Å´ÄÇJÏ'’žÈÌ@ï[ö­ýnÔmáºÂe¢êòn#º¼rOˆ”§å’1Ð#*ü:ç¶–ó¥_×¼ýöå¨ Ìkg"CCJå‚°³?T•a£UÛ·ô€.À™csÆ+.Ä®uM#”] %ÂGa~&sé ±{mó–²ö·cÕ·=·\”ìæC+tHRHà ÊT ?X9Æšë·eF䯙Gtû¬6Ód»¸Ž¼R@)!) Wû W^¥:_ºcʆìKYH‡¾OÊ‘"–S òo¦ñÊë³Äþý.*î»m©WÊÜÉL«Â¤™.VH}L¸{Êd ç¿Lh6I©ºbòj.á­„ÏŽûñüœh‡3êU韦¹Ü;h1­Ü­Ÿ¹bԸ힕!™èšÚq’¶C޲OàB=±í­»k~c‰ÔV0\gÇ[ó 8âRÒr<á¶ÃÍõQH>Äèçí{0_޹öa¶°Üº¸0ÞlOݵÖ8œËX¹#pS¦ …¿˜r<ý²È[o `-ÐÛD¨cË…3Þ„ÏQÕ3ªg´ÌǾiÚÑä0|ªE‹‰HòúàzF¶ÞÜ¢T*ÙrÜG–µåÚ©s«c¥Õ’® ¼™Ç£dûõé æ _üTØPi÷Vä`ÔĺÚ+ÝHz,_7IS%dò=cÊŒ{2ÚÑREÜÕµôömKÈZ_nJ1ž*íÅ6˜î¥ ‘ôX¨êíÝZcÜ-½É”-ö‹Z\9R§a%¢ ‘ôäX:½NÂŽ§«ßV6S__… É´!(ƒ—C-)àãö€ï@²ªÚ ±¡¶æÝ­~"JKöOx¡D¶•#ÄR’Gìå'#½;ZÄ·¶¥âæúž´]¯L7b°âPx¥¶•òÁ=ë\£Ùwµõòã±Q*ª:Tù6ç¡·žWºË¬œŸrÐèU&у}ZæÝf[Ö\^vCï»}Xt«õÓ”¸úHäG™ ~#í·qÜÓ=ýí¾üï¶Ì'_ð”—»åÌ´¢ðB³ø‡,œ´J5†Ü¯ÜÛs•r—]Œí\µB(8p%¨©þ¾.B}{Ò Ë6t”IÙò¯·œ@Ì |—1Ý@$ãÇ+â¬à ”ûh­nòzCW´Ó³~ÇŽ—寇Mq•HAJO°ð\H]ωWín¨3¾kbÕYLî3%çã:ê#òÉZHÅ(uäJINõÑ}½¿œjKvÎ}’·Ç¨2²@ÂFB‘„å=aEÓŽ…Tng <"G!‚â–í,Ń¿ÆL5êr¥ÌheĽ¾›·{‰pè°Û-& Î2¦ÁûÁÅ(ò«*Cœè3Þ”s‰ m£M.Qm˜2#?_& ÀñÛ«p•¿Bsìé£uÖ÷PÙGÙ;:hJ£É/ÊÃò™Wª–䈨_dÁëÛ×IÕM9¹7 û©Ñm–ãˆ[r$×M†”c-:Ó)P±ÚŠp;ëL²Í|™ÌÜ »ÓyM ÑØ8ä¹IAåż¥Xô‚œg×½U§•I·m— ™•ðåÊG&‚¬–óÒNW$ F}”®½»ÐýÄË“.¤ÇÚô»%‡<þБX™IZºæ0”ìåX 롤 ÉÕwRc¹¢t&Ó!Hq©ó£*R ²×%HW· ^¶G‹C¢;Û.Eòo[–˜ÒàÉP“’— Pã#A@h n|“+²ƒEyòjR~R³i2”µPë§š’ÊÓƒ€Sß}_ÛJ~Ö¨t–q_?2QYo\RûK-n-ø !?Ó¤Éö–õnÅ•»æÀ‡nåº"<ö¾í*G—2 R”òüJäN3í­Ÿ¦UßÍS¹`_MS*/CçÉÕç*JK9pÿŽÿ=FlKnJ¡Å›tg[O1G3! Ïño)j$ŸU£ÐúŠ9³"’$©ï˲ۋµÛ-„Ji}) -´€1ÖT¥àý4~â y„¾ãÛ}»C"­2}•dó<$©-\ûý:#/rD´¦°qWöU¶éò¦déñU ú© q—x×ë}{ôÐs­ÓQ¾v½¦á“¶w…kŽÇã]¦¢ 8ä´…„޳Å+'Ü \Úû£yÞÙ+wnZ†¢£ø.]7]*(g‰âßÃèg¼ä§ÓèÅÌ[G«`Ú_©¶`d:ë¨.>‚Òzæž u§Gº É#Dê6#–ŽØ3e2–µÙ><)H†Ìf|4ö”¨Ì¢²¬öxçÛÛ@Rk©æÌÜןÞÜ,È„´±[&#í¥KHPmÇ+ Î|è õ€um{ž¶ÃqV (“wm‹µÅ'ÄLu>\4R’B³û9Ñ {¦äÂä -ëP˜KzJ[ ñH'ïRd<\J¾¡HìÐé—çJ®¼°²§Œôv] Â,‡dÍÜ© §®8Ç¿®€vÑÿJ¡A«Û¶ƒQAzS¬¥¦SœºóI+ñ#¦–žý>™q·Z䋺›zÙ¯¼sòÆŒÓIiG¯f:V•(äáQï¢N‚™Ô_nQÈÝÕ3 ¹­’Úâ¯qnáól‚žÿ|‚1Ös¦k7 j¹2khllâ8éB™©‘òá*ë)–Ÿžûà@8ô: «Ù6ÑÓ#tnö!*cj4Èjµ¦^ZpR‹<Ý@>ž!>žš¡½Øøc:®E}܆œeô?E;µñœôËŠJ[QQèœjýÞù½ðì;,5–C><ÙaÙ I*,ð[kâót}}4_·Ñ.ÚKt³ð„†ìke´ÛŒ~6ÂТáÎ H'Ó5MvÙz<„5ã\رá-d aÀÓüÓëå.œ}ƒvï¡™¶¶…]Jcоԉ.-%,„/’ðO$§ÄÀ)—Iï²N¨¹/t7F‰VQdÙ"© J¡CùwÂÏ—È V@£)#±í [–Šù§ Ï\ÑJv*¦¦2”‚Ú—ê\„Êo'¾ÐzôÕˆŒV3\µÜus'AzÒ‡š–Ê T¥¿ ñ)'Õ*Î:ÐjãuNð.ª.Å;Ž!´:ê’è1â‚S„Eñlààöß"=¶[îË©ÔÒ ZnYJ˜…©ÄÔÒΆ÷)(Zl8N|Ãéï­¨®Ø5[Z5¶ 12C‰bK¯W=Q]=%µø øˆõÈ(_·X:Jv²§x>½6ìЩ":ÑcÑ2Y!9â’–ŠT¬ŸÙ¿¿@^ºòÊSñ?N‘g\Ô2Ê'¡¶Z+l“à:•ÆRÖ|½‘IüYÑµî› zú¤×mjÈ¡çË’b¶<`ëI)%„4òV·zï’RCB·=¬•¡¬ÛW[~M«Ê.†\‚äb…¯$)kþP eDœö7÷”²¯èé¬D",^D¶˜’y$¶¢Üœ§Ì@ þ/}zÉ3¾!Ç›dåZ£ÒZn,§Á¯à2HOáZH÷ðü¾Ç­U©¦ÚÎ;6R‘ò°ãçœyqaHùô$t”‘nñW±$œcUvÓð,vT»Ÿú6wlxξã2%¾•!ž\BÒµ: ‘úÙñ1ߠײ®§mgd¨‡Zï_W<_¼ñšåް”8æ1’žûµwnÍŒ+ámgÉW©À”&4x«P<›uÈìp)ÊH<óÙ:ѳlcÀu0!Ó1µ¥ÙžlJrÊå­°žqã qW¾*ú“¦ µ2S­Õm½Õ ç%qLYÏw-JÔ[€}zZ“ŒçF-%ÒÁfÂópìiH0ˆéSs"‡TTÈzIR³ês‘œ 4›¿-÷¡5§u×RÈKÌ="+ï©%Àç9m©UÇÊzHÀF-™nêLK™?¥À…B\z1-„’AuÉkR‰ôò‚{ïF`mW¯¯¥J¯¬³«i‡Ì¥¢‡šRÀ-)N¼•$¤¶ ¢–yœµ®a¼ÚôßeÑßUne"KL&4 œ¼’?‹Yëi)#°P’?.´l7ª>/¹&uZn|”ÑÏˤ7Ë*8KH.§9ÊT—²r£PÞ÷UÑ œ´m£8µ£”v àåÕ~4QÁIIÇjJ1펆M\YN´¬™N˜»{gÆ ðÑeC«‘è°†¼'Ì}H'Ðà÷ª·¶PæTJ™yÙ5lIC-<ÓÍ%Ôñ ¯ŠÛâÊÏ…à•Ž±Ö€Ôf™’¨²^²‡tDüƒQZzJžì†‚Ýâ- z¸… öO©&äW îÖýåã;EiaÏÒ +Ö™ ô$ºã%M¬fÈöº “E–Ì­–¨¦2_e†Ü[2ÖÚínIAŽ÷A çBæUJ‘öR/).b7)Õ¸˜–ö ®;|3ŽC’<ê>œUêAÈ΂åõÁÄì±Mù¹ÈaéÍh–S‘çð†è¢A$ž‰Ðföý¢¥mëjÛq:©¦¼(Оº… `Tb­Â;O¢R€=ÈÀÖ?¶üfwÚ£C±žÝ™-8ßÌA–XKÊKn>|D2;¯ÚïW+èåI†æ×r¤;%KC‹]b•@ÉI%Õ²‘ÞG,«?S t²b32jZܧFCq% ­ÖÚ’N8¶]çÍÌt Rןtƒª¶´ª‡sn˜R(lâË@mKr¡ã ´…~°µsÆà{“¡òöL8ÎCNÑ~m…º™³¬c-´¤•-Iù ^½€Ìé>EUŽ4g“{´¬¡Í&8f:œ}”%9ŠÚd$9œãÄo^º›hn•Á]cGÁ‰)^;l1á´·–›“o¥+÷ŒžúÖ0®ï.#Õì½Nü˱-.ÂþS€· R‡21û%ö“¥ª$ü_fÄ:Öž¶ÛõòQþ/2+a ' ä#8ÚT¡“ÖG ÈõÓôJM·"uÌÍÓ ÞD%ÏUjâÒ y+l+ÅÇ©(QZAÉ>š ·–ê†Ð7[Òå4ØCiûHwÅsñ ¾Ê™ãÄ‚ŸQŽþªí]nXáØ*rýÚY™O1)µ!Ä §ÌèrB<2 ñ ¿›ª{¾moÀ²¯ÞT-²¨ë”̶ŽFRs€Ràl+àò¿}“·šÙV3Õ¸6úæÈJi´UÈ>>Ë‹jy¦ÜPõ#Îýú÷\v+¬ mÝ¥Hd%¸³ ”xj$eõJumJÉÏÞIÕÚk«›©Qv¤Zgrº8rÉ’Ÿ–fĨT•²H#Æ9rǦµí«éÕt0é‚ý➃d—B¢J\ ™|‡Ñ@¬Ž“õ•[+uo{`äªH}æÑTä‡$>ñý^>*ÀPÇì ù‡gAë›f‰Àš´ƒSeJrqD7ØeÂ{O˜Z¹êÓ××B¬,¶Ã7³¶í~Á©ž…¥%ÙîU´ñNZ¹AJ|Ä×r'Dªm­.cîemtÙ¡çX,}¸êÃc>L‹=ñ©ÆXÎNÈv,׈ösS×<¥¨Nj-Üâ Ãð¡<yJšIã:ʲ¤ªÜ²n#lú˜±•à!ù70Ösû´6˪AOªApÖÇV%.rþ&Ö*eõ…ªM<ß 2§9#‚JâžC—áR³Þ ü)ôÀ×B”Ä©s"ÃÝ»Uv‹[F[ÒS!(ñ€IW|Ì„‘ŒùAÆ¥XWÛoÊkJz9•°¬±mµIq…—brBKJP! §Ížóêpt7ø¹?–|:ÿÎMú{Û£»‡¸Ç×Ðúè'Ãÿ”zÿ0kûu–wü.ÿ‰Ûßç½ýƒ\‡kþ1ûõ×ÿÂìe½þ{ߨqý²~ð~ý]E½ñr­¿+mÜ%ÛUÕD.½ -ñ˜rSåe89ÁÈôÉãWboÍÖkcÒÖXny²­[©mê”>¸ D­ðN@É䒱Ƭ½óKÝ›U0á¦câÅõ!•!* "¾aôP ý{§aŠÿr´ûòëh^ªArd6cÁ.>â‚r¥9â #®°±Ö¶ª¶¤=÷1•"ôÌG„”ɱ.)d`øŒ¶Ã‰ úŽxDZô!·• ²$-ÍÉqLº×좡åNH*- … Ä¡‘ôÐØ{~޶í‡çÜÕ"4öÊã–ÛÙ}GpëK ,$çÊ3ô:d;‰Ôï9)¨51#Èä‡X§3L€{ JÚJ’søuÞfÌÙ»ÙÕ³·îví„–c0áÄuÇÙB‘¦^RJ†rT@>š)Q·çíŠÁ0ÄFß…òî164WåGaÄ`„¤üñZ;'8ë9Ƶnèó©¥>%5 SÑà)Q,¶~Îd©$Çp‚}B•1øN¨hécJ³Üñ¥¸çŠÜÄBgt똆¶HIV8‘‘ ¿M?|Ýí™Û¡‹fà2ÒQ0à ’úÒ•Ñ0ÒUƒ€9¯ ïWí6ñ¾ Kº|ÓÈ”òg!¸êœê[ŠŠJƒe]þ%'ú´žÜ—›Õصr.^„Ürò˜ñ¤×)–×ør \ 9Ëâ§'8ǵ՘4ò\¶klnÈöf'˺Y´wøFN0¤)•’2AYÿ8úè?µb‹Ë9L&s2–Têù‹yò”’¥%×\J_ä:ãEë§]HŒX§¦ÞõÌü‚›[ð+J_!Á_0P—“ø”¤ £íM²¶ø|ÛlmKí½.Â!y¥0µ:Èq(ÂÛO¹Hz ¥Ø»† †cnkjÈ3[L‰/A”†°JÒ8žAdç¯#öNpt)ÿ… «Ø3$¼ “&\?´Ñ€¯*~ç‚x€ Ï%«'²5VMžÏÝv fñ›³Q.x0j娣JŽ–€ï¼’¬úvq£’öž×Ý®@mÕ^Ý5! H!ßÖHÿ+(<‚¥$÷æN@뾩ï8•õˆ4³7>r]£‰là`ßuµ#8ìùÁëÐè=¦¹v äî,¤ˆˆJÜj²¥èüä6²¤œd–Ò=ùz¨»øi™„ËöLòÌÕ|´EISŠïÄâÚÑ£×\È­’óÄ´Ó–²]mô¤ç‰m(ƒ„œ†xît'â5ŸèÄ6%nÊ™kZ‘!‡>Ï—1¢Ø'ßÄ A à¤þÑ^…S\UA–¨”wq¢4‹&dgXC?€G•Õ4…¤¨äs Pôï5±÷Ößrã“jXxãÁ¦á$©ÓþLÇ1Û*õþ3Їæth¤>»ÈÒäî e!¥":+Õ%$:IˆPu)Œ’öï"­wňé—×x:„ºÛ…2¹§Œ¯çqC­¡zþ/Ôúƒë¦)—´ïÙ\9 dSàJŒìÈÂ(W¤’RÚ¼C×IQ8Õ‰Lų°^Û»‹Y·l$ÈàÜ·"DqÂÒT’P”…ŒþÐÿ­ô û\|Cžñ‘2âD_”wÄ?hHnHÉé·c´¥(ç'³ƒéÞ‰o* ÜZ?{XË(k+[‘$RÚ²xDÞjÄäÖtŸ7mÓ¥–­¸ãD‰ı"b£EZW‚<«q‡2ÙW˜yÊð=Æ›k6œ;‡œE\DA‘ÿŒÊg!¼“ò ñ^yòY'w©6³qè“yµcÏ[èQ†üE/¼³Ä„>§9zü äv}u¶ƒáÍžÞ2YYötˆÎ‡cÙ2Í”GÜ9õ_ˆ°Êp:äAèŽÎtVûoªž &[SW5Km¶¶rã¾Â ¯Ä$)À’I8Ç]di~²+Vmz´± øñƒñw"BÑËψ>å””åÅ+Ð÷ 3Mgº7&ð“U·ícÂåLD¹ b`}ÓÛ€%¦RˆýPIõÉÖÈÛs{nŠbý‚–šæ’¸-ËHž” ²Ÿ¹íx'ø°=ºÒË—OØÊ©‰²ÅÍ|gžLV!“)¯ ôS#‚ú)ºGOYÓuõS,Ù ÞmýÊìè²Pû3Yºx©³Ä…øKä› É?„zk±D'ê+æ­V¶1*eÿšsÅmG¢´2ì†Ô•z£Ð}µ~¥éõΊúŠ­ã:cs[?>Õp–ðÁó!žËjk>T%y#×L{qIœÝ¤Ç6Näe¶¤…‚_ ´:™H)OˆG²€$cÐh,]“¹›žöâ‰idÄÏ™q„–ÚR@ïÃ.òYÀ=¨lPkå|GŠ&1¹gÀT°`&ÃŒ‡[IÉR–Â4¯*Zß¡:ÂÓqm‰ fŸrè–m£Â(j¦T'œ*ôO¶áV>œ±žð1£(jfT¿·¬÷àÜ”æe­ä;-mIZûÔ©–ϧ•D0Ö£hm½“¶bÛU³¹àME Ïë òüEÁ‡ƒxõï¬û}°ëÛsÆ„‹•´™!a¶W·åBZ†? t©9$ž¼®`ÃõÑïbøóäJ]œ›õ©H-\1O!´ŸâÇ"…ñVzèÛâÅ”ÕsÒªmz”µZÜ èJŽrò#AÁÀäpp8õ¥íýµvµj·tjyV—å„ËL(V.¨à8U÷~#iü21Ë@cjîm¹%Ë6k°¥†ÛIàâ¬Le2£ÙË^ƒÇ×…¨ûw­—l)6Úå\nù5ì$´¤ød¬8RH+iÕd…ªJsøRŸ]#׾̹̈́¢›s.³™TèIs€Vx¶TãJIò÷€°N=NtqÞ¯íØÕöãÙ–Âqï·Sðâ ,á@’~è<¢=1 ÕëêèîÓ^ÆbœB$¦$y1IS$þ8µ(«Ø†Ô èdg§yñéT´àN°›a`’–Ñ> ³Þl‘Á·¥ rSïnÜ»’†EÕz«¤&¤¡Rc´Ä˜é[ˆ'‘-•·sø}ó“ë¥é{ª¬H“Lv­,¤ºJf¸LBž^¨BÛA+ç I=Ìvé²!ˆ_+ak É%—^›®si*8QÌ®3cþÿL颾®ÎÒ Wܶ«b™nD%,EOIiÔŽó“„à’ÆŒGÛ4éJ`À¤MlØÉ.AŠç)Ç£9¨}ã*ž¹r^p4²cíèwók©¶¤ff†YùÍÅ:Ü.c¤6è ÇTsÖ}ôèçʬÜ5I¹­±š&¼$GE\É+)õTµ™Ž!X´ùµÐIÛÿtÌKmÊ©kV¨fS‘#¯Å÷Ž–Îyã’1ÐÆIÆÍƒNü¹ƒâ^«† „Ö:Ï'ʉ沥(àrHëýšÓi·cÚìØoXPü@°(xÇe¿µq÷Iæãe‘èz<}ˆ$`JÝ×û'h2+¹·rGŠóë~Ùâ€;IB8’ š ç ënÐu;¢­ÙÓBĸjµûF%Ä&¢g…·ò¸[™#òAúúéº.ßvMm|›í‹¦*”йw-¡Ô¤œxˆhÃ\{r­™·ö¢j'ÃØûqóc(—+v©æªCÖ¢MåØ*y*f;gº&²RŸ;©JДºŸ~)o ¦ˆîšXõïUÛÜXÎ}Jq|“¹‰â$z6Y'‰Ê[)'Üh)í}ñK"Lˆëª§\6¼4q†ÒåxϤùT”¡×Û£ÎG"O¾‰È²MµUmU<äG®»yhL˜áÆÖµ!CÄ爩Jù¬‚}³ë¡q#ØæžÝZv9S»CqÙq ôðÊP^Æ;9õü²5}[åt•võö‘Y»˜Z[±cÔ»%Ð×%aan4Ñ,àv Ç}~`>"Û\×ÖÜS;Kk¶BÒº5Í>ûŽŒ §Ä)kДã¼ö5[omJºÔËQ·îlì[P”ÀU³.4$ñ RÒ¶iÕœôqéè3¦—j&Ø×¸ˆ;¢Å4ʈ¹‘vÃæK^Ëâ§B<@=›=c‰ë9Ðͽ`ª}¦Õ=¥u¢ƒÈ{Äzc#Il«îòµIBP$„„à‚:ýœœ/‰h<Ü›Ús›r¡¤Í“lý“éRa8ó>#˜!K”EKiâê-'êqØÝCWO2òÂØJµMÈ«Á‹ ÖÛn'Ì¿ ÅSnŸÅæüGËé¦k­ÇSGµ«L:˜•“VÊÃ¥©ª´ ¤ ­ <ãœc©±fx唩Cts*Ïe!#¼`hmföüݬÔÉ–vŠr¹ÇŠX—â=ÅTyŠ…ç# ÷Á/n鯡«rÓ¤øÂ!@i„'É‚ú‚Ü^:ˆ?C¦mɼª¡ØüÀ¡¦¾iÔ!¼?%¦ J°â‚J€ÁàB¹ˬçZáTíéÉvdºjÕåf½bìä®O?º@ä úñ oÐhvt[kŠfîµX8„²Õb‚Wâ'®`º†‰ÊC$¨g¼ Ý_kSØN‘>,·!ÃX„óh!Én6 é©ëKyÎrB{öëL;ž¶‚¦æµÛM¹bðQzT›&ëØä‚!2¬þ©zF=‡¦‹·5{]2$Ðn6U¸d¶êž§°Šú„ä%-º”+—]÷Þ3ÈÒvëÕíI‘cº¶Ô…°Úc4ÊÝñ–ØHàq_v°Q_·dUÝèöϬ­s-Ûå[% 7ò*¼qÆÚçØZÖ’T{ÊR·0éôi­­zÞ5Ó6TÿÃA¿ÆçY­‡R¤‚€ÐWxâµ}@ë"hö¬‡«&Ð7²§VTL(W‹yh˜ª—îP°a«’þ™ÏC×@„›Š]Á ô‘;qÌ99ÅèvìG–ÂŽ –·Åá…}qÌõÇeSÈ™›lÛm½ÈólºÁfÎBK  t´)ˆ¥°2GnŒuë묪ê>°ëSÝÙïA”ÓE™ÐÙ¬vjV¼ñl¥Ô·áô@Ï:Î4©]úçTõYƒ¾+ÒæXºÔyi8à†––›B>ª*õÁöÐ2+bî;ERI‡YºÈ6óh–§ßÉ(%YZƒ-6ç€B’’1ÑÐ]¹¹£PKBü:%Nk&cÉqo8””ù›mõ-ÆÎ0 @Ï]9ozO­±šõƒ•ì¥ Kk¸j,¨ú ©l© ## ZOÔ(ii¶˜oQ=c!pÞd>ÄMÆ„©iÆ9*J›¼`Ñ9öÐNè®j•Žßi˜ÆM%öþUÖœŽÒðÁ(Œµ”g$)C¾ÈÐk—o6«p݉Qa¸äeªl·b·11Pè%KB†µwÑ”Ž:)]¹¬ví´gw*¡ˆ‹ãpX}É3£À†ÛJŠÿTd‘ôöLíËâÙRκ¡Ÿ&YeÚû!1ÈHo‘Ámn6 DŽÈ ¤á>ú¡·èå¿òÆ-í¬›ón:+AlóÈBÛ*Ie9'ŠR¬«M4‰—´É1«¾,Øó1–êk"HŒx}û’ÔJxþÏŒeF™[VöñçµµiN! r-y —ùèJƒèJ¸‚AY<€ÁëŽêÕ;4Ô)ܤØKZÞz¹öÞa³Ã)<üEs€®K÷˜ô 5ضUÂâ=Õb[v3 K¶râ0¦d×6ø¥JNp‘çÎ=N´îÈ•NìŠúú ›K»j”¤°ü÷¤0pJÈd¶„ œ‚Wè@N¬#}[Ÿ©¸fÂT'^)~Z¦)p+й m}Ðë9myWGR´È• ðâfcgæ ŽR–Øjg%(õÉ^™âsÐyµZM>ùVðn8©q,4^‚ÐT8ki`„(¾IR{ë%=þÞYæo¹q`ßÌ‘¹§­–[ËÒc8µ'Õ>‡aI$„åÃÌô1©Ñ­/›nÇhXRÜÈiÂn‹?ÄùTXKi/œþ 98Óu,ÚÚ=³býÆÙ޹MÖòþD×1Í\p…ºë‹œŒ“œõø{Ð"TE­Ü&‹ô™µN!ÖÊáD’†—)^© u$œç J=}GCAí8·ñÑmx“œR*årù’º,|# Èÿ9Då=çÕïjÖ§uYÝnMÂ:% D\;å!D@–Ò„ §¼$µË#×­.î›Z™Û÷o³Mm2Ö3É~W™Å)NC*à’qÄý0qp¯þ/ËAþÿç"‡ÿÌþÝÜ1óùhWÃqŸ‰ÿâ n²Ó®…Ñþ ·ÿÏ{û®;¶Þ'?]v/ð¹ÿÛÿç½ýƒ\{n~1Ö® ¥éÿÃ[h•%øEà u-‚L xJèÐïBSMºê)…Œx¢øR›uB3ò|W’² |ÈY!#‘å9ôÑõÃ~Ãwí(q¬U\ë¶Ž! RKcä%’r’¦GGßDlh†×•"¹Ûæg;!Ôº·§¼ü…¤Žø -¢‚1üåœ}uq {Z½ÇeâîšþÚ”¢äÊû'[Šr¢ê=F? së®}¼­7FÜ~é”Oyæd:YnÁ뛆žhŒ)+o8Î3ë뢗7”Õ$QÈ›EeñÎ5|:ÙqÔ_V%Å *'ó¼j¦ÙeçgOܳ\Ý5fÇÊÄy¹,…¤"›Zd)|±Ú”ŸLw ¾ææ¡´Êá"ÂDp•I®n,™8¼~H%]•{ã­/n˜{šMõƒ64[‚‘v T´ªS«ptAL†ÒÙïxúXÕ׿#5L¸qow¬²?+;jeDvËeÖÙPõ'Rÿ }²Ú4V¶`Y1slò#¬(ÙºÊÒÙ)%+í qµú~Ç¡ÐZ¥­Þ¿”íÛ‚|f¤´ÓIuñÖGâËn¼¥7Äzð.~º¿aWîK´Zͼۣz:Ó¶Aò[ÆI*q8B²: ý5MÝÛ·¦3ŠönïŠÜÖÓs`­ »×­ô ·ÙK`œz‘«ŽÞEøm K~ªÚÞÛtCOÁ <¥-_ˆ”€ŸL ݹ"fæeLím¿uötf@„ä8Ʋ# *>"¦ä9Ë‘8)J3ëÞ¶ÒÄØ7ЏbûQìKl„¶üÅ¥!ðyü0µÎ r??]y¶Âá6Vö²bÒVYW¤AÉô)*->“ó>¤ñ<ôζü6sn»²\´aË;39ÖÂí¥-¤œ~€ÞR 1øz#°Fƒ[û¯b³döÍ\3…ůe)%Þ9ñu§´ŒwÀ(äBzÐ[Ë+ì¸Õ•ßhŨ}Ä)û÷%%|üV}•2 €¬“œsu^SS̵°L'£¡Ò†£U…ø²\9+™Ê~œs×âÇGr~ ºkbD€ìÙ—2£s˜Å—ƒÍè•FHÇ`ƒ“ùMÇwOC m~áÙîU@w.W:…1™\ǘ ÄR졜àö4ýðòƯnƒ¦ë·6-…¹Ë11°^iCŽ$Þ3ÙëÛ½knäNÎn;uO©ÇZR´M„…)^)Ki(ë¾Á$û“ ³ÍÞږ̨õöQdYB Ïù…¦AqÌä)¹Ii>¾éAÐ=üC¸™´¨•¸*ë.¼Fµ}òÓö*u-?e8üôˆ½Í{-»iÑ*)倄¾áù—YnZBA%?ÁÈ9ÁRÿ£¡wŠî’ÇÈL®‹1n¡Ù’ìÔpѵ©\])8=¶µƒžÔub‚Ÿjι‹Pão¾•šWÁO.ÕÉ&Atò9§ßÕ9΃¤U›} -­”˜”ò-"¡ ˜“d#ïÚP¹-–É 8òG¾¹¥… ôíÉe>±ŠÒÛ‰RYšì…º¼¤÷j *#  úé‡u7 S·¶×•)sÓ:*Pì€Û~$¥ÓÅ`v•còÕíϵޡ´MüýÔ«'B›.J˜HÇd¤%ÀôÁRG§^ú ;‰{£nEƒºèn¦µ´· ÚÛ‘#–IPY[«èG5ŸËW¾%5u¶÷$Y•r§XCf0pÆ›qlÚšÏYB™+å€;õóÕ- íØ¬X›Í¼Ðy%™¨ûRÞy´ŸÃÉÌúÞ¤{-î+˜qaC¼§­inLausÒ ÍwæÂÔ¼Œ„!¢¬ã¡ØÐZÛº²~ÜT+‰ª´µuײôMÊ•¦ßx6àGg §Û=kЭÀûU6 íÀÝk!Qçßù˜å $)͇@P'8qJä02=4BÓ{E«U×v4óh\w+XGŠ€:}|ã6× ¯4¯×J4¿fÜÇ2l,wÊf¾Úl\ŒC¥' m^#jGù ã}]½³÷t'#n8©¹z$7Ö÷Š”¶Þ[ÆËOÉZ\Iè'’‘Ù»¼ì•½(c «½ä%2L½¾—”ÒÔx¥´¬$¬yNRUŒã–ªî«ŠMŸoiµþ^ñŠÙ(K¾R¼_•lU†œCmßâÊÀÇcUપš7éÕ+—·5°´Ø>jµ%µŽú™[}SZÕ-|Y£ŸÍ¶‘8%_‰Ö”–V€ Æz>ÿ]e²bíf÷Õõl»{»?‘Š\ŽÌh •d•pJJId£‰ïÓAºÂ÷clÆ‹†ÚrSŠ žÄT;%ö¿Y-…(¬ÿAÕ)[Ž5:ì´bÜùrt®õóòá`‚³×@qIÈÉK¥=ç×EµºEãÿ(ªHì²TV…8묶ýeœy±ø¸‘×iW½ ‰Ì®«)_lB’d†ëaÎ ­•î†Òð®ðK˜ü´¢X³SWÒvÜr}d† VWl|¹) å<ÜSέÄwØ' g¯møci¶YbNí©Fã%-F‡z¥ÇZ³ø<5ÁIÎxùG^ã:?³Õ¹'µ:ÝÚ®J瀮2¡¶–ò;VBÞY$ÒÖG¸B¦WßWÁMãÕVŒØ×Î ˆó’û)htAC4¯U%CAÔ&¾©T˾EÄã¶TbÈZÐÓ‡*Sl¼R¡è;I?–¹t=ñ¸gAké~o.·É‡^Jc€”©JŠ£ß} t{?ZÛ…Ë71!Ë2#µ&; %+¼D­Õ8ØÇ}x‰PÎBs¡`ѱ¶· ”׿BR&É1”²¤þj~F õ$`{ñ>º³¬j.«úM²–M,Õs\Y/Hq>ÅÄa(SYÎQëÛ[µç5»W"íœÝ âòˆnáàË@‘Ñ}SæsÈ”ñ#÷íª3i“_G1»85–›f$%JaŠréº@#îÒ¥´¢N=Oî:_Ü&ßbWUìݵ¹(Öòã©”bµà·Ÿ7ŠÔ¾ˆ' ïÐ:\ü:2–õê÷^éL(”B‚ãŠJв• ©ÏO`F=Æ€n‡'oÕG›òörŸûY2Z’ìǃͯ'‚W·¯¢kK‰¦³©~Óí†X@mNÛx¨ ârJq¤ç¢S™Îµ=*îðÔ&‘—gBeblجIC‹O£D²òø‚:Î4>ùÞ G¶jÞÂ4ö\m1a¥ÆŸJSåÏ7ŠË…G¾EHö:å7×Û™W"XÚ¬”H3"âC AlŒ-î)W™8àï pÓ•µæüÞ›~[q謣sX6VÚ gþ->4ŒŒ ç¼$étVîJº+˜íÆ“Gh„•´„Ø¡„¼Öx%¦Òž '$”¥XW¿ õ›Ûn/l «yK®žìÂÙ°\ÌÄ’áO|°®±ûJEXÙ¤Z·e" ­‡Ë²ël:†aAl$vŒëK)Ï  =œãK›{pnkJHtv[Ò¶ÂÆ,†ÖâuÆËÌpí)}>ÈÙÀ9δPìÈÛÂS®[>-"8V¦kÚšëØpz”¾úTÐŒþCAäˆ×0T±K4æ=͘wëJƒŠiZ•!JÏÑJJUôÉÎ[D´¨ÙMNEã6µ-<‚ë,UÇR–¥‘‚€• 'ÛD÷Ö€ÛlÕoOœ´¾Üªöu©Å†Ü5sP´°ýûh"ïd-láªû6’+"»=‘ a$ùÒÑ _/¢4Ã>ÎbXû4 É[a^´´%0Øjq>¥. )ì§¤à §HêkjmÈ/ª,w§ªl¤?ˆ¶m2˜Î,‘€¦|7ù§NqÞ·×}ƒe`ݴ͇·_ŒÞ[zDùÆYÆV®L‡‘žýV¤“ž”t­. }{†Ú¾âÚÂBÚf+HW\z1ZÚFH=n’7äY¶nâ®#²¾u* Á·”äƒá’ ðyðr pos§½É»v¾Ð·E*vräÇ€„ªµÖQH|,øhåæG¨¨}»:ݹ~,L‰@ãô» êŽS‘[K\ùp–Ôxàù•ä±ÄŸË> µeº&Àê¥íÃdl¢%ȱœ}*‰à‘Ž qçòï* ž¾¾„v´?ˆÓè ¾ä:õ²ÒVôu±fì‰IX츇¤¤àú9Þ0F4¥YO_W錥8óž*Ü‚ìw‡5)>…1T‘“8lÿ4vt÷f="=Í5T»&|W_eÈZŸl4È!>#$+ðœƒéJ§r½íÜä»VárÉÄ6û.·á¿ %jQࢦ†9¥vGC8Ñ©µÛåý«²Ó6¶±Éa‰íIg„™¡ ¥.¶¤ºTzâ‚”ûŸÏ\â¿q³[cc}¶ö¨²Q\°ÚY‡TH#Ç<¸ÈPRFHN3ô'­t=¹zã;­ÄÌ­‡1A)ipùµ¤úåXR“ßêà~ýTÖmçmmߺ­+k$-ÂÔÓ-Ÿ¢•uã…:¤çö¹žú:i·ã±e+m¦²Uµt6K´–çÊ[rŽ?v„¸Ùm9ü*S`c'×OÛ¦§iÙn†ÚÜ;šÒ}ݱC_%ÂošR“’#+ $dä$cÜõ¬7Т­¦•SZ$WW¬ó~²+-®RË)Ì^J@åDŸÌM·l¬6.Þ›¶-¤ERd>. ׹ऀúü3à&CM2‚Œy‘ÙåÈ…(’^ç|?ý"j4X{›pUƘ„Kz[Oú¤­O(`ö ‰ëè©åmˆ70öÆ×Üh”0ËS@a†Z‘É$©ï ¨¤òOñ~ Œ{›D[m÷âC²¶°‘-ä—Ÿ¯”•†ÎGZŠ¿ë ë×Û@Ý'á‹oVXÚ¶í#ýœüt79õ²xgIÕqé#ÑŸÙÕ“¹·=")k$8ŠšGsÁëß0óØÀNPú›[H€”§Øõ¤S>R©ì*)é—-.Ê^Ü™ C+¥×ÚBæ¯ÕV N8€30Öý—¼j£¢s;’ýi™¹9W ‚ÄVÜtó+ ôHNÏ®«ÒÐî*Ë–^º­— .¥A6 šËG–J’Ò–Ê ‰<@“‰ìwêE}¯¹7…k¶µ7›âdL/·™*K‘ÞÇ5ü«èç* Ǧ=t Ÿ£ð·usS ”ÝËå!òü:ÚÒ—•a º VÚ±×, ®¨îŠ»Z»yr+àÎ¥¬Ž’Ë“'Ê2â­*-ò\‡ÈÇóÈö#ÜtšYw—h6Ù–RËM¢[I´yß ÄÅ-$çÝ8ýþ‚ݧÂz¸³àÁjžgÈ»# W¡–ÀÆ|NN8°=?`¯Bö­U£õÓ$Ònzd8ã$­˜pã>ÊP‘’2¯ ºTdñèœèmñi¸q Ì€¦aŽ¥S ü¬pâ<ªJœ&r)·/ÃrdÄ:²¢Ö4D­…ÉD{'e:×a¶Hð8´A° :>_¡Šè{Q·†áTWŒ€Â⪽2ãVÈåIa°£Œt¢¾CÓ@ëâgÙÉûH^L6é[ìÙÃKJ…=ñAZ |Ã×ÓŠµU»~0§?º73 ƒ:|&U^É’°£Ž$‡â–Oëþ!ƒÞtœÌª‹èÍ0™]d”¼o8IkÔ$-µ¾ò†O§t7ÙÛm­·âJcgÂT;G›Áq—ÙŒãDy¸8UœÔ?у X7‘`È“6EmC.BSÑ’o%È_FÞš¯´w36kVPÝ0­|Çr$YN> ÷¨q^3ÈÂT;û½t÷QñRªZ‘á…ÒÐÛçƒèLfRx¸œ‚=Ó×_¼kšKLù5Ýø,dEõä|sl/Ê‘á#Ä_]yR´õøÇc@õ&|CÜŽÚÉWXˆÏ¸ûì’븿 „8´¥~ª8J;>¤÷«WÏ}“k ËšÆ'ZÁ*@1.8©áøn9â/ÅL`{úi;pmf÷y²lÖWíªÆ”‰n§Až´“÷oýáPÈì6Gy«Hýk1©a/o7w: ÉÛÓÀa)•ŽË*T´$I%#$äŒh:ôê‹),†6#›gqÅ…ó>#¬¥q!©ÄåL$øˆÊ•žÖ¬dúiBþNö©œä‰Öv­Ã’ËI”Ù–¶Êº%‚\ ×®IÜ]ø{º¦Ú+rXÝGƒ^ᔿ#(u©M)>TJжVp™CòÔÝîÔXR·Þ[Åö#Ä*\TE ()J¦7"GÔ$þáë @¹Ûu;äÛ§°³Ý´Ö®i(غÒ!œùù_x˜ }1žÎ„mg|V\$À‰ ÕICRƒ‚99Ä:â¸ñ'ÄŒôNº¬=—¶éXjÆ.ÔÊÒOÍN(qs3Èò T^AÂN=²=N’ ÖQÕïj–*Ñ`ÜϲçüïÏ5ÁÀ|hÜzð›´:*þvƒWÇ1ô3á©ÿÊMGþkûtJóü\õí¡ß?óEþž×öë-:ßø[ÿ‹Ðž÷ö qͼ<Ã÷ë²…¯ñ4ç=ýƒ\soþ1«¨Ý¼£?.vÙŽÊÜJ×qþL² "É%#Æ!Œ1Ç}ƒÐ9ÅÛHzöD½¹>µÖÐ¥5!»ÊXh~ Õß2¥]'…8ü:ówÌL»rR£YÉJlÜ j¹*/­&B8©*Îx>™õôш×VѶü×Ú‘m!—#”9ëjÌPH¤)À0IÇ3ËÓ×U®¶´tüõL(×GoÄváBa.­#?r¤Œ+Ðó´jM™ÿ„*ËÈhK|‡§]{)ä}Tö9+=çÌ21­Uv2ìÃð“³v{Ék }Ÿj"©ÂSÑAiJZâ%)HöÎunPÄkk®)«j°¨«Æn|#&K+OJW!#Ë„€”¦€Å{ÛZË*½q¸÷Œ¸à ò}˜çöÒ¶P ïðõŽúA¿­!ÛÉÜ7R 3ó.ÕÈeÔ£…0Û*ãéøÉ>üN±bÄ-äÕ$½¿H´Ü6†^šÄVÔƒþ\%”€²xJ’}t×<·DmÄbP?c %´ãIyöoÊT† <ˆÀåÌ}¿»Ÿ®Û×PãÊi!À¸²e2$©IÈÊIKeG<–×îÐyß÷|X ¯í¹ñžvcA?0PBUÞ";(hœc!dãé¿sƺFô… {ft9K–KÙ?„´Óä+#Óê³Û%î&ÛÝÓ2üø3Ï5ê–\O\BDdpåœYÛß@7fÚnhöä.ú޲z¥Lm÷˜ë‘T?SJCj$õ„]e¿iæì{(׬¿É›u­ASªdÌ µž¾ëÅŒwÄ~íe&°-Ðw%DJÕ,¡ÅFm´»$”áäÇmÖÒ\B>êïG7LËkZék¢2æ¢rU_^„KiÒÏ€°Ê°¼ÒµwÙæ4mI´¯ÐGÜ5< "J’'ìá!¦Þ-‘Ù?#8õë[¥m§­žwº7]:ÑICo°ï¤(e(sÄp…zþªÆzëJ;.åÚN̵¸º½°…†"@jµéIaÂ|Ål¥õ¡*Æ8ú5o}UÞÜT&u‹wL@Yšàù7Ò}üGW ÐzãÔtuŽÏÛt¶–UÒ I™M%Ö È%M'™)g¶ôi*X%>'ˆµÿš’zôÆ—gm–d½;3sz†’ââÛUÂy‰ÉIä|7Á(@õ* ä¿Ú:v±øo*Ù¨óæ&=œ†šøÓçre’GBK¤œ‘õú Cy`õ’¦ÀwxV©øŸ/e·eÌCŠôqAIR¿G”/zh/ž«]¶äxñi®î›s2&a0˜Wá âÛ£÷¨ÿV‚F"¯v¡ÆUa¦<˜.W*jŸ)J\8*H9ü)g°5ª>á˜å’–v¾ÊïÜKï-I‚ð9ïÄKŠ hã8ä“‚F>º%·©gpYJ“¶®}ϼ –dZFy¥~«EÔRR.ôYVج´€¹[§qØn;KJËÍÈ|Ž%–É ï%X÷#'JûãvØTÜ¥“ùØí4·«v­å1Îó…üº]åžÇ€3ê4;z@° ”ÍË5µ“*˜“Áé \H€¹îÒÖÚTR?ÏÏDúhõ…D7áDÛnZ«Ô&¢KWŠðÝ)eÀèÉ’åé «´÷sö [Þ&$úéPÒÔ»'ŠRV2@ñÇŠ‘Ðò‡±Ø>šÎÄ-Ì©s&7.Êt´ç–#Ék’S’TiO42ANc­1ïUÜþŒÂ´­¹Û‰RÒ#˜òc&.{áN/ŠHÀÀï¬êµ–Í~öEt+JènÇr Teø¨Vs"ŽeÎ+“ÙϨ*Ðßn«k“®êÚ}ÈD@™>bÝ B83ß·_žšwµ†Þýa—Y”Òú!Ä>¼%88tŸËLv¬l%;yú*¦;°¨¢TK)Yì¡n—8§=v¥O¯¶±¯—[VÃÌ©{E‰o¸>eBbRâÊâÙdDƒúÅG÷Ma[U;q@nóÄ2+‘–Vĉ¬°Ç JX8õï¿OS ßi ’å/ϧ۵’/Á‰2œ±Œùeg-\Ô¦Òr; 'ÛÔiR=¢xZÛ[Ë‹&;ÈI˜ÍskiÌ,å";^"ÑѺIåÖ›î¶U“Õè~Ü¿YP^m‹B{‘È p8êBAöŽóÑÑkµ·eG«ñ'iÓÆ±Jž‘ ƌŠI%¯¿ÃkXõóñÈÏ¡9ÐP•y*Ê—pÅÚå´ÌX)Œ×«0êÒ}=qõCöôMŸ¦=$]³fühÔã¶OT|Ê$d-.°?œ¢ ;=Ñ=ÁµwÕ„O¶öÍ›s"6‘!¹Šû÷@ìñ –Ô’ÎQß±ÖÚx{ʹr¥··¬S`3öc*C )ι8Ó©eCˆÆpâ³ùh+M6ˆ\J/Ý•Z¼8Ëz3iç’¸·Á öÎ=õ‚ªÛ‹H±LÄZë[>IO–+‡6@ó 6”q8“ù[^êÝ»“dE‘EK}"Å¥xDhΈ$sR”ÙQOæÇòºm·÷ÅJ`L°‚%âËÎ*.ßæO|ÐèðÝO,`‡S¦ƒ#oêºûJ¶¥³ÛÞäÚß²z ñä?Å8ÇCŠï£­Ÿ QúE>l›}¢"QÆ+D9KJD“$ãÈ\ZÔH$rJ¸þZ­tós¡ÙÔ»¸¯èd™iR]´ˆ¨Ñä gFB 8ö> ý4&¦¶º±•î Ï"ΚtŸ¸‹9QÐÔ”ù’· ¤<¤àùJ>½&à²k¡n˜– px‡Ç´}’ðÉOˆ¶ð”¤þ× ‘ŸQ ›÷iLûmu®ßÀ®zAK)ù{×ÐòÖ¬y‚}°0£‚ ß dŠ÷‰{e-¿ˆíR,-nÅq\\¥qt†Bð`;$œÝ÷Q·TíSÕ»§pø¡*<™ÉL‡ PÛIJù/¾ø­vt Û?l½¶¤^ÔÖüU~ªKê.¥¾H󒵺Ø^ ?x¢“×, o\æ-· ˆÔ{ò=œ· e«hBJã”àa§sÂqJ>¥<³Ÿ^´+cî?‡TÅSåÙ_SÎŒávKmEfCm,«‰OÞ!ÕöO¡cÝ#]FfìØS-ªµ'K>:×ÍŠ4r.#ñŽ}ø‚@™M™¸êÙj¯tß0ÖâbO)þÊ[‚(‰ÀiD+#d‘Žóì)·6 ‡Ä6ï§=7ìľ¥—ÔbÄŠ8`‚µ© ©Gýu•cÐ÷]¨j¶m´›ê&®›mo.3‰„Ûr$¡JWj[YSD”ô¥ä{{hí=^ÏÚo%‘h«v„—’ôI5Íxá÷<@ƒÚ†?$ÙÐ.Ì"ÎêX¥Ü1$×H{ÄE’dH%C ó¡×’zÂB·®i|”N+pXÛ>äU—ŒÅo޲¼õ”¡žiX?¬¤ù] ÛÓvO脉Qî,¶Ìzõ)˜æÂKe§Aâ¥6Æ;Âx§ÈT¢ÁÜ‘e»ë`TZ)q“‰Ê“Hô%䃼¾Ž0 ÐirehKRg7:ñéÒÚ˜²®MWÉ…øÁ,%Âp dtN„n =¿U¹ä».ÌH…\°¨2ÙmÙM 'E%^ É¥@~í2'kªuº§Îa\ô¦Dd´%4àn7@$Gq”‰ÈW¨{cZéþí¦Óí"õ3§Êh$À±²òâóÁJkÅg#³ê 'ÐýA>ÖÞnë²~E}Û3R’ëQÓ᫉V„qãOãñ‚0të;jÌjdÇiªwjU²ÈUnàr:daDóuÒ©˜ëZ­`YmMÎÝ S(˜Š#!Æ®q²·1è–—‘”õƒ“ß©ÑKÍÊ¡.ÒÆ– l!°SŠvBÊBÁü<ºÉÎ4 2iç^M+3nݬð[y’êX‘:1°òšñy%I ¨Œå#Eöýä˜v5u쩹MµÂ~Íš¥ÇzZ*ðœSÜAYʰÓ[ivÎø¯¦º“º6¶Ð˜èàÒ®ˆµeJR°VP€Ò‹de!G%GÓ½xÖßÞ©.B¹ÚÛ‘¶f,®@ž¡Áµ ‘–G¯.øå@gŽ´ ”Qöô9–®=·çÝÚÝ6µ:^ܶ#Ž_Å€×'ѫԟÈä—œ¤¯\ºk;j¸¥+¯LD/—à·¹\”€3õÖš=µ¼ªåGŠõ:ë–ÒÕ!R !5!¢®A.-,s '®IJGy:/U»·§®¶ôª+سYJ^Cm˜ò”ÎQÓiS€ èã¿>´kéáDqÙó˜‡"\VÆf7%¨!ÃäV2\Wôj•5WÄhsäË¥¾©lSÖžWË!²pyÔ œ` `g®ûÍT?§R;wuNã'ÄSmÆû.`' Ce*ã(-FFuƒEù&®ånJÕ¹m¹)š“w0G›îÒ2·Y9Æ€]Û;ÍèÍBvœ+0>×e|ë!”¨-§JÓæç–GâÓÖ胵|_’Enæñ?*ô3äÉñn8 zúzœûãæÕ´s•=ÀÝãõ >Zd–œq’r¾+L°’ „zŽÁÓ­dŠÉŒÑ¦¯uþBCOx;:3ìFF{aµ8[uDþ×~ªÇ¾ƒ^ìÙ’©¨«Ã–°¡0”©MÈ›o6+©hC—#(V3‘áä{ì¡Q²—C»+l[øŠªù¶TâdH|:¦Ÿ*Ré[i§Ê¥ž~¤µÑfÛS¡Ú¸Ýt»¦CmrІ¤IŠ˜ z—‚òxàã´ŸnÆuÊê-vËû…Oo¶ÔÖr„°˜m—¬œøkã+$>lñO·Xë@Ë{g™áKø lç¶ëŽºÄäpä©jÀÏKm„þÂÔ=ã[)­¾ÀÝ EßЛ‹&!Uhfµ¤·1*IïîÄ`p¯2±××LÿðƒðöVÍPjæîÆØ}¶§¾õ+M¶£À’Ói$õÐI'éÖ‚n†öåÎìéàÙÆ•”>y¤0ñ@ó„5JJÝ¡SÀzÙ™°–Ú‘€zÊ”P¡“¢aíæd=¸,/¬˜±™)ø¶õ¨l–°A´¥$dcŸ qÈúêýLí‘e»,£4ÝÅ”ÒdÊ–ÓEiHÈBI ž\Iú«½;*ˆ®®=­ìÑ^úŠSl¥ò´“‘Ç-rqèŽ^ž£T­fÕ?6L’íó¢$¥ŠÉ[t²‰)Ç |°…´ó–=}}ιÙÉíÛVÓÒïZå¨GœãÑšChO”³ÉøêòÏà#8:Înß~Ïå¾j†E$h—Ûj5‚YGÌ0FXl9€HÇ>'óÐÜÒ)~J €ËPçµãN¬‹-É*Ž¥8¸òœq °ÝLîA§¡¾ˆ\4•Å,©iïδá$+óJÐYO®›ð£k7t7]¦å—Kî6܇Ñ Âr´$¶Z¢p¼wÞ}æå¥‘·*âÞÒ¿¶êر”VÜrùSYÊròð¥>©ÉzwEý܃%·¤O KÌ2äV`Èq/Cm#´”¼8û9§¢5P~ìÞBWð¿ˆe5É GD?™œ†UÒ¼#Ã|½`¤ã¯M'·7rý¥siY·`S×´Ó¤c?â)´Æ® H '²¬ûôJØL%VK‘qã¸iËjÄHm´« “ŒŸ1ä=÷^¶!RïfæÔmíºÍ£ˆ%—ëáü£¸Æä\ÆÐ=°Iúh;³·Žíq™{‘زÐëi]s_6´:èÁÊ îr ÿ:{LÑE-{"ÆPSdTL>:Ç,ê %jô $©Ñ¨×7­—&¾¾Ø3 8—ßzR\Œz <âd€Ú”èVÜU–žuØ[ëu?àdHÜ ÇkÄÁ%¶¥¢y“Ž’„©õΛ·”‡×]ÞFÏ›a¹ ?,äYQ|( ¡=)Õ‡ O”{¯Øt4so#+mD/¹p±]-Èn{ I}×3€èq(YÈt[9ãØΚþYM™Që αm*2’Äã®:8JR¨èi”4· “ùü»æœ26‚fíuLrµSÕ wŒÓjOê©ÔrO¾K`®€ßWÛn+J‡ž®j+0 ¤Gb&ÂSê'ÌâeC×8ç€3¦_‹ ¹¡ê˪êy‘œºPd­JôZÝ#¬SÉ_P5OdmyÔNC“±n-)véa^*¢@sö >¥$¯ÌŒ–'[W.5l¹í°ÔÆSµw¨uðZAï qÆ»öÉHïµ¶ëö—…I:,É_=%nü¢"¶Svˆ¤¡HZq„…êIÖÔ[üD…5MÅøšm€’ý€—^}Œœ¡A&'ÝùO›$÷ïVŠ»êýÒô+ÙûNŽÁŠÖÃÎMtÆmø~¼VŽkI¹ãߦ‚”°ÆÆ­a ­mŠé^$tÉfm$Žƒ_ÂWÁ´ô=ÆqÑÕ•Ö@±©mÛvD÷ædÊ’Éä ) 1(º?.ºþ(n£ZåÌÙ[Nšµ«Y9.H’}–Üìá!…©_U…ƒé“«ôQ¤Pm)iS»†¥°áHq0œh sí[BWºÒ²?gA®my¡ ÕW¿dÈÕ8R±Ìå-¶W$»Ë'Û—·¦•bWŨ¦’ÁgÜœ:¶cøîNŠÂã‹*BTzü#­3ÍÝq׺úº7ÚS±ó×2¤—’®Ëj*Ž¢³ôôK×a8Òî÷Ä…WJ©Mµ)M¢-–øäña’¿#*?]ÖÜ—,qcQ[% B<V\¥¶°RÚIñ þrtù³w5Z ÑÑíØ{Y¹Ö(X+yÁ% ¼ŽÖ„”7÷‹ ñäõúèné{mKvuT›«$OЍ­GŒ\u–Ô‘În­N¨ÚR‘ÐãªÛÛû6zUö+ô¢Êu·ZSËmÙKRr—„TÑ8èðZO¦AÐ5ßIµ}K¶£ÞìC¯m’©Ñ¢ÅøxKŽü°â¤Œú`û]#YȺ•wVÍ |;GCn9w& „=%Å(àqÊWÄÕ9úkl[HJ±ƒr;alLŽÃáKÿvûeI*€õ÷:¹¶kg®»¸Û»FD‚RTâjˆà=qÁù”rWCñ+ë ¢ºýñ»#½dȭб)Ö%‰:ÊP¡‘ÀòJr}¸óµ¢Ûl+nÐXÁm ±94èB'-Ú 4¤¶¾Hï—œLúèÖç´¼zÕ4É®¸vÍImG奣ÃBz$- Ì<†?YJPôÈ÷Ö»èvÓE³«qĘ’²ô¶­F‰ È tºÏ„“ž{Ïg@±PÅ|+')~kzX|ÌQ"C¶•²ò¸“¤–ø'ß+¬{yŒÎv€ƒ¹(l^¦Urjá8”Éä3À—š<†@$Ž>ž§Aê7$È»v^ÝVâ]”‡¤x©r#X´Ç™´`ç‰èŒ=5ŸÂûåYÝ•d­±PÌ„¦,%ØçÅ$dølÅmOúc9Pǯ}è0ƒº—E$»xûSo˰š!ýŸdÈO2A*âAm@ûa`ç±Þ43qÄ´E+n7µ˜¦ØøóX…29)…²´3ŽG²zO “t]ä›Hð”ð§–ÔþXYd°°Ùìÿò8õ JF¹×/ÙÛZ<†žºØ½Qx¹|¦øø‹C|ŽWÈ”ä äIÁìÞ‚üSu¶kÕ)¹v4²¦Ú¦»"Lw”¥`È28û gÓ³\iÊ&í&K²CAÕ³òëfª+~ÇNK\|U6Aì•å>À½™ñ=ˆ]ñF[³f)-ƃi¸ühð¾]Î}Ç Æs‘í¢UÛšf悽¯mOQºç!ÐÓŒÎŒË }@vœ,7…$zœõÞƒc{v¿iÕu·èÐb²„HV+Ýñ õu@Ó‹è„àcÓÙSaO*;֮ĭœÝ›ŠCù1-à~7$€ N¬uî'Pm«“£mʇf0+/X-¤ókÐ%L%`%?²…÷îsª[&’Ú¦åù“šµjSˆWŽóxS/òÁO~Q t§Ø:¼tUé ³c¶Û~3N9MãØÉL†âDmÕGiH?Œ‰qŒn=úgK€•î9ÛâUTXŽ*˜–™ rH#l6P”Ug>Ýhéܰ\¯ 盵q°ó¶Û†C¯!Ä+!d 9üA †…Y Ê+þhÃŒ0ëÊv8v;/”ÅIxÅJžYX W·¦ƒM,«›^l΄Ôxk.0ýÄâú²AZ[Iú¬hí.àÞÕÿgÓ°Ê­ÂØTtºfETu^HÃMº®¿2G¸Õ µgMWW]iµæÚ±µÀú¢AqçVµçïPD‚†Ð¢¡ÙðÊ”1…jåÒÆô´TùÛ>cöŸZcM°+iŠöN<©â âý‡¡úãA£nìv,Fë±Ü5IÜPÕÉ5ÍOûºôgʆ÷˜$ä;Fw wïÚ¦®š3"œ²³cbŸpã’•â¿÷-œP?¤çUþmÛϳeÖ×Ü@MpiÈóYdË[QÖ¡ÊðýÏIÇ@uí©ñ#ní»8Pl.TŠˆåÆ¨b6Ð$)`$ö2¤ž¼ºÕ2÷6â °¨zCÕTQDÝÃèÌ)° >àÈ!)ÿÞ':£smRôVlwƒtÐ$Åm§dÝÌ”´º”ÉqÐÐd8ƒÑÀQõÓ=3‘©a5*=à“i0 Ê[H˜ègV¿• H=å)ÀÏ®¶îÿˆÌ½1ª’ne°$¸ôx¡œt‘á–ÉH$äÜ’4vÜyLÙ»uúábd@2‰‰oI õÉH¤¥#è§3“è}u¦M 5¯"b7 Ø\Rظƒ!Æå c.£ ”S’SëcE¾bî,ÏÒ—÷!²ëËÉŽ e¦|VÜôíNŸNΘ·ÄÈ{«kF±›»hø‰ “[,¡€ r\m¿Gë‘Ç×£ Ê}Nà³Ú(™Y{õ>ÒPýœYJiIDJZ4q?òjÇäF¹”mÒÊ.æUÈÜSœy…·›*ë×¥rãÏáJåêB1×CNçmíë]ë:ê¿q¢’tXAPg6\-pëÌ”¥G´»ôôÓM5•tZ´H›¼w'ÊÃʘCíE[Ž£êKkR†AÂÊÓŒã¬cAÏæl8W[V\èðd^ªZ„)3äÈ’·t|B˜ªZÞYJOåª6ŸbVBQ…VÖêaA¸Í®Lu°„€çŠóáiOæ¤!$ûh…ê îÃrlºÇ{%”XJ~ÖsnÅ´ËÇ2TÛO xÖÒdŽ$Z@Ûm¡ë÷¤0¢í‘ïÐ:f2âÖ,ú~?T6¼y)LfëH÷l.K¨õìŒãV¦ë ?˜ÛŒ.ñèsÛy«„í‘’Û%²CiÉÂH)9Á$hnðÙ¶×Ö§Œ[iRãÉL¤2&+n%Y!Øì¿ÅI cÈß/Om Õ×N„ä*¹.¦¸÷ÉÅK­:’8¨¥¦ùŽ>ç‚“Ö®u[{QÞOCÓm*2_q(uíÂËén:ÿñòÀO%ûi´ÔÄePßÃÚ¸ófƒÎ;ÑÜ,¡Ê”˜Ê*J¥ ‚´uùEÃUm4™‰r»i†PZi1`Çyçè6 ”x¥)ÆNGôã­hïn­Ã±`¤<ÂÃÉ‹Td4Ç‘>U‡ÛQ@9 sŒzfíW÷æáÎô±¬¢I(r5zf¹5ÒIZG%pãwëlŸº?Lê"±iWa½kâFâ’Ôs4·‚úZŠ”8ôœ“Ç8ôÖÜWn¥&–ue}‹Þ„ÅŽä⥶z%_Â޲A+Hôè \'vTÓÅFß[Þω"-„ØÉJ†Â0Ú“‘ß?Cíë õ6;úä] Z–¦ÚÊH[­Ç1[ùL‚B›&> > )ő鎎™¯¶í[ttw× ­»9\nº¾/̥㠖âœ*ÇX<‚Ç›Jû*²š¢äÇ&3^ãÃfsèš{—n) ŽG,dò+Q™õÐU±U¾Ú§R«wŒÙqâÎZÕe>ÉÁ µ([yL²Jò1Èzõ­Mý¶ô:íñ¶w"âÉæc"gÌ4áŠZIqkZ‰È õuºøŠºÍºÓO̱Ÿ&KÞZ‚Ú8wϦÛ!Dƒ…OLçI“w/øqî,XC2B‘bŸŒ¼œ—Zqo~¯áâ OêM[úQdûö“n7 <…©*D©°d†YW!†œBÔæB½äïÓÐÚÑ,¬ëå·â®Åèn+„fZt|¾È POË/$`rïÛ:¾ÌÖë¡›fêjSM7ÍF¥Çq)ãü[ê_†O¯^Š?–’Û{Zê³nÓÊÜRÛ}À‰ïÌ ’¥òËmñR]I P+Q$M ûy{fú-Uåü»WÖ§&>ÄKDÈ”Òdz¤­”! ç®9ëÔèþÝ¢ƒº—óÂdýÏ*;_<ÊfNÞO-Â8¶Ê‰VR†·ð<£¾@”ž²{3[·]rl‘Ww¶÷ ˆ ʵ_}ä´1÷hT· klŒuØõôÒ¼{¶)ïí’™Š²”‚6oÏ*Lt(ö„%I)J +Š3‘צ‚oºø-Æ‚§­éÐõÃ<”ü¤Ç* ÄóðŠsÒ|áÎúèã:1]¹ã uÐÅ6M&8‰)BSŽ”§/™Ž„)x=eiÏY×E)Ðä„WÏØûe–¤§Éuök­–ÀO\Vìd«¡ž)#¿]-ÞÕÌ£e·¢Ì¯rê4€ã²Ì40ì˜äRó9ôÈAÎ=t²y³µ‘-ìML"†cI‚ü8KmÉZÖàðüE(¨„¤ÐÁ:ÂeÅ}4É•°l·í@äO‡bË+°:i´¥I'‚ÏæFš(l$ïÆcE°˜Þܲ‚´™¯­A1#ŠÂ)> £ûtks¾Ý””Vнp4ä50ˆ1Ö$²‡óñ$w ¡eI&±˜ò6Ý·ÉÃBþNøYŒÚJsæe/dúémÑ=S}G)Øôè+¬O*±÷*R]‡Ëð­I$déÏ·F‰J¡5Y¤ Û£ç&·2<5c>#hq°Aò€sùƒë¤•ß.Óâ*õîcuò0,”óqÃŽÄõÈЏûŒ~z ÷¿ÄÝ¡{ \7í:ÇêÌAÿn‰ß}?£CvÎú©ûR·YiÕÂÝ|%Ñÿ˜¿í×*ÛMø„ã]3ü/Ïþ£ïüŠÿíkšm5tª1ø…*%z¶ì©ÈyæjBÛi ©KÌI —¤žÈƒëÖzè»"†Ž[-ʾ3¡Â””Ï,Ä “ÅL$øKÆ R@Ær'J‘]¹¶”ffJ†â­–PôfÃŽ ˆR•*BÁ=c´Ÿ_oQ¶Mß¼žä{›[-Ùg~ ‹zŸå]Jáâ¡„¬|ÈW·gJ¦Í×_±ö¥5¥;±ªÚ’!äcêJ[Qàl«ˆ= (l›(sï"µ*ÊÆt¹ |áð%ArA‡'¿þjd÷9íšØÊµ›!½Çb¨µ l6‰µ’r•#åÆ~˜9ïC®ëbAÝCq_SÙÈ®–•6ü§âDm†ÚB|ì¡ìt:N}p¾«-—ÛÓnÔ¡÷ö¼Feȯ 2ØU¬&ü•*Sd’´gùÒAôè ˜ÎèiÛMçj=)ÔÒWC+t0éG0[iÐrx‘뀣ְU]vÍYgiïI0~^'ͱMdµE^Om©ÀÚ@¬ Óê=5ºÂVêÜÛz׉,¿b®%Õ<„2¯P·aA`úåxÀÐRøO]»*ã?!S®"ÿR~A°Æ ‚ûñÁm z ž°N†néñºÍ‡l.iÍK3xˆê“\²€¼à¡É c—GÓ¥ ;WB°ÛûeÚ«é¸P•ȼkY+ HÇ?~ PÀÎ8çè4¿>ÖZ݉fÉZÔÒ~ÑëÎÈ#Ù$†›[kF1ï@z¿nĸ²Ÿ:Óâ"­äYF!ºÈKm¹ ‚0J#@'Øôq¥»÷¦Öµ ¶Æ6ò›c2@ µjˉgÊ6†Ð °0 …#FöFùÚ׋kr¶ä ‰î¨Ø9VÛ°Ém$qSŠQJÊsû!yÔ˜æÅ§¸v=vÜžì§Ûoìù>2úY=óC®œ§'9 ÉÀþ’¦nªêÑUbeQ‡Õâ6ìZ–øþ³É. Ž9Rùºc ÚÖÚ\:zL@çÙ©%¦ä¬(þ–Ûï9Âxc¼é÷uËÛif?g{­´‚‰œ´ñ\p„å+mFH,ŽÉJTN05ÈQ"]‘û~–þDx¨MÊcÍu (ô¡!%Ì’1Éj=Ÿq ~¹—Uâ·º·,•ö›ñ•¹È–ÓyÂÊx  Ž–£~ó¥šáC¸ï¯%[YºÅL×ì=ÀÊ ­ÃÇ )^ €? P8ý]jn­¸õŸh1µj£B‘šù/. W~l•Hq·’?5/Р꼪åu}T}‰CJ—âÜ—ª£­R”•à§ uÞ¸öÓžÙ­Œ«Y²Üv*‹P–Ãh˜Py'!)R>\g铞ô:î¶$Ô7õ=œŠéiSoÊ~$FØa=¤'ÎÊÇC¤ç×{ê²ÇqîÍ·_ZøÛ±Û>hD×i—Z^@J”ßá)ÎâPAôUMò÷FÖ~&ïe¶_•ü®º¸¸¥VÓnã'àÁ⣑ª*«®Ù«,í=é&ËÄù¶"I¬–¨«Éíµ8Hõ€AZ}G¦·XJÝ[›oBÚò%—ìUÄ¢:§†UêãŒ(,\¯[oÞ™ïÞ©Vtò‚Ä6 ÁðRÚ€Á+Ic ½Ÿ7^§:­º÷ÏÄjùêT»ê¶j|²ë™DÅXñCm²C€Êzöt®…a·ö˵WÓp¡+‘;xÖ²V‘Ž~"ü@¡œqÏÐi~}¬µ»6Í’µ©¤ý£!×G²I 6¶ÖŒc ,Þš%Kw2+Þñ\†Ñr¾ª±¸ìºêÒŒžmðRJÎ;'J EòU©o{µ"cî%¸2Ûu¸Ëç"x#Å_¶V¬${ Ùçk\R-­ÊÛ.'º£`å[nÃ%´‘ÅN)E+)Ïì…çRc›žáØõÛr{²Ÿm¿³äøÊCéd÷ͺrœœä''ú4W=¸6ÂQ\WªTûE´¼Ý® äg€}’§Ø—^ÃŽ1ª±$»¡7VÏ­÷¡¦#=ù*‚€¿ µ+9#‰B”É'×OÛ®^܃K1û8“Ým¤HŒå§Šã„')[j2A` vJR¢q®B‰ìlˆ¯Ûô·ò#Å@ŠnSk¨iG¥ y.`$‘ŽKQìûÕã´¿¢™¿­‹O >cìÈÒž‘=°Tp|Ãn+‘ë™XIÇ=‡:«rn6¬¶]mdbÄxv‘þDºÊÀä’—p@!IÉÏ©N¨7VÜzÏ´ÚµQ¡HÍ|——+¿6ʃ$8ÛÉš—èu^Õrº¾ª>Ä¡‚¥KŽñnKÕQÖ©JJðS„ºï8éJ ýþúmÔü"r¹;)r&ºYX˜ì‰è ÇYRž ´¥c RIöÐz­ó^¹ö“˜vLH΄=I* qæŽi:Àæ¿ê ºýP1¡û_oSÊdÎõ¨®kfêÔë§ï|W²Y õë«V{†Õ»¤·c¶7ZìÚò¦ ‰5ÑÚCikJd„•ì¬$û«M󳃸„Ê:©ñ’9XÇièËq´ñǶ¥œzöIÉÇyʬÖjwmÄ›”£à!§LÑZ‡iqî ‚sØR”z èÙo˜û¢\ÕVIÛÍ3¦Ói6;ö„ƒøS–$%¥(äŸúäuo¯…º«ÝFèÚpoon \“i¶ü$K 9B%fI@ù €ú¤jÌÊûøkchí™Ê‹·d‡Rò0T–¶Ç!Ž($u9ÇMe³hÛЭ/›˜ÈZä.Só"””å\G•?@’SNûÐøWtÎë°zMà ¯m-©3fI®]xJɼ`Ÿ)úq]Ú¿ ç^ÚÊ¡û}Ä!"7„ÃÇØ=T‘ÍjK©õÁ@gZ¶•.ÝålêwÖà–·‰m¼[ÉñAÂÓÇ(ë'õ¹Ò7Ä[߉﬌K;ip¡ºŽ¶‡[ñP! gé“MB‘w²égJ·‹ey·+ž #õ°‡8§Ì•-6 G~5z÷ŒéU™Õ»ÇqÎ*ûÉ@ñTË©uøÏ5ÖŠÛ‘ÐIÈ=O©Ïz¯a·¦Ùl7làÓH»~SbBØ—*By~¸{ÁRAN•¿Î.Ó|ÁÛðªo#ßÀq…%/N“aÏÅhú5ó(®€ =ÐnpTÖ=Wìû› 6Òë‹‹^ÌtÆQ9P)DŒ+±„“×®G®"Î ¶ä[)U¢Ý±Cì¿1…¡C€$ø)Iôò£ïŸma¶÷Ò%9ej¼Åp!IJER$/™ïÃæRÓEIçI[¢>ò§r-¤x×ÕËyÁ%“lԸϷÖ9·ó O§~€zý4 U;'kÛ¿eo1Èvw‘ä‰Ò 1òÉ$ø‰qçµ döß]ë:ø÷•û‚S·3âÖÒ<µ*$(tž0yÒ’T\}u±éè…“ÐòëSÐ6Û›F-»0¶…mkç×ë›)씨ä!x88ózt¬èVØfŠ+WwicÈK¦¶4w o!](-¢è(É#.€pz:”ß¼VaUºûtч‡6îL6aEqàK‹-”箊9Þq 4T÷ì­· *l¬vüæ.¾nÙIЬçy<Iý® Py†™7‹%ÂcgßÖʼnD.¡ºÖÛJ“êT„rG]¥@þj=èSŸ'B±@‹„G‘æê4¸G†Ø8QO$(ðÁö=úñ>À[mÌZ­á^·¶÷ ™š…¸™'™Ÿƒ!HS®2”'Ü`;ÈãU©­©­·<ª˜pMmª·fɶYá=Ÿ Ÿ¬ôqßïŸm3×»¹\rÁ·®6ÿ€ùmÈ.Añ¦¥ahl‘’;⃜è.áÜ´ ¤ÙÞ¶ÜK&ìR„H?gº— Øòòs—Ž»$$ö4dÔC/vþÓ›¦rùFmʇ¢½ÌqPym´áBT®üèOyÉÕŸ¹¯Ø» ÚÊUeZ"¥ƒ=œÒë/œ„2²†Â\R†O›‰ôìrO}YQÁ¬]lš9òÖœ‰!lDDfÝãæ!M)$wû@s=º¶,ÉŽAºj¼KÇûEi[J?ò@*1PJO~ªÎr“ï hÞÈDê{êÍ›fãO%È\F‹RË@ ë¡ß$絬„Γ9wðÜ5h‚!GŽýÓ‰$ä¡8|%0F=ýN¯îZŠ+{»V~æ—6t–ƒDŒòZŒ„ŸÀ¯—Km“ŒqR€ìjæÅ3fíIð/©§ºt¥™î\Ã’´ðQ'%1ïß`=ÚthrÕUu%¶Tµ12ª–Ê ’òáÇ’Z#$^Æ0h½º«ÝÚŸk½²w,ùL>gE7>+¨á…!.¡Õ£9Ç— ÈèötÕ2þÂ=dv·7Í50óDTº•-§RN<­´…‚pNIQPÎ{ë@+¶´:ú¸×”î.E«[מmâùVx­¥€¢GXÀi$c×¼8v©Ý{¡Sº¾—k¤Ér¢¿h-óÞ#€õ­ WÅ9ÔhÆäÝʳp˹6ûU­qB›˜–Ÿa§V%¸ìp³×i*ǧл:Læ\‘¹÷¥­Ä˜{^ÓœRòz<ÌuºF=ó鱧¥:½v;ÊÞ·KŠ€¶mæ ©`þÒRBz莳ž± ß»ëþćÞÙvÑw4§Ò¶>Iþnr2¯·{H‘|{{Š6ÒŽÔ5RGºbÙÇãKen)΋…^ n…(zðRB-/îô\RlGÙû–æz¼T4ìYˆSý‚¤üïõè~]éiHÝ»‰ê]Ï"áÏø[ qµ:Ñg‰š×ƒŒ}»IΧï-«2; 1}uk&1ûõ¿5!ñ•rË(ñ‚p#@Nª»ED–Ù•òeªù ùjHHC?3!Ǭ“‘Ç>Ýj¢+w¦Üß²¬ª¶­‚ 6Ò~d×”ÀjjáZÀK!$~Î3Ÿ}¥Ü›‰©S’‚Ä‹‰N†#ÁµRd©(>¨rÖëꤟnÆt6eÄ‹+† [BÚ¾#|݉.ÖBˆ’pJ8Qy¼ã>º¹ªvÖç‡ ùl:ó*ùwÖ¸í(ç%¦Še'†Iý`}Oç– ÁUÌZúj”7öœ5M‡V¤Tüª’—¹ ñNsæAR}t£°&ÒàSïjxó­&âH»ŽÜ§ *äµ+Ð×@Ù½vå•|fâü7\E–a‰žYeÆó%M#.ïåmG#Ôê1½¡ìõó%XO°iÆQ%š}rÀ TÚqŒ~¯'#¡ŽÔ÷+Uµ·­J‹i³£\Á”$&1im§8º‡9' %aCú:Ó|jbYϰUõl‹‡øñ·z¹+q´)$¥K*ô'¤¥¶óŽó T°S÷»‘›$YLkw¶Ÿ³Õa,¸ Â]Še!C>\„+ŽOcÛEÝÒç×ÔîJiŠºùeº˜îß¹9•)JmÓ¾SŒ¥ Æ1í¬°Ü[‡-÷Uù™^¥+lÀu'‘ühe)JëŸ.O§`êíîÝž•ùo¶Ù³ii—&Æ[aQH!$†ÊrIü*IÆrÝÕ¸«Z­‹¸/6^äˆVÒZqé1ÛR1’Ÿ:[E¾û<Ò3ÖÒí›]ÞôWPÓZ¿´iç)Ra”/Æ vN%JæFOXÀÉ«×] sVGº­˜‹Ë¥‘Áq£ïJ@quÄ”äò¬ŒûëÝo˜Û³â}}S1aúJ‰ŒÈ[m­´¸µ;yBŽxù:Ï×Ôé£ÝÂ0Ît3áÒ’¯ˆ÷2Ñýº'¸ÏÜF€üÚ\gçv¼Ö^°ø‘lÛœÑâ¡û7¦°Óe9–áŒvHõìë•×Ó¢Îvà—5sÅ1šnIe•-DøþyÅŒ Wâ´IèÊK-Ÿ7J¯¶zZ#8i6c á¢DròØðû<¼AËRs `µÚQ÷vÝ“y¹7ù«t>‡áHæžIÀi!hãûœÀ=ã@a{6¦ÚíµÍO*:Ùmh‹4©ÆÔ¡È¸²¯ 9õp‘î}´SâÞáÝ•ªfu„š5¾|V,Tõ|'e°°>è…%$IHHã‘Ù'Ó¶í†á?ðç"êòbÛNÞXüÔIÉðò_‰ÁÎO°>À±ñ&7Û…õWõp6Ãjf+ɯà’ù”Ú|&“â'8ü_™:¯Fa­1)#ÛÉ{rIÃS0×ͦÐO¥Åðu¦A$%Ì «8ï ´ÿ ™¼Úñ°ß”1ì¾aô×µU5×Ò¥ SN8úBÉÀ8Ñ#TøA±)뛪òÛ‰ ;«Vá6ô+ZxÖŸcoºxÐëæ¨Ív$yކW²Ô]'ÛîzHÐ3nW«£n«kÙÕÕ‘Ciq‡\ÚÉa¯0ù…ñO^ç)ô;Õ(ÊnªÎ=«;>dyÎ"Þ â=8sAp<îœ$Z iì½ÃjÖáVîuû\ç&2%„Ä'!H NyK±••àã vN}}¦Øy©»?i±ö+™ù˜¿ðyòÁ%xyæœ@ìô„éí |ŠÝ„¸©²š‡¡¦$•&,VÜ„­ Ÿ7䬑ÒdziqqUívä¤ÙlÐ’ÒÛ\‰ûu¶@ *s(BšÈú¨gÛZm÷ØÛ´Ñ!WÚP·'.¦ ó &JÔ T ¿cB’ÓJÒ·}ôÍÕú?OJ'Â%¥¶Þ “å ε!n##=$ŸêÐ9I“»$ÖØßÖLu©ä*±Ô†”^BU–’¯IH8ã:JµÚ»É½Ç2õÝånÜö3+RÚÐ0RC/®DAÇDç:g­§­¦”!WUˤ´u+TG¹ž~C‰N-¡¶P¡„D‚:ÂvóÞ7&%k;f¦c2J$ϘÚ|(ã›…´‚®ý’Øú醀‹­Âõw´¦O˜óî724V%È q 9Ry5Å èå)YHýœè¦Ò“mq³½eèèZ|h•ó’¹ Gª€B.•žð‘ÄýuµÉs¶«Q)¶ý;(š$9U¥IG„§Js’²”%+ú'‘QÇ~½¼»äÏ…2}´S)K/غð€WŒ…4 ZÒÛ¤ãÌõPôÐM°ÜÐfF¡Þ¢Ä­qƱ9Ï•x¤•(R úúã×>Ú\gçv¼Ö^°ø‘lÛœÑâ¡û7¦°Óe9–áŒvHõìë•×Ó¢Îvà—5sÅ1šnIe•-DøþyÅŒ Wâ´IèÊK-Ÿ7J¯¶zZ#8i6c á¢DròØðû<¼AËRs `µÚQ÷vÝ“y¹7ù«t>‡áHæžIÀi!hãûœÀ=ã@a{6¦ÚíµÍO*:Ùmh‹4©ÆÔ¡È¸²¯ 9õp‘î}´SâÞáÝ•ªfu„š5¾|V,Tõ|'e°°>è…%$IHHã‘Ù'Ó¶í†á?ðç"êòbÛNÞXüÔIÉðò_‰ÁÎO°>À±ñ&7Û…õWõp6Ãjf+ɯà’ù”Ú|&“â'8ü_™:¯Fa­1)#ÛÉ{rIÃS0×ͦÐO¥Åðu¦A$%Ì «8ï ´ÿ ™¼Úñ°ß”1ì¾aô×µU5×Ò¥ SN8úBÉÀ8Ñ#TøA±)뛪òÛ‰ ;«Vá6ô+ZxÖŸcoºxÐëæ¨Ív$yކW²Ô]'ÛîzHÐ3nW«£n«kÙÕÕ‘Ciq‡\ÚÉa¯0ù…ñO^ç)ô;Õ(ÊnªÎ=«;>dyÎ"Þ â=8sAp<îœ$Z iì½ÃjÖáVîuû\ç&2%„Ä'!H NyK±••àã vN}}¦Øy©»?i±ö+™ù˜¿ðyòÁ%xyæœ@ìô„éí |ŠÝ„¸©²š‡¡¦$•&,VÜ„­ Ÿ7䬑ÒdziqqUívä¤ÙlÐ’ÒÛ\‰ûu¶@ *s(BšÈú¨gÛZm÷ØÛ´Ñ!WÚP·'.¦ ó &JÔ T ¿cB’ÓJÒ·}ôÍÕú?OJ'Â%¥¶Þ “å ε!n##=$ŸêÐ?×5{xÝ—ÈɹeèËãˆ^Z¹ÁHZ¸ã¯0÷‚Aå26KQ ÛÊøÒ¶ZTïƒd5N»gÊ#§) ?ª‘è3§ºØ{_k¾ãs*¡R¸ë¥•Ün9’à)$7á=Å+9Pº¿Ee]­k*X?,!ÅZb,ùDfR섃ߢx÷é‘Öí/šÆ¢=ÆâlG }÷\³å<ŵ0ïñƒÍ@{cK{y;Zt•1y/eJ¸>Îüý/·tQæ-]#9’pG­u+]åSG{|–÷£U®²¤üëðրޛ Lpê§“šF@ëAvgÅMŸiºbÓÖ Ëbúã­€'JYñ‚†y‡|@=yÆ Ð&ÙHÍœMÄ‹Wb˜Koìè¯2ìFDTKeœ/šF=â;ÈÓdÙ[¦eswÔV2Í\é&B£²V¥Ì[d•¥˜t- õ8H‚<¤u­ÌB{tK³”ßÚNÅ[ÉÃÜ3$JÏ™gÔ²¾»)N=OxÐ×w ¾‰Sl¶œcŠbG°´¤M Ž­o‚ rNH=çÈ Z²S•[…š*ͧ‡-£=s&ÜžL¼¾‰~;üYV:ÏsHõï[aîýá&ÒÞlâ^®!+y™ìËn6 x¼QÚP’¯ªG®9cK65÷[i·¨\”.¤Z8¶äX~­ÒòH䤕(6õ-'ò=èÅœ(Ëz®:ãU@}D­Å\ÓÑž’Þ8º¯˜%Ä…ö2”ž'¼zà)¯wn'%L°˜¥!l¹&¹·c6ç`,¶ðB–žñÇ#¡®§ð΋sÁÙl9uœùr¯ ‹¦ËždòS¨J”æ20 Œƒ®+¿þîùÌÄy«µ6Ûp\‰‡œykýe¸û,¬-®ü ,çÛF÷”Íå½§Í´(φÛbE |©À­8Hiµ¸–Â3ëÃ’³úÇ@ï¼>Ú9EY£fEÈ zRoå¡xà\Èh,äw‚¤ÏBöfÏbT5Ï®Ü{r`e^,õÖËK.-JxN¸‡ù%°®‚T¢3Þ3Ö¹ãò7µFÖÙÈÖ%kaäÜÍ´fSǾHZ÷‘è2@#×:7o¿6%ŽÎ®jëlßÓÜB€[lÓº¦¢¡«ËÃy*PϨP*÷Îïá •/7¹nwþP!ÆËoœDi ‚ €y|£c¿L÷¢ÍΆ¡*îfßýS¯x1gÈ© ºÒ\Ò²â\#'¥$Œkí/‡óZ„Ýxº¨±T‰ É­”…ËJ–2U⣊™ ó |Ø“ée\Ÿm*úuƒ‹ä’ëϲmÊÔÒ3ž‚V@$Iϸ:ñUIsxëâËíz|rK­xõéiÔƒ÷¼ðêÉ럈}Ε+¤ÔÓÝ»_.ÞK‘."T'Ÿ8- ä!) {99$ ºf²«©²TÊ"ªuPe)‘] JRT8C|¥Öò~¡Õz ë û1»ªcÉL­ãöe`r=KUÑd°˜àà8Ó‡àgÌò”`{áë”Uq–)\i·^4tÄ20uÔ›q·Ó :úÔ®(JÖ¼zIìŸßª±™g|Ý„ý×u:¶3êK›C±”ÚR“ÈÉyÖŠ]9Sƒ$á#ÓE7^̲½ùuBÜ‘Zš•yeŸX#¡âYe•IK“ƒœj»ÔËÙrà7·¶ ØÖÂå“vv»ã,’§>Um9OJzŒuŠ»E»vëa^lùF3Œ¶Ún—)¸þñÚ ‰R”’};É÷%E0ÛRßûWyZWɉſ²ÙrÁ,´2ŠÚ8¡èŸ|éñ» )+«K:\L– ]=’’¤¥AÓŠ@ë ¤o]³¹¨)~1ç|úc‚ãTRJ†}jeIR½<ªåžóËAÇ÷̓s-„‹ž £ ÍM|™ˆq í*OÌGJ9ž°¼’púêÊÑLŠçS´•AË«ïhªV¥"Á-ºâ]R£Ùâp1ƒÖX|ZÚµ‘jöðf\vmuéñØ ä„€¦“à·åë6@ÈëWl·d=ñiÕFl"®^#F˜»¥ÅS…'Ô¶Ü´)jó`å#8Ð.l‰20æË¬µvkŽK2*Ër¤.I##Ìâx$ `Ž*QFNί>-Wó³w:¬mç×­v5òÛ’bÂS‰òðÌr¢’‘€• ç¼ó~æ§tRG—a¶šqµ:×ÊÊ®óvJ}®ŠÝBVµ´¥rËûò{Òµu5ÝýkvÏÙ­†¡?Åʵí' c'†ŒÚ‘ÈùZZ}É’H0ÌÝÛšÐbé®5rdqA“|Á}²¢0ùWˆâpq…¬(Žº—[§w·"r<MÉa<¡®*rQâ0êJ—;RUæåYКi~‹„ÖØ7A’·AÏ•! c¬(m-ïöó“úS¶ëm¡®Æzd ß’ÛYó%6ç_û¡>ø:i]A¼o™^Æ›e_ökI}Êûù2©R¼Þàâ”§%§ó<3nSí&kÜ“Òq•+Á#eÔž!XÏ`²4 wH£“ÊØ×Qj$¤øq+QTVWD¸”4\JUòÁÒ%—Ãé60S;’utÉŠs“VBKÇŽ¢Ûªð›¼ŽÆ>¸Ñ=“±kvƒY6‘&;ºÜ˜’$:]I JZ{â BÏ”ôw]E}D9«z]lŽJrb…Ä— W~rÊA%jú”'ŽOz«FÙ·5Ò,$Fg·ñå7b’âA䔉 Ryc²9XÑý·ê«ø²ª[v6å–ꢹg —þe¥е—œtu•8ÚxžÂF4ÙzÝE}#u×ïïqàÝœ™Jæÿë)$>ÛïŒÃø\@'A¢}¥œš5UÑ7a2$Ô´ãµp³%— ó¥µ-k=`þè`žô9L|C§¯dH­½‘„®;iq—\/#$¥KCKsšÉõYJzþ­—¸¶µ.ðf+ߦ³ã).*­»T€.a÷œâ}R¥dtp;:{ÝЦXHŒQ¹&¯ÃlÇ`˜~J9ò­?*³ã+þ¼çAÌ>ÒºxÍ|îxöfB"([´ô¨Ì¨KJP N×$œ}=µ]ˆh¯Ý4‘ÌÛYý›d¥»dñ[ªø˜W! h¤Œ c¢4Z·áÀ„仫ZônzøÈ[ AŸ)˜±®ƒ¦:\æ•g%I ¼ D‹¼*keRH¥‰¾Ãå¢)éO4‚§a”.K ¬’@È X`'=´\ÜâÿÑ¥ýÿœí½ÿæ ÿn˜7 þ ýðÙߊûqÔØ#YiÑ¿Âû½õH?þ¯ÿXt¶º ÓÏø]w¾©¿ü¸ÿúämµê]LYÜÆq¶ß™ É‘‘dêœe¼rPezÑǯ|cßD6væÚ{|×IÚòRã Qì$NCç€8à¶`€yZ=}tzJƒnÝ‘`ÛKŽ›UJLI!$…¶´à(ƒ’ž±œ‚9 Uô»>-|¹6Tsóqñ YE®ð˜ sP,Ç`¼ GaJJÀçLM;«xV]Êk??.Ž¥Äqˆ®0¬褭…ãŽ}FzÎ5£lo.lMK×Ö¬©<šm–k\y5ƒË !n(ãÕM-Ño khŒS]xRƒü«ãC“3Çe´'S.á”þð3×X+~ì{©¦÷è¬E6„¸ø´¬”Ûî§ •&s.ÖpG˜Ÿ_Tõª G¯CsÚa¦kjj|åà .¤àãB@9è$‘“îtãáL»½ã=ìUCÁ\‚ÂÝiY%Eä!IJó±ÐõÖ½ÙA´þQë=­1¤6ªágÈȆÛh J.-pp úòÎ:iR¯díìY§i[ŸqYËÌ©¹Í©—â|Ž:ó h䀤§–qŒh/êíÛ[ðl®j&ÓÈl6‘Űð)P()iæODŒ§¡Œ’жÌåVÌzÆ›mGx¡É.GiÅÄÓJ\ÃÅûúéCoÔ\Øß»E;hNLxÁ ŽúmÞŠê\GñiL°¤6xg²Rµ(úéŽçpÊ«—OQS'ͰÔøV(ù¥Ê`¯’ÖQ–T°¤ŸÚÐ'î§^öâ~ÞÇqÄ£[,*fß!¤©¨«ÆIAW~Gåªÿ ¾N:âA¾À)æQôº¤ÊBr┞ÀʈëÔêݦӗ*ZÑrÞÝ›kÏ&éF LXî),„“’æIïëÞ›ZÝøtý{ ­ûˆq³_kL’ W5ÈdØÆy~G¬è.G{äì¤A©…·ëì%-n<ë%a…öŽÔ”¡ÂG²\û r/¯¬[«\]¢Ö|G‘<ÏÿÊxn­X=g=~ýjŒÅ*&7}:·Q@TÛ”&Í%I6Ëž ¤ä…TŸ¢t÷/snŠªv§Òí´ÚÈœ±Î™ëm´«!ƃÈéOá@ 8ôM±»™nÔšŠ(ñ¬–T·ìðÏH 4µ,ûcúéÒÚ;»^C–V’©›a´§=á:‡+|Fxžc×ð u’s­ÛÃv[D¤uÛ‘ªŠ>j4÷ÒÛ 'õ£´¥)ï>!TÖ¸æãjî5/mýã\ûÎ6ë­ ¦Á¶T{ -q>ª úðï@Ïz2Í-mOÎXMioº¤ÚÀa|\ˆCËgñ)]ö®(ïÜèæØÝ4¯AˆÅ-Ì7„÷ÔW-"Î[™íÄ¥ì;$¯}heçβ•^o Éâ+}¨up’„ú§ÃCÈóò$¡JÏ~™¿oñI•GbCmî‰H Dhð(dÆq‡ â Üñ–ß’Hô'Ðè7\ÍÚŒÜØ¼ú¤Ou<ƒm q–©i@!kK|Sè2pœçODÙÛ›iíó]'kÉKŒ-FC°‘9žã‚Øi‚äzhõõÕ½õ½"È¿—ÆÆ¥ÈL©´®eü=Àd)¤«>bGòÐZú]Ÿ¾\›*9‰y¸ø,¢×xL9¨c°^P#°¥%`ó wV𬻔Ö~~\ÿKˆã\aX#ÑI[ ÇúŒô3œkFØÞ\Øš—¯­YRy4Û,Ö¸òk–BÜQǪ>š[¢ÞÖѦºð,¥ùWƇ&gŽËhN¦\ #Ã)ýà g®°VýØ÷SL ïÑXŠm qñiY)·ÝOA*Læ\ ¬à1>¾©ë@R=zžÓ 3[SPËà‡/Yu'ÿâÏA$ŒŸs · `íÝïè·bª äÞëJÉ*/! JP?އ®µîÊ §òYíi!µWÓ>FD6Û@P*Qqk„ë×–qÐ#J•{'h¿bÍ;JÜûŠÎ\neMÎmL¸Çäqט@KG$%<³Œc@ÑWnÚ߃esQ6žCa´ˆv-‡JAH O2z$e= d謔Pí¶g*¶cÖ0,Ûj;ÅIr;N(~ ¦šPòàž(ïß×J~¢æÆýÚ)ÛBrcÆ\wÓnôWRâ?‹Je…!³Ã=’•©GЧLw;†U\ºzŠ˜±>m€¶§Â±GÍ.P#|–°êˆ<²¥…$þÖ?pí:÷·öö;Ž%ÙaPã6üy %HåE^2J »ò8°-WøUòq× }öKÿ2ˆÏ¥Õ&R£”€‡„¤öTG^§Ví6œ¹RÖ‹–öìÛX¾xé3øGJ0HJbÇqId$œ—2O^ôÚÖèˆßçëØmoØ4CšûXòdJ¹¨.C ÀÆ3Ëò=gAr;ß'e" L-¿_a)kqçY(Ë /´v¤¥=’à'Ø‘}}bØ…Zâí³â<ˆ1à†x7þSÃujÁë9ë÷ëTf)Q1»éÐ¥¸ÊЦܡ6i*Hé¶\ðÀe'$(¤ý§¹{›tUSµ>—m¦ÖDåŽp¤Ï[m¥X4GHâ IÇ Ð*mØôËv¤ÔQGd°¥¿`Ï„z@a¥¨)gÛÏ×N–ÑÝÚò²´•LÛ  ½9ï Ô8ÁXãâ3À,ó¿€c¬“nÞ²Ú%#®ÜˆTQóQ§¾–Ø`ñ?­¥)HÇyñú¤µÇ7Wti©{oïçÞq·]hU0ž ²£ØhIkˆÉõPpgׇzxûÑ–ikj~rÂkK}Õ&Ö àäB[?‰JïµqG~çG6Æé¥z F)na¼'¸¶¢¹i&rÜÏn%/`Ù  ,}{ë@ë/>u”ªóxnHXûè C«„”'Õ>GŸÁ% V{ôÈÅûŠLª;£otJ@J#GC&3Œ8OV猶øŒ’G¡>‡A²ñͼ归–ëÓ<É`)È’~m ƒÍA•%#Ó—iÉC«Ûvûg½[¸0묒àiƤÃ(’òQæ‰I HV8«ˆúh>ðÝFÓsÈ®]Í{L´¤sµ-iq(jðü'Æ;Fzü]éCpm=Ϻ˜gCqͺéËRA—ÂRKÑ´g(9úç½Ýç»a"õ7wŽ#ÇqÇ>YÉ‘Aì€[(>!ÀÀt&âøw¼cÞSíú›¹±ãaÈùd8—r¡Ñ1Ø o¬ú+ØßÓ)fTÅ¢U݆ۦM”Öj|{Z}Å6HIBÙ@=¡Ntxn*è”ódm¥s¶!}ÆÖÊ^‡ ô”òJ‰8=6>‡ÓAÊÑa¼w3JzTꉰ"—m-Çò@äF á#Øý~ºg­±·Š‡jÛÙ6Cu.Ú¶ëQÛOë€ã¬¨##)Ozi{á¢dEw·.£V).Åû ©jqÿÔËÎ -góÏ_µ¥(Ô±áбSi·­÷SÕsÝ“.T O–Œ×!Ÿ?%¸ÓE9 ñàqé-ŠîíùÛÔ5SëŸQ ¨KˆŠ¼òP<ÙlõRA÷'×WL›yFê¯qn]¿O.\T¦DÚÙŒ¥¨©A8@ò¬çÓ ã=g[7ÝÁAYöl‹jH‹ŠPIÎŽr t¡¤„¤Þ’±õÒ¶Ðùz6§%[‡nÇlò~¾FšBÛBß¼ì¥9‚IÇ8öï l’³nÔ3aOu=EeÆ¥Ce×ó'¢çŠƒƒíåR³×®†n*[gî"½I¹+Rô¤¥è›ää†Ò•[m…ó¼«ÓÐ)Z½q¶ã6}™û‹oøÒ24É»1¥;ÈyRÙu·SÁ@ôØèúãF+èî#DSóãI“48Q"-¬öž“Ùb:›ðÈÇ¢}È:‹¤ïMŸpn¥ÇÚjŸM¬p €â“æä–š%¨`ùUŸuzaÛjJ)ÙÛÝ7tî$:™I6ÛG&—øã×®J†N¹Ýµþþ¸aÉÛ=¸{}¹.*½æ•²êÛè–\*mj@F<«l‘è«S¤Y*%(Ý[ŠÖIàÕµÄÄ"Sd·€¶PãyQ9â0O¯¾³q\3¶M¢÷Ä+™.¡Îë'EC*À6„¬’ízúãÓK–ÍØAz•{g|Ñ|Äu-4¸á•¡#*â´6sÞ8“Ÿ|kJÿI"=2Î=^ÅÛA—UóÒXm•Ès'ŠÀPvPdã¿;gÐÞ7rȤW¿Yn*˜¬ÿ²M¥{HR:Ãl—à …ŽÇÝG®Aï@ÏWS´dK¬¾¯¡ºûE+ò½i%¸À¤¤8•†üç¼ÈwžôÑesºª ··vÜ(sd’Ûfü™Jä¯ïYÆ è,Ÿ¡CÙ«Žäh—{‹qÈolÆqÄ5ß&c¡ñºq)JC<³Œhü‹[Ncî±Cº#ÔÉ⧤´™L¨§Õi2 º÷J½?§AÏen­ÏIf`ü@¯œÔÛuµ7ó¥ÀðòV2FO¦F4r<ÊöùÚíÞùÇ`ÍÊ¥6£…%*HÀ?²¯LœoÜ;êÙ;¦Ò¶“a[Åé(`E‰Nd€úóð_yÊóœ~k×»ƒo_Ahª¯rU" ÅXå0Ë> <š[ê H*Î0ØH>äh,Ù[ßIÛuɤ§~ª<—Öä[ŽG-9âÚ]”zÏÞ0~š¿ceḧ.3 Õ»ôDAUƒ±c†$’R©t¥%88ÉR½u»aͤ…º«\Ùµµ¶-ÔùK ¥—ÜIRHK«ÌgŒy–âAÎ2¯]´¸³Ü·EÜNU·Siz:mRA§ËªŒÚIï’IöV‚¤ žÍüQ!ö¥A˜Ù]‘ ‡#ºœá^#¬ö°Ÿ2”’>žº+o¹ÒÝ"æQÁa†’Có"†ØC©@ âG°PQÏ×I¦[–%ÄššéB€ °ËÀž%2 ©D… ½ÏóµÃ­Ÿu·¬ì(7•lkz›€·U-QÇ!éóKaNµåþ-KÆNz’7÷ÃjZ¯Ò¢U½Š7‰ +ñ9਒=x÷€uîî´“OlÌ݃bÔ÷qšCmÏŽû!d ¡°†ÂJ‚•ê“ù÷žÅ#wRD·Usp6|{ÑÂ,Žlº‰$”xk ’¢Æ i²ƒnîVæ@¶)víâl gm¦K!ãÚOË…:ÞG^à¯Ô+âÞÀ[Ï.šeƒH oì¨RR´”œá 6T£ÐÁQ>š>õ…ŬI‘6ô*k—\*€—TRùNRVÒbòFr{ä~§Wwɲڛ¢²m†àE­ul§YfuÎIy@‚„-‡R•Ž'=œêÿÃæijîçCse]ÔXKCÏͶOŠûD’£žØIå3ÈN‚õì𺇛[µèj^oÃ|HK ÈpŽˆo`‘Æ=}=µ›qÛ¸ÞÐï]¶ûUåF v™‰“òm¤`¬¥'ÏõÇ_C¤ÍÓ¶ã³2<׿ÛNZ”ZD§Q&K5-vG„•8É'µG¾:a•¸ŠÐå¶÷Üs"­©ÅOIb(CYÀqä0 ÙëÊà9þ5Fª³2“@ÿÞ8$[¶ãlxÍÉ!Å?$ù}ÔƒÒííÜi§\WÍu*~b-rÄ—pžN6òÚóÁAÆ?XgGÔ› Ñhå”›™Õ¯½ÊLxÛ’#ì@ZÆBJ u ϪR¾±ŒjÝS,)ÔÅ+t,L‘jé‰ty ªJT;FPó ¡Æ‚€è¯?AÖt65¶ì“¸*¡ØFr¦ª½›Ÿõx~ `œ¨x­„„ ƒ”,úŸ®ž,¦Ö½%ÈðwöÖ¯%ò\LY­‰.…akòçß9÷#\™v;Íç;Ïr]ËeÅ&4VC&TÒ‚y¡e ZØì(x‰Ç"q£3ß½³¤=;7oȨê~M›É­>¦\ Ïo¹5g>ÄO^± ›ƒp6›Ö›Syº‘€DšÙPÝSY>l¡K ǸþŸ][?£·v1ß·­ß2Y³Ž•5ä´¿)V$1“ž½çª-?º#Êv ¯ ý«…&5=‡ÇaxR› T7•s’]PV>™ÒÍ· {ˆuªLª;wœã9»bÃakPφ¡ 299×aC—~¿@ê[>=½Z‰t0ŠÅkŽ|º$^”$¡®èCxù¥µ~GK_wÅ7ƒwPªx×°¥Ÿš‰niIPÁ!!¤“žŽNˆBÞdS û{¹/Ú¸ f$Y¸û½ŸÀ…¾àV:õÈÏû5Jã|T_¢?9½ÇW!!ˆí 0è’d¼ûƒŸ±õìtC@£S.Ÿw7™„5¸+Ú zÉœL¢¢sƒ€¬Tc¼0J‘&¿y±R­¿"Ósž_3!+.6”ed­Ü‘ŸDÙ롪öSàìw*ì6•ûm)aæX\…º;Q quk!@Izz¯BwdÖÌ—.À=lr¶ãAº¸$ÀJÔUÇå\oŠˉJÏ~¹èz +ç¤[ͳ‡s2¥Ös섦3î¥YÈk%ÐWŒƒ`õ€t:$¹¯oZ¶—ãŠöª¦üš$4†@/E*J› QI“ëtíɹ¨>³[M[[XóN8¦ìß`²Ê¢J¤)³ dc°”¤ç£¥+fc7¾)ä!Èò%Ê­žô©L2Û Èp¹ ΖÛm)ýr¥sÐËDÜâÿÐtá’¼?ŠÛyÏÙœ“£[ƒü_ú€|?Ïü%ÑcÔÍ@ÿn²Ó¥…Ïÿ¿•þ\ýaÒ.ÝüIÓßø[ ïʯʼÿÛ:CÛàùuS>!Ì‹²&È\xâs©[ˆZRSÊ”ŽÔ´Sû_×èmT³¿$9ÕÉD†!¨‰q#²]ž€Hð˜QQQÀáƒëûõKâ+.>he—ÞpÚ”°´¡Ìˆ²R¥t1O¸Ðºõ[E„—ho÷.¡Ë .Jå:ç#ÍÔºHe*=ô1Â;ÓNÛž»lF r=(™ó lUÖÙEuŽ Q9Z\ŽØ*PâsœŸÜ5–Ù·Úu»í‹}Ȇ܊µÀbº îl¯âKŠ”SÚ}0•Ƕ¹Ì˜›‰WŽ9Mñd©GÇœô9«ÉQéHq³…û%Dƒ€3§¿¶áÛ"}5¦Ù ¨žê1X¨B%”$öö R²B°„§ëj‚Õîî7PvþëÚÓ¢6ӡІî¤=!¶Ç|PÈ{œ«€1}*7óŒíÃ`ëîÉGÏÄKn®+Jãç%ßuÉ$ûu­;N¯iSÍ{mÙíÝËi)¹h[¶OÇ‚ÓHJȤ¸¯º9¤ãèÛÖ6Qœ~‹©-m:w–Ìx&ú3JñJÂCžbUØQüó =ú/+nVȸ¯¡rõ3ÂÔkˆ˜ŠiÂBƒ„„ÐëÇ^¹Õ)»p}ƒPöõÅt‡qS¦  `?Ê„•}B–ŸÝí«—MßYJ€üÇ Ñ4 "IÝ’RãjRp”«ÄIÁ##¥$÷ÑΗ«¶Ý~ìnÇoĸª[ÞBTÔ™²ޤ“É!KO•+ •­µ!Jüôi#|C˜‡nõ›ŠÈ¬¢Jf*±§]qÁ–ø†”•/Ó°á#ò׫ڷNª¢-’ª¢1:Bße2`ˆ²Ãù$ä¶ây}<«Çdý5Œ}§ñ:š–Tvož•’˜‰ZPI+IZ: ò QÇá#E™²a5s7½\)Aá#À™´UÄ,Ôù…¤îÏû4Û›²e²­íÛ®içšz<‡\’—$ŸA÷­þc¾}cÐi~‚™0qƨZ°|H)æ¸JKÍ+°KM¬¬žÓÈ ûçNJq#qFSuq.)¥»òò¬©c-Ÿ@z¯øP ÏD”çÐúhu‹3ì\¶§rlÑ%Õ 4‡üTz¥ää­¦GC¥äŸ¦ƒ[ô[Â+”ÿ¦_cY×ÄÊŒtf;‰8l¡qIõÊ‚Oä¨LøŸ"–æêME  ¸e%.;òL!™)þ"]Y8¡$œõŒè%ýVì]¬öSY ñ(ÛE— Gu÷Naµ‚F € òé¹úê‰;“ÆÙ»ÎNÚj§Çôh+îkkéÛJ6ãÜæ’¼EZ\yÞhqh_M¸Ò¹¡IZGœ§#8 8IPvÎüçW%†¢%ÄŽÉvz#ÂaEEGG†¯ïÐÉ(•D}“Y7æc·òVõÞ dÆq§Çôh/E³ÝV ÓnK-ºÅ|v›RÖeµ ©ÖÈ%+o A â×U¾¢¸ú%χžK“%ÌŸC8 J|D§×y‡z^Û÷u[3pÅvGê›ØÞf,èM4§™s89‘ŸE9úiãm[n[«·öŽæ¤ ¬’êÕ?ø<'ƒíÆ$ö8e){ÓµdnZR÷fÑÜ;q¼·ë¦V6µºÅÒ–]s' †–%9ï²@úkvÀÛ°`miò£Î©¶KKñ•ös*’ü`@)g-:¥ œTzèc¼ä%NÚBæYî¦Y/’™–)”Ê^Fq€òâ¡\°G¦tV>ßÚI_[[aHÔ8 ‰S]‰]`XOa uÌ<£ÇÝ œg9Ç  ŸòÓqç75Óq8J5k}M3Ÿ:”\ JºõÈó:»ç×ND˜ûn-ä™PÒeÍNÝAm åW$”B°2y uƒ£Õ>[nõÈÚ;ÂÁÛ9ì¼Û .•ùpÆ뜠|¼qЃ‚1FͬMŒ©Õ»¦|*i5ÿ%%„QºZy@yжP0súäœûŒãA·h]* Umç§"d(-Kn4rÂÑR\*CK9ü!#óY®_:ÞãMÕM}TV‹-Æiörl…`øk>H8>€ö:ÀõÖ»:ÝÓ5uµ»=«+ Jö‡ åFf9p¹¤¼ÒdžIèà+†{È9Ñjw#WEpߨ¬Ý…B”ã-Eqg!OÐÔW‚Ãîõ‚’Û|Ú½‡áúõªU³¦7CÛÆŸgÖó–„øë[HBòŸiy8ìƒ×¦‰üIÛ2®¶µ[öÑ`Ø×Gl%„4fC‹Oº\[ dù‰V~§ÓG6–ÓøoQ°+¤M‹6f%rä%6ò%´—*ðÕŽC=;Ï]èè^ä¨+à³pÜi¾…Ô>%%¦Õúÿv„!+Ïí¶FÉÖåmJö÷vþnßbðexŽªÎlD<°ßIt…#Q%'¥û]l¾’ÏÃö¯hv%7ïÊ–¥‡VÛ­¸9ŽšJ½ðҳر/â.Ðvцº-[½lž—]KAC>ž×³öiþŸD,¥m–ŠUî¢AÈN¶M·ø‰_maö7#{·ŠaÉs°òœÒ™-ãÜ#Ðúè$j÷rþÓ°÷…xñª§&D–]=©@%å¡R²}À¿=6UñûÑnÌæÉD&MQyRNBžQ Ï„-IC­{â>ë;‰¹6k®¡¯Ã%n55sÙN%IPú)(À$D`À±ßsãF¾»ƒxÔy ä;Z§¶¡÷g„ÙRÆ3Èþ½VÜ¡¿’©Ío-šÕ[ØT™²WTR¥$Ÿ#L-Dåg°qÀo]l[nTvõkûŽ…ØŠS¥3âÇCªœ¡¥,’¤•zd’¦«ÝEb,¸Û~ö:~Æl¸œªY¿1i_Ý¡•¾ÚÒ¶Î? Wޟŧ-…]&¦]o»j¢8¶îS•)¦Ñ!)PVIP'ùÇAE;ŠvÛ®b²Æ’©d¬”2™Í²£×ˆáPP?Í)üõ®ÿÛõvU.Â¥«X«_Jº–‡$‚^e@ ë–=5Z¯}Y9¶c«i|2¨£‰Nè‘l%FO€”ãiH=(œààýs¢›Æîè«­ž„‡£\-N½)•3úŠ(,:K™õåÄz`w XŸ_¶·æ‰n͵-t—ñå½*Á%ãÈ}Ãk[Ö?4ýÓ6쨞Öá®Jèä²âd.\zùIeŒuÅ´ …ž³È)>¾§@)ê>1tä†ßÛ Ö°Bc¼¾n¬£åžmçˬŸÌ޵›;® ×îÎì9öªù¶¾Z´$ z¡Æá6êzγ¨Á s¦×1.ú.ê´ÜvÕøÍÑøìþÓ~&T{ÉìuõÐZéS‘¸dn\“R[SlÆ6±0ÜR mAÌòÇ’@Wìéí¿¶÷Ò†ÜÅ*DGàª%$„íòÒAåß)£Àg#œŠsÕ˜5b­»·´æk¾VK®Ð’ëL¬ ¿!öÈHÉÇþã©ÒNæh8”ÂM´À¢a+E.¬„‚® ­a^ã$þã¯)¨bç•KaníûðbµAq—Ìø8%¾h ’z¼œì:–ƒâ,8ʵUKÒªb»ó5VÓäÙ<Áx<”žÕê>™ÏLÛbÂ¥4ìiéU„Ø*C‘%9"Jpþ%¤yœÖ*õ'zBŽïçií§â¸¤ºó¯:—^Y'ñ). cŽF@O_Cë¢òfíÔÛüÛÒ6œye)·c±`ÓOyýHIŽ“Ëñc IÉѲ>m‡~&%‹ê<¸¹j“ÙqZSí÷†š *R† öô=Ÿvå·~9Ví¸û²*$µ1ز’\yJQóœ'$Ÿº8Èì`¦¹LAØ3bØmU76w‚°áLxá±’‡ŠÝ W.ð1È^£ÜnÇ›†ÞÛô?!-x–2Z®±Ž—µqm „ñ>b¤ãýúÊ>úÜ÷dÉêåmöZJS_cL4µ (%)xH_e<ŠŽOI=‹O|Uf½í-þ䦚ühŶçÁ&*Þ}Dá.).)O­ë &ÅÙV±ÙÛ‘¡xuKšEºÜS„ sZ<ÜXú’ÞXÖû*ûxðƒ¹£Ã­é’»i 4 ºð69\Áÿn·ÖnÚ;ˆ‘)--¶“`…†,zÀHxƒÌ€ë£Ó8þ‚z:µg¹ªª&Çv ƒ³ü˜¶mVI EŽ£[J–ŽDp¥Œc­ö씹ÖV1˜%ÚR0°™1ù+t±€AKIZ[ÎÇ%zwÈúh´mõ²-++šTÔÂ"Û‹&]²Ÿ˜ Æ|ÒJ¸|¤¨tÕ…ÞüAµÚ‹¼n¾Ð$Lùk:øï1ÒŒ•¥×X-µ~ÒŠÈöÁ{ç{×%Ç"ÁÕ>É;k kŒçaAŸ ÆJ’N2¢µ`ã­8UQä0Ý䆖Ú%¶§añ=[â\RŽpR x‘ÙÒÎìkqËrÀ%ZBºöòõŸ.›¡ï}Æõ5šk¦4ëWeˆkñaòi€}A<¾½ 4 ½íœ~ZðÙ®vêjÅ¡þÝ»uŸËT>y~*mÅ},š?íÖZ=ÿ…{ú°} þçHÛÛO?á]ßÄ*ÿôÿiZHÛã¤è{¶²5ÅŽÛ¯—)XvÕ\TUÈŒI*v€T HÇC¬çÐi¾Ü­­f²òóÂò$̦èB¾È)°ÂžBÆ=rp-ÚÍf·qíYÒ"¿%–m–¥¶Ï‹Ì§äää§ÂJ–HõÀãÔ ‘kynÊäªÙØ»©Ž$ˆ«¯y¥xm%I'ŠP)x T¤Œ\MoÞ(UNÕ*¬—Yº ‰ RÅ’›ª RÕÈ­hu¶ƒÄ‚|ÙõÇ®¯O²‹C[svý[Ü}µ­çÂOê¶Ò°2í$ é'j¿q6^Ûª‹l탱ҘnÚMñÛt aL¥¦ÜO„{Ïnðë²uv=æÚ¹n¥L T¯ºf¹ÿÅäPB Jü¤Ÿ½ê*º¥µ·”òeTU·Ä~S“’¥¬|Ì¥(eEd×.Ç`+LÛJΦÅ0+"ÒUHªšÂžqmÃ’àC¸üGž2¾ŽE}FÌÚˆ†dÃðÙr&KIm"3¶u)([g¡ó$ç ¢;^Nî™vÕ^اøyQ˜S+ó+jKˆ rVB‰Ï©HN?=mÔÔ¢ºíi))>-è­RêYÎ@KÏrq'>ÁXÁÐÁ¶·vË’Ûô/g̳‘âËvgŽòÉXÀÃA÷S…c>nDôôÖÔ«„ÏÛÕ‘(øîôMS •&Ñ ¥å@:µ}r’B±é¢ ¬·Œçé>õgp8Üeñmêy©LvÉ=<·Ë‰úž#®:Í­yºk£ÍrEæÞÛQ¦Æ1¦¼d¡¨àøV¯¼=’”«¼§E%ÑÐUK©bnø¿‡u°ó/T³%qY9IðÃa²Î@?™ïU$ÃÚ´JKpB¦È°xHnE„±–ÂÐJšaÒ׊¢rA áëê4Z–†NÜÛnG¶ûµ©ŽéukŠ” ô¦ù%Žû'õï@©>={¸ìm$¢±ï›nÅP]¯Ž—¢T…0µ-Dý<Ø=i‚Äí»;iÌ2äÒXع0%®µØå.Œ¾nÈ÷ÖË·mwZÙ;v®dš¶ ’‚ßi ).…! eŹ…EÕê5žÃ¡²«[ÒI½ZméGŸÙí<”4€: däƒû$h,·u¾£IU]\êú§d1á²õ­U‚[…Yæ,´Ò@OXü‡âÕÖí>Óƒ&³xo6Ü"2^‹-•¸¹xr˜ü‚G¢¹¨ý5 m½§çâZ Á3ÅQ”ò®+œ*O¹JÞ1 ['œÇ¯¯¾µßlªÎp¥³%ÄüÔe;—ëÕbP•t†Ò€p:öìcëÞ€T {mȱ­ ^JƒbÔT¹-¨öë~\•g²‡°q߇ɰ'ˆè6Æ“âý³oDoЀTØfÒÚ ó>e­)qµ©|N9Ÿ^Ñþ:ì+é©ð‰Ô[•O0Óã'ñ$4ä’T{<€9ô>šgX‘[wßUï-ŸGȦ5c+S“ÚU„/?ˆùsúº Ú4T»OqÔÖDCm.dF™•(¼®I ”¢KˆpƒŽ¼0@óu‚Ar¶µšËËÏ ÈC2›¡Rû 8¦Ã y õÊAÂtkn‹·¥ 9qfÕÅÎ+˜y—fPªÔ_J=„´sèH©8ï-Ù\•[;u#qĘQuï4¯ ¤©$ñ@ /‚J”1‚3¡­ûÅ ©Ú¥U’ë7A‘!JX²SuAjZ¹­¶ÐxO›>¸õÕéöQhkbÎrß«}Ô°Û¶µ¼øIý@¶ÚV@ý¤$íC·î&ËÛuQm°v:S ÛI¾;n„ )”´Û‰ðyíÞvN®Ç¢¼ÛW-´©*•á÷L×?à8¼’ S¡)_”’âc×½•]RÚÛÊy2ª*Û‡â?)ÉŽIRÖH>fR”2¢²@ë—c°¦m¥gSb˜‘i*¤UMaO8¶áÉp!Ü~#Ï_G€¿¢¾£fmDC2aÁøl¹%¤¶‘÷]JÛGº””-³ÇÐù’sÐ@ѯ'wL»j¯lSü<ލÌ)•Æù•µ%Ä9+!DçÔ¤'ž‚¶ŽêjQ]Hv´””Ÿ ôV©u,ç %ç¹8“Ÿ`¬`èNàÛ[»eÉmú —³æYÈñe»3Çyd¬`a û©Â±Ÿ7"úzkNêUÂgíêÈ”|wz&©„Ê“h†Ò‚r Z¾ƒ9I!XôÑÖ[ÆsôŸz³¸n2ø¶õ<Ô¦;džž[åÄ‚}O׿ּÝ5Ñæ¹"óom¨ÓcÓ^2P‡Tp|+WÞÉJUÞS¢’èè*¥Ô±7|_ÃºŽØy—ªY’¸Ž¬œ¤øa°Ùg ŸÌ÷ª’aíZ%%¸!SdX<$7"ÂXËah%M0ékÅQ9 „ðõõ-KC'nmÇ·#Û}Ú‰ÔÇtºµÅJzS|‚’€G}“úÀ÷ TŸ½‹‰ Üv6’QX÷Í·b¨.×ÇK‡Ñ*B˜Z–¢~žl´ÁâvÝ´æri,l\˜WZìr—?Æß7?ÎáÄ{ëNåÛ¶»Š-l»W2M[ÉAo´†— „²â܇¢ƒjõÏaÐÙU­é ¤Þ­6ô£ÏìöžJ@…²rAý’4[ºßQ¤ª®®u}S²ðÙzÖªÁ-¬óZi '¬~CñjÆëvŸiÁ“Y¼7›n/E–ÊÜ\„5l6æUÏr6Ù–Â`¶ã­>2äëiBZñ@Wº’O¦ž«(˜J+íî¯è¬"LBZƒZÃ2[(X-¶TàK^¸ä´ýU­grT³WfÍØntðžV¶ôvä´ØUÛmx9ô*VO¦«>öä°jªÏ‡vPÓ* i·lÁKÐæQ ¨¹ÀŽðæ>ÃA·m éQÜ”Í·ÌøOª+°— ¯ gƒ.¸–ë¼@õC‡±ݱ® lÈ7 ÐGu°êa¡–äð¡Œn"ÐWL‚ü óÒ좰§_Κm Jk=þ÷‚>¥€[*ö‘1¶C{*mÔh¡nH­‘,ºø›C$—•…Ú¸$¯C@YÝ£²U­¥t„@KE“VëJqÂOݺ”¾ºÁÜã@ýÍ“sRµ6}½Àx?>3H.6² €¸¥ø©_¸uŽwñ­ÈPn 9jVÕKŸ ·ìÄ ŸÔòC@޼èÊ{Ç29c¸§?WýˆP]“ẶëS.#®…*K‰òƒÙR|¿¿V'×ÉÛõ¶tÐ ­Óg*BК÷ͶW’Ñ\»H™? -kFß~j©öÒ¥ þøaðþ®Ê*Û‰uS9LÚ©RDy)¤%$‚ÁS cõõJÇÓVfÓÀ¨²D ÛŽ5¼‹;ST½j†K +8mu¢°OC8ï®Æ€—Ã`+™}Ë šédƒó%[ìÉ[Ü’p£%%N$ŒáYëÔ¾yêTJ”ÿÄ:Jqäøâ?ÙÑÞµŽ¼6Û u.ÿ8¤œMs}Ñ|Xï/0ͬiHy訋™ò- t¥)¾(9þoAÞuY[?âm×ÈVH¨…RÛ2JÕ55…—žIÁ*tøk¯Öpc׳ §2~ÑÝ0-n*y†AŒ«¬]‰!lÉMŸÆŸ`_°Ç¾º5<ÊçT_ȵ1c>Ü8Ó&0™ÅÄ/°´…¡iô$`”Þ:yA±6þäz‰ò+¯Ë®o¹kq.mº$Ð540—íkê?0U’êT§VéÀÊÓ³êÁñ:ÊÆ6ÓŽÿÃÈÛ’¦©Ô·&u¬–^f:›Ž“ÞÀò:³ðÏq¢ sNo)» kÏ´¢Údʊ儤('Šy•„$œø¼N§Z[FºmÌ^~¹ém®Re2Éi¾s\«}N7È!]çšÒ“Ÿ.} ¾Îº~=¤Šßˆ4;Z5|gî©Ì-?äÛNŸ)$"ð> ܶ饢Ão»µ¢UÈd9 ·­c¼…~ùyRú’IOé‚qÙ»ƒ|+qÙÀS1lbÇa2&=aV§8Œ¥µ2BV2¡ÐÁG¹:[Jíªšë_³~Ö <·¤¶ÁÄö+HRsú¡Dúõ鎴í"±~Ì÷vì7«b—Xn<$´Ë1r:qhR‰ä;qå-?ž5ÔaT¹sTndßXFTY…O6Åœ´1(VCJóñÇ`’AýÚ¹ GÜ[ºË/³(«`Û0_˜ôH«˜8vÐJšqkÆ2¤1ï>€íVÚ°)¶›¸)ç]qAeªÛGÀBFF”=á8 OjHJIj•Ú]ÅeÄ_–AµªyèËuG JRÂKA)ýµ{w룖Ÿ ©·¡îf¨¥*z¤ªk.»"0v¹-N¡?ˆy²‘ô½-X¸äŠ7ÞÙÁŸ³fM\n"ObHm#²žm*Éõò¨úŒ峿9UCwTLÜÄ-.|¸ñ㤠ðÔêHO¾2¼ìæw54'ÙÛ7»Îu™3]Ž˜&;m^b§\l© W¹P÷õî»¶©þ$5[_& Ö,6êÂ"[PŸ)å€è*ë¿Ppý£¢Ô_Bvµ­ÄGP|W’ä(EÑ$ƒ’2ãÈöä=qõÐkÚìUÓî÷,©gY:"-˜©®¯¶2ІúÅ+Ê”;é)$ߌé‡*š~ïQÚ!Z\1- |¤šÔ '‰-®9ØaKõý(mýÄý–ÙûQ÷Tûå¢ÀD‡€J|¡µ†KŸ"N;Á÷×pýåì´Ü«mÝÁ›¼Iup,d";¹8R8GAçŒd£®ñùè Zn éeÊuMRMp–È”ÂDÕzÉBøöqœ¬wƒƒ¤HÕÆ¿{@J'×I`Á°#Êl%^,2£Éå­+ÉV96qå9öÕÅÃM®éù:Y›‰ÔèqÆÙ—. qÞ=•“XoñspŽõgsµ?*ÕÃç×ö–Þ{íXóJ]ø|#Ðõó)(*ï¯)ÓG·_ÄÿF‡|;ëânß?ÿkûtNà}ÏôhfÀëâMÿÛÚÿµ¬¯O¿áS“ñÐAOý¥i*€yFž?„rø‡ý öŽ’èÓøq òý0Mæ×U”4LŠ›Gã+ÂJ± IVGYã=ŒàéuçkäÜ[µ­¿ô¥M"Ü÷—/$Ÿ¹k•”ž‰JG±Ö{¦ªu՞ܬ­f©éOÙ¸–ÑfØr2¿J'šJTÀ8ëמ¡î—iZL€[¯wfQÒ!Rª£"J%p®il¶œòô uŸ}\M$®Uj˜]æïz柉y~Ê!Ô'¯ M¸á+ëõ,dôuŽì…°b³õÔ«SèmØaDr2™ ¾ihO?ÇǾ€Óäý¯SžLay|ÿÚ,!q9?•yI)(@Õ.r'Øè5ånÙ“I;ô‘ÚèÖ¸DuíÖœRSÒÒÃKuŧê´81ŸÂ5FØÑi6ÝuTkiR7-šã†•":L’NWÅD¤yJõÎU¢kî»RåT+ª’•¦;†8}¤´€’•+‘÷pç?ƒ\jêÖžªÞ$› ªÊ·PÊ|'àR¼âo™ÏO¸…œ`(çéÓ/ÃË»-È$ZÖ»N‰²·,#JŸü8ÆOä†Gˆ¢œ¨Œ~mõVü™ò²Ÿ-–áa·Y\$²¯ÁåxcÄYõôâ”õôÕ핸í%ÝÙÕ?RʹȈqWÎñmxO˜)m ”zœ¯¿tê¥[•Œ¸›˃…<†Y¼h— ¨ó†Ú29×Oæ4£º. ÒCe¤ÓÃ\™/–m+q¡²² \<$+#9#š ÚX÷_hQîôíVÄSí@œ§$4·)SÍ®Sn­E?@…¡NŒPnŠÖ,ëî-7»²M«*L¤;”Aµ–Û'$d>ž¹[£—´‰'m½*i@3bÕÚ¶¶QPñ£¡¢Fr|Üë`…qÕÐJ{j–-`¦fçàücŒø.öp¾»8Ð2Åø‹UZ©/[7pÓqT‡6Cl¤¾œ a´¤!#>¾Süî´Z]æÒ¬&ßÚ]-·\q¤1fã-àĤ7Ž*G±çæ>¹Ö¶(·4v\žšø’æª3o¥„Aá)|!§ƒØïÂÆsœhN÷¯núØ}¡ ;÷!†]j/¢CŠüGÄKj@Rsè HõPïA¶kž4—¤m¯±mB*Ù»i¯Ê‘ ”°µ© ( ”«¿Ër¢«©SÎqØÕS ,G´œ´È*OK++‡@€}>šKf¢ÙRyKÛóniâÕx*E„¨°ÞT°<„¶© lä÷ÀŸC »][••‹8Ûwq@a ¢êcKð×â‚GßCd¹Ÿ®‘ûGAÑbm½¯2},84Ön#—ðH@üGrQ'ËœàO]emS½m^A«ªq¶Lvã´ô„"BÇh ůÂâ<‰ h¼ÛHH‘.Páâ~XdzYìd ,v@C×÷kÍÆ´!Ö3*±0lc”#í jæV†Òçá ã4©‘ÐÁ`õ€q DÛÛ7oÔî »;åÙšó"Bî™SÊâç•e|⌧ '^„Û¯;_&âݨ­møÏ¥*i.ç¼¹y$ýËXðÔ¬¤ôJR=ŽŠØmçfZ3Ê™V¬¸ÔuÚKmØéJ;q^ÙæáÊH)茅cM4»JÒdÝ{»2Ž‘•UQ(ƒ…sKe´ç—¡¬ûèW*µL.ów½sOļ¿e ê׆¦Üp•õú‡–2z:ÇvBØ1YˆúêaU©ô6ì °¢9L…ß4´'Ÿ¿ããß@iò~שO&0¼‡>@ÿí¸œŸÊ¼¤‡” ê—9ìtò·lɤúHítk\":öëN))éia¥ºâÓõZÏá ±¢Òmºê¨ÖÒ¤n[5Æ+ *Dt™$œ(¯Š‰Hò<•뜫D>×Ýv¥Ê¨WU%+Lw 6pûIi%*W#îáθÕÕ­=U¼I6U•n¡”øOÀ¥yÅ:ß3žŸp) 8ÀQÎ=Ó¦_‡—v[Hµ­vd)nXF•?øqŒŸÉ D'8)Qü:Ûê­ù3åe?:[-ÂÃn²¸Ie^#ƒÊðLj³ëéÅ)ëé«Û+qÚK»³ª~¥›i‘â ¯âÚðŸ0RÛA(ô'9_~éÕJ¶/+q64—+ y ³xÐ .Qç ´dr®ŸÌiGt\A¤†ËI§†¹2^1,ÚVãCed@¸xHVFrF=4´±î¾Ð£Ü3éÚ­ˆ§Ú9NHinR§›\¦ÝZŠ~ B Ý¬Y×ÜZowd›VT™Hv(2‚j -¶NHÈ}=r4·G/h7NÛzþTÒ€fÅ«µml¢0¡ãGCDŒäù¹Ö4Á ã« ”öÕ-:ZÁLÍÏÀ!øÇð\ìá}vq e‹ñªµR^¶ná¦â©*l†ÙI|)8@ÃiHBF}|§ùÝh48´»Í¥XM¿´º[n¸ãHbÍÆ[À‰HoTcÏÌ}s­lQnhì¹=5ñ%ÍTfßKƒÂRùCO:±ß…Œç8Ðï^Ýõ°ûBv+îC ºÔ&_D‡øˆ–Ô€¤çÑ@‘ê2¡Þƒl×ú}4–ÍE²¤ò—·æÜÓŪðT‹ Qa¼©`y mRÙÉï>‡Avº·++q¶îâ€ÃAEÔÆ—á¯ÅŽ-¾†És?\%#öŽƒ¢ÄÛ{^þdúXpi¬ÜG/à6.øŽä¢O—9À9žºÊ>Ú§z2Ú¼ƒWTãl˜íÇiéD…ŽÐ‹_„Äy@Ð+y¶6‘"\(2¡Â'Äý ±f³ØÈX(쀇¯î×›hC¬fUb`ØÇ(GÚÕÌ­ ¥ÏÂÆiS#¡‚ ÁëãAÈ·.Éj¾¶®FÜ”¶nÓÏí'S«VJ¼¼B•Œgð¥)WïÆº;*¨ŒQßΗ}i/7^ogÀmœa$êµ{ÆUëÖ5~|ÐíYy‰5¶i±eÆ"UãqÒN8•­¼ƒGG¼õ¢ñvþÅf®;Õ5ÍÚ®0K(²¥Œªô $ŽEo¯Yìž`vF€$í¾ª‰Uû_o|7™²E›rd8ìôu¨'¾.;âðÆ rVƒžò5¶ºnú–ýë1+ëšj4‡<¯¶ ÛoØòm*ålj#.c둪Î7{Úª¯v\í›1)-ý’h7œx¨}éE±’0HXë¼{j…ÏØ1ìå¬!CqÅ´©ÙKŠû¡ Qû¤H%%XðÎzÈIÐVÚ÷6.XÙ&êÁkÙW„Ô&BçȧÊÔ‡2@8àUÇëùµ¢,:ß³äíèñ¨+ÞC‰B b„ÉO¢ËägáŸLe'Tè÷|É—7P>zºLg¢‰Š±bÅ´O)!#ÇBT²=NKH9ì‘¢V1(à:ÄÅoÝžšÕ¤¹)‰vAW §“Ã*pç²Tœã±®Ýÿ vÚ]zà ±*:P‰SãÁ†ÚéWeŸ|” ÊB½=t5«Í³¸îT‡6¬XУçáU„JPüXS<Œœ•zào¨¼§{`\0‰L[ÎJB‘ ßi"–p¶Ó¸RAëÃÉ#¬èFÌ«‹ióêQ&¼aâ»$¥% `ƒã(:ÂT®ÁJÂIö'@gkÎØ»i—)§NrÊ,¢-k²2ÃI_ªœCmž$]ýú9U;hÙQ·úsG‡KªwÇ‘‹X?x |üNH¤ýÕªvì"²å’¬þZÂWß)Åm™’@ü!âúB²Èz'Ù~ßÜR·5V²—- ñÛ¨‰.IÁBØSh’œ‘éêsÑ>º ;’ [§{¿_Okfô&™IùǤ¸ñI> ›à¤Œ{º?MP·:¾µ6j²HKž›1RïÌ#¼ WIRz9Ïõè^èødåÕ{?)ö«Ž­kðe© °ùd¥@pK§Ã[~¤ˆq—¾™ê¾YlÚHÐänhwÎ=-ƃ1—£)iâ´$øŠð•‘ŸâÉïÓ@¿a–ÑÖ§JzñçÛaLÂndÇà|ºBºu•:°i!'®±±~fâªT ¨êû:+Éáû‰Ó‚’_((s'#%ö::lø—¹àÖÀfM¦Ù™nˆ§ÒÛ“þY°âRpґ௓+‰A`œkœìûÈ(–Üvhw2â.+O¦¾NëL†ŠJ†RÛF2œZûü#¿_®† ‡l5/oÃC1e¼°úV̆”¬–”÷†—U€ÚxçÜ Ü núµLÞɶª\æâ·…¼–”ÛM+H•-Å—æXºÔè¶Nòsr.—uQCŒ×ÌÇ€‡ ¥LJr‡#‡[JR¡‚G^à÷ŸnwFæp*¢µ»—f]ºeÃ([ÑŒd'+_ßøjQð¶Rp’8“ 5Nås[1/µlÜ¥´œ5Á×çÅOãÄo>É#òëB¯g×mݼ¿³+è«7,¶Ð—%âDKžÓÅ—2“êþ½QÜÛöqÖF¿i½iŸ¥š†æÀa3o#JÏò{è•+߉Ó\ï7 !\ÕËܶuÊh§åÚºŠàPψ — ÓŸÀYëÓ‘üZ ý5™´äx{“o%›œ]=#Ü ­¤y}0[V@þQ‚©sŸYu|äÁB[iÕ×Åi+F{@Km„Þå¦êš»jRµ<õÝ Ì2â«Ý™,JL•ŸÄ¥7da$d)νµMíéa2µ˜5»’‚d6X¹–õQZëÜ*#šÌ©JPÀ =c$h9ý¯»#Ú=ò»’]c0–—u“5 „Œ«È–Ò[ARFXÏöë¤F©©Ü,7¹ŸÙ¯,b:‡ØyÈü—œ^ABž)OC$aD€z÷mÁÚÖ‹ŠýâvÛJC&Ei¶vJ3ÚÒÓIJYYÇ©J–³ÝõìÃ6ë7ÛuÁ-µ0„)rmd¸ˆèq¥ 'Ðá O¦€JåîÈ”®Þ1µÑ[a:ì©Ç¤!ŸâÁì-¾ =úä¡GùÇZ>"ÏÞõÇ[’k!<çÇy¶”®`œ)│S×”6G_¿7n’©‘mU¼o§Y$)-¤Hj%k-%)þ5h2CŠÈ9í>¹èkû…ªêû'"]P©ç]Cë®S±ÒÊÚl’ãIsÃ^{Á mxÏ”ç@ÅPÍ=´¦‘T‹{–[):G€SžÔ©ðÒ¶Õœù F}‡zŹÛ^,ÞÔ°7tf¦áFvgå²IÈBx« o×$çë‘¢?s!¹WÔôÒ]†Ì”"KÍK€…(›Œ´%±êBÕì3~Öš®}zfï=µ.RµÍ~¶#l8“ØoŠ‚ÐRŸL€¢z L;ïˆ;IöIáõLwYZP˜NA„ó äœâÝâ?I zõÖ…v¿Wº¹=·¦ÆRP"2ÂIã÷AÀòR:à‘“0ÖfQÌÞKmè*Ê[ ·ù™iðÜÇ™Öˬ©¤¨Ž%ÌŸ¯¦˜+hl#†«S&wÙO¥§£=<¯Ž0¯ ¯ Y$B¿©ÐmFåØ N…>¯jν0T@–…:·Ò…~'R¿TžÀRŠ}p¬îy›r5 Í´w.«-gê`‹ d:99oŠ“ƒ’H PYߨ2‡®´¶Ž¨/2éa Û¿)á-  vQu¦ÉÆ0¢ÞO¿±M£Úô×Upž¬¡§¥8´¾_™¢êBŠBZmL¼1߇€£‘ƒ ³Y¶cÅUͬhˆž[Lï Ͱ:#Ÿ„âüÑÐÆ©4ý»ræTîIv¬=…FLŠfç–Ã'’Ò¢²„·Ž>Å=vuSgü¶{p›h²¶ël8ÛíÆr¥QÐFG$‚ÛØFF|¼‚»í#]o%p~Ö‹¦=ÓîxŽA²„\@PkM©>rÒÎ:PRòG`P簩۞،KCî¥ 0¨ûšKd+Äq,²”¤ŽÈõÉëóÔöܺ\ù{…Èq1_àŒä¶œF ’ûGÎH¬¬úþ ÝûªžÂß—Ø›»Øðœz[ðwJZÊùñ(pˆá ^A볎´Ï ÂU¶Ò™ŸfÝÍ!¤8›v—’Úxdd!¦P=%|²{QœÝ»†-¤V,˜ kHi´*K.Ÿ¬´˜áMÇG@Œúa“¬*dO…»™Ûö׌Áb‘„µXísjSͨÉ.6ÒpAʲUÈ}>ºÙ_:Ò²–= y›ÇÅŠ¦Mˆêþèç“ÔI.¹ÄžŠOYí>ºÓYñ=Qf»oº`nh´»…ÔµmL[®DâpµpÊÕœñò„¡yö9дFõÓѧWRÙSBmBBW+’0UÚÔç«hì 9Η åµ¾è“®ÛmÀ¢m)i¶LØ<‘Œ%9a¡ÞÇ`d÷­Û6ÛÁ¼´Úp·Fí`_qm91æ"¬¡~œC«JÔ¤ò'6ˆÏôîí­Ô–"-Ê­×g.(ZRû—q3 GT¥¸ñÈý‘Èõëí YÝ/oHóî'Ú&{ÜÄbÕ}-zKãSÙyjI*OåŒè|èñšøZã0]ާ*%•¶”uâDÂF Éõ'Ôã|{q5¶­ofZ® Ÿ—Q2 UÑRÝh,•d)èúài2ÒÊÞÏâk—ÏV¦Í5³Ë‘"BðK`½‡TCŽ$•÷ÐQÇ^ôѺØ}ΆlPGÄJ#ôž×ý¡¢¶©û¡¡Û)8ßÔ‡ÿnkþÐÖZ>„àåñ7ú?´é>‘=´áþÞoˆìþP›þÓ¥JTùFˆ½âÚL“·£STöž»Eø1%±ã4áä“”dd€ ‡Ð€uNlk–_…GaU 3Ò´Y¼óIL·9•„«$yzô*÷Ó%ƒm«rmd®b!c#ïÖŽa?ø>_ê€s“è}uB¾ß¸¹ù»¨lÙ9\‘ ç’˜ì•>N2ÚVsÇÇ8ü8ëZÄÓÒohW¥¦%Þ^E›ÜwfД„` a$ºæ}€Qï×®Ž;†>߃‹H ÝV 2 ¡iö$+A^ƒkÖÈÛRæ]ÛÄNæY?,UjÄÃ|³Œ4’¤øŒ®@§ÙsZ¬½•¸,C)r,eYN0%¥x¾žËO- øYA+w|@—2<ÈlºÔT¼ïÊÉ‚Ôàü8}µ¸Úz!ÄàcåwzZn=¾òjì>IS8¦;¹·”êB‰À'ʨ“Œ`såù“Þ‚ÔÚs%» ÒŽå|g:fÕ^yå=)ÇAë“äz¤ŠõüwçM±øxÔhÑK±KŒ¼”•c²¤!¢Q‚R”Œú0³ae3a×Wn­ÑDâ¦@q Ñœ¯“§)*) I  ’} ëcáe|özt”ˆíJz:ÐòqÀByà©h>þnóÚH¥2=VË®¬iýíVªå0^ŽëKze(«%ir"JV®€Éqûº/·wC›ÉÇ¡»[ÈéÇå?¹šð{L-¶‹¹Àè’=òOzh¬¾­r­Žet-¿RÓ€ø³Z”ÐiE8ShoÊÑz``žøç½ø‘wSk*-å©2‚¹Ÿ„§‰QÀñu t€ê ÐZA{KGw®Ã1ü ¨Âm“ó¡<=ù%ÐF $‚ŸLr>éÐþ2WNðªié¨áMˆBãpei8 I!N2r2û´n¯{ÙA¨–fGÜ”Õ ž¦Úò’Òc‚äùUûoç/ (Ì+EüËg’¹+¥O(7¦»â4lk–_…GaU 3Ò´Y¼óIL·9•„«$yzô*÷×B)É»ªÁ3¡¢ÿñŸ&O¶¦Ô IYQÈTCÜqΔ¡[íû‹Ÿ›º†Í“•É`Îy)ŽÉQãäáó-¥g8ü|sÃŽ´ I½¡^–˜—yyoqÜe˜BR€<5„’ë™öG¿^º8îû~- 'uX$Èðü7æ[!’BŽRy9Ú¿!õÁÅí}¯½"A\V ÛÈd¶àfs1W9%L» 3æe\HS/¿ÁµŒg-©X?Cª3íœÚX¦¾d;KxŠJ~L:ÈÈ„òÆHRØG˜ú‚…§Ø­z ¯[#mK™wo;™dü±U«[ òÎ0ÒJB{â0>º=ŸdYÍj²vöVà± "t¥È²u•e8Àh–•âú{-<´3áe­Ýñ\Èó!²ëQRó¿+$N SƒðáöÖãiè`‡Ž?•Ýéi¸öûÉ«°ù%Lâ˜ì:æÞS© 'xŸ*¢N1Ï—æOz SiÌ–ì'Hr;•ñœé›UxIäS”ô§@Y®L‘ê4"’+×ñß6ÇáãQ£D\u.Å.2òRUŽÊ†‰F HBR3êtÂÍ…”͇]]º·EŠ™Ä<'Fr¾Lrœ¤¨¤)$€@*H=ôNƒ­…•óØyéÐR#µ)èëCÊuÇ! ç‚¥ ûù»Ïi ”Èõ[.º±§÷µZ«”Áz;­-èI”¢¬•¥È‰)Zº%Åÿîè¾ÝÝo'†íl#¤”þækÁìy0¶Ú.ç¢H÷É=颲úµÊ´n9•жýKNâÍjSA¥áM¡¿+Dé‚{ãžô#âEÝM¬¨·”r6¤ÊvB äB~ž%GÄiÔ€}Ò_©ü'Aj5í-Üvv» Çð‚£ ¶O΄ð÷ä—A$’B}1Èû§CøÉ];©§¦£…6 KÁ•¤à)$x…8ÉÈÊîѺ½ïe¢Y™rST&z›j?ÈBKIŽñp9FG‰=œgvÂ>'|±Ùvû}ˆMH?i0ËÉyçÂò•<<AÁ?€h.mK'·&ØŽÝÝuˆDi*ÄÞ-Eù% «É 4 ÐÃIÎ{#TwÓ" í »ËiÊ5á?~ôi-/'B“Ž@àIÆsæ'U TYXn&ÖaàÎ.4ºû-´`„P 1ëÁy—~˜ÕíŸm¿©gÌòc0ÒÃ+aÈUå¾úñí¡ >¿€%CêN‚­5TÚû箕K1sÛl|ÄyR–á^y„©#›Ç²qÇŒû1ø—>µ0TãÕðêXeÖ[aD…xü6ãrκ ­ž·[Üxv¶²lëÍ;‰BP&¼Ä&%·@#‹(üDd%A@g­aI¹w2¬×|VxE1ÐìšçÚ8ñÀPRÝRRpr=±žºÎlàÀ•» õ¥<^Œ¥»+•î:âž ºêxpÈ% 'ØãM3dmù›rE…$ãBâç7ß‘­”Ã¥“‚œ¸%¥*=ŽóÞw¦©І¤·Ksk¨ï>íˆTycÆpB¾YJÉÈ l^½ôὊ÷^寨°Ü“-1¾qåRCj+àÿ”-·¹ç#!)JIÇyÐiÛKÜÛ~æÊ¾ÊÖœÔ0â‰×¥8µz5ÍÕ, ‘Ÿ/;Õë=åOÕø-ÑQ1-`6ýUkmË3UÌ~7O „~"rß± çÑŽëg|Bq¹ö–U{gÆ[-uRéHÊ_ÈO_ôÕmÑÊÒÍ5•·;n<¨ð[‘"S”ÇI=ó@ùu'‰g×#AÌ7Îä݉ß2kÞ¨ve¹)‡—šb)ÀÊy%i$ ‚OCðŽÆ™ö…²jQc#qm?¶YvRMkèÛpa„Åâ{*RPy÷ê3®Ÿ«›¶Û‰MÅ[®Ú8è"lgêã0‡‚“Ä)+ŽÀy Îz ‘žÀÒvýºjÑ‘-ý.η¡w°BÕó%x**ù¨Ù8ýU#–~º›J+÷#ØJÜSÝ °ãS°ùiJŽÚ²Bàaž„§¬tŪZdG·wd»K¶ãN5^âY`¤¹÷e–Ã4ô*A=žñÞMí©˜Ú褸zÆÞ+í7!—äD™ QíöÖ”=8©(Û[·+N@Üž]\™‚Ä4¦i 0‡†FSãññ?¡x#×:ô{‹t?Q!‡šjòB ~[/Ü´§R†WІÔAìœàö4Z橈Ö3¦î³ 1‚k%Ú?L€¥!I $ÇâV~º¬­²âœžˆöołąf$ ¸ñT’¤P—N˜ú­$z‘Œç^Æs~Kù¿¶²eTG–ë°llYqù±ñåS¡…€ÚOAHQï£ù%Ýeµ}å;ۢƪò½…)æ'¡µH[ )$¡«-!ë q8'dA»­¤®oé©xHËq`6ô6ädÎ;çËïÉA##Õ#U÷–ÞÛ,×9 Ä·Ê| ¨ìXÍtDŽ•yƒè8B¦0SÙëÜei¹ï#È‹É \•¶åti.;à<98dÈHÇ] ç¯BtXìÄôwgÜîíµ&ÙBªCÒVéBÔ£¥<êÊIIè$æ>oMmûCô{zª;ÉT›7ÊT}_ë²ÒRƒC#¢ åõ&=Ú¶´[•YmèV(’ë2åA–RÓ Y% qÄIoÍÞydôJºÕäZnʘ¯&â2&Û0„½D€‡ÀJŠ[Tä¡dg*(Aúœžô­Á`7 ²·Û›–­ )Uò%Èq–œ––”+ïêIâP=0rC2hbRÕW"êY-q—©í²…¼JÖµ'׬€¸Î%Žç}ÓiSa&ª3ËW‹ÆkSå)$ãÆñYe¢I (RAïÓ9K"s´•›š]œ«-Ž M±Uau~'Kq¸¥-0xôy'èÚÁÜ,n)·Â4Uñ$ÈÜp©!XqÍj _ŒŒœy°ƒô·º¾'ìø³ÑMI] qÈø´ôk’ë) O›¦Ö¥%^ çó: °\UE ëžÛn:¨­%¸O²ãËT¾µ r ¬dòá¶VÚ] mâ¢ÛRK£ii-7 KlHrAíh 9Ç <‰©^žº«}¸,'m(ìQnéû4!ï¸#Ãa+=Â[k QõÊ–Hï8>ºò#;Ú¾tÖaOmøÕëá*½¸·Ø^BÊDÞM)C8)RF}jü›Ë ’~Æ‹_)¶(\ [[ͧŸeO<ÄÇðÆNs‘žŠz 1vŸu.Êtî[¶S3„—W%âpA[®„¸ß]©IõÀêçËÎv·q?[³Òó޼~P&®$dIJ±“kñHRèô#Vign¹Péí-ãÙ|Ë/êêX†Ûa9þ1^i d¥I쨎ÈÓ<+Ë¿¶í£B¿ªqQƒ|ä}ªf=Ï*Q”àm®Àä?ÌÐ'Ö<öܹ¨«Üè‹auÂZT¦9ª*Hé^ \Á õÊR… {cA7lˆ¿Zž˜p2¶j˜‘ 7!ÀìBâ‡Oë§¥rO×E¾om‹]q\LÜÑKêpÂ+-SÑ+á(ZUî¾<»AÝpwný¦•]·×Mºi¡¤|¢™mÌ»´(¡)Xëõs€Fq !fŸ¹ÐÝžœoºSÿ·5ÿhhÅ’0΄í.õ§WÒs_ö†²Ñçü#ÓËâ:ÐÛÿ¿JÔãi³ü"†~#ôFÿïÒÅBz"¾áJMÎØKŠm 6On)°–ÏÈKÁ>"’޽{#ÓßÓBÓ·Ù›N³M¼'Ú΋!µ4#ÍSˆl¯Ç“˜' `v‘ŽŽÜ}”Í´~Ú*Úîx¡¾\ð\@ãÞJ±Œku£ûuVNWíz}Ã*®à‹ ~«GjRÿƒvAè’µ÷ëkNÛ*ÑÊ­¶Ä›»xÏÖGuiyÉUωy$äa8âqÌ¡@sÆÄû;K*£¸ì$µ`áZéâ]2¤8‚r ìuŒƒôÕË}ÁcáQhvþêaéˆKé–2^e¢@ó%— žæ5·oÔI~ͽÕME½ƒ !ûš¢Òœ Ïãép0–Ò‘êA>š;Ê4ÌoÕmØ1IBVäÞM°ï¿ˆ‚êÇËÚÏìã§_7âÙ¸óÛª·qÔκ˜Ó›f3Ÿ¶´ÇRp1åê9c½{}öµÄg\‹³vDå!i’oeÐ;qe’”õŽË˜÷¬5mÊõP]Ço[·ê˜MüЊÈV‚|4>¾CŸ)þ£ q¶é¨j™·¹*ì+ÃiHK.—Qƒæ>2Ÿ<@»Ï목K¼$H_G.Ýlâ!«÷Üf!F<4á.$(úöIã¬*ÞrÖ–ÉÛ7”¬:â"·b†V¤¶ 2ãDšPÆ|Ü9NôorÐüA¤‹ VЉR܉­ˆó#Î[e”àù'\H è!_]J6·çm^Ü“!mÆÑ§eLN’ù@V[­zœò@QôίmäUÅ\Ø+°mçÛn›F–\ZO—)i( ¡Œdö3Þµm½µ_>Uƒö^á·T%7>¹L y²¢×“`’qê°ø_¸Ü;FNÛ«¯ŽÄö¥¾·FÛ|4ÙuH%>Ý…zòƒ ´.÷Ó›±Ù mÈ’ ¶ÇË ¯H ·ÇѤ¥ìŽò ÕœœM º¨ß“¼§8ïË4¿èi,¶YP9KÆ_d=×”•yŽ:Õ6£\)©Qè,%Xn«,³k5+LT¬­Ä¹”§#>© öôÎq°›¸*Z¯ÛNŃDãQù=2¤%(}Ãê #:ÐQ$dsõ΂Íë_*£ËZÜKˆ“ mHeè Pý©KW$(d”;:iÚ{ŠÅRª§‘¶àK‚Â_³.ÅHRû*ðœIW|»óý³¡• ÓØm¯² n™ °TãNí¯ wõ–C™*${…+×TmRûÕ±åT]6üJÈé)lD—!þ52—‚\σ³Ö¹Êvû3iÖi·„ûYÑd6¦„yªq •ã˜òsä Ò1ÑÓ¥=½+¬F†‹ ;šEÏqVe±%N6€Ú‚mÏy¼BØâ~žºhþÝU“•û^Ÿpʄ넸"Ã_„êÑÚ”¿àÝz$­}úçLÛ*ÑÊ­¶Ä›»xÏÖGuiyÉUωy$äa8âqÌ¡@sÆÄû;K*£¸ì$µ`áZéâ]2¤8‚r ìuŒƒôÕË}ÁcáQhvþêaéˆKé–2^e¢@ó%— žæ5·oÔI~ͽÕME½ƒ !ûš¢Òœ Ïãép0–Ò‘êA>š;Ê4ÌoÕmØ1IBVäÞM°ï¿ˆ‚êÇËÚÏìã§_7âÙ¸óÛª·qÔκ˜Ó›f3Ÿ¶´ÇRp1åê9c½{}öµÄg\‹³vDå!i’oeÐ;qe’”õŽË˜÷¬5mÊõP]Ço[·ê˜MüЊÈV‚|4>¾CŸ)þ£ q¶é¨j™·¹*ì+ÃiHK.—Qƒæ>2Ÿ<@»Ï목K¼$H_G.Ýlâ!«÷Üf!F<4á.$(úöIã¬*ÞrÖ–ÉÛ7”¬:â"·b†V¤¶ 2ãDšPÆ|Ü9NôorÐüA¤‹ VЉR܉­ˆó#Î[e”àù'\H è!_]J6·çm^Ü“!mÆÑ§eLN’ù@V[­zœò@QôίmäUÅ\Ø+°mçÛn›F–\ZO—)i( ¡Œdö3Þµm½µ_>Uƒö^á·T%7>¹L y²¢×“`’qê°ø_¸Ü;FNÛ«¯ŽÄö¥¾·FÛ|4ÙuH%>Ý…zòƒ ´.÷Ó›±Ù mÈ’ ¶ÇË ¯H ·ÇѤ¥ìŽò ÕœœM º¨ß“¼§8ïË4¿èi,¶YP9KÆ_d=×”•yŽ:Õ6£\)©Qè,%Xn«,³k5+LT¬­Ä¹”§#>© öôÎq°›¸*Z¯ÛNŃDãQù=2¤%(}Ãê #:ÐQ$dsõ΂Íë_*£ËZÜKˆ“ mHeè Pý©KW$(d”;:iÚ{ŠÅRª§‘¶àK‚Â_³.ÅHRû*ðœIW|»óý³¡• ÓØm¯² n™ °TãNí¯ wõ–C™*${…+×TmRûÕ±åT]6üJÈé)lD—!þ52—‚\ÏBډ蔧¬eZ­.ËoÃnµ;qUFžÛ¯»U–LÀ~+C •—©pÏ\Í>ºªÝ[_]5í¥DÚ¸ÅÅ8‡¥1g!@’T¤óm Œ“€TŸ`€þß¼påcwNÇK¡ƒa¥·"='U¶Òpú½;H V[=k;}ÀÅóeð‘`ÊÃr®¬°ŽÒ—ËʑȠgÉW×úu’nn¥WÄwoJ¦ƒFIDvTf”—yy[q¯’…‘“Œ+ß˦‰ugw2ââæ½Ô©2ÖÜv^ˆß”òÆ8âp0—–ótî™Üó¤ÊÛûv—pÐV¡„â\fÐ~uü'È¢ê\HAä{Bý»Ð+hŸ+$B³ETÃE Å‹’dÄñÌu~4!,¡µ’IõQ9:¹_º>*7dÒã*•A+;`¸*ËÌgø¾Z”T1ès’1Ö–·6ãÜ›ÊáŠË›ª™è€§¤IC•ŽW†R xÅY$ÖO^`Nt¯m“:Z‘Oy¦©‡’Úݪ¯·Ö’|¥ao‚1êHýzëLÕ—j:妋{Þn ñ——bJ‡+Åt„”©* 7Ä£Üv}GgT›C‹€+¶e§èêìƒeVLN>`a,¥JÏ}xÄû“¬¬¶\нÕßjÑÛ§rÅNX&CL´\P󸶒Vœ’B²2=Æt {Öñ4v6Üv-4d¥˜U6pƒ!Åô¼¥°¾ öO#üâ1¢×? ~Öv}”YÊ—. ÚPyQÔðÉäÚáâpHÇ.8×Ó\¾Bw45E‰.d*¿ÌJ™±·*ŸxœO¬¬,dgŠ‘ß宊m*w&àD•U—ÉÇ˲fK¸Ïktµ•ö1å8ü´0,6e*—sS®ñ–œS5r•kv:‚x+¤»’Ø'J;#×B7Enàcg&¿qÏ•5×^Zâ­Æ ~ic l0‡BSœùÜ?#]·pmšëÙ°•¶¶þÖŠÔp–¤>Äe)ô¸H ¤2µ +'9V¦©‹-šåŠlhÙÏ8ËëaqæN‚Ó‰Y¬‚Ñ O·c¼ûhgØmŸˆ†¾W‡6žU ‡ÃL”Ê-­)¾+iJWYód}AјêØ{¼Ç—p!Ú¦Táy/Øä”©]v@ʉü½‚LíǺ•WoñšÓä8ˆÎŠ)<Ó Ïñ…eoÐz€;ëBö¦Ïv®tQÒ²¥"7Ì†Ó ‘ÙÛS‘–Hü’³þvÚ2vsÛrÒÎ¥Ut´Dƒ;O%G(ðÝQ'Ød#Ñ:£¶éíš·¯X»k å\Sªy ¦2Oº0¶T¢pNKgÔ kŸ®s·"â©•OáVï𕪾C«uR]y·T ‡ 3ŸN´×¶ª÷Ö•â§(Ùi?&ô•JvC c?.Sâ2£ê|Ýú‘­ôwf[“êú<„%LEÃm–B½T‡–êRFHÊR ú=ØÐ¯+k휃³ë¯ëÒÓ‰“.u‹¿%ÑŒ©|¤2“G]w“W©Û­ÑÞÄK¦Ljb‹–¶ÃŒ-D¿ÆÊxPp¥/8>cìnmXÕWw±¾R|µ«Çf_±‹ÃG^t6°[`u‚}{Ð0ÂðíˆLN}½I!”‡|)m‰/4°¼òB£¾¤¯Ø)'B÷Îॼ+ÜS7«hИ,7S9‰ Wº’·”ãIü¼¤Œûj믕{âH—¸.X­i¢Ó±¼g‚÷i÷PP3R4Op§cÇÜç9s¶#Lujq礱Ž,€r…'-©$ö:Oô+:U?ðzýsÆ|{6ß~?Ž©.4ã«s P¸ªJPyp'#°46›q]WNK!¬A2¸Ç¥ï"[2AkPƒŸªÆª×_ü£eWn6Ñ …8ä(Ïn˜æ;EyJ”ˆÄñþb”C®º'¶wmD«Å©U!ܸÈ@ʰ}O¾4¿³[Oü/H”ÓŽ>‡ªäýû‰XRÈ}‚FHH)ÀÂR:ôév›‹aH…‹ua 2†S7ʨåAKe 7•wŒƒôïKÑ]ˆwµ48lm´µ®ÅÚY,:ۇlj٠¡%?_1Vrqï 1d>ëBvêq»ªþØ×ý±£V)û­ ¡N7]gú[_ö†²Ñßü!F~#ôF¿ïÒÍJziÿ$çâ7ý ¯íV–êSŒu«©€Ûú$9RvË3œˆÜan§\¤´ˆrW•$­CËéÈgÓ¿Ci™Us*mÓ´mÖ©¦ÇÌ.‰Å<Üèäd : 02ƒîu_â$›¯í—ê„_MÁðD”º¦ÊŒ9#5ç>½cßÙÑhû/w}ˆü–vÄx3\iEO×ÜÏ̓ȫ‚˜ åË=,ã¿]\MnÜ)ÛÏÕ3tè~™ŠÖJQY*…m( óy8@g>/#õÒ¦ÉæD“:7­(Ü[zCÔ_8AÛŧ889û`邚¿v3÷ÏoÛHÍHoà zdTÞR’´—œ)Æò¶UÙζÔ&;О¯ºq¹Yi_0¥—C¬…*ðÖ† <{äq õº°²‡I³ëöd(M ?*£¿-±ú¥aÜ6;ìñöèkŸ²ázÉÛ[Re\÷^KëCíRI p·<†â$'Û‰ÕûXQ¶nõ€£¼Ý‹Ydd®µˆËTvÏe“…)IÈë“júi†¹–¡½öµ›0œIR™±z3o:ÊäWŠ–C‹û-CAƒp÷u~ß­KÕæ>á[‹bc0ë[-•xø¨AA^F T3ß×H—±%TËE ªP°zs^2k«Deº}TËH-88yß¾4ýv½+tÕÚVÛ[3PûÄÇRg4òE.¥n!xô8 'é£ÏÕÁÛófשÕ;)+ùÈHŠÛñC¹<ÒÃ.rH®\ŽGiÏz zóN—þØk{©˜’Q1B®ŒAëÁRZH÷øÕŸM1ü\ÛatN)æçG# ¥ÐP‘€œs¢û±ÔÎ8½»g êõL6´Éq…¸ÒIX JðVê<½´¡“Ž@Œæ´}—»¾Ä~K;b<®4¢§ëîgÇæIäUÁLòåž–qß®ƒváNÞ~©›§CôÌV²RŠÉT( i@q›ÉÀ*9ñy®•6H‡2$™Ð!½iFä‚ÛÒ¢ùÄz †Ü-9ÁÁÈÛLÕû±Ÿ¾{~ÚFjC~KÓ º¦ò•¤¼áN0•²®Îu¶¡1Þ„õ}ÓÈšËJù…,¸Âd(ñW†´4Qãß$ƒ¨ÝÐE…”:MŸ_³!BhaùP•ùmÕ(Cá±ßg·C\ý”ï;ÖNÚÚ+*çºò_\hrh¸Ò’H[…¸éä0!>ÜN¯Ú³w¬æìZË %u¬FZ£¶{,œ)JNG\›WÓLhÜ5̵ ﵬلâJ”͋ћyÖP¯"¼T²XïÙj ‡»«öýj^¯1÷ Ü[‡ZÙl¨“ÇÅB ò00R¡žþºD½‰*¦Z(MR…ƒÓšñ“]Z#-Óê ¶ZAiÀ ÀûÎýñ§ëµìé[¦®Ò¶ÚÙ˜²‡Þ&:“9§”z)u+q Ç¡ÀI?M~®ß›6½N©ÙI_ÎBDVߊÈæ–s’@=rär;N{Ð(Sךt¿öÃ[ÝLÄ’‰ˆšítb^ ’Ò@@¿Æ¬úiâæÙâˆT*’·ÜmS¬¹ßH*B8…'˜p©²0}ý5¡tV4RÚÜðÓgfÜWTYC•èh²|Ä$2„¬ç²¿ —~£­VÞ–o4”[YFÛówÔ‡S.½ •4BâÛkAÇäàë°4öEûwûZg(¢ÍצcW¿T³‘14¡ŒDœ}}uf{/lFµ›lÍä¹-à!ã)æÒGi'&’;ýp=p4«µöÄJ÷›[ì›I¯$6è6²Ô )>b„¶·\ZIï )8úkV㯧•·³}È—ÂÛ϶\Yì¡*Açƒß›ýš6Ö³fѵ6¥í«Sãxo*ªêB|9‘Îx­ *Y*é$Ž=r=ž´&éÜMH]ÈnÝ©™Ëa) ©°>ë‚›l©IÀ r±Ö4ß´÷•ÌS&=òÓBŠ€…­¢~ìÊõÊ}5ZÖà9 ùRœÜ«ÛÅ8ëzxÿ’ò¼çüï.qæÎƒÏ…ŒØMÛHÝ‘­CÒ¦8© [®©Jh+\â[_XÀ%Ÿ]k)ÔT’"vÜcX†òÞÅ\G¥§%%+[ÁmzuíÞ=ëJÜ꯲¾×žÓÑ’äuKL?”ð¢PO$öâyuÖ5r¢Ãd²÷ËTn¥ÅrB@–bU•GeXq ×Ð_m}õ*¯x±›k”Ë”óJZ+[ˆÜ‡|Dà€µ6· 2žÆ9úkb¶|ªkæVR³Â|w˜‡9·Ü­’[an$$ÚV3Žôbu.Êvé5®•góñÒܹ±™Bʳ„¤—ƒ…°zlŒý®ªZ|6ØÔ–MooîºÖ–„¦Cr[u´ãsuJãè,ý=4 SâVÕÅ›5«­¸ê–¡¹-+‘ÇÊëžqíéÉ'BN™«âî Øb>⯢“KHiq™”°–ü jQ ²¦ÁãìR•wôôÕËM§uY¶;Z]kÎ)àâ£Â®C±äÈÊNP¯ î¸`³ûôdì™P¤ÌDíºÊ#Æ@]z•.‚é=¸äpz¸ïLÿ¯¢µ¶#TÖnê«íÁ/”ðèm S*HL©E òÈè©<¶t°óeS5o:–«›T™¬³ù&œþÊÜiÒ¬uœô8ïGv܀ܦ+kdý¯A%噾†cJ(>W!eJPè„¥a$ž³ uÛÍ»xò®n¥Â©¿§k®œnAõ„´Ð=óïǾ¹¥ÌMŒâæLÜŽYXÂŒÓøóË.¥ÇG”pW7=;Î@ÈÆ=4À†ö}]3fÃkÜE².êÚ´EoŒñôRPe.:Ǧ4âææÜ"¶á˜è®ASñd[F-¾@1”!*q]ä—#®‰ÐM‘WBæßbÂ`]YZÁ`*æóa*)rÙƒ`§>š+iµ2¦Sv;Zûi9 …;¹I“Œ¶Úˉ󫱀ž½{Õ·ñ’²žuL¯ø=Ú0ûëe·á´ëXJâ¢2I9 þdçMWŸ­c³¸›šæÓ–Ç$¹Å¥ô ”£ s±’¤çš õ_úäÄì´´Ýc*޶œ¹Sœ2 R‹j ñ ÎómØ;µé¬W/a¥5óZŽåu `0‡([¥N3€IÜdg#ÕšÅѦ±»› º›:uFù·Ù› ÔÈ*Κñ#´Žc1çs[¡„¢}FÐÚõ̼†YyØ3BÒÚÕŽ àžÇ]úÚÐS®Úð%%×ä½*j¸6B-Žø£ñ>R¥dñã®ˆÓ ÒüJ”P¶$%"BÀyËXcñÖ8ËNpœ¯?ž:ÖíШö ª¡ÜnUu£©ù¹wQ#6ÓqÔØR¹¸<ü“åÆ2G›@iüh±~ÏâE[éqóä~¶fÖ¥ŽÖ>éJPÆqÉ)ýú ð·•}$iªm‘iÀC±dVÓ­ÇÛng äîZRôòà÷¥Ý Ã`ÔV}¶§–¦|xsyÍB0PâŽJÉòÎ@ôÇzéðhö³ï}ŸmW|XÜZ+~ŸÃBxàòBÛAA½„ÌL¬‹NšíÃERµ-ÿ ˆk :´‚2˪ÂO®<<÷ƒÞ7áŽÍœÁ[göt¸–Ô†]RHa*O$ñ‚ìdñHÿiÁéµ6Ͱ‹D¹Wi**©0•·Tû’R¢•â¸{ǪNq£¥q#Â7BZÕ-©ò¥€Ê ̸Êâ=‘‘ ûŠÂœH•/KÒË2Ÿj ra¡ÒTÔ&²}qæÀë9Û[dVn•Ë©†Ýєߊ·eÔØyÀ T¬)Ž—•(ô1Þ·BntuJ 7’+j+¶NLi§PO™ „'Gcútpì-‰ºi~Óržî|þME-Dðbª0dá-–R¬RTöÉÀèkW¸‡7.ëÚŠjiWË«ÃRÝQF8 9É$}JŽz ;]ˤ¸ëT5µp„¤¯ç¬%Gzï;Ï<¼aÍdgß#=uŒhíÎѱ°ˆåÜ-·^å²R²Û©[y‹Sç“¡!>å ’{æFÅóP[‹º+.b£øT6i±-—VrØKd%9Á(Ñ­ô{zJ°º­–k,+ž Reʦà‡ã‚¢„% èTFz]¡[o¢\fê eøœRÙ¨­Ç”œ,­Ìåcè2œý42Á¢‰)•3u{¶e"œuQß\UHǘå¢èპ²î×µ;˜m…¯ôÛoO³“!ÆÂU9lCPâBÒZ((8Ïãëª-%ªUÖÂû?iÚÂ1× ä³)n¾¢2žIYm-§Û̲ÆsœdÓ^%ïˆ0EÇÄHQë ’ó_<ãé~²y(äØQÁÂÊùFºäÝÁenÄ_²HýUš&?Ì¿òˆl'’¥\Põ“ƒéÑÈ×7‰¦ºÁè¦K©™\Ðr¹³r©)qÐr(nB‘Èœþ!Ä翦šn% ®°ÜûaÉÉËŠšÛ1ã·$?Ÿ*Þq·Ú pœ ˆÔð*àGUÝÜ‚ §~F ŸÌ +¥ <âR1”wôçBÃx»¢ V¨åÍxÄRìþHðYSŠU!¥ ,ýáüÆÿJ*éÓan3c2”}Ç· i<œ‰m©ä…gõˆú÷é®qöý¦Ö¸sCÛ»£çHqÏ’‰_.Ú›*%8)'ðÙèPn¾¡~ÑcWü)ÜI‡*,OŠë­>ÐYä®)mÕx¹‚V·×Ba= áîðŒºúY6(²Ž”¥Iv2 8¼¤¡ANµ’NNr“Þ5r‹ã4»MеmÊ-µ·Ý¯–“òh sÇO,,¶„¥ ²¢=º±/vGÝÛÂDHÄ`ó&Ku’àõñ\ä‡[Æ hèžò47E„‹Ëå×µ²ëTõDdºW!±fRÒœtºPgê~¹>ú%¹f3º­‹*²ãlI‚€Ì¦œe¸ Z8Ž%@K<ÒFGŸmeaq´)cºå†Ó«6qXL©ëÚq( QÞ:ÖTOG–që•gL”7s,çO³ÚµShÛŒ—LhhqrᔩJ$r8ÏÏ­¹Q[IfNÙvÔ”opWâêe“á,zç =ôF‚ZÙ7Äî)»glÕÚË“òõ“Ãï6óOåOÇoÄ9÷QOïïQèÑ^‘pV^HÚT•Jr²u|i.6B¸%Ð\@JpN9{è£mC”•ØÊÜoÚŒnQ«cÈpr#’–”4…¥$ÕWôŽìß1\·©­™.B¯¡µÂËíeü«2'$) S‰ ÇYÎOõj­zm7ŒØ±ßÚ¶¢FR˜³#-´ÑëƒN•c¿Â…ÙÈ×R¯¯Ùue˜Ú%VŠ<Ë•Ðx:ÙJ - $×ULfÒÅdòÌØÕI‚™(SˆJp®8õ䣿ì{>šÖkçLÜR!ðYR"•2ãÍ3ëÊà)}ã8èuœ*m3+âCvŸjI“&E|ô9øe…4„½‚ݶUÈú$ ${ç@í`œ7¡TiÿƪÏôÆ¿í°oÓB©ÿ5éÛËG_©ÏÄ_ú_Ú­.Õ74Ïñá9ø„?ÐÚþÕhRzº˜Wø©bhÆÙ¶þ¤Çº RbGKî©?+')J8œŒŽý‰:t¡Ýߤ2'Yºôî dUB]£1x¯<¹ ä¬þjÐì• -¯ÅM¥i½ÁNC\ •}Ÿ/Âl…(ƒCÑÁöÐûkۘ谈å+w“¦2Ó“âË(Yyi°°‡V: òÇg–5q4NÒÙvh›OWeu"d‘ó±-«Íâ*IO qÈdþYO„åÖ벉+s\¦ñä<¸ÐdüäÁÈÚJ„½2@ýú;·Âíše5 ¦l8˜˜b|2—?[ù@lþZfs2/• ²òÕL¤ør›L¹scÐ- ’Ú†iC–€5Í¢“Nï•.Öc^xÊ’d|¨H%Iq ujã픂ŸËBî«é§ªµ3E:bÌÅŸ:½ØÌ§—G JRâIR24Vº“vÝJS’$4ˆí78ˆât(ÉÕ¶UE¬ É·ü@ÛÛv²É‚ý÷ä¬ÇfÒ’·ž>qy8_ž(('$ttõC»¿HdN³uéÜ Ȫ„»Fb0ñ^ysAÈ)X)üÕ¥µÍ”«¸Î*¯ä¥ËŠãkzζT×ÃA*[a%!$-)é°YÕ[kۘ谈å+w“¦2Ó“âË(Yyi°°‡V: òÇg–4í!m—f‰´õvWR&I1ÛÚ°<Þ(Ò¤”ò†O呤øNXÝn»(’·5ÊoCËOÎAl<¤©@ëÓ$ߣ»|.Ù¦QSPºfÃÙ‰†'Ã)sõ¸ñO”‘æÏå¦g3"ùP«/-TÊO‡)´Ë—1Ö=Й-¨gö”1ùhPlÚ!91äîùRíf5猩&GÊ„‚T—·V®>ÙH)ü´.꾚z«Qó4S V(üÌYó«ÝŒÊytz¥ þ$•'ó#Ek©7mÔ¥9"CHŽÑSqcˆŽ!ÇBˆ[eXôZÁ œœèÄ ½·k,˜/ÐA¯~JÌvcÆ¥‹2C®!$-n;÷~SŸDçúºÐl…·w, â«:Ø0%É@ŒþÞCÎe¥d‚Ÿ:†ÓØ$„¨œþYÓåVç‘LÅ}¾ß‹rÛÞœ—R«_–O™(HqtuכϠҕ|kýÑB´ªÐ‰Ì±ƒje–TØ<–…$©m«¥+$£ß Ξ6&Ý™·¨ ÓÎÛÒƒò’¢ì–¦´•!k åÚJÜ8õ$#÷náõÌ"emú¨~Í_e&qS‹’K µâ¤uÈ6ÔúQÚS¿eC°…¸DÕ· GTË$ði 8âS*0+üÈäQÛLŸBá®|*Û©’U\Ê\[r^ÐQ’‹î+‰ôIåË$þªïRí™!]\š„Ji¿ u!Ô­®jK­¡ŒpQ)X¸ïØ/1°·2, ¹,‰î€ázu%°Bó÷iRq¡‚}<¡ dku[~ò¶¶Ëf4П!NH˜kÖëkQ$$€„8–T3’éX*=/+á}*œTè{Uú”D1›v[,"{ŠÂŠ‚Àqe9â’±éÖ}rÉK»ìkJ.ïdÖYÅi8©1|eK'!)Àu'’~ $cЭý*šÅm5¨˜ò÷‹X”è@ x4‡OÓgöIÓU5«b¼^\ÔѶ×Þ8µ®¹öՃȩçd— =e9èç½ÞŒªÒñ{nÊÂÒ±û/9 ÇZ&{(ê% ú‚×'B^M^×Û— 9‰Ç IOÍ5_\ÒÚKÉ „éOƒÒ”Tœú !tÃ2$¢ ³Šãk¤11ùJÙj.!ó“Ÿ/\ $ÙXWm=½'i˯Ü”„¥Ç'ZøÍÇuÀ|¾g ~Š:-]¼®7u*%R\î4„¾¡ã²"ÂÈÎr#œ$ûàç$ë~àºvÜ}*|«Y¢KrW_:^n[|1•:"rRò9OYõÐg¶v™ÝU²Y•m>Útrå&CùAØ ­µ¸¤á=ePSƒ¥ù³"C]Íe†ò51Ûq°ëpi„d«$râ´qBÎ3•ç×Lv6—,ÙÆz¾±p­'ÇTU;aK² Εc‹B‚ÉÆ²’ô™1Í]¶à,¦$^pëê‹°Â çÍj ’s‚IN4 ´ñvjjê¥íš÷c‡”Yj;àJÜRêùgÕ]àö­"îªX¬îK ‹ÍÅ:Uÿ¶ê¬¥»-/œ“É&S i)N3È$§)ÇZz‰jE¢nÂÂÂÊØÉq/75³ö/¶xžÉmÓ’0I {,ÝÍÙ·’cÊMÞB$´µ",Q$´3Û¡â@Vsúœ‰ýãAjli—tÐn%Å’ÍrR!Ê]C-&I* ñ€dãt“ŸP=´&^Û™Gº>ιÛÛŽÄIs 5_¹ãÁŠŒ«%L´Ò—ƒ‘ÅHÓ4r%JbÆ&Ó*‡Zù„¡¤`ðð ìJSîï¬Ú’§ÿEd³*Pe–µHqÄ'ð¡ KÀŸóI8>ƒè ›_l;6,ÚÚq¬âG£&5…òÕ-•L¶Á( +äF=~€­bíªýÙö{•Í·l¥¡r›¥¹eBBR]K O0 @Pö·í‹ÇY“;%Ö‘Ã,Ý0Ø‚àsŽâ$¬®]W¾Óq³‰agþ å¸edÍ\–Lwˆ<œGа•ôI9è]'fn(ʶ«µ—-ÊõÚŽ‚ÛkbKƒ!-¿3ÃãÿòÊ1ŸC¡5;Ox±†7žÍ«ðb ¾ÊæxG–Sâ8äÏ1 äðÆG¾¡½¡mÁ'jÃvz$©“*l8²Ò¬«Ä*kŽGxè‚ýùÝwÒÇÛŸ9²6~Ú›/Åù7b2ZÓ‘Ä ŽiJW^Ú·{³iÉ-L¿â¾kQó.ÃUªØR$qZ•©Ä -gèuVÖ÷qNŽ/³¦ƒAÑÊB¤‰ŠR@RÔ•¾\B†|£!ÌŽÒœé·nÆÝ–ö¯ï*ÍÓY4„†ÓJ™¹K*Hó#(l±Ñ 'êt—¾$mæ+~n,x¶{¥ùJqùPëÛ~O—ÕJR—“ŒqÆ3cuunÊalî7#=^•-ÅEqů 'B‹«ž'ŠÛëïžyPã‘)¶Æíin Á§ë£6àAQ(àKEc 3„$v20q£»{ô²ÆíãéPærO`µ&ˆHÊä0ò–}z Nqë¦ÛjXòª`î[J³¼†—rrß —“æm ðIVFp¤ž½{Ð'š«ËžåŽÜÛR«CŠ4õºÒââ²…mÄðJ®ù%(Bޝ9ZëÕ/¶ÝÒÜ7Í©™é Äj"OK[μV¥µ‚<ÅY9ë×Jûb\¸›ÎM®ÉrI’ÙTù ª»Î¦”|È œÛ^±ìpcÕÓÒ8!m}Æú®@r[©àJüN8im­D%¼ú§+ôW]ô »?oné61þzßr®9z"&iiÄró/‹N!.'>…×8ëBí/•nŽÛ†·uÜDQ\Ѝð]°tÇ›*uÀÊ>`µgÓ)w‘²gTÖ±¸÷EµeuthjhÓÒá€òŽ+Oî>šG_ÀÄÜ´ûÊ’ã¼YŽù°‘Ì2›Z”µ‡!£Ç¿s  X–o"x••pjâG’¿ü%Å%Å'ˆÆmöÓqÙlœà‚ŒÖl[ ÉV©®ã0•›i.8Ã-,ŽJR’âXPIï-«üí/YÝý¡=ÈúàCd!¥”«ŠÇ|Ö”)*ÊyP9—¦–·›TìR³:Ô¸%1ÅÇŸoœG•Þ„!¼•$PýÃA[|moÑ( ¶D©ƒêiÄ¿a %œ•« ·ç¿Ö=c×­YÙ Ù6»ÉönîÜ–N% Çq÷XŽˆ~PJ—ÕÉK$2Rq‚3­u6Û¡q‘=‰”õmDaPa<+HŽØ9âÚ•*Çg+=ç®»%·ëéìíÛB·=’Z’Ës©…l ‘ø‚Yæ’¼à‘„ÙïÓA»w×xû>D¸v7•ôÐV¤Ì’ÌÙqÊד…,±¥Äß$«€Î4­·¨Ú³ÜbíÝÈÛ•–#OESr×<AæÚ[.”'ð•©E?×§;»-å×&¥‰ß6ùK’.YqpÞõä¶Öë…%_šUŸQôÐ}°ic¢R*öó/N”êã¤Bb*Fzó4ÚÔ’@ s_`Ÿ]½ÅðÞÆ+ïÒí™ðY”·x+‡g 8­m/‡´@å‚âHþ­ ¨TôHvNƾ۲–†Z‘c»Ú‘Rð0V爵'¼Ú{ú¿mQY¢º®Š±×ß _ÍÊm’¶Æ BI ‚õI õ>šU³¸šÝŠ%¼˜I—&_˱:ªØ•“á…-n£ØÙÀö»¶¿ÈÓÈŸ»ª¨$Ãp%o)»¥‡sÓ­:þH)ÆH ô}4’ãeŬå2ÂʸMsø Ïš\Ä>rÒ˜G'rrP úçE+whÎȦŸQfÜå”ñŠ\nyKÊGJHkˆdöµ„÷éªáмSÐÛm²"!ç •Ü¢¸„ø‡ x¡Ò·ÙÎyzË&í+ø·Ig`U(•Ábs9åÐú†#¾ÙJÏÕi¾ýôFª]—_oH¯ÙRe7ó¢­yÙ9)q,¸ø àœ… ÷﫟jü=¨Ü¿bIÚûi %åDDÚ[Š9 •ù›Á)´ç?]{o}y¸ß—µa§Úi’± ’x²¤©'¶Ç•8OXãÇ×Û@ â1ÔîÞÚWî­ž ÓÍÞ­ÈÍ­x*_!à·‘ß“ïö õÕ­¶a&΢õÔnY­ERõK* *äU%I|6H8(…õìi†ò ±!VÓï»ê›Št/'ÇYÜ•'öÓ”§ôÀQöÉúó!dµ?hÕ5ké¤SÈRc¦“ñȤ,q%98"[=J•ôÊtoáÔY–ÐaÔnØVUðP›IJʘJ›Qv¥¨…qÏ|J#=ý¥ÓÛo £ö]M…BÑq•b„Û|RRÛkO% ddúƒå‹Õ]l¸ÕíÌø‡ßšÊuo¿-.xj’…¹#‹‡ù©JϨÁÁ:Z‹cWr¨àXªK¨r²)U4„(Ž @RÒéüÊyò¦©õÔôöpv¤ÉBå×Û¥Âñdqt!m…“ëŽ#?Ûv9•¶(×IU½Y”¥)LAkҖDzÎH¬`€ž*â=ýô#m«WTûlºäi\Ö‚¸uóã˜ëYϘ¹ 8,œr@9ü^úÓU¶A¸vç9V.©êËD”Î|8âJƒ’pµ€.°¯m3N¯‡Çåw ɬ¦8PˆÜ`ü¥Ì'ÕC$ù³ŽÇZDÛ‰K?„öËôÉn®bù™+y—ʈpÙP p2ûC>Úkþï×B©“ÿŒõéŒÿÛ;=?u §Gþ3Õÿ¦³ÿlk-~: üAèmj´ ­ 1|oNwÿý ¯í^ƒV7éûµSw¾Ó»k£BŸ.|AHÓÜBÁhõZ1…ŸlçèEÀ±Q·yî–YB‚Ò‚ìU' “è¨ç’}ôú[Ê}5ç‡ïƒ¦)"×dʳeÖ¦ïØ÷Œçˆ·ì_ŸAç cù¹Ç¦‚3ð~­›³›Ý;¯æ"()‡%…xdw 8õ×Q)Mbצ•!iwid~_©õ^#‘à-Iï8Æ$z{j­þÔ´½Ê¬wµáYXZÜb4²:”Üt’ ’¸:oãéÖ¡N=”Že+áT‡’é½´iÔÉ2ÂãÅ„ÊüSïÉ sî_–­§á“(þ/rÚ$ø¡ìˆpAñÈV~_ó×CJAõþz~¸þ)æÂÖaÏzt}Ïm󵯄¼çÔáL?£YFøf"D\h{¾úkp8¡¸AÈí ƒýƺ) úê$+cJBHÙSUXõZ÷¥ÓÑÇŠÛ± ¯Ÿï*ŽIþýY¯ÚÖµóZ›zZµ!¦ü4¹öur”î;ï¦âÞ=uŸ†1¥!$ìÛ“|nÄ=Ð&>T4IõË^†}Oêë{tK…Ü1¼­›žáIqáUÄyr |gNü5èOzRÛÛwÉq+]<¶ÖV’ô”êG8çööÐ뇳-éE$Íñ|šàB‹ 1”•œýÛ)ï>þþú~ðõèOå¥#™ËøR™q¼ [ÂéïB¨ñ)î÷lôŸ=‘[`ç–|.»Îºn3¯8õ¥#˜CøRaÍzt}ágóƒÍk®†¼ç×¥6@þŒk8¿ äEЏ°·ÅÄ6Öâ\WËCŠÉRÈí ƒË8×Ká¯R)Gb\*±êµïÛg!¿·k¡/–>¤´IÖúí¥ss"oéÍHiû½D'ÜvΊuè@Ò‚vVãUéºÿ„ÍÆ&Ž$ç9h#Ã>§õ}õŒM‡oåˈûæÅ¹î•¼* ’¢xçî°«]ÃÔ éHKN×Ý uˆ¶Ž© SˆSõ0]('ך8ýÃÓÛC.~[[R Y›þçìàB¾]ˆ1XI ç?vØÉÏ¿¯ï×GáÞ¡o#JG6ðêÂ,¦e5¾¬Vû iÇjḴ¨ ÉM“éž¿=_°Ú[ŽsªrGÄkPT¢¥øU0š“ÄØ ‘ßë§òמN”…(ÛÒáGø¥p¦QPKÕP*$’rVÙ'³ï ‡±÷8Ò™‹ñ7p´‰R%Ð"Ç'Ä_â ñÊAý‘ûµÐK–±-÷¥#šÔ|7³©Ü(Ü¿/"X cÆjpT:ÈRxñWá ý>º³`Ü39™Íü@´KÌÉ2’ElB6ÏóWásHýÇO¼ãÞ”Ž}?`ÜKœ©î|EÜM>¤„•Gb39c°ÚÏC¿S­ ü3Óo6éb£aYÕ0† ï›D´‚²”®¶ÂyzÉ“€~žš~ ×¼zôÒ¥nîH/:ìMýbÚoÃ_þ®Â‘ôÁ`]÷ŸÿÜIÁ]’E^¯åó¦3¨SÞ”„˜>溹Uð÷´ö¢©Òñkìzâ9ösÛ™þ½ygî3ÚâNâK휅ªGÃÇš÷ÃJb R²‚ ï9Æ1ûô¤C‰BS½îHB„…×Õ’ô0ϧýúÁª©K»me}chüXïGŽ—£Ãe ¡Õ6¥ùXa¼’ZGdœ`ô3£^}µê[üŽ¢ÀùÉû½ ¨N75gúc?þ±:=5v:ЊÄã-oúk?þ±:#­oí‡k¸7/Úq$BC?.†¸ºµ%YIWÑ$c±ªÕÿ ìšOßM†óJ•ÿp×OÔÕˆçC`Lüqê:ÈlËþ£®‡©«¹³ßçz·69üˆ:Í?åp¦3ŸÈtmM!\å?¤Å9“û’uãŸå8Îd}rº>¦®pŸ‡r‚Ç™'÷`~Ïö›úŽºV¦®l¯‡s±ÔØùýÇ^·ðörNLÈäûzë¤ji ç_ ÿ•Æÿo÷kßÐ+ Fþµvº&¦®r­`ãq¿­_ݨ6 ˆÿÆ'ßµûµÑµ4…sŸÐåQë+ûµçè —ò¨£ÿy_Ý®©Þ®súeí*7õ«ûµïèŸò¨Ùýêþít]{Þ®rv–?Æbç÷«ûµ¬ü>²õù¨Ÿõ•ýÚé=ÿû OéÒÍàúÓÔKˆ?÷•ýÚËô×Þ\Lœ¯î×IÔþ!\ÛôÓ#¡éW÷j‡öyÿ‰ýjþítMHW6í=>nõ¯ûµèØ6ŸÊaÿZ¿»]#úu;Õ…sÐ+2FdÄþµv½; ˬI‡ùö¯î×FïSHW8ÈÆâéW÷k!°ì±þ5ú¯î×EÔÒο@¬¿•Dþµv¼ý³þSþ²¿»]:šB¹ÁØ6_Ê¡ÿÖ_÷kð,ÿ•Cÿ¬¿î×HÔÒÎÁ³÷•þ²ÿ»Pì /å0ÿë/ûµÉÿà tn]¿c4»‚Ú±*@8‰5ÆAëù¤kæg>)üG¯ˆ¯ÿë?ÞÒ#ïÐ /å0ÿë/ûµïè —ò¨õ—ýÚø-?>$g¿ˆ;¯ÿë?ß×dÿ­õ¼.>#@‰qºïl#­XSR¬u?P¥¤G~€Ùÿ*‡ÿYݯFÁ³þUþ²ÿ»]SHµÎ@¬ÿ•Dÿ¬¯î×£aY*‰ýjþít]M!\ïôËùTOúÊþíbv ™ÿCÒ¯î×FÔÒÎÁ²?5óó/ûµ?@l³‘* þ•vº>¦®nv ¡ô•J¿»^hãQ?­_Ý®“©¤+šÿÁõŸ¼¸Ö¯îÖG`Yÿ*‰ÿY_Ý®‘©© æÃ`Z*‰ÿY_ݯÃûBÆâÿÖW÷k¥ji æ¿ð{gŸñ¨Ÿõ•ýÚÍ;Èñ¨ŸÖ¯î×GÔÒΎ²þUÿï+ûµè —¼¨ÇúUýÚèúšB¹Ïè —ò¸§ÿy_Ý©úd?ãQOô«]SVÎ@,HÁ•~å+ûµàØfd_Èå_Ý®©¤+…aüª7õ«ûµçèüçæ£é?Ý®‹©¤+ÁüÃø¥F=çÐëd>Cž#“#©A$¿¯õtM!\ñ­‡`Ó‹[s£‚°¯)ïÇöŸë׈ø})!)3ÀëðtMM!\õ{R’ÒžÉC?€cqì$N²oaÌmä<Ôöâ? ¸“®©¤+ž$­K3YRÖy(”žÿý¿îÖ ø}-L©Ÿž`´¥s)(ýlç9ýÿÛ®©¤+žþ€KÇøã?ÔuçèÏåŒQ×CÔÒÍ$ü;žã|[™'ö¹þÍ‹ðÂí«H²•.»ƒ2u@:²HJ8::ëššDMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÔÐMMMMÔÔÖ*RR2¥û΃äŸðòW‡gUõ\r¯ö‘¯Ý{Ì{×Ô¿áïdÜÑU…x‰j䤀J×ÿÓ_'­Jåùè,¡ÜvÏðJ“ÇâÅJAÇ'Ò?Ú5ÂQË]Sü'.¿âµ …¡E¤ËG"=†{:ÒÍMjjC ´ókÍP:Û šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššš ©©© šššÓ*Cš.Èy z©jÀÐnÔÒ}çÄä¨!Ó!cöz×®w¹~0ÉPR!©ÓõO¯õéV;l™Q⣜‡Ûi?U¨ /Úï½^“ÊgŠ¡ú¨÷|Ë}ñl§§e­Dû•gI¶›ªBÖ\KÙÈô:”§í¾0@g’aÆJ±Zô«kñ–Á@ø.2Çä5ól­Ç)Dåá “râÉ*yGòÒý?âõ³p]ƒŠÏ¯A§|J–¤’©ŽŽò£®庇i8ÕIÎ×:Eø©v«Ç‹¯,­@`dçß?ß®Xú<çGçÊ/~%h[©çDÕ6Q•>ü9”+§·% BÕ¤ä% ‚4R‚Î8‘¦˜úR¯âDæÚHù•u}0W|[´C¥´NZ1ij޾f‹lâ@ޝ³n¥z«?ž‘_ZUüb±B€yM>?04ÙUñnµò”ÊŒP}Ô…ÿݯŒ"Þ:’ ^Pž‹CÜ’RGÞŒi÷=VHðg!*ý•õiÖÝHSN%iú¤ç_SîÉ :/`ý¨¾#NФ©©N çÙZR>­Ô×Û¿PJ&Þú“ÑÓý&ø¥²H wÀYöWcúõi :šÕöd6eÄ8“î“mÑSSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554SSSA5554ß}|K‰PëÐëø­æÉJÜPèì5Å7WÄ9óÞRܔⳟUdj|o µÛ7²¦Üv ª.2ø‚x?˜×°°YQʱ¬êšl·+®8N–çÝ­DùôTâIó·C$J=þz¹€¼»E(Ÿ>…ȰQ÷:ëÊ:®µ“ ¸ìÕ|Ú¬©*?]WV± ê£bžW×Z–á'×^(k: :À÷­…:œt¬Ð¢§z Ú‡5½·ÏÔçU@× è·)@zŸëÕ¦g(c³¡úu±@ÉÉI#̯E¡[¨ÅÖ’ÛY×V™|¤ûêèÕ׋I}6Snw[)ÄkŽÆ”@Ï/öè´;<ÄN›‹šú+moé‘AL…Ìu}Ÿñ=‹ÆÄ)D$8:ïóøö¾ÕaIO.ϧzíÿ6µå“&!l×´BÕÌ`ºx–u0×ÒÚšššÒ&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦€6è¢{ °øAèŒ-<’Aö#_=üDø¸äˆ¬=œ¦|íŸî×ÓºðŒŒÆ üþÜ? w %«åü9H²p¯êÒ=žÞ¸„JeW¾®RN¿H­6Õ%?5\Ê”}T‘Å_Ö4¥uðšš`?+1øÿD­!ÄÿÜÛ üóq‡p¤)?‘Ô[VOZûfïà;ïgåÕU(^iSgú»I¸øh’®;p,}X}þ¬çýš£å’ßï×…–»ÅŸÁYì(ò¡¸ke1V¡ýxÆ—§ü11Iñ„¶OÑÆÊOûtœ cXú×Gsa¶3ÆY?Õ­*ظI?Õ ç¼5áGz~VÇ#þ0«X’åÕýZU„@Þ½ðÿ-=•ÿã«úµÙ9ÿŒ+ú´!6u˜oòÓê6J3æ¯êÕÈ»: _pýœèŽrÖA£Ÿê×_ð–ÊAšKw÷DE‘ýšd«ø¸ÁFØ›ûÝ!¿ûDh8QôI:³—•÷L8çù©Î¾£¨ÿÛÅq.W×DúøÏ…ÿD:S|K\LëhèÕ,Gɸ«û´"ÕíKÉ„xpÖõYÀvÛ çÌqTœdþSÈëëzŸ…[Zórf¨Ë9×õ iº¶¢®µ0`ÇŽÆP€õêðóàÓq R]ÄŒYï÷„ë¸QT±U4Ñ+V0TF? a¢Zš ©©©ª&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&±sðêjh¯¿ ´‘sø¦¦¦®¬ÿ¿yÒüãÆ¦¦¢á‚·ø†ÿpÓM'¨ÔÔÐÓÝ7áGîecÐjjjã-Úššš¢jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦‚jjjh&¦¦¦ƒÿÙvdr-plugin-live/i18n.cpp0000644000175000017500000000132312650773437014726 0ustar tobiastobias/* This file has some own functionality and is used as backward compatibility for vdr prior to version 1.5.7 language support. Backward compatibility to old language support has been dropped on Feb 13, 2015. */ #include "i18n.h" namespace vdrlive { I18n& LiveI18n() { static I18n instance; return instance; } I18n::I18n() : m_encoding(cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8") { // fix encoding spelling for html standard. std::string const iso("iso"); if (m_encoding.find(iso) != std::string::npos) { if (iso.length() == m_encoding.find_first_of("0123456789")) { m_encoding.insert(iso.length(), "-"); } } } } // namespace vdrlive vdr-plugin-live/users.h0000644000175000017500000000347212650773437014764 0ustar tobiastobias#ifndef VDR_LIVE_USERS_H #define VDR_LIVE_USERS_H #include #include #include #include #include namespace vdrlive { enum eUserRights { UR_EDITSETUP=1, UR_EDITTIMERS, UR_DELTIMERS, UR_DELRECS, UR_USEREMOTE, UR_STARTREPLAY, UR_SWITCHCHNL, UR_EDITSTIMERS, UR_DELSTIMERS, UR_EDITRECS }; // --- cUser -------------------------------------------------------- class cUser : public cListObject { int m_ID; std::string m_Name; std::string m_PasswordMD5; int m_Userrights; public: cUser() : m_ID(-1), m_Userrights(0) {} cUser(int ID, const std::string& Name, const std::string& Password); int Id() const { return m_ID; } std::string Name() const { return m_Name; } std::string PasswordMD5() const { return m_PasswordMD5; } int Userrights() const { return m_Userrights; } int GetPasswordLength() const; std::string const GetMD5HashPassword() const; void SetId(int Id) { m_ID = Id; } void SetName(const std::string Name) { m_Name = Name; } void SetPassword(const std::string Password); void SetUserrights(int Userrights) { m_Userrights = Userrights; } bool HasRightTo(eUserRights right); static bool CurrentUserHasRightTo(eUserRights right); void SetRight(eUserRights right); bool Parse(const char *s); const char *ToText(void); bool Save(FILE *f); }; // --- cUsers -------------------------------------------------------- class cUsers : public cConfig { public: bool ValidUserLogin(const std::string& login, const std::string& password); bool ValidLogin(const std::string& login, const std::string& password); bool Delete(const std::string& Name); static cUser* GetByUserId(const std::string& Id); static cUser* GetByUserName(const std::string& Name); int GetNewId(); static std::string logged_in_user; }; extern cUsers Users; } #endif vdr-plugin-live/status.h0000644000175000017500000000067312650773437015146 0ustar tobiastobias#ifndef VDR_LIVE_STATUS_H #define VDR_LIVE_STATUS_H #include namespace vdrlive { class StatusMonitor: public cStatus { friend StatusMonitor& LiveStatusMonitor(); private: StatusMonitor(); StatusMonitor( StatusMonitor const& ); virtual void Recording( cDevice const* Device, char const* Name, char const* FileName, bool On ); }; StatusMonitor& LiveStatusMonitor(); } // namespace vdrlive #endif // VDR_LIVE_STATUS_H vdr-plugin-live/preload.cpp0000644000175000017500000000570312650773437015603 0ustar tobiastobias#include #include #include "filecache.h" #include "preload.h" using namespace std; namespace vdrlive { // to get an updated list of these files do: // (cd live; find * -type f ! -wholename '*CVS*' ! -wholename '*themes*' ! -name '*~' ! -name '.*') | awk '{print "\"" $1 "\","}'} // and clean out unneeded entries. void PreLoadFileCache(string const& configDir) { static char const * const preloadFiles[] = { "css/siteprefs.css", "img/rounded-box-blue-bl.png", "img/rounded-box-blue-br.png", "img/rounded-box-blue-ml.png", "img/rounded-box-blue-mr.png", "img/rounded-box-blue-tr.png", "img/rounded-box-green-bl.png", "img/rounded-box-blue-tl.png", "img/rounded-box-green-br.png", "img/rounded-box-green-ml.png", "img/rounded-box-green-mr.png", "img/del.png", "img/info-win-t-r.png", "img/info-win-m-l.png", "img/info-win-m-r.png", "img/info-win-b-l.png", "img/info-win-b-r.png", "img/close_red.png", "img/info-win-t-l.png", "img/rounded-box-green-tl.png", "img/rounded-box-green-tr.png", "img/rounded-box-orange-bl.png", "img/rounded-box-orange-br.png", "img/rounded-box-orange-ml.png", "img/rounded-box-orange-mr.png", "img/rounded-box-orange-tl.png", "img/rounded-box-orange-tr.png", "img/active.png", "img/arrow.png", "img/bg_box_h.png", "img/bg_box_l.png", "img/bg_box_r.png", "img/bg_header_h.png", "img/bg_header_l.png", "img/bg_header_r.png", "img/bg_line.png", "img/bg_line_top.png", "img/bg_tools.png", "img/button_blue.png", "img/button_green.png", "img/button_new.png", "img/button_red.png", "img/button_yellow.png", "img/close.png", "img/edit.png", "img/ffw.png", "img/file.png", "img/folder_closed.png", "img/folder_open.png", "img/help.png", "img/imdb.png", "img/inactive.png", "img/logo_login.png", "img/logo.png", "img/menu_line_bg.png", "img/minus.png", "img/movie.png", "img/on_dvd.png", "img/one_downarrow.png", "img/one_uparrow.png", "img/pause.png", "img/play.png", "img/plus.png", "img/record.png", "img/record_timer.png", "img/reload.png", "img/rwd.png", "img/search.png", "img/stop.png", "img/stop_update.png", "img/transparent.png", "img/zap.png", "img/remotecontrol.jpg", "img/tv.jpg", "img/arrow_rec.gif", "img/favicon.ico", "js/live/vdr_status.js", "js/live/infowin.js", "js/live/liveajax.js", "js/live/hinttips.js", "js/live/pageenhance.js", "js/mootools/mootools.v1.11.js", 0 }; FileCache& fc = LiveFileCache(); size_t i = 0; while (preloadFiles[i]) { FileCache::ptr_type f = fc.get(configDir + "/" + preloadFiles[i]); if (0 == f.get()) { isyslog("LIVE: can't preload %s/%s! Generated pages might be degraded!", configDir.c_str(), preloadFiles[i]); } i++; } isyslog("LIVE: initial file cache has %zu entries and needs %zu bytes of data!", fc.count(), fc.weight()); } } vdr-plugin-live/filecache.h0000644000175000017500000000314112650773437015517 0ustar tobiastobias#ifndef VDR_LIVE_FILECACHE_H #define VDR_LIVE_FILECACHE_H #include #include #include #include #include #include #include "cache.h" namespace vdrlive { class FileObject { public: FileObject( std::string const& path ) : m_ctime( std::numeric_limits< std::time_t >::max() ) , m_path( path ) {} std::size_t size() const { return m_data.size(); } std::size_t weight() const { return size(); } bool is_current() const { return m_ctime == get_filetime( m_path ); } bool load(); char const* data() const { return &m_data[0]; } std::time_t ctime() const { return m_ctime; } private: static std::time_t get_filetime( std::string const& path ); mutable std::time_t m_ctime; std::string m_path; std::vector< char > m_data; }; class FileCache: public vgstools::cache< std::string, FileObject > { typedef vgstools::cache< std::string, FileObject > base_type; public: FileCache( size_t maxWeight ): base_type( maxWeight ) {} ptr_type get( key_type const& key ) { cMutexLock lock( &m_mutex ); // dsyslog( "vdrlive::FileCache::get( %s )", key.c_str() ); // dsyslog( "vdrlive::FileCache had %u entries (weight: %u)", count(), weight() ); ptr_type result = base_type::get( key ); // dsyslog( "vdrlive::FileCache now has %u entries (weight: %u)", count(), weight() ); // dsyslog( "vdrlive::FileCache::get( %s ) = %p", key.c_str(), result.get() ); return result; } private: cMutex m_mutex; }; //typedef vgstools::cache< std::string, FileObject > FileCache; FileCache& LiveFileCache(); } // namespace vdrlive #endif // VDR_LIVE_FILECACHE_H vdr-plugin-live/livefeatures.cpp0000644000175000017500000000146012650773437016647 0ustar tobiastobias#include "livefeatures.h" #include "tools.h" namespace vdrlive { using namespace std; SplitVersion::SplitVersion( string version ) : m_version( 0 ) { static const int factors[] = { 100000000, 1000000, 1000, 1 }; size_t pos = version.find('-'); if ( pos != string::npos ) { m_suffix = version.substr( pos + 1 ); version.erase( pos ); } vector< string > parts = StringSplit( version, '.' ); for ( size_t i = 0; i < parts.size() && i < sizeof(factors)/sizeof(factors[0]); ++i ) { m_version += atoi( parts[ i ].c_str() ) * factors[ i ]; } } bool SplitVersion::operator<( const SplitVersion& right ) const { if ( m_version == right.m_version ) { if (right.m_suffix.empty()) { return false; } return m_suffix < right.m_suffix; } return m_version < right.m_version; } } // namespace vdrlive vdr-plugin-live/tntconfig.cpp0000644000175000017500000001736712650773437016161 0ustar tobiastobias#include #include #include #include #include #include "tntfeatures.h" #if TNT_LOG_SERINFO #include #include #else #include #endif #include #include #include #include #include #include "i18n.h" #include "live.h" #include "setup.h" #include "tntconfig.h" namespace vdrlive { using namespace std; TntConfig::TntConfig() { } namespace { std::string GetResourcePath() { string resourceDir(Plugin::GetResourceDirectory()); return resourceDir; } void MapUrl(tnt::Tntnet & app, const char *rule, const char * component, std::string const & instPath, const char * pathInfo, const char * mime_type) { #if TNT_MAPURL_NAMED_ARGS tnt::Mapping::args_type argMap; argMap.insert(std::make_pair("mime-type", mime_type)); #endif app.mapUrl(rule, component) .setPathInfo(instPath + pathInfo) #if TNT_MAPURL_NAMED_ARGS .setArgs(argMap); #else .pushArg(mime_type); #endif } } void TntConfig::Configure(tnt::Tntnet& app) const { string const configDir(Plugin::GetConfigDirectory()); #if TNT_LOG_SERINFO cxxtools::SerializationInfo si; std::istringstream logXmlConf( "\n" " " + LiveSetup().GetTntnetLogLevel() + "\n" " \n" " \n" " cxxtools\n" " " + LiveSetup().GetTntnetLogLevel() + "\n" " \n" " \n" " tntnet\n" " " + LiveSetup().GetTntnetLogLevel() + "\n" " \n" " \n" "\n" ); cxxtools::xml::XmlDeserializer d(logXmlConf); d.deserialize(si); log_init(si); #else std::istringstream logConf( "rootLogger=" + LiveSetup().GetTntnetLogLevel() + "\n" "logger.tntnet=" + LiveSetup().GetTntnetLogLevel() + "\n" "logger.cxxtools=" + LiveSetup().GetTntnetLogLevel() + "\n" ); log_init(logConf); #endif // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ // ------------------------------------------------------------------------ // These mapUrl statements are very security sensitive! // A wrong mapping to content may allow retrieval of arbitrary files // from your VDR system via live. // Two meassures are taken against this in our implementation: // 1. The MapUrls need to be checked regulary against possible exploits // One tool to do this can be found here: // http://www.lumadis.be/regex/test_regex.php // Newly inserted MapUrls should be marked with author and confirmed // by a second party. (use source code comments for this) // 2. content.ecpp checks the given path to be // a. an absolute path starting at / // b. not containing ../ paths components // In order to do so, the MapUrl statements must create absolute // path arguments to content@ // ------------------------------------------------------------------------ // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ app.mapUrl("^/$", "login"); // the following redirects vdr_request URL to the component // specified by the action parameter. // inserted by 'tadi' -- verified with above, but not counterchecked yet! app.mapUrl("^/vdr_request/([^.]+)", "$1"); // the following redirects play_video URL to the content component. // inserted by 'tadi' -- not verified, not counterchecked yet! //app.mapUrl("^/vlc/(.+)", "static@tntnet") // .setPathInfo("/$1") // .pushArg(string("DocumentRoot=") + VideoDirectory); // the following selects the theme specific 'theme.css' file // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/themes/([^/]*)/css.*/(.+\\.css)", "content", GetResourcePath(), "/themes/$1/css/$2", "text/css"); // the following rules provide a search scheme for images. The first // rule where a image is found, terminates the search. // 1. /themes//img/. // 2. /img/. // deprecated: 3. . (builtin images) // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/themes/([^/]*)/img.*/(.+)\\.(.+)", "content", GetResourcePath(), "/themes/$1/img/$2.$3", "image/$3"); MapUrl(app, "^/themes/([^/]*)/img.*/(.+)\\.(.+)", "content", GetResourcePath(), "/img/$2.$3", "image/$3"); // deprecated: file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) $2@" << endl; // Epg images string const epgImgPath(LiveSetup().GetEpgImageDir()); if (!epgImgPath.empty()) { // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/epgimages/([^/]*)\\.([^./]+)", "content", epgImgPath, "/$1.$2", "image/$2"); } // select additional (not build in) javascript. // WARNING: no path components with '.' in the name are allowed. Only // the basename may contain dots and must end with '.js' // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/js(/[^.]*)([^/]*\\.js)", "content", GetResourcePath(), "/js$1$2", "text/javascript"); // map to 'css/basename(uri)' // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/css.*/(.+)", "content", GetResourcePath(), "/css/$1", "text/css"); // map to 'img/basename(uri)' // inserted by 'tadi' -- verified with above, but not counterchecked yet! MapUrl(app, "^/img.*/(.+)\\.([^.]+)", "content", GetResourcePath(), "/img/$1.$2", "image/$2"); // Map favicon.ico into img directory MapUrl(app, "^/favicon.ico$", "content", GetResourcePath(), "/img/favicon.ico", "image/x-icon"); // takes first path components without 'extension' when it does not // contain '.' // modified by 'tadi' -- verified with above, but not counterchecked yet! app.mapUrl("^/([^./]+)(.*)?", "$1"); #if TNT_GLOBAL_TNTCONFIG tnt::TntConfig::it().sessionTimeout = 86400; tnt::TntConfig::it().defaultContentType = string("text/html; charset=") + LiveI18n().CharacterEncoding(); #else tnt::Sessionscope::setDefaultTimeout(86400); tnt::HttpReply::setDefaultContentType(string("text/html; charset=") + LiveI18n().CharacterEncoding()); #endif Setup::IpList const& ips = LiveSetup().GetServerIps(); int port = LiveSetup().GetServerPort(); size_t listenFailures = 0; for (Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip) { try { esyslog("[live] INFO: attempt to listen on ip = '%s'", ip->c_str()); app.listen(*ip, port); } catch (exception const & ex) { esyslog("[live] ERROR: ip = %s is invalid: exception = %s", ip->c_str(), ex.what()); if (++listenFailures == ips.size()) { // if no listener was initialized we throw at // least the last exception to the next layer. throw; } } } int s_port = LiveSetup().GetServerSslPort(); string s_cert = LiveSetup().GetServerSslCert(); string s_key = LiveSetup().GetServerSslKey(); if (s_cert.empty()) { s_cert = configDir + "/live.pem"; } if (s_key.empty()) { s_key = configDir + "/live-key.pem"; } if ( ifstream( s_cert.c_str() ) && ifstream( s_key.c_str() ) ) { for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { app.sslListen(s_cert, s_key, *ip, s_port); } } else { esyslog( "[live] ERROR: Unable to load cert/key (%s/%s): %s", s_cert.c_str(), s_key.c_str(), strerror( errno ) ); } } TntConfig const& TntConfig::Get() { static TntConfig instance; return instance; } } // namespace vdrlive vdr-plugin-live/grab.h0000644000175000017500000000136612650773437014536 0ustar tobiastobias#ifndef VDR_LIVE_GRAB_H #define VDR_LIVE_GRAB_H #include "stdext.h" #include "tasks.h" namespace vdrlive { typedef std::tr1::shared_ptr< char > GrabImagePtr; typedef std::pair< GrabImagePtr, int > GrabImageInfo; class GrabImageTask; class GrabImageManager { friend GrabImageManager& LiveGrabImageManager(); friend class GrabImageTask; public: bool CanGrab() const; GrabImageInfo GetImage() const; private: GrabImageManager(); GrabImageManager( GrabImageManager const& ); GrabImageManager& operator=( GrabImageManager const& ); void PutImage( char* image, int size ); std::auto_ptr< GrabImageTask > m_task; GrabImagePtr m_image; int m_size; }; GrabImageManager& LiveGrabImageManager(); } // namespace vdrlive #endif // VDR_LIVE_GRAB_H vdr-plugin-live/buildutil/0000755000175000017500000000000012650773437015441 5ustar tobiastobiasvdr-plugin-live/buildutil/version-util0000755000175000017500000000504712650773437020035 0ustar tobiastobias#!/bin/bash # ----------------------------------------------------------------------------- # Shell script to determine the last commit version of the project It # checks for CVS and .git repositories. The output is a string that # can be used in a define at compile time to automatically mark # repository versions. For CVS repositories the string contains the # date and time of the commit that lead to the current version of # files. For git repositories the output contains the git-id of the # current tree. An indication if localy modified files exist is # added currently only for CVS. # ----------------------------------------------------------------------------- [ $# -lt 1 ] && echo "USAGE: version-util [-F] " && exit 1 VERS_FILE=$1 FORCE_EMPTY=0 [ "$VERS_FILE" == "-F" -a $# -lt 2 ] && echo "USAGE: version-util [-F] " && exit 1 if [ $# -gt 1 ]; then VERS_FILE=$2 FORCE_EMPTY=1 fi SCRIPT_PATH=`dirname $0` # echo "file: ${VERS_FILE}, force = $FORCE_EMPTY" # exit 0 createVers() { cat < /dev/null } cvsData() { fileVersions cvsLog } cvsVers() { d=`cvsData \ | awk -f ${SCRIPT_PATH}/version-util.awk \ | sort -u \ | tail -1 \ | tr -d ' \-:'` m=`cvs status 2> /dev/null \ | grep 'Status: Locally Modified' > /dev/null && echo "_MOD"` echo "_cvs_${d}${m}" } gitVers() { b=`git branch \ | grep '^*' \ | sed -e's/^* //'` h=`git show --pretty=format:"%h_%ci" HEAD \ | head -1 \ | tr -d ' \-:'` echo "_git_${b}_${h}" } emptyVers() { echo "" } checkVers() { s=`$1` if [ ! -e ${VERS_FILE} ]; then echo "$VERS_FILE does not exist! creating a new one." createVers $s > ${VERS_FILE} else v=`grep '^#define VERSION_SUFFIX' ${VERS_FILE} \ | awk '{print $3}'` if [ "$v" != "\"$s\"" ]; then echo "$VERS_FILE is being recreated!" createVers $s > ${VERS_FILE} fi fi } if [ $FORCE_EMPTY -eq 1 ]; then checkVers emptyVers exit 0 fi if [ -d CVS ]; then checkVers cvsVers exit 0 fi if [ -d .git ]; then checkVers gitVers exit 0 fi checkVers emptyVers vdr-plugin-live/buildutil/version-util.awk0000644000175000017500000000133612650773437020610 0ustar tobiastobiasBEGIN { FS="|"; init_revisions = 1; rev_trigger = 0; date_trigger = 0; } /= == ===marker=== == =/ { init_revisions = 0; FS=";"; next; } init_revisions == 1 { # print "XXX " $1, $2; file_revs[$1] = $2; next; } /^Working file:/ { rev_trigger = 0; if (match($0, "^Working file: (.*)$", f) > 0) { if (f[1] in file_revs) { revision = "revision " file_revs[f[1]]; rev_trigger = 1; } } # print "FFF " f[1], revision, rev_trigger; next; } rev_trigger == 1 && /^revision/ { if (match($0, revision) > 0) { # print "FOUND " revision, $0; rev_trigger = 0; date_trigger = 1; } next; } date_trigger == 1 { if (match($1, "date: (.*)", d) > 0) { print d[1]; } date_trigger = 0; } { next; } vdr-plugin-live/thread.h0000644000175000017500000000061412650773437015065 0ustar tobiastobias#ifndef VDR_LIVE_THREAD_H #define VDR_LIVE_THREAD_H #include #include namespace tnt { class Tntnet; } namespace vdrlive { class ServerThread : public cThread { public: ServerThread(); virtual ~ServerThread(); void Stop(); protected: virtual void Action(); private: std::auto_ptr< tnt::Tntnet > m_server; }; } // namespace vdrlive #endif // VDR_LIVE_THREAD_H vdr-plugin-live/grab.cpp0000644000175000017500000000402112650773437015060 0ustar tobiastobias#include #include #include #include "grab.h" namespace vdrlive { using namespace std; const unsigned int GrabMinIntervalMs = 500; const unsigned int GrabPauseIntervalMs = GrabMinIntervalMs * 20; class GrabImageTask: public StickyTask { public: explicit GrabImageTask( int quality = 80, int width = 729, int height = 480 ) : m_firstTime( 0 ) , m_lastTime( 0 ) , m_quality( quality ) , m_width( width ) , m_height( height ) {} void Activate() { m_firstTime = 0; } bool IsActive(); private: uint64_t m_firstTime; uint64_t m_lastTime; int m_quality; int m_width; int m_height; bool GrabImage(); virtual void Action(); }; bool GrabImageTask::IsActive() { cMutexLock lock( &LiveTaskManager() ); return GrabImage(); } bool GrabImageTask::GrabImage() { cDevice* device = cDevice::PrimaryDevice(); if ( device == 0 ) { SetError( tr("Couldn't aquire primary device") ); return false; } int size = 0; uchar* image = device->GrabImage( size, true, m_quality, m_width, m_height ); if ( image == 0 ) { SetError( tr("Couldn't grab image from primary device") ); return false; } LiveGrabImageManager().PutImage( reinterpret_cast< char* >( image ), size ); return true; } void GrabImageTask::Action() { uint64_t now = cTimeMs::Now(); if ( m_firstTime == 0 ) m_firstTime = now; if ( now - m_lastTime < GrabMinIntervalMs || now - m_firstTime > GrabPauseIntervalMs ) return; if ( !GrabImage() ) return; m_lastTime = now; } GrabImageManager::GrabImageManager() : m_task( new GrabImageTask ) , m_size( 0 ) { } GrabImageInfo GrabImageManager::GetImage() const { cMutexLock lock( &LiveTaskManager() ); m_task->Activate(); return make_pair( m_image, m_size ); } bool GrabImageManager::CanGrab() const { return m_task->IsActive(); } void GrabImageManager::PutImage( char* image, int size ) { m_image.reset( image, &free ); m_size = size; } GrabImageManager& LiveGrabImageManager() { static GrabImageManager instance; return instance; } } // namespace vdrlive vdr-plugin-live/md5.cpp0000644000175000017500000002054012650773437014636 0ustar tobiastobias///////////////////////////////////////////////////////////////////////// // MD5.cpp // Implementation file for MD5 class // // This C++ Class implementation of the original RSA Data Security, Inc. // MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle. // All rights reserved. This software is a derivative of the "RSA Data // Security, Inc. MD5 Message-Digest Algorithm" // // You may use this software free of any charge, but without any // warranty or implied warranty, provided that you follow the terms // of the original RSA copyright, listed below. // // Original RSA Data Security, Inc. Copyright notice ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All // rights reserved. // // License to copy and use this software is granted provided that it // is identified as the "RSA Data Security, Inc. MD5 Message-Digest // Algorithm" in all material mentioning or referencing this software // or this function. // License is also granted to make and use derivative works provided // that such works are identified as "derived from the RSA Data // Security, Inc. MD5 Message-Digest Algorithm" in all material // mentioning or referencing the derived work. // RSA Data Security, Inc. makes no representations concerning either // the merchantability of this software or the suitability of this // software for any particular purpose. It is provided "as is" // without express or implied warranty of any kind. // These notices must be retained in any copies of any part of this // documentation and/or software. ///////////////////////////////////////////////////////////////////////// #include #include #include #include #include "md5.h" static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 // PrintMD5: Converts a completed md5 digest into a char* string. char* PrintMD5(uchar md5Digest[16]) { char chBuffer[256]; char chEach[10]; int nCount; memset(chBuffer,0,256); memset(chEach, 0, 10); for (nCount = 0; nCount < 16; nCount++) { sprintf(chEach, "%02x", md5Digest[nCount]); strncat(chBuffer, chEach, sizeof(chEach)); } return strdup(chBuffer); } // MD5String: Performs the MD5 algorithm on a char* string, returning // the results as a char*. char* MD5String(char* szString) { int nLen = strlen(szString); md5 alg; alg.Update((unsigned char*)szString, (unsigned int)nLen); alg.Finalize(); return PrintMD5(alg.Digest()); } // md5::Init // Initializes a new context. void md5::Init() { memset(m_Count, 0, 2 * sizeof(uint4)); m_State[0] = 0x67452301; m_State[1] = 0xefcdab89; m_State[2] = 0x98badcfe; m_State[3] = 0x10325476; } // md5::Update // MD5 block update operation. Continues an MD5 message-digest // operation, processing another message block, and updating the // context. void md5::Update(uchar* chInput, uint4 nInputLen) { uint4 i, index, partLen; // Compute number of bytes mod 64 index = (unsigned int)((m_Count[0] >> 3) & 0x3F); // Update number of bits if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3)) m_Count[1]++; m_Count[1] += (nInputLen >> 29); partLen = 64 - index; // Transform as many times as possible. if (nInputLen >= partLen) { memcpy( &m_Buffer[index], chInput, partLen ); Transform(m_Buffer); for (i = partLen; i + 63 < nInputLen; i += 64) Transform(&chInput[i]); index = 0; } else i = 0; // Buffer remaining input memcpy( &m_Buffer[index], &chInput[i], nInputLen-i ); } // md5::Finalize // MD5 finalization. Ends an MD5 message-digest operation, writing // the message digest and zeroizing the context. void md5::Finalize() { uchar bits[8]; uint4 index, padLen; // Save number of bits Encode (bits, m_Count, 8); // Pad out to 56 mod 64 index = (unsigned int)((m_Count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); Update(PADDING, padLen); // Append length (before padding) Update (bits, 8); // Store state in digest Encode (m_Digest, m_State, 16); memset(m_Count, 0, 2 * sizeof(uint4)); memset(m_State, 0, 4 * sizeof(uint4)); memset(m_Buffer,0, 64 * sizeof(uchar)); } // md5::Transform // MD5 basic transformation. Transforms state based on block. void md5::Transform (uchar* block) { uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16]; Decode (x, block, 64); // Round 1 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); FF (c, d, a, b, x[ 2], S13, 0x242070db); FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); FF (d, a, b, c, x[ 5], S12, 0x4787c62a); FF (c, d, a, b, x[ 6], S13, 0xa8304613); FF (b, c, d, a, x[ 7], S14, 0xfd469501); FF (a, b, c, d, x[ 8], S11, 0x698098d8); FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); FF (c, d, a, b, x[10], S13, 0xffff5bb1); FF (b, c, d, a, x[11], S14, 0x895cd7be); FF (a, b, c, d, x[12], S11, 0x6b901122); FF (d, a, b, c, x[13], S12, 0xfd987193); FF (c, d, a, b, x[14], S13, 0xa679438e); FF (b, c, d, a, x[15], S14, 0x49b40821); // Round 2 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); GG (d, a, b, c, x[ 6], S22, 0xc040b340); GG (c, d, a, b, x[11], S23, 0x265e5a51); GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); GG (a, b, c, d, x[ 5], S21, 0xd62f105d); GG (d, a, b, c, x[10], S22, 0x2441453); GG (c, d, a, b, x[15], S23, 0xd8a1e681); GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); GG (d, a, b, c, x[14], S22, 0xc33707d6); GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); GG (b, c, d, a, x[ 8], S24, 0x455a14ed); GG (a, b, c, d, x[13], S21, 0xa9e3e905); GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); GG (c, d, a, b, x[ 7], S23, 0x676f02d9); GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); // Round 3 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); HH (d, a, b, c, x[ 8], S32, 0x8771f681); HH (c, d, a, b, x[11], S33, 0x6d9d6122); HH (b, c, d, a, x[14], S34, 0xfde5380c); HH (a, b, c, d, x[ 1], S31, 0xa4beea44); HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); HH (b, c, d, a, x[10], S34, 0xbebfbc70); HH (a, b, c, d, x[13], S31, 0x289b7ec6); HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); HH (b, c, d, a, x[ 6], S34, 0x4881d05); HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); HH (d, a, b, c, x[12], S32, 0xe6db99e5); HH (c, d, a, b, x[15], S33, 0x1fa27cf8); HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); // Round 4 II (a, b, c, d, x[ 0], S41, 0xf4292244); II (d, a, b, c, x[ 7], S42, 0x432aff97); II (c, d, a, b, x[14], S43, 0xab9423a7); II (b, c, d, a, x[ 5], S44, 0xfc93a039); II (a, b, c, d, x[12], S41, 0x655b59c3); II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); II (c, d, a, b, x[10], S43, 0xffeff47d); II (b, c, d, a, x[ 1], S44, 0x85845dd1); II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); II (d, a, b, c, x[15], S42, 0xfe2ce6e0); II (c, d, a, b, x[ 6], S43, 0xa3014314); II (b, c, d, a, x[13], S44, 0x4e0811a1); II (a, b, c, d, x[ 4], S41, 0xf7537e82); II (d, a, b, c, x[11], S42, 0xbd3af235); II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); II (b, c, d, a, x[ 9], S44, 0xeb86d391); m_State[0] += a; m_State[1] += b; m_State[2] += c; m_State[3] += d; memset(x, 0, sizeof(x)); } // md5::Encode // Encodes input (uint4) into output (uchar). Assumes nLength is // a multiple of 4. void md5::Encode(uchar* dest, uint4* src, uint4 nLength) { uint4 i, j; assert(nLength % 4 == 0); for (i = 0, j = 0; j < nLength; i++, j += 4) { dest[j] = (uchar)(src[i] & 0xff); dest[j+1] = (uchar)((src[i] >> 8) & 0xff); dest[j+2] = (uchar)((src[i] >> 16) & 0xff); dest[j+3] = (uchar)((src[i] >> 24) & 0xff); } } // md5::Decode // Decodes input (uchar) into output (uint4). Assumes nLength is // a multiple of 4. void md5::Decode(uint4* dest, uchar* src, uint4 nLength) { uint4 i, j; assert(nLength % 4 == 0); for (i = 0, j = 0; j < nLength; i++, j += 4) { dest[i] = ((uint4)src[j]) | (((uint4)src[j+1])<<8) | (((uint4)src[j+2])<<16) | (((uint4)src[j+3])<<24); } } vdr-plugin-live/tntfeatures.h0000644000175000017500000000221112650773437016155 0ustar tobiastobias#ifndef VDR_LIVE_TNTFEATURES_H #define VDR_LIVE_TNTFEATURES_H // This header mapps tntversion strings, whose 'structure' changes over time, // to features of tntnet used in the live plugin. This avoids scattering the // version check for TNTVERSION over several source files in live. Thus when // an other change in the structure of the version string was needed then only // this file needs to be adapted. // Query params without boolean parameter #define TNT_QUERYPARAMS_NO_BOOL (TNTVERSION >= 22000) // new version of TNTNET allow the request watchdog to be silenced. #define TNT_WATCHDOG_SILENCE (TNTVERSION >= 16900) // version of TNTNET that binds ipv6 addresses with IPV6_V6ONLY flag set to true #define TNT_IPV6_V6ONLY (CXXTOOLVER >= 21000) // version of TNTNET with properties deserializer for logger configuration args. #define TNT_LOG_SERINFO (CXXTOOLVER >= 22000) // version of TNTNET wich expects name, value mappings for Url-Mapper arguments. #define TNT_MAPURL_NAMED_ARGS (TNTVERSION >= 22000) // version of TNTNET where configuration is global #define TNT_GLOBAL_TNTCONFIG (TNTVERSION >= 22000) #endif // VDR_LIVE_TNTFEATURES_H vdr-plugin-live/live.cpp0000644000175000017500000000345412650773437015115 0ustar tobiastobias/* * live.cpp: A plugin for the Video Disk Recorder * * See the README file for copyright information and how to reach the author. */ #include #include #include "i18n.h" #include "live.h" #include "setup.h" #include "status.h" #include "tasks.h" #include "thread.h" #include "timers.h" #include "preload.h" #include "users.h" namespace vdrlive { using namespace std; const char *Plugin::VERSION = LIVEVERSION; const char *Plugin::DESCRIPTION = LIVESUMMARY; std::string Plugin::m_configDirectory; std::string Plugin::m_resourceDirectory; cUsers Users; Plugin::Plugin(void) { } const char *Plugin::CommandLineHelp(void) { return LiveSetup().CommandLineHelp(); } bool Plugin::ProcessArgs(int argc, char *argv[]) { return LiveSetup().ParseCommandLine( argc, argv ); } bool Plugin::Start(void) { m_configDirectory = canonicalize_file_name(cPlugin::ConfigDirectory( PLUGIN_NAME_I18N )); m_resourceDirectory = canonicalize_file_name(cPlugin::ResourceDirectory( PLUGIN_NAME_I18N )); // force status monitor startup LiveStatusMonitor(); // preload files into file Cache PreLoadFileCache(m_resourceDirectory); // load users Users.Load(AddDirectory(m_configDirectory.c_str(), "users.conf"), true); // XXX error handling m_thread.reset( new ServerThread ); m_thread->Start(); return true; } void Plugin::Stop(void) { m_thread->Stop(); } void Plugin::MainThreadHook(void) { LiveTimerManager().DoPendingWork(); LiveTaskManager().DoScheduledTasks(); } cString Plugin::Active(void) { return NULL; } cMenuSetupPage *Plugin::SetupMenu(void) { return new cMenuSetupLive(); } bool Plugin::SetupParse(const char *Name, const char *Value) { return LiveSetup().ParseSetupEntry( Name, Value ); } } // namespace vdrlive VDRPLUGINCREATOR(vdrlive::Plugin); // Don't touch this! vdr-plugin-live/users.cpp0000644000175000017500000001045712650773437015320 0ustar tobiastobias/* * users.cpp: User specific rights for the LIVE plugin. * * See the README file for copyright information and how to reach the author. */ #include "users.h" #include #include #include "tools.h" #include "setup.h" namespace vdrlive { using namespace std; std::string cUsers::logged_in_user; // -- cUser ----------------------------------------------------------------- cUser::cUser(int ID, const std::string& Name, const std::string& Password) : m_ID(ID), m_Name(Name) { SetPassword(Password); } void cUser::SetPassword(const std::string Password) { ostringstream passwordStr; passwordStr << Password.size() << "|" << MD5Hash(Password); m_PasswordMD5 = passwordStr.str(); } int cUser::GetPasswordLength() const { // format is : vector< string > parts = StringSplit( m_PasswordMD5, '|' ); return (parts.size() > 0) ? lexical_cast< int >( parts[0] ) : 0; } std::string const cUser::GetMD5HashPassword() const { // format is : vector< string > parts = StringSplit( m_PasswordMD5, '|' ); return (parts.size() > 1) ? parts[1] : ""; } bool cUser::Parse(const char *s) { char *line; char *pos; char *pos_next; int parameter = 1; int valuelen; #define MAXVALUELEN (10 * MaxFileName) char value[MAXVALUELEN]; pos = line = strdup(s); pos_next = pos + strlen(pos); if (*pos_next == '\n') *pos_next = 0; while (*pos) { while (*pos == ' ') pos++; if (*pos) { if (*pos != ':') { pos_next = strchr(pos, ':'); if (!pos_next) pos_next = pos + strlen(pos); valuelen = pos_next - pos + 1; if (valuelen > MAXVALUELEN) { esyslog("entry '%s' is too long. Will be truncated!", pos); valuelen = MAXVALUELEN; } strn0cpy(value, pos, valuelen); pos = pos_next; switch (parameter) { case 1: m_ID = lexical_cast< int >(value); break; case 2: m_Name = value; break; case 3: m_PasswordMD5 = value; break; case 4: m_Userrights = lexical_cast< int >(value); break; default: break; } //switch } parameter++; } if (*pos) pos++; } //while free(line); return (parameter >= 4) ? true : false; } const char *cUser::ToText(void) { char* buffer = NULL; if (asprintf(&buffer, "%d:%s:%s:%d", m_ID, m_Name.c_str(), m_PasswordMD5.c_str(), m_Userrights) < 0) return NULL; return buffer; } bool cUser::Save(FILE *f) { return fprintf(f, "%s\n", ToText()) > 0; } bool cUser::HasRightTo(eUserRights right) { return ((m_Userrights & (1 << (right-1))) != 0); } bool cUser::CurrentUserHasRightTo(eUserRights right) { if (!LiveSetup().UseAuth()) return true; cUser* user = cUsers::GetByUserName(cUsers::logged_in_user); return (cUsers::logged_in_user == LiveSetup().GetAdminLogin() || (user && (user->m_Userrights & (1 << (right-1))) != 0)); } void cUser::SetRight(eUserRights right) { isyslog("set right '%d' in '%d'", right, m_Userrights); m_Userrights |= (1 << (right-1)); isyslog("now rights are '%d'", m_Userrights); } bool cUsers::Delete(const std::string& Name) { cUser* user = Users.First(); while (user) { if (user->Name() == Name) { Users.Del(user); Users.Save(); return true; } user = Users.Next(user); } return false; } cUser* cUsers::GetByUserId(const std::string& Id) { cUser* user = Users.First(); while (user) { if (user->Id() == atoi(Id.c_str())) return user; user = Users.Next(user); } return NULL; } cUser* cUsers::GetByUserName(const std::string& Name) { cUser* user = Users.First(); while (user) { if (user->Name() == Name) return user; user = Users.Next(user); } return NULL; } int cUsers::GetNewId() { int iMaxId = -1; cUser* user = Users.First(); while (user) { if (iMaxId < user->Id()) iMaxId = user->Id(); user = Users.Next(user); } return iMaxId + 1; } bool cUsers::ValidUserLogin(const std::string& login, const std::string& password) { cUser* user = GetByUserName(login); if (user && MD5Hash(password) == user->GetMD5HashPassword()) return true; return false; } bool cUsers::ValidLogin(const std::string& login, const std::string& password) { return ((login == LiveSetup().GetAdminLogin() && MD5Hash(password) == LiveSetup().GetMD5HashAdminPassword()) || ValidUserLogin(login, password)); } } vdr-plugin-live/pages/0000755000175000017500000000000012650773437014543 5ustar tobiastobiasvdr-plugin-live/pages/setup.ecpp0000644000175000017500000003076412650773437016566 0ustar tobiastobias<%pre> #include #include #include "setup.h" #include "tools.h" #include "users.h" #include "i18n.h" using namespace vdrlive; using namespace std; <%args> string lastchannel; bool useauth = false; string login; string pass; string times; string channelGroups; string scheduleDuration; string startscreen; string theme; string localnetmask; string showLogo; string useAjax; string showInfoBox; string useStreamdev; string showIMDb; string showChannelsWithoutEPG; string streamdevport; string streamdevtype; int authchanged = 0; <%session scope="global"> bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth() ) return reply.redirect("login.html"); if (!cUser::CurrentUserHasRightTo(UR_EDITSETUP)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); #define SELECTIF(x) reply.out() << ( (x) ? "selected=\"selected\"" : "" ); #define CHECKIF(x) reply.out() << ( (x) ? "checked=\"checked\"" : "" ); std::string message; if ( request.getMethod() == "POST") { if (authchanged && useauth && (login.empty() || pass.empty())) message = tr("Please set login and password!"); else { LiveSetup().SetLastChannel(lastchannel != "" ? lexical_cast< int >(lastchannel):0); LiveSetup().SetUseAuth(useauth); if (useauth) { LiveSetup().SetAdminLogin(login); if (pass != "") LiveSetup().SetAdminPassword(pass); LiveSetup().SetLocalNetMask(localnetmask); LiveSetup().CheckLocalNet(request.getPeerIp()); } LiveSetup().SetTimes(times); LiveSetup().SetChannelGroups(channelGroups); LiveSetup().SetScheduleDuration(scheduleDuration); LiveSetup().SetStartScreen(startscreen); LiveSetup().SetTheme(theme); LiveSetup().SetShowLogo(!showLogo.empty()); LiveSetup().SetUseAjax(!useAjax.empty()); if (LiveSetup().GetUseAjax()) { LiveSetup().SetShowInfoBox(!showInfoBox.empty()); } LiveSetup().SetUseStreamdev(!useStreamdev.empty()); LiveSetup().SetStreamdevPort(streamdevport.empty() ? 3000 : lexical_cast(streamdevport)); LiveSetup().SetStreamdevType(streamdevtype.empty() ? "PES" : streamdevtype); LiveSetup().SetShowIMDb(!showIMDb.empty()); LiveSetup().SetShowChannelsWithoutEPG(!showChannelsWithoutEPG.empty()); LiveSetup().SaveSetup(); message = tr("Setup saved."); } } pageTitle = tr("Setup"); int ilastchannel = LiveSetup().GetLastChannel(); if (ilastchannel == std::numeric_limits< int >::max()) lastchannel = ""; else lastchannel = lexical_cast(ilastchannel); login = LiveSetup().GetAdminLogin(); useauth = LiveSetup().GetUseAuth(); times = LiveSetup().GetTimes(); channelGroups = LiveSetup().GetChannelGroups(); scheduleDuration = LiveSetup().GetScheduleDuration(); startscreen = LiveSetup().GetStartScreen(); theme = LiveSetup().GetTheme(); localnetmask = LiveSetup().GetLocalNetMask(); showLogo = LiveSetup().GetShowLogo() ? "1" : ""; useAjax = LiveSetup().GetUseAjax() ? "1" : ""; showInfoBox = LiveSetup().GetShowInfoBox() ? "1" : ""; useStreamdev = LiveSetup().GetUseStreamdev() ? "1" : ""; streamdevport = lexical_cast(LiveSetup().GetStreamdevPort()); streamdevtype = LiveSetup().GetStreamdevType(); showIMDb = LiveSetup().GetShowIMDb() ? "1" : ""; showChannelsWithoutEPG = LiveSetup().GetShowChannelsWithoutEPG() ? "1" : ""; <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("setup") &>
<$ tr("Setup") $>
<$ tr("Use authentication") $>:
CHECKIF(useauth); onclick="changeduseauth(this)"/>
<$ tr("Show live logo image") $>:
CHECKIF(!showLogo.empty()); />
<$ tr("Use ajax technology") $>:
CHECKIF(!useAjax.empty()); onclick="changeduseajax(this)"/>
<$ tr("Allow video streaming") $>:
CHECKIF(!useStreamdev.empty()); onclick="changedusestreamdev(this)"/>
<$ tr("Add links to IMDb") $>:
CHECKIF(!showIMDb.empty()); />
<$ tr("Last channel to display") $>:
<$ tr("Additional fixed times in 'What's on?'") $>:
<& tooltip.help text=(tr("Format is HH:MM. Separate multiple times with a semicolon")) &>
<$ tr("Channel groups for MultiSchedule") $>:
<& tooltip.help text=(tr("Separate channels with a comma ',', separate groups with a semi-colon ';'")) &>
<$ tr("Duration of MultiSchedule in hours") $>:
<$ tr("Show channels without EPG") $>:
CHECKIF(!showChannelsWithoutEPG.empty()); />
<$ tr("Start page") $>:
<$ tr("Theme") $>:
<%include>page_exit.eh vdr-plugin-live/pages/remote.ecpp0000644000175000017500000001704012650773437016711 0ustar tobiastobias<%pre> #include #include #include #include #include "grab.h" #include "setup.h" #include "tools.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> int channel = -1; <%session scope="global"> bool logged_in(false); <%request scope="page"> cChannel* Channel; <%include>page_init.eh <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }> <%cpp> if (!cUser::CurrentUserHasRightTo(UR_USEREMOTE)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); pageTitle = tr("Remote Control"); ReadLock channelsLock( Channels ); if ( !channelsLock ) throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); // cChannel* Channel; (see %request above) if ( channel > 0 ) { Channel = Channels.GetByNumber( channel ); } else { if (cDevice::CurrentChannel()) { Channel = Channels.GetByNumber(cDevice::CurrentChannel()); } else { Channel = Channels.Get( Channels.GetNextNormal( -1 ) ); } } if ( Channel == 0 ) throw HtmlError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") ); <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> % reply.sout().imbue(locale()); <& pageelems.logo &> <& menu active="remote" component=("remote.remote_actions")>
<{ if (!LiveGrabImageManager().CanGrab()) { }> bloek <{ } else { }>
<{ } }>
" width="162" height="378" border="0" usemap="#remote" alt="" /> Power 1 2 3 4 5 6 7 8 9 0 Vol+ Vol- P+ P- Mute Record Menu Exit Subtitles Audio Up Right Down Left Ok Red Green Yellow Blue
<%include>page_exit.eh <%def remote_actions> <$ tr("Snapshot interval") $>:           <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> vdr-plugin-live/pages/edit_timer.ecpp0000644000175000017500000002615312650773437017550 0ustar tobiastobias<%pre> #include #include #include #include #include #include "exception.h" #include "tools.h" #include "timers.h" #include "setup.h" #include "epg_events.h" #include "timerconflict.h" #include "i18n.h" #include "livefeatures.h" #include "epgsearch.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> // input parameters string timerid; string epgid; string async; // form parameters tChannelID channel; int active = 1; string title = ""; string date = ""; bool wday_mon = false; bool wday_tue = false; bool wday_wed = false; bool wday_thu = false; bool wday_fri = false; bool wday_sat = false; bool wday_sun = false; int start_h = 0; int start_m = 0; int end_h = 0; int end_m = 0; bool vps = 0; int priority = 0; int lifetime = 0; string aux = ""; string directory = ""; <%session scope="global"> bool logged_in(false); string edit_timerreferer; TimerConflictNotifier timerNotifier; <%request scope="page"> cTimer* timer; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); if (!cUser::CurrentUserHasRightTo(UR_EDITTIMERS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); bool ajaxReq = !async.empty() && (lexical_cast(async) != 0); tChannelID channelid = tChannelID(); tEventID eventid = tEventID(); string message; cMutexLock timersLock( &LiveTimerManager() ); SortedTimers& timers = LiveTimerManager().GetTimers(); timer = 0; if ( !timerid.empty() ) { string tId = SortedTimers::DecodeDomId(timerid); // dsyslog("DEBUG: TIMER: tId = %s", tId.c_str()); timer = timers.GetByTimerId(tId); if ( timer == 0 ) throw HtmlError( tr("Couldn't find timer. Maybe you mistyped your request?") ); } if ( request.getMethod() == "POST" ) { uint flags = ( active ? tfActive : 0 ) | ( vps ? tfVps : 0 ); string weekdays = string( wday_mon ? "M" : "-" ) + ( wday_tue ? "T" : "-" ) + ( wday_wed ? "W" : "-" ) + ( wday_thu ? "T" : "-" ) + ( wday_fri ? "F" : "-" ) + ( wday_sat ? "S" : "-" ) + ( wday_sun ? "S" : "-" ); int start = start_h * 100 + start_m; int stop = end_h * 100 + end_m; if (!directory.empty()) title = directory + "~" + title; if (title.empty()) message = tr("Please set a title for the timer!"); else { // TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's time_t tdate = GetDateFromDatePicker(date, tr("mm/dd/yyyy")); string sdate = DatePickerToC(tdate, "yyyy-mm-dd"); LiveTimerManager().UpdateTimer( timer, flags, channel, weekdays, sdate, start, stop, priority, lifetime, title, aux ); timerNotifier.SetTimerModification(); return reply.redirect(!edit_timerreferer.empty()?edit_timerreferer:"timers.html"); } } if (message.empty()) edit_timerreferer = request.getHeader("Referer:", "timers.html"); auto_ptr< cTimer > eventTimer; if ( timer == 0 && !epgid.empty()) { EpgEvents::DecodeDomId(epgid, channelid, eventid); if ( channelid.Valid() && eventid != 0 ) { cerr << "grabbing event" << endl << endl; cSchedulesLock schedLock; cSchedules const* schedules = cSchedules::Schedules( schedLock ); cSchedule const* schedule = schedules->GetSchedule( channelid ); eventTimer.reset( new cTimer( schedule->GetEvent( eventid ) ) ); } else { cerr << "grabbing new timer" << endl << endl; eventTimer.reset( new cTimer() ); eventTimer->SetFlags( tfActive ); } timer = eventTimer.get(); } if (timer == 0) { timer = new cTimer(); timer->SetFlags(tfActive); } if ( timer != 0 ) { active = timer->Flags() & tfActive; channel = timer->Channel()->GetChannelID(); title = timer->File() ? timer->File() : ""; if ( LiveFeatures< features::epgsearch >().Recent() ) { vector< string > directories = StringSplit( title, '~' ); if (directories.size() > 1) { directory = directories[0]; title = title.substr(directory.size()+1); } } // TRANSLATORS: only adjust the ordering and separators, don't translate the m's, d's and y's date = timer->Day() ? DatePickerToC(timer->Day(), tr("mm/dd/yyyy")) : ""; wday_mon = timer->WeekDays() & 0x01; wday_tue = timer->WeekDays() & 0x02; wday_wed = timer->WeekDays() & 0x04; wday_thu = timer->WeekDays() & 0x08; wday_fri = timer->WeekDays() & 0x10; wday_sat = timer->WeekDays() & 0x20; wday_sun = timer->WeekDays() & 0x40; start_h = ( timer->Start() / 100 ) % 100; start_m = timer->Start() % 100; end_h = ( timer->Stop() / 100 ) % 100; end_m = timer->Stop() % 100; vps = timer->Flags() & tfVps; priority = timer->Priority(); lifetime = timer->Lifetime(); aux = timer->Aux() ? timer->Aux() : ""; } <& pageelems.doc_type &> VDR Live - <$ timer ? tr("Edit timer") : tr("New timer") $> <%cpp> if (!ajaxReq) { <& pageelems.stylesheets &> <& pageelems.ajax_js &> <%cpp> } <%cpp> if (!ajaxReq) { <& pageelems.logo &> <& menu active=("timers") &> <%cpp> }
<%cpp> if ( LiveFeatures< features::epgsearch >().Recent() ) { RecordingDirs recordingdirs(true); <%cpp> }
<$ timer ? tr("Edit timer") : tr("New timer") $>
<$ trVDR("Active") $>:
type="radio">
type="radio">
<$ trVDR("Channel") $>:
<& channels_widget name=("channel") channelid=(true) selected=(channel) &>
<$ tr("Title" ) $>:
<$ tr("Directory" ) $>:
<$ trVDR("Day") $>:
<$ tr("Weekday") $>:
/>
/>
/>
/>
/>
/>
/>
<$ trVDR("Start") $>:
:
<$ trVDR("Stop") $>:
:
<$ tr("Use VPS") $>:
/>
<$ trVDR("Priority") $>:
<$ trVDR("Lifetime") $>:
<$ message $>
<%include>page_exit.eh vdr-plugin-live/pages/searchtimers.ecpp0000644000175000017500000001022312650773437020103 0ustar tobiastobias<%pre> #include #include #include "epgsearch.h" #include "tools.h" #include "setup.h" #include "users.h" using namespace vdrlive; using namespace std; <%args> // input parameters string searchtimerid; string action; <%session scope="global"> bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%cpp> pageTitle = tr("Searchtimers"); SearchTimers timers; if ( !searchtimerid.empty() ) { if (action == "toggle") timers.ToggleActive(searchtimerid); if (action == "delete") { if (!cUser::CurrentUserHasRightTo(UR_DELSTIMERS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); timers.Delete(searchtimerid); } } if (action == "update") timers.TriggerUpdate(); <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("searchtimers") component=("searchtimers.searchtimer_actions")>
<%cpp> for (SearchTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer) { SearchTimers::iterator nextTimer = timer; ++nextTimer; bool bottom = (nextTimer == timers.end()); <%cpp> }
<$ pageTitle $>
<$ tr("Expression") $>
<$ tr("Channel") $>
<$ tr("Starts between") $>
"><%cpp> if(timer->UseAsSearchTimer()) { " alt=""><%cpp> } ">
<$ timer->Search() $>
">
<$ timer->ChannelText() $>
">
UseTime() ? timer->StartTimeFormatted()+" - "+timer->StopTimeFormatted() ?>
">UseAsSearchTimer() ? "active.png" : "inactive.png") $>" alt="<$ tr("Toggle search timer actions (in)active") $>" <& tooltip.hint text=(tr("Toggle search timer actions (in)active")) &>> ">" alt="<$ tr("Browse search timer results") $>" <& tooltip.hint text=(tr("Browse search timer results")) &>> ">" alt="<$ tr("Edit search timer") $>" <& tooltip.hint text=(tr("Edit search timer")) &>> ">')">" alt="<$ tr("Delete search timer") $>" <& tooltip.hint text=(tr("Delete search timer")) &>>
<%include>page_exit.eh <%def searchtimer_actions> <$ tr("New search timer") $> | <$ tr("Trigger search timer update") $> vdr-plugin-live/pages/channels_widget.ecpp0000644000175000017500000000220412650773437020550 0ustar tobiastobias<%pre> #include #include "exception.h" #include "setup.h" #include "tools.h" using namespace vdrlive; <%args> name = "channel"; selected; onchange; bool channelid = false; <%session scope="global"> bool logged_in(false); <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }> <%cpp> ReadLock channelsLock( Channels ); if ( !channelsLock ) throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); vdr-plugin-live/pages/menu.ecpp0000644000175000017500000000671412650773437016370 0ustar tobiastobias<%pre> #include #include #include #include "livefeatures.h" #include "setup.h" #include "i18n.h" #include "timerconflict.h" using namespace std; using namespace vdrlive; <%args> active; component; <%session scope="global"> bool logged_in(false); TimerConflictNotifier timerNotifier(); <%request scope="page"> std::string set_active; std::string set_component; <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); set_active = active; if (!component.empty()) { set_component = component; }
">
<$ tr("Your attention is required") $>: <$ timerNotifier.Message() $> <$ tr("React") $> <%cpp> if (LiveSetup().GetUseAjax()) { ">| <$ tr("Dismiss") $> <%cpp> }
<%cpp> if (!component.empty()) { <%cpp> } <%def setactive> <%args> current; <%cpp> if (current == set_active) { class="active"<%cpp> } <%def component> <%args> current; <%cpp> if ((current == set_active) && (!set_component.empty())) { <& (set_component) &><%cpp> } vdr-plugin-live/pages/schedule.ecpp0000644000175000017500000001255012650773437017213 0ustar tobiastobias<%pre> #include #include #include #include #include #include "exception.h" #include "livefeatures.h" #include "setup.h" #include "tools.h" #include "epg_events.h" #include "i18n.h" using namespace std; using namespace vdrlive; <%args> int channel = -1; <%session scope="global"> bool logged_in(false); <%request scope="page"> cChannel* Channel; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%cpp> pageTitle = trVDR("Schedule"); cSchedulesLock schedulesLock; cSchedules const* schedules = cSchedules::Schedules( schedulesLock ); ReadLock channelsLock( Channels ); if ( !channelsLock ) throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); // cChannel* Channel; (see %request above) if ( channel > 0 ) { Channel = Channels.GetByNumber( channel ); } else { if (cDevice::CurrentChannel()) { Channel = Channels.GetByNumber(cDevice::CurrentChannel()); } else { Channel = Channels.Get( Channels.GetNextNormal( -1 ) ); } } if ( Channel == 0 ) throw HtmlError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") ); cSchedule const* Schedule = schedules->GetSchedule( Channel ); <& pageelems.doc_type &> VDR Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("schedule") component=("schedule.channel_selection") &>
<%cpp> if ( Schedule == 0 ) { <$ tr("No schedules available for this channel") $>. <%cpp> } else { <%cpp> string current_day = ""; const cEvent* PresentEvent = Schedule->GetPresentEvent(); time_t now = time(NULL) - ::Setup.EPGLinger * 60; // tChannelID channel_id(Channel->GetChannelID()); // int evntNr = 0; for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) { if (Event->EndTime() <= now && Event != PresentEvent) continue; EpgInfoPtr epgEvent = EpgEvents::CreateEpgInfo(Channel, Event); string title(epgEvent->Title()); string short_description(epgEvent->ShortDescr()); string description(epgEvent->LongDescr()); string start(epgEvent->StartTime(tr("%I:%M %p"))); string end(epgEvent->EndTime(tr("%I:%M %p"))); string day(epgEvent->StartTime(tr("%A, %b %d %Y"))); string epgid = EpgEvents::EncodeDomId(Channel->GetChannelID(), Event->EventID()); // string strEventID = lexical_cast(Event->EventID()); bool truncated = false; bool lastEventCurrentDay = false; { cEvent* NextEvent = Schedule->Events()->Next(Event); if (!NextEvent) { lastEventCurrentDay = true; } else { string nday(NextEvent->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), NextEvent->StartTime()) : ""); lastEventCurrentDay = (day != nday); } } if (current_day != day) { if (current_day != "") { <%cpp> } <%cpp> current_day = day; } <%cpp> }
<$ day $>
"><& pageelems.event_timer epgid=(epgid) &> "><%cpp>if (LiveFeatures().Recent() ) { " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>><%cpp> } else { <%cpp> } "><& pageelems.imdb_info_href title=(title) &> ">
<$ start $> - <$ end $>
topaligned rightcol ">
<%cpp> }
<%include>page_exit.eh <%def channel_selection>
<& channels_widget name=("channel") selected=(Channel ? *Channel->GetChannelID().ToString() : "") onchange=("document.forms.channels.submit()") &> <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(Channel->GetChannelID()) image="zap.png" alt="" &> <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &>
vdr-plugin-live/pages/page_exit.eh0000644000175000017500000000045712650773437017034 0ustar tobiastobias<# do not add to Makefile #> <%pre> #include "exception.h" <%cpp> spoint.commit(); } catch ( vdrlive::HtmlError const& ex ) { tnt::QueryParams param = qparam; param.add( "pageTitle", pageTitle ); param.add( "errorMessage", ex.what() ); callComp( "error", request, reply, param ); } vdr-plugin-live/pages/login.ecpp0000644000175000017500000000346212650773437016531 0ustar tobiastobias<%pre> #include "tools.h" #include "setup.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> std::string login; std::string password; std::string action; <%session scope="global"> bool logged_in(false); <{ std::string message; if (action == "login") { if (Users.ValidLogin(login, password)) { logged_in = true; cUsers::logged_in_user = login; } else { message = tr("Wrong username or password"); } } else if (action == "logout") { logged_in = false; cUsers::logged_in_user = ""; } LiveSetup().CheckLocalNet(request.getPeerIp()); if (logged_in || !LiveSetup().UseAuth()) return reply.redirect(LiveSetup().GetStartScreenLink()); }> <& pageelems.doc_type &> VDR-Live - <$ tr("Login") $> <& pageelems.stylesheets &> <& pageelems.ajax_js &>
<$ tr("VDR Live Login") $>
" alt="VDR Live">
<$ message $>
vdr-plugin-live/pages/vlc.ecpp0000644000175000017500000000741112650773437016203 0ustar tobiastobias<%pre> #include #include #include #include "setup.h" #include "tools.h" #include "users.h" #include "tntfeatures.h" using namespace std; using namespace vdrlive; <%args> tChannelID channel; string async; string recid; <%session scope="global"> bool logged_in(false); <%request scope="page"> cChannel* Channel; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); if (!cUser::CurrentUserHasRightTo(UR_STARTREPLAY)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); bool asyncReq = !async.empty() && (lexical_cast(async) != 0); // the availabilty of Channel signals that we will do live tv streaming. Channel = 0; if (recid.empty()) { pageTitle = tr("VLC: live video stream"); ReadLock channelsLock(Channels); if (!channelsLock) { throw HtmlError(tr("Couldn't aquire access to channels, please try again later.")); } Channel = Channels.GetByChannelID(channel); if (Channel == 0) { throw HtmlError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") ); } } else { pageTitle = tr("VLC: play recording"); } <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <%cpp> if (!asyncReq) { <& pageelems.ajax_js &> <%cpp> } else { <%cpp> } <%cpp> if (!asyncReq) { <& pageelems.logo &> <& menu active="vlc" &>
<%cpp> } <%cpp> string server = request.getHost(); server = server.substr(0, server.rfind(':')); string videourl; if (Channel != 0) { int streamdevPort = LiveSetup().GetStreamdevPort(); videourl = string("http://") + server + ":" + lexical_cast(streamdevPort) + "/" + LiveSetup().GetStreamdevType() + "/" + *Channel->GetChannelID().ToString(); } else { videourl = string("http://") + server + ":" + lexical_cast(LiveSetup().GetServerPort()) + "/recstream.html?recid=" + recid; } <& vlc.controls videourl=(videourl) asyncReq=(asyncReq) &> <%cpp> if (!asyncReq) {
<%cpp> } <%include>page_exit.eh <%def controls> <%args> string videourl; bool asyncReq;
<%cpp> if (asyncReq) { <%cpp> }

<$ tr("VLC media URL") $>: <$ videourl $>

vdr-plugin-live/pages/rwd_recording.ecpp0000644000175000017500000000115312650773437020244 0ustar tobiastobias<%pre> #include #include #include "exception.h" #include "setup.h" #include "tasks.h" #include "tools.h" using namespace std; using namespace vdrlive; <%args> string param; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType( "application/xml" ); BackwardRecordingTask task( param ); LiveTaskManager().Execute( task ); <& xmlresponse.ajax name=("rwd_recording") pname=("recording") value=(param) result=(task.Result()) error=(task.Error()) &> vdr-plugin-live/pages/content.ecpp0000644000175000017500000000310012650773437017060 0ustar tobiastobias<%pre> #include #include #include #include "filecache.h" #include "setup.h" using namespace std; using namespace vdrlive; <%session scope="global"> bool logged_in(false); <%cpp> //if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); string mime("image/png"); if (request.getArgsCount() > 0) { #if TNT_MAPURL_NAMED_ARGS mime = request.getArg("mime-type"); #else mime = request.getArg(0); #endif // dsyslog("vdrlive::content found mime arg (%s)", mime.c_str()); } reply.setContentType(mime); // dsyslog("vdrlive::content::mimetype(%s)", mime.c_str()); string const path(request.getPathInfo()); // dsyslog("vdrlive::content: path = %s", path.c_str()); // security checking of path. In order to not allow exploits the // path must be absolute and not contain any upward references (e.g '../') if (path.empty()) { return HTTP_BAD_REQUEST; } if ('/' != path[0]) { return HTTP_BAD_REQUEST; } if (string::npos != path.find("../", 1)) { return HTTP_BAD_REQUEST; } FileCache::ptr_type f = LiveFileCache().get(path); if (f.get() == 0) { // dsyslog("vdrlive::content: DECLINED"); return DECLINED; } string ctime = tnt::HttpMessage::htdate(f->ctime()); string browserTime = request.getHeader(tnt::httpheader::ifModifiedSince); if (browserTime == ctime) { // dsyslog("vdrlive::content: HTTP_NOT_MODIFIED"); return HTTP_NOT_MODIFIED; } // dsyslog("vdrlive::content: send %d bytes of data", f->size()); reply.setHeader(tnt::httpheader::lastModified, ctime); reply.out().write(f->data(), f->size()); vdr-plugin-live/pages/users.ecpp0000644000175000017500000000421512650773437016557 0ustar tobiastobias<%pre> #include #include #include "users.h" #include "setup.h" using namespace vdrlive; using namespace std; <%args> // input parameters string userid; string action; <%session scope="global"> bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%cpp> pageTitle = tr("Users"); if ( !userid.empty() ) { if (action == "delete") { Users.Del(Users.GetByUserId( userid )); Users.Save(); } } <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("users") component=("users.user_actions")>
<%cpp> cUser* user = Users.First(); while (user) { bool bottom = (Users.Next(user) == NULL); if (user) { <%cpp> } user = Users.Next(user); }
<$ pageTitle $>
<$ tr("Name") $>
">
<$ user->Name() $>
">" alt="" <& tooltip.hint text=(tr("Edit user")) &>> ">" alt="" <& tooltip.hint text=(tr("Delete user")) &>>
<%include>page_exit.eh <%def user_actions> <$ tr("New user") $> vdr-plugin-live/pages/pause_recording.ecpp0000644000175000017500000000115212650773437020564 0ustar tobiastobias<%pre> #include #include #include "exception.h" #include "setup.h" #include "tasks.h" #include "tools.h" using namespace std; using namespace vdrlive; <%args> string param; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType( "application/xml" ); PauseRecordingTask task( param ); LiveTaskManager().Execute( task ); <& xmlresponse.ajax name=("pause_recording") pname=("recording") value=(param) result=(task.Result()) error=(task.Error()) &> vdr-plugin-live/pages/multischedule.ecpp0000644000175000017500000004606412650773437020275 0ustar tobiastobias<%pre> #include #include #include #include #include #include #include "exception.h" #include "livefeatures.h" #include "setup.h" #include "tools.h" #include "timers.h" #include "epg_events.h" #include "i18n.h" using namespace std; using namespace vdrlive; struct SchedEntry { string title; string short_description; string description; string description_trunc; string start; string end; string day; string epgid; bool truncated; bool has_timer; int start_row; int row_count; }; std::string channel_groups_setting; std::vector channel_groups_names; std::vector< std::vector > channel_groups_numbers; std::vector times_names; std::vector times_start; <%args> int channel = -1; unsigned int time_para = 0; <%session scope="global"> bool logged_in(false); <%request scope="page"> unsigned int channel_group=0; unsigned int time_selected=0; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); pageTitle = tr("MultiSchedule"); ReadLock channelsLock( Channels ); if ( !channelsLock ) throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); #define MAX_CHANNELS 10 #define MAX_DAYS 3 #define MAX_HOURS 8 #define MINUTES_PER_ROW 5 #define CHARACTERS_PER_ROW 30 if ( ( channel_groups_setting.compare(LiveSetup().GetChannelGroups()) != 0 ) || ( channel_groups_numbers.size() == 0 ) ) { // build the groups of channels to display std::string channelGroups=LiveSetup().GetChannelGroups(); if ( channelGroups.empty() ) { // setup default channel groups int lastChannel = LiveSetup().GetLastChannel(); if ( lastChannel == 0 ) lastChannel = Channels.MaxNumber(); std::stringstream groups; int i = 0; for (cChannel *channel = Channels.First(); channel && (channel->Number() <= lastChannel); channel = Channels.Next(channel)) { if (channel->GroupSep()) continue; groups << channel->Number(); if ( (++i % 5) == 0 ) groups << ";"; else groups << ","; } channelGroups = groups.str(); LiveSetup().SetChannelGroups( channelGroups ); } channel_groups_names.clear(); channel_groups_numbers.clear(); channel_groups_setting = channelGroups; size_t groupSep; std::string thisGroup = ""; while ( ! channelGroups.empty() ) { groupSep = channelGroups.find(';'); thisGroup = channelGroups.substr(0, groupSep ); if ( groupSep != channelGroups.npos ) channelGroups.erase(0, groupSep+1 ); else channelGroups=""; int cur_group_count=0; channel_groups_names.push_back( std::string() ); channel_groups_numbers.push_back( std::vector() ); while ( !thisGroup.empty() ) { std::string thisChannel; try { if ( cur_group_count != 0 ) channel_groups_names.back() += std::string( " - " ); size_t channelSep = thisGroup.find(','); thisChannel = thisGroup.substr(0, channelSep ); if ( channelSep != thisGroup.npos ) thisGroup.erase( 0, channelSep+1 ); else thisGroup = ""; int channel_no = lexical_cast< int > (thisChannel); cChannel* Channel = Channels.GetByNumber( channel_no ); if ( !Channel ) { esyslog("Live: could not find channel no '%s'.", thisChannel.c_str() ); continue; } channel_groups_names.back() += std::string( Channel->Name() ); channel_groups_numbers.back().push_back( Channel->Number() ); cur_group_count++; if ( cur_group_count>=MAX_CHANNELS ) { // start new group if group gets too large cur_group_count=0; channel_groups_names.push_back( std::string() ); channel_groups_numbers.push_back( std::vector() ); } } catch ( const bad_lexical_cast & ) { esyslog("Live: could not convert '%s' into a channel number", thisChannel.c_str()); continue; } } } } if ( channel < 0 ) { if (cDevice::CurrentChannel()) { // find group corresponding to current channel int curGroup =0; int curChannel = cDevice::CurrentChannel(); for ( std::vector< std::vector >::iterator grIt = channel_groups_numbers.begin(); grIt != channel_groups_numbers.end() && channel < 0; ++grIt, ++curGroup ) { for ( std::vector::iterator chIt = (*grIt).begin(); chIt != (*grIt).end() && channel < 0; ++ chIt ) { if ( *chIt == curChannel ) channel_group = channel = curGroup; } } // if nothing is found, fall back to group 0 if ( channel < 0 ) channel = 0; } else { channel_group = channel; } } if ( channel >= (int)channel_groups_numbers.size() ) channel = 0; channel_group = channel; { // build time list times_names.clear(); times_start.clear(); // calculate time of midnight (localtime) and convert back to GMT time_t now = (time(NULL)/3600)*3600; time_t now_local = time(NULL); struct tm tm_r; if ( localtime_r( &now_local, &tm_r ) == 0 ) { ostringstream builder; builder << "cannot represent timestamp " << now_local << " as local time"; throw runtime_error( builder.str() ); } tm_r.tm_hour=0; tm_r.tm_min=0; tm_r.tm_sec=0; time_t midnight = mktime( &tm_r ); // add four 8h steps per day to the time list for (int i=0; i<4*MAX_DAYS ; i++ ) { times_start.push_back( midnight + MAX_HOURS*3600*i ); } vector< string > parts = StringSplit( LiveSetup().GetTimes(), ';' ); vector< time_t > offsets; vector< string >::const_iterator part = parts.begin(); for ( ; part != parts.end(); ++part ) { try { unsigned int sep = (*part).find(':'); std::string hour = (*part).substr(0, sep ); if ( sep == (*part).npos ) { esyslog("Live: Error parsing time '%s'", (*part).c_str() ); continue; } std::string min = (*part).substr(sep+1, (*part).npos ); offsets.push_back( lexical_cast( hour )*60*60 + lexical_cast( min ) *60 ); } catch ( const bad_lexical_cast & ) { esyslog("Live: Error parsing time '%s'", part->c_str() ); }; }; // add the time of the favourites to the time list for (int i=0; i< MAX_DAYS ; i++ ) { vector< time_t >::const_iterator offset = offsets.begin(); for ( ; offset != offsets.end(); ++offset ) { times_start.push_back( midnight + 24*3600*i + *offset ); } } // add now times_start.push_back( now ); // sort the times std::sort( times_start.begin(), times_start.end() ); // delete every time which has already passed while ( *times_start.begin()< now ) times_start.erase(times_start.begin() ); // build the corresponding names for ( vector< time_t >::const_iterator start = times_start.begin(); start != times_start.end(); ++start ) { times_names.push_back(FormatDateTime( tr("%A, %x"), *start) +std::string(" ")+ FormatDateTime( tr("%I:%M %p"), *start) ); } // the first time is now times_names[0]=tr("Now"); if ( time_para >= times_names.size() ) time_para = times_names.size()-1; time_selected=time_para; } <& pageelems.doc_type &> VDR Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("multischedule") component=("multischedule.channel_selection") &>
<%cpp> cSchedulesLock schedulesLock; cSchedules const* schedules = cSchedules::Schedules( schedulesLock ); time_t now = time(NULL); if ( time_para >= times_start.size() ) time_para = times_start.size()-1; time_t sched_start = (times_start[ time_para ]/300)*300; time_t max_hours; try { max_hours = lexical_cast( LiveSetup().GetScheduleDuration() ); } catch ( const bad_lexical_cast & ) { esyslog("Live: could not convert '%s' into a schedule duration", LiveSetup().GetScheduleDuration().c_str()); max_hours = 8; }; if (max_hours > 48) max_hours = 48; time_t sched_end = sched_start + 60 * 60 * max_hours; int sched_end_row = ( sched_end - sched_start ) / 60 / MINUTES_PER_ROW; std::list table[MAX_CHANNELS]; std::vector channel_names(channel_groups_numbers[ channel ].size() ); std::vector channel_IDs(channel_groups_numbers[ channel ].size() ); if ( channel >= (int)channel_groups_numbers.size() ) channel = channel_groups_numbers.size()-1; //for ( int chan = 0; chanGroupSep() || Channel->Name() == '\0' ) continue; channel_names[ j ] = Channel->Name(); channel_IDs[ j ] = Channel->GetChannelID(); cSchedule const* Schedule = schedules->GetSchedule( Channel ); if ( ! Schedule ) continue; for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event) ) { if (Event->EndTime() <= sched_start ) continue; if (Event->StartTime() >= sched_end ) continue; EpgInfoPtr epgEvent = EpgEvents::CreateEpgInfo(Channel, Event); if ( prev_row < 0 && Event->StartTime() > sched_start + MINUTES_PER_ROW ) { // insert dummy event at start table[ j ].push_back( SchedEntry() ); SchedEntry &en=table[ j ].back(); int event_start_row = (Event->StartTime() - sched_start) / 60 / MINUTES_PER_ROW; en.start_row = 0; en.row_count = event_start_row; // no title and no start time = dummy event en.title = ""; en.start = ""; prev_row = en.start_row + en.row_count; } table[ j ].push_back( SchedEntry() ); SchedEntry &en=table[j].back(); en.title = epgEvent->Title(); en.short_description = epgEvent->ShortDescr(); en.description = epgEvent->LongDescr(); en.start = epgEvent->StartTime(tr("%I:%M %p")); en.end = epgEvent->EndTime(tr("%I:%M %p")); en.day = epgEvent->StartTime(tr("%A, %b %d %Y")); en.epgid = EpgEvents::EncodeDomId(Channel->GetChannelID(), Event->EventID()); en.has_timer = LiveTimerManager().GetTimer(Event->EventID(), Channel->GetChannelID() ) != 0; en.start_row = prev_row > 0 ? prev_row : 0; int end_time = Schedule->Events()->Next(Event) ? Schedule->Events()->Next(Event)->StartTime() : Event->EndTime(); if (end_time > sched_end) end_time = sched_end; int next_event_start_row = (end_time - sched_start) / 60 / MINUTES_PER_ROW; en.row_count = next_event_start_row - en.start_row; if ( en.row_count < 1 ) en.row_count = 1; prev_row = en.start_row + en.row_count; // truncate description if too long en.truncated=false; en.description_trunc=StringWordTruncate( en.description, CHARACTERS_PER_ROW*(en.row_count-2), en.truncated ); }; if ( table[ j ].begin() == table[ j ].end() ) { // no entries... create a single dummy entry table[ j ].push_back( SchedEntry() ); SchedEntry &en=table[ j ].back(); en.start_row = 0; en.row_count = sched_end_row; // no title and no start time = dummy event en.title = ""; en.start = ""; } } <%cpp> <%cpp> for ( unsigned int channel = 0; channel< channel_names.size() ; channel++) { <%cpp> } <%cpp> bool odd=true; std::list::iterator cur_event[ MAX_CHANNELS ]; for (int i=0;i now ) { row_class +=" current_row "; } row_class += odd ? " odd " : " even "; <%cpp> for ( unsigned int channel = 0; channel< channel_names.size() ; channel++) { // output spacer column <%cpp> if ( cur_event[channel] == table[channel].end() || cur_event[channel]->start_row != row ) // no new event in this channel, skip it continue; SchedEntry &en=*cur_event[channel]; if (en.title.empty() && en.start.empty() ) { // empty dummy event <%cpp> ++cur_event[channel]; continue; } // output an event cell <%cpp> // move to next event for this channel ++cur_event[channel]; } <%cpp> } <%cpp> for ( unsigned int channel = 0; channel <= channel_names.size() ; channel++) { <%cpp> }
<$ tr("Time") $>
 
<$ channel_names[channel] $> <# reply.sout() automatically escapes special characters to html entities #> <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channel_IDs[channel]) image="zap.png" alt="" &> <& pageelems.vlc_stream_channel channelId=(channel_IDs[channel]) &>
 
<%cpp> if ( minutes < MINUTES_PER_ROW ) { <$ FormatDateTime( tr("%I:%M %p"), sched_start + row * 60 * MINUTES_PER_ROW ) $> <%cpp> } else {   <%cpp> }   " rowspan="<$ en.row_count $>">
<& pageelems.event_timer epgid=(en.epgid) &> <%cpp> if (LiveFeatures().Recent() ) { " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> <%cpp> } else { <%cpp> } <& pageelems.imdb_info_href title=(en.title) &>
<$ en.start $>
<%cpp> if ( en.row_count>2 && !en.short_description.empty() ) {
<$ en.short_description.empty() ? " " : en.short_description $>
<%cpp> } if ( en.row_count>3 && ! en.description_trunc.empty() ) {
<$en.description_trunc$>... <%cpp> if ( en.truncated ) { <& tooltip.display domId=en.epgid &>> <$ tr("more") $> <%cpp> }
<%cpp> }
   
<%include>page_exit.eh <%def channel_selection>
% // <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(Channel->GetChannelID()) image="zap.png" alt="" &> % // <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &>
vdr-plugin-live/pages/xmlresponse.ecpp0000644000175000017500000000302612650773437017774 0ustar tobiastobias<%pre> #include #include "i18n.h" using namespace std; using namespace vdrlive; string const XMLHEADER = ""; <# ------------------------------------------------------------------------- #> <%def ajax> <%args> string name; string pname; string value; bool result; string error; <$$ XMLHEADER $> <$ value $> <$ result $> <$ error $> <# ------------------------------------------------------------------------- #> <%def ibox> <%args> int update; string type; string currentTime; string caption; string title; string duration; int elapsed; string prev_chan; string next_chan; string infoMsg; string infoUrl; <$$ XMLHEADER $> <$ update $> 1 <$ update $> <$ type $>
<$ caption $>
<%cpp> if (recording && recording->Info()->ShortText()) { <%cpp> } if (recording && recording->Info()->Description()) { <%cpp> } if (recording && recording->Info()->Aux()) { <%cpp> }
<$ tr("Edit recording") $>
<$ tr("Name") $>:
<$ tr("Directory") $>:
<$ tr("Delete resume information") $>:
<$ tr("Delete marks information") $>:
<$ tr("Copy only") $>:
<$ tr("Short description") $>:
<$ recording->Info()->ShortText() $>
<$ tr("Description") $>:
<$ recording->Info()->Description() $>
<$ tr("Auxiliary info") $>:
<$ recording->Info()->Aux() $>
<$ message $>
<%include>page_exit.eh vdr-plugin-live/pages/switch_channel.ecpp0000644000175000017500000000200312650773437020400 0ustar tobiastobias<%pre> #include #include "exception.h" #include "tasks.h" #include "tools.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> tChannelID param; string async; <%cpp> bool ajaxReq = !async.empty() && (lexical_cast(async) != 0); string referrer; if (!cUser::CurrentUserHasRightTo(UR_SWITCHCHNL)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); if (ajaxReq) { reply.setContentType( "application/xml" ); } else { referrer = request.getHeader("Referer:"); } SwitchChannelTask task( param ); LiveTaskManager().Execute( task ); if (!ajaxReq) { if (!referrer.empty()) { return reply.redirect(referrer); } Normale Seite:
channel: <$ param $>
result: <$ (task.Result()) $>
error: <$ (task.Error()) $>
Seitenende! <%cpp> } else { <& xmlresponse.ajax name=("switch_channel") pname=("channel") value=(param) result=(task.Result()) error=(task.Error()) &> <%cpp> } vdr-plugin-live/pages/error.ecpp0000644000175000017500000000152012650773437016543 0ustar tobiastobias<%pre> #include #include "setup.h" using namespace vdrlive; <%args> pageTitle; errorTitle = tr("Page error"); errorMessage; <%session scope="global"> bool logged_in(false); <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }> <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.logo &> <& menu &>
<& error.error_widget errorTitle=(errorTitle) errorMessage=(errorMessage) &>
<%def error_widget> <%args> errorTitle; errorMessage;
<$ errorTitle $>
<$ errorMessage $>
vdr-plugin-live/pages/tooltip.ecpp0000644000175000017500000000054012650773437017105 0ustar tobiastobias<%pre> #include "setup.h" using namespace vdrlive; <%def hint> <%args> text; title="<$ text $>" <%def display> <%args> domId; href="epginfo.html?epgid=<$ domId $>" <%def help> <%args> text; " alt="" <& hint text=(text) &>> vdr-plugin-live/pages/stop_recording.ecpp0000644000175000017500000000115012650773437020432 0ustar tobiastobias<%pre> #include #include #include "exception.h" #include "setup.h" #include "tasks.h" #include "tools.h" using namespace std; using namespace vdrlive; <%args> string param; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType( "application/xml" ); StopRecordingTask task( param ); LiveTaskManager().Execute( task ); <& xmlresponse.ajax name=("stop_recording") pname=("recording") value=(param) result=(task.Result()) error=(task.Error()) &> vdr-plugin-live/pages/timerconflicts.ecpp0000644000175000017500000001436612650773437020453 0ustar tobiastobias<%pre> #include #include #include "timerconflict.h" #include "tools.h" #include "setup.h" #include "epg_events.h" #include "timers.h" #include "i18n.h" using namespace vdrlive; using namespace std; static const size_t maximumDescriptionLength = 300; <%args> // input parameters <%session scope="global"> bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%cpp> pageTitle = tr("Timer conflicts"); TimerConflicts timerConflicts; cMutexLock timersLock( &LiveTimerManager() ); SortedTimers& timers = LiveTimerManager().GetTimers(); <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("timersconflicts")>
% if (timerConflicts.size() == 0) { <$ tr("No timer conflicts") $> % } else { <%cpp> for (TimerConflicts::iterator conflict = timerConflicts.begin(); conflict != timerConflicts.end(); ++conflict) { const std::list< TimerInConflict >& conflTimers = conflict->ConflictingTimers(); for (std::list< TimerInConflict >::const_iterator confltimer = conflTimers.begin(); confltimer != conflTimers.end(); ++confltimer) { <%cpp> for (std::list::const_iterator timerIndex = confltimer->concurrentTimerIndices.begin(); timerIndex != confltimer->concurrentTimerIndices.end(); ++timerIndex) { cTimer* timer = Timers.Get(*timerIndex-1); if (!timer) continue; std::list< int >::const_iterator nexttimerIndex = timerIndex; ++nexttimerIndex; bool bottom = (nexttimerIndex == confltimer->concurrentTimerIndices.end()); std::string timerStateImg = "transparent.png"; std::string timerStateHint; if (timer->Index() == confltimer->timerIndex-1) { timerStateImg = "timerconflict.gif"; timerStateHint = tr("Timer has a conflict."); } else if (timer->Flags() & tfActive) { timerStateImg = "arrow.png"; timerStateHint = tr("Timer is active."); } EpgInfoPtr epgEvent; string longDescription; string title; if (!timer->Event()) timer->SetEventFromSchedule(); if (timer->Event()) { epgEvent = EpgEvents::CreateEpgInfo(timer->Channel(), timer->Event()); longDescription = StringEscapeAndBreak(SortedTimers::GetTimerInfo(*timer)) + "
" + StringEscapeAndBreak(StringWordTruncate(epgEvent->LongDescr(), maximumDescriptionLength)) + "

" + tr("Click to view details."); title = epgEvent->Title(); }
% } <%cpp> } }
<$ FormatDateTime(tr("%A, %x"), conflict->ConflictTime()) + " " + FormatDateTime(tr("%I:%M %p"), conflict->ConflictTime()) + " - " + lexical_cast(confltimer->percentage) + "%" $>
<$ trVDR("Channel") $>
<$ trVDR("Start") $>
<$ trVDR("Stop") $>
<$ trVDR("Priority") $>
<$ trVDR("File") $>
">" alt="" <%cpp> if (!timerStateHint.empty()) { <& tooltip.hint text=(timerStateHint) &><%cpp> } > "> ">
<$ FormatDateTime(tr("%I:%M %p"), timer->StartTime()) $>
">
<$ FormatDateTime(tr("%I:%M %p"), timer->StopTime()) $>
">
<$ timer->Priority() $>
"> ">" alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> ">Flags() & tfActive) ? "active.png" : "inactive.png") $>" alt="" <& tooltip.hint text=(tr("Toggle timer active/inactive")) &>> "><& pageelems.edit_timer timerId=(timers.GetTimerId(*timer)) &> ">" alt="" <& tooltip.hint text=(tr("Delete timer")) &>>
% }
<%include>page_exit.eh vdr-plugin-live/pages/epginfo.ecpp0000644000175000017500000000725412650773437017053 0ustar tobiastobias<%pre> #include #include #include "stdext.h" #include "exception.h" #include "setup.h" #include "tools.h" #include "epg_events.h" #include "recman.h" namespace vdrlive { class SchedulesLock { public: SchedulesLock() : m_schedulesLock() {} operator cSchedulesLock& () { return m_schedulesLock; } private: SchedulesLock(SchedulesLock const &schedulesLock) {} cSchedulesLock m_schedulesLock; }; typedef std::tr1::shared_ptr SchedulesLockPtr; } using namespace vdrlive; using namespace std; <%args> string epgid; string async; <%session scope="global"> bool logged_in(false); <%request scope="page"> EpgInfoPtr epgEvent; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); pageTitle = tr("Electronic program guide information"); bool ajaxReq = !async.empty() && (lexical_cast(async) != 0); bool aboutBox = false; // One of these get initialized when needed. When freed by getting // out of scope they will release (if initialized) important // Semaphores/Locks. SchedulesLockPtr schedulesLockPtr; RecordingsManagerPtr recordings; if (!epgid.empty()) { const string recording("recording_"); const string event("event_"); const string aboutbox("aboutBox"); // check for recording: if (epgid.compare(0, recording.length(), recording) == 0) { recordings = LiveRecordingsManager(); const cRecording* recording = recordings->GetByMd5Hash(epgid); if (recording == 0) { throw HtmlError(tr("Couldn't find recording or no recordings available")); } epgEvent = EpgEvents::CreateEpgInfo(epgid, recording); } // check for event: else if (epgid.compare(0, event.length(), event) == 0) { schedulesLockPtr = SchedulesLockPtr(new SchedulesLock); if (!schedulesLockPtr) { throw HtmlError(tr("Error aquiring schedules lock")); } const cSchedules* schedules = cSchedules::Schedules(*schedulesLockPtr); if (!schedules) { throw HtmlError(tr("Error aquiring schedules")); } epgEvent = EpgEvents::CreateEpgInfo(epgid, schedules); } // check for aboutbox: else if (epgid.compare(0, aboutbox.length(), aboutbox) == 0) { aboutBox = true; } } <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <%cpp> if (!ajaxReq) { <& pageelems.stylesheets &> <& pageelems.ajax_js &> <%cpp> } <%cpp> if (!ajaxReq) { <& pageelems.logo &> <& menu &> <%cpp> }
<%cpp> if (epgEvent) { string start(epgEvent->StartTime("%a,") + string(" ") + epgEvent->StartTime(tr("%b %d %y")) + string(" ") + epgEvent->StartTime(tr("%I:%M %p"))); string tools_component; if (recordings) { tools_component = epgEvent->Archived().empty() ? "recordings.rec_tools" : "recordings.archived_disc" ; } if (schedulesLockPtr) { tools_component = "epginfo.epgTools"; } <& pageelems.epg_tt_box boxId=(epgEvent->Id()) caption=(epgEvent->Caption()) tools_comp=(tools_component) time=(start) title=(epgEvent->Title()) short_descr=(epgEvent->ShortDescr()) long_descr=(epgEvent->LongDescr()) archived=(epgEvent->Archived()) elapsed=(epgEvent->Elapsed()) &> <%cpp> } if (aboutBox) { <& pageelems.about_tt_box &> <%cpp> }
<%include>page_exit.eh <# ---------------------------------------------------------------------- #> <%def epgTools> <%args> string id; string title; int detail; <& pageelems.epg_tool_box detail=(detail) epgid=(id) title=(title) startTime=(epgEvent->GetStartTime()) endTime=(epgEvent->GetEndTime()) &> vdr-plugin-live/pages/pageelems.ecpp0000644000175000017500000004016712650773437017366 0ustar tobiastobias<%pre> #include #include #include #include "exception.h" #include "livefeatures.h" #include "tntfeatures.h" #include "i18n.h" #include "setup.h" #include "timers.h" #include "tools.h" #include "epg_events.h" #include "gen_version_suffix.h" using namespace std; using namespace vdrlive; <%session scope="global"> int update_status(1); <# ---------------------------------------------------------------------- #> <%def doc_type> <# ---------------------------------------------------------------------- #> <%def stylesheets> "/> <# ---------------------------------------------------------------------- #> <%def logo> <%cpp> if (LiveSetup().GetShowLogo() || (LiveSetup().GetUseAjax() && LiveSetup().GetShowInfoBox())) {
<%cpp> } <# ---------------------------------------------------------------------- #> <%def hide_element> <%args> int hide = 1; <%cpp> if (hide) { style="visibility: hidden"<%cpp> } <# ---------------------------------------------------------------------- #> <%def progressbar> <%args> int progress = 0; string id; int duration = -1; // invalid duration as default <%cpp> string cls("__progress"); if ((duration >= 0) && ((progress < 0) || (duration == 0))) cls +="_invisible";
if (!id.empty()) { id="<$ id $>"<%cpp> } style="width: <$ progress $>px">
<# ---------------------------------------------------------------------- #> <%def ajax_action_href> <%args> string action; string tip; string param; string image; string alt; string id; <%cpp> { if (!id.empty()) { id="<$ id $>" <%cpp> } <& hide_element hide=(id.empty()? 0 : 1) &> href="vdr_request/<$ action $>?param=<$ param $>" <%cpp>if (!tip.empty()) { <& tooltip.hint text=(tip) &> <%cpp> } >" alt="<$ alt $>"> <%cpp> } <# ---------------------------------------------------------------------- #> <%def imdb_info_href> <%args> string title; <%cpp> if (LiveSetup().GetShowIMDb()) { " alt="" <& tooltip.hint text=(tr("Find more at the Internet Movie Database.")) &>> <%cpp> } <# ---------------------------------------------------------------------- #> <%def vlc_stream_channel> <%args> tChannelID channelId; <%cpp> if (LiveSetup().GetUseStreamdev() && LiveFeatures().Loaded()) { " alt="" <& tooltip.hint text=(tr("Stream this channel into browser.")) &>><%cpp> } <# ---------------------------------------------------------------------- #> <%def vlc_stream_recording> <%args> string recid; string linkText; <%cpp> #if TNT_WATCHDOG_SILENCE { " alt="" <& tooltip.hint text=(tr("Stream this recording into browser.")) &>> <$ linkText $> <%cpp> } #endif <# ---------------------------------------------------------------------- #> <%def event_timer> <%args> string epgid; <%cpp> tChannelID channelid; tEventID eventid; EpgEvents::DecodeDomId(epgid, channelid, eventid); const cTimer* timer = LiveTimerManager().GetTimer(eventid, channelid); if (timer) { <& pageelems.edit_timer timerId=(LiveTimerManager().GetTimers().GetTimerId(*timer)) imgName=("record_timer.png") &> <%cpp> } else { " alt="" <& tooltip.hint text=(tr("Record this")) &> /> <%cpp> } <# ---------------------------------------------------------------------- #> <%def edit_timer> <%args> string timerId; string imgName = "edit.png"; " alt="" <& tooltip.hint text=(tr("Edit timer")) &> /> <# ---------------------------------------------------------------------- #> <%def ajax_js> <%cpp> if (LiveSetup().GetUseAjax()) { <%cpp> if (LiveSetup().GetShowInfoBox()) { <%cpp> } <%cpp> } <# ---------------------------------------------------------------------- #> <%def infobox>
<$ tr("retrieving status ...") $>
--:--
--:--
<& ajax_action_href action=("switch_channel") id=("infobox_prevchan") image=("one_downarrow.png") tip=(tr("previous channel")) &> <& ajax_action_href action=("switch_channel") id=("infobox_nextchan") image=("one_uparrow.png") tip=(tr("next channel")) &>
<& progressbar id=("infobox_elapsed") &>
<$ tr("No server response!") $> <$ tr("Failed to update infobox!") $>
<# ---------------------------------------------------------------------- #> <%def epg_tool_box> <%args> int detail; string epgid; string title; time_t startTime; time_t endTime; int lastCurrentChanel = int(); <%cpp> int duration = EpgEvents::Duration(startTime, endTime); int elapsed = EpgEvents::ElapsedTime(startTime, endTime); tEventID eventId = tEventID(); tChannelID channelId = tChannelID(); EpgEvents::DecodeDomId(epgid, channelId, eventId); if (detail) { // output for vertical toolbox <& pageelems.event_timer epgid=(epgid) &> <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channelId) image="zap.png" alt="" &> <%cpp> if (LiveFeatures().Recent() && eventId != 0) { " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> <%cpp> } if ((duration == 0) || (elapsed >= 0)) { <& pageelems.vlc_stream_channel channelId=(channelId) &> <%cpp> } if (eventId != 0) { <& pageelems.imdb_info_href title=(title) &> <%cpp> } } else { // table output
"><& pageelems.event_timer epgid=(epgid) &> "><& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channelId) image="zap.png" alt="" &> "><%cpp>if (LiveFeatures().Recent() && eventId != 0) { " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>><%cpp> } else { <%cpp> } "><%cpp>if ((duration == 0) || (elapsed > 0)) { <& pageelems.vlc_stream_channel channelId=(channelId) &><%cpp> } else { <%cpp> } "> <%cpp> if (eventId != 0) { <& pageelems.imdb_info_href title=(title) &> <%cpp> }
<$ tr("Search settings") $>
<$ tr("Search term") $>:
<$ tr("Extended search") $>:
onclick="changeduseextendedsearch(this)" id="useextendedsearch"/>
<%include>page_exit.eh vdr-plugin-live/pages/ibox.ecpp0000644000175000017500000001112612650773437016356 0ustar tobiastobias<%pre> #include #include #include #include #include #include #include "exception.h" #include "setup.h" #include "tools.h" #include "epg_events.h" #include "recman.h" #include "timerconflict.h" using namespace vdrlive; using namespace std; <%args> int update; <%session scope="global"> bool logged_in(false); int update_status(1); TimerConflictNotifier timerNotifier(); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); string EMPTY_STR; tChannelID prev_chan; tChannelID next_chan; reply.setContentType( "application/xml" ); if (update_status != update) { update_status = update; } string infoMsg; string infoUrl; if (timerNotifier.ShouldNotify()) { infoMsg = timerNotifier.Message(); infoUrl = "timerconflicts.html"; } const char* NowReplaying = cReplayControl::NowReplaying(); EpgInfoPtr epgEvent; if (NowReplaying) { RecordingsManagerPtr recManager = LiveRecordingsManager(); cRecording *recording = Recordings.GetByName(NowReplaying); if (recording) { epgEvent = EpgEvents::CreateEpgInfo(recManager->Md5Hash(recording), recording, tr("playing recording")); } } else { string CHANNEL_STR("channel"); ReadLock channelsLock( Channels ); if (cDevice::CurrentChannel()) { const int SKIP_GAP = 1; cChannel* Channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel* tmp = Channels.GetByNumber(Channels.GetPrevNormal(cDevice::CurrentChannel()), -SKIP_GAP); if (tmp) prev_chan = tmp->GetChannelID(); tmp = Channels.GetByNumber(Channels.GetNextNormal(cDevice::CurrentChannel()), SKIP_GAP); if (tmp) next_chan = tmp->GetChannelID(); const string chanName(Channel->Name()); cSchedulesLock schedulesLock; const cSchedules* Schedules = cSchedules::Schedules(schedulesLock); const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Event = Schedule->GetPresentEvent(); if (Event) { epgEvent = EpgEvents::CreateEpgInfo(Channel, Event, CHANNEL_STR.c_str()); } else { const string noInfo(tr("no epg info for current event!")); epgEvent = EpgEvents::CreateEpgInfo(CHANNEL_STR, chanName, noInfo); } } else { const string noInfo(tr("no epg info for current channel!")); epgEvent = EpgEvents::CreateEpgInfo(CHANNEL_STR, Channel->Name(), noInfo); } } else { const string chanName(tr("no current channel!")); epgEvent = EpgEvents::CreateEpgInfo(CHANNEL_STR, chanName, chanName); } } if (!epgEvent) { const string ERROR_STR("error"); const string noInfo(tr("error retrieving status info!")); const string chanName(tr("no current channel!")); epgEvent = EpgEvents::CreateEpgInfo(ERROR_STR, chanName, noInfo); } else { if (prev_chan.Valid() && next_chan.Valid()) { <& xmlresponse.ibox update=(update_status) type=(epgEvent->Id()) caption=(epgEvent->Caption()) currentTime=(epgEvent->CurrentTime(tr("%I:%M:%S %p"))) duration=(epgEvent->StartTime(tr("%I:%M %p")) + string(" - ") + epgEvent->EndTime(tr("%I:%M %p"))) title=(epgEvent->Title()) elapsed=(epgEvent->Elapsed()) prev_chan=(prev_chan) next_chan=(next_chan) infoMsg=(infoMsg) infoUrl=(infoUrl) &> <%cpp> } else if (prev_chan.Valid()) { <& xmlresponse.ibox update=(update_status) type=(epgEvent->Id()) caption=(epgEvent->Caption()) currentTime=(epgEvent->CurrentTime(tr("%I:%M:%S %p"))) duration=(epgEvent->StartTime(tr("%I:%M %p")) + string(" - ") + epgEvent->EndTime(tr("%I:%M %p"))) title=(epgEvent->Title()) elapsed=(epgEvent->Elapsed()) prev_chan=(prev_chan) infoMsg=(infoMsg) infoUrl=(infoUrl) &> <%cpp> } else if (next_chan.Valid()) { <& xmlresponse.ibox update=(update_status) type=(epgEvent->Id()) caption=(epgEvent->Caption()) currentTime=(epgEvent->CurrentTime(tr("%I:%M:%S %p"))) duration=(epgEvent->StartTime(tr("%I:%M %p")) + string(" - ") + epgEvent->EndTime(tr("%I:%M %p"))) title=(epgEvent->Title()) elapsed=(epgEvent->Elapsed()) next_chan=(next_chan) infoMsg=(infoMsg) infoUrl=(infoUrl) &> <%cpp> } else { <& xmlresponse.ibox update=(update_status) type=(epgEvent->Id()) caption=(epgEvent->Caption()) currentTime=(epgEvent->CurrentTime(tr("%I:%M:%S %p"))) duration=(epgEvent->StartTime(tr("%I:%M %p")) + string(" - ") + epgEvent->EndTime(tr("%I:%M %p"))) title=(epgEvent->Title()) elapsed=(epgEvent->Elapsed()) infoMsg=(infoMsg) infoUrl=(infoUrl) &> <%cpp> } } vdr-plugin-live/pages/timers.ecpp0000644000175000017500000001440212650773437016720 0ustar tobiastobias<%pre> #include #include #include "timers.h" #include "tools.h" #include "setup.h" #include "i18n.h" #include "epg_events.h" #include "timerconflict.h" #include "livefeatures.h" #include "users.h" using namespace std; using namespace vdrlive; static const size_t maximumDescriptionLength = 300; <%args> // input parameters string timerid; string action; <%session scope="global"> bool logged_in(false); <%request scope="page"> cTimer* timer; TimerConflictNotifier timerNotifier; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); pageTitle = trVDR("Timers"); cMutexLock timersLock( &LiveTimerManager() ); SortedTimers& timers = LiveTimerManager().GetTimers(); timer = 0; if ( !timerid.empty() ) { string tId = SortedTimers::DecodeDomId(timerid); // dsyslog("DEBUG: TIMER: tId = %s", tId.c_str()); timer = timers.GetByTimerId(tId); if ( timer == 0 ) throw HtmlError( tr("Couldn't find timer. Maybe you mistyped your request?") ); if (action == "delete") { if (!cUser::CurrentUserHasRightTo(UR_DELTIMERS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); LiveTimerManager().DelTimer(timer); timerNotifier.SetTimerModification(); return reply.redirect("timers.html"); } if (action == "toggle") { LiveTimerManager().ToggleTimerActive(timer); timerNotifier.SetTimerModification(); return reply.redirect("timers.html"); } } string previousDay = ""; <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("timers") component=("timers.timer_actions")>
% if (timers.size() == 0) { <$ tr("No timer defined") $> % } else { <%cpp> // output of the timer list: for (SortedTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer) { EpgInfoPtr epgEvent; string longDescription; if (!timer->Event()) timer->SetEventFromSchedule(); if (timer->Event()) { epgEvent = EpgEvents::CreateEpgInfo(timer->Channel(), timer->Event()); longDescription = StringEscapeAndBreak(SortedTimers::GetTimerInfo(*timer)) + "
" + StringEscapeAndBreak(StringWordTruncate(epgEvent->LongDescr(), maximumDescriptionLength)) + "

" + tr("Click to view details."); } string currentDay = SortedTimers::GetTimerDays(*timer); SortedTimers::iterator nextTimer = timer; ++nextTimer; bool bottom = false; if (nextTimer == timers.end()) bottom = true; else { string nextDay = SortedTimers::GetTimerDays(*nextTimer); bottom = (currentDay != nextDay); } if (previousDay != currentDay) { if (!previousDay.empty()) { <%cpp> } previousDay = currentDay; <%cpp> } std::string timerStateImg = "transparent.png"; std::string timerStateHint; if (timer->Recording()) { timerStateImg = "arrow_rec.gif"; timerStateHint = tr("Timer is recording."); } else if (timer->Flags() & tfActive) { timerStateImg = "arrow.png"; timerStateHint = tr("Timer is active."); } <%cpp> } }
<$ currentDay $>
<$ trVDR("Channel") $>
<$ trVDR("Start") $>
<$ trVDR("Stop") $>
<$ trVDR("File") $>
">" alt="" <%cpp> if (!timerStateHint.empty()) { <& tooltip.hint text=(timerStateHint) &><%cpp> } > "> ">
<$ FormatDateTime(tr("%I:%M %p"), timer->StartTime()) $>
">
<$ FormatDateTime(tr("%I:%M %p"), timer->StopTime()) $>
"> ">Flags() & tfActive) ? "active.png" : "inactive.png") $>" alt="" <& tooltip.hint text=(tr("Toggle timer active/inactive")) &>> "><& pageelems.edit_timer timerId=(timers.GetTimerId(*timer)) &> ">" alt="" <& tooltip.hint text=(tr("Delete timer")) &>>
<%include>page_exit.eh <%def timer_actions> <$ tr("New timer") $> % if ( LiveFeatures< features::epgsearch >().Recent() ) { | <$ tr("Timer conflicts") $> % } vdr-plugin-live/pages/event_widget.ecpp0000644000175000017500000000152712650773437020105 0ustar tobiastobias<%pre> #include #include #include #include #include #include "tools.h" using namespace vdrlive; <%args> title; short_description; description; channel_name; start; end; <%session scope="global"> bool logged_in(false); <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }>
<$ channel_name $>
 
<$ start $> - <$ end $>
<$ title $>
<$ short_description $>
<$ description $>
vdr-plugin-live/pages/keypress.ecpp0000644000175000017500000000100312650773437017253 0ustar tobiastobias<%pre> #include #include "setup.h" using namespace vdrlive; <%args> int keycode = kNone; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); reply.setContentType("application/xml"); <$ keycode $> <$ cRemote::Put( (eKeys)keycode ) ? "1" : "0" $> vdr-plugin-live/pages/play_recording.ecpp0000644000175000017500000000140412650773437020414 0ustar tobiastobias<%pre> #include #include #include "exception.h" #include "setup.h" #include "tasks.h" #include "tools.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> string param; <%session scope="global"> bool logged_in(false); <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); if (!cUser::CurrentUserHasRightTo(UR_STARTREPLAY)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); reply.setContentType( "application/xml" ); PlayRecordingTask task( param ); LiveTaskManager().Execute( task ); <& xmlresponse.ajax name=("play_recording") pname=("recording") value=(param) result=(task.Result()) error=(task.Error()) &> vdr-plugin-live/pages/edit_user.ecpp0000644000175000017500000001462412650773437017406 0ustar tobiastobias<%pre> #include "exception.h" #include "tools.h" #include "users.h" #include "livefeatures.h" #include "setup.h" using namespace std; using namespace vdrlive; <%args> // input parameters string userid; // form parameters string username; string password; bool ur_editsetup = false; bool ur_addtimers = false; bool ur_deltimers = false; bool ur_delrecs = false; bool ur_useremote = false; bool ur_startreplay = false; bool ur_switchchnl = false; bool ur_addstimers = false; bool ur_delstimers = false; bool ur_editrecs = false; <%session scope="global"> bool logged_in(false); <%request scope="page"> cUser* editUser; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); #define CHECKIF(x) reply.out() << ( (x) ? "checked=\"checked\"" : "" ); editUser = NULL; if (request.getMethod() == "POST") { if (!userid.empty()) { editUser = Users.GetByUserId( userid ); if ( editUser == 0 ) throw HtmlError( tr("Couldn't find user. Maybe you mistyped your request?") ); editUser->SetName(username); if (password != std::string(editUser->GetPasswordLength(), '*')) editUser->SetPassword(password); } else { if (Users.GetByUserName( username )) throw HtmlError( tr("This user name is already in use!") ); editUser = new cUser(Users.GetNewId(), username, password); Users.Add(editUser); } editUser->SetUserrights(0); if (ur_editsetup) editUser->SetRight(UR_EDITSETUP); if (ur_addtimers) editUser->SetRight(UR_EDITTIMERS); if (ur_deltimers) editUser->SetRight(UR_DELTIMERS); if (ur_delrecs) editUser->SetRight(UR_DELRECS); if (ur_useremote) editUser->SetRight(UR_USEREMOTE); if (ur_startreplay) editUser->SetRight(UR_STARTREPLAY); if (ur_switchchnl) editUser->SetRight(UR_SWITCHCHNL); if (ur_addstimers) editUser->SetRight(UR_EDITSTIMERS); if (ur_delstimers) editUser->SetRight(UR_DELSTIMERS); if (ur_editrecs) editUser->SetRight(UR_EDITRECS); Users.Save(); return reply.redirect("users.html"); } pageTitle = !userid.empty() ? tr("Edit user") : tr("New user"); if ( !userid.empty() ) { cUser* User = Users.GetByUserId( userid ); if ( User == 0 ) throw HtmlError( tr("Couldn't find user. Maybe you mistyped your request?") ); username = User->Name(); password = std::string(User->GetPasswordLength(), '*'); ur_editsetup = User->HasRightTo(UR_EDITSETUP); ur_addtimers = User->HasRightTo(UR_EDITTIMERS); ur_deltimers = User->HasRightTo(UR_DELTIMERS); ur_delrecs = User->HasRightTo(UR_DELRECS); ur_useremote = User->HasRightTo(UR_USEREMOTE); ur_startreplay = User->HasRightTo(UR_STARTREPLAY); ur_switchchnl = User->HasRightTo(UR_SWITCHCHNL); ur_addstimers = User->HasRightTo(UR_EDITSTIMERS); ur_delstimers = User->HasRightTo(UR_DELSTIMERS); ur_editrecs = User->HasRightTo(UR_EDITRECS); editUser = User; } else { ur_editsetup = true; ur_addtimers = true; ur_deltimers = true; ur_delrecs = true; ur_useremote = true; ur_startreplay = true; ur_switchchnl = true; ur_addstimers = true; ur_delstimers = true; ur_editrecs = true; } <& pageelems.doc_type &> VDR Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("users") &>
<$ pageTitle $>
<$ tr("Name" ) $>:
<$ tr("Password" ) $>:
<$ tr("User rights") $>:
/>
/>
/>
/>
/>
/>
/>
<%cpp> if (LiveFeatures< features::epgsearch >().Recent()) { />
/>
<%cpp> } />
<%include>page_exit.eh vdr-plugin-live/pages/searchresults.ecpp0000644000175000017500000000722512650773437020311 0ustar tobiastobias<%pre> #include #include #include #include "epgsearch.h" #include "tools.h" #include "setup.h" #include "epg_events.h" using namespace vdrlive; using namespace std; <%args> // input parameters string searchtimerid; string searchtimerquery; string searchplain; <%session scope="global"> bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); pageTitle = tr("Search results"); SearchResults results; if (!searchtimerid.empty()) results.GetByID(lexical_cast< int >(searchtimerid)); if (!searchtimerquery.empty()) results.GetByQuery(SearchResults::PopQuery(searchtimerquery)); if (!searchplain.empty()) { SearchTimer s; s.SetId(0); s.SetSearch(searchplain); s.SetSearchMode(0); s.SetUseTitle(true); s.SetUseSubtitle(false); s.SetUseDescription(false); results.GetByQuery(s.ToText()); } <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("searchepg") &>
% if (results.size() == 0) { <$ tr("No search results") $> % } <%cpp> string current_day = ""; for (SearchResults::iterator result = results.begin(); result != results.end(); ++result) { cChannel* channel = Channels.GetByChannelID(result->Channel()); if (!channel) continue; string channelname = channel->Name(); int channelnr = channel->Number(); string start(result->StartTime() ? FormatDateTime(tr("%I:%M %p"), result->StartTime()) : ""); string end(result->StopTime() ? FormatDateTime(tr("%I:%M %p"), result->StopTime()) : ""); string day(result->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), result->StartTime()) : ""); string description = result->Description(); string epgid = EpgEvents::EncodeDomId(result->Channel(), result->EventId()); bool truncated = false; bool bottom = false; SearchResults::iterator nextResult = result; ++nextResult; if (nextResult == results.end()) bottom = true; else { string nextDay(nextResult->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), nextResult->StartTime()) : ""); bottom = (day != nextDay); } if (current_day != day) { if (current_day != "") { % } % current_day = day; % } % }
<$ day $>
"><& pageelems.event_timer epgid=(epgid) &> "> ">
<$ start $> - <$ end $>
">
<%include>page_exit.eh vdr-plugin-live/pages/Makefile0000644000175000017500000000273112650773437016206 0ustar tobiastobias### The official name of this plugin. PLUGIN = live ### Additional options to silence TNTNET warnings TNTFLAGS ?= -Wno-overloaded-virtual -Wno-unused-variable ### Includes and Defines (add further entries here): INCLUDES += -I$(VDRDIR)/include -I.. ### The object files (add further files here): OBJS = menu.o recordings.o schedule.o multischedule.o screenshot.o \ timers.o whats_on.o switch_channel.o keypress.o remote.o \ channels_widget.o edit_timer.o error.o pageelems.o tooltip.o \ vlc.o searchtimers.o edit_searchtimer.o searchresults.o \ searchepg.o login.o ibox.o xmlresponse.o play_recording.o \ pause_recording.o stop_recording.o ffw_recording.o \ rwd_recording.o setup.o content.o epginfo.o timerconflicts.o \ recstream.o users.o edit_user.o edit_recording.o ### The main target: all: libpages.a ### Implicit rules: %.o: %.cpp $(CXX) $(CXXFLAGS) $(TNTFLAGS) -c $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $< %.cpp: %.ecpp $(ECPPC) $(ECPPFLAGS) $(ECPPFLAGS_CPP) $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile $(OBJS:%.o=%.cpp) $(OBJS:%.o=%.ecpp) @$(MAKEDEP) $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $(OBJS:%.o=%.cpp) > $@ ifneq ($(MAKECMDGOALS),clean) -include $(DEPFILE) endif ### Targets: libpages.a: $(OBJS) $(AR) r $@ $^ clean: @rm -f *~ *.o core* libpages.a $(OBJS:%.o=%.cpp) $(DEPFILE) dist: clean @echo "Nothing to do for distribution here ..." vdr-plugin-live/pages/whats_on.ecpp0000644000175000017500000002476312650773437017252 0ustar tobiastobias<%pre> #include #include #include #include #include #include "livefeatures.h" #include "setup.h" #include "tools.h" #include "epg_events.h" #include "epgsearch.h" using namespace std; using namespace vdrlive; static const size_t maximumDescriptionLength = 300; static const size_t maximumTooltipHintLength = 150; <%args> type = "now"; string mode; string attime; string fixtime; <%session scope="global"> bool logged_in(false); <%request scope="page"> string current_type; string current_mode; string current_attime; string current_fixtime; string current_displaytime; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); cSchedulesLock schedulesLock; const cSchedules* Schedules = cSchedules::Schedules(schedulesLock); string head; time_t seektime = 0; string displaytime; string headTime; string headDate; if (mode.empty()) mode = LiveSetup().GetLastWhatsOnListMode(); else LiveSetup().SetLastWhatsOnListMode(mode); current_type = type; current_mode = mode; current_attime = attime; current_fixtime = fixtime; char const * timeFormat = tr("%I:%M %p"); char const * dateFormat = tr("%A, %x"); if (mode == "detail") { dateFormat = tr("%a, %x"); } if (type == "now") { headTime = FormatDateTime(timeFormat, time(0)); headDate = FormatDateTime(dateFormat, time(0)); head = string(tr("What's running on")) + " " + headDate + " " + tr("at") + " " + headTime; } else if (type == "next") { headTime = FormatDateTime(timeFormat, time(0) + 3600); headDate = FormatDateTime(dateFormat, time(0) + 3600); head = tr("What's on next?"); } else if (type == "at") { if (attime != "") displaytime = ExpandTimeString(attime); else if (fixtime != "") displaytime = ExpandTimeString(fixtime); current_displaytime = displaytime; seektime = GetTimeT(displaytime); if (seektime - time(0) + 3600 < 0) // if wanted time is past more then 1h, then use tomorrow seektime += SECSINDAY; headTime = FormatDateTime(timeFormat, seektime); headDate = FormatDateTime(dateFormat, seektime); head = string(tr("What's running on")) + " " + headDate + " " + tr("at") + string(" ") + headTime; } else if (type == "favs") { head = tr("Favorites"); } <& pageelems.doc_type &> VDR-Live - <$ head $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("whats_on") component=("whats_on.whats_on_actions")>
% if (mode == "list") { % } <%cpp> std::list eventList; // collect the broadcasts if (type != "favs") { ReadLock channelsLock( Channels ); if (channelsLock) { // int evntNr = 0; for (cChannel *Channel = Channels.First(); Channel && Channel->Number() <= LiveSetup().GetLastChannel(); Channel = Channels.Next(Channel)) { if (Channel->GroupSep()) { continue; } const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (!Schedule) { continue; } const cEvent *Event = NULL; if (type == "now") Event = Schedule->GetPresentEvent(); else if (type == "next") Event = Schedule->GetFollowingEvent(); else if (type == "at") Event = Schedule->GetEventAround(seektime); if (!Event && !LiveSetup().GetShowChannelsWithoutEPG()) continue; EpgInfoPtr epgEvent = EpgEvents::CreateEpgInfo(Channel, Event); eventList.push_back(epgEvent); } } } else // get favorite broadcasts from epgsearch { SearchResults results; SearchTimers timers; for (SearchTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer) { if (!timer->UseInFavorites()) continue; SearchResults curresults; curresults.GetByID(timer->Id()); results.merge(curresults); } time_t now = time(NULL); for (SearchResults::iterator result = results.begin(); result != results.end(); ++result) { long diff = result->StartTime() - now; if (labs(diff) >= 24*60*60) continue; // skip broadcasts more than a day away EpgInfoPtr epgEvent = EpgEvents::CreateEpgInfo(result->GetChannel(), result->GetEvent()); eventList.push_back(epgEvent); } } // display broadcasts for(std::list::iterator i = eventList.begin(); i != eventList.end(); ++i ) { EpgInfoPtr epgEvent = *i; bool truncated = false; string truncDescription = StringWordTruncate(epgEvent->LongDescr(), maximumTooltipHintLength, truncated); string longDescription = StringEscapeAndBreak(StringWordTruncate(epgEvent->LongDescr(), maximumDescriptionLength)) + "

" + tr("Click to view details."); const cChannel* Channel = epgEvent->Channel(); if (!Channel) continue; int chNumber = Channel->Number(); string startTime(epgEvent->StartTime(tr("%I:%M %p"))); string endTime(epgEvent->EndTime(tr("%I:%M %p"))); string startDate(epgEvent->StartTime(tr("%a, %x"))); string timeSpan(startTime + " - " + endTime); if (startTime.empty() && endTime.empty()) { timeSpan = mode=="detail" ? headTime : string(); startDate = headDate; } if (mode == "detail") {
<& pageelems.epg_tool_box detail=(1) epgid=(epgEvent->Id()) title=(epgEvent->Title()) startTime=(epgEvent->GetStartTime()) endTime=(epgEvent->GetEndTime()) &>
<$ (startDate) $>
<$ (timeSpan) $>
<& pageelems.progressbar progress=(epgEvent->Elapsed()) duration=(epgEvent->Duration()) &>
<$ (epgEvent->Title()) $>
<$ (epgEvent->ShortDescr()) $>
<$ truncDescription $>
% if (truncated) { % }
<%cpp> } else { // mode == "list" std::list::iterator last = i; bool lastCurrentChanel = (++last == eventList.end()); tChannelID chanId; tEventID eventId; EpgEvents::DecodeDomId(epgEvent->Id(), chanId, eventId);
<& pageelems.epg_tool_box detail=(0) epgid=(epgEvent->Id()) title=(epgEvent->Title()) startTime=(epgEvent->GetStartTime()) endTime=(epgEvent->GetEndTime()) lastCurrentChanel=(lastCurrentChanel ? 1 : 0) &> % } <%cpp> } % if (mode == "list") {
<$ head $>
">
<$ (timeSpan) $>
<& pageelems.progressbar progress=(epgEvent->Elapsed()) duration=(epgEvent->Duration()) &>
"> ">
% }
<%include>page_exit.eh <# ------------------------------------------------------------------------- #> <%def whats_on_actions> " href="whats_on.html?type=now&mode=<$ current_mode $>" id="nowhref"><$ tr("Now") $> | " href="whats_on.html?type=next&mode=<$ current_mode $>" id="nexthref"><$ tr("Next") $> | "><$ tr("What's on") $> | "><$ tr("at") $> " onchange="showspectime(this)"/> | % if ( LiveFeatures< features::epgsearch >().Recent() ) { " href="whats_on.html?type=favs&mode=<$ current_mode $>"><$ tr("Favorites") $> | % } % if ( current_mode == "list" ) { <$ tr("Details view") $> % } else { <$ tr("List view") $> % } vdr-plugin-live/pages/edit_searchtimer.ecpp0000644000175000017500000011233412650773437020733 0ustar tobiastobias<%pre> #include #include #include #include #include #include #include "exception.h" #include "tools.h" #include "epgsearch.h" #include "setup.h" #include "i18n.h" #include "users.h" using namespace std; using namespace vdrlive; <%args> // input parameters string searchtimerid; string test; // form parameters string search = ""; int mode = 0; bool matchcase = false; int tolerance = 1; bool usetitle = false; bool usesubtitle = false; bool usedescr = false; int usechannel = SearchTimer::NoChannel; tChannelID channelidfrom; tChannelID channelfrom; tChannelID channelidto; tChannelID channelto; string changrpsel = ""; bool usetime = false; string start_h = "00"; string start_m = "00"; string stop_h = "00"; string stop_m = "00"; bool useduration = false; int durationmin = 0; int durationmax = 90; bool useweekday = false; bool wday_mon = false; bool wday_tue = false; bool wday_wed = false; bool wday_thu = false; bool wday_fri = false; bool wday_sat = false; bool wday_sun = false; bool useinfavorites = false; int useassearchtimer = 0; int searchtimeraction = 0; bool seriesrecording = false; string directory = ""; int delrecafterdays = 0; int keeprecs = 0; int pauseonrecs = 0; int blacklistmode = 0; string blacklistids[]; int switchminbefore = 0; bool useextepginfo = false; string extepgvalues[]; bool avoidrepeats = false; int allowedrepeats = 0; int repeatswithindays = 0; bool comparetitle = false; int comparesubtitle = 0; bool comparesummary = false; unsigned avoidrepeatscatselected[]; int priority = 0; int lifetime = 0; int marginstart = 0; int marginstop = 0; bool usevps = false; bool delmode = false; int delaftercountrecs = 0; int delafterdaysoffirstrec = 0; string blacklistids_internal; string useassearchtimerfrom; string useassearchtimerto; bool ignoreMissingEPGCats = false; <%session scope="global"> bool logged_in(false); <%request scope="page"> ExtEPGInfos extEPGInfos; ChannelGroups channelGroups; Blacklists blacklists; RecordingDirs recordingdirs; SearchTimer* editsearchtimer; <%include>page_init.eh <{ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); }> <%cpp> if (!cUser::CurrentUserHasRightTo(UR_EDITSTIMERS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); #define SELECTIF(x) reply.out() << ( (x) ? "selected=\"selected\"" : "" ); #define CHECKIF(x) reply.out() << ( (x) ? "checked=\"checked\"" : "" ); SearchTimers searchtimers; bool testmode = !test.empty(); editsearchtimer = NULL; if ( request.getMethod() == "POST") { SearchTimer searchtimer; if ( !searchtimerid.empty() && !testmode) { editsearchtimer = searchtimers.GetByTimerId( searchtimerid ); if ( editsearchtimer == 0 ) throw HtmlError( tr("Couldn't find searchtimer. Maybe you mistyped your request?") ); searchtimer.SetId(editsearchtimer->Id()); } searchtimer.SetSearch(search); searchtimer.SetSearchMode(mode); searchtimer.SetTolerance(tolerance); searchtimer.SetMatchCase(matchcase); searchtimer.SetUseTitle(usetitle); searchtimer.SetUseSubtitle(usesubtitle); searchtimer.SetUseDescription(usedescr); searchtimer.SetUseExtEPGInfo(useextepginfo); if (useextepginfo) { vector< string > infos; unsigned int i=0; for (ExtEPGInfos::iterator extinfo = extEPGInfos.begin(); extinfo != extEPGInfos.end(); ++extinfo, i++) { ostringstream os; os << extinfo->Id() << "#" << (iSearch(); mode = searchtimer->SearchMode(); tolerance = searchtimer->Tolerance(); matchcase = searchtimer->MatchCase(); usetitle = searchtimer->UseTitle(); usesubtitle = searchtimer->UseSubtitle(); usedescr = searchtimer->UseDescription(); usechannel = searchtimer->UseChannel(); channelfrom = searchtimer->ChannelMin(); channelto = searchtimer->ChannelMax(); if (!channelto.Valid() && channelfrom.Valid()) channelto = channelfrom; if (usechannel == SearchTimer::Group) changrpsel = searchtimer->ChannelText(); usetime = searchtimer->UseTime(); ostringstream os; os << setw(2) << setfill('0') << ( searchtimer->StartTime() / 100 ) % 100; start_h = os.str(); os.str(""); os << setw(2) << setfill('0') << searchtimer->StartTime() % 100; start_m = os.str(); os.str(""); os << setw(2) << setfill('0') << ( searchtimer->StopTime() / 100 ) % 100; stop_h = os.str(); os.str(""); os << setw(2) << setfill('0') << searchtimer->StopTime() % 100; stop_m = os.str(); useduration = searchtimer->UseDuration(); if (useduration) { durationmin = searchtimer->MinDuration(); durationmax = searchtimer->MaxDuration(); } useweekday = searchtimer->UseDayOfWeek(); if (useweekday) { int dayofweek = searchtimer->DayOfWeek(); if (dayofweek >= 0) { wday_sun = (dayofweek == 0); wday_mon = (dayofweek == 1); wday_tue = (dayofweek == 2); wday_wed = (dayofweek == 3); wday_thu = (dayofweek == 4); wday_fri = (dayofweek == 5); wday_sat = (dayofweek == 6); } else { wday_sun = -dayofweek & 0x01; wday_mon = -dayofweek & 0x02; wday_tue = -dayofweek & 0x04; wday_wed = -dayofweek & 0x08; wday_thu = -dayofweek & 0x10; wday_fri = -dayofweek & 0x20; wday_sat = -dayofweek & 0x40; } } useinfavorites = searchtimer->UseInFavorites(); useassearchtimer = searchtimer->UseAsSearchTimer(); if (useassearchtimer == 2) { useassearchtimerfrom = searchtimer->UseAsSearchTimerFrom(tr("mm/dd/yyyy")); useassearchtimerto = searchtimer->UseAsSearchTimerTil(tr("mm/dd/yyyy")); } searchtimeraction = searchtimer->SearchTimerAction(); seriesrecording = searchtimer->UseSeriesRecording(); directory = searchtimer->Directory(); delrecafterdays = searchtimer->DelRecsAfterDays(); keeprecs = searchtimer->KeepRecs(); pauseonrecs = searchtimer->PauseOnRecs(); blacklistmode = searchtimer->BlacklistMode(); switchminbefore = searchtimer->SwitchMinBefore(); useextepginfo = searchtimer->UseExtEPGInfo(); vector< string > infos = searchtimer->ExtEPGInfo(); for(unsigned int i=0; i parts = StringSplit( infos[i], '#' ); extepgvalues.push_back(parts.size() > 1?parts[1]:""); } else extepgvalues.push_back(""); } ignoreMissingEPGCats = searchtimer->IgnoreMissingEPGCats(); avoidrepeats = searchtimer->AvoidRepeats(); allowedrepeats = searchtimer->AllowedRepeats(); repeatswithindays = searchtimer->RepeatsWithinDays(); comparetitle = searchtimer->CompareTitle(); comparesubtitle = searchtimer->CompareSubtitle(); comparesummary = searchtimer->CompareSummary(); for(unsigned int i=0; iCompareCategories() & (1<Priority(); lifetime = searchtimer->Lifetime(); marginstart = searchtimer->MarginStart(); marginstop = searchtimer->MarginStop(); usevps = searchtimer->UseVPS(); delmode = searchtimer->DelMode(); delaftercountrecs = searchtimer->DelAfterCountRecs(); delafterdaysoffirstrec = searchtimer->DelAfterDaysOfFirstRec(); editsearchtimer = searchtimer; } else { for(unsigned int i=0; i(EPGSearchSetupValues::ReadValue("DefPriority")); lifetime = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefLifetime")); marginstart = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefMarginStart")); marginstop = lexical_cast< int >(EPGSearchSetupValues::ReadValue("DefMarginStop")); } <& pageelems.doc_type &> VDR Live - <$ editsearchtimer ? tr("Edit search timer") : tr("New search timer") $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <& menu active=("searchtimers") &>
% if (extEPGInfos.size() > 0) { % }
<$ editsearchtimer ? tr("Edit search timer") : tr("New search timer") $>
<$ tr("Search term") $>:
<$ tr("Search mode" ) $>:
<$ tr("Match case") $>:
id="matchcase"/>
<$ tr("Search in") $>:
/>
/>
/>
<$ tr("Use extended EPG info" ) $>:
onclick="changeduseextepginfo(this)" id="useextepginfo"/>
<$ tr("Use channel" ) $>:
<$ tr("Use time") $>:
onclick="changedusetime(this)" id="usetime" />
<$ tr("Use duration") $>:
onclick="changeduseduration(this)" id="useduration" />
<$ tr("Use day of week") $>:
onclick="changeduseweekday(this)" id="useweekday" />
<$ tr("Use blacklists" ) $>:
<$ tr("Use in favorites menu") $>:
/>
<$ tr("Use as search timer" ) $>:
<%include>page_exit.eh vdr-plugin-live/pages/recordings.ecpp0000644000175000017500000003267612650773437017571 0ustar tobiastobias<%pre> #include #ifdef HAVE_LIBPCRECPP #include #endif #include #include #include #include "exception.h" #include "epg_events.h" #include "setup.h" #include "tasks.h" #include "tools.h" #include "i18n.h" #include "users.h" #include "recman.h" #define MB_PER_MINUTE 25.75 // this is just an estimate! using namespace vdrlive; using namespace std; <%args> string sort; string todel; string diskinfo; string filter; string deletions[]; <%session scope="global"> bool logged_in(false); <%request scope="page"> string currentSort; string deleteResult; string currentFilter; <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); currentSort = LiveSetup().GetLastSortingMode(); if (!sort.empty()) { if (sort == "date") currentSort = (currentSort == "dateasc") ? "datedesc" : "dateasc"; else if (sort == "name") currentSort = (currentSort == "nameasc") ? "namedesc" : "nameasc"; LiveSetup().SetLastSortingMode(currentSort); } currentFilter = filter; pageTitle = tr("Recordings"); deleteResult = ""; if (!todel.empty()) { if (!cUser::CurrentUserHasRightTo(UR_DELRECS)) throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); deletions.push_back(todel); } for (deletions_type::const_iterator it = deletions.begin(); it != deletions.end(); ++it) { if (cUser::CurrentUserHasRightTo(UR_DELRECS)) { RemoveRecordingTask task(*it); LiveTaskManager().Execute(task); if (!task.Result()) deleteResult += string() + tr("ERROR:") + " " + task.Error() + "
"; else deleteResult += string() + tr("Deleted recording:") + " " + StringReplace(task.RecName(), "~", "/") + "
"; } else { throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") ); } } deletions.clear(); int FreeMB, UsedMB; #if APIVERSNUM > 20101 int Percent = cVideoDirectory::VideoDiskSpace(&FreeMB, &UsedMB); #else int Percent = VideoDiskSpace(&FreeMB, &UsedMB); #endif int Minutes = int(double(FreeMB) / MB_PER_MINUTE); int Hours = Minutes / 60; Minutes %= 60; diskinfo = cString::sprintf("%s %d%% - %2d:%02d %s", trVDR("Disk"), Percent, Hours, Minutes, trVDR("free")); <& pageelems.doc_type &> VDR-Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> <& pageelems.logo &> <%cpp> if (!deleteResult.empty()) { <& menu active=("recordings") component=("recordings.delete_error") &> <%cpp> } else { <& menu active=("recordings") component=("recordings.sort_options") &> <%cpp> }
<$ string(tr("List of recordings")) + " (" + diskinfo + ")" $>
<%cpp> if (Recordings.Count() == 0) { // Access VDRs global cRecordings Recordings instance. <$ tr("No recordings found") $> <%cpp> } else {
    <& recordings.recordings_item filter=(currentFilter) &>
<%cpp> }
<%include>page_exit.eh <# ---------------------------------------------------------------------- #> <%def recordings_item> <%args> filter; path[]; int level = 0; <%cpp> RecordingsTreePtr recordingsTree(LiveRecordingsManager()->GetRecordingsTree()); RecordingsMap::iterator iter; RecordingsMap::iterator end = recordingsTree->end(path); list recItems; list::iterator recIter; for (iter = recordingsTree->begin(path); iter != end; ++iter) { RecordingsItemPtr recItem = iter->second; if (recItem->IsDir()) { recItems.push_back(recItem); } } if (currentSort == "namedesc") recItems.sort(RecordingsItemPtrCompare::ByDescendingName); else recItems.sort(RecordingsItemPtrCompare::ByAscendingName); for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { RecordingsItemPtr recItem = *recIter;
  • <& rec_item_dir name=(recItem->Name()) level=(level) &> <%cpp> #if TNT_QUERYPARAMS_NO_BOOL tnt::QueryParams recItemParams(qparam); #else tnt::QueryParams recItemParams(qparam, false); #endif for (path_type::const_iterator i = path.begin(); i != path.end(); ++i) { recItemParams.add("path", *i); } recItemParams.add("path", recItem->Name()); recItemParams.add("level", lexical_cast(level + 1)); recItemParams.add("filter", filter);
  • <%cpp> } recItems.clear(); for (iter = recordingsTree->begin(path); iter != end; ++iter) { RecordingsItemPtr recItem = iter->second; if (!recItem->IsDir()) { recItems.push_back(recItem); } } if (currentSort == "dateasc") recItems.sort(RecordingsItemPtrCompare::ByAscendingDate); else if (currentSort == "datedesc") recItems.sort(RecordingsItemPtrCompare::ByDescendingDate); else if (currentSort == "namedesc") recItems.sort(RecordingsItemPtrCompare::ByDescendingName); else recItems.sort(RecordingsItemPtrCompare::ByAscendingName); for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { RecordingsItemPtr recItem = *recIter; // xgettext:no-c-format string day(FormatDateTime(tr("%a,"), recItem->StartTime())); string dayLen(lexical_cast(day.length() - 1) + ".25em;"); // TRANSLATORS: recording duration format HH:MM string duration(recItem->Duration() < 0 ? "" : FormatDuration(tr("(%d:%02d)"), recItem->Duration() / 60, recItem->Duration() % 60)); string shortDescr(recItem->RecInfo()->ShortText() ? recItem->RecInfo()->ShortText() : ""); string description(recItem->RecInfo()->Description() ? recItem->RecInfo()->Description() : ""); string hint(tr("Click to view details.")); if (!shortDescr.empty()) hint = shortDescr + "
    " + hint; else if (!description.empty()) hint = description + "
    " + hint; #ifdef HAVE_LIBPCRECPP pcrecpp::RE re(filter.c_str(), pcrecpp::UTF8()); if (filter.empty() || re.PartialMatch(recItem->Name()) || re.PartialMatch(shortDescr) || re.PartialMatch(description)) #endif {
  • <& rec_item_file name=(recItem->Name()) level=(level) id=(recItem->Id()) day=(day) dayLen=(dayLen) startTime=(recItem->StartTime()) duration=(duration) hint=(hint) shortDescr=(shortDescr) archived=(RecordingsManager::GetArchiveDescr(recItem->Recording())) &>
  • <%cpp> } } <# ---------------------------------------------------------------------- #> <%def sort_options> <%cpp> { " alt="" /><$ tr("Sort by name") $> | " alt="" /><$ tr("Sort by date") $> <%cpp> #ifdef HAVE_LIBPCRECPP | <$ tr("Filter") $>:  <& tooltip.help text=(tr("Look in recordings titles and subtitles for the given string and display only the matching ones. You may also use perl compatible regular expressions (PCRE).")) &> <%cpp> #endif | " alt="" <& tooltip.hint text=(tr("Expand all folders")) &>/> " alt="" <& tooltip.hint text=(tr("Collapse all folders")) &>/>
    <%cpp> } <# ---------------------------------------------------------------------- #> <%def del_rec> <%args> string id; <%cpp> { >" alt="" /><%cpp> } <# ---------------------------------------------------------------------- #> <%def edit_rec> <%args> string id; <%cpp> { " alt="" <& tooltip.hint text=(tr("Edit recording")) &> /><%cpp> } <# ---------------------------------------------------------------------- #> <%def rec_tools> <%args> string id; string title; <& pageelems.ajax_action_href action="play_recording" param=(id) tip=(tr("play this recording.")) image="play.png" alt="" &> <& pageelems.vlc_stream_recording recid=(id) &> <& pageelems.imdb_info_href title=(title) &> <& recordings.edit_rec id=(id) &> <& recordings.del_rec id=(id) &> <# ---------------------------------------------------------------------- #> <%def archived_disc> <%args> string archived; string title; " alt="on_dvd" <& tooltip.hint text=(archived) &> /> <& pageelems.imdb_info_href title=(title) &> <# ---------------------------------------------------------------------- #> <%def rec_item_dir> <%args> string name; int level; string collapseimg = "plus.png"; string folderimg = "folder_closed.png";
    <%cpp> reply.out() << StringRepeat(level, "\"\""); " alt="" />" alt="" />
    <$ name $>
     
    <# ---------------------------------------------------------------------- #> <%def rec_item_file> <%args> string name; int level; string id; string day; string dayLen; time_t startTime; string duration; string hint; string shortDescr; string archived;
    <%cpp> reply.out() << StringRepeat(level + 1, "\"\""); <%cpp> if (!archived.empty()) { " alt="on_dvd" <& tooltip.hint text=(archived) &> /><%cpp> } else { <%cpp> }
    <$ FormatDateTime(tr("%a,"), startTime) + string(" ") + FormatDateTime(tr("%b %d %y"), startTime) + string(" ") + FormatDateTime(tr("%I:%M %p"), startTime) $>
    <$ duration $>
    <%cpp> if (archived.empty()) { <& recordings.rec_tools id=(id) title=(name)&> <%cpp> } else { <& pageelems.imdb_info_href title=(name) &> <%cpp> }
    <%cpp> if (! archived.empty()) {
    <$ archived $>
    <%cpp> }
    <# ---------------------------------------------------------------------- #> <%def delete_error> <& recordings.sort_options &> <%cpp> { reply.out() << deleteResult; } vdr-plugin-live/pages/recstream.ecpp0000644000175000017500000000450712650773437017407 0ustar tobiastobias<%pre> #include #include #include #include #include #include #include #include "tntfeatures.h" #include "setup.h" #include "recman.h" using namespace std; using namespace vdrlive; off_t RecSize(cRecording const * recording) { cFileName recFile(recording->FileName(), false, false, recording->IsPesRecording()); off_t recSize = 0; for (cUnbufferedFile *recData = recFile.Open(); recData; recData = recFile.NextFile()) { struct stat buf; if (0 == stat(recFile.Name(), &buf)) { recSize += buf.st_size; // dsyslog("LIVE: size of recording part %s is %ld", recFile.Name(), buf.st_size); } else { esyslog("LIVE: can't determine size of %s", recFile.Name()); } } // dsyslog("LIVE: total size of %s is %ld", recording->FileName(), recSize); return recSize; } <%args> string recid; <%session scope="global"> bool logged_in(false); <%cpp> //if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); cRecording const * recording = LiveRecordingsManager()->GetByMd5Hash(recid); if (recording) { reply.setContentType("video/mpeg"); reply.setKeepAliveHeader(); reply.setContentLengthHeader(RecSize(recording)); reply.setDirectMode(); cFileName recFile(recording->FileName(), false, false, recording->IsPesRecording()); // dsyslog("LIVE: start send video data."); for (cUnbufferedFile *recData = recFile.Open(); recData; recData = recFile.NextFile()) { char buffer[KILOBYTE(16)]; ssize_t bytesRead = 0; // dsyslog("LIVE: send file %s", recFile->Name()); while (0 < (bytesRead = recData->Read(buffer, sizeof(buffer)))) { // dsyslog("LIVE: copy %zd bytes", bytesRead); reply.out().write(buffer, bytesRead); if (!reply.out()) { return HTTP_GONE; } #if TNT_WATCHDOG_SILENCE request.touch(); // retrigger the watchdog. #endif } // dsyslog("LIVE: bytesRead = %zd", bytesRead); if (bytesRead < 0) { return HTTP_PARTIAL_CONTENT; } } // dsyslog("LIVE: finished send video data."); reply.out() << std::flush; return HTTP_OK; } return DECLINED; vdr-plugin-live/livefeatures.h0000644000175000017500000000277212650773437016323 0ustar tobiastobias#ifndef VDR_LIVE_FEATURES_H #define VDR_LIVE_FEATURES_H #include #include namespace vdrlive { //LiveFeatures().Available(); class SplitVersion { public: explicit SplitVersion( std::string version ); bool operator<( const SplitVersion& right ) const; private: int m_version; std::string m_suffix; }; template< typename Feat > class Features; template< typename Feat > Features< Feat >& LiveFeatures(); template< typename Feat > class Features { friend Features< Feat >& LiveFeatures<>(); public: bool Loaded() const { return m_plugin != 0; } bool Recent() const { return !(m_version < m_minVersion); } char const* Version() const { return m_plugin ? m_plugin->Version() : ""; } char const* MinVersion() const { return Feat::MinVersion(); } private: cPlugin* m_plugin; SplitVersion m_version; SplitVersion m_minVersion; Features() : m_plugin( cPluginManager::GetPlugin( Feat::Plugin() ) ) , m_version( Version() ) , m_minVersion( Feat::MinVersion() ) {} }; template< typename Feat > Features< Feat >& LiveFeatures() { static Features< Feat > instance; return instance; } namespace features { struct epgsearch { static const char* Plugin() { return "epgsearch"; } static const char* MinVersion() { return "0.9.25.beta6"; } }; struct streamdev_server { static const char* Plugin() { return "streamdev-server"; } static const char* MinVersion() { return "?"; } }; } // namespace features } // namespace vdrlive #endif // VDR_LIVE_FEATURES_H vdr-plugin-live/exception.h0000644000175000017500000000050212650773437015610 0ustar tobiastobias#ifndef VDR_LIVE_EXCEPTION_H #define VDR_LIVE_EXCEPTION_H #include namespace vdrlive { class HtmlError: public std::runtime_error { public: HtmlError( std::string const& message ): std::runtime_error( message ) {} virtual ~HtmlError() throw() {} }; } // namespace vdrlive #endif // VDR_LIVE_EXCEPTION_H vdr-plugin-live/epg_events.cpp0000644000175000017500000002417012650773437016313 0ustar tobiastobias#include #include #include #include #include "tools.h" #include "recman.h" #include "epg_events.h" #include "setup.h" using namespace std; namespace vdrlive { /* * ------------------------------------------------------------------------- * EpgInfo * ------------------------------------------------------------------------- */ EpgInfo::EpgInfo(const std::string& id, const std::string& caption) : m_eventId(id), m_caption(caption) { } EpgInfo::~EpgInfo() { } const string EpgInfo::CurrentTime(const char* format) const { return FormatDateTime(format, time(0)); } const string EpgInfo::StartTime(const char* format) const { time_t start = GetStartTime(); return start ? FormatDateTime(format, start) : ""; } const string EpgInfo::EndTime(const char* format) const { time_t end = GetEndTime(); return end ? FormatDateTime(format, end) : ""; } int EpgInfo::Elapsed() const { return EpgEvents::ElapsedTime(GetStartTime(), GetEndTime()); } int EpgInfo::Duration() const { return EpgEvents::Duration(GetStartTime(), GetEndTime()); } /* * ------------------------------------------------------------------------- * EpgEvent * ------------------------------------------------------------------------- */ EpgEvent::EpgEvent(const std::string& id, const cEvent* event, const char* channelName) : EpgInfo(id, channelName), m_event(event) { } EpgEvent::~EpgEvent() { } /* * ------------------------------------------------------------------------- * EpgString * ------------------------------------------------------------------------- */ EpgString::EpgString(const string& id, const string& caption, const string& info) : EpgInfo(id, caption), m_info(info) { } EpgString::~EpgString() { } const string EpgString::Title() const { return m_info; } const string EpgString::ShortDescr() const { return ""; } const string EpgString::LongDescr() const { return ""; } // virtual const std::string Archived() const { return std::string(); } time_t EpgString::GetStartTime() const { return time(0); } time_t EpgString::GetEndTime() const { return time(0); } /* * ------------------------------------------------------------------------- * EpgRecording * ------------------------------------------------------------------------- */ EpgRecording::EpgRecording(const string& recid, const cRecording* recording, const char* caption) : EpgInfo(recid, (caption != 0) ? caption : ""), m_recording(recording), m_ownCaption(caption != 0), m_checkedArchived(false), m_archived() { } EpgRecording::~EpgRecording() { m_recording = 0; } const string EpgRecording::Caption() const { if (m_ownCaption) { return EpgInfo::Caption(); } if (!m_recording) { return ""; } return Name(); } const string EpgRecording::Title() const { if (!m_recording) { return ""; } const cRecordingInfo* info = m_recording->Info(); return (info && info->Title()) ? info->Title() : Name(); } const string EpgRecording::ShortDescr() const { const cRecordingInfo* info = m_recording ? m_recording->Info() : 0; return (info && info->ShortText()) ? info->ShortText() : ""; } const string EpgRecording::LongDescr() const { const cRecordingInfo* info = m_recording ? m_recording->Info() : 0; return (info && info->Description()) ? info->Description() : ""; } const string EpgRecording::Archived() const { if (!m_checkedArchived) { if (m_recording) { m_archived = RecordingsManager::GetArchiveDescr(m_recording); m_checkedArchived = true; } } return m_archived; } time_t EpgRecording::GetStartTime() const { return m_recording ? m_recording->Start() : 0; } time_t EpgRecording::GetEndTime() const { time_t endTime = 0; if (m_recording) { time_t startTime = m_recording->Start(); int length = m_recording->LengthInSeconds(); endTime = (length < 0) ? startTime : startTime + length; } return endTime; } int EpgRecording::Elapsed() const { cControl* pControl = cControl::Control(); if (pControl) { int current, total; if (pControl->GetIndex(current,total)) { if (total) { return (100 * current) / total; } } } return 0; } const string EpgRecording::Name() const { string name(m_recording->Name()); size_t index = name.find_last_of('~'); if (index != string::npos) { name = name.substr(index+1); } return name; } /* * ------------------------------------------------------------------------- * EmptyEvent * ------------------------------------------------------------------------- */ EmptyEvent::EmptyEvent(std::string const &id, tChannelID const &channelID, const char* channelName) : EpgInfo(id, channelName), m_channelID(channelID) { } EmptyEvent::~EmptyEvent() { } /* * ------------------------------------------------------------------------- * EpgEvents * ------------------------------------------------------------------------- */ namespace EpgEvents { string EncodeDomId(tChannelID const &chanId, tEventID const &eId) { string channelId(chanId.ToString()); string eventId("event_"); channelId = vdrlive::EncodeDomId(channelId, ".-", "pm"); eventId += channelId; eventId += '_'; eventId += lexical_cast(eId); return eventId; } void DecodeDomId(string const &epgid, tChannelID& channelId, tEventID& eventId) { string const eventStr("event_"); size_t delimPos = epgid.find_last_of('_'); string cIdStr = epgid.substr(eventStr.length(), delimPos - eventStr.length()); cIdStr = vdrlive::DecodeDomId(cIdStr, "mp", "-."); string const eIdStr = epgid.substr(delimPos+1); channelId = tChannelID::FromString(cIdStr.c_str()); eventId = lexical_cast(eIdStr); } EpgInfoPtr CreateEpgInfo(string const &epgid, cSchedules const *schedules) { string const errorInfo(tr("Epg error")); cSchedulesLock schedulesLock; tEventID eventId = tEventID(); tChannelID channelId = tChannelID(); DecodeDomId(epgid, channelId, eventId); cChannel const *channel = Channels.GetByChannelID(channelId); if (!channel) { return CreateEpgInfo(epgid, errorInfo, tr("Wrong channel id")); } cSchedule const *schedule = schedules->GetSchedule(channel); if (!schedule) { return CreateEpgInfo(epgid, errorInfo, tr("Channel has no schedule")); } cEvent const *event = schedule->GetEvent(eventId); if (!event) { return CreateEpgInfo(epgid, errorInfo, tr("Wrong event id")); } return CreateEpgInfo(channel, event, epgid.c_str()); } EpgInfoPtr CreateEpgInfo(cChannel const *chan, cEvent const *event, char const *idOverride) { if (event) { string domId(idOverride ? idOverride : EncodeDomId(chan->GetChannelID(), event->EventID())); return EpgInfoPtr(new EpgEvent(domId, event, chan->Name())); } if (LiveSetup().GetShowChannelsWithoutEPG()) { string domId(idOverride ? idOverride : EncodeDomId(chan->GetChannelID(), 0)); return EpgInfoPtr(new EmptyEvent(domId, chan->GetChannelID(), chan->Name())); } return EpgInfoPtr(); } EpgInfoPtr CreateEpgInfo(string const &recid, cRecording const *recording, char const *caption) { return EpgInfoPtr(new EpgRecording(recid, recording, caption)); } EpgInfoPtr CreateEpgInfo(string const &id, string const &caption, string const &info) { return EpgInfoPtr(new EpgString(id, caption, info)); } bool ScanForEpgImages(string const & imageId, string const & wildcard, list & images) { bool found = false; const string filemask(LiveSetup().GetEpgImageDir() + "/" + imageId + wildcard); glob_t globbuf; globbuf.gl_offs = 0; if (!LiveSetup().GetEpgImageDir().empty() && glob(filemask.c_str(), GLOB_DOOFFS, NULL, &globbuf) == 0) { for(size_t i = 0; i < globbuf.gl_pathc; i++) { const string imagefile(globbuf.gl_pathv[i]); size_t delimPos = imagefile.find_last_of('/'); images.push_back(imagefile.substr(delimPos+1)); found = true; } globfree(&globbuf); } return found; } list EpgImages(string const &epgid) { size_t delimPos = epgid.find_last_of('_'); string imageId = epgid.substr(delimPos+1); list images; // Initially we scan for images that follow the scheme // '_.*' where distincition is any // character sequence. Usually distinction will be used // to assign more than one image to an epg event. Thus it // will be a digit or number. The sorting of the images // will depend on the 'distinction' lexical sorting // (similar to what ls does). // Example: // 112123_0.jpg first epg image for event id 112123 // 112123_1.png second epg image for event id 112123 if (! ScanForEpgImages(imageId, "_*.*", images)) { // if we didn't find images that follow the scheme // above we try to find images that contain only the // event id as file name without extension: if (! ScanForEpgImages(imageId, ".*", images)) { #if TVM2VDR_PL_WORKAROUND // if we didn't get images try to work arround a // bug in tvm2vdr. tvm2vdr seems always to use // one digit less, which leads in some rare cases // to the bug in LIVE, that unrelated and to many // images are displayed. But without this 'fix' // no images would be visible at all. The bug // should be fixed in tvm2vdr.pl (Perl version of // tvm2vdr). There exists a plugin - also called // tvm2vdr - which does not have that bug. imageId = imageId.substr(0, imageId.size()-1); ScanForEpgImages(imageId, "*.*", images); #endif } } return images; } int ElapsedTime(time_t const startTime, time_t const endTime) { // Elapsed time is only meaningful when there is a non zero // duration (e.g. startTime != endTime and endTime > startTime) int duration = Duration(startTime, endTime); if (duration > 0) { time_t now = time(0); if ((startTime <= now) && (now <= endTime)) { return 100 * (now - startTime) / duration; } } return -1; } int Duration(time_t const startTime, time_t const endTime) { return endTime - startTime; } } // namespace EpgEvents }; // namespace vdrlive vdr-plugin-live/Makefile0000644000175000017500000001210512650773437015103 0ustar tobiastobias# # Makefile for the 'LIVE' Video Disk Recorder plugin # # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. # By default the main source file also carries this name. PLUGIN = live ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep '\#define LIVEVERSION ' setup.h | awk '{ print $$3 }' | sed -e 's/[";]//g') ### Check for libpcre c++ wrapper HAVE_LIBPCRECPP = $(shell pcre-config --libs-cpp) ### The directory environment: # Use package data if installed...otherwise assume we're under the VDR source directory: PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc)) LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) # TMPDIR ?= /tmp ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) ECPPC ?= ecppc ### The version number of VDR's plugin API: APIVERSION = $(call PKGCFG,apiversion) ### Allow user defined options to overwrite defaults: -include $(PLGCFG) ### Determine tntnet and cxxtools versions: TNTVERSION = $(shell tntnet-config --version | sed -e's/\.//g' | sed -e's/pre.*//g' | awk '/^..$$/ { print $$1."000"} /^...$$/ { print $$1."00"} /^....$$/ { print $$1."0" } /^.....$$/ { print $$1 }') CXXTOOLVER = $(shell cxxtools-config --version | sed -e's/\.//g' | sed -e's/pre.*//g' | awk '/^..$$/ { print $$1."000"} /^...$$/ { print $$1."00"} /^....$$/ { print $$1."0" } /^.....$$/ { print $$1 }') CXXFLAGS += $(shell tntnet-config --cxxflags) LIBS += $(shell tntnet-config --libs) ### Optional configuration features PLUGINFEATURES = ifneq ($(HAVE_LIBPCRECPP),) PLUGINFEATURES += -DHAVE_LIBPCRECPP CXXFLAGS += $(shell pcre-config --cflags) LIBS += $(HAVE_LIBPCRECPP) endif ### export all vars for sub-makes, using absolute paths LIBDIR := $(shell cd $(LIBDIR) >/dev/null 2>&1 && pwd) LOCDIR := $(shell cd $(LOCDIR) >/dev/null 2>&1 && pwd) export unexport PLUGIN ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) ### The name of the shared object file: SOFILE = libvdr-$(PLUGIN).so ### Includes and Defines (add further entries here): DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -DTNTVERSION=$(TNTVERSION) -DCXXTOOLVER=$(CXXTOOLVER) SUBDIRS = pages css javascript VERSIONSUFFIX = gen_version_suffix.h ### The object files (add further files here): PLUGINOBJS = $(PLUGIN).o thread.o tntconfig.o setup.o i18n.o timers.o \ tools.o recman.o tasks.o status.o epg_events.o epgsearch.o \ grab.o md5.o filecache.o livefeatures.o preload.o timerconflict.o \ users.o WEBLIBS = pages/libpages.a css/libcss.a javascript/libjavascript.a ### The main target: all: $(SOFILE) i18n ### Implicit rules: %.o: %.cpp $(CXX) $(CXXFLAGS) -c $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(PLUGINFEATURES) $(INCLUDES) $(PLUGINOBJS:%.o=%.cpp) > $@ ifneq ($(MAKECMDGOALS),clean) -include $(DEPFILE) endif ### Internationalization (I18N): PODIR = po I18Npo = $(wildcard $(PODIR)/*.po) I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po msgfmt -c -o $@ $< $(I18Npot): PAGES $(PLUGINOBJS:%.o=%.cpp) xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --omit-header -o $@ $(PLUGINOBJS:%.o=%.cpp) pages/*.cpp setup.h epg_events.h %.po: $(I18Npot) msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Nmo) $(I18Npot) install-i18n: $(I18Nmsgs) ### Targets: PAGES: $(MAKE) -C pages PLUGINFEATURES="$(PLUGINFEATURES)" .dependencies $(VERSIONSUFFIX): FORCE ./buildutil/version-util $(VERSIONSUFFIX) || ./buildutil/version-util -F $(VERSIONSUFFIX) $(SOFILE): $(VERSIONSUFFIX) $(SUBDIRS) $(PLUGINOBJS) for SUBDIR in $(SUBDIRS); \ do $(MAKE) -C $${SUBDIR} PLUGINFEATURES="$(PLUGINFEATURES)" all; \ done $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGINOBJS) -Wl,--whole-archive $(WEBLIBS) -Wl,--no-whole-archive $(LIBS) -o $@ install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install: install-lib install-i18n dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @tar czf $(TMPDIR)/$(PACKAGE).tar.gz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @echo Distribution package created as $(TMPDIR)/$(PACKAGE).tar.gz clean: $(SUBDIRS) for SUBDIR in $(SUBDIRS); \ do $(MAKE) -C $${SUBDIR} clean; \ done @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot @-rm -f $(PLUGINOBJS) $(DEPFILE) *.so *.tgz core* *~ @-rm -f $(VERSIONSUFFIX) .PRECIOUS: $(I18Npo) FORCE: vdr-plugin-live/epgsearch/0000755000175000017500000000000012650773437015405 5ustar tobiastobiasvdr-plugin-live/epgsearch/services.h0000644000175000017500000001530312650773437017403 0ustar tobiastobias/* Copyright (C) 2004-2008 Christian Wieninger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef EPGSEARCHSERVICES_INC #define EPGSEARCHSERVICES_INC #include #include #include #include #include // Data structure for service "Epgsearch-search-v1.0" struct Epgsearch_search_v1_0 { // in char* query; // search term int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression) int channelNr; // channel number to search in (0=any) bool useTitle; // search in title bool useSubTitle; // search in subtitle bool useDescription; // search in description // out cOsdMenu* pResultMenu; // pointer to the menu of results }; // Data structure for service "Epgsearch-exttimeredit-v1.0" struct Epgsearch_exttimeredit_v1_0 { // in cTimer* timer; // pointer to the timer to edit bool bNew; // flag that indicates, if this is a new timer or an existing one const cEvent* event; // pointer to the event corresponding to this timer (may be NULL) // out cOsdMenu* pTimerMenu; // pointer to the menu of results }; // Data structure for service "Epgsearch-updatesearchtimers-v1.0" struct Epgsearch_updatesearchtimers_v1_0 { // in bool showMessage; // inform via osd when finished? }; // Data structure for service "Epgsearch-osdmessage-v1.0" struct Epgsearch_osdmessage_v1_0 { // in char* message; // the message to display eMessageType type; }; // Data structure for service "EpgsearchMenu-v1.0" struct EpgSearchMenu_v1_0 { // in // out cOsdMenu* Menu; // pointer to the menu }; // Data structure for service "Epgsearch-lastconflictinfo-v1.0" struct Epgsearch_lastconflictinfo_v1_0 { // in // out time_t nextConflict; // next conflict date, 0 if none int relevantConflicts; // number of relevant conflicts int totalConflicts; // total number of conflicts }; // Data structure for service "Epgsearch-searchresults-v1.0" struct Epgsearch_searchresults_v1_0 { // in char* query; // search term int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression) int channelNr; // channel number to search in (0=any) bool useTitle; // search in title bool useSubTitle; // search in subtitle bool useDescription; // search in description // out class cServiceSearchResult : public cListObject { public: const cEvent* event; cServiceSearchResult(const cEvent* Event) : event(Event) {} }; cList* pResultList; // pointer to the results }; // Data structure for service "Epgsearch-switchtimer-v1.0" struct Epgsearch_switchtimer_v1_0 { // in const cEvent* event; int mode; // mode (0=query existance, 1=add/modify, 2=delete) // in/out int switchMinsBefore; int announceOnly; // out bool success; // result }; // Data structures for service "Epgsearch-services-v1.0" class cServiceHandler { public: virtual std::list SearchTimerList() = 0; // returns a list of search timer entries in the same format as used in epgsearch.conf virtual int AddSearchTimer(const std::string&) = 0; // adds a new search timer and returns its ID (-1 on error) virtual bool ModSearchTimer(const std::string&) = 0; // edits an existing search timer and returns success virtual bool DelSearchTimer(int) = 0; // deletes search timer with given ID and returns success virtual std::list QuerySearchTimer(int) = 0; // returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL) virtual std::list QuerySearch(std::string) = 0; // returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL) virtual std::list ExtEPGInfoList() = 0; // returns a list of extended EPG categories in the same format as used in epgsearchcats.conf virtual std::list ChanGrpList() = 0; // returns a list of channel groups maintained by epgsearch virtual std::list BlackList() = 0; // returns a list of blacklists in the same format as used in epgsearchblacklists.conf virtual std::set DirectoryList() = 0; // List of all recording directories used in recordings, timers, search timers or in epgsearchdirs.conf virtual ~cServiceHandler() {} // Read a setup value virtual std::string ReadSetupValue(const std::string& entry) = 0; // Write a setup value virtual bool WriteSetupValue(const std::string& entry, const std::string& value) = 0; }; struct Epgsearch_services_v1_0 { // in/out std::auto_ptr handler; }; // Data structures for service "Epgsearch-services-v1.1" class cServiceHandler_v1_1 : public cServiceHandler { public: // Get timer conflicts virtual std::list TimerConflictList(bool relOnly=false) = 0; // Check if a conflict check is advised virtual bool IsConflictCheckAdvised() = 0; }; struct Epgsearch_services_v1_1 { // in/out std::auto_ptr handler; }; // Data structures for service "Epgsearch-services-v1.2" class cServiceHandler_v1_2 : public cServiceHandler_v1_1 { public: // List of all recording directories used in recordings, timers (and optionally search timers or in epgsearchdirs.conf) virtual std::set ShortDirectoryList() = 0; // Evaluate an expression against an event virtual std::string Evaluate(const std::string& expr, const cEvent* event) = 0; }; struct Epgsearch_services_v1_2 { // in/out std::auto_ptr handler; }; #endif vdr-plugin-live/HISTORY0000644000175000017500000000051312650773437014527 0ustar tobiastobiasVDR Plugin 'live' Revision History ----------------------------------- 2007-01-01: Version 0.0.1 - Initial revision. 2007-05-28: Version 0.1.0 - First release. 2008-04-30: Version 0.2.0 - Version 0.2.0 2013-03-24: Version 0.3.0 - Declares GIT-Tree as new stable version. See http://live.vdr-developer.org about details. vdr-plugin-live/tasks.h0000644000175000017500000000535512650773437014752 0ustar tobiastobias#ifndef VDR_LIVE_TASKS_H #define VDR_LIVE_TASKS_H #include #include #include #include #include namespace vdrlive { class Task; class TaskManager: public cMutex { friend TaskManager& LiveTaskManager(); friend class StickyTask; typedef std::vector< Task* > TaskList; public: bool Execute( Task& task ); // may only be called from Plugin::MainThreadHook void DoScheduledTasks(); private: TaskManager(); TaskManager( TaskManager const& ); void AddStickyTask( Task& task ); void RemoveStickyTask( Task& task ); TaskList m_taskQueue; TaskList m_stickyTasks; cCondVar m_scheduleWait; }; class Task { friend void TaskManager::DoScheduledTasks(); public: virtual ~Task() {} bool Result() const { return m_result; } std::string const& Error() const { return m_error; } protected: explicit Task() : m_result( true ) {} Task( Task const& ); void SetError( std::string const& error ) { m_result = false; m_error = error; } private: bool m_result; std::string m_error; virtual void Action() = 0; }; class StickyTask: public Task { protected: explicit StickyTask(); virtual ~StickyTask(); }; class SwitchChannelTask: public Task { public: explicit SwitchChannelTask( tChannelID channel ): m_channel( channel ) {} private: tChannelID m_channel; virtual void Action(); }; class RecordingTask: public Task { protected: explicit RecordingTask(std::string const& recording) : m_recording(recording) {} std::string m_recording; }; class PlayRecordingTask: public RecordingTask { public: explicit PlayRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); }; class PauseRecordingTask: public RecordingTask { public: explicit PauseRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); }; class StopRecordingTask: public RecordingTask { public: explicit StopRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); }; class ForwardRecordingTask: public RecordingTask { public: explicit ForwardRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); }; class BackwardRecordingTask: public RecordingTask { public: explicit BackwardRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); }; class RemoveRecordingTask: public RecordingTask { public: explicit RemoveRecordingTask( std::string const& recording ) : RecordingTask(recording) {} virtual void Action(); std::string const & RecName() const { return m_recName; } private: std::string m_recName; }; TaskManager& LiveTaskManager(); } // namespace vdrlive #endif // VDR_LIVE_TASKS_H vdr-plugin-live/cache.h0000644000175000017500000000664112650773437014667 0ustar tobiastobias#ifndef VGSTOOLS_CACHE_H #define VGSTOOLS_CACHE_H #include #include #include #include #include #include #include #include "stdext.h" /* Interface for TValue: * size_t weight() * bool is_newer( time_t ) * bool load() * */ namespace vgstools { template< typename TKey, typename TValue, typename KeyComp = std::less< TKey > > class cache { public: typedef TKey key_type; typedef TValue mapped_type; typedef std::tr1::shared_ptr< mapped_type > ptr_type; private: /*struct Value { key_type key_; ptr_type value_; Value( key_type const& key, ptr_type const& value ) : key_( key ) , value_( value ) {} };*/ typedef std::pair< key_type, ptr_type > value_type; typedef std::list< value_type > ValueList; typedef std::map< key_type, typename ValueList::iterator, KeyComp > KeyMap; public: cache( size_t maxWeight ) : m_maxWeight( maxWeight ) , m_currentWeight( 0 ) {} size_t weight() const { return m_currentWeight; } size_t count() const { return m_values.size(); } ptr_type get( key_type const& key ) { assert( m_lookup.size() == m_values.size() ); typename KeyMap::iterator it = m_lookup.find( key ); ptr_type result = it != m_lookup.end() ? it->second->second : ptr_type( new mapped_type( key ) ); if ( it != m_lookup.end() ) { if ( result->is_current() ) { if ( it->second != m_values.begin() ) { m_values.erase( it->second ); it->second = m_values.insert( m_values.begin(), std::make_pair( key, result ) ); } return result; } m_currentWeight -= result->weight(); m_values.erase( it->second ); //m_lookup.erase( it ); } if ( !result->load() ) { if ( it != m_lookup.end() ) m_lookup.erase( it ); return ptr_type(); } // put new object into cache if ( result->weight() < m_maxWeight ) { m_currentWeight += result->weight(); typename ValueList::iterator element = m_values.insert( m_values.begin(), std::make_pair( key, result ) ); if ( it != m_lookup.end() ) it->second = element; else m_lookup.insert( std::make_pair( key, element ) ); while ( m_currentWeight > m_maxWeight ) { value_type& value = m_values.back(); m_currentWeight -= value.second->weight(); m_lookup.erase( m_lookup.find( value.first ) ); m_values.pop_back(); } } return result; #if 0 typename KeyMap::iterator it = m_lookup.find( key ); if ( it == m_lookup.end() ) { typename ValueList::iterator element = m_values.insert( m_values.begin(), Value( key ) ); std::pair< typename KeyMap::iterator, bool > result = m_lookup.insert( std::make_pair( key, element ) ); it = result.first; } Value* value = &*it->second; std::time_t now = std::time( 0 ); if ( value->creation == 0 || !value->value->is_current() ) { m_currentWeight -= value->value->weight(); if ( !value->value->load() ) { m_values.erase( it->second ); m_lookup.erase( it ); return ptr_type(); } m_currentWeight += value->value->weight(); value->creation = now; } if ( it->second != m_values.begin() ) { typename ValueList::iterator element = m_values.insert( m_values.begin(), *it->second ); m_values.erase( it->second ); it->second = element; value = &*element; } return value->value; #endif } private: std::size_t m_maxWeight; std::size_t m_currentWeight; ValueList m_values; KeyMap m_lookup; }; } // namespace vgstools #endif // VGSTOOLS_CACHE_H vdr-plugin-live/recman.cpp0000644000175000017500000004527512650773437015432 0ustar tobiastobias#include #include #include #include #include #include #include "stdext.h" #include "tools.h" #include "epg_events.h" #include "recman.h" #define INDEXFILESUFFIX "/index.vdr" #define LENGTHFILESUFFIX "/length.vdr" using namespace std::tr1; using namespace std; namespace vdrlive { /** * Implementation of class RecordingsManager: */ weak_ptr< RecordingsManager > RecordingsManager::m_recMan; shared_ptr< RecordingsTree > RecordingsManager::m_recTree; shared_ptr< RecordingsList > RecordingsManager::m_recList; shared_ptr< DirectoryList > RecordingsManager::m_recDirs; int RecordingsManager::m_recordingsState = 0; // The RecordingsManager holds a VDR lock on the // Recordings. Additionally the singleton instance of // RecordingsManager is held in a weak pointer. If it is not in // use any longer, it will be freed automaticaly, which leads to a // release of the VDR recordings lock. Upon requesting access to // the RecordingsManager via LiveRecordingsManger function, first // the weak ptr is locked (obtaining a shared_ptr from an possible // existing instance) and if not successfull a new instance is // created, which again locks the VDR Recordings. // // RecordingsManager provides factory methods to obtain other // recordings data structures. The data structures returned keep if // needed the instance of RecordingsManager alive until destructed // themselfs. This way the use of LIVE::recordings is straight // forward and does hide the locking needs from the user. RecordingsManager::RecordingsManager() : m_recordingsLock(&Recordings) { } RecordingsTreePtr RecordingsManager::GetRecordingsTree() const { RecordingsManagerPtr recMan = EnsureValidData(); if (! recMan) { return RecordingsTreePtr(recMan, shared_ptr< RecordingsTree >()); } return RecordingsTreePtr(recMan, m_recTree); } RecordingsListPtr RecordingsManager::GetRecordingsList(bool ascending) const { RecordingsManagerPtr recMan = EnsureValidData(); if (! recMan) { return RecordingsListPtr(recMan, shared_ptr< RecordingsList >()); } return RecordingsListPtr(recMan, shared_ptr< RecordingsList >(new RecordingsList(m_recList, ascending))); } RecordingsListPtr RecordingsManager::GetRecordingsList(time_t begin, time_t end, bool ascending) const { RecordingsManagerPtr recMan = EnsureValidData(); if (! recMan) { return RecordingsListPtr(recMan, shared_ptr< RecordingsList >()); } return RecordingsListPtr(recMan, shared_ptr< RecordingsList >(new RecordingsList(m_recList, ascending))); } DirectoryListPtr RecordingsManager::GetDirectoryList() const { RecordingsManagerPtr recMan = EnsureValidData(); if (!recMan) { return DirectoryListPtr(recMan, shared_ptr< DirectoryList >()); } return DirectoryListPtr(recMan, m_recDirs); } string RecordingsManager::Md5Hash(cRecording const * recording) const { return "recording_" + MD5Hash(recording->FileName()); } cRecording const * RecordingsManager::GetByMd5Hash(string const & hash) const { if (!hash.empty()) { for (cRecording* rec = Recordings.First(); rec; rec = Recordings.Next(rec)) { if (hash == Md5Hash(rec)) return rec; } } return 0; } bool RecordingsManager::MoveRecording(cRecording const * recording, string const & name, bool copy) const { if (!recording) return false; string oldname = recording->FileName(); size_t found = oldname.find_last_of("/"); if (found == string::npos) return false; #if APIVERSNUM > 20101 string newname = string(cVideoDirectory::Name()) + "/" + name + oldname.substr(found); #else string newname = string(VideoDirectory) + "/" + name + oldname.substr(found); #endif if (!MoveDirectory(oldname.c_str(), newname.c_str(), copy)) { esyslog("[LIVE]: renaming failed from '%s' to '%s'", oldname.c_str(), newname.c_str()); return false; } if (!copy) Recordings.DelByName(oldname.c_str()); Recordings.AddByName(newname.c_str()); cRecordingUserCommand::InvokeCommand(*cString::sprintf("rename \"%s\"", *strescape(oldname.c_str(), "\\\"$'")), newname.c_str()); return true; } void RecordingsManager::DeleteResume(cRecording const * recording) const { if (!recording) return; //dsyslog("[LIVE]: deleting resume '%s'", recording->Name()); cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording()); ResumeFile.Delete(); } void RecordingsManager::DeleteMarks(cRecording const * recording) const { if (!recording) return; //dsyslog("[LIVE]: deleting marks '%s'", recording->Name()); cMarks marks; marks.Load(recording->FileName()); if (marks.Count()) { cMark *mark = marks.First(); while (mark) { cMark *nextmark = marks.Next(mark); marks.Del(mark); mark = nextmark; } marks.Save(); } } void RecordingsManager::DeleteRecording(cRecording const * recording) const { if (!recording) return; string name(recording->FileName()); const_cast(recording)->Delete(); Recordings.DelByName(name.c_str()); } int RecordingsManager::GetArchiveType(cRecording const * recording) { string filename = recording->FileName(); string dvdFile = filename + "/dvd.vdr"; if (0 == access(dvdFile.c_str(), R_OK)) { return 1; } string hddFile = filename + "/hdd.vdr"; if (0 == access(hddFile.c_str(), R_OK)) { return 2; } return 0; } string const RecordingsManager::GetArchiveId(cRecording const * recording, int archiveType) { string filename = recording->FileName(); if (archiveType==1) { string dvdFile = filename + "/dvd.vdr"; ifstream dvd(dvdFile.c_str()); if (dvd) { string archiveDisc; string videoDisc; dvd >> archiveDisc; if ("0000" == archiveDisc) { dvd >> videoDisc; return videoDisc; } return archiveDisc; } } else if(archiveType==2) { string hddFile = filename + "/hdd.vdr"; ifstream hdd(hddFile.c_str()); if (hdd) { string archiveDisc; hdd >> archiveDisc; return archiveDisc; } } return ""; } string const RecordingsManager::GetArchiveDescr(cRecording const * recording) { int archiveType; string archived; archiveType = GetArchiveType(recording); if (archiveType==1) { archived += " ["; archived += tr("On archive DVD No."); archived += ": "; archived += GetArchiveId(recording, archiveType); archived += "]"; } else if (archiveType==2) { archived += " ["; archived += tr("On archive HDD No."); archived += ": "; archived += GetArchiveId(recording, archiveType); archived += "]"; } return archived; } RecordingsManagerPtr RecordingsManager::EnsureValidData() { // Get singleton instance of RecordingsManager. 'this' is not // an instance of shared_ptr of the singleton // RecordingsManager, so we obtain it in the overall // recommended way. RecordingsManagerPtr recMan = LiveRecordingsManager(); if (! recMan) { // theoretically this code is never reached ... esyslog("[LIVE]: lost RecordingsManager instance while using it!"); return RecordingsManagerPtr(); } // StateChanged must be executed every time, so not part of // the short cut evaluation in the if statement below. bool stateChanged = Recordings.StateChanged(m_recordingsState); if (stateChanged || (!m_recTree) || (!m_recList) || (!m_recDirs)) { if (stateChanged) { m_recTree.reset(); m_recList.reset(); m_recDirs.reset(); } if (stateChanged || !m_recTree) { m_recTree = shared_ptr< RecordingsTree >(new RecordingsTree(recMan)); } if (!m_recTree) { esyslog("[LIVE]: creation of recordings tree failed!"); return RecordingsManagerPtr(); } if (stateChanged || !m_recList) { m_recList = shared_ptr< RecordingsList >(new RecordingsList(RecordingsTreePtr(recMan, m_recTree))); } if (!m_recList) { esyslog("[LIVE]: creation of recordings list failed!"); return RecordingsManagerPtr(); } if (stateChanged || !m_recDirs) { m_recDirs = shared_ptr< DirectoryList >(new DirectoryList(recMan)); } if (!m_recDirs) { esyslog("[LIVE]: creation of directory list failed!"); return RecordingsManagerPtr(); } } return recMan; } /** * Implemetation of class RecordingsItemPtrCompare */ bool RecordingsItemPtrCompare::ByAscendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second) { if (first->StartTime() < second->StartTime()) return true; return false; } bool RecordingsItemPtrCompare::ByDescendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second) { if (first->StartTime() < second->StartTime()) return false; return true; } bool RecordingsItemPtrCompare::ByAscendingName(RecordingsItemPtr & first, RecordingsItemPtr & second) { unsigned int i = 0; while (i < first->Name().length() && i < second->Name().length()) { if (tolower((first->Name())[i]) < tolower((second->Name())[i])) return true; else if (tolower((first->Name())[i]) > tolower((second->Name())[i])) return false; ++i; } if (first->Name().length() < second->Name().length()) return true; return false; } bool RecordingsItemPtrCompare::ByDescendingName(RecordingsItemPtr & first, RecordingsItemPtr & second) { unsigned int i = 0; while (i < first->Name().length() && i < second->Name().length()) { if (tolower((second->Name())[i]) < tolower((first->Name())[i])) return true; else if (tolower((second->Name())[i]) > tolower((first->Name())[i])) return false; ++i; } if (second->Name().length() < first->Name().length()) return true; return false; } /** * Implementation of class RecordingsItem: */ RecordingsItem::RecordingsItem(string const & name, RecordingsItemPtr parent) : m_name(name), m_entries(), m_parent(parent) { } RecordingsItem::~RecordingsItem() { } /** * Implementation of class RecordingsItemDir: */ RecordingsItemDir::RecordingsItemDir(const string& name, int level, RecordingsItemPtr parent) : RecordingsItem(name, parent), m_level(level) { // dsyslog("REC: C: dir %s -> %s", name.c_str(), parent ? parent->Name().c_str() : "ROOT"); } RecordingsItemDir::~RecordingsItemDir() { // dsyslog("REC: D: dir %s", Name().c_str()); } /** * Implementation of class RecordingsItemRec: */ RecordingsItemRec::RecordingsItemRec(const string& id, const string& name, const cRecording* recording, RecordingsItemPtr parent) : RecordingsItem(name, parent), m_recording(recording), m_id(id) { // dsyslog("REC: C: rec %s -> %s", name.c_str(), parent->Name().c_str()); } RecordingsItemRec::~RecordingsItemRec() { // dsyslog("REC: D: rec %s", Name().c_str()); } time_t RecordingsItemRec::StartTime() const { return m_recording->Start(); } long RecordingsItemRec::Duration() const { long RecLength = 0; if (!m_recording->FileName()) return 0; return m_recording->LengthInSeconds() / 60; if (RecLength == 0) { cString lengthFile = cString::sprintf("%s%s", m_recording->FileName(), LENGTHFILESUFFIX); ifstream length(*lengthFile); if(length) length >> RecLength; } return RecLength; } /** * Implementation of class RecordingsTree: */ RecordingsTree::RecordingsTree(RecordingsManagerPtr recMan) : m_maxLevel(0), m_root(new RecordingsItemDir("", 0, RecordingsItemPtr())) { // esyslog("DH: ****** RecordingsTree::RecordingsTree() ********"); for (cRecording* recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { if (m_maxLevel < recording->HierarchyLevels()) { m_maxLevel = recording->HierarchyLevels(); } RecordingsItemPtr dir = m_root; string name(recording->Name()); // esyslog("DH: recName = '%s'", recording->Name()); int level = 0; size_t index = 0; size_t pos = 0; do { pos = name.find('~', index); if (pos != string::npos) { string dirName(name.substr(index, pos - index)); index = pos + 1; RecordingsMap::iterator i = findDir(dir, dirName); if (i == dir->m_entries.end()) { RecordingsItemPtr recPtr (new RecordingsItemDir(dirName, level, dir)); dir->m_entries.insert(pair< string, RecordingsItemPtr > (dirName, recPtr)); i = findDir(dir, dirName); if (i != dir->m_entries.end()) { // esyslog("DH: added dir: '%s'", dirName.c_str()); } else { // esyslog("DH: panic: didn't found inserted dir: '%s'", dirName.c_str()); } } dir = i->second; // esyslog("DH: current dir: '%s'", dir->Name().c_str()); level++; } else { string recName(name.substr(index, name.length() - index)); RecordingsItemPtr recPtr (new RecordingsItemRec(recMan->Md5Hash(recording), recName, recording, dir)); dir->m_entries.insert(pair< string, RecordingsItemPtr > (recName, recPtr)); // esyslog("DH: added rec: '%s'", recName.c_str()); } } while (pos != string::npos); } // esyslog("DH: ------ RecordingsTree::RecordingsTree() --------"); } RecordingsTree::~RecordingsTree() { // esyslog("DH: ****** RecordingsTree::~RecordingsTree() ********"); } RecordingsMap::iterator RecordingsTree::begin(const vector< string >& path) { if (path.empty()) { return m_root->m_entries.begin(); } RecordingsItemPtr recItem = m_root; for (vector< string >::const_iterator i = path.begin(); i != path.end(); ++i) { pair< RecordingsMap::iterator, RecordingsMap::iterator> range = recItem->m_entries.equal_range(*i); for (RecordingsMap::iterator iter = range.first; iter != range.second; ++iter) { if (iter->second->IsDir()) { recItem = iter->second; break; } } } return recItem->m_entries.begin(); } RecordingsMap::iterator RecordingsTree::end(const vector< string >&path) { if (path.empty()) { return m_root->m_entries.end(); } RecordingsItemPtr recItem = m_root; for (vector< string >::const_iterator i = path.begin(); i != path.end(); ++i) { pair< RecordingsMap::iterator, RecordingsMap::iterator> range = recItem->m_entries.equal_range(*i); for (RecordingsMap::iterator iter = range.first; iter != range.second; ++iter) { if (iter->second->IsDir()) { recItem = iter->second; break; } } } return recItem->m_entries.end(); } RecordingsMap::iterator RecordingsTree::findDir(RecordingsItemPtr& dir, const string& dirName) { pair< RecordingsMap::iterator, RecordingsMap::iterator > range = dir->m_entries.equal_range(dirName); for (RecordingsMap::iterator i = range.first; i != range.second; ++i) { if (i->second->IsDir()) { return i; } } return dir->m_entries.end(); } /** * Implementation of class RecordingsTreePtr: */ RecordingsTreePtr::RecordingsTreePtr() : shared_ptr(), m_recManPtr() { } RecordingsTreePtr::RecordingsTreePtr(RecordingsManagerPtr recManPtr, std::tr1::shared_ptr< RecordingsTree > recTree) : shared_ptr(recTree), m_recManPtr(recManPtr) { } RecordingsTreePtr::~RecordingsTreePtr() { } /** * Implementation of class RecordingsList: */ RecordingsList::RecordingsList(RecordingsTreePtr recTree) : m_pRecVec(new RecVecType()) { if (!m_pRecVec) { return; } stack< RecordingsItemPtr > treeStack; treeStack.push(recTree->Root()); while (!treeStack.empty()) { RecordingsItemPtr current = treeStack.top(); treeStack.pop(); for (RecordingsMap::const_iterator iter = current->begin(); iter != current->end(); ++iter) { RecordingsItemPtr recItem = iter->second; if (recItem->IsDir()) { treeStack.push(recItem); } else { m_pRecVec->push_back(recItem); } } } } RecordingsList::RecordingsList(shared_ptr< RecordingsList > recList, bool ascending) : m_pRecVec(new RecVecType(recList->size())) { if (!m_pRecVec) { return; } if (ascending) { partial_sort_copy(recList->begin(), recList->end(), m_pRecVec->begin(), m_pRecVec->end(), Ascending()); } else { partial_sort_copy(recList->begin(), recList->end(), m_pRecVec->begin(), m_pRecVec->end(), Descending()); } } RecordingsList::RecordingsList(shared_ptr< RecordingsList > recList, time_t begin, time_t end, bool ascending) : m_pRecVec(new RecVecType()) { if (end > begin) { return; } if (!m_pRecVec) { return; } remove_copy_if(recList->begin(), recList->end(), m_pRecVec->end(), NotInRange(begin, end)); if (ascending) { sort(m_pRecVec->begin(), m_pRecVec->end(), Ascending()); } else { sort(m_pRecVec->begin(), m_pRecVec->end(), Descending()); } } RecordingsList::~RecordingsList() { if (m_pRecVec) { delete m_pRecVec, m_pRecVec = 0; } } RecordingsList::NotInRange::NotInRange(time_t begin, time_t end) : m_begin(begin), m_end(end) { } bool RecordingsList::NotInRange::operator()(RecordingsItemPtr const &x) const { return (x->StartTime() < m_begin) || (m_end >= x->StartTime()); } /** * Implementation of class RecordingsList: */ RecordingsListPtr::RecordingsListPtr(RecordingsManagerPtr recManPtr, shared_ptr< RecordingsList > recList) : shared_ptr< RecordingsList >(recList), m_recManPtr(recManPtr) { } RecordingsListPtr::~RecordingsListPtr() { } /** * Implementation of class DirectoryList: */ DirectoryList::DirectoryList(RecordingsManagerPtr recManPtr) : m_pDirVec(new DirVecType()) { if (!m_pDirVec) { return; } m_pDirVec->push_back(""); // always add root directory for (cNestedItem* item = Folders.First(); item; item = Folders.Next(item)) { // add folders.conf entries InjectFoldersConf(item); } for (cRecording* recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { string name = recording->Name(); size_t found = name.find_last_of("~"); if (found != string::npos) { m_pDirVec->push_back(StringReplace(name.substr(0, found), "~", "/")); } } m_pDirVec->sort(); m_pDirVec->unique(); } DirectoryList::~DirectoryList() { if (m_pDirVec) { delete m_pDirVec, m_pDirVec = 0; } } void DirectoryList::InjectFoldersConf(cNestedItem * folder, string parent) { if (!folder) { return; } string dir = string((parent.size() == 0) ? "" : parent + "/") + folder->Text(); m_pDirVec->push_back(StringReplace(dir, "_", " ")); if (!folder->SubItems()) { return; } for(cNestedItem* item = folder->SubItems()->First(); item; item = folder->SubItems()->Next(item)) { InjectFoldersConf(item, dir); } } /** * Implementation of class DirectoryListPtr: */ DirectoryListPtr::DirectoryListPtr(RecordingsManagerPtr recManPtr, shared_ptr< DirectoryList > recDirs) : shared_ptr< DirectoryList >(recDirs), m_recManPtr(recManPtr) { } DirectoryListPtr::~DirectoryListPtr() { } /** * Implementation of function LiveRecordingsManager: */ RecordingsManagerPtr LiveRecordingsManager() { RecordingsManagerPtr r = RecordingsManager::m_recMan.lock(); if (r) { return r; } else { RecordingsManagerPtr n(new RecordingsManager); RecordingsManager::m_recMan = n; return n; } } } // namespace vdrlive vdr-plugin-live/tools.cpp0000644000175000017500000003522112650773437015313 0ustar tobiastobias#include #include #include #include #include #include #include #include #include "exception.h" #include "live.h" #include "setup.h" #include "tools.h" #include "md5.h" using namespace std; using namespace tnt; istream& operator>>( istream& is, tChannelID& ret ) { /* alternativ implementation string line; if ( !getline( is, line ) ) { if ( !is.eof() ) is.setstate( ios::badbit ); else is.clear(); return is; } if ( !line.empty() && !( ret = tChannelID::FromString( line.c_str() ) ).Valid() ) is.setstate( ios::badbit ); return is; */ string line; if (!getline( is, line ) ) { if (0 == is.gcount()) { is.clear(is.rdstate() & ~ios::failbit); return is; } if (!is.eof()) { is.setstate( ios::badbit ); return is; } } if ( !line.empty() && !( ret = tChannelID::FromString( line.c_str() ) ).Valid() ) is.setstate( ios::badbit ); return is; } namespace vdrlive { string FormatDuration( char const* format, int hours, int minutes ) { char result[ 32 ]; if ( snprintf(result, sizeof(result), format, hours, minutes) < 0 ) { ostringstream builder; builder << "cannot represent duration " << hours << ":" << minutes << " as requested"; throw runtime_error( builder.str() ); } return result; } string FormatDateTime( char const* format, time_t time ) { struct tm tm_r; if ( localtime_r( &time, &tm_r ) == 0 ) { ostringstream builder; builder << "cannot represent timestamp " << time << " as local time"; throw runtime_error( builder.str() ); } char result[ 256 ]; if ( strftime( result, sizeof( result ), format, &tm_r ) == 0 ) { ostringstream builder; builder << "representation of timestamp " << time << " exceeds " << sizeof( result ) << " bytes"; throw runtime_error( builder.str() ); } return result; } string StringReplace( string const& text, string const& substring, string const& replacement ) { string result = text; string::size_type pos = 0; while ( ( pos = result.find( substring, pos ) ) != string::npos ) { result.replace( pos, substring.length(), replacement ); pos += replacement.length(); } return result; } vector< string > StringSplit( string const& text, char delimiter ) { vector< string > result; string::size_type last = 0, pos; while ( ( pos = text.find( delimiter, last ) ) != string::npos ) { result.push_back( text.substr( last, pos - last ) ); last = pos + 1; } if ( last < text.length() ) result.push_back( text.substr( last ) ); return result; } int StringToInt( std::string const& string, int base ) { char* end; int result = strtol( string.c_str(), &end, base ); if ( *end == '\0' ) return result; return 0; } string StringRepeat(int times, const string& input) { string result; for (int i = 0; i < times; i++) { result += input; } return result; } string StringWordTruncate(const string& input, size_t maxLen, bool& truncated) { if (input.length() <= maxLen) { truncated = false; return input; } truncated = true; string result = input.substr(0, maxLen); size_t pos = result.find_last_of(" \t,;:.\n?!'\"/\\()[]{}*+-"); return result.substr(0, pos); } string StringFormatBreak(string const& input) { return StringReplace( input, "\n", "
    " ); } string StringEscapeAndBreak( string const& input ) { stringstream plainBuilder; HtmlEscOstream builder( plainBuilder ); builder << input; return StringReplace( plainBuilder.str(), "\n", "
    " ); } string StringTrim(string const& str) { string res = str; string::size_type pos = res.find_last_not_of(' '); if(pos != string::npos) { res.erase(pos + 1); pos = res.find_first_not_of(' '); if(pos != string::npos) res.erase(0, pos); } else res.erase(res.begin(), res.end()); return res; } string ZeroPad(int number) { ostringstream os; os << setw(2) << setfill('0') << number; return os.str(); } std::string MD5Hash(std::string const& str) { char* szInput = strdup(str.c_str()); if (!szInput) return ""; char* szRes = MD5String(szInput); string res = szRes; free(szRes); return res; /* unsigned char md5[MD5_DIGEST_LENGTH]; MD5(reinterpret_cast(str.c_str()), str.size(), md5); ostringstream hashStr; hashStr << hex; for (size_t i = 0; i < MD5_DIGEST_LENGTH; i++) hashStr << (0 + md5[i]); return hashStr.str(); */ } #define HOURS(x) ((x)/100) #define MINUTES(x) ((x)%100) std::string ExpandTimeString(std::string timestring) { string::size_type colonpos = timestring.find(":"); if (colonpos == string::npos) { if (timestring.size() == 1) timestring = "0" + timestring + ":00"; else if (timestring.size() == 2) timestring = timestring + ":00"; else if (timestring.size() == 3) timestring = "0" + string(timestring.begin(), timestring.begin() + 1) + ":" + string(timestring.begin() + 1, timestring.end()); else timestring = string(timestring.begin(), timestring.begin() + 2) + ":" + string(timestring.begin() + 2, timestring.end()); } else { string hours = string(timestring.begin(), timestring.begin() + colonpos); string mins = string(timestring.begin() + colonpos + 1, timestring.end()); hours = string(std::max(0,(int)(2 - hours.size())), '0') + hours; mins = string(std::max(0,(int)(2 - mins.size())), '0') + mins; timestring = hours + ":" + mins; } return timestring; } time_t GetTimeT(std::string timestring) // timestring in HH:MM { timestring = StringReplace(timestring, ":", ""); int iTime = lexical_cast< int >( timestring ); struct tm tm_r; time_t t = time(NULL); tm* tmnow = localtime_r(&t, &tm_r); tmnow->tm_hour = HOURS(iTime); tmnow->tm_min = MINUTES(iTime); return mktime(tmnow); } struct urlencoder { ostream& ostr_; urlencoder( ostream& ostr ): ostr_( ostr ) {} void operator()( char ch ) { static const char allowedChars[] = { // 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , A , B , C , D , E , F , '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', //00 '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', //10 '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', 0x2D,0x2E,0x2F, //20 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,'_', '_', '_', '_', '_', '_', //30 '_', 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, //40 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,'_', '_', '_', '_', '_', //50 '_', 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, //60 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,'_', '_', '_', '_', '_' //70 // everything above 127 (for signed char, below zero) is replaced with '_' }; if ( ch == ' ' ) ostr_ << '+'; else if ( static_cast< signed char >( ch ) < 0 || allowedChars[ size_t( ch ) ] == '_' ) ostr_ << '%' << setw( 2 ) << setfill( '0' ) << hex << int( static_cast< unsigned char >( ch ) ); else ostr_ << ch; } }; string StringUrlEncode( string const& input ) { ostringstream ostr; for_each( input.begin(), input.end(), urlencoder( ostr ) ); return ostr.str(); } // returns the content of ... string GetXMLValue( std::string const& xml, std::string const& element ) { string start = "<" + element + ">"; string end = ""; string::size_type startPos = xml.find(start); if (startPos == string::npos) return ""; string::size_type endPos = xml.find(end); if (endPos == string::npos) return ""; return xml.substr(startPos + start.size(), endPos - startPos - start.size()); } // return the time value as time_t from formatted with time_t GetDateFromDatePicker(std::string const& datestring, std::string const& format) { if (datestring.empty()) return 0; int year = lexical_cast< int >(datestring.substr(format.find("yyyy"), 4)); int month = lexical_cast< int >(datestring.substr(format.find("mm"), 2)); int day = lexical_cast< int >(datestring.substr(format.find("dd"), 2)); struct tm tm_r; tm_r.tm_year = year - 1900; tm_r.tm_mon = month -1; tm_r.tm_mday = day; tm_r.tm_hour = tm_r.tm_min = tm_r.tm_sec = 0; tm_r.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting return mktime(&tm_r); } // format is in datepicker format ('mm' for month, 'dd' for day, 'yyyy' for year) std::string DatePickerToC(time_t date, std::string const& format) { if (date == 0) return ""; std::string cformat = format; cformat = StringReplace(cformat, "mm", "%m"); cformat = StringReplace(cformat, "dd", "%d"); cformat = StringReplace(cformat, "yyyy", "%Y"); return FormatDateTime(cformat.c_str(), date); } std::string EncodeDomId(std::string const & toEncode, char const * from, char const * to) { std::string encoded = toEncode; for (; *from && *to; from++, to++) { replace(encoded.begin(), encoded.end(), *from, *to); } return encoded; } std::string DecodeDomId(std::string const & toDecode, char const * from, char const * to) { std::string decoded = toDecode; for (; *from && *to; from++, to++) { replace(decoded.begin(), decoded.end(), *from, *to); } return decoded; } std::string FileSystemExchangeChars(std::string const & s, bool ToFileSystem) { char *str = strdup(s.c_str()); str = ExchangeChars(str, ToFileSystem); std::string data = str; if (str) { free(str); } return data; } bool MoveDirectory(std::string const & sourceDir, std::string const & targetDir, bool copy) { const char* delim = "/"; std::string source = sourceDir; std::string target = targetDir; // add missing directory delimiters if (source.compare(source.size() - 1, 1, delim) != 0) { source += "/"; } if (target.compare(target.size() - 1, 1, delim) != 0) { target += "/"; } if (source != target) { // validate target directory if (target.find(source) != std::string::npos) { esyslog("[LIVE]: cannot move under sub-directory\n"); return false; } RemoveFileOrDir(target.c_str()); if (!MakeDirs(target.c_str(), true)) { esyslog("[LIVE]: cannot create directory %s", target.c_str()); return false; } struct stat st1, st2; stat(source.c_str(), &st1); stat(target.c_str(),&st2); if (!copy && (st1.st_dev == st2.st_dev)) { #if APIVERSNUM > 20101 if (!cVideoDirectory::RenameVideoFile(source.c_str(), target.c_str())) { #else if (!RenameVideoFile(source.c_str(), target.c_str())) { #endif esyslog("[LIVE]: rename failed from %s to %s", source.c_str(), target.c_str()); return false; } } else { int required = DirSizeMB(source.c_str()); int available = FreeDiskSpaceMB(target.c_str()); // validate free space if (required < available) { cReadDir d(source.c_str()); struct dirent *e; bool success = true; // allocate copying buffer const int len = 1024 * 1024; char *buffer = MALLOC(char, len); if (!buffer) { esyslog("[LIVE]: cannot allocate renaming buffer"); return false; } // loop through all files, but skip all subdirectories while ((e = d.Next()) != NULL) { // skip generic entries if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) { string sourceFile = source + e->d_name; string targetFile = target + e->d_name; // copy only regular files if (!stat(sourceFile.c_str(), &st1) && S_ISREG(st1.st_mode)) { int r = -1, w = -1; cUnbufferedFile *inputFile = cUnbufferedFile::Create(sourceFile.c_str(), O_RDONLY | O_LARGEFILE); cUnbufferedFile *outputFile = cUnbufferedFile::Create(targetFile.c_str(), O_RDWR | O_CREAT | O_LARGEFILE); // validate files if (!inputFile || !outputFile) { esyslog("[LIVE]: cannot open file %s or %s", sourceFile.c_str(), targetFile.c_str()); success = false; break; } // do actual copy dsyslog("[LIVE]: copying %s to %s", sourceFile.c_str(), targetFile.c_str()); do { r = inputFile->Read(buffer, len); if (r > 0) w = outputFile->Write(buffer, r); else w = 0; } while (r > 0 && w > 0); DELETENULL(inputFile); DELETENULL(outputFile); // validate result if (r < 0 || w < 0) { success = false; break; } } } } // release allocated buffer free(buffer); // delete all created target files and directories if (!success) { size_t found = target.find_last_of(delim); if (found != std::string::npos) { target = target.substr(0, found); } if (!RemoveFileOrDir(target.c_str(), true)) { esyslog("[LIVE]: cannot remove target %s", target.c_str()); } found = target.find_last_of(delim); if (found != std::string::npos) { target = target.substr(0, found); } if (!RemoveEmptyDirectories(target.c_str(), true)) { esyslog("[LIVE]: cannot remove target directory %s", target.c_str()); } esyslog("[LIVE]: copying failed"); return false; } else if (!copy && !RemoveFileOrDir(source.c_str(), true)) { // delete source files esyslog("[LIVE]: cannot remove source directory %s", source.c_str()); return false; } // delete all empty source directories if (!copy) { size_t found = source.find_last_of(delim); if (found != std::string::npos) { source = source.substr(0, found); #if APIVERSNUM > 20101 while (source != cVideoDirectory::Name()) { #else while (source != VideoDirectory) { #endif found = source.find_last_of(delim); if (found == std::string::npos) break; source = source.substr(0, found); if (!RemoveEmptyDirectories(source.c_str(), true)) break; } } } } else { esyslog("[LIVE]: %s requires %dMB - only %dMB available", copy ? "moving" : "copying", required, available); // delete all created empty target directories size_t found = target.find_last_of(delim); if (found != std::string::npos) { target = target.substr(0, found); #if APIVERSNUM > 20101 while (target != cVideoDirectory::Name()) { #else while (target != VideoDirectory) { #endif found = target.find_last_of(delim); if (found == std::string::npos) break; target = target.substr(0, found); if (!RemoveEmptyDirectories(target.c_str(), true)) break; } } return false; } } } return true; } } // namespace vdrlive