././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/0000755000175100001770000000000014640646230013107 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/MANIFEST.in0000644000175100001770000000015014640646222014642 0ustar00runnerdockerinclude setup.py README.md include doc/* include test/* include pywebdav/lib/*.py pywebdav/server/*.ini ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/PKG-INFO0000644000175100001770000000704514640646230014212 0ustar00runnerdockerMetadata-Version: 2.1 Name: PyWebDAV3 Version: 0.11.0 Summary: WebDAV library including a standalone server for python 3 Home-page: https://github.com/andrewleech/PyWebDAV3 Author: Andrew Leech (previously Simon Pamies) Author-email: andrew@alelec.net Maintainer: Andrew Leech (previously Simon Pamies) Maintainer-email: andrew@alelec.net License: LGPL v2 Keywords: webdav,server,dav,standalone,library,gpl,http,rfc2518,rfc 2518 Platform: Unix Platform: Windows Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries Requires-Dist: six PyWebDAV3 --------- PyWebDAV is a standards compliant WebDAV server and library written in Python PyWebDAV3 is an updated distribution for python 3 support. Python WebDAV implementation (level 1 and 2) that features a library that enables you to integrate WebDAV server capabilities to your application A fully working example on how to use the library is included. You can find the server in the DAVServer package. Upon installation a script called davserver is created in your $PYTHON/bin directory. DETAILS ------- Consists of a *server* that is ready to run Serve and the DAV package that provides WebDAV server(!) functionality. Currently supports * WebDAV level 1 * Level 2 (LOCK, UNLOCK) * Experimental iterator support It plays nice with * Mac OS X Finder * Windows Explorer * iCal * cadaver * Nautilus This package does *not* provide client functionality. INSTALLATION ------------ Installation and setup of server can be as easy as follows: ```sh pip install PyWebDAV3 davserver -D /tmp -n -J ``` After installation of this package you will have a new script in you $PYTHON/bin directory called *davserver*. This serves as the main entry point to the server. If you're living on the bleeding edge then check out the sourcecode from https://github.com/andrewleech/PyWebDAV3 After having downloaded code simply install a development egg: ```sh git clone https://github.com/andrewleech/PyWebDAV3 cd PyWebDAV3 python setup.py develop davserver --help ``` Any updates, fork and pull requests against my github page If you want to use the library then have a look at the DAVServer package that holds all code for a full blown server. Also doc/ARCHITECURE has information for you. QUESTIONS? ---------- Ask here https://github.com/andrewleech/PyWebDAV3 or send an email to the maintainer. REQUIREMENTS ------------ - Python 3.5 or higher (www.python.org) - PyXML 0.66 (pyxml.sourceforge.net) LICENSE ------- General Public License v2 see doc/LICENSE AUTHOR(s) --------- Andrew Leech [*] Melbourne, Australia andrew@alelec.net Simon Pamies Bielefeld, Germany s.pamies@banality.de Christian Scholz Aachen, Germany mrtopf@webdav.de Vince Spicer Ontario, Canada vince@vince.ca [*]: Current Maintainer OPTIONAL -------- - MySQLdb (http://sourceforge.net/projects/mysql-python) - Mysql server 4.0+ for Mysql authentication with with read/write access to one database NOTES ----- Look inside the file doc/TODO for things which needs to be done and may be done in the near future. Have a look at doc/ARCHITECTURE to understand what's going on under the hood version: 0.11.0 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/PyWebDAV3.egg-info/0000755000175100001770000000000014640646230016245 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/PKG-INFO0000644000175100001770000000704514640646230017350 0ustar00runnerdockerMetadata-Version: 2.1 Name: PyWebDAV3 Version: 0.11.0 Summary: WebDAV library including a standalone server for python 3 Home-page: https://github.com/andrewleech/PyWebDAV3 Author: Andrew Leech (previously Simon Pamies) Author-email: andrew@alelec.net Maintainer: Andrew Leech (previously Simon Pamies) Maintainer-email: andrew@alelec.net License: LGPL v2 Keywords: webdav,server,dav,standalone,library,gpl,http,rfc2518,rfc 2518 Platform: Unix Platform: Windows Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries Requires-Dist: six PyWebDAV3 --------- PyWebDAV is a standards compliant WebDAV server and library written in Python PyWebDAV3 is an updated distribution for python 3 support. Python WebDAV implementation (level 1 and 2) that features a library that enables you to integrate WebDAV server capabilities to your application A fully working example on how to use the library is included. You can find the server in the DAVServer package. Upon installation a script called davserver is created in your $PYTHON/bin directory. DETAILS ------- Consists of a *server* that is ready to run Serve and the DAV package that provides WebDAV server(!) functionality. Currently supports * WebDAV level 1 * Level 2 (LOCK, UNLOCK) * Experimental iterator support It plays nice with * Mac OS X Finder * Windows Explorer * iCal * cadaver * Nautilus This package does *not* provide client functionality. INSTALLATION ------------ Installation and setup of server can be as easy as follows: ```sh pip install PyWebDAV3 davserver -D /tmp -n -J ``` After installation of this package you will have a new script in you $PYTHON/bin directory called *davserver*. This serves as the main entry point to the server. If you're living on the bleeding edge then check out the sourcecode from https://github.com/andrewleech/PyWebDAV3 After having downloaded code simply install a development egg: ```sh git clone https://github.com/andrewleech/PyWebDAV3 cd PyWebDAV3 python setup.py develop davserver --help ``` Any updates, fork and pull requests against my github page If you want to use the library then have a look at the DAVServer package that holds all code for a full blown server. Also doc/ARCHITECURE has information for you. QUESTIONS? ---------- Ask here https://github.com/andrewleech/PyWebDAV3 or send an email to the maintainer. REQUIREMENTS ------------ - Python 3.5 or higher (www.python.org) - PyXML 0.66 (pyxml.sourceforge.net) LICENSE ------- General Public License v2 see doc/LICENSE AUTHOR(s) --------- Andrew Leech [*] Melbourne, Australia andrew@alelec.net Simon Pamies Bielefeld, Germany s.pamies@banality.de Christian Scholz Aachen, Germany mrtopf@webdav.de Vince Spicer Ontario, Canada vince@vince.ca [*]: Current Maintainer OPTIONAL -------- - MySQLdb (http://sourceforge.net/projects/mysql-python) - Mysql server 4.0+ for Mysql authentication with with read/write access to one database NOTES ----- Look inside the file doc/TODO for things which needs to be done and may be done in the near future. Have a look at doc/ARCHITECTURE to understand what's going on under the hood version: 0.11.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/SOURCES.txt0000644000175100001770000000200714640646230020130 0ustar00runnerdockerMANIFEST.in README.md setup.py PyWebDAV3.egg-info/PKG-INFO PyWebDAV3.egg-info/SOURCES.txt PyWebDAV3.egg-info/dependency_links.txt PyWebDAV3.egg-info/entry_points.txt PyWebDAV3.egg-info/requires.txt PyWebDAV3.egg-info/top_level.txt doc/ARCHITECTURE doc/Changes doc/INSTALL doc/LICENSE doc/TODO doc/interface_class doc/walker pywebdav/__init__.py pywebdav/__main__.py pywebdav/lib/AuthServer.py pywebdav/lib/INI_Parse.py pywebdav/lib/WebDAVServer.py pywebdav/lib/__init__.py pywebdav/lib/constants.py pywebdav/lib/davcmd.py pywebdav/lib/davcopy.py pywebdav/lib/davmove.py pywebdav/lib/dbconn.py pywebdav/lib/delete.py pywebdav/lib/errors.py pywebdav/lib/iface.py pywebdav/lib/locks.py pywebdav/lib/propfind.py pywebdav/lib/report.py pywebdav/lib/status.py pywebdav/lib/utils.py pywebdav/server/__init__.py pywebdav/server/config.ini pywebdav/server/daemonize.py pywebdav/server/fileauth.py pywebdav/server/fshandler.py pywebdav/server/mysqlauth.py pywebdav/server/server.py test/.gitignore test/litmus-0.13.tar.gz test/test_litmus.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/dependency_links.txt0000644000175100001770000000000114640646230022313 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/entry_points.txt0000644000175100001770000000007114640646230021541 0ustar00runnerdocker[console_scripts] davserver = pywebdav.server.server:run ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/requires.txt0000644000175100001770000000000414640646230020637 0ustar00runnerdockersix ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/PyWebDAV3.egg-info/top_level.txt0000644000175100001770000000001114640646230020767 0ustar00runnerdockerpywebdav ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/README.md0000644000175100001770000000510714640646222014372 0ustar00runnerdockerPyWebDAV3 --------- PyWebDAV is a standards compliant WebDAV server and library written in Python PyWebDAV3 is an updated distribution for python 3 support. Python WebDAV implementation (level 1 and 2) that features a library that enables you to integrate WebDAV server capabilities to your application A fully working example on how to use the library is included. You can find the server in the DAVServer package. Upon installation a script called davserver is created in your $PYTHON/bin directory. DETAILS ------- Consists of a *server* that is ready to run Serve and the DAV package that provides WebDAV server(!) functionality. Currently supports * WebDAV level 1 * Level 2 (LOCK, UNLOCK) * Experimental iterator support It plays nice with * Mac OS X Finder * Windows Explorer * iCal * cadaver * Nautilus This package does *not* provide client functionality. INSTALLATION ------------ Installation and setup of server can be as easy as follows: ```sh pip install PyWebDAV3 davserver -D /tmp -n -J ``` After installation of this package you will have a new script in you $PYTHON/bin directory called *davserver*. This serves as the main entry point to the server. If you're living on the bleeding edge then check out the sourcecode from https://github.com/andrewleech/PyWebDAV3 After having downloaded code simply install a development egg: ```sh git clone https://github.com/andrewleech/PyWebDAV3 cd PyWebDAV3 python setup.py develop davserver --help ``` Any updates, fork and pull requests against my github page If you want to use the library then have a look at the DAVServer package that holds all code for a full blown server. Also doc/ARCHITECURE has information for you. QUESTIONS? ---------- Ask here https://github.com/andrewleech/PyWebDAV3 or send an email to the maintainer. REQUIREMENTS ------------ - Python 3.5 or higher (www.python.org) - PyXML 0.66 (pyxml.sourceforge.net) LICENSE ------- General Public License v2 see doc/LICENSE AUTHOR(s) --------- Andrew Leech [*] Melbourne, Australia andrew@alelec.net Simon Pamies Bielefeld, Germany s.pamies@banality.de Christian Scholz Aachen, Germany mrtopf@webdav.de Vince Spicer Ontario, Canada vince@vince.ca [*]: Current Maintainer OPTIONAL -------- - MySQLdb (http://sourceforge.net/projects/mysql-python) - Mysql server 4.0+ for Mysql authentication with with read/write access to one database NOTES ----- Look inside the file doc/TODO for things which needs to be done and may be done in the near future. Have a look at doc/ARCHITECTURE to understand what's going on under the hood ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880856.0 pywebdav3-0.11.0/_version.py0000644000175100001770000000023214640646230015302 0ustar00runnerdocker# Version managed by git-versioner version = "0.11.0" version_short = "v0.11.0" git_hash = "4d46948" on_tag = '0.11.0' dirty = False SUPPORT_PATCH = True ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.158574 pywebdav3-0.11.0/doc/0000755000175100001770000000000014640646230013654 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/ARCHITECTURE0000644000175100001770000000541014640646222015462 0ustar00runnerdocker OVERVIEW -------- Here is a little overview of the package: A. In the pywebdav/lib/ package: 1. AuthHTTPServer This works on top of either the BasicHTTPServer or the BufferingHTTPServer and implements basic authentication. 2. WebDAVServer This server uses AuthHTTPServer for the base functionality. It also uses a dav interface class for interfacing with the actual data storage (e.g. a filesystem or a database). B. In the pywebdav/server/ directory: 1. server.py Main file for server. Serves as a start point for the WebDAV server 2. fshandler.py Backend for the DAV server. Makes him serving content from the filesystem. Have a deeper look at it if you want to implement backends to other data sources 3. fileauth.py Handler for authentication. Nothing very special about it. 4. dbconn.py Mysql Database Handler. 5. INI_Parse.py Parses the config.ini file. 6. config.ini PyWebDav configuration file. Information ---------- This document describes the architecture of the python davserver. The main programm is stored in pywebdav/lib/WebDAVServer.py. It exports a class WebDAVServer which is subclassed from AuthServer. The AuthServer class implements Basic Authentication in order to make connections somewhat more secure. For processing requests the WebDAVServer class needs some connection to the actual data on server. In contrast to a normal web server this data must not simply be stored on a filesystem but can also live in databases and the like. Thus the WebDAVServer class needs an interface to this data which is implemented via an interface class (in our example stored in fshandler.py). This class will be instantiated by the WebDAVServer class and be used when needed (e.g. retrieving properties, creating new resources, obtaining existing resources etc.). When it comes to parsing XML (like in the PROPFIND and PROPPATCH methods) the WebDAVServer class uses for each method another extra class stored e.g. in propfind.py. This class parses the XML body and createsan XML response while obtaining data from the interface class. Thus all the XML parsing is factored out into the specific method classes. In order to create your own davserver for your own purposes you have to do the following: - subclass the WebDAVServer class and write your own get_userinfo() method for identifying users. - create your own interface class for interfacing with your actual data. You might use the existing class as skeleton and explanation of which methods are needed. That should be basically all you need to do. Have a look at pywebdav/server/fileauth.py in order to get an example how to subclass WebDAVServer. === * describe the methods which need to be implemented. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/Changes0000644000175100001770000001715714640646222015163 0ustar00runnerdocker0.9.14 (September 3 2019) ------------------------- Include tests dir in release pack to unblock debian packaging tests. 0.9.13 (August 15 2019) ----------------------- Fix responed data type error Fix exception when trying to list directory over WebDAV Don't send Content-Type header twice Fix python2 support Don't decode binary data on put 0.9.12 (October 29 2017) ------------------------ Allow running davserver as PyWebDAV server 0.9.11 (August 3 2016) ---------------------- Added unit test to run litmus webdav testing suite. Added travis-ci job to run said test, but it has false positives. Runs locally correctly. Fixed a number of unicode issues from the python3 translation identified by the unit test. Still a number of litmus tests failing to do with props and file locking. 0.9.10 (July 21 2016) --------------------- The original package name PyWebDAV was being referenced in lib, causing the server to fail No other change in functionality [Andrew Leech] 0.9.9 (July 8 2016) ------------------- Updated to support Python 3. No other change in functionality [Andrew Leech] 0.9.8 (March 25 2011) --------------------- Restructured. Moved DAV package to pywebdav.lib. All integrators must simply replace ''from DAV'' imports to ''from pywebdav.lib''. [Simon Pamies] Remove BufferingHTTPServer, reuse the header parser of BaseHTTPServer. [Cédric Krier] Fix issue 44: Incomplete PROPFIND response [Sascha Silbe] 0.9.4 (April 15 2010) --------------------- Add somme configuration setting variable to enable/disable iterator and chunk support [Stephane Klein] Removed os.system calls thus fixing issue 32 [Simon Pamies] Fixed issue 14 [Simon Pamies] Removed magic.py module - replaced with mimetypes module [Simon Pamies] Print User-Agent information in log request. [Stephane Klein] Fix issue 13 : return http 1.0 compatible response (not chunked) when request http version is 1.0 [cliff.wells] Enhance logging mechanism [Stephane Klein] Fix issue 15 : I've error when I execute PUT action with Apple Finder client [Stephane Klein] Fix issue 14 : config.ini boolean parameter reading issue [Stephane Klein] 0.9.3 (July 2 2009) ------------------- Setting WebDAV v2 as default because LOCK and UNLOCK seem to be stable by now. -J parameter is ignored and will go away. [Simon Pamies] Fix for PROPFIND to return *all* properties [Cedric Krier] Fixed do_PUT initialisation [Cedric Krier] Added REPORT support [Cedric Krier] Added support for gzip encoding [Cedric Krier] Fix for wrong --port option [Martin Wendt] Handle paths correctly for Windows related env [Martin Wendt] Included mimetype check for files based on magic.py from Jason Petrone. Included magic.py into this package. All magic.py code (c) 2000 Jason Petrone. Included from http://www.jsnp.net/code/magic.py. [Joerg Friedrich, Simon Pamies] Status check not working when server is running [Joerg Friedrich] Fixed wrong time formatting for Last-Modified and creationdate (must follow RFC 822 and 3339) [Cedric Krier] 0.9.2 (May 11 2009) ------------------- Fixed COPY, MOVE, DELETE to support locked resources [Simon Pamies] Fixed PROPFIND to return 404 for non existing objects and also reduce property bloat [Simon Pamies] Implemented fully working LOCK and UNLOCK based on in memory lock/token database. Now fully supports cadaver and Mac OS X Finder. [Simon Pamies] Fixed MKCOL answer to 201 [Jesus Cea] Fixed MSIE webdav headers [Jesus Cea] Make propfind respect the depth from queries [Cedric Krier] Add ETag in the header of GET. This is needed to implement GroupDAV, CardDAV and CalDAV. [Cedric Krier] Handle the "Expect 100-continue" header [Cedric Krier] Remove debug statements and remove logging [Cedric Krier] Use the Host header in baseuri if set. [Cedric Krier] Adding If-Match on PUT and DELETE [Cedric Krier] 0.9.1 (May 4th 2009) -------------------- Restructured the structure a bit: Made server package a real python package. Adapted error messages. Prepared egg distribution. [Simon Pamies] Fix for time formatting bug. Thanks to Ian Kallen [Simon Pamies] Small fixes for WebDavServer (status not handled correctly) and propfind (children are returned from a PROPFIND with "Depth: 0") [Kjetil Irbekk] 0.8 (Jul 15th 2008) ------------------- First try of an implementation of the LOCK and UNLOCK features. Still very incomplete (read: very incomplete) and not working in this version. [Simon Pamies] Some code cleanups to prepare restructuring [Simon Pamies] Port to minidom because PyXML isn't longer maintained [Martin v. Loewis] utils.py: Makes use of DOMImplementation class to create a new xml document Uses dom namespace features to create elements within DAV: namespace [Stephane Bonhomme] davcmd.py: Missing an indent in loop on remove and copy operations on trees, the effect was that only the last object was removed/copied : always leads to a failure when copying collections. [Stephane Bonhomme] propfind.py: missing a return at the end of the createResponse method (case of a propfind without xml body, should act as a allprops). [Stephane Bonhomme] 0.7 --- Added MySQL auth support brought by Vince Spicer Added INI file support also introduced by Vince Some minor bugfixes and integration changes. Added instance counter to make multiple instances possible Extended --help text a bit [Simon Pamies] 0.6 --- Added bugfixes for buggy Mac OS X Finder implementation Finder tries to stat .DS_Store without checking if it exists Cleaned up readme and install files Moved license to extra file Added distutils support Refactored module layout Refactored class and module names Added commandline support Added daemonize support Added logging facilities Added extended arguments some more things I can't remember [Simon Pamies] Changes since 0.5.1 ------------------- Updated to work with latest 4Suite Changes since 0.5 ----------------- added constants.py data.py must now return COLLECTION or OBJECT when getting asked for resourcetype. propfind.py will automatically generate the right xml element. now only contains the path changed HTTP/1.0 header to HTTP/1.1 which makes it work with WebFolders added DO_AUTH constant to AuthServer.py to control whether authentication should be done or not. added chunked responses in davserver.py One step in order to get a server with keep-alive one day. we now use 4DOM instead if PyDOM the URI in a href is quoted complete rewrite of the PROPFIND stuff: error responses are now generated when a property if not found or not accessible namespace handling is now better. We forget any prefix and create them ourselves later in the response. added superclass iface.py in DAV/ in order to make implementing interface classes easier. See data.py for how to use it. Also note that the way data.py handles things might have changed from the previous release (if you don't like it wait for 1.0!) added functions to iface.py which format creationdate and lastmodified implemented HEAD lots of bugfixes Changes since 0.3 ----------------- removed hard coded base uri from davserver.py and replaced by a reference to the dataclass. Added this to iface.py where you have to define it in your subclass. added davcmd.py which contains utility functions for copy and move reimplemented DELETE and removed dependencies to pydom. move actual delete method to davcmd. implemented COPY implemented MOVE fixed bugs in errors.py, needs revisiting anyway.. URIs are now unquoted in davserver.py before being used paths in data.py are quoted in system calls in order to support blanks in pathnames (e.g. mkdir '%s' ) switched to exceptions when catching errors from the interface class added exists() method to data.py added more uri utility functions to utils.py millenium bugfixes ;-) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/INSTALL0000644000175100001770000000061214640646222014705 0ustar00runnerdockerHow to install python WebDAV server ------------------------------- 1. Check prerequisites + *nix OS (including Mac OS X) Windows seems to work + Python >=2.4.x 2. Run setup.py $ python setup.py install 4. Change to the PyDAVServer directory and start server with > ./server.py -h 5. Enjoy Please send bugs and feature requests to s.pamies@banality.de ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/LICENSE0000644000175100001770000006144714640646222014676 0ustar00runnerdocker GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 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. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; 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. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/TODO0000644000175100001770000000125414640646222014347 0ustar00runnerdockerGENERAL ------- - web page needs to get done: - Download - News - TODO list - Changes - Name - use a better solution than DAV/INI_Parse.py [Stephane Klein] - create WSGI server version [Stephane Klein] MOVE ---- needs to get implemented (will get used for renaming files and dirs) PROPFIND -------- - PROPNAMES need to get implemented - only DAV properties are possible right now - Depth=infinity should be implemented GET --- - guessing mimetype? PROPPATCH --------- to be done (not that important as only DAV props are supported right now which you cannot change) TEST ---- - create some unit test - maybe use davclient package to make the tests ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/interface_class0000644000175100001770000001006614640646222016730 0ustar00runnerdockerHow to write an interface class ------------------------------- (this information might be a little out of date. See data.py for more details). The interface class of davserver is the interface between the actual data and the davserver. The davserver will ask this class every time it needs information about the underlying data (e.g. a filesystem or a database). So how do you write such a class? Simply take the existing class which models a normal unix filesystem and change it. You actually have implement the following methods: get_childs(self, uri, filter=None) This method should return a list of all childs for the object specified by the given uri. The childs should be specified as normal URIs. get_props(self,uri,values=None,all=None,proplist=[]) This method will be called when the davserver needs information about properties for the object specified with the given uri. The parameters are as follows: values -- ?? cannot remember ;-) all -- if set to 1 return all properties proplist -- alternatively you can give get a list of properties to return The result of this method should be a dictionary of the form props[propname]=propvalue Note that in the example class this one is simply a dummy class as only DAV properties are handled which have their own methods (see below). get_data(self,uri) This method will be called when the content of an object is needed. Thus this method should return a data string. get_dav(self,uri,propname) This method will be called when the server needs access to a DAV property. In the example implementation it will simply delegate it to the corresponding _get_dav_ method. You maybe should handle it the same way. _get_dav_(uri) These methods will be called by get_dav() when the value of a DAV property is needed. The defined properties are: - resourcetype (empty or if the object is a collection) - getcontentlength - getcontenttype - getlastmodified - creationdate put(self,uri,data) This method will write data into the given object. It should return the result code (e.g. 424 if an error occured and None if everythin was ok). mkcol(self,uri) This method will be called when the MKCOL WEBDAV method was received by the server. The interface class has to test - if the parents of the uri all exists. If not, return 409 - if the object already exists. If so, return 405 - if it is allowed to create the collection. If not, return 403 If everything is ok, then create the new collection (aka directory) and return 201. rmcol(self,uri) This method is called when a collection needs to be removed. Only the collection should be removed, no children as the davserver is automatically iterating over all children and calling rm/rmcol for each of them (because it needs a result code for every deleted object). If the user is not allowed to delete the collection then an 403 should be returned rm(self,uri) This is the same for single objects, the same as above applies. is_collection(self,uri) This one simply returns 1 if the object specified by the uri is an object or 0 if it isn't. So these are basically the methods which need to get implemented. While writing this I also noticed some problems: - the actual user is not know to the interface class. This should be changed as it might be important when testing if an action is allowed or not. Also some implementations might need a user in order to decide what to return (e.g. GROUP.lounge will need this.) - the return of result codes is not standardized throughout the interface class. This should be changed. - The should be a super interface class to derive from in order to handle some common things like get_dav() or property handling in general. Some things then also might me moved from propfind.py/devserver.py into this class. As the changes above might break existing code you have been warned with this message :) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/doc/walker0000644000175100001770000000232214640646222015064 0ustar00runnerdockerWalker methods -------------- In the COPY, DELETE and MOVE methods we need to walk over a tree of resources and collections in order to copy, delete or move them. The difference between all these walks is only that we perform a different action on the resources we visit. Thus it might be the simplest solution to provide a walker class or method to do that work and give it a function to perform before starting. Way of walking -------------- When we delete things we should do it bottom up but when we copy or move things we should create resources top down. Thus we actually need 2 methods. But the following method might work: We create a list of all the nodes in the tree in tree order (means top down, left to right). When we walk over this list from begin to end we can copy and when we move backwards we can delete. Thus we need an indicator for the direction and the method to perform on it. Here the iterative approach (in order to save memory): dc = dataclass queue = list = [start_uri] while len(queue): element = queue[-1] childs = dc.get_childs(element) if childs: list = list + childs # update queue del queue[-1] if childs: queue = queue + childs (first try..) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.158574 pywebdav3-0.11.0/pywebdav/0000755000175100001770000000000014640646230014730 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/__init__.py0000644000175100001770000000030514640646222017040 0ustar00runnerdocker"""WebDAV library including a standalone server for python 3""" __version__ = '0.9.14' __author__ = 'Andrew Leech (previously Simon Pamies)' __email__ = 'andrew@alelec.net' __license__ = 'LGPL v2' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/__main__.py0000644000175100001770000000006014640646222017017 0ustar00runnerdockerfrom pywebdav.server import server server.run() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/pywebdav/lib/0000755000175100001770000000000014640646230015476 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/AuthServer.py0000644000175100001770000000652114640646222020145 0ustar00runnerdocker"""Authenticating HTTP Server This module builds on BaseHTTPServer and implements basic authentication """ import base64 import binascii import six.moves.BaseHTTPServer DEFAULT_AUTH_ERROR_MESSAGE = """ %(code)d - %(message)s

Authorization Required

this server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required. """ def _quote_html(html): return html.replace("&", "&").replace("<", "<").replace(">", ">") class AuthRequestHandler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler): """ Simple handler that can check for auth headers In your subclass you have to define the method get_userinfo(user, password) which should return 1 or None depending on whether the password was ok or not. None means that the user is not authorized. """ # False means no authentiation DO_AUTH = 1 def parse_request(self): if not six.moves.BaseHTTPServer.BaseHTTPRequestHandler.parse_request(self): return False if self.DO_AUTH: authorization = self.headers.get('Authorization', '') if not authorization: self.send_autherror(401, "Authorization Required") return False scheme, credentials = authorization.split() if scheme != 'Basic': self.send_error(501) return False credentials = base64.decodebytes(credentials.encode()).decode() user, password = credentials.split(':') if not self.get_userinfo(user, password, self.command): self.send_autherror(401, "Authorization Required") return False return True def send_autherror(self, code, message=None): """Send and log an auth error reply. Arguments are the error code, and a detailed message. The detailed message defaults to the short entry matching the response code. This sends an error response (so it must be called before any output has been generated), logs the error, and finally sends a piece of HTML explaining the error to the user. """ try: short, long = self.responses[code] except KeyError: short, long = '???', '???' if message is None: message = short explain = long self.log_error("code %d, message %s", code, message) # using _quote_html to prevent Cross Site Scripting attacks (see bug # #1100201) content = (self.error_auth_message_format % {'code': code, 'message': _quote_html(message), 'explain': explain}) self.send_response(code, message) self.send_header('Content-Type', self.error_content_type) self.send_header('WWW-Authenticate', 'Basic realm="PyWebDAV"') self.send_header('Connection', 'close') self.end_headers() self.wfile.write(content.encode('utf-8')) error_auth_message_format = DEFAULT_AUTH_ERROR_MESSAGE def get_userinfo(self, user, password, command): """Checks if the given user and the given password are allowed to access. """ # Always reject return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/INI_Parse.py0000644000175100001770000000302414640646222017621 0ustar00runnerdockerfrom configparser import ConfigParser class Configuration: def __init__(self, fileName): cp = ConfigParser() cp.read(fileName) self.__parser = cp self.fileName = fileName def __getattr__(self, name): if name in self.__parser.sections(): return Section(name, self.__parser) else: return None def __str__(self): p = self.__parser result = [] result.append('' % self.fileName) for s in p.sections(): result.append('[%s]' % s) for o in p.options(s): result.append('%s=%s' % (o, p.get(s, o))) return '\n'.join(result) class Section: def __init__(self, name, parser): self.name = name self.__parser = parser def __getattr__(self, name): return self.__parser.get(self.name, name) def __str__(self): return str(self.__repr__()) def __repr__(self): return self.__parser.items(self.name) def getboolean(self, name): return self.__parser.getboolean(self.name, name) def __contains__(self, name): return self.__parser.has_option(self.name, name) def get(self, name, default): if name in self: return self.__getattr__(name) else: return default def set(self, name, value): self.__parser.set(self.name, name, str(value)) # Test if __name__ == '__main__': c = Configuration('Importador.ini') print(c.Origem.host, c.Origem.port) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/WebDAVServer.py0000644000175100001770000006075314640646222020323 0ustar00runnerdocker"""DAV HTTP Server This module builds on BaseHTTPServer and implements DAV commands """ from . import AuthServer from six.moves import urllib import logging from .propfind import PROPFIND from .report import REPORT from .delete import DELETE from .davcopy import COPY from .davmove import MOVE from .utils import rfc1123_date, IfParser, tokenFinder from .errors import DAV_Error, DAV_NotFound from .constants import DAV_VERSION_1, DAV_VERSION_2 from .locks import LockManager import gzip import io from pywebdav import __version__ from xml.parsers.expat import ExpatError log = logging.getLogger(__name__) BUFFER_SIZE = 128 * 1000 # 128 Ko class DAVRequestHandler(AuthServer.AuthRequestHandler, LockManager): """Simple DAV request handler with - GET - HEAD - PUT - OPTIONS - PROPFIND - PROPPATCH - MKCOL - REPORT experimental - LOCK - UNLOCK It uses the resource/collection classes for serving and storing content. """ server_version = "DAV/" + __version__ encode_threshold = 1400 # common MTU def send_body(self, DATA, code=None, msg=None, desc=None, ctype='application/octet-stream', headers={}): """ send a body in one part """ log.debug("Use send_body method") self.send_response(code, message=msg) self.send_header("Connection", "close") self.send_header("Accept-Ranges", "bytes") self.send_header('Date', rfc1123_date()) self._send_dav_version() for a, v in headers.items(): self.send_header(a, v) if DATA: try: if 'gzip' in self.headers.get('Accept-Encoding', '').split(',') \ and len(DATA) > self.encode_threshold: buffer = io.BytesIO() output = gzip.GzipFile(mode='wb', fileobj=buffer) if isinstance(DATA, str): output.write(DATA) else: for buf in DATA: output.write(buf) output.close() buffer.seek(0) DATA = buffer.getvalue() self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Length', len(DATA)) self.send_header('Content-Type', ctype) except Exception as ex: log.exception(ex) else: self.send_header('Content-Length', 0) self.end_headers() if DATA: if isinstance(DATA, str): DATA = DATA.encode('utf-8') if isinstance(DATA, str) or isinstance(DATA, bytes): log.debug("Don't use iterator") self.wfile.write(DATA) else: if self._config.DAV.getboolean('http_response_use_iterator'): # Use iterator to reduce using memory log.debug("Use iterator") for buf in DATA: self.wfile.write(buf) self.wfile.flush() else: # Don't use iterator, it's a compatibility option log.debug("Don't use iterator") res = DATA.read() if isinstance(res,bytes): self.wfile.write(res) else: self.wfile.write(res.encode('utf8')) return None def send_body_chunks_if_http11(self, DATA, code, msg=None, desc=None, ctype='text/xml; encoding="utf-8"', headers={}): if (self.request_version == 'HTTP/1.0' or not self._config.DAV.getboolean('chunked_http_response')): self.send_body(DATA, code, msg, desc, ctype, headers) else: self.send_body_chunks(DATA, code, msg, desc, ctype, headers) def send_body_chunks(self, DATA, code, msg=None, desc=None, ctype='text/xml"', headers={}): """ send a body in chunks """ self.responses[207] = (msg, desc) self.send_response(code, message=msg) self.send_header("Content-type", ctype) self.send_header("Transfer-Encoding", "chunked") self.send_header('Date', rfc1123_date()) self._send_dav_version() for a, v in headers.items(): self.send_header(a, v) GZDATA = None if DATA: if ('gzip' in self.headers.get('Accept-Encoding', '').split(',') and len(DATA) > self.encode_threshold): buffer = io.BytesIO() output = gzip.GzipFile(mode='wb', fileobj=buffer) if isinstance(DATA, bytes): output.write(DATA) else: for buf in DATA: buf = buf.encode() if isinstance(buf, str) else buf output.write(buf) output.close() buffer.seek(0) GZDATA = buffer.getvalue() self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Length', len(DATA)) self.send_header('Content-Type', ctype) else: self.send_header('Content-Length', 0) self.end_headers() if GZDATA: self.wfile.write(GZDATA) elif DATA: DATA = DATA.encode() if isinstance(DATA, str) else DATA if isinstance(DATA, bytes): self.wfile.write(b"%s\r\n" % hex(len(DATA))[2:].encode()) self.wfile.write(DATA) self.wfile.write(b"\r\n") self.wfile.write(b"0\r\n") self.wfile.write(b"\r\n") else: if self._config.DAV.getboolean('http_response_use_iterator'): # Use iterator to reduce using memory for buf in DATA: buf = buf.encode() if isinstance(buf, str) else buf self.wfile.write((hex(len(buf))[2:] + "\r\n").encode()) self.wfile.write(buf) self.wfile.write(b"\r\n") self.wfile.write(b"0\r\n") self.wfile.write(b"\r\n") else: # Don't use iterator, it's a compatibility option self.wfile.write((hex(len(DATA))[2:] + "\r\n").encode()) self.wfile.write(DATA.read()) self.wfile.write(b"\r\n") self.wfile.write(b"0\r\n") self.wfile.write(b"\r\n") def _send_dav_version(self): if self._config.DAV.getboolean('lockemulation'): self.send_header('DAV', DAV_VERSION_2['version']) else: self.send_header('DAV', DAV_VERSION_1['version']) ### HTTP METHODS called by the server def do_OPTIONS(self): """return the list of capabilities """ self.send_response(200) self.send_header("Content-Length", 0) if self._config.DAV.getboolean('lockemulation'): self.send_header('Allow', DAV_VERSION_2['options']) else: self.send_header('Allow', DAV_VERSION_1['options']) self._send_dav_version() self.send_header('MS-Author-Via', 'DAV') # this is for M$ self.end_headers() def _HEAD_GET(self, with_body=False): """ Returns headers and body for given resource """ dc = self.IFACE_CLASS uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) headers = {} # get the last modified date (RFC 1123!) try: headers['Last-Modified'] = dc.get_prop( uri, "DAV:", "getlastmodified") except DAV_NotFound: pass # get the ETag if any try: headers['Etag'] = dc.get_prop(uri, "DAV:", "getetag") except DAV_NotFound: pass # get the content type try: if uri.endswith('/'): # we could do away with this very non-local workaround for # _get_listing if the data could have a type attached content_type = 'text/html;charset=utf-8' else: content_type = dc.get_prop(uri, "DAV:", "getcontenttype") except DAV_NotFound: content_type = "application/octet-stream" range = None status_code = 200 if 'Range' in self.headers: p = self.headers['Range'].find("bytes=") if p != -1: range = self.headers['Range'][p + 6:].split("-") status_code = 206 # get the data try: data = dc.get_data(uri, range) except DAV_Error as error: (ec, dd) = error.args self.send_status(ec) return ec # send the data if with_body is False: data = None if isinstance(data, str): self.send_body(data, status_code, None, None, content_type, headers) else: headers['Keep-Alive'] = 'timeout=15, max=86' headers['Connection'] = 'Keep-Alive' self.send_body_chunks_if_http11(data, status_code, None, None, content_type, headers) return status_code def do_HEAD(self): """ Send a HEAD response: Retrieves resource information w/o body """ return self._HEAD_GET(with_body=False) def do_GET(self): """Serve a GET request.""" log.debug(self.headers) try: status_code = self._HEAD_GET(with_body=True) self.log_request(status_code) return status_code except IOError as e: if e.errno == 32: self.log_request(206) else: raise def do_TRACE(self): """ This will always fail because we can not reproduce HTTP requests. We send back a 405=Method Not Allowed. """ self.send_body(None, 405, 'Method Not Allowed', 'Method Not Allowed') def do_POST(self): """ Replacement for GET response. Not implemented here. """ self.send_body(None, 405, 'Method Not Allowed', 'Method Not Allowed') def do_PROPPATCH(self): # currently unsupported return self.send_status(423) def do_PROPFIND(self): """ Retrieve properties on defined resource. """ dc = self.IFACE_CLASS # read the body containing the xml request # iff there is no body then this is an ALLPROP request body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(int(l)) uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) try: pf = PROPFIND(uri, dc, self.headers.get('Depth', 'infinity'), body) except ExpatError: # parse error return self.send_status(400) try: DATA = pf.createResponse() except DAV_Error as error: (ec, dd) = error.args return self.send_status(ec) # work around MSIE DAV bug for creation and modified date # taken from Resource.py @ Zope webdav if (self.headers.get('User-Agent') == 'Microsoft Data Access Internet Publishing Provider DAV 1.1'): DATA = DATA.replace(b'', b'') DATA = DATA.replace(b'', b'') self.send_body_chunks_if_http11(DATA, 207, 'Multi-Status', 'Multiple responses') def do_REPORT(self): """ Query properties on defined resource. """ dc = self.IFACE_CLASS # read the body containing the xml request # iff there is no body then this is an ALLPROP request body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(int(l)) uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) rp = REPORT(uri, dc, self.headers.get('Depth', '0'), body) try: DATA = '%s\n' % rp.createResponse() except DAV_Error as error: (ec, dd) = error.args return self.send_status(ec) self.send_body_chunks_if_http11(DATA, 207, 'Multi-Status', 'Multiple responses') def do_MKCOL(self): """ create a new collection """ # according to spec body must be empty body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(int(l)) if body: return self.send_status(415) dc = self.IFACE_CLASS uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) try: dc.mkcol(uri) self.send_status(201) self.log_request(201) except DAV_Error as error: (ec, dd) = error.args self.log_request(ec) return self.send_status(ec) def do_DELETE(self): """ delete an resource """ dc = self.IFACE_CLASS uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) # hastags not allowed if uri.find('#') >= 0: return self.send_status(404) # locked resources are not allowed to delete if self._l_isLocked(uri): return self.send_body(None, 423, 'Locked', 'Locked') # Handle If-Match if 'If-Match' in self.headers: test = False etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass for match in self.headers['If-Match'].split(','): if match == '*': if dc.exists(uri): test = True break else: if match == etag: test = True break if not test: self.send_status(412) self.log_request(412) return # Handle If-None-Match if 'If-None-Match' in self.headers: test = True etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass for match in self.headers['If-None-Match'].split(','): if match == '*': if dc.exists(uri): test = False break else: if match == etag: test = False break if not test: self.send_status(412) self.log_request(412) return try: dl = DELETE(uri, dc) if dc.is_collection(uri): res = dl.delcol() if res: self.send_status(207, body=res) else: self.send_status(204) else: res = dl.delone() or 204 self.send_status(res) except DAV_NotFound: self.send_body(None, 404, 'Not Found', 'Not Found') def do_PUT(self): dc = self.IFACE_CLASS uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) log.debug("do_PUT: uri = %s" % uri) log.debug('do_PUT: headers = %s' % self.headers) # Handle If-Match if 'If-Match' in self.headers: log.debug("do_PUT: If-Match %s" % self.headers['If-Match']) test = False etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass log.debug("do_PUT: etag = %s" % etag) for match in self.headers['If-Match'].split(','): if match == '*': if dc.exists(uri): test = True break else: if match == etag: test = True break if not test: self.send_status(412) self.log_request(412) return # Handle If-None-Match if 'If-None-Match' in self.headers: log.debug("do_PUT: If-None-Match %s" % self.headers['If-None-Match']) test = True etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass log.debug("do_PUT: etag = %s" % etag) for match in self.headers['If-None-Match'].split(','): if match == '*': if dc.exists(uri): test = False break else: if match == etag: test = False break if not test: self.send_status(412) self.log_request(412) return # locked resources are not allowed to be overwritten ifheader = self.headers.get('If') if ( (self._l_isLocked(uri)) and (not ifheader) ): return self.send_body(None, 423, 'Locked', 'Locked') if self._l_isLocked(uri) and ifheader: uri_token = self._l_getLockForUri(uri) taglist = IfParser(ifheader) found = False for tag in taglist: for listitem in tag.list: token = tokenFinder(listitem) if ( token and (self._l_hasLock(token)) and (self._l_getLock(token) == uri_token) ): found = True break if found: break if not found: res = self.send_body(None, 423, 'Locked', 'Locked') self.log_request(423) return res # Handle expect expect = self.headers.get('Expect', '') if (expect.lower() == '100-continue' and self.protocol_version >= 'HTTP/1.1' and self.request_version >= 'HTTP/1.1'): self.send_status(100) content_type = None if 'Content-Type' in self.headers: content_type = self.headers['Content-Type'] headers = {} headers['Location'] = urllib.parse.quote(uri) try: etag = dc.get_prop(uri, "DAV:", "getetag") headers['ETag'] = etag except: pass expect = self.headers.get('transfer-encoding', '') if ( expect.lower() == 'chunked' and self.protocol_version >= 'HTTP/1.1' and self.request_version >= 'HTTP/1.1' ): self.send_body(None, 201, 'Created', '', headers=headers) dc.put(uri, self._readChunkedData(), content_type) else: # read the body body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] log.debug("do_PUT: Content-Length = %s" % l) body = self._readNoChunkedData(int(l)) else: log.debug("do_PUT: Content-Length = empty") try: dc.put(uri, body, content_type) except DAV_Error as error: (ec, dd) = error.args return self.send_status(ec) self.send_body(None, 201, 'Created', '', headers=headers) self.log_request(201) def _readChunkedData(self): l = int(self.rfile.readline(), 16) while l > 0: buf = self.rfile.read(l) yield buf self.rfile.readline() l = int(self.rfile.readline(), 16) def _readNoChunkedData(self, content_length): if self._config.DAV.getboolean('http_request_use_iterator'): # Use iterator to reduce using memory return self.__readNoChunkedDataWithIterator(content_length) else: # Don't use iterator, it's a compatibility option return self.__readNoChunkedDataWithoutIterator(content_length) def __readNoChunkedDataWithIterator(self, content_length): while True: if content_length > BUFFER_SIZE: buf = self.rfile.read(BUFFER_SIZE) content_length -= BUFFER_SIZE yield buf else: buf = self.rfile.read(content_length) yield buf break def __readNoChunkedDataWithoutIterator(self, content_length): return self.rfile.read(content_length) def do_COPY(self): """ copy one resource to another """ try: self.copymove(COPY) except DAV_Error as error: (ec, dd) = error.args return self.send_status(ec) def do_MOVE(self): """ move one resource to another """ try: self.copymove(MOVE) except DAV_Error as error: (ec, dd) = error.args return self.send_status(ec) def copymove(self, CLASS): """ common method for copying or moving objects """ dc = self.IFACE_CLASS # get the source URI source_uri = urllib.parse.unquote(urllib.parse.urljoin(self.get_baseuri(dc), self.path)) # get the destination URI dest_uri = self.headers['Destination'] dest_uri = urllib.parse.unquote(dest_uri) # check locks on source and dest if self._l_isLocked(source_uri) or self._l_isLocked(dest_uri): return self.send_body(None, 423, 'Locked', 'Locked') # Overwrite? overwrite = 1 result_code = 204 if 'Overwrite' in self.headers: if self.headers['Overwrite'] == "F": overwrite = None result_code = 201 # instanciate ACTION class cp = CLASS(dc, source_uri, dest_uri, overwrite) # Depth? d = "infinity" if 'Depth' in self.headers: d = self.headers['Depth'] if d != "0" and d != "infinity": self.send_status(400) return if d == "0": res = cp.single_action() self.send_status(res or 201) return # now it only can be "infinity" but we nevertheless check for a # collection if dc.is_collection(source_uri): try: res = cp.tree_action() except DAV_Error as error: (ec, dd) = error.args self.send_status(ec) return else: try: res = cp.single_action() except DAV_Error as error: (ec, dd) = error.args self.send_status(ec) return if res: self.send_body_chunks_if_http11(res, 207, self.responses[207][0], self.responses[207][1], ctype='text/xml; charset="utf-8"') else: self.send_status(result_code) def get_userinfo(self, user, pw): """ Dummy method which lets all users in """ return 1 def send_status(self, code=200, mediatype='text/xml; charset="utf-8"', msg=None, body=None): if not msg: msg = self.responses.get(code, ['', ''])[1] self.send_body(body, code, self.responses.get(code, [''])[0], msg, mediatype) def get_baseuri(self, dc): baseuri = dc.baseuri if 'Host' in self.headers: uparts = list(urllib.parse.urlparse(dc.baseuri)) uparts[1] = self.headers['Host'] baseuri = urllib.parse.urlunparse(uparts) return baseuri ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/__init__.py0000644000175100001770000000000014640646222017576 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/constants.py0000644000175100001770000000121014640646222020057 0ustar00runnerdocker# definition for resourcetype COLLECTION=1 OBJECT=None # attributes for resources DAV_PROPS=['creationdate', 'displayname', 'getcontentlanguage', 'getcontentlength', 'getcontenttype', 'getetag', 'getlastmodified', 'lockdiscovery', 'resourcetype', 'source', 'supportedlock'] # Request classes in propfind RT_ALLPROP=1 RT_PROPNAME=2 RT_PROP=3 # server mode DAV_VERSION_1 = { 'version' : '1', 'options' : 'GET, HEAD, COPY, MOVE, POST, PUT, PROPFIND, PROPPATCH, OPTIONS, MKCOL, DELETE, TRACE, REPORT' } DAV_VERSION_2 = { 'version' : '1,2', 'options' : DAV_VERSION_1['options'] + ', LOCK, UNLOCK' } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/davcmd.py0000644000175100001770000001413214640646222017310 0ustar00runnerdocker""" davcmd.py --------- containts commands like copy, move, delete for normal resources and collections """ from six.moves import urllib from .utils import create_treelist, is_prefix from .errors import * from six.moves import range import os def deltree(dc,uri,exclude={}): """ delete a tree of resources dc -- dataclass to use uri -- root uri to delete exclude -- an optional list of uri:error_code pairs which should not be deleted. returns dict of uri:error_code tuples from which another method can create a multistatus xml element. Also note that we only know Depth=infinity thus we don't have to test for it. """ tlist=create_treelist(dc,uri) result={} for i in range(len(tlist),0,-1): problem_uris=list(result.keys()) element=tlist[i-1] # test here, if an element is a prefix of an uri which # generated an error before. # note that we walk here from childs to parents, thus # we cannot delete a parent if a child made a problem. # (see example in 8.6.2.1) ok=1 for p in problem_uris: if is_prefix(element,p): ok=None break if not ok: continue # here we test for the exclude list which is the other way round! for p in exclude.keys(): if is_prefix(p,element): ok=None break if not ok: continue # now delete stuff try: delone(dc,element) except DAV_Error as error: (ec,dd) = error.args result[element]=ec return result def delone(dc,uri): """ delete a single object """ if dc.is_collection(uri): return dc.rmcol(uri) # should be empty else: return dc.rm(uri) ### ### COPY ### # helper function def copy(dc,src,dst): """ only copy the element This is just a helper method factored out from copy and copytree. It will not handle the overwrite or depth header. """ # destination should have been deleted before if dc.exists(dst): raise DAV_Error(412) # source should exist also if not dc.exists(src): raise DAV_NotFound if dc.is_collection(src): dc.copycol(src, dst) # an exception will be passed thru else: dc.copy(src, dst) # an exception will be passed thru # the main functions def copyone(dc,src,dst,overwrite=None): """ copy one resource to a new destination """ if overwrite and dc.exists(dst): delres = deltree(dc, dst) else: delres={} # if we cannot delete everything, then do not copy! if delres: return delres try: copy(dc, src, dst) # pass thru exceptions except DAV_Error as error: (ec, dd) = error.args return ec def copytree(dc,src,dst,overwrite=None): """ copy a tree of resources to another location dc -- dataclass to use src -- src uri from where to copy dst -- dst uri overwrite -- if True then delete dst uri before returns dict of uri:error_code tuples from which another method can create a multistatus xml element. """ # first delete the destination resource if overwrite and dc.exists(dst): delres=deltree(dc,dst) else: delres={} # if we cannot delete everything, then do not copy! if delres: return delres # get the tree we have to copy tlist = create_treelist(dc,src) result = {} # Extract the path out of the source URI. src_path = urllib.parse.urlparse(src).path # Parse the destination URI. # We'll be using it to construct destination URIs, # so we don't just retain the path, like we did with # the source. dst_parsed = urllib.parse.urlparse(dst) for element in tlist: problem_uris = list(result.keys()) # now URIs get longer and longer thus we have # to test if we had a parent URI which we were not # able to copy in problem_uris which is the prefix # of the actual element. If it is, then we cannot # copy this as well but do not generate another error. ok=True for p in problem_uris: if is_prefix(p,element): ok=False break if not ok: continue # Find the element's path relative to the source. element_path = urllib.parse.urlparse(element).path element_path_rel = os.path.relpath(element_path, start=src_path) # Append this relative path to the destination. if element_path_rel == '.': # os.path.relpath("/somedir", start="/somedir") returns # a result of ".", which we don't want to append to the # destination path. dst_path = dst_parsed.path else: dst_path = os.path.join(dst_parsed.path, element_path_rel) # Generate destination URI using our derived destination path. dst_uri = urllib.parse.urlunparse(dst_parsed._replace(path=os.path.join(dst_parsed.path, element_path_rel))) # now copy stuff try: copy(dc,element,dst_uri) except DAV_Error as error: (ec,dd) = error.args result[element]=ec return result ### ### MOVE ### def moveone(dc,src,dst,overwrite=None): """ move a single resource This is done by first copying it and then deleting the original. """ # first copy it copyone(dc, src, dst, overwrite) # then delete it dc.rm(src) def movetree(dc,src,dst,overwrite=None): """ move a collection This is done by first copying it and then deleting the original. PROBLEM: if something did not copy then we have a problem when deleting as the original might get deleted! """ # first copy it res = copytree(dc,src,dst,overwrite) # TODO: shouldn't we check res for errors and bail out before # the delete if we find any? # TODO: or, better yet, is there anything preventing us from # reimplementing this using `shutil.move()`? # then delete it res = deltree(dc,src,exclude=res) return res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/davcopy.py0000644000175100001770000000616514640646222017526 0ustar00runnerdockerimport xml.dom.minidom domimpl = xml.dom.minidom.getDOMImplementation() import string from six.moves import urllib from io import StringIO from . import utils from .constants import COLLECTION, OBJECT, DAV_PROPS, RT_ALLPROP, RT_PROPNAME, RT_PROP from .errors import * from .utils import create_treelist, quote_uri, gen_estring class COPY: """ copy resources and eventually create multistatus responses This module implements the COPY class which is responsible for copying resources. Usually the normal copy work is done in the interface class. This class only creates error messages if error occur. """ def __init__(self,dataclass,src_uri,dst_uri,overwrite): self.__dataclass=dataclass self.__src=src_uri self.__dst=dst_uri self.__overwrite=overwrite def single_action(self): """ copy a normal resources. We try to copy it and return the result code. This is for Depth==0 """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error(412) # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urllib.parse.urlparse(self.__src)[2] pd=urllib.parse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error(403) return dc.copyone(self.__src,self.__dst,self.__overwrite) #return copyone(dc,self.__src,self.__dst,self.__overwrite) def tree_action(self): """ copy a tree of resources (a collection) Here we return a multistatus xml element. """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error(412) # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urllib.parse.urlparse(self.__src)[2] pd=urllib.parse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error(403) result=dc.copytree(self.__src,self.__dst,self.__overwrite) #result=copytree(dc,self.__src,self.__dst,self.__overwrite) if not result: return None ### ### create the multistatus XML element ### (this is also the same as in delete.py. ### we might make a common method out of it) ### doc = domimpl.createDocument(None, "D:multistatus", None) doc.documentElement.setAttribute("xmlns:D","DAV:") for el,ec in result.items(): re=doc.createElement("D:response") hr=doc.createElement("D:href") st=doc.createElement("D:status") huri=doc.createTextNode(quote_uri(el)) t=doc.createTextNode(gen_estring(ec)) st.appendChild(t) hr.appendChild(huri) re.appendChild(hr) re.appendChild(st) ms.appendChild(re) return doc.toxml(encoding="utf-8") + b"\n" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/davmove.py0000644000175100001770000000431514640646222017515 0ustar00runnerdockerfrom six.moves import urllib from . import utils from .constants import COLLECTION, OBJECT, DAV_PROPS from .constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from .errors import * from .utils import create_treelist, quote_uri, gen_estring, make_xmlresponse, is_prefix from .davcmd import moveone, movetree class MOVE: """ move resources and eventually create multistatus responses This module implements the MOVE class which is responsible for moving resources. MOVE is implemented by a COPY followed by a DELETE of the old resource. """ def __init__(self,dataclass,src_uri,dst_uri,overwrite): self.__dataclass=dataclass self.__src=src_uri self.__dst=dst_uri self.__overwrite=overwrite def single_action(self): """ move a normal resources. We try to move it and return the result code. This is for Depth==0 """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error(412) # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urllib.parse.urlparse(self.__src)[2] pd=urllib.parse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error(403) return dc.moveone(self.__src,self.__dst,self.__overwrite) def tree_action(self): """ move a tree of resources (a collection) Here we return a multistatus xml element. """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error(412) # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urllib.parse.urlparse(self.__src)[2] pd=urllib.parse.urlparse(self.__dst)[2] if is_prefix(ps, pd): raise DAV_Error(403) result=dc.movetree(self.__src,self.__dst,self.__overwrite) if not result: return None # create the multistatus XML element return make_xmlresponse(result) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/dbconn.py0000644000175100001770000000417014640646222017316 0ustar00runnerdockerimport logging log = logging.getLogger(__name__) try: import MySQLdb except ImportError: log.info('No SQL support - MySQLdb missing...') pass class Mconn: def connect(self,username,userpasswd,host,port,db): try: connection = MySQLdb.connect(host=host, port=int(port), user=username, passwd=userpasswd,db=db) except MySQLdb.OperationalError as message: log.error("%d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 else: self.db = connection.cursor() return 1 def execute(self,qry): if self.db: try: res=self.db.execute(qry) except MySQLdb.OperationalError as message: log.error("Error %d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 except MySQLdb.ProgrammingError as message: log.error("Error %d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 else: log.debug('Query Returned '+str(res)+' results') return self.db.fetchall() def create_user(self,user,passwd): qry="select * from Users where User='%s'"%(user) res=self.execute(qry) if not res or len(res) ==0: qry="insert into Users (User,Pass) values('%s','%s')"%(user,passwd) res=self.execute(qry) else: log.debug("Username already in use") def create_table(self): qry="""CREATE TABLE `Users` ( `uid` int(10) NOT NULL auto_increment, `User` varchar(60) default NULL, `Pass` varchar(60) default NULL, `Write` tinyint(1) default '0', PRIMARY KEY (`uid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1""" self.execute(qry) def first_run(self,user,passwd): res= self.execute('select * from Users') if res or type(res)==type(()) : pass else: self.create_table() self.create_user(user,passwd) def __init__(self,user,password,host,port,db): self.db=0 self.connect(user,password,host,port,db) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/delete.py0000644000175100001770000000114214640646222017311 0ustar00runnerdockerfrom .utils import gen_estring, quote_uri, make_xmlresponse from .davcmd import deltree class DELETE: def __init__(self,uri,dataclass): self.__dataclass=dataclass self.__uri=uri def delcol(self): """ delete a collection """ dc=self.__dataclass result=dc.deltree(self.__uri) if not len(list(result.items())): return None # everything ok # create the result element return make_xmlresponse(result) def delone(self): """ delete a resource """ dc=self.__dataclass return dc.delone(self.__uri) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/errors.py0000644000175100001770000000272114640646222017367 0ustar00runnerdocker""" Exceptions for the DAVserver implementation """ class DAV_Error(Exception): """ in general we can have the following arguments: 1. the error code 2. the error result element, e.g. a element """ def __init__(self,*args): if len(args)==1: self.args=(args[0],"") else: self.args=args class DAV_Secret(DAV_Error): """ the user is not allowed to know anything about it returning this for a property value means to exclude it from the response xml element. """ def __init__(self): DAV_Error.__init__(self,0) pass class DAV_NotFound(DAV_Error): """ a requested property was not found for a resource """ def __init__(self,*args): if len(args): DAV_Error.__init__(self,404,args[0]) else: DAV_Error.__init__(self,404) pass class DAV_Forbidden(DAV_Error): """ a method on a resource is not allowed """ def __init__(self,*args): if len(args): DAV_Error.__init__(self,403,args[0]) else: DAV_Error.__init__(self,403) pass class DAV_Requested_Range_Not_Satisfiable(DAV_Error): """ none of the range-specifier values overlap the current extent of the selected resource """ def __init__(self, *args): if len(args): DAV_Error.__init__(self, 416, args[0]) else: DAV_Error.__init__(self, 416) pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/iface.py0000644000175100001770000002055114640646222017123 0ustar00runnerdocker""" basic interface class use this for subclassing when writing your own interface class. """ from xml.dom import minidom from .locks import LockManager from .errors import * import time class dav_interface: """ interface class for implementing DAV servers """ ### defined properties (modify this but let the DAV stuff there!) ### the format is namespace: [list of properties] PROPS={"DAV:" : ('creationdate', 'displayname', 'getcontentlanguage', 'getcontentlength', 'getcontenttype', 'getetag', 'getlastmodified', 'lockdiscovery', 'resourcetype', 'source', 'supportedlock'), "NS2" : ("p1","p2") } # here we define which methods handle which namespace # the first item is the namespace URI and the second one # the method prefix # e.g. for DAV:getcontenttype we call dav_getcontenttype() M_NS={"DAV:" : "_get_dav", "NS2" : "ns2" } def get_propnames(self,uri): """ return the property names allowed for the given URI In this method we simply return the above defined properties assuming that they are valid for any resource. You can override this in order to return a different set of property names for each resource. """ return self.PROPS def get_prop2(self,uri,ns,pname): """ return the value of a property """ if ns.lower() == "dav:": return self.get_dav(uri,pname) raise DAV_NotFound def get_prop(self,uri,ns,propname): """ return the value of a given property uri -- uri of the object to get the property of ns -- namespace of the property pname -- name of the property """ if ns in self.M_NS: prefix=self.M_NS[ns] else: raise DAV_NotFound mname=prefix+"_"+propname.replace('-', '_') try: m=getattr(self,mname) r=m(uri) return r except AttributeError: raise DAV_NotFound ### ### DATA methods (for GET and PUT) ### def get_data(self, uri, range=None): """ return the content of an object return data or raise an exception """ raise DAV_NotFound def put(self, uri, data, content_type=None): """ write an object to the repository return the location uri or raise an exception """ raise DAV_Forbidden ### ### LOCKing information ### def _get_dav_supportedlock(self, uri): txt = ('
\n' '\n' '\n' '
\n') xml = minidom.parseString(txt) return xml.firstChild.firstChild def _get_dav_lockdiscovery(self, uri): lcm = LockManager() if lcm._l_isLocked(uri): lock = lcm._l_getLockForUri(uri) txt = lock.asXML(discover=True, namespace='D') txtwithns = '
%s
' xml = minidom.parseString(txtwithns % txt) return xml.firstChild.firstChild return '' ### ### Methods for DAV properties ### def _get_dav_creationdate(self,uri): """ return the creationdate of a resource """ d=self.get_creationdate(uri) # format it return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(d)) def _get_dav_getlastmodified(self,uri): """ return the last modified date of a resource """ d=self.get_lastmodified(uri) # format it return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(d)) ### ### OVERRIDE THESE! ### def get_creationdate(self,uri): """ return the creationdate of the resource """ return time.time() def get_lastmodified(self,uri): """ return the last modification date of the resource """ return time.time() ### ### COPY MOVE DELETE ### ### methods for deleting a resource def rmcol(self,uri): """ delete a collection This should not delete any children! This is automatically done before by the DELETE class in DAV/delete.py return a success code or raise an exception """ raise DAV_NotFound def rm(self,uri): """ delete a single resource return a success code or raise an exception """ raise DAV_NotFound """ COPY/MOVE HANDLER These handler are called when a COPY or MOVE method is invoked by a client. In the default implementation it works as follows: - the davserver receives a COPY/MOVE method - the davcopy or davmove module will be loaded and the corresponding class will be initialized - this class parses the query and decides which method of the interface class to call: copyone for a single resource to copy copytree for a tree to copy (collection) (the same goes for move of course). - the interface class has now two options: 1. to handle the action directly (e.g. cp or mv on filesystems) 2. to let it handle via the copy/move methods in davcmd. ad 1) The first approach can be used when we know that no error can happen inside a tree or when the action can exactly tell which element made which error. We have to collect these and return it in a dict of the form {uri: error_code, ...} ad 2) The copytree/movetree/... methods of davcmd.py will do the recursion themselves and call for each resource the copy/move method of the interface class. Thus method will then only act on a single resource. (Thus a copycol on a normal unix filesystem actually only needs to do an mkdir as the content will be copied by the davcmd.py function. The davcmd.py method will also automatically collect all errors and return the dictionary described above. When you use 2) you also have to implement the copy() and copycol() methods in your interface class. See the example for details. To decide which approach is the best you have to decide if your application is able to generate errors inside a tree. E.g. a function which completely fails on a tree if one of the tree's childs fail is not what we need. Then 2) would be your way of doing it. Actually usually 2) is the better solution and should only be replaced by 1) if you really need it. The remaining question is if we should do the same for the DELETE method. """ ### MOVE handlers def moveone(self,src,dst,overwrite): """ move one resource with Depth=0 """ return moveone(self,src,dst,overwrite) def movetree(self,src,dst,overwrite): """ move a collection with Depth=infinity """ return movetree(self,src,dst,overwrite) ### COPY handlers def copyone(self,src,dst,overwrite): """ copy one resource with Depth=0 """ return copyone(self,src,dst,overwrite) def copytree(self,src,dst,overwrite): """ copy a collection with Depth=infinity """ return copytree(self,src,dst,overwrite) ### low level copy methods (you only need these for method 2) def copy(self,src,dst): """ copy a resource with depth==0 You don't need to bother about overwrite or not. This has been done already. return a success code or raise an exception if something fails """ return 201 def copycol(self,src,dst): """ copy a resource with depth==infinity You don't need to bother about overwrite or not. This has been done already. return a success code or raise an exception if something fails """ return 201 ### some utility functions you need to implement def exists(self,uri): """ return 1 or None depending on if a resource exists """ return None # no def is_collection(self,uri): """ return 1 or None depending on if a resource is a collection """ return None # no ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/locks.py0000644000175100001770000001761214640646222017173 0ustar00runnerdockerimport time from six.moves import urllib import uuid import logging log = logging.getLogger(__name__) import xml.dom from xml.dom import minidom from .utils import rfc1123_date, IfParser, tokenFinder from .errors import * tokens_to_lock = {} uris_to_token = {} class LockManager: """ Implements the locking backend and serves as MixIn for DAVRequestHandler """ def _init_locks(self): return tokens_to_lock, uris_to_token def _l_isLocked(self, uri): tokens, uris = self._init_locks() return uri in uris def _l_hasLock(self, token): tokens, uris = self._init_locks() return token in tokens def _l_getLockForUri(self, uri): tokens, uris = self._init_locks() return uris.get(uri, None) def _l_getLock(self, token): tokens, uris = self._init_locks() return tokens.get(token, None) def _l_delLock(self, token): tokens, uris = self._init_locks() if token in tokens: del uris[tokens[token].uri] del tokens[token] def _l_setLock(self, lock): tokens, uris = self._init_locks() tokens[lock.token] = lock uris[lock.uri] = lock def _lock_unlock_parse(self, body): doc = minidom.parseString(body) data = {} info = doc.getElementsByTagNameNS('DAV:', 'lockinfo')[0] data['lockscope'] = info.getElementsByTagNameNS('DAV:', 'lockscope')[0]\ .firstChild.localName data['locktype'] = info.getElementsByTagNameNS('DAV:', 'locktype')[0]\ .firstChild.localName data['lockowner'] = info.getElementsByTagNameNS('DAV:', 'owner') return data def _lock_unlock_create(self, uri, creator, depth, data): lock = LockItem(uri, creator, **data) iscollection = uri[-1] == '/' # very dumb collection check result = '' if depth == 'infinity' and iscollection: # locking of children/collections not yet supported pass if not self._l_isLocked(uri): self._l_setLock(lock) # because we do not handle children we leave result empty return lock.token, result def do_UNLOCK(self): """ Unlocks given resource """ dc = self.IFACE_CLASS if self._config.DAV.getboolean('verbose') is True: log.info('UNLOCKing resource %s' % self.headers) uri = urllib.parse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.parse.unquote(uri) # check lock token - must contain a dash if not self.headers.get('Lock-Token', '').find('-')>0: return self.send_status(400) token = tokenFinder(self.headers.get('Lock-Token')) if self._l_isLocked(uri): self._l_delLock(token) self.send_body(None, 204, 'OK', 'OK') def do_LOCK(self): """ Locking is implemented via in-memory caches. No data is written to disk. """ dc = self.IFACE_CLASS log.info('LOCKing resource %s' % self.headers) body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(int(l)) depth = self.headers.get('Depth', 'infinity') uri = urllib.parse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.parse.unquote(uri) log.info('do_LOCK: uri = %s' % uri) ifheader = self.headers.get('If') alreadylocked = self._l_isLocked(uri) log.info('do_LOCK: alreadylocked = %s' % alreadylocked) if body and alreadylocked: # Full LOCK request but resource already locked self.responses[423] = ('Locked', 'Already locked') return self.send_status(423) elif body and not ifheader: # LOCK with XML information data = self._lock_unlock_parse(body) token, result = self._lock_unlock_create(uri, 'unknown', depth, data) if result: self.send_body(bytes(result, 'utf-8'), 207, 'Error', 'Error', 'text/xml; charset="utf-8"') else: lock = self._l_getLock(token) self.send_body(bytes(lock.asXML(), 'utf-8'), 200, 'OK', 'OK', 'text/xml; charset="utf-8"', {'Lock-Token' : '' % token}) else: # refresh request - refresh lock timeout taglist = IfParser(ifheader) found = 0 for tag in taglist: for listitem in tag.list: token = tokenFinder(listitem) if token and self._l_hasLock(token): lock = self._l_getLock(token) timeout = self.headers.get('Timeout', 'Infinite') lock.setTimeout(timeout) # automatically refreshes found = 1 self.send_body(bytes(lock.asXML(), 'utf-8'), 200, 'OK', 'OK', 'text/xml; encoding="utf-8"') break if found: break # we didn't find any of the tokens mentioned - means # that table was cleared or another error if not found: self.send_status(412) # precondition failed class LockItem: """ Lock with support for exclusive write locks. Some code taken from webdav.LockItem from the Zope project. """ def __init__(self, uri, creator, lockowner, depth=0, timeout='Infinite', locktype='write', lockscope='exclusive', token=None, **kw): self.uri = uri self.creator = creator self.owner = lockowner self.depth = depth self.timeout = timeout self.locktype = locktype self.lockscope = lockscope self.token = token and token or self.generateToken() self.modified = time.time() def getModifiedTime(self): return self.modified def refresh(self): self.modified = time.time() def isValid(self): now = time.time() modified = self.modified timeout = self.timeout return (modified + timeout) > now def generateToken(self): return str(uuid.uuid4()) def getTimeoutString(self): t = str(self.timeout) if t[-1] == 'L': t = t[:-1] return 'Second-%s' % t def setTimeout(self, timeout): self.timeout = timeout self.modified = time.time() def asXML(self, namespace='d', discover=False): owner_str = '' if isinstance(self.owner, str): owner_str = self.owner elif isinstance(self.owner, xml.dom.minicompat.NodeList) and len(self.owner): owner_str = "".join([node.toxml() for node in self.owner[0].childNodes]) token = self.token base = ('<%(ns)s:activelock>\n' ' <%(ns)s:locktype><%(ns)s:%(locktype)s/>\n' ' <%(ns)s:lockscope><%(ns)s:%(lockscope)s/>\n' ' <%(ns)s:depth>%(depth)s\n' ' <%(ns)s:owner>%(owner)s\n' ' <%(ns)s:timeout>%(timeout)s\n' ' <%(ns)s:locktoken>\n' ' <%(ns)s:href>opaquelocktoken:%(locktoken)s\n' ' \n' ' \n' ) % { 'ns': namespace, 'locktype': self.locktype, 'lockscope': self.lockscope, 'depth': self.depth, 'owner': owner_str, 'timeout': self.getTimeoutString(), 'locktoken': token, } if discover is True: return base s = """ %s """ % base return s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/propfind.py0000644000175100001770000002667714640646222017714 0ustar00runnerdockerimport xml.dom.minidom domimpl = xml.dom.minidom.getDOMImplementation() import logging from six.moves import urllib from . import utils from .constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from .errors import DAV_Error, DAV_NotFound log = logging.getLogger(__name__) class PROPFIND: """ parse a propfind xml element and extract props It will set the following instance vars: request_class : ALLPROP | PROPNAME | PROP proplist : list of properties nsmap : map of namespaces The list of properties will contain tuples of the form (element name, ns_prefix, ns_uri) """ def __init__(self, uri, dataclass, depth, body): self.request_type = None self.nsmap = {} self.proplist = {} self.default_ns = None self._dataclass = dataclass self._depth = str(depth) self._uri = uri.rstrip('/') self._has_body = None # did we parse a body? if dataclass.verbose: log.info('PROPFIND: Depth is %s, URI is %s' % (depth, uri)) if body: self.request_type, self.proplist, self.namespaces = \ utils.parse_propfind(body) self._has_body = True def createResponse(self): """ Create the multistatus response This will be delegated to the specific method depending on which request (allprop, propname, prop) was found. If we get a PROPNAME then we simply return the list with empty values which we get from the interface class If we get an ALLPROP we first get the list of properties and then we do the same as with a PROP method. """ # check if resource exists if not self._dataclass.exists(self._uri): raise DAV_NotFound df = None if self.request_type == RT_ALLPROP: df = self.create_allprop() if self.request_type == RT_PROPNAME: df = self.create_propname() if self.request_type == RT_PROP: df = self.create_prop() if df is not None: return df # no body means ALLPROP! df = self.create_allprop() return df def create_propname(self): """ create a multistatus response for the prop names """ dc = self._dataclass # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth == "0": pnames = dc.get_propnames(self._uri) re = self.mk_propname_response(self._uri, pnames, doc) ms.appendChild(re) elif self._depth == "1": pnames = dc.get_propnames(self._uri) re = self.mk_propname_response(self._uri, pnames, doc) ms.appendChild(re) for newuri in dc.get_childs(self._uri): pnames = dc.get_propnames(newuri) re = self.mk_propname_response(newuri, pnames, doc) ms.appendChild(re) elif self._depth == 'infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() pnames = dc.get_propnames(uri) re = self.mk_propname_response(uri, pnames, doc) ms.appendChild(re) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") + b"\n" def create_allprop(self): """ return a list of all properties """ self.proplist = {} self.namespaces = [] for ns, plist in self._dataclass.get_propnames(self._uri).items(): self.proplist[ns] = plist self.namespaces.append(ns) return self.create_prop() def create_prop(self): """ handle a request This will 1. set up the -Framework 2. read the property values for each URI (which is dependant on the Depth header) This is done by the get_propvalues() method. 3. For each URI call the append_result() method to append the actual -Tag to the result document. We differ between "good" properties, which have been assigned a value by the interface class and "bad" properties, which resulted in an error, either 404 (Not Found) or 403 (Forbidden). """ # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth == "0": gp, bp = self.get_propvalues(self._uri) res = self.mk_prop_response(self._uri, gp, bp, doc) ms.appendChild(res) elif self._depth == "1": gp, bp = self.get_propvalues(self._uri) res = self.mk_prop_response(self._uri, gp, bp, doc) ms.appendChild(res) for newuri in self._dataclass.get_childs(self._uri): gp, bp = self.get_propvalues(newuri) res = self.mk_prop_response(newuri, gp, bp, doc) ms.appendChild(res) elif self._depth == 'infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() gp, bp = self.get_propvalues(uri) res = self.mk_prop_response(uri, gp, bp, doc) ms.appendChild(res) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") + b"\n" def mk_propname_response(self, uri, propnames, doc): """ make a new result element for a PROPNAME request This will simply format the propnames list. propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...} """ re = doc.createElement("D:response") if self._dataclass.baseurl: uri = self._dataclass.baseurl + '/' + '/'.join(uri.split('/')[3:]) # write href information uparts = urllib.parse.urlparse(uri) fileloc = uparts[2] href = doc.createElement("D:href") huri = doc.createTextNode(uparts[0] + '://' + '/'.join(uparts[1:2]) + urllib.parse.quote(fileloc)) href.appendChild(huri) re.appendChild(href) ps = doc.createElement("D:propstat") nsnum = 0 for ns, plist in propnames.items(): # write prop element pr = doc.createElement("D:prop") nsp = "ns" + str(nsnum) pr.setAttribute("xmlns:" + nsp, ns) nsnum += 1 # write propertynames for p in plist: pe = doc.createElement(nsp + ":" + p) pr.appendChild(pe) ps.appendChild(pr) re.appendChild(ps) return re def mk_prop_response(self, uri, good_props, bad_props, doc): """ make a new result element We differ between the good props and the bad ones for each generating an extra -Node (for each error one, that means). """ re = doc.createElement("D:response") # append namespaces to response nsnum = 0 for nsname in self.namespaces: if nsname != 'DAV:': re.setAttribute("xmlns:ns" + str(nsnum), nsname) nsnum += 1 if self._dataclass.baseurl: uri = self._dataclass.baseurl + '/' + '/'.join(uri.split('/')[3:]) # write href information uparts = urllib.parse.urlparse(uri) fileloc = uparts[2] href = doc.createElement("D:href") huri = doc.createTextNode(uparts[0] + '://' + '/'.join(uparts[1:2]) + urllib.parse.quote(fileloc)) href.appendChild(huri) re.appendChild(href) # write good properties ps = doc.createElement("D:propstat") if good_props: re.appendChild(ps) gp = doc.createElement("D:prop") for ns in good_props.keys(): if ns != 'DAV:': ns_prefix = "ns" + str(self.namespaces.index(ns)) + ":" else: ns_prefix = 'D:' for p, v in good_props[ns].items(): pe = doc.createElement(ns_prefix + str(p)) if isinstance(v, xml.dom.minidom.Element): pe.appendChild(v) elif isinstance(v, list): for val in v: pe.appendChild(val) else: if p == "resourcetype": if v == 1: ve = doc.createElement("D:collection") pe.appendChild(ve) else: ve = doc.createTextNode(v) pe.appendChild(ve) gp.appendChild(pe) ps.appendChild(gp) s = doc.createElement("D:status") t = doc.createTextNode("HTTP/1.1 200 OK") s.appendChild(t) ps.appendChild(s) re.appendChild(ps) # now write the errors! if len(list(bad_props.items())): # write a propstat for each error code for ecode in bad_props.keys(): ps = doc.createElement("D:propstat") re.appendChild(ps) bp = doc.createElement("D:prop") ps.appendChild(bp) for ns in bad_props[ecode].keys(): if ns != 'DAV:': ns_prefix = "ns" + str(self.namespaces.index(ns)) + ":" else: ns_prefix = 'D:' for p in bad_props[ecode][ns]: pe = doc.createElement(ns_prefix + str(p)) bp.appendChild(pe) s = doc.createElement("D:status") t = doc.createTextNode(utils.gen_estring(ecode)) s.appendChild(t) ps.appendChild(s) re.appendChild(ps) # return the new response element return re def get_propvalues(self, uri): """ create lists of property values for an URI We create two lists for an URI: the properties for which we found a value and the ones for which we only got an error, either because they haven't been found or the user is not allowed to read them. """ good_props = {} bad_props = {} ddc = self._dataclass for ns, plist in self.proplist.items(): good_props[ns] = {} for prop in plist: ec = 0 try: r = ddc.get_prop(uri, ns, prop) good_props[ns][prop] = r except DAV_Error as error_code: ec = error_code.args[0] # ignore props with error_code if 0 (invisible) if ec == 0: continue if ec in bad_props: if ns in bad_props[ec]: bad_props[ec][ns].append(prop) else: bad_props[ec][ns] = [prop] else: bad_props[ec] = {ns: [prop]} return good_props, bad_props ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/report.py0000644000175100001770000001046214640646222017367 0ustar00runnerdockerfrom .propfind import PROPFIND from xml.dom import minidom domimpl = minidom.getDOMImplementation() from .utils import get_parenturi class REPORT(PROPFIND): def __init__(self, uri, dataclass, depth, body): PROPFIND.__init__(self, uri, dataclass, depth, body) doc = minidom.parseString(body) self.filter = doc.documentElement def create_propname(self): """ create a multistatus response for the prop names """ dc=self._dataclass # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth=="0": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): pnames=dc.get_propnames(self._uri) re=self.mk_propname_response(self._uri,pnames, doc) ms.appendChild(re) elif self._depth=="1": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): pnames=dc.get_propnames(self._uri) re=self.mk_propname_response(self._uri,pnames, doc) ms.appendChild(re) for newuri in dc.get_childs(self._uri, self.filter): pnames=dc.get_propnames(newuri) re=self.mk_propname_response(newuri,pnames, doc) ms.appendChild(re) elif self._depth=='infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() if uri in self._dataclass.get_childs(get_parenturi(uri), self.filter): pnames=dc.get_propnames(uri) re=self.mk_propname_response(uri,pnames, doc) ms.appendChild(re) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") + b"\n" def create_prop(self): """ handle a request This will 1. set up the -Framework 2. read the property values for each URI (which is dependant on the Depth header) This is done by the get_propvalues() method. 3. For each URI call the append_result() method to append the actual -Tag to the result document. We differ between "good" properties, which have been assigned a value by the interface class and "bad" properties, which resulted in an error, either 404 (Not Found) or 403 (Forbidden). """ # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth=="0": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): gp,bp=self.get_propvalues(self._uri) res=self.mk_prop_response(self._uri,gp,bp,doc) ms.appendChild(res) elif self._depth=="1": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): gp,bp=self.get_propvalues(self._uri) res=self.mk_prop_response(self._uri,gp,bp,doc) ms.appendChild(res) for newuri in self._dataclass.get_childs(self._uri, self.filter): gp,bp=self.get_propvalues(newuri) res=self.mk_prop_response(newuri,gp,bp,doc) ms.appendChild(res) elif self._depth=='infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() if uri in self._dataclass.get_childs(get_parenturi(uri), self.filter): gp,bp=self.get_propvalues(uri) res=self.mk_prop_response(uri,gp,bp,doc) ms.appendChild(res) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") + b"\n" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/status.py0000644000175100001770000000105214640646222017372 0ustar00runnerdocker STATUS_CODES={ 100: "Continue", 102: "Processing", 200: "Ok", 201: "Created", 204: "No Content", 207: "Multi-Status", 400: "Bad Request", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 409: "Conflict", 412: "Precondition failed", 422: "Unprocessable Entity", 423: "Locked", 424: "Failed Dependency", 502: "Bad Gateway", 507: "Insufficient Storage" } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/lib/utils.py0000755000175100001770000001531114640646222017215 0ustar00runnerdockerimport time import re import os from xml.dom import minidom from six.moves import urllib from .constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from six.moves.BaseHTTPServer import BaseHTTPRequestHandler def gen_estring(ecode): """ generate an error string from the given code """ ec=int(ecode) if ec in BaseHTTPRequestHandler.responses: return "HTTP/1.1 %s %s" %(ec, BaseHTTPRequestHandler.responses[ec][0]) else: return "HTTP/1.1 %s" %(ec) def parse_propfind(xml_doc): """ Parse an propfind xml file and return a list of props """ doc = minidom.parseString(xml_doc) request_type=None props={} namespaces=[] if doc.getElementsByTagNameNS("DAV:", "allprop"): request_type = RT_ALLPROP elif doc.getElementsByTagNameNS("DAV:", "propname"): request_type = RT_PROPNAME else: request_type = RT_PROP for i in doc.getElementsByTagNameNS("DAV:", "prop"): for e in i.childNodes: if e.nodeType != minidom.Node.ELEMENT_NODE: continue ns = e.namespaceURI ename = e.localName if ns in props: props[ns].append(ename) else: props[ns]=[ename] namespaces.append(ns) return request_type,props,namespaces def create_treelist(dataclass,uri): """ create a list of resources out of a tree This function is used for the COPY, MOVE and DELETE methods uri - the root of the subtree to flatten It will return the flattened tree as list """ queue=[uri] list=[uri] while len(queue): element=queue[-1] if dataclass.is_collection(element): childs=dataclass.get_childs(element) else: childs=[] if len(childs): list=list+childs # update queue del queue[-1] if len(childs): queue=queue+childs return list def is_prefix(uri1,uri2): """ returns True if uri1 is a prefix of uri2 """ path1 = urllib.parse.urlparse(uri1).path path2 = urllib.parse.urlparse(uri2).path return os.path.commonpath([path1, path2]) == path1 def quote_uri(uri): """ quote an URL but not the protocol part """ up=urllib.parse.urlparse(uri) np=urllib.parse.quote(up[2]) return urllib.parse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) def get_uriparentpath(uri): """ extract the uri path and remove the last element """ up=urllib.parse.urlparse(uri) return "/".join(up[2].split("/")[:-1]) def get_urifilename(uri): """ extract the uri path and return the last element """ up=urllib.parse.urlparse(uri) return up[2].split("/")[-1] def get_parenturi(uri): """ return the parent of the given resource""" up=urllib.parse.urlparse(uri) np="/".join(up[2].split("/")[:-1]) return urllib.parse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) ### XML utilities def make_xmlresponse(result): """ construct a response from a dict of uri:error_code elements """ doc = minidom.getDOMImplementation().createDocument(None, "multistatus", None) doc.documentElement.setAttribute("xmlns:D","DAV:") doc.documentElement.tagName = "D:multistatus" for el,ec in result.items(): re=doc.createElementNS("DAV:","response") hr=doc.createElementNS("DAV:","href") st=doc.createElementNS("DAV:","status") huri=doc.createTextNode(quote_uri(el)) t=doc.createTextNode(gen_estring(ec)) st.appendChild(t) hr.appendChild(huri) re.appendChild(hr) re.appendChild(st) doc.documentElement.appendChild(re) return doc.toxml(encoding="utf-8") + b"\n" # taken from App.Common weekday_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] weekday_full = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def rfc1123_date(ts=None): # Return an RFC 1123 format date string, required for # use in HTTP Date headers per the HTTP 1.1 spec. # 'Fri, 10 Nov 2000 16:21:09 GMT' if ts is None: ts=time.time() year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts) return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekday_abbr[wd], day, monthname[month], year, hh, mm, ss) def iso8601_date(ts=None): # Return an ISO 8601 formatted date string, required # for certain DAV properties. # '2000-11-10T16:21:09-08:00 if ts is None: ts=time.time() return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts)) def rfc850_date(ts=None): # Return an HTTP-date formatted date string. # 'Friday, 10-Nov-00 16:21:09 GMT' if ts is None: ts=time.time() year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts) return "%s, %02d-%3s-%2s %02d:%02d:%02d GMT" % ( weekday_full[wd], day, monthname[month], str(year)[2:], hh, mm, ss) ### If: header handling support. IfParser returns a sequence of ### TagList objects in the order they were parsed which can then ### be used in WebDAV methods to decide whether an operation can ### proceed or to raise HTTP Error 412 (Precondition failed) IfHdr = re.compile( r"(?P<.+?>)?\s*\((?P[^)]+)\)" ) ListItem = re.compile( r"(?Pnot)?\s*(?P<[a-zA-Z]+:[^>]*>|\[.*?\])", re.I) class TagList: def __init__(self): self.resource = None self.list = [] self.NOTTED = 0 def IfParser(hdr): out = [] i = 0 while 1: m = IfHdr.search(hdr[i:]) if not m: break i = i + m.end() tag = TagList() tag.resource = m.group('resource') if tag.resource: # We need to delete < > tag.resource = tag.resource[1:-1] listitem = m.group('listitem') tag.NOTTED, tag.list = ListParser(listitem) out.append(tag) return out def tokenFinder(token): # takes a string like ' and returns the token # part. if not token: return None # An empty string was passed in if token[0] == '[': return None # An Etag was passed in if token[0] == '<': token = token[1:-1] return token[token.find(':')+1:] def ListParser(listitem): out = [] NOTTED = 0 i = 0 while 1: m = ListItem.search(listitem[i:]) if not m: break i = i + m.end() out.append(m.group('listitem')) if m.group('not'): NOTTED = 1 return NOTTED, out ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/pywebdav/server/0000755000175100001770000000000014640646230016236 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/__init__.py0000644000175100001770000000000114640646222020337 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/config.ini0000644000175100001770000000207614640646222020212 0ustar00runnerdocker # PyWebDAV config.ini # Read documents before editing this file # Created 11:48 10-08-2006 By Vince Spicer [MySQL] # Mysql server information host=localhost port=3306 user=root passwd=rootpw # Auth Database Table, Must exists in database prior to firstrun dbtable=webDav # Create User Database Table and Insert system user # Disable after the Table is created; for performance reasons firstrun=0 [DAV] # Verbose? # verbose enabled is like loglevel = INFO verbose = 1 #log level : DEBUG, INFO, WARNING, ERROR, CRITICAL (Default is WARNING) #loglevel = WARNING # main directory directory = /home/spamies/tmp # Server address port = 8081 host = localhost # disable auth noauth = 0 # Enable mysql auth mysql_auth=0 # admin user user = test password = test00 # daemonize? daemonize = 0 daemonaction = start # instance counter counter = 0 # mimetypes support mimecheck = 1 # webdav level (1 = webdav level 2) lockemulation = 1 # dav server base url baseurl = # internal features #chunked_http_response = 1 #http_request_use_iterator = 0 #http_response_use_iterator = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/daemonize.py0000644000175100001770000001246114640646222020570 0ustar00runnerdocker#Copyright (c) 2005 Simon Pamies (s.pamies@banality.de) #Copyright (c) 2003 Clark Evans #Copyright (c) 2002 Noah Spurrier #Copyright (c) 2001 Juergen Hermann # #This library is free software; you can redistribute it and/or #modify it under the terms of the GNU Library General Public #License as published by the Free Software Foundation; either #version 2 of the License, or (at your option) any later version. # #This library 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 #Library General Public License for more details. # #You should have received a copy of the GNU Library General Public #License along with this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA ''' This module is used to fork the current process into a daemon. Almost none of this is necessary (or advisable) if your daemon is being started by inetd. In that case, stdin, stdout and stderr are all set up for you to refer to the network connection, and the fork()s and session manipulation should not be done (to avoid confusing inetd). Only the chdir() and umask() steps remain as useful. References: UNIX Programming FAQ 1.7 How do I get my program to act like a daemon? http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 Advanced Programming in the Unix Environment W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7. History: 2005/06/23 by Simon Pamies 2001/07/10 by Juergen Hermann 2002/08/28 by Noah Spurrier 2003/02/24 by Clark Evans http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 ''' import sys, os, time from signal import SIGTERM def deamonize(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile=None, startmsg = 'started with pid %s' ): ''' This forks the current process into a daemon. The stdin, stdout, and stderr arguments are file names that will be opened and be used to replace the standard file descriptors in sys.stdin, sys.stdout, and sys.stderr. These arguments are optional and default to /dev/null. Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect. ''' # Do first fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit first parent. except OSError as e: sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment. os.chdir("/") os.umask(0) os.setsid() # Do second fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit second parent. except OSError as e: sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) # Open file descriptors and print start message if not stderr: stderr = stdout si = open(stdin, 'r') so = open(stdout, 'a+') se = open(stderr, 'a+', 0) pid = str(os.getpid()) sys.stderr.write("\n%s\n" % startmsg % pid) sys.stderr.flush() if pidfile: open(pidfile,'w+').write("%s\n" % pid) if sys.stdin.closed: sys.stdin = open('/dev/null', 'r') if sys.stdout.closed: sys.stdout = open('/dev/null', 'a+') if sys.stderr.closed: sys.stderr = open('/dev/null', 'a+') # Redirect standard file descriptors. os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) def startstop(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile='pid.txt', startmsg = 'started with pid %s', action='start' ): if action: try: pf = open(pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if 'stop' == action or 'restart' == action: if not pid: mess = "Could not stop, pid file '%s' missing.\n" sys.stderr.write(mess % pidfile) if 'stop' == action: sys.exit(1) action = 'start' pid = None else: try: while 1: os.kill(pid,SIGTERM) time.sleep(1) except OSError as err: err = str(err) if err.find("No such process") > 0: os.remove(pidfile) if 'stop' == action: sys.exit(0) action = 'start' pid = None else: print(str(err)) sys.exit(1) if 'start' == action: if pid: mess = "Start aborted since pid file '%s' exists.\n" sys.stderr.write(mess % pidfile) sys.exit(1) deamonize(stdout,stderr,stdin,pidfile,startmsg) return if 'status' == action: if not pid: sys.stderr.write('Status: Stopped\n') else: sys.stderr.write('Status: Running\n') sys.exit(0) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/fileauth.py0000644000175100001770000000345014640646222020414 0ustar00runnerdocker#Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de) # #This library is free software; you can redistribute it and/or #modify it under the terms of the GNU Library General Public #License as published by the Free Software Foundation; either #version 2 of the License, or (at your option) any later version. # #This library 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 #Library General Public License for more details. # #You should have received a copy of the GNU Library General Public #License along with this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA """ Python WebDAV Server. This is an example implementation of a DAVserver using the DAV package. """ import logging from pywebdav.lib.WebDAVServer import DAVRequestHandler from pywebdav.lib.dbconn import Mconn from .fshandler import FilesystemHandler log = logging.getLogger() class DAVAuthHandler(DAVRequestHandler): """ Provides authentication based on parameters. The calling class has to inject password and username into this. (Variables: auth_user and auth_pass) """ # Do not forget to set IFACE_CLASS by caller # ex.: IFACE_CLASS = FilesystemHandler('/tmp', 'http://localhost/') verbose = False def _log(self, message): if self.verbose: log.info(message) def get_userinfo(self,user,pw,command): """ authenticate user """ if user == self._config.DAV.user and pw == self._config.DAV.password: log.info('Successfully authenticated user %s' % user) return 1 log.info('Authentication failed for user %s' % user) return 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/fshandler.py0000644000175100001770000003013414640646222020560 0ustar00runnerdockerimport os import textwrap import logging import types import shutil from io import StringIO from six.moves import urllib from pywebdav.lib.constants import COLLECTION, OBJECT from pywebdav.lib.errors import * from pywebdav.lib.iface import * from pywebdav.lib.davcmd import copyone, copytree, moveone, movetree, delone, deltree from html import escape log = logging.getLogger(__name__) BUFFER_SIZE = 128 * 1000 # include magic support to correctly determine mimetypes MAGIC_AVAILABLE = False try: import mimetypes MAGIC_AVAILABLE = True log.info('Mimetype support ENABLED') except ImportError: log.info('Mimetype support DISABLED') pass class Resource: # XXX this class is ugly def __init__(self, fp, file_size): self.__fp = fp self.__file_size = file_size def __len__(self): return self.__file_size def __iter__(self): while 1: data = self.__fp.read(BUFFER_SIZE) if not data: break yield data time.sleep(0.005) self.__fp.close() def read(self, length = 0): if length == 0: length = self.__file_size data = self.__fp.read(length) return data class FilesystemHandler(dav_interface): """ Model a filesystem for DAV This class models a regular filesystem for the DAV server The basic URL will be http://localhost/ And the underlying filesystem will be /tmp Thus http://localhost/gfx/pix will lead to /tmp/gfx/pix """ def __init__(self, directory, uri, verbose=False): self.setDirectory(directory) self.setBaseURI(uri) # should we be verbose? self.verbose = verbose log.info('Initialized with %s %s' % (directory, uri)) def setDirectory(self, path): """ Sets the directory """ if not os.path.isdir(path): raise Exception('%s not must be a directory!' % path) self.directory = path def setBaseURI(self, uri): """ Sets the base uri """ self.baseuri = uri def uri2local(self,uri): """ map uri in baseuri and local part """ uparts=urllib.parse.urlparse(uri) fileloc=uparts[2][1:] filename=os.path.join(self.directory, fileloc) filename=os.path.normpath(filename) return filename def local2uri(self,filename): """ map local filename to self.baseuri """ pnum=len(self.directory.replace("\\","/").split("/")) parts=filename.replace("\\","/").split("/")[pnum:] sparts="/"+"/".join(parts) uri=urllib.parse.urljoin(self.baseuri,sparts) return uri def get_childs(self, uri, filter=None): """ return the child objects as self.baseuris for the given URI """ fileloc=self.uri2local(uri) filelist=[] if os.path.exists(fileloc): if os.path.isdir(fileloc): try: files=os.listdir(fileloc) except: raise DAV_NotFound for file in files: newloc=os.path.join(fileloc,file) filelist.append(self.local2uri(newloc)) log.info('get_childs: Childs %s' % filelist) return filelist def _get_listing(self, path): """Return a directory listing similar to http.server's""" template = textwrap.dedent(""" Directory listing for {path}

Directory listing for {path}


    {items}

""") escapeditems = (escape(i) + ('/' if os.path.isdir(os.path.join(path, i)) else '') for i in os.listdir(path) if not i.startswith('.')) htmlitems = "\n".join('
  • {i}
  • '.format(i=i) for i in escapeditems) return template.format(items=htmlitems, path=path) def get_data(self,uri, range = None): """ return the content of an object """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): file_size = os.path.getsize(path) if range is None: fp=open(path,"rb") log.info('Serving content of %s' % uri) return Resource(fp, file_size) else: if range[1] == '': range[1] = file_size else: range[1] = int(range[1]) if range[0] == '': range[0] = file_size - range[1] else: range[0] = int(range[0]) if range[0] > file_size: raise DAV_Requested_Range_Not_Satisfiable if range[1] > file_size: range[1] = file_size fp=open(path,"rb") fp.seek(range[0]) log.info('Serving range %s -> %s content of %s' % (range[0], range[1], uri)) return Resource(fp, range[1] - range[0]) elif os.path.isdir(path): msg = self._get_listing(path) return Resource(StringIO(msg), len(msg)) else: # also raise an error for collections # don't know what should happen then.. log.info('get_data: %s not found' % path) raise DAV_NotFound def _get_dav_resourcetype(self,uri): """ return type of object """ path=self.uri2local(uri) if os.path.isfile(path): return OBJECT elif os.path.isdir(path): return COLLECTION raise DAV_NotFound def _get_dav_displayname(self,uri): raise DAV_Secret # do not show def _get_dav_getcontentlength(self,uri): """ return the content length of an object """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): s=os.stat(path) return str(s[6]) return '0' def get_lastmodified(self,uri): """ return the last modified date of the object """ path=self.uri2local(uri) if os.path.exists(path): s=os.stat(path) date=s[8] return date raise DAV_NotFound def get_creationdate(self,uri): """ return the creation date of the object """ path=self.uri2local(uri) if os.path.exists(path): s=os.stat(path) date=s[9] return date raise DAV_NotFound def _get_dav_getcontenttype(self, uri): """ find out yourself! """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): if MAGIC_AVAILABLE is False \ or self.mimecheck is False: return 'application/octet-stream' else: ret, encoding = mimetypes.guess_type(path) # for non mimetype related result we # simply return an appropriate type if ret.find('/')==-1: if ret.find('text')>=0: return 'text/plain' else: return 'application/octet-stream' else: return ret elif os.path.isdir(path): return "httpd/unix-directory" raise DAV_NotFound('Could not find %s' % path) def put(self, uri, data, content_type=None): """ put the object into the filesystem """ path=self.uri2local(uri) try: with open(path, "bw+") as fp: if isinstance(data, types.GeneratorType): for d in data: fp.write(d) else: if data: fp.write(data) log.info('put: Created %s' % uri) except Exception as e: log.info('put: Could not create %s, %r', uri, e) raise DAV_Error(424) return None def mkcol(self,uri): """ create a new collection """ path=self.uri2local(uri) # remove trailing slash if path[-1]=="/": path=path[:-1] # test if file already exists if os.path.exists(path): raise DAV_Error(405) # test if parent exists h,t=os.path.split(path) if not os.path.exists(h): raise DAV_Error(409) # test, if we are allowed to create it try: os.mkdir(path) log.info('mkcol: Created new collection %s' % path) return 201 except: log.info('mkcol: Creation of %s denied' % path) raise DAV_Forbidden ### ?? should we do the handler stuff for DELETE, too ? ### (see below) def rmcol(self,uri): """ delete a collection """ path=self.uri2local(uri) if not os.path.exists(path): raise DAV_NotFound try: shutil.rmtree(path) except OSError: raise DAV_Forbidden # forbidden return 204 def rm(self,uri): """ delete a normal resource """ path=self.uri2local(uri) if not os.path.exists(path): raise DAV_NotFound try: os.unlink(path) except OSError as ex: log.info('rm: Forbidden (%s)' % ex) raise DAV_Forbidden # forbidden return 204 ### ### DELETE handlers (examples) ### (we use the predefined methods in davcmd instead of doing ### a rm directly ### def delone(self,uri): """ delete a single resource You have to return a result dict of the form uri:error_code or None if everything's ok """ return delone(self,uri) def deltree(self,uri): """ delete a collection You have to return a result dict of the form uri:error_code or None if everything's ok """ return deltree(self,uri) ### ### MOVE handlers (examples) ### def moveone(self,src,dst,overwrite): """ move one resource with Depth=0 """ return moveone(self,src,dst,overwrite) def movetree(self,src,dst,overwrite): """ move a collection with Depth=infinity """ return movetree(self,src,dst,overwrite) ### ### COPY handlers ### def copyone(self,src,dst,overwrite): """ copy one resource with Depth=0 """ return copyone(self,src,dst,overwrite) def copytree(self,src,dst,overwrite): """ copy a collection with Depth=infinity """ return copytree(self,src,dst,overwrite) ### ### copy methods. ### This methods actually copy something. low-level ### They are called by the davcmd utility functions ### copytree and copyone (not the above!) ### Look in davcmd.py for further details. ### def copy(self,src,dst): """ copy a resource from src to dst """ srcfile=self.uri2local(src) dstfile=self.uri2local(dst) try: shutil.copy(srcfile, dstfile) except (OSError, IOError): log.info('copy: forbidden') raise DAV_Error(409) def copycol(self, src, dst): """ copy a collection. As this is not recursive (the davserver recurses itself) we will only create a new directory here. For some more advanced systems we might also have to copy properties from the source to the destination. """ return self.mkcol(dst) def exists(self,uri): """ test if a resource exists """ path=self.uri2local(uri) if os.path.exists(path): return 1 return None def is_collection(self,uri): """ test if the given uri is a collection """ path=self.uri2local(uri) if os.path.isdir(path): return 1 else: return 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/mysqlauth.py0000644000175100001770000000366014640646222020645 0ustar00runnerdocker#Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de) # #This library is free software; you can redistribute it and/or #modify it under the terms of the GNU Library General Public #License as published by the Free Software Foundation; either #version 2 of the License, or (at your option) any later version. # #This library 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 #Library General Public License for more details. # #You should have received a copy of the GNU Library General Public #License along with this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA from .fileauth import DAVAuthHandler import sys class MySQLAuthHandler(DAVAuthHandler): """ Provides authentication based on a mysql table """ def get_userinfo(self,user,pw,command): """ authenticate user """ # Commands that need write access nowrite=['OPTIONS','PROPFIND','GET'] Mysql=self._config.MySQL DB=Mconn(Mysql.user,Mysql.passwd,Mysql.host,Mysql.port,Mysql.dbtable) if self.verbose: print(user,command, file=sys.stderr) qry="select * from %s.Users where User='%s' and Pass='%s'"%(Mysql.dbtable,user,pw) Auth=DB.execute(qry) if len(Auth) == 1: can_write=Auth[0][3] if not can_write and not command in nowrite: self._log('Authentication failed for user %s using command %s' %(user,command)) return 0 else: self._log('Successfully authenticated user %s writable=%s' % (user,can_write)) return 1 else: self._log('Authentication failed for user %s' % user) return 0 self._log('Authentication failed for user %s' % user) return 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/pywebdav/server/server.py0000755000175100001770000003121014640646222020117 0ustar00runnerdocker#!/usr/bin/env python """ Python WebDAV Server. This is an example implementation of a DAVserver using the DAV package. """ import getopt, sys, os import logging logging.basicConfig(level=logging.WARNING) log = logging.getLogger('pywebdav') from six.moves.BaseHTTPServer import HTTPServer from six.moves.socketserver import ThreadingMixIn try: import pywebdav.lib import pywebdav.server except ImportError: print('pywebdav.lib package not found! Please install into site-packages or set PYTHONPATH!') sys.exit(2) from pywebdav.server.fileauth import DAVAuthHandler from pywebdav.server.mysqlauth import MySQLAuthHandler from pywebdav.server.fshandler import FilesystemHandler from pywebdav.server.daemonize import startstop from pywebdav.lib.INI_Parse import Configuration from pywebdav import __version__, __author__ LEVELS = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL} class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): """Handle requests in a separate thread.""" def runserver( port = 8008, host='localhost', directory='/tmp', verbose = False, noauth = False, user = '', password = '', handler = DAVAuthHandler, server = ThreadedHTTPServer): directory = directory.strip() directory = directory.rstrip('/') host = host.strip() if not os.path.isdir(directory): os.makedirs(directory) # log.error('%s is not a valid directory!' % directory) # return sys.exit(233) # basic checks against wrong hosts if host.find('/') != -1 or host.find(':') != -1: log.error('Malformed host %s' % host) return sys.exit(233) # no root directory if directory == '/': log.error('Root directory not allowed!') sys.exit(233) # dispatch directory and host to the filesystem handler # This handler is responsible from where to take the data handler.IFACE_CLASS = FilesystemHandler(directory, 'http://%s:%s/' % (host, port), verbose ) # put some extra vars handler.verbose = verbose if noauth: log.warning('Authentication disabled!') handler.DO_AUTH = False log.info('Serving data from %s' % directory) if handler._config.DAV.getboolean('lockemulation') is False: log.info('Deactivated LOCK, UNLOCK (WebDAV level 2) support') handler.IFACE_CLASS.mimecheck = True if handler._config.DAV.getboolean('mimecheck') is False: handler.IFACE_CLASS.mimecheck = False log.info('Disabled mimetype sniffing (All files will have type application/octet-stream)') if handler._config.DAV.baseurl: log.info('Using %s as base url for PROPFIND requests' % handler._config.DAV.baseurl) handler.IFACE_CLASS.baseurl = handler._config.DAV.baseurl # initialize server on specified port runner = server( (host, port), handler ) print(('Listening on %s (%i)' % (host, port))) try: runner.serve_forever() except KeyboardInterrupt: log.info('Killed by user') usage = """PyWebDAV server (version %s) Standalone WebDAV server Make sure to activate LOCK, UNLOCK using parameter -J if you want to use clients like Windows Explorer or Mac OS X Finder that expect LOCK working for write support. Usage: ./server.py [OPTIONS] Parameters: -c, --config Specify a file where configuration is specified. In this file you can specify options for a running server. For an example look at the config.ini in this directory. -D, --directory Directory where to serve data from The user that runs this server must have permissions on that directory. NEVER run as root! Default directory is /tmp -B, --baseurl Behind a proxy pywebdav needs to generate other URIs for PROPFIND. If you are experiencing problems with links or such when behind a proxy then just set this to a sensible default (e.g. http://dav.domain.com). Make sure that you include the protocol. -H, --host Host where to listen on (default: localhost) -P, --port Port to bind server to (default: 8008) -u, --user Username for authentication -p, --password Password for given user -n, --noauth Pass parameter if server should not ask for authentication This means that every user has access -m, --mysql Pass this parameter if you want MySQL based authentication. If you want to use MySQL then the usage of a configuration file is mandatory. -J, --nolock Deactivate LOCK and UNLOCK mode (WebDAV Version 2). -M, --nomime Deactivate mimetype sniffing. Sniffing is based on magic numbers detection but can be slow under heavy load. If you are experiencing speed problems try to use this parameter. -T, --noiter Deactivate iterator. Use this if you encounter file corruption during download. Also disables chunked body response. -i, --icounter If you want to run multiple instances then you have to give each instance it own number so that logfiles and such can be identified. Default is 0 -d, --daemon Make server act like a daemon. That means that it is going to background mode. All messages are redirected to logfiles (default: /tmp/pydav.log and /tmp/pydav.err). You need to pass one of the following values to this parameter start - Start daemon stop - Stop daemon restart - Restart complete server status - Returns status of server -v, --verbose Be verbose. -l, --loglevel Select the log level : DEBUG, INFO, WARNING, ERROR, CRITICAL Default is WARNING -h, --help Show this screen Please send bug reports and feature requests to %s """ % (__version__, __author__) def setupDummyConfig(**kw): class DummyConfigDAV: def __init__(self, **kw): self.__dict__.update(**kw) def getboolean(self, name): return (str(getattr(self, name, 0)) in ('1', "yes", "true", "on", "True")) class DummyConfig: DAV = DummyConfigDAV(**kw) return DummyConfig() def run(): verbose = False directory = '/tmp' port = 8008 host = 'localhost' noauth = False user = '' password = '' daemonize = False daemonaction = 'start' counter = 0 mysql = False lockemulation = True http_response_use_iterator = True chunked_http_response = True configfile = '' mimecheck = True loglevel = 'warning' baseurl = '' # parse commandline try: opts, args = getopt.getopt(sys.argv[1:], 'P:D:H:d:u:p:nvhmJi:c:Ml:TB:', ['host=', 'port=', 'directory=', 'user=', 'password=', 'daemon=', 'noauth', 'help', 'verbose', 'mysql', 'icounter=', 'config=', 'nolock', 'nomime', 'loglevel', 'noiter', 'baseurl=']) except getopt.GetoptError as e: print(usage) print('>>>> ERROR: %s' % str(e)) sys.exit(2) for o,a in opts: if o in ['-i', '--icounter']: counter = int(str(a).strip()) if o in ['-m', '--mysql']: mysql = True if o in ['-M', '--nomime']: mimecheck = False if o in ['-J', '--nolock']: lockemulation = False if o in ['-T', '--noiter']: http_response_use_iterator = False chunked_http_response = False if o in ['-c', '--config']: configfile = a if o in ['-D', '--directory']: directory = a if o in ['-H', '--host']: host = a if o in ['-P', '--port']: port = a if o in ['-v', '--verbose']: verbose = True if o in ['-l', '--loglevel']: loglevel = a.lower() if o in ['-h', '--help']: print(usage) sys.exit(2) if o in ['-n', '--noauth']: noauth = True if o in ['-u', '--user']: user = a if o in ['-p', '--password']: password = a if o in ['-d', '--daemon']: daemonize = True daemonaction = a if o in ['-B', '--baseurl']: baseurl = a.lower() # This feature are disabled because they are unstable http_request_use_iterator = 0 conf = None if configfile != '': log.info('Reading configuration from %s' % configfile) conf = Configuration(configfile) dv = conf.DAV verbose = bool(int(dv.verbose)) loglevel = dv.get('loglevel', loglevel).lower() directory = dv.directory port = dv.port host = dv.host noauth = bool(int(dv.noauth)) user = dv.user password = dv.password daemonize = bool(int(dv.daemonize)) if daemonaction != 'stop': daemonaction = dv.daemonaction counter = int(dv.counter) lockemulation = dv.lockemulation mimecheck = dv.mimecheck if 'chunked_http_response' not in dv: dv.set('chunked_http_response', chunked_http_response) if 'http_request_use_iterator' not in dv: dv.set('http_request_use_iterator', http_request_use_iterator) if 'http_response_use_iterator' not in dv: dv.set('http_response_use_iterator', http_response_use_iterator) else: _dc = { 'verbose' : verbose, 'directory' : directory, 'port' : port, 'host' : host, 'noauth' : noauth, 'user' : user, 'password' : password, 'daemonize' : daemonize, 'daemonaction' : daemonaction, 'counter' : counter, 'lockemulation' : lockemulation, 'mimecheck' : mimecheck, 'chunked_http_response': chunked_http_response, 'http_request_use_iterator': http_request_use_iterator, 'http_response_use_iterator': http_response_use_iterator, 'baseurl' : baseurl } conf = setupDummyConfig(**_dc) if verbose and (LEVELS[loglevel] > LEVELS['info']): loglevel = 'info' logging.getLogger().setLevel(LEVELS[loglevel]) formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') for handler in logging.getLogger().handlers: handler.setFormatter(formatter) if mysql == True and configfile == '': log.error('You can only use MySQL with configuration file!') sys.exit(3) if daemonaction != 'stop': log.info('Starting up PyWebDAV server (version %s)' % __version__) else: log.info('Stopping PyWebDAV server (version %s)' % __version__) if not noauth and daemonaction not in ['status', 'stop']: if not user: print(usage) print('>> ERROR: No parameter specified!', file=sys.stderr) print('>> Example: davserver -D /tmp -n', file=sys.stderr) sys.exit(3) if daemonaction == 'status': log.info('Checking for state...') if type(port) == type(''): port = int(port.strip()) log.info('chunked_http_response feature %s' % (conf.DAV.getboolean('chunked_http_response') and 'ON' or 'OFF' )) log.info('http_request_use_iterator feature %s' % (conf.DAV.getboolean('http_request_use_iterator') and 'ON' or 'OFF' )) log.info('http_response_use_iterator feature %s' % (conf.DAV.getboolean('http_response_use_iterator') and 'ON' or 'OFF' )) if daemonize: # check if pid file exists if os.path.exists('/tmp/pydav%s.pid' % counter) and daemonaction not in ['status', 'stop']: log.error( 'Found another instance! Either use -i to specifiy another instance number or remove /tmp/pydav%s.pid!' % counter) sys.exit(3) startstop(stdout='/tmp/pydav%s.log' % counter, stderr='/tmp/pydav%s.err' % counter, pidfile='/tmp/pydav%s.pid' % counter, startmsg='>> Started PyWebDAV (PID: %s)', action=daemonaction) # start now handler = DAVAuthHandler if mysql == True: handler = MySQLAuthHandler # injecting options handler._config = conf runserver(port, host, directory, verbose, noauth, user, password, handler=handler) if __name__ == '__main__': run() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/setup.cfg0000644000175100001770000000004614640646230014730 0ustar00runnerdocker[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/setup.py0000644000175100001770000000304114640646222014620 0ustar00runnerdocker#!/usr/bin/env python from setuptools import setup, find_packages from io import open import os import pywebdav README = open(os.path.join(os.path.dirname(__file__), 'README.md'), 'r', encoding='utf-8').read() setup(name='PyWebDAV3', description=pywebdav.__doc__, author=pywebdav.__author__, author_email=pywebdav.__email__, maintainer=pywebdav.__author__, maintainer_email=pywebdav.__email__, use_git_versioner="gitlab:desc:snapshot", url='https://github.com/andrewleech/PyWebDAV3', platforms=['Unix', 'Windows'], license=pywebdav.__license__, version=pywebdav.__version__, long_description=README, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: GNU General Public License (GPL)', 'Operating System :: MacOS :: MacOS X', 'Operating System :: POSIX', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries', ], keywords=['webdav', 'server', 'dav', 'standalone', 'library', 'gpl', 'http', 'rfc2518', 'rfc 2518' ], packages=find_packages(), entry_points={ 'console_scripts': ['davserver = pywebdav.server.server:run'] }, install_requires = ['six'], setup_requires=['git-versioner'], ) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1719880856.162574 pywebdav3-0.11.0/test/0000755000175100001770000000000014640646230014066 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/test/.gitignore0000644000175100001770000000001614640646222016054 0ustar00runnerdocker/litmus-0.13/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1719880850.0 pywebdav3-0.11.0/test/litmus-0.13.tar.gz0000644000175100001770000162111414640646222017120 0ustar00runnerdockerN\{sFϿħS\k)ERHA.)2(DI'FDX6~ٿsx}΃9r˄{u>l{HE98+?xٵnzNHݧ&mU/z^wEE^ ɯ|oKg'J2q;]xNݞM?'i0q?jsfνag맂%"Nx>s,S7l]/B!H0` {,у'xgl~ұE=Mfgn8~mLa8FӦw(WxG.,vWoFš3yYD|$`QkK,s5oy&%"9H8%P1ꓽ&Q6O8e𸰓 z0}]4BZŝAxPkp&@eV4^Ng)#c''ZQSٹcIKw1 k {0;=;q4zHt|F4Ϋw[ﰿERִybR'ﴄ7ڮ~[(+ybpG~’.J̔Nw8Ӑ<9_ɅӋCi;S!E  EDt%EQHA殔 E&d1]yճ>4 }Y*f]V,ֺZkXڌK9s~fܶȁ=pY!lAЂ *^F!8x7Z}kM}7牮-kX6زkW hKi8dV{4\Ƃ'< VZDO:ML[*B.ݴ@AT(Ya|Ck C2/xEd)}pJDQJq 3g!>Z瘻'Lznlv8lWw<< qi80'4otPX1K>N.DDn'l Vj%?[ ֙pu]ǂ#X\ t7UA?A 0 d32({@ zAВp>DY<`(["]u?{Ƣ-xUb;)k_pׇKlCbdycF6(%4 bgLnE෤7b. |n?n1 ρi8'(2,r$~=C.{~>}HT9 aaNxz^Mg/'{BϷ@wHIˢZΒZ6pR?zԶpbaH.I$tcȁwYm9flc&Rŵ'9*V a:*uj5oU6^_12{C"6Ei3Di*mkGt>({o;j,0E>s 6•r>!ox0]30md-YAϭeC h-|@(-xch²Ss R% {ର0prA\8@ϾOC9ٛg?xxn.uTx~sP#*i-Ly@P$WNUrocjfPж»0ЏC09xP=Az\ao֕ G,H\O=Hrtw1(yIpUNV5!7RŒ4mV  v8WG7Y/ .kNU2<.DqT1 VB1CGdT^YdKdmr*s5[l SCWȨUQ Ӌu dޭCeTJ e>ڛƚnGvry3(g)u?s1+>2n~NPt\_Fs||fmZ!\~nƳ dI' CojSih}n?@Af"tsk{>&e!205<>.:G/keawoߋج[$௤(=rJ&#PbJJJo@K9V{h p+]Fbu;ř `jx)*F:J_~ի M}{gPs["DuyV)aZ{4IOʑ!7]{ ՞LiL>l.:W#f|eo-D6˱B~ s1K=}`ɽEX.$/cK2E_ǻ{c/<4`P]}s6-Wo~!ZpeAUps~ٽTƖtg.ͭU _WvWEG߹Y$Ln>\zjw|;(xTXKPvVvb]<+“s槫;@28\N)zYY'i| 4H` kKm>ZE֨9˛˙E=TtR4"YYƠ)CMLD*-[E ὦtMTPNϟ߇ລ䘱1\G>2(QRӠWi"(VT-*0(+۫mJn3TόfѳL`uyU8J,;Ybwz<)'+iPŰ -A N0.C<*RklRVb@=22D {b#]'fxp3.cgWW\C(NVC!1!Ll'r:&~nwpf/%Uilv#[!mu* ޻IѳH?_Qj9zp969e ptuJZNT#>KQa}["PgQyM@O$/9ÖEmVMn1j,!VTuie㑚bu(I!%:+hE%Ɠ`<ڌ"*;(kR yLVHNo=ᾬuOkɘ\c5,x&i$k9z80MggSR]+5m ~E.$y]ISHȠ2#J,jXGͣeTLNw_f42wbREѿkJF2kg1rWnU3blidED6GA(pR Jк4R qgQǠzx oN l]mzp|Qf|t#E ^9M`X UT'00TDQ+*Q0Fh4;{-$ fB9U}u3G"e tБ"0`r\,k"_fRF$s0L8,q=xa1fɴSbܣE"4}|1hs @2|ـM w -6蹶%enخS_JE^oKc,S) WdyVc%ەr.}_=*l]9HMR">t>ė! >A@F*B1+G>Ȅ)DkdbQų_$0/l` PZ|''Er࿲yO#_BagFfA8Gnh,jɘI|g]kUuUwϾ'=1tWsz?>mQyBiwW/kGҨ7kkn)-pQs{niEW>nJnָ =q_"ێ >F#:ܟ6HJN1dЃfP_mR"~H,Gt*(1=![QR$!?%i1b gӠ w\mͬ 'Fl#,2=%L$ϑ"1EXfp" .I)!βG| TglFwBb1HJHD2es%ë8sA\RYs@iS+,=4|r1{Qm_<-BJW-1bdYf/aK!o3lz+GDhM r`yE&.x^lʝ\hU<@[6gg $`&%!9 kis+ nԚ0#!U=>bpu8 V_JdEwEp-r4$ v$Q8{/E23 3:2W6&TB`~8[Hp:Q66h'%YK`1ZɌ\&4AYaXID9#.Zg+kap d'@(t.GB 5ab˛Wn̵D 9'*0;gBQ5AwϒND+\t"0tnRz"ppo(wWCeaB$F]l%a&2F:^Al:N)wu~2)̫1j.CkF\^B*!g5GYդ` TVF-fLesQqUih2j"uqRx @( U$C5|XIn8KD<#옌󻴷F\o9f F#= xҪ&8̓a`u mrTH "Ԓu~3>;f~U)㽌A6&= h'`H,[1zCGF ڞfX:`z2DxFO#VFdY,̉$|ڡ鄠cBShn.B Γ]C!F -43.\K@0_ /|٧ 䗪,|-y*‚k|^ 6\%ph X؍"+>u#FW& %S9wZdEK0*H@f5ySptVn&V4NNW3,={'/q?fhլ2]xD*ф9Ĕ@$8i?BCPwdEԷuD*e;$34γD<`[Q˘bD4aHKYˆe8hIF(ԯ *; T"r0&sїp03,|ʲ&i8  ]iiQ!GZj&LY>S#Gnjj2-#j& xv[{Uubv&"řf̜Naf;T<)XZ@9tsK*:+E#HωT$x8RORo2Qqz>}S,t21ϙMiH)TnjV=!B 15j4*>akGٔ 8[j9Ec@ewJT)첋4$TLSfBx")Z1$Jysk9|zx]->'4ìU7E[XY~eOrW%p$cGp䴾eNP 1B*C,Q@ĠnjZM k=qFg;f ↓gН])5pdVO0 ء,< kL&l+ԏGD)Il˩;DkBr/-ڳCNdu)R̅͂rrq%3E E#g^eHc 8)aJ-$ g K&a݁Qoh 'ᅵޫ_3`*\`\QޗU8W^ ] 52~J]L q3aOfl_lbFQW5L2(W׬x:5d.?Dds J+CO%:~3/<ǥqP4 ʠl*DeTXaS"kڊ36qJMRHvqN TyQ- agu ]Qk _¤8ҩ؜KĉD&@k8XT̢R-9P0#`/X̊3I\6b4\蚘o;DT&wOkIoBӏOC gCĀA4T\㭇XV;)"XosI9]=cvh0/IL\fr;|1&)7H*hD<,X'fe6 ̳(\:N aQhYu1R:zFɥ]2vgÐ0`ҝ'ÝGn'jIƞb9f:PJz*l@F'3SɭwOԭ†auQOuu8L/Tbmf O=is=N 3#j@DHX3 Y% /xGud%hK5J/س]a wOY`j"#X EJ  3SvD1 tB mC2N<Ls虅jƸSkc }ʂHKSJ 'e˕GHΗXEěG^ `zwqFh>>c D酓(]JU\3é 3$ ҍ1Kt vGbB990)mZݙ"sJ`T#f+:vx_[oԬ 铒tX_ܓ`nF͔pwB#0C;MQ(^xA)fDvdԧZ!! hZH^?RLۜ !qSJ GaJqLFCmČL*o(sT [>#٥a o>lZ< q] h|PB}^aF.}(=g X{pp.YRbz`x0 DRHkI7@.q8woр>0EߧJ~d"|)>̎m@&M%#S'[DCͣ>F-xnjQe6^;V+8xl@* >Nnz?[G/wo!u| i7[n/Ztzc`w?x}{;Ub{;#]ytjhZliڋ䱸jZڴfܢ{v)pLD+y֘w _z:?n>ۥ!9lx`|^݂[HІn?^5mG6T +P ZLlT+i=kmBK-i-1o^ڦ"yu6t:lG nYJZ^aG@h>'hf:^zKㄲ_OEzo7Fi=} H{Ӣ`CpD;͗vdVgj>lmzOGg'Bp@; tXP wo`r:v{m r xZi:5_B |Ai˶χRz6ۯMccKm$E<M]D #>3V0{gl/Z`*qr;?/t&quMRWp6`)l I (.E!C}eê//dTM "ﴷlwbE9-v,6Nw{4B {A{)ҕ<]+<{ˆKEYj "2D~FaUC4nl,ͽnG %%d4GHީT/\w:u|Ew.)3-ȴ\r>gc7 G0 pB9tY 9w$%}\#ڟf::iE@wc3*H8T&zDyz献_65?9|u\ G\N< xD_}GjrkϏjm1?I a,.` J$+@(CM:Њ?.Va l $m$iv.A\3,"8% DRФz -LK ׃`/z%X|R5{PÑkMZYrͥR"5+lA˒VI$PMCNVm)S}IEʽ-Cj쩭~$S\6J ᱞ23EݡV)M'7C0βM ҽn568 WpE>=AU /Gb_F?00AƉԺTPZ䳥C ii4$O,mvKy XC9W͡I. &֌hK$bp_jiuo237dE6fdAOʆW"n$ޯ<-ڂ&LppWWf't WD%[r 6x_d+2^IW2koPU>1{6N9xPD(_\+ A-i#7B{[34 >+}}@T4għ3=; 1hk`8+ꚞD83@ƄX|"!J) ^͑/ FFÜKTZ AjhgRӖ~;_~kGSz:;U3+,-Nsx<~av#.hHt~`^_]S3GҚƺIf+aiiDPԹ9TFQGMDf]\$MXQ0该3R&qIP%:t(Lg t hjon)-K=zL^c~?$1Z0£_s~/k:?>xp!?Sj?"@ʌq9_߽?wI%g_gڣX_]?Y9VRir,+3ߥ{/3N{;}.h!;B?oI&?Ddi!ƭӠR/E?~wػ_e:>Z!? yQ)OMޔ&#r)dUGR\`++}-ot_ (ZW]n$ *J_JV^P?& \eO`VQ'`?'po zD{Q?xit^8Mdspj{_ﶏwfoN{jL$kO;wh:-ww .B?M_٧bfQ=^S!qhY@xL 37:mfAS0<?W'} 9QT5]< _mNc_| ϰckO%߻}c}<G劆Ua^DЛzbSbH3m$o80]:/s.FW.ƩaqOqȗZ$U?|-f>4+Z+ TEkatOLTđl=Ŗ1J7f!iG❠0 V. U{Db3y`ÏHAWٺ"TK EbeKQACU-ƀYWڻnK2 @ϖXz@^R>v,ԫ zbCr)2Jb'~vrizh6;83dz*9AD.tsl0{qG?e*7eΗ?A:j>]CLU;ڢB=]\ezHIй bl=uл9jkц~P#;eꯢKo%VˈO3#27ۢ#ݓ@WsZ&q3-g֋%:9 Ui">w`*- .7dfz|߳K. kBA{jkڨ= pDlo:?oن;(Y ShD`ՈsGc0"S9GB"u:^gJU5a0}6܅yb:]ejLcc$b{.\fn{6 ;}mߥײSݽZgi/_n9XQw-)VMG cayMt!|R~6e3b.0+]AmdW7pb >48hg\IsW- N`jzJqALŧD +CIerÏ s2e2n(`o b)lo1$DҨ<Cb }://*'>1{#IR͞omAypeTqx1AGL-cnF~}0Oօs뚱%oW}ɅR]Ҳt*SY2N(bbE4T qH`%q$ 6!upѬKH_,|.-;:f"ПVg2~yR+\VS ݷ=mxY~gl4_*]d[& {kD:gRR2U5@*Wqa.$e(Z=*`֗ dϑ.%xg!S\f)^1M2Wu?$IY /g/ǁadI|G:ps%3V! B={j|xZf\ZH;v!Oh ~ =}LZ&0_^ pK[K)22A|ArԌ.>@WJA.7AEx1sdrgo13x>R 7B͟(Ba\%[s(7<A5xbPlp Z,] Hu ,X //իr2fBQu1.4J:Oj.li9cq>'` ?{+Rj{l!术I-UMNDP/eNQm };8<1qGʢ H`."ClQ|vg -|.D+ р9s_"}8B~c(ph,p˼P / ϝjc] _ \"w².sJ;tеYF뉭`6 yHbA '"}@&mnD#}'LK_i, f=m!s^9ewKoZr9CIXsU58qGLϵw=ElJV3\}:Gvim+4Vo*jVO}+뼉N秖i^6uɺgчW(dʱv]nYbͣW*X:Ȯ6g"7[ 0 -̴\4ӟs]͖gv]Z!1r[8W9( fS@AŢnzasu d櫁R`R,YcӋp`RMBފʻo?9g#S'88G" R%9.RMaW߹ 2sW #9tp*ѕ/PvCWjF}m?!?۞ƃސ }ÁТw..@\\aޣ|\U޿7t /6ZvhVx eX O`$ 889irF`mqB' rcspq}܆_ A}ϊjl2 bq~~5?_4vbCfBcΖ"PԳ}pm>hkWw5$lݰb4c:H =wsD;Uz^?+:ISlU^"o.ѧmv.x# ߩl1|بUI!4PQdM.b>6[zzF RP_1s ,^F  疛Iw_쵚?r81\"akà\^ψG!30|0n{g mb`Ҥ/ Jh3-Zml;IT*>޾љ>je[ .䪀+$]rFO6|dr,68_,?{^atXxZPxJ7oFƄ.t8p l¶;ZF %}ӡ7"YrW?ᡢP ɸD )uAV t|t:TYND:EjZT@ʙ *`lTl.J69W"⌠='NSVd[-]sI4 k.azBKr?'9C25NS$p6 Y&jh;[q8-Ii\%#"OzD|RTTlZ7UBVor>BP1dA}-Ÿʬ23f6K`^]cYyLxVeBWhN5U;~v1bBgffB{,v,M>sjKWž^Acm{_5@`a0qi+=Y2OT%jj2qNg$ }>3\ W`"ƥqFbB3T\ ۘGmsegv}Mˋ/(h~MbIږ$Voy?tosiwNp}˅rfSuP48?'d^ !dJ [+Swd|2 E"=di,yBwŌ϶|GM*<4MR(`bB5( KU"[/ [kblPcθbl:s<G+!z=HE 10Kc2g0. a lk 7־|H $#;$RǛuߣ(#+ڡUBG|[Mm0Ň*b2)PN{Ԃ76A(Q+6#0> -=:0zC٭6_FM@Us%&6I[ꂪ%ϱ n028U _-H|qqQ ;6ttVऽAG%p=/Ճ=!4a&g}mb)X<_d|SM?X/VJWmHǰ#5[o00r8iJ>rM;eMHo\!_3~wS&](oj5ҴWV'gx<22ldGvģ%sq_v0g<+y񡲓?Kf[_ NmOvO_Гwh q;$_p jˏ;G/>֫Z{Dɷ% 5q~)k'-9X "Aa*3 Z΂Jd[rg{4ruѱSD27du_pI_zi>[,HnԜ 8:C4D=we1$|ʤvA :l>=8:n,zx- Kşnie p̈[|=\%T~mIJRA2Q6 6ŠZ=|R`sD)B7O{1B[bg1%Z 3 Ts02%od2 ]b截iVLd J+f!]7LKI 4Ke'g[̂W{@W7e 9YrV`%͢ фЂc}M9J=ĩH{&ls)wX`֓4K+KpJBz 4j+mcLֱ$rC"K[m *P5 Ik&^w7Y$ZށP+$tzyˋ8^[ŝd[ӏ7Ј'GJE[uE8{ [GU%RH0-yre9{ 838S|}I.\dkG̝_ "ٳ>Ie&2##zi2Qw@N88~u[և|/-$QMbj1ㅭj^qe4~\ٙXWk ɤL/?QIX3,iWKErԧ۞)2 .&,`jH^ݢeU2sSq7,O~$;s+u}V 0K@-&Tf"ppyz6gg/+U!2z񯼀_r霻w=(en1mb;-m Ko6.ojF_2mW5y$Ĉ0$gӷȟ_Nn~<pks5GjG2B,IĿՂ&=iZsEQMrrM%EZ3څ>p`^!dv~Nx`I C4)/Yc;2dav+~\v] t`HJkŢ"s?_5'w'-6?7e~ P E͡(g,G-,CY {3"B$ԑ -u*:Es o{AnjFoDA/.ȍ:xP,"oVF!XЍF.A?œ't LIJDkBr.@{4At'tVS[\p[+' n4xp[: +6wz}6LFόuAեC$h t3x~xпC͜YE^[aiىS:?}I66N$G@ h[,nʦ\s9IDn[ r3c;cY`0J. =#ۗyvH:0ChS"2󷶡tmJ`Gx݂ |en7ܡp x=MMY1$t;IiHpqL/cG)A=CNlbm[lph*÷Y+$\C|M0?ԓy$-I8M&@ki~a$؃[]$W=ium& ~14,栌.@az2sONfEDD!7*opRޚtm[e}LTofN T8u e-Z3)V0D/`ޭ}??˵7٣nH !qVwŅ'_o\yd 57U'GrM,rrh6Ri9ub j%m&yQŀbzKa 8EEhDIOɡ3|E|Lio[k7,CWB}QNqn+SbӼ)yb\:!^\mEx2UVtUg=9;-r6[FwKj:qִ$ژ0;NҘs!Ճ5DRH0La 8Ɥa|z1M-z:z䪚f]FZZ`PoDfN$*Xe0M8@%OFK5zB=)NpE)ۀ5$p$JU2$)f/]yWM* EUa/k{?Y/'[Mghi8m7Q^ItD)4RPWrΕFP!l'Ofúǚ9>e="c,&0VL\DaJQDP2.'Q \ahGlh.Ow E.RuW}\rmDũL؝d"5\WM'Q𴽓F(\kψ:I866GdnDy Di .XiĬ&M08h/%0H$Yk"'I<桝;jнKMY\LBm8yЕ#hcCWɯtI;OT˷2`O3菐LhK`b&SoOۢ;q5?NbtburNf߷tNJ} pɃJ`[<RBVV_ӉדɂNnkϐB0HC74LPv!ءra(r0UhE0X!]sOM`t\57$aT*̏׽hvs`Zrԣ)$hd 4ۯBtzYw/YZ˶qo^p^-52Si=# /%ó2eE)3M3+ iٵUM9/Vݼ`7zi5ѻEef'DQ,=XBg mw-8B7?@ڲAQ2]D39+lp4O~=oԙȴش|ݿ*sZ6.-I%$e2Ιյ0 30$0$)ͧIiyx"g\A4f+|_O+J#Ui \~R0 JZy~TWuZsu^T9jbfPd$,~{4+b?9S/.FaYZJ {2]t/֠+чTUo&m*zeQ8X}0A}WJт |w-%K~9׏cd>BDGcI ahiDR+ugS䝨2Ɂ),JQ|Qs6a.f~{%z;C/"x#758\]hɝ#/Y<\ˆ52ŠSP$0O!6XEK+qgP>֠h*7o(^YC{8'L7tꑦ]W8DHTe}Ol@tLq!I*rDƓ8~D l|YɆnUV{n 730UR-^+ [TzVxvDO$(5s1Kk)HLPPnOOk6ײTIz_4n}umџل8Y8?vx!pP{FHߵO^S,>p. _cB퐨5Iߺd\35O3GcM?V#~ [֘e$k_45*?ڨ75hOG p(F|Uܰ) oe|2^WE^=A(o|װ0/V^ ]%V&ɱD$t64O\);CG-('Q?Ihz=ekVRN!s~ v8LiEllFv&KlՖMތf6qTo;{{$32m4QIEkX鰳u=ﴷvrgQt}{;pR/gugӘnZ𘺑a5>۝ֳWE{W--5j=OZ巹fwh./KfV3!o5.ꆖUؑCGZyW=q.a/M}*]ϝgv?;0P5_FF;(Wsގb2얻گs%{?W1xQF'#~e{W5ˌqG)bƒ0|By{ 0!<U~-zah.gzO|!7>43}6i`,Ԯ} faxrCYA(m1%^ MhAn[ q8 `%!rPGNh8ę'٪A=[ݧR("PdutE]\q\wj]D'#q݊#Giq؇p%jGQCxh~. 7W\Q}^kLHPse}plzW ~9luy2 {[Bp1웊}ΤSIbb[8{=9%jn_#|€glx&a:Ѣ/6ŴO$`M' |` g2(Bs`fph4p#ck8f9X'LŚqeslX6:I(KɕȻꙨz}eVku:\ XZʹ{3& f5r]B–Nq\ łU%ňե #\R1tJL>\riqI."3'*0I)0@ Z!Ib۫?]fK[k}KW+b^jqBPvi$!pȵXD#uCx38jWUʌ#OP}_qW Z̒w!(-С3^'D<:gԈêIšOC}{I1_ yHO1# &~N#gQDI<<mvѹK=M#K ^. * HX ɧ4#w]?bs i9u41ڴ@̯e֙beLh)~ f gOQ:{TBnmGpڼE{>xҹPo﯂_q(;G0Qx9yXjqx:jZۨ'A+k–2#R^t|-~A}Kӈ$OtIjŋX b*4>N6ivVR7Rgg/>{$cWxup vxw Q։s?zUQhCk°傥Vn2'u$I`t^輩w}0|Nn?9x3qxy.qõJCyR/ewRvO|{ǵO@HL퉊[#OhQQj>o=ԓ{vdqfm.dU"ea^%b@~e Jut@#;_;!xsgC=Z*ާ/y-0+f] J]]V7?7jjfg-?_W&>;*.x{F,s\$53#tatp7Ib2@X6`<}"cERKvV]IO@A8׋e&;ʲ9q![X"hWG~Ng vĕbA jGOGdmǽ/ ^XNW\`g=KBsVm3?\#]2Ӥj}j-SHe(B`K1QraWv1W o;FU)ˁm7::'fa`^,z5R=#\gr[t1gG`p`4[Hp3 }Ndȫ6uǭ/ VB? `-%TB1|=很7soZMu)!}1|l5 -ݞ0J_YS 9q 67;?uK?k+{FF{{VXD=za^B9hu)D99(g4ŴOÎӞ\of3 I=$a'v{S4Q:o>|f>3A{mIG'~ܧgH}T:xS7qC@#>/?F;i9Z Tݢ=0^G7}}.S0cH}Ô&?fe ߙ܊4]1U~;sFI,j˨wE6T߾}{Bu S”,)8*Jv[w >C>}hcXb(vYB/L%J[nD1Fj\{IJ y('ha;=o_dsdox*WȳR^W~:]ΠLE*/*Ir襢l.tLWV.V@泱b$?=xuJM~72DOL#N:3gHV;k$>-J\Z,v:ވEX2B>ŧ#)>fwLPqqV-$&2OA_&xq!k[s-@xݲi&ʁ$Ouu =*f6F߶v8VQv͝Bz079k y"wrT{'z>@'A[hZ !!jߴ[/Y7+^vx`Yw/}?7qC:^5|[n/?}J "ĸm>;o`l (tUkz?vH2#Cf-EZ3#f(q-1б1?ʇV$@] Dq_,^8cz,a}2F*xo9 }aE:]vNjiw6p a)hD#98:܆r){sž!7?|ؘ1_ni ck3pWO#.rB׃>MH*fǯF=@)t2W:r-fu{pVe వluN4irbY= @E&PEf4Bpu"$##^~pvIbrAQoa\1SUJȤA@X2緤IF/9ձLG[IpEx) s{E +oTEqjFW{%v FD%bؕBvv졾Au8v^5XfHTUKZ`|srါ`BB#.譨kYtK9 Y\c.W+3)O7*9v q YvbIo$'pWq'U8[8$b\`Q+8{]{1>t^w[jhJ/aH;piduYs*Oƥ$"p| Oqd3%ThvHK Dh2@s!E\ptIҊ(= pXV4~ssYn4=saOȻRdyDm5ΣJ If}ЖUR)X8܌4rEۗXnO3 M"MiD?gq# \qJRwd6K79`cq\܉ڸۣTq4R0 G3kL'95FOwwvjMp|:Fc>ݒeFhi3l' b$= 83%0Np2WjH O84ͥ5S4/?ݱ;j7ߕU'&ɛ9݇a8eJh~1yQrS^~:yfT쿡͔lcvȼ*E%#gQz',U,!M"^<&W 巼ǻ/[q]Jodvď`W1I>q6z\{M\.2umw x2_@u<wǗRgӗ>}Ȫ?'ZoNwlf=:,@[}x0R1Z\Ow)=#g:b 'Nk{;fP+jsn{2o,)tG;(W|yzp||@PLeJws}M)?4Kt,T-& ^8֣ ;!QbRKoYmG~']˃E80K\IHF`jHTMC +;^cKph2aG\@?N1Hf0RMaanNτ4ah{Eҡ姴W'QGjw&{g _NhchpҭƇt p4ow\Rh=-~V迍O* U9g|*{FbW4U ;d3.ҿ}kɠ P>{:n!V?-B|AW|WsGsZMF*T&t|z1 `j2ZLG4N gd}V\ H?TXTlM+/rF_b_UW@]h`P{u)ZK3oF)ta#׬ @$sJ84<Sw'1ЉhѲ6( INI?Flb+[}=YD_#- SyKqOؾ<}=ɪLptX5:zK ztT 3ц|gTu{շLKؖ:AU. 8U3W/NS8#,ߖ2־6gu^>>o<6`{FpQJ6F#r\ n7O˫WsCaԞz7jQKWfmX5[lp۾ʮϴqZe/[/+xz^wNϧq_ ҇}R'ؕpRB%lG:BstF913!MB\1豯[z<+)q;lznNk%-ǣ(OV{w,'>Z:WKf]G/a>{eݏױ:梉lM>U#@jN kEhz|eہ5{^hc׿NLuҜ7AjEݭ RkMz`vP>fg3^qWvD\^ $2Ed)!0ԜDS1ELMv'|q;|e3r[؛^W X29K %J}&/z;xq #w4)2n~ESy\ (un<8fh_@C'o\I@+VS2" y| q3ydș,~RPcIXĴPQeLRfDjðL0fE^}CeqW8YȬI8ubl؃Q֎I @2K&+n [aGc>6+g<" r)\e=yd,tl|ŕ!x(@ |gnH6l#;g$߽\5sϕks)yV n.2)LRMoyx@-N'࿝tz3PQLX-- _᭤r}ȹwۙ4 L"❻\.ɄA8bAdM0ݻѮ*^qI+1\l/Nm;1ەc `caUEj/ a,D+ $+=8kKL}biM^B,VS2d>Y]"Dt0FԧE'n'A#v"z>9A91p+#]Yc$Ѵ3荧pe*Afh|r/xiR+Jfǜeh7gA,1s1pm%Mm7H|?v_;e+6:D]i6gm ^yP.egt9S;U)taAHI\~]IVt4{s8ۈG:MT<.op:3?*M 6G3yqy &XaKLBv']- p7͔1c; VG('*JǸB褾u]e:53qCPq^lހ9`כan 쀜<ӎ$sNr4RߒMZfRZIE:iV~)]޽ R6q>?C"dݠ Wl{f?s"Zœ@![T~+]?_%Ĩxw P 'EV6(weuB48Hk%g'cEq%΅+wN0Qɋ ~ Q2?j܍&Sq<~C>_vѪ rcVafO}뺑,[4 α*g,dc~\G; ĊMw76(>qq;gť6(I%-#OҊ R&WΖF%4C頯ZLg'Le/шteI¾)M*6&2L쯇5n/M+j톚 0Mf™S$x[rEݰl$Ea\Lx1iA6څ+Ԉz00&o9%eXfIP@vOq2;nN)wMiK+A0@L{4q,9NiĜN pu|LM:O0:i&hH"1o4JN\M]5Ȇ`vle嶷Qk{sZ+vs幉0rϒXt;<<+92S"xޥZߣo @A~dF*\(o$.nǓUfyo}55n*e,͟_sA7s |IΊ*󅧸,XgnNOB}TNK-/s_]Q`lY $BQ[29Ys$xK"jMZ~̼+Rڋ6ʽ磧]dK^ k;ğ.i͓"IТib+CJ}S.7juG]BYE|*yPFءjL\*6=~5,^XQvN$X@5G#s8/CjȽ rh@troJXJ"a#j4 +fbma]r3dxJU"0o tŽҬ6%Zq pz ]~}>H .Kqrh/_K 2xJc؀_s;_'i!6MLlF. z]~1X?=>fT c%SrsXfw/˗ic3# (}~.nB7!ndB0^(L 9BEψGl5Ř.J J ^My9QWtIއioA! Ƌ"YmjoRg2O>|9se44ņyʈoe99K 7n3V2}bL>pw?ɝR^h]etPeh 0r$w|VvC>XtJn|ΦFg13O;M/{{ F=` =&E4}Nn?FW(lyi"Pb~4WV9sEuZuN1u٬8i?9uj HB+6@+^]y:!K;[W~9s懽^ "c{X܊[r`J8y^kp,_t>\Hͻ+Ç̿zc/F}zQc_{"H$/:x4u "||9Mv%h<~jQ 迏Qp?+v.֍k?0,C=i$ӟ"VpAKCOBllNFK:^Lx㆚H.$D,0 sY8|Cm5Fhq,Prxb/W4KHj%)ΠO5œSFW+< QUz >8 QcG+ڦ߆֤B :rL3$L>DԨ=ި} ( ;aM x/Km:,1ț_fZkL1V$]j-м*ѲN.MOwW!"-[C``ЌĽoc1FaSǻ(#7i 23s"Nnn&G[hF\c?ē~UgI< m54731ui{UنKZ G79)6x~ʌtXqTkA',A$]#jJhx6zF?5wg?]zfbiy ȸ{ɖ ?mZQ柺67x0Vx7M3M^sUG+kΊkAZ[]:GMR43ȴ&pӔOVNycU,+1#:0RqI֬H;;P4V,2[2Iw%I^ȫVmS)`sU*MaS{O2;PU8$2GUd9"[4`Ɠaژ :6Q;Hܜʏ7]N(AV:BzS> J`O!Dti*5PV"lj%D>4tS3e!tՙLsߔZ/Gy3=!ٲY~*\&W$"I8X ߻yis5zQW *I,3ȃðbu%$ 4ʌ$މQ?yZy"ssryyϯ !޷]nj' x~JBdOŚ^@+ͫԇ|>z-{ [0` "Pn<DZ %+Z ;DŽӺȨfC[]Vh/g[xR-g|t:I7o%s/80~4U(5\+(/8o蹋,^rԛniA2hU,S"E@ɏ `S+ 59reSwQJeBuz0簔=łE$X{|Xtv8c/uV' Wc~ g4ڋOWյտ4GGo#~ڳQЎAc5hfc KLk끄 ![IYt;jٕ*Ziz8T6Y4A? tPT C67md Ӝ77V772²C4vG)4:><҂q?>:cʯjIl9Į8;x,$Ѳ^'i4oo>JυkJmB `-h46o_sgIJY+jurY9鮑nl)FqUBG_sS>FUz_rjOόҎNm EN*E4:iMB #ջc}C y6elƿأG_y[wqf9P_J Q+[i{ pj]C:rpmiÕ$j,Щ*D n?(:~9%q Lxs]˾w:;!ɀXˠڃa^DL*R`' Tu۫ hh(ģ;W"- nڮJg3Bl:;"x`i8\MKa4:U33zD쎈,)х|r>#Hj*(kD6> )Ip ԍ6dp_UU$ ;8Q^ӭT5%)4rj3V:o_SKGmBٮ Kʛཪ,61#HA `?sil{Ue1OLG`NYŖHDaYWw"I"%z9x\iK8E2W[sԉ[*< j=n}l6#em + =9 4?ƃ^''LТj=a E(,F0҃JkaD{7Y >i2;B9g,&鑐|[PNyUsu' op%U"dDn@iMz58F. \?ƝW 6t5`7tJ; S7 < e}Mu$_2fÕ(jnnl9B-/됿_ Ev+ 2. )'鶫^ļ~IڷkUZ0mNHI[nƀ۲Y_~?$SeuϤz0@[ݛͮQ 6ub^HNd{l YۧSlrM GPj!H /⒂Yi g9/&B!X A2O[69발%(`khG#!Ɔ n_١LZd!ZZ t3ǠkąޝZ(M iKV(ڽIٓ JX '6X@~Ka'qzKVN̂ I5:hɏp%ZbCUQN∬ j|:9T];WACh'̾C[$c%2A?>t# ,iȟUFwlGp{Gƀ>,BoEm v,=fE߸܊%ˑtMx$ZJ8"YX{, MMQ;2[FK \*նz <.-/l F7UC,USkV q-رsx:Tfw6µ`zif+#d+w$36lR# $|zu u?dT5njBF/w쨵jBfbz&{vpl*_e0Mt`cus/XB';dߨ^|'xY۝1^^Svە̛6hJXHt5c(Bv=Ϊ@د@Y“p4Mῴ}~{ؒZGI޸0p,/ZU0eгUMt>}1wO ;~)H1D'E,z-Gh:.`{k u -NDXrnQ,^U!> c c j lY1p1}Gu#{wteq~ea@RIl=r贃_g#̭=#J(t0kea;jg:yyl/;Qf*J˯H IOUZ .^Gb& T4b4a߁?f}&wu];!Q\&n1jZu([6){4y0#G'Svqbkyrn^Gg!h>ahF68vP97h͍;= N` dE cwRc0V?\#ث:dm/ja* N4*2%S:TS ]q.D%ÁWgIqo6~{-SX&@%p>ˌn" ,c|@[+-fKNLt Gj\[WKOIjԋA*,"tS!McᮙM xpgCD ŒޘgƬߝj$k1Hl|Z3'l.Z%4YRՠSb!ƺT} `Qn-H h rĐ-ԎM88/fI'q꩎kQ`~0yvpJvfG:@2n[$cCӃ҂)8Ouv6HW ]!R=O =1l;jDٌfR@|kč;uF\q4!zqo0}"C4wj3]Z] HM 5D&<t/8tye[үd‚V×2Z#! M?gC D@CqZ(Z'K0릮}<9OA\Y䄒d ^+.sMN;k*3j-S`̎1<$gޣܑM,jws^7NCxj rnU x]QoDJɺ[m˷n E^jTN^TI i4̃_kUw?!ۜb{6nzxfNx+ӶBsd_*CEle&uf*T,:h~FM̍&ē۱`$qdV;mz>=>@E?[,a*HmJpZ`IX)JQLT4,꠯y1H<HafcOMr rmhX&6c4{A4Bbf 눥Ö*} KVE" @Oxa>`m+rG"S,DK|-5Eia,zܷi,UIľH (V4\XǠ;9m/ͽjT_"I8 3g3|BcDzP& A;0O{NA99 YBy]ERcšciEt=64qV&̲73+h6|$L`tHKJ _PLi!:e&os_FBryq)pn*ԱStf^N"Mc"~а/#/f4F)G}H{\~UZ /h3K\H@yI5Ÿ$H`1Yu Ob/ڝP^ʎ.#Qf*dM+ aGmH y mB\#~MeiRʹx "VLa$feLw ~&6IxI7,O%4{sq {—dXkm_ -ʤG`JQ{'a"a΁L{eiAzc@(I)ԏ$3Ke=k˩,uT'"kYHW9` ir,Lai; p q/8̤w"{y<:wOfZ;\Y䗁Y4%'=HԸUM^=3eBlUm:\ mm٭a_lؿ&! M P+J\W )U63VmYLI Ay6 1\_=Lhq4V_WsnX6#HvЌl),A9p*FV!$ZuskiONaY}S"Szf3A4^3b+G|9F'2ڴs/i 6 i\z*5'W=xRGg 9c3H{7\PYyͨ㇔5Uh%L(q~}w3-jB"jj.ɓ&WiLٝ`Neگ깮h4mN`|9I78/a;H4lRO##3e9m0j@_&{ȊQ`TaT/fb&^B+|c[A3~eFd%]^,;S̴֑?5[=d I,-njR"k!g#rtyXkw&}TɤeGUu>'Sl$ ^;jl86="м6xW(f5ۉpաKUppz6=/:~ݏvVşqN5_Ft=" L/C8NY-LF0sM>檉>oHmXRSȪe|.@3_MJW Hnz ,d e8PZEl4~b_-,w>Ji2uEݮ+cUHVmRY ɥm#əGKԼp(: qp)۬ԉX&x $..sB]KoBf6;U2 3KI=|!|os1 iD8ckQH2͟MKok_$1?E;4G^=I26vI,SV#|M3*e.!c$: S:p`/Q<Lj1֐y86DGqIZniq6WUUnҧ3@R̺ vܝϳP`/~o%} ;LZvWɞ_`qZd\ `{YVl\05%~S1%~mZ5S`(^DU(o{X.R֜26PvC^iC>14+(15!5*Wp}Uht0LkA-ͨH !WوʲK<{AL" 'q/ #3澹ɤE*o53#5M{L4{I2\6vv?(v HT3 cU IiQD+m,8+UBjL]R%e1euWLN+}3h ׈2sh)~skɺp!3IMaʉLf[75*\ n/,/%~pEٵvi8Znn=Q|-Z֨ \ &-I,YWEY鰩XgW9-+Zz_"o-S+chS:3,,Lsa;` ]Ӎ|-"Q.LTਣɻ%qK*TƵS7i8@(Ƀ"_ܬ x$B2aQi7_g8ڮiUecP>\eƣ_꣍Gk%%^3Kp˿J緻ПhV.oW?~T}Cc(hPZ<9Khϟ8:z\b(/^k/U4eU_Ud3Z+#4c䨯oKL)G`zIcQ9ש3 '_WG(`R߅-M(RhV['I؏:}\X.mMUOMq+]Ph/"UOdf_>]t} `Qj[)YNj[;eT߶UzjEQ_\WnXxx '#~rM6mƗ? ^;(i3QWĄXDIEtSd .ҐV7MSNO ]d0WaII "3L(<'ۚ|Cgaf@;1g8&<9mnE7h ^7o`gB#=0زSGm9[`p4~:~A=6<;8 $nkQ/-bh:pOR`~=~KBTŝUµ:Lh7|H*Ĵ,g%+=E==?܃I5 խȴMĽhΥ,P815^sAsQtrqqQNzGV,P s g\fGeЏI8_ Y$zd"qQc f4䡔Arup|RcxzoE} ~Y:䈌iO8hMP84erd3{2rbN?ŗ`߲j@tWzNk&o[FM D8@v@2ddQܼ7[A"g ,,X)e`}qdhD2{iG{.}{w5knRJ*NEe'zj2$}Q::7Pyw^6niyZ$.$mMQQ_gX8H͏d'SJPiL7G4ʵ>zsx|!Iĥ4SvM#)C|/i8'Hrﴶ:/:['Xh;&}:[/0-x=`^_EQ; <ˮ~w4^.϶_ws2uUj7_ߕ[87wݠӔ_gbz.WwP&F]=B{wpxŕ^Fz;_QLg4N7LE:4Χc[Us:-n7yڝ_vnC=/;&MEmƃ'QO^8 o0hGĖa;-#6Ї |'ؓMcxp|x;#K3O7@nx=:Mp><:xVw:_2gt܌19I`ng nkھpͮ(4YkT/y;KJ00> c 3=ajq/ UhrvSN[z&F".jMX@{ 0#q#6]3$'Ӆ c܉?nu-wB9ΨE}QG]V݈inܞnݕĸ6A_զi74/.f,K16~{>Cw{}FMr_>=͵r췜1}E PZeEDO}Lbh rvSd%ĕ+}yDnn$ y`:܍u3] ?^ӍPvis`eeR+a_-G#;cv? -Å=q4J6Q 5 φoQGmNޠ?4 zϒ\C,o2 Gs&yScSU~^eA }bi.=// R|,Iuܡ9)Eg.Qvuێw~Jwtu%=9D[tU@T~{7vx8*S5lg$xwb ͣ\Da?^F88g»H+|e(i4'!I4wvrhsޮ"gOX瞖0p(LU]a>A;4IB{,]Νt/D)grøϲÈ^dw0U[/ǻt 8 Og^֓kV,;9p %7`lؙ"ՓmNG ht:K/ZNr^!%|R_4]ȔRәpX"UáV0˳)!=ٮnx21p-'si\'k\RvL47&OT) w!只@2-sP1_Ǎ!sb y1/?i_ꍵ_d/ɞ?tF}cX[][o z?PxQ}Z}V}^}Q}j3"|ip)t`>Y)UOG3T*|>8rK1*iHgE AFܒW<3?+_>f= uքv B:zjJ:Jq!mG,aRw:x}U,@c}'sɜ9N+ډF'~t[$En#6:'V`CU# u]Nry#l{9x^[u7eMіPBʾ61pXo'N },K?_ T;ݣEoxH.͗{0FeO0ELkNﹽerL~}Z_LEϮ`+G!}gf] L"ǖi1D~uO3bİ* Mu7x`lex rvj`Nt'ʽˉ+V?^ *9'߂u:V:pww;G.b;X5lj%ƫ`U;LU@s*LP dmUWQ0: 8f] Z F٦b<ƑiK=`!ٷJSjq8{gp: J+<XCQYY'hqԘ+CjAJm \ C|PI/Jb^ol""!:<= \_Ëg/}WjS)yފnxXG8y7h0t\R;uF]a]b7di+P:x/9_p a)+%zRGvdsՒ}%)N3QYp1Q;lRedp'&.$8p۪+]D2BP@nB|=Vo[]tjO[wEc߿Uu֯Ǧ8Lַ'{p]4L)KAڕ>l!}هHnwv><$|ohw6IPy2%,RZЕͤh/WU:.\WWр=IkH{|d .,;k1CƱLSW:Šwɪ2) QnD& Je49ȗmP[ĹU.ܶ"*K=/ %,_aeߴjܥ&Uoe}g5a|AJVeW|w ^%Ly3["" (nLI0߾yYo|yKH*Cg /j%y\8;WAU=k+سd3G"=cMe]Iby9hw:=: $["{"#B7m " #NOj<Me#SV:S-rxfau'.X]zZkzLumw8^t6fQs3{dJzֶF0aJF?ӋX`7uId,oX G(8Ȅ-JRY=i*5*{Q^2B^F O}6'i F@*@QYXZ|s3N(vJ b-<N. 8Eu$%(:w:[3IDmJ N#|#WEAt]n^ qkW;lreq+}(5̓w6^Ceq#;eoWn,qJ '3 ԼyxU iBf/F焭/]5iu"S]~1Z:%2}+9x-A'!2(]2462^EG6W[A)1fkaǤ`/1)}gW*-(˜Dk E}p,<֌2 q3g1~'BcE%~jb\PALI7U͖3ypE ws{]TA &2Ύu}ˎ1XW)j \ ~ s>R9!2b'HOtFS,/7>gF&=2GM0\ Q(Jb;QJņetkNɸf6iXuE,9z8aږ2 o4ar/8xZd,_6 ̹[ N7-;kv2#A-YC+eq4S wuyjdE$,c q#zR邈+vGڀt=tY_yZ㫕Dx.5?^VYU0~\n:ƈ9/O.EV"jswF^@Э5n.j/:uA/W*FJ]ݍяS $e^4_Bju_.9\{8_Qbz>  Ws7I},7zCNV3MWڨJA|Rљ1v4B^iJ[G-nPq*OU--̺`o9o2gƱw9-PGKt;V,~/4Yė`ǬI%4<&;H"-|?G sθR]OWDRj2ʥ>/},U8gߧ|u\o3fN]~nAH>"Y{z;wܾϼ+l3:=E_tᨶ7ܳ.hP6$͇;/9S[ oUo D rFraK:2-H![tߜ| Qg<[@ uٰ;Pu@]:^+tC 9Zϡ)wi9OsF- *,` Zfٕ7.PY-͡)j5V^R A,{!.5}S.qHA=ش]׷vrĊ7 3A:ÂMD qj&sjNbA2iSB#YbҚGSSy?N\GN9p][> 5Cݨi˶uX~M5gxhC"&9K BksR7ljU熣"b?Rį1hVI;]`HE[-M}$_TWոb,ͽ]8 38w4milZ}d%,bEzKs&f*1:8ZLbm0r ȟTޢTq;z?|Z47~fcf2xYM>>yuX\;!谨LO;Lsy:puu t KOo0Wk.,?+`cc}v4i\{1Aubүo[_*Kf \$ReRf9sɹP]DRǘ1)`QMCDإ8g: bK1q:#ۀѠ|ނ鸹kHROSB-G5p= gHjBٖкΆ C%#hx-&CmcE"'rF&gLZGG(Sq~m[j.l{D[ l-ZP@$^̃NY% j¡amT! e%D$7\kό)ïaǫL͹b \kS2qS7%<`W0 R`NLX*=0\bJ9 i/%+$Bs {6L΂䌭݆qso"Wfͼd_МdgQ<؟S(]WEq@Txs: a?R_cE… C<_;ok{| Ou5TTg59wZpuԕ.%~r]Hӈ8Ln)[s/U;x\5$qO{<֋-3YbjnOv|.{Y"US;W0 edϺë܍5ZAO E*`Cɿ|3Gh{ߦxm>繻&]_K+Њ x0~>}Sgu?Y.C0 Q6<|J5tU-q9^4}2|eܪ~Wdr>D(涷y 2f+?)F *z*l/5P,<É)H̽'Wr:`ZMҪ5}3Kk_ͥϪ8TYeq%"NژA CĄg5q $YRY-eBնuI~W\<=[eh۝irD x7Y Ąg~t *zZG~O[qE:,pOl BjIa\چ}Z^rXΙYYH>DLO4Xˉxfk~δrXo`7j cJ5ӵ4Ohbǩ=5q2b@3GO2NӹhuiHpE Qu {fSS7b!D|Ezi2'KM$q>2 oy8BvҊ6'mUuml! }m=&@QYSa#qS,ؒ0h\\YeI`rj.c@4 {ܓhGr4զaz 1nD]'^7F!t4o6`gs?a7@l *vM.Wdt8,m.9QQ)\dH)I t}(ˢ\ uٲ\ If ElSDdL\0Ga>빅\f￧oGx؇yZ?ϋv,MXGoXҖu(%Y_`u>Z5RҚsN&^ \ۙ'N@vK;Cujg+gg{d2#q xv?i:ǫd+)  6DU`M>}!ЖLB: 3uSC1Ww,c' $U,_6 xSf1ᭆPq~u 9mޙЮN!UtAM;p&y/j C/ViKN) cl%)jm K]AMp؈pEljK4ޟ7$ pk>E5HXIv/f uJPm!iTLo\yV$ޞ}RUfdfdddddɰwhwCH+s]"uC6ETآ\h ż!IN~t64]b;g_SdJ:Vh| yJѓ:W0\xP[M5=tsn M@DѬ5.9.PiG*.k y(U +^%GhcF6@ҽĖ17'J(@jOt4%)ĿR5uR43zTŢ2 xczŞl%{_ϔՖD$W~izu7?J@F رr2"vRe#e@y`by$#dgi"1&td5֭Z"ng ֋`.eo5Ů?Zk SDч4`W A.(NK9FkR zz`T_+FEHvIG3|1D"C&T;8P1|/a[zyS{m!"#d+mm6RGjdVG_o2/X`ض~T2R};j呅XAOI;WVoe@I%&Z."([ģ/&&SE-[ YGU_2Y.ѶY">Fʥu%63tqn4dYSj[X TaPLjãCf:5Z$%t Z%z7NMo|Ǻ4KD'Ӽ6h VCE?!o?Xu yχx4B`ӜR# |(?Vecw'߃vAaq3Gې73"0'a爎VX/0 ̈́6f"g:U2"bSP^ &5]h`h׸>>t1vIɷ-K@2א4 E!͊Mr=2MCnxG }OsoZx`is 9U~pLM:A 12!9g-#tFxB-lxJ}>mQz|Q~sxӡrGN>0M|)S ,Ex:2 jwKrB1H~vq+6I;dZHbvI쑾#`fA >Н`:9%&Վ,(K'م!teJ2"H:,NKjD;++'6F+;|/'}X˗T)Cs 0d@ײbBhD4F9nz9\H0{\VhWPVUC40 HIL\ge71]U%wg1(m?mAa7KY;]Cwu `.b{.HPYk4wߠKFFgWk12DZzyZ],OSOrӳ .w'܏豰/u"IbW'TT\;be(yB%ZϽJ0 jieDKt 7vhh1_}?+t}s/o77V.6RsO2 Y$$D8?Z_O6bZF8Ӥ(^#O/}(\h%af/ӱDO6`ɲhs7:DIkX0W8IS"):m 06i IGuxG՗_a Q־IP`(h0J [TP, Z0$E9! a"=ۅZ.][VYY0۴& ZGa;z؁9xZRqTYYjF{7œ >gGOi/>'8ţOɨt5T^XNG筿voDž87aJ-}rх}QҍOl Ly(0+BhxƢInEWQ% XkzQfn(,G $.|sT4SmTa`tQ sDZj_j*}pA`b\S9ȉFй/$?Pm$ V_Țᴡ}vJ%(ذ2B*o۱,ёb FB17ڒB얆XI{'xvyNF]54rEO>/ %xџs%Dm;b"{g, r-Z Mͮ`c˧ʎ 4qhkWj#wwh0?sncd^IxH$ZPrZR}gi0^ԐЌ0utEdE.a 1Lec4$a#,?GZV3L5\BP'u61L"Y{ˆOΜ 6a;ۥ\Hс)ai@G(lg1D+#8P_l=es-Q* ni-wM2_\$՗7iz]U֬%(CwZ'oޞ󄬠#MAF5hOTU2A5nM C,SR/B/YuV_fpb={.NAh{@40|tW]&}Μ *''N!QO-vp,,cڢAIMOe x0Tܢ!Y$ș$r31Jwԟ/kj  vޜ8ZfM8혬FA^JZ/~[Σa!rPjbv(d%/^Sx|xO{.+U{dyUocۙ߂2|82/H}B/)RQ@I;'x'W Dub Lja?R'n=T_aA,]Bī,``KZ Crru(.4jh`s'[Nf=<4"ş.(Q-UXENG2!K$Ј<؆%F i <~\#qXn06q&-T՛NuNۉV-%=!qeQ =}yObwC\[uUxUx&oB#W8W 7b9 t63'_IsgK,yHlhA^]~)=] 'Z6BՈ=@&v"*s9KvV;Dkm<碁5Z-mpTucqx35Hx).=(+e$9xEW;ukZdd( s~nSo W!=̚j+9 .3յn } /̕[d&aRH?%?ߗ^nQ.e*iGh#h&YzJ$X#[wfqmUNTH2j%f)x=qf5<_G_w0`:2u;sAPh*@%;)ܙSg p`/# nCA}? EtKU0T~11Gg?ѡLfG${M8 }I.-|` .R&:xlیLKQgz^g  \zp =yLl0JK_OX[lUvEoCpʡCrƦ~[pPjf6$!=? gud}{4P-YKgKuˆ'^p$ 8Ǔ%er9@p;O QgMtG!8yʲZEb sCMī 1Bۅ^%lPp#w3k_δsQ7=r)/#+$24 5TqJީu*NڗkN֌e5g)Y5~`T_1:gJ亦|_?y-M pF@4_\GX<~69z݌*FR~ڛ/wNҔ3v?ѫnMBN_$/na_^AlycnU HD ޘP!Dhr:t!(vP@$([W.DzZUN+_ Tԍw3:RJ)|7#y~@OƣmtJ:__mNW8-Z]^Y΢j%ƨ_X)C' $pw-Mz(x0 Qn7ѦSԕ񱛢TNL3>$q~ˊfodJ]B\~ _ d(7~76A*azmh+#<_pI+K2 v5OQol7ksQP(z{vvɜGprڨ՞U$$z 7 qM˕`e%J=~@f RB{(3Ebi"(@hh¹G9\zQ#SFbw'B똃tOtl21f6èeYqf=BQeimo)t['4ar+//a9Ԥ20ÔOVr; spW_COFINŃa FϙpKlLe[DQӧ⫇QnLFir0`,y TaS Fa7aĝ v}1m dPF'ti*͊POȍeztz㩋:N1ЫB-A{;~Y "1s7ZR_"+%D:rqu&# ЏJxB 0bL@vh#ms1X7Q\܄UZvn/ 7Q=ɍ(n*!s͊.JHXp+SsҎRH&ĵ(P#v4M0E(Fq ΈHZL$N= HqJYF_W,ܗ8<@,o /PSTާF GBzpfS0$*OﶰEkRDK9f;0ZT7b6ZVdVC\ӛL"P_OΎ*lo[Y񪧵L Sswl\waZhCLR(ňPr$@Ҕ8᎜]Vuв *%299)&$Wdےbf*&Uۘd=t!76O1z nSҟhUX=2#XTXzɦC'0M}LC,Aq`0N[G8/!dC!HL'_gZmY<I?\rѼ2ܕ`/ `IXH4ٔ=c%)v9K1}^;v"`ccjL {Ր)yCSeMM/f.5p[p+.@#_];ܕ9-Z_85Ao sh?򶘞QNdI&*.P_G%zD F# vNlp;B<DMz.!Lc x֮?c'`ڮ"<2Molb`ykTf߉0sOM T@0QE:\ (r 2ےN AwTB (*>m]O̰=x pHcCs"*s;gͽ-80.4øm؂5X³PʕK^vsn5Tx0Hn߾VV<]hj_plB>ʂw "9'JbLAN=n4&'Qbj^j&f`/! .jP5WC>LnA&8-BH# <+cD9d5=Lo3ތ&{C}å*oHJ则T6UOYu }@ք4 9cq`̒3{ +~8J)󝝳-VG$=Hތ.5FVF^, 85ӎ aoFYgJv YCRep2iO\H_6W#6*_g W2qR0!ƛ>kc6&l)12kӅs9L87wH87/NV3s +(;.,&#_jLu7N{dXJzӃO;{,g-mKƼmaJZlor ƽ#$UĆq)U٣pa0Wۺ3ly4 9޲GNmJ>3xߛ=H AӸ֝q?<;yzj#ґ.l~ހO@}vTa@0ysIrqzW[H:#yvg0?Ӿ΅Ef8-6ckXHd ]&Q̽, Xtm;}%LHnLj1v=Xd:N/^TZيji$4:Q͸5X{l`h5)3 B6B=رu޶'U"8CV|Z=ɀSس,K7sD2_gt\ObHbR!wr!j]ĥF^s-*Ǐ/oh>~r# :!.z-]ϋut#."FZ\-h "5~5 !aTo6$qs/3Nd"!弗\e,#FyUpd3 $]W%5WbM<hGwrX9AojF|D j #P}πYE J#W_0 ngwm#X&]:I*ћ1#b=.%8;ܸ| V'.=d{pQqu!Ap wgioSTQG\/# b_dNr|wNBȴD+YM: e'`rqHj#B0C9undvwjQ4٢D6/`J>֡P_ K'm,&!+JtHzj~,Ω@z^ֹu`]j,5aL CLxelWYڢR;ڨc.[GcۺHLj./[Dks,mI ~ݽ̩wV`ݷREª}DL?ѡCZ"9i`bu'P}\|vpns2dTʌ@RIwCՆ;aDVXM(]I*TeyCaquQ\5FUS'O 2԰ iw?vY>'N Ȍ[(`1f@70 VNHb>NY4^S? I."e!\'yY&&UF[˙_^2N+{>uX]`lZ4ԣKk t>Ymy}NϢ-$3Ca鴈0Z\d _,x$&DJpK'f}9RmW RxD+ dehCܶW sQD]툽\ND0mnI:6Nv\("] Tm_GNa1-;*6=mٙyK@L7;e5P&JYnS;dKc_u)jiJT}*+ }gDN;L~_uч=*(m|WPp_v<ɢ&˻t;qNijф ⣨KwWCalvqD$$eC 7&]_ʄĒ W9kl\!b;,!tiQ0G3j?5C8*1g\xb5]Ea'@uY4dPHVhk[o;|& w7}8`[Nt%Qxֹ/d yeput!hkEXr9s{GAâ7bQ6qsT IIz)-~ ,Ѱ iϿ-鞣&nSs?.-/@eV6}1H|pthC@2sJߥ󘧩/'} *2DëDD>!'O S@i 2c[Zr)$#L7\;}|״:>5Q+p KSf@-n^`]T"{Elҳ)n ?pq\zI@Y j[+e qVvYab_E%o@f;hu`Hgjzgo6:1:gɅt;7|c6 ʰ&m4;9|ɯ>33QV/^`득7Pw"CQc\" P/I֎T<9z/9(%a9ǣ3B0najv]3~hllbb/k|!˿SwGݕY˻Lɝ#{*?Uzzߏw_Sw݃O{SӤ? uv?Q՟Փ{ʞ=k~ bֳk+za~EX{_V+z`-|CrR ,iNˏjrSN$TG%2'Rb_|eqDx5s!>CEGQ[jw0X8ߕ]jK%}Hy-.jUŠ*`!`#.r@}Z}N%x5%@ڏp}y~&*V"U)y4\YK!E)K%|2#6jBiQl|U^䞗O'T.+oյZwPE6/մapwr/‰=ˌ,Ӿ{蕱55h˒Y\5S]?';,i),89zUr%UBx닗 ߁T%/5ެ<6gP?XO(e7|؄~_!Q֒ Ѐ/)G@Yy۩{~>s\@ I:  =upB qf [vonL+|syH/cJ^dY-5'Z.GvDmދ9]y#;J~# J~茉Gl~%#1@B0|ago%(b*6%4*"m!0XMR+HjdvOQ:=t!ygi/CWMa :DW!~WE_`^:FS}OV.>/G =y.L*%(+u h1u0=̩_/A=pHٜI[(0tXA!T4g2swieD 3w\~˻(˪*'3LުI ?{4{?wN@,_xd}!} kQ>⯿-zʠG7*]gO=mHg ^GWl\  > _MB~٢jcC$isj6g Z)B nsbތP.;l+l j_0尓]q/#c we\wZ c <:;cVVAH?9g\o-\%vQ9v<.͘GېvdWH6p;Z_$Tas fz%9{R rI׃P{xWaF){ PԢ=S(xmra LcddhmB[Gbnu szmodh<}xyD)P7ň" ݝ0ÛT+;N|l{ېSǏ_Ò\ŅF֦[ nYLc*+DXޝun Yۋnj]) mO:p2֖(m")FdsVKlNI ?Wo!iwuۊCgiqJnz;5l]g# Ac\OAOʓ{ڟt<(PlƮ; >^yTk# {i@T@\k$/`DDKC*) YZU{'2Xz'_vu +4.D.RPs# Yp{FS0Bĉ/|4 5|DSd\L)# #D»(Жr9ijv"VT/T /Xfڱ|ZӬ_.Z iPl=v6(#Cr4*i!4

    5n+DOx)~XHit7SM*}wNw% Tm`s~~sI?Q.ËM*im5vW~8nhcorU?f^$}fwfwY\ڱcY$wfJ6Xӗsj ]YqRICK6XqC%N[z,$h,^>8DFHMC2 jܸȺ-pF;;Kt}E=Ь?FT&PpFޡTVE&ͭhq_)Hp|SI ֳlgȭ97O +G<+*"wXު:PJRheP{*.;;.Sba^TxϨZjrZ϶zLqTWϹ?-3}UoOѲ .I63 Z/?h)e>BŐ2Ѫ$ Z+\@}}BE*GtMUOs.'./bS/) 4= z@+p߿t 9B"m!Y_(P5Ŋ/W'C(ę V) OTzC5'ݙ :!z5Ⰰ@NdaxCIM07i5DsVG#?T%t Bņ 9@pD9cD-aASS4s\h޺,G s-u<`D821zb[rf%J>)6qf"qs_)-Y+ ôBuHWCS'nRYj͍''Z?6֟}W|VqPH*7OV 3wȟ_gB1`JwSv(]a+QBn頻s2,"!:9 )bGҟ\w_<)~%N{)gx $qQPn^Q|$B"lftӦ'WI7bbM~2#X#IƢ_GV_Zm+>ӿ*œ3Q[ o ~ 0\BgQġH{7ήsV)G8Gxu;>JzVWQ+:6qfyTn*hYID2,;9 ÐIg50gFQ~òn|G%j3!cWJwѲ\hh?NBJ5qP}9)fɤ3NG?eyt\Xj(bkcz(pܣr/nm|1c80 (SӧysZYɂ ed"bB?˾>=hå`8-v8RSr*߻.^`>s8.Gi  qa_hg';?XJGq su(=zx:8CqRHGfF8 Γ?r-?9ha; I-3#=%Dټ6ukHbSd> sè dWʓ&^Vgc)*>eD ]eǒ`l (1]O[t$\0U"PU]}q^X˜BaP|4LK %ѐQ*3)I5!g_",Z}2[Ut.B] @@L%m@̒rƩtJr!iFOY+$GYg̶+Ri*7_>Q!}vzw:GYڗ8028 3CrLDŦ=u$Hi~V};o.ålZgr`\V}_b~=|xImPJc[bc-̜!RQ"m"+9-@[wsAՔG?9pJT]Vw.Sp#9=qsEE4p16"H8b^5u*#nK^0 Kl(N7܆KOn\bQfa v,_b@UvBRlmf,SqE" %`L3YJx)*9P8O"Sm\uЭr.-BcX#IQV|R5rxO/2 f|0!b]zh2,!*`8JyNpЮgԃ1`8!',OX)T b^=z_dŵ)Q}>AIsg]1Q&E7_Yn|oDq^xHK۳U)QUGv|>w8 ZKXڟ U9)o4i=&[ 0nMrމW u"VeTVbJ^SlԾ*1 ka7+V{$}eX/Kt딪uAn$#"Q=HST1IJn1V\y`l3W5#ꍵ'O^_Ȫd\P;ZEзoA5;}3F͓L{zgi>7e>iz*OS튳UvxbQ[mໝ_ZvΎO[`k.![1 xǥ杣ƶzj'6Ay^\&$$K׉s3E]L:!Աl}xnF I<ޚh?V{>fv1h@u五t h2),xKʝY3]q$5vCKKkCxH l ϙyϡ՗zqFjONN-I{ɤ|<%"6H^|-^K)8qXrhbˈEYz " y$\S*ex*, cKֳD<_SD I LFc[ca_ {㳷l0uOi q,)Sf4,dG"m('o߰B1TlJoߛ *ZX='WpyS(PC"s)!5XU)9ud[1ABkN)S% %Hp'} 4CzX*8~J=`HFc:Wfhv͔ ?;XR xa8SRq"rPNgGVqhj<|MN 99b p4_Pv9.*%UA.a#Tz:0yuNUއG%6CKqi?`u z(yov[D+/VTȚ gV fzk4"#;_i#-f"7^sg5fM  _48l:3hth#M !IS5΄ aRnY0ir)/4xyI^j8%XY r$O *:"$z9Hb æQE͞6dfHN:@EhM1j|qԙ\]%xeσ Tsy9K 9xȆ\TN.}ҕ86_gs']\Ah(шea_R/M*L&;rA͔;ʈ.~Iq 7􏀡_ 99fGv7n9̃e:B[\3. )*A[sHi8Y`¬yə#+Ab Dvͮɍ0PlbK߄Dc(ɂkdHUI>F^k28ŀOɏ4ki`΀NY @3tęefuXM z-^I%f`ag+lIx&b;w'劅 n4kO^f^Q4'^T>`&QD;JC`Ml@dF@#c ޮbJVQٯU^6DHOhPO$!T>" d+K%0[T_FS<>@EGxVM rќk-bΎllY+ϴ lHB?oZy馩jː۩3C5v۟MOUo. x-xGmӦpWs̀竸NZN㙥 1hr@b;Y}^KS{ Ik)rHMR(?IG|^42Ri| jVY"bD^UB7鐹'㴫2M/s[t Xk7zѤ$5?^ʀ?w%@؂B=U;:hOL,a6GcF&FxwȎaJɸ=g78t7E_  pqBPtWlDCnwF@ןXyب?hcN$/8?jV^Loo }U ;eSڻJbv[֎}0RyH3@ !0E_V@)~LWGR9mt3ŶhO883CtTӘGVR;/W@GN 2v12>~.lDn X|ޜq.wlգG΅=BہPlvRݽ T^!!Dx&S*2fFp`|!Q.X*B 7bp_GyM^/2J/(P;ZءGfdF/WZQx NHPӲǴ^Pqܚ Q02+:%ʕ4uWZ n/A`h>܄'w)$[;jcb%sW-8vl:I:cl١VekcX=RIו\c~rĉɣJx]*&sƒRkil/SNt!4Q3 _9TyIC-5i֌i"jFT|ld%L^]Wvb ROE& ,c 5ň\T2{n s20Fmە;[>-Z&|נڥל+uUR4V{u&s\m@r Yrrb+_L^x;vÇX+`Ri.ڪj~(FڐO݀]UBM9+MYoosg: ?J7X*Q}- ط(`S^w*EL^"FKD=\+^$QmnԞ]Euok{ʹÊ WݣqLt)l0Ca3PGPXg80@ ZSʨle›u`q<9?:ly=jIkOj D?񱳸dѻV'$?1vchQiꡲ [&Êv[,vN-=˔2v^.iӬwi6xh5OWDSB SLzaCd~zyB#hkF˝>xr[Pv ^_pe%7MCBzgOɡ f w;0ZĶJ}+T@ϵ%E q3} 9&Bu^ھ$oK\Ԣlp)C`OV-8nCYOZtY:jBfr"p#vYWCtik&4&__'H$YȞI%%OV;]y=\[>2՝{vͺ5= a8AX$gQӍgzhj_;VPt@# u7ɒ=Kxd7)g|Fj X! X'oTLPW=\`<} =Cs--z<9-#GbJ|76K˷NSMQϨI@xA~0導i`jJ{]ѭUR'u lPr>V$kCNA9A_n>'VogryN,Yq6~+]@k5(+cn*六3KD ÃfDҡ;67EW8̧bb?4翗Pv5b* TcJ Yt:#lswũ[d5^+Xq Z%5)<ĬF|WjS4T2|O02hs0$ذ#JC) .[ֺ vtU ()I ˜-t5uLq3EQԡwp#u/?FA;QonN+)*OamZI-eɬ8Ō`^^q^4ghu0CC iJmI&vnW_m#4^n;ŵmoG%~c eآí6A  \0rqXUʽShS<=ܕh (`)" t0ɆY# ^O{;g͍̓` e~ZfgxW} / {ewXg\^9r_ZwŢxO}.2o܂%qb"L`۶X-L3ԲqOT }Osa\{>=E`@UQ[<;4;V/a0)`4DP[{JŸsf:8VHN$R6tr|@"G[`J<JMMT_/9!44 dϑXL{дytK[28BAPG~w*3RD/J@;eS9gŰÎg5L(jN]Iu|Ɩ%a;>?^@"Po|&szvtl4U$dٯIڏR̺xjӆ;4Q<9](x(t#_8ߤOD ## S ?w EŔQfhS`*͸âăӸ Eѱhˆ  T~ d_:^/UCh2*NHUo}*)UbՕY{8pݨ.х*ի6ՊK 0%Db c܊~" ԫ(78E/^Łx`˻yyE>\qsr+P^׉#3Q |,Q6Pj?Dg͓nl~[G;6^N6akaIӑ@0߃7?5O_:h0蝳'Mc_)|P@[E9<:k 8i`/ \GR WzGx2owN[_Oi0٣BEr;.UoU}h;ٻݹO˸9}=C}EL&s ;bp6Ԍlʺ~Bݒ,,K%x,-HOxƜNa\y#>7+;LJTS8I](삀^wiQ'Qڢ%}!ўzKd÷4'x-Le?JyII-Զ9{$EaH(ȕ+_XFnQ$ qàq?|=9\h≯S[t]S>1q.c1r FG=0_۽{zr}m&x͘)6-GQMZXbh}b0=5 U@Yɉ0)+\bF()%gMazaG eCHtIn=5ӕ3Pt_Zb { FmLj* A}~.U at0ZebqEg_a4MؾnF4׈~yޒ95V6+rɕMƍ-{ ?"Zdfhh *JooRX,/-j܇7?6h/(ZbW(OC'BJ#lߢ7d@1N1vpDr{zV? ddg^NJmʇHTq2T{OanO;/rB`n~t8O>:)C?Ƀ]fVzӰ5xin; lDs\PZ.ʙ@|IĘ Kb2_!0dc%MS)HUhQVvD1JomX؞5ܴہ(P7ejn ⲕUkZjQMRmWz$Ċ)o˧(9ƏTf;m mljUʻK$ S)"ep8\;l DOkKϞj%0iLM#]Mյn_:7e%<bWJ-L(yY;n![:C/MWT~gm{%0CͪIdJnKzXFˑf s\g1tC Dyf Gs߃\g35m9WԎWI"Rᄒ2};rG{A1Gk14.WvDe-alB'm d;t2˜W.xfW ֌:ִU/p"(4"j|dzΘ P\kgyA'7&:uZmpӶt@b,3`yxfTn6O*mP`N'?Zϔ3eU6yz ۦ:7坱1(儭\)8Bo' N@ 5y=|3rvϜv(\LT^DWkKQxF+hQq uK!;%s.jNa3(Yޕ2NyӹЀzcAaPca.!%Ez0ꓩbV[OtK ?TF; YT hgU96MѼ, G_Ѧ7 ETp#`A$8Vk9 +5@y͓ RCT1 dCm4gȲɕDhѭ+v-ͩ %Z36n9=옧w2.#zz{WŰUZ pe~ef*p^/' \ ){z9VtM(gZڊN^&~#!*Ď&!|*P$TRW|| Bť69hp͐o -8[;}@Λi `}$>_h[v63r#&GrG rn|45WvsMrH,5crkg@E} ϺbଌiOCb#rNՁ9zo-̚`>@u!+MY&&Nda 3B5pq&ÌD94Yws]R7զOvG6V$T ?6و[0gl9o5;)&[c Qk1GYVݮ$WqG\rBfx/*3waqTie`lNFm}ѻwTvpG%Jh7^t~`F> tGwϞ1"BRwTܤ䉣 YO7߉AYddYA)k9/LxQOsWlLbӰ2tyPpŭ` Űq&8Rpu,Ǫά 82'L{USқ6nHAm!Aք3_X{:0'_6/F6#yv d`uw`8PI+I>=4 h#YV[3x]aѐp/jI[8(e5DcBv)>Gl8th4 )Ք2={)Jm QP[bjDž{0`RgXgR֫h"揃4*F"kim dmW se 'Le%2`ztQGB'1PL]2MAϟ%R*d&wO_.Y@j[ o:-0Lؓk/Ə lO:Z(u@ ɢTFƿz7&%Qʌ%oBICHĒk+eA@Lؚ,_iFY|ⶆgR4I(O'ɬҾNW̙8bh2 苖GIխ)gފGz̔:KeLA,8KT9P/"z^rtpR5@A.P.t ! 7I+,7>V9iOH3X j.B-ڊǎΡWDuBQA t8g"@A,o"HmyƄWʾ|;RK+ŭ{e)]%./xM&Z@Q&iõNEAYn~l8c2[(7tSiZwP'!<+LW˜ySqLͬy<; o|ktS $IWp.EXu|qPB49L4%cY+q) їb9~2V\ūWz.<*n`z(Zk`L8%{)Sp;iaW;?Db`d_cFvOh}a = u.Nwϴ'~ %7+ %Yű ( ;ӊmhb|!?axʳė:c0h?%  z2 u-=+>Ǣ 4hB]d6' Еo]([:@*03 ҒL|,E{Z1^ _Xf;G#nvөĈ }Y_IzXWh g1|?eϊV7Zԯ="V9QؽT/Et0<ecz+AuFٗ.H@մN KVZ@;l*yC;dZ( `+Y _}̚EӶu̜!N85MpՌLՉ5xF`Ap'.{_񱘼R^7рn1LQ6f ,CߔUl]z| n׹jR`"i&`[3 2 ~8֓ğN{ۻ&)3X@!d㘩d3~T*=`$\( u,am XSP-82m?U-G gcENN^*P:˳>3T(K~"n*9 L'c'`_qK䑧^u:3Qj1pyphfa*k*Z@`y}r7SZld9xZÃQ2nGl(41MT(1IfIयMFL.;[Dn!ݹJ~7n c*ufQ\bْғQh/yalwn`asjPmdРi]yoY^:qZ[]ZpZi6}ss}[?٬}W6]]T:O t58*1H g ʴc"(O-cVJӤ<]D;.ە,yhkv H\?e۾]`t iQΑfq+t71MRY5t8TYP8ޤߑ LIO{i@o0]kƾJ_@.WQ▇a"jNA;LjiʴK#p;jۼA ˊD ?v~999:v㝓;'&N%G 1µF4n_WFIƨZ!2Ys:獒vb0=璄 [hTjJD*32LtJ%x%(DtFVD w;QQ׫T; (db yKMxO=,~߾LI?%ɛY#2g0Ji& 22{: дVrif}_ I2FQyx=]Jy;\ L&I"nGݡ ;cK/1&bIB!.s~9`jS3.[Ľzsd]׃Ͳ=v8h@ē񓠳s1jc,NqR.E\ 8I)k @L6@ _b9 g!WV[8.wpAk>z:}||ܳyS7[^W5q<iqn ` 8\cJ>:wz W`:O^655%I'MiH sݖ`1;d'&HۗБBH%&u;PbuWꠂ~= 0o'F%pHa^no^Tz@#e't,ږٸV._:X>AOgmT[#[ [X꬇_[9Zd֞՞j=}*k!Lz˜N6,_ԻAw9T1OXeMD `r~Mxmmw0u*@rt=$ : Z͉8Ej,[l_ާRi*E$ȁfRvޟviTvᕖыh'ZT!{joa( \ T\K$V5IbE)u8lZZzP v(dfқ6 J^o.ߖ'ioGd(FW,XVNƤ,yN0jI_i> ϬF,N[gr %Yf8bwT(ɿ==NMz*^}hQXhvl;kZ8U=NB;Yʵ7J+6eSU 5ElJ[$ÔU5Z [ WElc2`[&lyiVb 6anTZqA4gŢ9QT -#< +#)B )_&r㑫 ^2ќCqBɃD60?++ZcEXCO0twVPFMX vvzF)1} xEqWG/֍PM1$^y @֗ɳF0N-*J9-GN>1溺 ՒL>~%|ߖmR*vmyWuzUņSN7CT+9Tq#Tq*N5.:Sq**nP ]qөATqSW|P*Ҍ#ka%$y`"isۨ_8%1)Zdњ:KdM4 D^2G5֧cA/5s LBc0O# ϨՔ\0nqg(̊=,g}4(dR,74M"4ik5ɚ\УOV$_ri0}U_o޳gK^ܿ+>:Fų Z8',RrC̏0nPzZ.Gn]XۺCN'x&peKí߻RBE~x6 c/P5'*HP }7oNOj Rt"hDBSQnw!~|Y-D7,Ͳr8:a8]tAf@=&nSLMwq̂Ѧ/jQ=c.8"ƃp2)InK5ȼbxcSYE\&Zpx ^Iq*8@J52)|!ʊc=vT)BtY>`7Ǹθ!د3K h@u2cݏ&E~_Y݈YG?:㴜:lbq&IGJeʬ!i_ S&=@z ˼O]UBZ>GʯϪ {OufϨjz!QT8G{L6)Б>O٘X~jJFem8ȽL+F4{YD `_,4or<&jG.9WłH܊c-<nOI2DfKwEۆި$܉E5H+sx||]GhC9W\{7 BdF_{6*,̵ FtS%LSǭYTKz({sV\kM<ޣ).pnmU.US[1Wp,xwxTnE7mJ0 RBgOB#\_ӄ?nnztjNQrt8o>w('M_HErTz%Z%ί=>T[uVTGeߔ,kO06sGIIj6]%ml*XvIԔ#Yaf) jQ\6k,(hL'g%[aZ.8vc=k9XI@ߤCQHo%P?a4d7b@gƗ̀zmlH07h/gɼ/6ו\!//j;o8;8︌;+y1.b7+9?O (b G+V{}Rg SDrs4 'k+GjXRqUnDpuW٭N2-FZr[LK)0yTeop$eP]f.|Mw!.1'Kv;c 4߰$DW3AӯX@&RH @8,vMŒ=)( ǵ-\T NǝOɲߐ:,@!Tk5ZVcwБ^(ڠCJ2-mV;̿/ϘOb^7(b%S2ЫEeHߺ1{ZO#$?<Z u_V^}-;tS %@^ Nƀ RN[Bw bG32S({)Y9sJ?CǮG $c4z\@k$ c|8[\*k̥NhÉE 3SR4l$4k~Ci[%;T!Pz7~>䗶#Q7*ӿ$_QF 8#ccI]٨מ4`F[ǿNv~`֣+tC 'K ݈gϞU0ÕIth>H*ur=X|[Dw":Ro jUV٩Tu]3aa9s9IfF8'z{= W{+mKُ rۑDpSoݭ{. õ ڿY~ /] p$=ǣHOG~+:'9ܶ b8sË˄b4#ǚN^yؘdxpLxQ:^ Aaf Xa>q@2U{ic3#$KxFr93h(.v}2r*%U9ŚJ_GKٶǎ1HAթL Ҟ&M9c x L;p@"ba^lj=ac R\ڹ X;l-VEk_^vFqI #^%W/@˗PHR'h /@ bl[U}~'ޑ"ya`@\g{GS!)m/h[v@奣PU؟6b* XkmK<уuK;#\hUAJwt̽L{L)uȽ*P>a{H2's~3Xޔ`E_stJ>A(M *"/9p)Qy(mckm8%4EU\<УGE]$VSŢ;Ba*JHU%W%- lkM-K@+iyact + ⧱Z=&5jsXOVJ$6|1%DZ\gE\s/qiYP:*a[O;%+rww;CyZD}Qb j쏔K<.Z1tXrMEo SQ+'0q>.G]t ]{Cb,vWw_ PSXq(; &-WG'gvv8 ^ޒ}:?- щqXf $[%q6跆#8z) 5` {Icg).oS۬|wjX8Sh?3Q‘Tm@ɈJL* zIg{!7x.ƓV~$gJ Yz]S2WXy;o=aF{jY6 2Q"X85SR$Z L,IӘWON?x@knk?۳cXcBX[Ìri*~`j`oA*-I!49,J?@-q`I+޳Ѽ|X]d@֊_tw7x#I1(7)+1sA/J'cJ'AnpG d`~N|ܗ1MRڰeJf^LƓ}J#1^fz;>rgCWf% 8dBχ.82ri]Ne9G;11qʶNîM%4[AO,c x8X!)ĢkO=@<7짴:Fqɒ?Q`aAf ;n  quEJVdr *Q2᳣ۛ#q8O֢G]~V.a`Aaf./ƉEOkD\bT}pnܮkGwgABfQܵFdZ_"Q͑*YU(WՑU`l<|ߣi )ԧ )]i/6&Zj1`Xu)Z^ɏc (+EEDl >V~!̪ː=Ђ; @Rj E\4PV̒BSAF(Ae"ŒƒtHv+9nE:Eә59&ZgoL2J3ɓ操͍wfɷɇbGG?p{!q r?f;o ,}wXN-|-Ȧ>`bK`F0iSKx5$k%:)nVj%G!9 nm9%H,|֞8nk P};=J!Z ط4eRZtry wJ֜N^. 3C+D.<ӡܳ99{.l{9eh 1T)?]6/ -( X6g{Vr֬ug "n@͢4A9p ̩qq"jr=:80;#ؾSnC}GeBy/8L H3XwwQ +9 Ukؒ;FTї3Eko2%ʔ,b;g@˔N銼R<Rd>I?\MGlYCZANTx\LҌk>XnErJ" :+T]P#bFxj].w&5*ͮ:B(kO¹{i z}@o^J+)ӔO=WN+$ *fD6z,KI?X_ 6St[Cv)@w]"b>OJ1sD w ?FX5_#(s@ajFOHuNK _/'-P1^o*dl.9*0K  l$[ft?\.MtZ6I-V[6 d^z*gg`/?SW}z@4[:(+t Yh4 3l _aS7ūe#x|0xۼSA52!r| &O'_~wzcVofW|$){f6Nt<]8 ځ>icWUڗdHn0Vz6ݤO 8ټeNq0(npW-53WŦ[N3Y_pYL M8'}N0x-uƨS z*,d pxllt(zt?6yFfy}H`<³Ǒ~%V6 l)GrXO ^^y=+ }2! ZmzKEیe8Ǐ.A6vîQT;Hvo 1,"݀p(_{.76jqK{Jxu3(!ɠ"MX޾4:7NuD&PaRxf;i5Y@SLS \7^tDM;( Dυxeǭ C: B^Ayo`̤x r>ZZ|I*nYջ&=^É%q1,'\/ Ra'u |4,u=*+ҝ,E BdvuIZ;,@ya) eXNK8Ozu糷Fa\mE徥!,I0TyVVxuYQAZ.*c #h$QD=¨1YF\֞l|E[9_-r#J` …]E>MP<(aq.<`hn\l"9g@0ku/ ̷+^ụn>'|`BFNRTTC˒<П3ӯ NUy.!Kgn$(VޥobXiXbԚ"~ePc C?Fxhlh*B=%*̥SLNwӳ'V 0U*Dmp{`f>*hm3V?<4=|+y1@uUmv<@qhl^0aC" țU;*wBrh%fV|fثheb, n԰Xf8՝7V9R` ow,f!Z-4d.by@!zL Ru OJ7R ēv!(UJɇ-$qM[6^*ve,(YVUb` I=/lZf>Y[C&6{1_!/Hd Y;M[tNH1O( $-ؑRZvSF]amT-l^݁'I1W/[%BJ]%;r)^&- yv1k擧v^5_/r֘9aeh_ `#ʜQT#Zʖ*byKJ{!^Iɸ;F52VA^ygIa@-KK!cϭD,@ X"{}m;Fɮ0 /f<wg~/lՠ7"Ɓ:_">+d g` ;xM<~Aw+LrƳW8<:ۨJ;J1EnfE:8Y '.ܙ@}fRydRR~ߖ/nJ,-`lmjݏ3C\A_Aj+e9%fjFPCrߧ7˝;MsE$>0ȴ6<7X;*qBzyuaV^$t1`q{:*XgbU5[CVShTp;,\Ŝ"J&#Chj[eXS* UJ!h)gҌwe?( 3DZ͔Ś|XaH ϾqO}ᮣD4\~}܎ϟzD6ڌ0~ ™$$qOY5m9u2d[UM"@ض#8{N@I*a$}{=oUҋ0G~f^h[M O):۟vZ6׷H8_j_.!#Da8$3[W~? HibsK>/H5c?Xs+>U Ke=k2:l%+DЊ!SQPd 8jlcGhˑ^UsdZh`ڬR^CـkejIٖm1ۢ{ֵRzuq.ҾeZ#@1y%Ωwo8{]d Oig vLIھW10HdbVPH>6>݄W`kPq]~;z ˌ,@/4g/1gAbZ02nK`Y?O#gnWaMԲKf#+ƆU6{Z~oj|qnk\:V 5ٛ WB+J`ƱL)wۢA˓>_6B76CQmV"a)Dup5fTS8{rg0|:pv+?R6]w>1҃g7M;7]]iZZ֨5jiZZ֨5F-QKkF-QKkujiZZ֩ujiZZMK:N-SK:N-6 jiZڠ6 jiZ0-mPKA-mPKaZڤ6MjiZڤ6MjiӴI-mRK&I-mRKҦi ZzB-=PKO'j ZzB-=PKO5Jtd i2ralR|SV+j# I ,XwM|=1d7zZ[rU1,xyɗu'ݷ;'cuj6х 1`Ď`TN:u:㮸j6m:,pJJm,lTIC]OXC_r=r:"&N\#W_CT3\(,kr_qږQ?*MJPy葤=fO2@,>eAC1X zvDƣt`Y Fmci,'AXZ9CH.fp/r c};GM22' >lFUW5j$_H=`yj$ZHhU#ѪFUDZ ~ ~ ~ ~ ~ ~ ~ ~˶3߉簰ps= t0$pO!zBHtrXI_" J)J)J)J)FgFgFgFg ~Lc?&1 ~Lc?&1?'sN 9?'sN 9o6o6o6o6o6o6o6o6O~B'?! O~B'?! .......nDu܂L'wwGC`r(B-RkFr b{f?bmuէhևi5!e=jaQ6,PwڳU9(/ eyI)Ҩ= LS+".nؗ;xU8џo:K'/ޑ㯚&l~}O9S]S_-ߧ8 6g4~81vwÎq'PeKB.aq!pLw-՞ $7×10lEifOÓBz|3Wg~o"E>)} + *&G9dz8Cbx֦ ҪnRKdrgG̡rC_!\~6u>676t_v+>r{vvHplQM >ZW6['x<=&y1r'w<q<U8U*T`t^stяQ}N%ɨ+*թL2mta2pY ~|&&!rS= &@#ZY(G~C[_0c.ArIȣ3&ҦT4)@퐿[4ғr{ut<;5*=*'xt8^\3vi@%|:%23jaF>GT0*$S1A. I{)Y?(~rQDt>p_T$%a5LnɀɒrBA%vE`t8R|( m)}`R?DБ"EPSޟ! _Mv<4;O; D^9$<@_@'zT#Ν]'@%XK%LF9);aPV=D@ƒJ &Kd>}8Ww&^.q(;|ۣto,p(t0h1n'?.:P!@%J<AqǓ^o.wb ;(Q{'8)+(B YcQ/&MܴQ-yO< 效&]wcl˶eZ܉<uf;Wʪ)v$׼iZr0ĠVBW(76P3GGĝҡfQ`PN==K+^quYEkoe[ʫi?CD1&KdiAZаWrv#)X -օp{QT0.E@HrR`Hy"Qh;0 NFFW!3 ,ّ y񗊠Cf+ȝAgu& y34!'Ԛޒ k5Po.Y1w*}|)&QX K}FM=ך:}!1 :J=r >0h^5 ( ;yX%w:TN*$>ue/ܾh]2_9"uB[;A"Xy#O##:00spLeh渏{ȅL"-ᔞqԋ?ӹ]*^YfF)XE04\Cd';BK@f T5,xٳް#;0P5(5K)%J!ac[u{\%h oG)]aefֵ*+rA?98k4EhSylpx@]w"ELDϒ^W~D.g;J~3,F 2iQ)|,;7 ˶RjT7F].d@I P4DG>tm<Z{ )DLwDT/:WӋ}H1wl{ 3P5V,cbBԷ.wIIiF|Ux[65emj^~~ڇ3gd P !*35'N.{92%ABD U`u,@AR5&]1 i:H;, `OXn,6C=u?L v~6۲u> PͭDKŲg;oZ_Aj]2줏~̹L4M#*",OE!ήoo6~Κgci˞>M&\ 4r%KNς}99=cN ''4˙~r#%Y"=#gf oNQuNCbW;?j WB=Ke,L8!ZWvqv9EHz[VvLr0]m,C*NkQilÏT-*,@|$%!47QYJO`Enˈ2E6 zh Q&3]!DU2z{uaټpD3',heTN41]wRz. ܩխ4[zɹ8>㓬x ĠyMW{ 01`q2cp/Pi" J,&ڕ >Oqx]hlGdC/SRe~n;Dw~ $SVγ=4L^p~:N^IeH5M%Ίu?@99&jnnm"^jЈ}zC&BiYl[wD'I6艽5_8*xT-v+-mzS KeIB !C~ڊI2[e*{Q42π4tD/EcX|RP]xCkXK `e|S*vKH& -zLYFe3=7) }Tx;lWA;4`ɰ{@+L:oX^"[W[}XvFL4PemZ\ubcM]&wB80[ I(<EE"džM.Y;6Pe W׵ {@}EkL ES#79Q3"n6ȫ֑ވg9TVΌte'xmH7vD@GOϦz\*!2Nf0 O"g`S32Y!04Ni7v:$ qa܂d\şHcC0 8cQ!| c:Ӵ9b56{ w~:av$ Hqghj`U tLjp|!.D:@IP1[!v8bBzJ e䪪{Wmz5"E0Wxəcf2^h8Нc߻~tHᵅ b$%00xnRIG)bE ,gA n89y甧>qZ,&H5Do~cӲ`SQK}AbKlg_~]*> ˒-xd, jxC7g钿L:*Sjv],cn#uE-"q6Q#l xb 8cJmm=Z8=vVYvk~v(ݾi r S܊Bgi&Nura.D{*"b's wTq|Bay.- @œfEܱ?ڔk( Jx3/u0pc5z>x<Ȁ$i;H.$3r./G}Rw D+6'f? &^3M,˙6yp <)Xhkr}px\ di[0L㮊Lm˥&upowȷ$A_1Ν2cĖ;DB|&zwC LIz.o4Hv&}8VXvS:/mgXS{JWX!ϽT;*\D"-KH_wD"\R_2]Ddrr;@9>Qg 䬼^K[^z.'WqR'~@[iNDŽY9tYENcN3+\&" -/v7ԉ3b&sa3hW/=P] 99OI0`2F sOoAOFR,PY[ $c_N:a=+y5@lwe(ŴE tȆS@hm-ٱQӽQdgC6KGyn2OevYl[CW*!DMi=FD b,ߩ~mnJw(ٿ 5|[+aw9tk&H}DA!v&fԷRFTN*Q"Dn*0Ҙԯ;Ak|9Y@4045= <{(1Eړ,zm^[lkOO7%99)Y*X #1ONo A8F\g~h^峺+juCjz&- .;pk}V-xgtX^rE\7l=J2C nbk1uˢ[ѺXr`Vΰ(Pv3h%,wQgмfzzQ)!fY2aIPIf3 66e)Df3IH(MMȕ|qJ]BHZ2V``齐.cAb|J%Tb5ya]\)̷UJ[Tu 9DPޟ6l_^STX `,l:6xN+*-d8o7VUBٽ>Y5sq# $ͺ)Q.>&Ttwr-B9G e5z~Gj2Of0mT S# TT/ޤpt`t!t{;0*VPP!e6iu*3Vʕ}H~՞{;6V4.&8Q'90%CH奁 Q%m7R\#f+n޵͵+w{=^Îr,sLf) Yc֛ J5Mj8!gǾÜ>u XÚ~0yP]۪DmڄϘߐ~]b h$m 9/eLe#hJZM;ZPK5+9sN<*g{ᘻcX("*ϋClL1| 5C+N8:wXQA4ol@f;:ĨۓZUeš8ӲGwtrG QN:0A̶{=~yJku}v{|ph%k?j.;6 Yx{WSFw)_+ͩ X0 AA_D@oL"~RD\=h:ث(b5.h8:C9p _^pIXٰ8SŃb#t>*g#)|96|k>eHk:}! 5ŏ{چ\aBgOgꍔEIisEF1gMM3t@Ĭ%L#AO~AC8ѿ}lT-44ɀ7"VK#C#=~=94yěF|;>=?yW*Clt?x,7N+n4/^;dۿf]n|D|Lh*LLX>e7U8gImivfDAzg$Kk%i̓/jJg^i$8C᩾PԳ{$rfks(d]bL sg\zpm'5-)av/εӢǦ3Ӟd,HR̀iAF[kpyNI1xGᐗMZ0Βkqj/-i?z#틉m~ )m `0/XQ8>Ug]Kz 2B4ݲFXGQb#P$ԕr4:JBH FzpzyIs2,t'fzXf{gWO_۫{x%~m).>/I!w)p["[g($d8LC)I? HhE ?O!6aŧZwn9i8!V7q]j btM*[xןy4%μL~^6/{8?he_&=+Xy HZs?>96Ȝ; +_xP {qe^ir+\ǔjջtKnoc9 m͒Jm{Mu+8{ۅ.~]HZ ]Hٴfvؚ>bl?YRP1~6$Dҕ&$ySu=qf3g~%մodnɣ z$hx#\/y1ދ )ǫ)m2Ft>|&{M>Je᭯q if(1XtGL4LΕEr VrxA˾(}|ƃ5仐#Hs^-lX+Ό0?ss(vCp1BX(8t;<*u*0_2ɝ4V=z \ξSrƱ^Yo@L!#5L\,]v; =Qahy&n:}A P}oK/+}i*r?cn+ԟgT,@4r~t],.&Edљ C- ׇg2`QVR60 ՟54 XNXDfp_",}~ŭz 2Ýdq wmE#;M6+?\ >_JOyA+{FSQb~q2.>s ؽ%GV:DrD@w~j26֞/9d0SC!9t..?[ԩ6Y~O8f 7iRG|gCR[ d-6L`s_=9}ũIZ뼼ԡf -W5B@53kiMQFy^ɒ^g:5Ú;AQu?a85[F2H-9:`y ʐŠVUZ*ov"'xsJRm'BjHԌ%v_!AkL_ZŦ2NSjLo $-ƚnMj%M.74LNFwk^\4"oxџmVݨ6R 5mBm UIƆ$PS -='S)\;0w]F/b9[*1 g ZE WF$f<#3r[fk5$(f+tVF1P +gd#sܛW 6e'?԰5\ ^ibqZKGx}*aM!HzvKvu+:Lx0 #% eǣ*fB+*}Ty}1r -xoB*(F5\a$%2:+հ-6J׷x-s#߿P}N}ɵ{Jq<Ӆ+e Rz3=u7m"z ,I -ĐDjs z>Z~n]GL(aX ~G{ݟvΡdU\$=E31l73uVfhQ5BE*z6^YA1 O2Fg J20(GXK0'3rыQ0wAĹIۏՉ䁂xb& ] _pFMJa;ovXYZӇv1f-yLaN) {!EgSUYMh#S/Yy&|!abqsUQ\7XRrM-wk qٽ"w]']!nՐE#duF,s''s "o@}M_T腵Zj)l7i/i`4DŽ cqmUi5PKPDs60D, z8{*X1,5 ZWF+G2v\Vq\lR]UMLpa\K_*Tn] 6{쀻?^K`E2$i]+z]^+̽=ċ}vXū{;p*#씫8s)δ!?CS t_xsxΕONߕl^%MM0Q './H=OZ41qV;jі&@(yC= Պxz8 بՖ]NA)x p^+`>](/> wB' WJq ׿E?Ʀ 9ẃrB!h|ςL%u=}v9?*TnsM\15k<EmzC(е鞭i3!nXG6Ah|Hi1ԄF.0IkNHp/O b}lVq*VUkjә*} >cEDߪfD>n0Y7[śo,EV5K4g@ _{3ǑbFY"&GM7}X:}+zeif6}'vg_Ŗ1շ8 L7h2`E]saGr! r+%QRMٟFay]ir3pd\r8A=c'•/ht݅L+!_;V:sf^.9F>,tb+2h"f1,>Vyss~\v)u)POZyz+.V^3݃ӏOܼWi@;MmLKQ+Y:cg'ΖU}q)XݥKZ}dt\Q9'tJ^& 6)ŌxQ*?Qh{nQW?7={ܨGuT B]E˞< +^`8.9[vLe;Bv9:o9+Tˢf E=4BҐpz=mYdk(5x{<;gEO`*hO4u2UpN1ڜtrb) F~8dU^bӯL2qtǛ2ZJ}^AF? 16k8I+$+Yr# 0XܼhY k@l%!N AqMO8+ĺ>&{k="0bŽ& n ݰ|ڦlD7ml5n&m+4y\˄F*L)- \an5d:O+B9ل˱"C/vϫEW5'E$<5A{ > xI +0x-73B $d~4zwt|{3 77舣q~_ o%)q,'màv atڅctZz}r—3:KU`j ҝD??5S2wg`7z8%2v{SCgJ5I[eE٭m-78DL #wDj@eh#?s=S!zTBCϑ CDart8UD/9e9RV0"3ðއc!e:|P6y>gpacfU'wmJLI(ւz6 .g$WWr{1o7̬T9Wd?~Zm\e΄ Adhy ^TMӫvk}yG5R а>]3iW1gU>ccdυ=Sݜ#0x;mdYISρ/: .K*j3+ttzw"71Ȇ>̷Rz0Ḱiiƨ@UiGfw!EP??er+Ns=2\u \ I+s7r-/bޓΗĂNZy~S_YҾ~ijH LwxӋ?~[q0NJwzjGOQ.K}Ey!P7AF0*b qkOӡb㈬#yfH/7,ŠWZ.kC:B/IƬFQb"x 2AOsA[Vfgf73hۘ]f<$B_ 4Yf8N}Za]LķxM}O8!VHޭV}H#RUH:aR_;%xe$xytғދwoZ랝7>5fdt x Ŕ!,𻽛x}9+1LVD 0:fbV-ObMu k>uĹSS icz1K)qwO&)wɌ\ {Jk  BYۍVMlQ a9ȇCLds",$cd1BxX^o-*B5M%9pF"Ƀdեy$Dw+Ÿ6ؗ=@:4d('-D'NbZޅKq|F\S#7貿 Ɍ$@qߥ4(ZT2{ghf݆ ߒ ]>&a ,O15pq ea8F(f?`K۳>#m3^Vr}%˚wlwHynV ['j;NΡ1ma9O$g4%дU7߹d6h A 9xe"I*OvВ:*_; ypM.= M*(͇ܷS@s.*؅7RZ }7YzVFְ!&E)FLF?eBJfGۖ LZj/UG-Y%yŭ SbnS74PVg&HE@{ Ԁr%Vp9R1+. E:߬^gh p.kAߍD:2ʾ5]&_9" ]=*tƸ%G%Ɖ3;&M Gtzf#Olg1({qvժTrmd(Bm2c!_qcy/_#ttFG^**~al/6f|Uǥlο"|t3;ϹljPhetdx+e6ZK| fq^Yj1+{/snW٦|A!@}_hgXs6 }^ygs*OXǸkᇤWokbӲUմܐI'A6*dqP3u`8?1p ti9PD,FJR9OLS4T,gӆi%xaJ3>-}kΠ<[h%$;ƚb~Zպ#p]ppr|hYCMք҃Q_J䮳 U`HNly܁-pv[/.uRvGP|/^kgh^s0Qyf:+OyL\Nwfmm0UlJû?T9EV}n/QIhPc|0EȩFғMa#6L#ǥ~8;ӈGЗ iF*,ؑT80dxf`>Hf@ͨ"J[pZzz?ȇjG+Df4Da c 1.v5 tG,ك6u^aPcіK[- f~$=8?:9Kt}p5GjP',\z]L&" }>$Vd%ṔF5NDEq_2**]c_ !ב 5:=gbz15 \G&)^a~-%e.  $d^5y> {k2ucJ3m2E' ?n!Gd! ZvUٮ`MtOӠ!?+4E}-l))bK^kH\睮[ӱrqJ,;̦z"駨! `E',,8(ݩL>w6vt8IxN61\z̑dX&%Nӫa6dj|ȺoD\0pރiѵs7>aL&6pxJjN+n8XWv@U< 2@/]Z݅#s`7JcbN o;$+B1 =+F5%\r EĥWX~Gy7 b8\$qt~s~|v=uN^\g8*WUKdcw}_ ԄI1g,,M'̫hO5ԯb#A]rU2D 3 "q0H*|zK&A蠖biK'{ԗ.Di&Huڮ8AsǢ68<$("}Lgy4EiOh2Nə0KV3 L G?Uȟlוdu$6ZA+GccГ p먫Z[,˂ ~1w\[}ER/J؎Aծ Fx]:~YOrQ 2.] aѥTHIm\){JlbȠv`5w0,SnaGqw L}2T -eFMs4oA)C\ Gefk f5Q\B`!@K>oYYwOR$ӹxRfw>ǞG6Tf Bqa18Iʦ$+UCmr47g 骥'd;^c4OUITTC݄+mq.1󐜂PQgx 2=:>?,ZTQAlQ~5svlX1e^|9Br6" ty&y20kۭ6LGyą?WۊJQ/ l񕓣8澭YJ|zxchxCœ~)Sq(4iM}jJEEz<B BYBi2nRF=9JI=fRNOLb1)]`䰯ݯ+iG{ߕ y{ kEf#F99κm0'DTU4rI^8vT9l K2rd(/*.g)|jٻx~ anͿ!?z.3Q}ZGC[Fʘ9#8!A 㜨Oqۣ.ܟ_.@?'GXE*l*׀#:&{wC Wowp(?Hv2CJ>Mynj-o;Rzo8ď'n]%-(Rp擄Oē*#F9s:9 -][\֤ E[iɕm6 BuVYqH9Svt:m- 8(Z=Tef6M9KLH4EG9IL+>7r=aSW05#r4WP]0h$1gvdm1Y5Y)4Ҍ9Frk;Yb[uԳw4W+VR+Vqai\eqūճ;* y*&嬭 ࿺wSq}aFʝ(CT}*PqI 0 a]r'*"R|Ux''hc 4eƬ5ÁXxoj]كdti9Kjޣ-(.x,/`zw9'p;] 1 )c )ջ?η @^9b>*.nR ?ko}yI2A'Dw+{\X~\a|Kq!J}HsncP}H1i eP#1:\ h j~*K&//ӃCMSyslde n?/az%y"trchÇ;G۝΃G΃GLp=?> _x@atÕ L01 6Qɓ'[V10 ˜`' 3qB籆7ӃWG!w΢Óh?zz~tiۓ.$N4h\F̪db_a?ʃ גRu ^=nY8]eb[QhED -g[5lo[s~t:Vly;CE.ӫwm:bSI{M9dsP[ePʟU|P|:}0`k:]eɰW ='ǽwowOaS{}nUǷa>w'֌GK)7t{8;Qpy` KU.1r Y.;NK(0rX<;{THnG&G֨泗A+$9i[`l;r9'茺Na1 (}|_: oґA}urC{ ;w"ZX͏ 8M"P_KwV2/rMo"E`pJOH< QfO2 ٸ&p)R(Hz3 D /|,i(d875!)*]nlY3)\WIRԥԨ$}-{}h_H0!< ݗfrxVd,AJlC~6y M$U޾p{n hdoV~s̑B'o>0˵A{Ur@6{LUe,tIq1uGJV$-moxiwZ81O=ͪzrts z =e|Rcǥ~?~Svן|ꥃ >?XxCM9MD3sq7cŗQttfؑ'v{ʌ =5mbV$ 7^rNɳ0"[1(f6C'‘t hxr](KQD\zIKʇ_ʳ> qIS1*!K﹇g8 d=ܫEi f;onm )|I.(@/NX;gvI :(Ӕx4_t"䌧S"Mo _`bQ0I&u( fG$,]} 5/]}vetMhBSDԑ &.HVޝ/G-t8ƣCrilٞ`5 >3M)EM )4}lf;Hˆ8.¥2} +-H9>N\(0I>GaV{/Rxă~s$ũ..-#U9\ h5yH wq)v˾oglB`XZt,ĝ_Gf K0Rb{u5D [:9~!y_Yl:ٛI&qf+Fa<7 T͠i~%7,âʲ懅iX䈰,?t'Za̪{Z#{{d%Y{AC;~ ՈĶoBAP2/.A-D$4}7&{0A7bٸsm-[++KsW}a&r4,gQךm>LLWvȬ8ɣrm*p蹑MHNd9+gGA6EqHo)N(#!sgJ=%ۜV1ޗăJ~"gszE.'(nt1˺EYFTY-it:$M킞d:m⦂-KTM'N\MpW12:47.).*Z52O6.K36! c ib5qโChy-q"6_PJ~>zBL_գrPbGeW8$tK re+6*caVcA7\ JaۮӬw>=o_tr"ZuqnQ7R]Q:OKKpSLQӔ%"YLgȴHZ-Z d@J[ b^Ӽ֤喤{$#'X ,SƆ IndҰ]hFιWG[o !ov,UƓ͋F62 p  pe?W:]ʠ/,Zld%/>D5ѻߖ&kxw$?DtVq:NDNΏtטrbJ0³Fc_j}eX4hEm ~$fv>u]'@_iE6ՙ%J@f3BANIA7ԽV􍬄hP{8}Ϻ/ȃÙ7"`Cqa;/٠yUXI Ad%mngl" e|ݙq;.0P[ie7BoAFg9 r 7%j~%4n*K?16hIMHPP?sBKS蜛{m8mg=%v I_0A.mlp"v/-Q_y{Er|p4M'oVkנъbEYlJ8VRᴍI l;Zc9 wL:KO@eφ4M'cn:Ve"`e *V)^($ʨn@fRjSdȓf+WK™ݱ*XQ|<%H7o*t2麀n>$~~{cC2bFeEv&ZX 68 8{&c1u$,i )N&Vy")IevTa+wScS_y+oޝM6mywjp,{{ cFsΝ(e-L3[Jl9msLjwg&Y Xu z<ɋM~_U13Ra{U_ Vu; GtÆA:KSY56̥WIj뫚 4tYadoĈ;E? a¾*ͰV! #ײЭpw/k/BuVX3΂0Gs؛⳧QP:4 dعui!]DHnAǔ<k>V5cMla,e®}+QLj*wxdsc]S% 𛤣$wYB JXW<G@6TlP*ܺ[Wu"ůՋS܈>Upsc|]ŏAmW=~,ɨq:JLz=nWh5ZU?$ ٴ"5)wo6WXgxz7B[*'@-AqNZ󄛀[ҽ P?0ouqY+K|D+;6!Ln8Zu]{3?|y (o@H© f͡}㑜 /ݍ ̈́ןKz/X%&]Zehmڡ ҵztZHKV풪/Vl܄m`UUZ0Aq zKj?.Y=ԖVx{v:N#?ڟ}t8 e(moDA#7?u"SܑVDPy(jSG Y%ڝc>&κљoZHE'sjV*ʙ!\J` sTmKj<8?W']u?+~/02\,%.'Y:RqGX:`foUX(\E~QechskYhPXT0.Y]3<|7bĖIfݲj+ھi*fޝHμ`xGb4FDL{ؤ8ibTyA)yGA-!t7s)~`9שv8Ya㛑+8}'C8E>NH$"2+?N)(ڋ29Kh8 nluי:޽U# WpL4Qcгun衋1Ĕ@m (eOܘ'BcA[)E: l~wu(w{-*p^ViQ8Q5Hd?o O@c@{3j,ϝTYRJܜ~L^ͪX%BU]j1V cvy2r+:m`UF$c@T^ڒc`l⪜!`szA@.IkQRr)05/m?G]%!tFUM++%zԝpd5xOV+E';[&x*&{]UW?:figxk[_$]nJ_x'r9T6*kB9=WS!ܻ-:3O aюEMFꮩ[O'Ilfys w:8D|M A2@]mJ$#J}]Kasp4}PوʭWXؤZuwQuV3u]ޠV8^[novR>O2Ȫԥ /n`8RlUmcyEE u ; y/(APQ1*/Y,^愷[;5Hd%g&:ىRayDNЛ1 W9WNL- vG,a—(UcP{c0th݇tzMn՘!/f+p:(3w+{0l(:t(]14|U/s\Ǎ KwzE$8Gova!ɑwhlll {HSJWS %52Z_Q̡ cǶӯj_ے7qGˆZ  A Ĝ'HZ\$pՃ;[^1R9!}IpLrc.8 -X-fE:°DՀpkYu\ռ>G GM'}1 {F>,4Z5̨i&9(_&݆Y?g!!9"'&A5=DYE߅0|F59Bky5Hmj~2J%ް^MZEŪ' *}Mi̶4ݭ^Mg:(5]Wz6 J!-|a_u oaZ BŶ-&nEX Mߣ7u 7 oƙBwPEN`1I}?5tBydXL:KףNS[w|6Jֵ{02 0zid xmG`q|,AъqϚa<{i#ުhhZor[7lR:~/}f-wszlV3E r۫q 2j.1&|ө4_"c҂w0@\Fsd*|^=f&-xn8P_6iacTs8Gb% i-ܒs !BΗcG)Q -Wh-?G+o^B|h22MBiPu+ Xe@wc v W@Hexp, Ѷ tİth@ }r+6(:VӂdUK%6pGCQ+F1w[8ąC%Xz` L*r@1rChik9lF |5B7WO ?pq,.b9#MʶPy!Y[~1ecJc&o߿wD 5Oy>v{ъϻo"I{S<8mmِx^@!.I]74pieFQS_"U*׫hLk#Ғ cOѡEIZmgdl6k]HA#Qٮ$-55۬G:ñʋpd V"NVZHӵCr:!\Udtꪖ%%׺~]5:GdUOkk/?6lk~_|%#=tݵ{j6Oilv֭(.PI7{E:͋0ZewU6t -"BS,%7wCU R_O- ^&Qcg0$8_7=WPR"} Ǭid++a+ExQnfFI|h:1\S)[? N"qq& q3:bl骵ۀS^苻SH 1xXr0 74@Ii0%!nBJ!u.IFu!sR΅YS(qs tTiv)hE! JJ[5nzSI6EX+sүLd}/i{zࡏcM4"~ H[O$AA܊'R6av̢]~' ulCl|SLW2kԳ|ҝ>^PCoi<,Qo /ڰX,MGFnJ҉ob`F毈 0Awe}\`&t@ a%tFn) n"zrsxh=W zfՙV73DsS몯_N/Y0<ւv`Ʒ[fN~h """ԖZfA8;\=gs |Bjpl;9l5%8_cq6c z_Ƙv׽fRygDWrNl-U6k>tG!SpV\Vrȅ^Vjj45bV/ G^a@Q?%P1-\x>x~N)A3J#44}@4:g%T$M Rgy]8AENF:I!?5q@旄{qGIUUi+\+///B]~vtt 3ALs=I@mG[A/^v[ 4|elUhz} e]y٪ӊ&fȿhDŽ:">X*r8AN:Q(WԞsK)Ќ,ϦJ9]xً=A,/RZ~x 3*,UOcsyTי7<)gEujmGIl=q<k!x҈G *+pTVxY~UXyUm0ư*e?*o '-nOuރܤg)' Q|b9y~Y΅=H/ !l0%V"MuO&,ݙpԘ&ExMG(/bzH}'Yd0#ncwAZQ$T@QBaa%a56W3,/|q|ٰB9k7N4%/$.j`qc:[*$o?ĖM\茧C(PXKt^q-['ܟϥ'fͪ 'Sn2m`5_߄?a+bܗsA) a.%uYB{5Q&qeY&яz2C Mߧ9rǜƑINFJ0Xh: ؝3%^4YByRNV*Ý JqМ={ZMFC< OqYd=\g gs;YuHVXN'5J"E?a0MSu rW)^wq:ha$%ߵ[:=@6c6/.gҮPm7CMMfOU5!2F)h0ihuwnV x%p].j5ձ3\uZܨ./ganz'X:JE% dAOݤ̦|dTVv ?s1 zHy)ʤgRYXSesX *z5>*s>j/J a\vXCz&D5dii6>•@"bᅀcNÐiObيʝT||=q[ x#'5-hH4X49gz6V;m|䗾K_ݢ܎ l:2ٸ,3zrKVa&!>{2orUҪu[20["aR9#ck*/5=.ik=NJD$XU{w@Y)#B3m}ITzl :oz S)f/4 @W4>j/O _I8_F;us6]V==h% /} }_לD:֫]lF?snSX-:"§E*Ab+ ,Yl|,+d=q U<$Os}! OhӒ sӤ38ƟՔAMyU"z4Kr])jRxa͝g cuX+i"O6~q2-.IBpꅾdnU7BNY]( EwM phCijwD po]@e3gXiqر-8WjrudjK8 W (g!` K;~$z@9)ыRh7q(-5#,ޞ8v^hݜSO?ya '!zP&WJȸdeaRF`PM` %sNA@!x0/kC~$a| O>p= 5F(rOM_Ue@hp>4l{I7{X2e1RU7Ո i&a!但QQ{an1JrtY-6-3)kͮry)})4y\f ٟQ6Ńw4(T;܌eoâ4! WWNCi!%Y$4Yr%| uYXF6K/_KH·**EK PX HI~?D':Pۊg2<"GՍOt0ihQ 3QIK3|89;$g!ŴaWO/l 𾩺f妪#m/2 |F9 WL4ZAWyL b(D\,7]w$^hM܉bscEo8W|"{(V1 yn;v 3@W)-!LhVL An:T7 BS/ НD8%u1coYS?&OQ#z7R$ÌP%X;n2|;G ٝݗ'GJ&]=ۮPu9aBE7 דɨpNe ^t~/)tR/Tr<.]TjBuQ伖ZH^8/]p1zAIOU@Ԫpox V&I5E3 nLA_W2LS^~a^}T:'/%-{1}u|ԞK.CާOgܧY))xfUmL+դ b^u {k98 2wdӉkc0Pؗ ڡ(Z^KRLEƧ;kwϝ[K_O_uf/gI׿̴9yy0,nk:9UR4l,Atjmcx{z_3ثw,35#6uj-0/_XzBY\Xl/Esuw #3L'7bYgOF~>ܡ> nwv>N{íN֣hwnGCZg_QǓjL 'eA>WדqЌ:ÖѴ@#?lnM}S(]Zxdavz1L봟h~//gAEIbn=[ڜTBs#0~ׄnFC -jph{a Tr: G?:ywOݣX&wJoFClrKQQ{z >~8ãYtxrGoOϏ޽?޾;}{r݈$щk3їb6H&0b_akC`AϽiB7ѴquB0F+z$:xøDkƠ @Qt;G2Ƶ<듃z3jXN bq Κ#|MKܯPn@[ϻ/G=x}FќXqƢ+Ծ*LQ/Lr!^L /l~^vփR7( |ң}A~񷤯Do^#J&]G_85ʣAgo4JУ] f).LUJY.ѰǛ #S KLқw'gb#j.i0nOt/x&`]W9=;#cH /X9SW8qn 5lYzd3u+$@_i,?9wN_ַhK {Ӗ`p, Pa<Nt&w R8"ŒRNaO):/nR8XŦ$rDMI\gޝB%M[-1༷$Rb2Y6LG݁ h 0]H84+Ayح=7l?84 )KAĴ.^Zt颇9L{.%[=,:}x fu+ͼܒ0g4ft[ⷈ8igd%G ҼP_8[}@ϗL.g^Q\Qy%!njAx^_Vq4JX<0r! .$5'Efu* ~~@$I̵ç\`M|hIde*Q:/'ߪc.uB'թX͛+pjpL!O yεwgL1"`+D~ c$"i-"$IzC50wD( jiƁ;Mn;ȴIdW );͞Nz"J U0}ΘC,8r$P |ףv1>R3w!勄)C;&Z##\,+|ϐ@L'1SDfnqoT\v܀zF f,T>hpP+F{qff7SboŹmQ>oDxYlpq-. jgIF1W4JVGt`JVqJ~n3<.o "y%c6,@_#A@W NRL%3:2'sܮdhdϸAЭجAA<A&91N3Ӭ;fXdʪģ8nxhձ8`.b I#^~XAL9'A9 X_3c{NXeǸURM5JlqtҔN!gI4Gb 1ݵ$ZDUL:aRiY-PiVYKGՇ>n-cȒmǴ&ZEğQ$~֡^8lmv 5OW?U'γf{1/I#D%$&p}%i\.\~̛:Ҹ(~Jʼ3NXG` D!C|a+"!((dMZR(=a+NoPu~8p0Q6lWT]˽jٴ`!Jx?uZxʲiikYe>y0B_zE < /LbP(q1^❣"DnܙD(dgJkԧj~iqmh>-7bz\wdX E#f>舊d#VE cNƬ[Yf$6F'a.ӉBMzIϲLyۅǺ)Qٟ/Y/K9Uܤ9:!aD!˄8"`X/Ox2i 5$7PL_7bĀa :A@0DQԏ{Gӱqh7be`&) m2:=Gr{hYlzx)x_Z)0i >X!nI16$q՚ WXTED+m GU1:-ǹ2,J<~5/bR OX]Cʝf&\ ͕M_!"Q43~<2EX:E֣6nmum!߿G7i#O1ZJ:. W0`w|Њ~ƃ&Ga=K> MbF>|fE79"d~J-:0EY2f=ӣ1j99ףspU7|==i^92}LAgg݃wz?oo9e?yªFlr>$&ϓo֞ɟ^O:D_O7aM&yWguV"K,>' )\fyxܫ7k$fmF;[𳳍ѿ.k:T|?߷ouHUezE*v=9Ҝ tV;?=:~'L}[$͕:r9#;yXዔ u=8:^p858#C.<q4z5iw}JVoQíRB D5I>6hwr Y Ut҂1C GjϾ{^<zicb0p~@LeOnn2}o}sAfe8%vVl>dc봿FR~ܿSnQO_:iby7!܃O<_Er* BBpxH 1(/}N s6M.Z3>{˷+N,!|Ta;kj͡l𢕱ORRb[vf5VsQ~J;}5nN *[s)v*Ћ#ȅB('8Ɩ((!0Y 2}}3E@7rڢ^ҼSB79ZdueBSWUC#]4Y3QݱW,?]PmuGt70=ڣztUe5 3L ~fYzҏ`}8wBcBCNps%xl7CB5EO4Rtv=yg=LVqaTh"aŨh#jno.!%xVi&5Iѽvo뉍M`~$!hs %z-D7u/ѓ5xۏvv@:̣f2~jqR$2^ڹ~*=d#C6:om߇&qe"F /tON=wESGONi{i=2|<, \,߾_N>%}2ll>ߨt8~| >#8P@s\RwPyAzr4)6˧0e >_CDs^>xP<~:'_G˲L?̻Tbz%h4(q^49by&չ喝oѽFuCY,&_'oB?5~ߖ_܂2h}i n}&$O1|ȥKor׳|݆'/ygݓ9c[կ<x{7{+k*"W|jU%E5U+K Ե0Am~W=kd:.b4azCzGө^%kbGY?5EmFVQO7tm*3,L>`߄=_A9`yyݳ]hm h#잛C2麎D)R6͐e>`+ x}ۤ ή K]Rܵrv+;ږ[b[;5s͸jo2ɡ-ּx%vXp&qw?w!W':.z׬!NYB :s@A7R-J^ohې?(`n=}s9J}~6ǒ;Ζ?#W>:wyC/QoZ a3Kq·mmۻ7R=l(6.7-ToDw_(zuX,x;aG G"YOY[wv #y=i:^[̬ I6k]sˮ).iLsH%lMaԞlo=n}nɢוQ";<)WҖ2Ā'| Jjo=ʿHq_ebx? 3Tdw{A=5qвLc04S a H㞔ONL(@Km$xHGcHj>H?ܵi}5D]΂%(nCmUQģGh4b+Yb~ҳB*gyv{G950 S%q,,FA*V: {Y,Q/qxTY~J*RZEFr!q$H PUL d9Rwwo>II x-/VR'JXNxEr&"1beM"9pa/zy=܀*+PIJ P+ylWH+b\8ad5ibϵB@c=w" "@%',Ii/{U`3hXY~3pHN(@AɏjS3 ؍S4fGJ) =\2GӉ,^pk'Nd2HUfi":#`e:vww6*HDAC(E+VAyWMqF)y%hH7s'Pr Of EL4,Uczgtޏu{ X1] R W)lWJkCUP.3l i:k<;+ٴ7Ԅ i ӊBBJz tu5Ikt 81Y0Ր4#Nkp  *889J:ިHGB=*\g%8'h Zdӗ`ӷ`:ݝ{N\ =nozyHpL/I yWke3"[ A $J6,=q=M Gv/9 6C]4\حf'E 8ȈTG$ECfhwXTĤ3Hi{{c) b[|W st0F:}LvY 8 pDDQ+&)0̹. B ˣ{P)Խ==E H%T\)ҥz}QWha%.9z!30Ɨf@:;m> vahk*ȕ&`~ V?OcA (13a>6 ;-U8;.O&||2`yb/E+.QFFl:؟LaBZV)z| oL} 淨ᡌfқZ:}\6{(;Ŵ/)u?dwjdڹԊ c j̽*_ c2\{XϘRFp`jqB$(]p&ׯFCDZ] $m߇crXXe8Ffyq:饗iFR9]Ao];fKBux<J g(Cf9q$ jG^ ؉<'grp>lkO/#9wv9b)va];%/[%|HmLky_'Bx;?z%t.6{&-&DSwK"-Xu묂(@ME3%:сI{+HT?vD8Gkh稙;tw ?'n$f$mTէ ӫ[O9r4cp" 6f@Xɥu*3zt/ BBJyEŨF;[+PW?gk0"E`#I!AlZF@xyp~i ~`Xhz!7qJFN#DT*Ym12-+HJU_"GqQc[;xL "fvx%yCB vUquP%bwPN%EV'ɨ5Z+bh,Eؼ?qB 7f+=k>%O&&ӺS'09]eMYLs}݊pX^bO^ȔovHѽ.jBruO`'_b*&ŗt4FˆQcr9,xUBW@Fڋ|mL_Ȁb wd^;Pg(v1$Q4H"QJ=U ,jI}a+ JZ02+CTAFn~mbTOG ,[_PBD^ [^R!Sd[؏xʰ]Åj}lg@B HƑxDԩ=wlDvqX/p|HaTS7Z7ԷDFdS봍+wjT'̳@9nVX t'8dټ]"TRZ04t‰(.ˑ%{:3YjS;kABXȉor 9K( FS{|Dd XTe YJ_DKY^vۇ-7&@7b8ra[4#\)8aRn">L(z/H5 8N׳E>S+c  gz0;8DNAQ>wP`,&_@YIQoŋS^^_l$ػt{):ǜ#DꭖnOLm_aItVF@!v+iOjoj9 ȼL 3n[7)1qBuDur~g AIa\1fJj%^Ze <9pB# #0Cc0{ *KB U*<{ 3T0 QDKo X2->oJZLRIq] BȀ_{xý#N 8^srƨ-( vmQ֘ Tۋ !":E>rh+E&+Snu|&k?uDߥ|Mru>A~~A@u=H?Ք[Q `'!kӕG-o jBn~{$u'H)쇞ɢ.o/ԩ&qzYݾQWzbhMffAإYH <Oh\bޛ"%>%,%gFXI ƱId]K'ؽӴxG/0ϧ㿡|7dHq8kS/ȟM牄{r!bܰy;HR!y<y!5M#T O`6@&VH;dAi4̔6ÅVJ4'b/Z#LEJuӠnQnc1@LmE C nbIv[|Jr{ ~ZV޽y=ڟ'Gv aM nfID#J<{-`: P^$Hb(u9Dް0.'oD>Ys"&py)*zP1DkH n-YۍM?6_C-/1$ۑiHLxFdEDJf7&E`Ʃ6pYөpcR2+tW6W$tepi AȁUdFiqD' Lo!3tD%} (;vǂ*$>.ԸWAI!3ɣ܅&t>ƞ8s{'؂Fb4ogN|B<8 {D &`!VISu~ %0[QPߕ"R^6x1=%Dvq.uYKOGu~}5$ՔU^Wͣė>HE7'+"b* m #57IŕB0PI۩ls_tZIX j`e״`JK`ȑj/AzM8J`eH.͎1@Ȝ,،3̃c?5RBY8l*\1#݊,t`Wk3߃syLJ,Xa@'Br+G5 sZ $f)J&9*}z})+ WΜp'IAp0dQ9[ <2S{" 8%t6.t L:s-a3p| νHh,Psf|6!2 Ñ ;UF 0#jD13{6(={r9ł)^fMG@ez.t6PIpQMEpA\*X t;. 1َT,V'-MnZn3vC33y؝+dvß~tvdsD:@I RRGy_[C"IӢ:|=`s(saH0H9`/hs"[=D$fZ5RQL-ӳnd.[^Q QEC$ :>Ra:be:GgѢ@'(B""һ# V{ -eH0ul i!yAGWIq2{˭~М*QB7Yn2,\3&FsEz RSb:73lDOg{_e$qHc]^L y?SЌxxtz]MP=QQ*9$Fd11G'&5qh ɥȣ 7`7ͣ9pc:K*AXc2%QXd EA%zeJ8. m.łldF$B #QLV1啓[6M=bL+Ub9W0/:^`b{ǻTtDE'6 K-Gp0|Y#Z2bCcw0)%a H|O be|XGf۔ۿHQ&&P9xbWx{V:␋G #I㗯0Hec"Oob+ ?>r9#t"f~a]t$`!)<So@*^: AmxU V]Z a9 `1P0G[BQoo^wQJl͐=9_b}%o[qo0 nJ UqX?jzgqHpWxI~C^D9Z"Gj ?i4F#<ݾ77͒4; dĵɠjpDKyygqH-oM0U $rhF=H5]%ygdg,; ϙ{I"ICE!eDp#eIL BUL-c1/d, VPM#/VHEKÇա%J^d5Ex@[ .h0s1fYPH *0u OƕIO2 U 0 72ER*(~8 Q{J槍ۍoÔɀ`S@|zZ?dزXQIl9X1=m_K ݸ?lgN)gڋxݗ~s>ple2y.b]ޭΎ߉PT﹧SjZpa_8JGesֿec!L=TQVbU޳}szk\̬j6LD;hy 9=8G6*iӴSD5VQв߱2(Lމp!ӏw=SgO>`C>pwzxU&6\9%aTv(_pmn戉9s1Ρ<{`n)쉛R&F M!Z>lW$Ғ[F!v^pTw81Yh&F`.dU+Aw#HI$)̝A Hm1iF\ԇw-['f4aBh6pd i -B~Q*zQ6Pl,gXS>-8:^Ep7 J"jӫ7 # ; {n/x敇35 շ[9SPM0 אTזHƪ8ܿ娅0hْ8yEN4BUtd\hS͘JP7b2j劉o(ss[JckJ C%$z̢˧݌MFuqoقa ՝8:tX0u7q I7HGa†rb]͂pQ\C@ֻ%53%Rdg4aߖdPY@(M9$^ /i棋:"ȅB7n PRZ%`(L 8>x!6=VD Egӿ_( +{"!? Jb#j|Zf3y0ExAh'}Ę5D)9y<0I:{o//ns8Xs= $a198eFQ9:?4R8G->5Hf'^ڼZAЉ-rS[EOE:SwFG̭/38x 1NKY.@!sMhǣvk\q{?3AZe_c!+#AZ׎/W6c5Wj(S%a.mi?fOˆP8kU#% e9[mX$D&!퐞W+y1/9X.[?%GӋ!NpUG:wx)Kz0!PVGvghq ԑStmƾY/{ eѫZ"su/"e&@~\r 5d-HScZ H*U¸*ZI l dQjU!rk%@2DgmI,Ue!"M/h \br;,{NL\A:r>tSh@k.8_&T@pV W)+dФaFF3T"br6N6ފ9B݌ U-rU&l2W|\Yn̎յ;x@G,W`ƅtaS'Vs#'=%ȫwZEQ10xVK.q@AɽXj68-R CON #/51`8 PPYV()Lj 2`YQA~C@; ݖ&zDw6Y &*zm} E1!02fAυG5M-YpRX3qްGYS>d4Mzc* E) ]Erʾ&hsvO*)\ vD R |5q{Л.߫7%95\9.=A21ќsqlA=s.|F{Q݉:đE  =$χS(5w.`Q|}@8S{?Cۨ vM;RokANN`BpOQLa1AGjPv%KVbO6Ѩތgu>1c \úG {2ŭcs3tmX? (t9Б9Cr MlY N8HC.'zYM"FJ)=]KCD$69"`w/_]e.o$22kIQ P,%c ASTDPO!Ҝ?@uSĿ|ć \DƵO YH 1 1FcI:x%U0VXr"3@Ǭ' hi!O~&|y CWZOW˥u ԃEå*ࢪ!y\$ى!oM!xHK:.ޢΕ/zԂ[5cKjJBBM`W ;x :mth{c:|#m8 9Y粏v~ˋlI􈮮 Bqw+hpXp~ʬpN&VXt"bLbn6.'hE>?5zKKΠz^iN3He7CIc4 RQUU6}-©E ԘUƏ婉%өz@v3 s6mtg9"q\]ZQ=(ښHhBxPeqqOJz _ry 5jiW\Kǫf<4qҹw> #AxV,);BʈX*$[*\6=喰Vdw=][(Ɓ8Hp^j%,Ԙ 93n4_ Έ $j8$5Rq:=~zוc]Q|s! ʔ^3T?s_8A&:EUDޘhkyS\-/wI8eBF'raB4\ nIsiqn%>*m8{qA[ߥ~:Wrv""kYw5qϓ)/fQeSS0[旮s0.lf >K FZQkǿU%#rjgW 0* ]zYv$s09x#dg-87e2L9߃\Cgˢ^W1I'\e0m{g-S'C[M}ImHꨢhQI]n/&9PDC1:e:;(7pri|0*fg'K} F6:\f3Y @m|) Ⱦnϼq|r~&X{3V6)4> ^@,cf vUⶼ苪g]fL-io8C_SJ^˄x>!|j>&R pq{1rՊme'U\EjuB%#srFTS.e/-h".Ҿpi) kc^8E֑gvZJ8|XUCd+2v:%lY[ۙ,HBK֕; mTJEjYSӄ|lB@A5@[ Oռ0P 29^@dM;"}j2Ҭu(!p7it>//:i0CY_b/mrt uҢ&;L]Ef#C4ZuGM k չ4=S `tYU7)ѤĘN)'w@UBTF' daZs BAw1ӽ'#s}>ġHz}\ʴi̝XZpw%w͇+edd/,OEC]xi?f&%(ބү P7UTxMoLꭰBAe\FVhMuI4H@@UZ`6gXQ}$X(o{a/^B1uL *\7 Xѝ+qXV>vB2Ma6w Fy-goN^t{OzNQwd!}M}Evv 4}q;ۮyON.2Wd"|zmc~SOt댣ĩ3/[$&& $P.EUh7QRhii/,')*Xm ʤXJ\~[v{K{քz===9E_V!a` '4'IW9arN]nOm)~+iB螊tt*t<Ra}ZN|.ƫۉ*E\-/bm,Kxg0r0y | ҍE-+x4K '@mTswQXBt)~VIrJcbh |絟yŜ^=f>Pt!T xƤ)[tHdD>w,H`\W=i;A}UNj9@|eE@scTTɹRm[R-BT mz-L7nuv;\TNi`Q1[LUp̎'uHi]V\N|$aЊL6B75v_/勂K-Ї= K-6mnbW# uw5K=ш/{:ځEў!"t!?1] (.:SNvY[ƂgGU(/dV?e[1D܆W JB*X^S viY"S+L1&^gX%ɝHmŨLޅ'IzC9kmS =r7/cNl-fSsd OH'?[}t9\'qy)@|Ke%7t(&bl dzC.+g=|k WIgZmA[EPJwF4FgbCC8Cқ?L. y-܌V!jǂ|֨$G򺑿V !X i7vL0%-0/ U"# +ީ_' 5ԇVMh 2T}ozM͌AVA `wQQ(:}ytdFI׀{{]`0F_<%Hmp风5DX QP`X05Bn>XwuyHR܋tB.`R@Zl;X70#@0Lz ]xCt) nTg:,uNѶPw LOIt!R2a$K s U !P4?|yGn5_R!q;7JD%jn8Wd1\ Ȃ3Nwv.eOhd5%{ GĢ~tQyvb1jZQbQ4.G= LP'>'^" dLM*}rbWؒ\ A}Ov @mXZ`f~]tHJEM˂u50g2.ѫFQ;E8h1@2)^Qwd0ڿ//}}<7?ĎY܏,!+蒐$13i0@t~<H:\06niRROzK( ſ;[NIqLLP,"tF%.Q8kQ텏,<}Z`B#Ksޓ\oERfd^4x}Gp;z+ֽ?Ƕ\P,}z:nC/:K\v9 $N}m)֦ zzn*IGÇ``UBB{:ގ7&w?=RX =`<ۿ&J c_'ђmy(o[nHuoK4epm{R#U~c #U3u'V.( /d3/ԯxhq`acC١j w:PN& @J8['5P#z`+4YS.m \Yٍ].T7wlZXͷDsxA"3uMe`y C)BՏs+hcw-vEN.; d6ld ßLSe͒$:qM4!I1lL^2~O(Ɠdxc%/!-JjdaKD2`X7oO1黃s|aǹAUޛ3u(k7:ᤔ#R2!5 y'U/G?'Mα™Ӕ!yF貶r=>cmH-q8FArKA>E&5xyYtLKWm3A6NE2vz ;m{t @BfELPo"pA&cb%䀲[)lz}2 *a/5"{Z6}8_ Au=%t:Ϧ~$ zڿO_ڬd>kK( Jlrk885ڏiT# v1#*٪P97ނL׎p33Åѕ.PVv˜Am4Y5\ aF2Ɣ\]ڰ"@P+p`t>þ=3{`.m,dͬ䍱tΘ¾L )4^/] ~^F>\k dqR\V1):a'*"ʂW D+WOG+-+x\h@+߁{{:b'K8!fp4^\Sl0Xb_`VsVP&VhE~LN_rϒcmOpkQ'q+ܔ{0}f=Å߽^4:^lϽֿZ۵eӡaFYd*& *1trx$ÿc:䶳}h )ę&x軛t8~ u6lcz3(geH=2erpRUqI| Rp [ 8%KU*'LL$;Rk@{-k “gIAfC)Nq c& |`\^€os7*@{eQKL e5Mvybw Rk^(/_$6Y3\8~xp.݊ZvEkڙtu0&6W QӯK@ ˎ` OO[yw0ƙ#&ߛlL"'%AGSf8$o%ce e n[zBɁx#QooYM'D" ~t:māc_yf<5; |p X/l3rXk+Mm^~rghr3\ Y\!4a@D[;xi̛RbLbA8/D`m<`b ywRXhEm\+(0U8scZ.|o%E?Uwn2О֥حXoeI~ƛ=,ͯBǖCVZfOx C0qA3 -Dž iM],rQ=C1hMږɎHGk' U/kj(l{a鐇Gw1cxSna4H 2VM{S13'zGO-l<ߠ9"i#*5}'')@~g^Yq*X8ھ@A]Yu2`^  =9oZ/LFئë.{Elb1m+Oj8P*-;ʳ" 3~>R2Ԋ1.˟&uGbT J'Ȧ2>W\Iꡑхy'. uwL{/"٪U鐫t#ٺn(8F>4ND&vP7MԊ*b{7#qI|=9쑨6){?1(r*26Ŧb֧x^lӔ.uܶ +Vt3E {ې;aN0"(%9. mi7GVN:[ϻȗ;*\7#&Y';*<<ͨdUoʍ|*Q(Ā# Zd0 \Ci|52K(AbGAo:w*8NW3t[_ք8Ud/nEa6FN?K&aFE{Gc ([q3w-pic<(sg׋=~dÓ9a# ec+}ꍫiCYxLOgԭ.9_U y%|Xg{ip ?B>7#+9&E1ZɉqJKr& ]6#\` 鉨G~yb|WHH5n m )Pex sΎ}Ύ}ܯc }w3~X3`qઁ-e$/Ԁ$I{zKqa&0yB蔕zZiY/w}:=yU ^u_+6t-h~/Ah ! 4ayM[d.swf2~2VwW}0KYT?wR- {ՈrRc&yO{bmR[ կϑpCcjG`6X{₁t8pXS;2:oz`pJ<:Ɲ1:XҎTsBmc^gv^%\K;С/xF]9/=3r/ɠYj~{gao0\]^2C}&:O-!jY"qDl QQ 2,֋0 `uR B6M#3XaY9BLJcg'JԿlYh7U:,hGT/SV/ 㖇X??uHz$"AK;!È<$l~peY'xle?gD1{MeMi+(+؃X'ny*4ӆȸ}67*3sX4!DJu!*h҈R<lHQq(rWokԦX-r8e7[Zj<1`/XJ6s *&& f2e<e>e$"A#jLҗ$Vս9ǔ64X OU&&V _y;[2r>8<{}LBAo<۫d( cy- {q=y#Ef ~Yo|ertҏSbAj1zw{W:US7+Rsy47$ [W@*#`$9n!;۳ptB.Υ#y&^x$OkvOyd$wZ#/3~*;֟ҢQ>>0 NO k:|l]tx#*ߺ59ے$kI/&דp9 Uw~Sj4;AAq32 T.<6ŖD5Vѩ[?qcB56Un[iS(6V(R7RFZ졪_bJgbrۥ1[S:,-jd-D=rxkcSNy~ zAMAD) "/VXLbA c}eӇw/ }}^%AS:po4`J]: +GokśYc76}frUrʪ_Z*ⷁ/ VF(xL֎}|4huQSI(~:!'& 3y ErU[.}ǡ]ͮf"&]+eܭ]9T{0wXrGWykNW\7 h< '{dp*M. 7ދV>رxc4`?"/vSxf'GI%hƤGc Ȟ)DʊlRwqقFϊ9S&Eh|xaUQ6K  ,KLjȭن0yxF[QA{G`_^) #xRžs쓳!U 1%Ӷ֦RʒXu!L[| r·f67N<>R S4j_~iE}Ξ\ ^cڏIhTQmdH豇Ma s~Cмmӧk6<}֫:e":AM J⻼4 {,&oj T-|dL#{|vp%ƸGF'\1rAowX%{k)Y wBy"ZŢԂ1"_vlr%8N\YS:GpH+s"y;h)\mh~I~ʳI]#.r.54+UBA} %2NJ$)7Śm)a(EA&⪴ĻΏ$~*fU#ɏ<=q>ޢ&jQ,iC-J0֐6ek:;'ӑvLII}hVӌ ZI CjdsZC5VX7M1>CtYD!1vnFQJc{Z<:%$"A*T^.4t,:O;H`# K oU* e>^V )3p-aTi9(ERpTICőֲS>_kKT\ Y/wT0NUH- $D_7lm˂4.ҩ@{K›9eOnx\% ̾d ǜ٤UJ;9δN4`lg>es1 89CbGio\"ɀR/q<:JFވMVSrwpnUf<u8$Pd[qk$G*** b:ńdҕ^$uWUų]g*K`*IJ=eAI2dhhV&%y.R>UDg8f„ 2iCS;PZ~pեx `{1plJo@'7PͮĜ+tsa=ޅ aBUE|%>#b.`o4KhgNdFef5 A!CnreUS|kk@k@cwJ^rl!(iLx$C7JxZs눅93IWu*G6qJFqTS,C3W;dO;B#sKI!k\rNXMw-rY_X` f?I|}{ZV-d$m)V/~5yhF?_fMnH>6f;R+n$N}lFpåfo")h4hQL9y /1pViLiNc2;*W();=単i7rW)@K_BfjwB^ˣW)H;,<^q> ~‰K/QtUCN`!\Γh€4 =Oa\$d&RUQJfLdk6l;&}Tod#U0; ,k; Qۿ Hf%-qk{$~ej1u_SH,.)3YσI|fm˪ZGk77vZ%OU׼> , ]ȸJ:3 L<W2,RMޚ3!G'Cii d9c??STfYY*d]qZ2G&ΩudMI_̽(^ m1Q7Z왱D2ifJGuH=-F‚/dN3{~dyiU*Qji'&jWٺc=15@X8E9gRy췽T:|*3"e:395#85L|n;sY(í\2 U:󞊩Q)MAśeG.m( :Ѵ8R30z[]vQJeT_G]"ւ+l&)E*Ȫ mn4xpKGRd/&3:rf@43PfG"%GAu+G;Ixi/!{"D w: Cސ) I)%yrF[`O/S}%&i*M S4LJI55T"o+WhXeKDǴڨФ\.+Pt,Ym\@/D$˃c (&> f185.AҊ,ܮu±nf+)>3_@712_pފbƊӖA%v^Ja$HYWJŅy[%Fd^.্w\ׂT}Bd~0RBù(!xۣpx]QVs@A25 ޓ;ŷtJj4gRUu yһTG,ŀؑfL0'G(\QU2pw*) pzps{yxq 0eC5_9ꈰ" $_vfvc"q q/D&čTEV:Rnd0%R9yK Q 'we@B@Sx@CnVj,*EmaA"ebXTc$u$&]Y1s nf}mijV.ɟ!-εs딏Dw1ikۥ],4?¤ @(N!_ c'pfQBL^Tb)Q)vZZЋujNd|YQ]a_x𼻿wqYy9:i}m;]ӥ݊ yLN\Q*62,F~q[:I0Ss(ɴNiOE@_=;溤.l Phķ7p$g}pS9̹V@| dI*LmOEɲ q4 Pwgk*d!| hW؄ ̪hg9:ݤ1KBu*q@B=HC%g)7Ӝ"K?:3dL+%#;g9re\V^! >{&?z KTTxӘtt԰OYpM#n1gU{N&)93Rrx٢4 `v09ؐr&* }9L/}ɸHF샌olXY넟G\ JpףNDS :dVHioB7u- s!Z!iMM)$p'EwQSGSJMM R-9i4c}u*hxrP ( *N لlRr)@hSB~ד#$8Zc4*,LUR2rZ* -U2L9첛SBex&Q ĵ\ Fb5tJ)ő_uJ]͉#R XmCU2LV==Bܤb}`\H=9U&iHaORRCfm=a<Nry,UDYyJn[aj8Eo6,_0]R[25UW*{ [][śgy)^hR@\1%^QmE\^Bx 0m@'8?<8:?ܿ@ލqc1/3Q Wɬ'>s3_)㱿YEfHU="F k5"]iDFRc|,S0TxL[F+喥tl2>%@KIgh%wY;ߢ,ykULҕѪM_y]VڃUNȓh.Eed(LRRfħ81%3\l},b%{8:VFy]FYK&\H-T`EqA98\J,%뺄EJhLJ2m$[꺎[Znv%n۳>'A䔫N&Y%RF{pHukִڶc{>w\n^-[7*q7V$cQ uH%%Y`^\FIul #~HK!1F3VGӸ4hZv<ےн(~%l S=yڠtT;IY; qU(3R41sT6nqv2JUra!" I\kϦ.G*pB0Ƽ{F*P,(NԄІXKluK{0*S=xsk0Jqqі^uWd,Hw4" I+p4ǵ-L E1 JNU Y YNy@ePsUPjwfPJj鶺[k0%hѼPk*$#,yLhuGYY ZYU+y5הOk^wڏ6/ZvXp eH;Of]KyL`\;ds)%X)ʋvccdgtў~_bJ YTk%=tThLl0[`fr0)$ 9Uj*LM$v$ 8'r25'Cכ[[2Soٔ9r]mJM6* tvU"/8rR5D C]hL\kȕwآ0LafvSf//~[ t ?"\*\e%3F=um<=<:=0 Famd܉jU2$}_2kJ[ odG!h]t7І{DR+` ɘO*˧D0@J\(Q)`ӹ7IE$R/b zIVdZfZa?/ыFAS%ErA+1X &}"2ze>وj%T^6[}SCifT02/I57JaWiw;rM/lzk5Rta:nș9ܹwhq¤hxʨu4$n[lq_&ULhlNȴ@KQ0eEW2; MJ0:ef~^OBʙa v{)&fؿKQknwi_a#N@I!OFJh w\9JF:/FԾDvAzԴқٔ<0ED_a ^2g>=(\4;Xo"`KA*qjpY" 11Ԣl8ĒLʣaQr2J`n@j,2ܜ2~S@lؓ[%wrȩlnF[/O,9,U7mo.U b$ Cf2&o;+ &zZtK8Ϡ/mL-? `5ô/vsR{#sxf ,_"3zhoRc nS&$-umVAHJ;4 v<>ISE8Ims6oa|}3m%C]ʏ*UI@YPyN>EfH1/chGH:sAyjM*"{5^y:j捛?~: V#_Nqi젪Xx:E8J'թx=0 ̡{(c@\R#~.؎N5;8%;>>F׃8K3)tNSc'WJ^re/QC`Q,MѾhra*U 8I4FK {cX l;ey' :r^oJO߼M8Ayq '̎]\3oJa%EL)])ٝ>kxE"Zt TM|\^X4&Y vm"fφb.UG20u"{ xHR(lEWe*SĒX'xX']-_MdZr@GbBl*`~&F-.g!)$ֱ&YNsqXfqtp͆cy]9CHX* U!|)bw?y%V%?u~t k} 5UKGb_\t Pzsٸs3x͂%ZC*YX˜!fr,70rryxfoPLN~9{{a)r]@bk_4a'r=]h:<(ّs~Y$ll"-IC*6۪p9l "$A˧/6?(p2)Wm?LZ7R@Qyq}qRq 'Udpv5,G,rwC1U)=4.2bJXdC*g O,.HP`Kڕ_2u.Tfxh]EI!F Sק:qiWLc]2 4Av\ 3 , oq:5E1p:"S`5҅Z!M#VW"2tGb-60tE^R&5Rg⼉I# [?U2RdKC9@ 8rvpR+8:?ppxQ QHP;pt҃ @R0Ѧ6K&PPK\dӑYa!H;݇~[c&׌UJݹN Pb;x _2i!R܉Xc9̳Fv 5M7T^}8RM{Jh1\.#KT*v ‘T@]SrZ=@2N020zeK K|3zJzkTJ_> d[N40 Xg/$ pB2%@N /zq"uT d[8MlI fy?!1*zXZ }5 O[lGL<.1hk1J\]8 ”9!5OQH `p؆=j3;L[DCצJD]0c, 3H(>ʂuJ7:բq53،He}(3EW9X`fH4]XNݠNL(5 "貗|4HpqùF+IF %ȄFx+O1( A:c2F ~8E- a˝q|$aW+/wgK<]ss%@(69kKI2c7ʡy)zR{f1eN0 +s%oJ%ut^q9 貱D/#˥Qe1v3nFUTFs̰C~ sΰhSMN%%rFj(;O%:>=9 ^GA p?h:Ϧ"2KJ^auï\ۧ L}؛J9Q"[O+ı.ũXdPbt4[[hmGŪGX.w,>TcN|unnz*g u"OF\;Ft<]$Egun864S6E`EXx""^J Y"ب wTr%O+VU|@&:T邴l<<x tMi wI^j:@P:mb_.U p2![L:_AE $S'R{U(K%%tEE_jRQ跃p(-/]~yjPb U\)3Pp2ClrGc)!AzAkAHfWU0!Yֱ` SPS/ +lp'0.< hm]#UiBs<>,mziT|8ReHE@@ӧ%>!Vx@t!gAUpP(zi#>f3 kIMމn_/0**Uh"&$Y lS KbIxdOhJPsqo,^XT <\Q6&vU%lTYjDa 6K2*pMJVԌg~RV-C`k?7g^ S͏K)Ǩ5NjCJXqΉ~^b[T^,K xc" h >Y^*QK#xxV%VƱfnoTш9'ܔ #ѭƆ,~0aZ*1a&$\t nndl"Rj^W2A?ǝc[xc&(PiibS/0sm+)')Ӱ2"|8xe"$x|@=3m|_68%jI B;߳H2yթ Ph-7=6׎[n~f&(Bc+x/tՉT6U?Hz3%Xn[m Te/@{@Y _^::`- e0rS"]Ϗ4V>$:7|S~om%(L*e6lc2X^W̓cGiZ@;-W[Rg(AppMꓳ7wȃb艆:OFpTZ4vvk`|'q -Z.&Ն+TaBýEH+OV_-؜Ib4G ͻ ,4uՏ29,wW"?eJ]Pz${NC<HQźi+TԢ!E׭z&fE=+|sI]ķӝG2?8(ѷ޾eّ:"x͛ť vju$a-՜v):42[2([_] P,)QoR9djy$5Kw|[/O;#&Ίm't6vEOY 6%Sc7xq[7򓮡5 Q:#T+ڔ~vF;𜸥3ao wՌjM4Pz}Lu$wh*-U(Z=n0e4#a$*ǢC3v4Z`!z[yѮޗ߲*Mo$BB.|%0d6Ƕ&ҝOь3F`~UVI<OU`T#p2qw(7kUZb]NU lذݟnN7 ^X ">zB<yϤj޸C5pRGeN5@P<|0;@2b FW2 .tZb-c_U>{]TՂ",b*r==lYtƔ3J*A/$/봋?Zc*--@l( B;EIGtMlGZk,hy#5iǨ2uѵ\9Iz\@WVʖғF(OܻnT/660I4Љ!q< Um$bȎȳNpJŚR|Sbbp$}aB)m%=`|P4.$/I:6LݳE̐h_MB ךߵWn*G~Kp s22t҂!,T&qD-C yscL[\58j)#XWh9-{T]5gC)ˑ*E߫1U`J@ wEftQ$9pUCf3;d~|-4u]m-!2*HXT´UQ &^?ig3r{Li/ lS7D&]P+U+/kZh,K ssMO*@8 aս(T)p\ҾU{ Hh/ 7Ri]]kN?kp;n~WVDuL # iu P2+J%,;?iТĔdxyjJvbYVy{c=QƧ _[ ̉,<ϯ GUV. '[ﵧ_Hz(G$O34m#:qr?plw|tP;:Nc@^aVyI)kيs0 IF#d?~Ǟ7L9Z֊>4g|}P|5DDڔ\Fڧxp H['I)[$'?{2WUU8د%P|X^R9^7Lwe[|5U\K=;P!agQި3SǠdc*$>먏rcRz(?}٧x9,¦ޠ]Q5|zM{\HY4'Vd[$h5"J3xBɮG[7 ~;&h[s吞~6Dø!270gǜ<$S^K16~JngCN=jG?ǍAʛ%e+ĝ_uTG&㉱ ^BiZ]L eY!EՒ FCyi=:uvwp/:8c t__51-)ȵUk-ݏYsP>کrS`8Eq,R4L&Y|ޒ^2"'g bQ {]^d 凘[_퐹$AOrpX^nWA н[VWN7ޗ_{%X_~7Mne(ӓ˚ʦ܏!#orhּP֚~gF3*3(ԯ z`WVLt4 d,Ҡ{?>ӯC]@!QZNzϜl,yR\rX qO:$&*T{kV!CGc"+y2ѡëRTh<8k4`N4;e+& <.&ǐj1L@=N6E$3yf@H/i]'S=,Y+'j7$5.'I4_wqê K(Œw&LtziW[" pr&Cu¶Z*chrs\7t8lI'jqML+ Fv4ڏ9Fe1kz*FDCIp4%Q#7-E XO9:V5%n꨿ WEyt$VecEPVİ RjXJpTX!qAҤnUʑ\[GcӀ#̢ (÷G']{.jɁ&"Oh=c2N} 5n$Xtħ%eeQ;'Eʚ‰-q 2l'|Z\ xKT GGx;\(;֡3g%#dХ|qR=#<ʛgrQnAo68'Bx2kQR. W%o:s(¯=r]6`ݺʺR;$ ,9Ij ?'5jP&\)+`lO4ï=Ao*T@{\Rq ʌbz@8E]/Y/P #yE_Y<U- \a^1ٻ86sa>𦪯zŞ#L<[ԟNq'K+TAQW:8=S#!>BN< <2"fj/Zwg6XS(Rj4d6φVȚTiLeZcy!ϠZgEءfH`.+R bZժ \tg+4ކ#s}Xp|3ʛvS hX{qC1*ʊgٵ({.:"Pn4|4nlQYDZ= (؟ꛐ(Z&Ά;K77:K]JgtQq6F<]e-jB^;/0Ven ¨ǥpFQJfPߎ;JE5I6㮗' ?ǛcDY:Sh<T:ɾKNZ5N:R,::*ѝ]UCje MjP6*MpF e63tD E,8ȿV6'Y:,)X9o(fznnNAb{x[ SlvNeF LPrg98K:Sj *ʙZP/Bo+ٹ.vӳ7G';);,}o^s#Qׯ-]K*y !G;}8s+/&T6T-Lb)t*Sey1))nn}z!<@Иsfi5+2oOי0'7fܱ2˻UڹӨ><1נJ˓ P0]Ҥ(D{m9Q'AtMSܒ}t?\,H6g+DjY[)nwL)Ksè1hq+n2?O(69w\`g0 --"^g Q\!~vTiEAzSxs ̜< C8XwJ)+[\M{j<"=}L>?F!/*ՋAIEÆBъnGNi㑳&sHd!e DMt(W74 17F]y#-k͛o*zw{.WJ)5&Io!f9*姘߻o;GJ3#L(8eTxqwrw|zrhĈWCH]Lqͷ T0i/&>2TauXeNəNe!j|0mU\`oIHHe*pp`:SA>aA^oW N.-`jM⊍/,i%ph^G$vB[9^{7nk+#SeDx6gwB<+o=̲H qx8(6NXdVuHzHVC8ZNcCrR\ΥfvE`^yEq@W;zq ^`v,Ċ-'f'ȅ.d,.L 8 7jT'5IUZ7;|5ʻʿI%9N9 `@Dq| $yQ (_qhT?͡AQ0̬r7=;lQ%'T_-Td}L8O&lc=o4'͏SjL%+}T̆U] H ˑ([1-:$n 9[ J]p$H,4|+cXrrTa)ЭJz^БFU$oI  .Zb [׎5XYް(^a&9HwJbY:{cL<=]Og?]]r2.jYg& ;t Ql,-+/#p])m,"2_%҂sNY̖4%D/V@ b%+u )!3D>%uJK$ ^ƁՈ5\H3z&~*9eKЂRwI*ΏO6ąͅiqML3ozpʊkkv?R.Ou0nw#:Q?h鬇1ϽiP˅|l!輄_` g$vK⽻%*=KUhhQsWuz-I'v~pxEHu333gE) @-ppu J:l,qV Fa<{h7כVjV6 nl43hT kI5Tj%Fj&xW%кw;6]2%5U!5*x*Z*|E;E_,;̼+T|OLae=tv/p٠dNI_f׸c,C;!l6x'FJ7F' s.^$05%5ZZyac*(HO6)sa_ՠƔxIY76@ _#栖f}Ò_vx8 MY9&>= T=xgd'ep?AAEf<8P5Y[FCTi*5-`R¡ଓ6?k&,A,T1gˁxw1|O>5fڰk*m/T'"*hfHT~ʆsegne3ٿE[Ğj5bͼ ^y+mC'0o׮f^iӧ/,6սl˄|NTYBD(! ۣ16ȅHjpJtTFm4*/vT:;J5A=_ꎥF"VQkvIfG:GլbfT ^uGɂ.Ci2\=c83_Whoiu=t tKeG[(w\2#@`?v(KۮNA';gx%F*B-sm'xCw7^z Xdܙ}tu j~vA`r{rzJus,"۷JSxےb@G-EmLV Z7G &vY_qez$*7o\l@-RqN'=o?#f0Z}OaDT:uߏ(a yq&9Ce~X mAS$wŒٖG_5pV[53G睹{y#0k+Go!/ʼdx-P)lL3g`6SBt`Ԑ;B$&B+)vȡȶVne.')(1z1\u:ߐ<^X/ouRYr]'֊| my,YCԂG f/mH mKq9gtv c}ꋶk%LɑO rV^:^G5())@ٜ>ԯG쿟sޣR>, DaƌCS>kp:>'^mgz۟*Gp8z7~DRwJP?/pgd"w2^ۣl k*feI x\MhKKͪ#[L~vT9C?/^=1j4P k x>_`^{\NA$Hv`;buݐlde_>Ę@i49ܛARdqp>Xwѽ) Hpchћg=b'xoIk:զl_X30멄dg 5<|0?pU|, < #^I +'_d0.!9;k ]}2PSSô>%xJaatO.rJYQ }$<*zG`OxJ倄X4- %Go~U'?{H<+m傫N8'-#H<Dzګ}GghG?gY$]^MR#ܷzMY:ͬ4/.c9\ ƜHzh#W8x!!F5JəE"Ͷ(C[dSmQtkBbk#bE݃A&P \0-i΁AnСyda=$k::qRoT\=jڐ~߳?.&0#P;,0R~r4R]\vq$ Ig,WE-X> $u7gxx8 rO;\#QFK&}k[?\=h.\},=7|#׍jj,6FIJz**s'@N$mT¥L4Bo1ꑣҖ5E\Ҽӣ}$!QkxZqiL[ߨAm8KǢpr6v;sUf⣽)/コr4E;i`h'ғ&A8I>uqg(ܱ/_=; 6#Unyc6> g-w z/d1/nd # /{Kq\Nqդ"̸rͩ|ƟR* $4nj*A٪I)xq xٽKȈp0m~F[UyF4k2W)8_hV4UzyMPM{e;t>Jxȴc@kS)$W|y>rEG׬4MP|`oE?txPS#u,虜]/~o^w|DczѹM@~wtB~vqystñxyŻM|d\X`Ӫ@EѧnZ3pKwɜ]WV '۟-Ay73Z: c & ֜gps9*au)ߨ\ 2 uAԷ$@vϨ{DAq7i2íՑXk.]8?==?|S%4VVZN KC= Vȣ[r\gIKG6dT~UWs0Y5{\[5 LI˘>İQl}~%|7[lWxUS !7a-QWT,jXdrJ#UxRF;)'Cz@k(_fœN6C40<>Z:/6W7_/|eOyގzz`щRkpW<ߩxUu{UF-j^3_Źu$Qc$thPOL#nY` `}Đ]2W?5T]ƺm-].b!Wkǰ }~xb}uDṮzNA6M2T=Ž ;!V,EJATkfH1og^nN e㘛HLһTXcF`8h$(]ݗΞ5W-DToYfƏaCnZe8..] rrǘd\T#̽'LJ2#/K}ɦ0K q4"Tz!t@!> .?T)~7FFB3djn͘T!|2Y1z>.ezvR4M~xf[u#Q.oC8}>h20Yӫ 'w1[bbtTOo.,>:fzMŕd@il ~ڿcm叠҂I(y4)s~Tdp93P\83 8|.[W)`5r2PNÔf Tes=x3>:#.5a.1Tnӫ::Lkky6mb*}VɌ(y'f[ѕiQ!GhA_Z^*0r=͂bqjjq˄alwdr H5dּ̜ |%*fXw&ȟ3/%?Վ*SZSvjcJS@yœ2T^ͮT˟$@g{W"1f{ŭ nw:uO=Р5L8Fq] gq`xwU+~61~Nj8O~ S H<|"Aɨlm܁\hK;ؾzt͇/Ն?>ZpDI+0gkq[0 } `'!K<#36'rðJhK5$ 25q*&ǃy*kenu&.` y9d99Drr,Mn!jRP6qR'+&~PQKj0D6UFzrk|gx_<3#xpbM‚X9hk UF0͗]v8Kϒ2u݁hEQn!iD^B" 9uIsU-eOOEͽrpXZM#^,YE}LȐL@1\`ğV$Kx_UXIUzUHQmaeXW_ yS~[2뺤ys6m=DW 3%yr/sJ<γӕ>ik +88a8oΔvٿ]^L1RPcJIovn5)#%2D疿p=.=\,60n ")B QkOٯ/JVWjmꃢ;X2S(/cm$Q"8<G_5[F@@>veAw1ޠ0nM#hLW0 e"M>jMl]xF _4baSNAp$itrz Z>:ם?hxT`z3/t5 p@Z^[DLjaR8^we/"MЇ3EUdT y?!kXH +KD-%q2 G )[$AG2}o9Y3l:φճQ?]qk|1𳹹Nny6ZVz^3K@̓?.dTn?p]^'R OfTAv%S\ߓϷpqz%WD)8jN`zN>QIԏSJgYBqF}Em,L|, pͮq??{%ÇI4A %x { O3~/D!hCJW9 f0nW$jbX_3ݾʊ% Qv>!ףw._Uq뮖ސqʣ[J ~2 GSNt?<>:>"xx/8;D(\/s%{&g用nf}MeָYqsWq:g"xah pU^aTT˽&Z4Inj8Ƴ_~힜=GT`Q=]tAi)1[>}FM]Z]LRL/pP03Ԏ [2TU&SBfhzL>k(_0+ybfd ַb]`d,@ -$"xv]L`fBk#|C9pц^N7SObt F ELY`Te{<]䚬fHQĬ=5kuIHywzS%*#% QW@:x)|}d? ۵܏*670PЉ}஡VRi F,i `Krhڪ|n4  TZ7T;CݛtjFjZc;ohV :YH,3ufD; }?26O%#Uȴ5|GK.)ZD_Kh/]!P9yruS (TrCG~I2 %( &"Tc'= U'H*.X+Ja!nS{`Y^X$0_JƩNioT=BlUzrri.Tk_&z45R_iW㘠,=DWS(d]\*S 5ۻi~<뛏C2_wpf3c@7hH_iP#RS{țR0srZ]"5n JZO,Ea>0%.S=CZnȒHbAMWp{5뤺َaH!!S\OkTn4P^ >MatͤP)Q}ЉvN8"RDg%uF1+;h^ lvұhzmXLwp 5~5LR%vi_o`t% -y(˴Y(0_ޣK]=HC /9ۻw#qKe}ZfF.ۺBRoXM7#@3ur{"45!dR/aM*( 'e}+?ſ87Ec7IVj@9s"/ YC=SI]@cAM(]SpxZ<()~q*jXoٞE*h gOve) /h498PUz7w57 }J!KOFVIӰ&1(Po?\J%Q`yI@"s"ͯW8t|Qʹ_is}.G*j Oק'ʽ$Xف'› !{Šj+\Tc\zND#Gg?oⲮseof29DԏKe|.;D}qԬWhg+tퟟGU *ڂ<?^b(ϒ̗FW?(|`@'@*07 vOakVZ݅FGFVɟړK:dJ[^)\(Wf#ȶWW,pWц/"Uz%oy\D@BS?zCb)ʊG uI%.gKr5{}h=ezPə2_c Mv$ƕBAG=ΰEB9/Ts]?D\Glm#MS: xpˢHf7#EM3ዢ͂o>}b_y ^ηvsؚb{2S,xDk̬ievzj*rh鴨]aji8F!\ 9yR RW,ED"&J,5_4 I.4ӗ./R PF*d2zQݥ<} L]k576W5:f^ۻ%Vk. rE6n<1Hͩ&j)^zx6'(KOu> B}!t&ӯe,+Z ksQa+a./_Oڏ`e!o㕛55:0wK=jGjX쇎 BAT:Gu=\3OQ}|3A cӗwp%1]szn{2~NQ)$?FN8RT(IBC1׈kۼ2J׃<~tD+:k#;+B\ q?EwƟFVss}si5[h6۝nFaȕ(s:z=$1?-/ͦ(Fz A5&wPu]pT/)KǼ 1Rxݖ L=Td•Vlb*iOO~=:y9frĶ +cx-;sF-\mGs8宓9=Z6 O X _>|{t=8?@?z 3IYTkHvMip_ravוh"WlV.EpUUo}J$.N\`_%!t# ggd$NaH2P>#$JpeI)8&1L>S] vYf.!3qD6ȋ{'2b6q[5F6k)'/qn]nT }@ k*w-)~hypޢxŋzcri`,$58jQh^TZ9D q[\]xOCW:ޠ#Qp PwHEVzZ1r6E8s1U.eb :gޟ_-PtYK|y/1؀RBAͥqrv"D:7&a*\)A<2-`]x`G.oJvx_ I]N/}<th\.ͦ&#qVHp11 /.3.H}<^a0@Mע@jtFBOr0Cԥ {4;!\g|;z&чA0Ӌ|8&I%Se;fH\mV⸐l):OT]0i4!r fyDuB_c7иy%Z%BՓ:jxhG{(;Z͍f͍?|KI(U$ė1w_! x^=<>!:QbT]VICZuT..It'tuLշHp'{Ǯ !'U>+뒗LM'<<.f,맺#qC ޺g>Xs@\/0a}{I 7޽q]꡻flsp?TOETMOt42ko ;{~2;yJ9Sϴ7=  NOq`/:{z+9_zg>_NM_[VkCNwX7ڜ3R7E6vY{%xCT9`Y}M)wH'+@ *R &G9D1 ˋ>Ѭ Q冶 *,/.WEAL"ػo;3\#g~sҾd,@NCe<+HUk룷'G{ R O\u2.J _'& MzmzZ yL-0|DN7 ~w]z@ae?a$"̗v (vj6L+8)ҒhhE[^s[s[wl`+͋Zel,C#&0Ίc@K,MUHpi-n(fr^F'^/l4U= RFD 8%#S>}o3}/96S,ӀxsJ~c3ܗS.w?e *O\֦jH~ULM IT14[mZS7&X׹l/-wtVq{ ,72ϫfrθ@YbAS \p;ڣeQ /~(;sxDBL%H]!o|WG%Y#5< sJYZc/&{Ga{w OW#&𣬉tVTc >\(TGZއ*3P8x9htMbu|S$Ck+=}.eu̶:C G\\W ] YuJ` 9DR$=R . *Re~O-QiAXl.#}WaG`93[,3d؉޿Ŋ S}m#{zb;"0w1_z:ר Rp!X+[?UlkQ#}zQ,bCzB5 8aaUeEhaH`twXNʽ)A% a ka8DdW@Y(H; x4O|NFC.Rs<,VrtAl.(^M{Z|r_yy^ج.#qGjOc4 +bWsNT ]mcN:3I+in&X_:PYrp$~M>dˠR:@ytP;ElF&O<"S܄Ȝj}\EdM'n0;݉=:C" c <2쟞_vЧB]O*!Sd @jeն>l3]!xgUkpdhH9+nmnIzmצvj'1JrG!^o݁nDPuQ]X wpͬobɉĒ fXg:"'P>3='FwG0Io%%W“ᜀvꥴw*^ȍ5#,]r`Ú6``fk})Jca5h|VfBc*pp}k?/[%Z-[>= *{ ւZpP Z ma3x[,m]mml:͸n٢V4#B6k]{Q9Ͳ 6zA8X@l ` ;VglfklϷϷmj}}M! ~6Z `~o]-ZͫV^۠|{h6w?Zon[UrF=.e`؞{á@V#瑜` {NP$_pNgĄ1u[-V`QTL1gzf_`}E"n :9pȰ~$d$]zezV 6(؄=\o^u֛>AuF4 }M>ϯ6{[ai`oF.쭦^_ootþ`ohs{~gp۞s{zhs>z;V?܆=(f{k> e҆QϣN1g A/Aveط[f|.H~;\m=cw9.9<_;oJی0Vkw9` 56wamtL&( þ`_GA|.L ֯6ao*د+8[Tbj+m·`°a(Ѡޘ ;7xs;lz. ϣlCa{6677rzySj* h?o}T:c7P[ΔyZWp:a3%hn1x 3˰onl\mM` [~k.HOANAv/ڌsaǞe;zUwQs qfkmgҁ`wA1\]mo;]Tt"j6?{|Hv}>:fng / )Sj*#qw<":q^*ҋ'rp\Iiwjvl@=o)7P$%w`KpۙL\+ EkS~ĭ\^=Z#5= PQc[#}5+nfxjO`6cvAіn8ޞߐ[AbB *ޖTi~p–za9=Lޱ%UKKEI*7|$w)CbW w0~._gAv{SA hbzǏ9XLL |_p/}ʻE+ REA9?.EfrB5 -A.}FV b`k^ổr"m';v Iyz.%_Թr4erm5+sJY5#%>1+9^42o)C4'* l goC=?<&X+@86Xz65s(}W*-fׂU^UULh].>VJC]A=Hy!Bh4 MQdQ_15Cԟ$A62-DS*nO+>F=t`{@ca'li IlQaERh&E$WzӆDlMeZCKvB8%8׵$r9AAMun !s{?CzЙ!£vUwI~(Y{Ccp/e\1QiDU?D N&orvN{.PrNo"hmzL8flCP&vמ,Zy |.8F"a#֥i_ :x.႒ﯪhu:s\:53$:0`Q*S+,r&29eلX8b=s40yK7[*Yp up,!YE2]f:?kbwb.5/頸σ뗃ܢ>T8P퓾1ąZ#ܖC̦)L4&S[J9rGppƙ%EFYe=yhj^_p~H NjVM`6_kI k풚 ѭ 'lGFHIk`ՠbh*ZNak륗8gcé. T齺˰-%rʺVI2b`:]3v#RzU{#9-- o 1>+(l#qC.l&Iʽ0t? F .eFJopJlK%c-q_gv 7Rl Y1I`FgJ<>$ o5z1;w̓3gZ>~ |z)@~YjV|'ѥ1`3/epC|u/=; V$`+shTΟ"oqRo]\omX?b"ځ9kpkm~duu hԶG:=nɩ洍/ {~|>C 1.> c!W8(yi=ZӪ(w&_*oN[l@DBd5-4QiR1/]_e? &u E@ϹyUG,V^Z_%S$2.P}t: T$&wAihZ=x DZ_trFc+QDM2gìg_|P`!?c"0敓#u>ɾ5Uw˪a)IY_#K׀V)挘\2[$A7QEnA᩹L wq'v(j: .9`a+}Xu=,nilk@j|˴ww }"Mr(-m-v^K7f(DI]ld~hU0vEVzLJu{$;x@k5o$`8Gӂ΀jGcD-",u V%-0JJKuW]'+?WEqoO+@c}_EPݓy2ZsЋ^.VE۵tT}mNmJTxijAnt #t'q4xr8[QאYV53s2p$o+Tc93LڄB gèUVփ)wx[l\70E~I[4xpk YadPHJ ^nQ|cǾx/"Q.t`^W>>;6l>3ADD~QƳ;]p$90pqEBWlM4muӂ=9=9̙1 c?wvYGhX[#ԒXwu]I`^Ë7{o/2m/^I6!"7Ԃ~2Zs'^jF(fhB=&i fxeݚ ~k!qj-)wijN7WZ0fֈE[oA * Ig27+S`'X)b7\,b&UV)k; ťV'ˊBHn~*[roCE`gSjZ&tchM6]`P} p?MdJXBX}N֋KgqjVU)>unf9#WזTΡ-kND_ϰ7aoU_ }d(>6Oճ>!D` (f6BcFWzX~W̻ )n-*O`L*,$X, ^Tx-pt7Vg.sCIW%W!,o,|ܝzb$hգ4:ۺd ]xb$"O?'|} F,Nď[;ݳj\M?8{cwbA26i&_ţY*aW?NMhC6L#dcʮT%=,- ~,蘈z&W~F`emÿ4Xhb":.k@3@„BFx2HcU(em"PS z x|b; B w Ѕ+3}SAa5&{`BOyq-e$弖YTN Lh'T-ǜ!Sp9⮅ԓ!䂏$ )q]R/26I u$iS0/xY'b fc7dV(3R@];pqsujv(@[ {Nt PA^ !mDZpUҹ::Wsܳ8p_Fp@ΣPrkOF (ċ"IJ*Ƽq vyC8JQ[w1BL)3qO{Q,fC080z .MGW=RN5ėK+[xH.~Z C_,8ԘܕtW3o.JfB9(gJT-H\> E`2..mj!:Voӵij3w(_ۚ13`vq 88ZY+CUy6~7[2*k8odw ГUl/V2o.PSg3nhE,hw-ğ%KAW<)% b[Fm9%1LM?N,P=r8V[(Nx>Qo (mMw)ڙ6߯R洤xԏ=dEL}uLB:,{<#zdz)gtR b@~={r[ dR"XG@>^h5σP"=) -m=YΛ-铠 rOػ<<><~Ej]v }Qh#u++[:O+y쎡7_#Wh6ghP\#s rV ."R gaȻFK'0K*mq:QH):,hO5_/;>:CXwTjLJ|Q1o]߻7^:a*"5'..DMtK 6Iz` yXxTϧ?͙L"x6Yˠ0DkPQ& ̯aG {6VI8SctY:ϰa19sqz [pfGSEJihTGvF'W!֨K\ߙҪ(';NeFT[Bo#X3G9}vb19Fhv V3~V YB#J+YR7Dz#6-Z~ aaEtqC1%W$Kj%AO[[#ah֯R]y"QJ^] PXQpƣ?ut$k2M>K^بYinkQmD7)B%_;0*n_TT3~ k {mC'/(eLF!FA`iPhM$3k%gQwAvD^<`Qp"l \ ,Ax }s:*Q=J'u!Vk>"鸩Qd7.zPY,4aGF>l͌21 M> z y~Ħs s/sHlW7 }3LK4rxe6VI"Tkc_y"}%^.޳011qvs ,!r ݣy._oCbi](Vq\f$sep$CY` k1,W\_8q*uSg{Z{IL(XUXB`ǫ8k q=XXYW OŒ{_ғ 9:9xɝ U9άzKō#/S U+88=^VjP_'wv]#5'l(\>Luf9vذE;:bcW49,( wp; ZNhϩ%^#bZѷnMR3ya\|GOK$=sxCԭlk(Hg&o7ٜS97>dqv/'Qpu/YtËe$G٨\MX 58f7TȦ:=C!CVG18]rZA8wT%̳$zmȚPhV2|auRFdc G`85YaXTFV~ c9Ιqp'SL>C=xx\~)F)Kwh6}nXΟɜD]PDQ!)ӅVPKZ_KNfPԲ#FχnlsNrpxv{tR-ko-i}&U2,w?se|iGWQ)\9r7nq' GU%LUcؒ3'ٰT+T2>g^o2⽈,KhU8k_P:}9X6;dhVd -;IaFLJUPZVdu ZRǜcaޕ-95kfeI&]tp hnk> s!0>X^SXcb8SXzC=ɇ\& y2as$)|x743^6*Gxm=+rY5tD<֚"3@aǎ*PWhƊE.Sd~7y 'X< <!≭Ak=*P)v7%XK˰(ܜnY=N(%êR߆F(o;r\$~PZChvx~j7e/mrӛ^KcXB6Qؓ<'u}3]6J߼nE)Pԭ֒:eOݬ6 UlD$;${첤?nWZpW݊қXSwM?ɴuwl'K\141}jd*L;6sw](~X2%/9Nv?7av^,ʟ!s,~@ӯÙڲ%A 8i2T=y}tB'{8K@bk͑3i.qʤ[L3(4r]OZ|?BdTiRBsMe]? $M,b0i)iiKVbXKeA>Z֜0K.QrTiKf}0fmЛ.Bc"pCBd7tץd9܃8E>g=9:cQYFR­ځs;{[E|]n3nP5QThQ+ޓXOqέN[Ndy [j} PcˀL +o]E1C,CӢ'&_:y +Dqr;E[b?8 Ώ G]ZO+B28/&iuXX8Q*hnvFCIGӻT.f-;k.Hm۰ϥm!$,:9|ɵp:MK]> |X{6[S:7T*!H96 _Go8% aQh |xw`r/76F~TsHm3JͪRa&,*0;uei;|,7p 4/|o_r12!Vkٹ>/_\p,_a9L9R>#C9oc|t 9+FiӥYJIbp> .N'q􅭞SqatYWa<wrXX\q7M(h׭SqJi3SISw^_V>o ?8U>5[gY|e/!jl{khI_#Ffu ċ~3;RIn`yU t&@F>^ 坖,WLc$!¢ynK }-PpQVvUV~at׽M~rbmj 侈VϹ#=M>Gq7Hԩ:jU rNOŌ},\ 3//ikKaT)mH^^[_܇1TZ>u,:=5]~V9s(]?[;icwaK@XD% RXe[U Q0ʋvB@>Qڿ4k b3)& _E4j6J)o*ö 6[X?5i-X^ & :7j+vT;XuuO`ɧ5ײ,pGFط!wZ JWy2Tn)e٠5iن$C%o2{SʈH?]HUWB盅ń9ںJ =xX3o'f,\KyPT>P>2ђWI~Ym Y|/UDd<* Q@jq?'S8J #p<:8|vzyxrɡ^E;]ꐚagZ],M| U*j4cQ/A̦Vh ǣ*8b WWy2߈'ݹ~ V+>3xfBQ|#[灳TDwП )x-UU=Sʪ9aVrCWH)hZY1Ãgnqv:iZD~\ ^ߓ;I-(6=XI=Ae<癆""_]lpU7Ĝ2,Ef`Hߋ9O}ICJ9iz##39.ÀFy;IK@[zK1+HM2tnn< &`o&xo,O%%XS{!Ůiɥ>"YSmqtk=]d_y:\^%522[CՆo.y2.~~ 5_ʐ|J52La ʿ~#>F>d>[Y99<9=|M :GPT;ƐGׯsV GVCY,N"yROIc7ey;?*B`Q0T?8Ӿ/D8$:{ԕvMa^s$ m>y\ۜ;l))Bs7"*-js=瓱'\r9gAAGIh5"w[ϣLbM1v+TQKWhRS>H1]hwڟi:l|1nmmmljmt:N<=G?_\?<+8!bBVnvّ翧= i1m2&H L`\YNZH~ɴXp3"BiVMN0YGRkbAв3=3*)÷G'd运+ی C݅b]$ժbJb>lewSOxN.jp%Q6N PD>!DF`}d2Hk+XtA3;p]'o0LN *]Ɉ.۪&/hD*b%PZUQG^D{?j oUd &&AznTOF̱AĵKN UyF悉ʔns$NJuO%;6P C9<<>`EUtm4EZ3C"5gO˚ 5ֻ"pKHBUs%RHTƐo vYY4W. 4uc'Y8d793.xsl'){UeAr!RFUgXn!ZſWb(pPe\Uܧ[b` ?0::QXsB̆pY-BN22fX ÝF3p`Dk.4\w҆ E3WGD K3Xb\cӛ[{\|-2uUUa#3;ּ0/r)nI4Mz1! |%Ę.O0#V'{9mh8 '']ZUy Vk܏a++H?y@*+oe'Kg?_$"L9"@9GϒT\YC1#t̨"hzԂYY sIYΆ7Sv@c y'ĆW۬ &Ъ?gˀU/Òr\[$*7-8[Hk֛dovGy,UVRJܳF͔BNV M^wɤpB?>Jd gܞ/cmPN]D- p*C6Fc) hIn/q2}AUiV)\|?3t,}NL5cClGlS}:؋`cbAIVbd\H쩹łs b܄22УO 9Z)-k񘅛pdDSj\ y]=L”>G<*-8~i6} Ͽ8!V#u.:[qưJ9ⓝ5+ Bjd8 pσD ^}8 XDNQհY!k|:I.p$'&{,ёM)ȺTЂEG}泯L`8,]t sxJ jc8% n(H~ cG@k_'C㿣wkVskZ׷֩8 YHj&l g>փ!GqGGרFQwo߽E[h(%ˋ;Dz}\tVûxOR8Otv w `ˣbqRNq="+q~" XC1GۛV4wͿܷ42ݿ+?6m%g3m? {8S죦{$_j;K{uo-qXc~Eh8T?0Z}XΦՄ!pb#8aC /QiƩu. n7",B4钉 ӮTsaA @C_m;y32_Tyg N .F* :?PCTJbf𧠳l;AK#  %>]x( gQ]嬇]j N w1)!k.˫8L5>pm4Őؠ˞0q@[~xmB9ݾ?D'{&7Twzஃ |@{}wYؽ^%s`IyNԞy yܵgtIXHoByvuR4 0"SD6 k$ډױX'{FzVV)#e|ϱ\{Bk'f=lEx(8X"(aC ʙG)Œni5M`˭-*6z F/ZmӧUU}NUs@H{n=^)]VoN >eR1 &NRL{DB>xB [1DQ34GpOL=NqnB|hr6/tvJ૕+ p<{y:~PD췺Z)il**;-p v,!%NN;?J3kr14<_G+0"^&8Snq2s&pM!T _/&kI #݇ ;=k܏Xܞ~%s %Ņ)W=ev pΆ;BtGmyXYeYY@,m7*=8h$/x0,bIDk ޴ahFxd{bBSuvT>n\WE\%MI$0aMd}"_ֽQ> ;T5@ d!Ymb CJЁMO |[_mn۫3$p0+/|Y &Sb u#0 ]Wvyi'*2Q8w&=@0d!N~!Ϋ`ut# o5].&ٛZ!oΦUyF@T4 2k_g),E'qzg-1^#(j}1Q!G0I,i\4[?<6no^]SӾРGl_ٯ) zGۏ4qҎrS?$?&M x;l"D-}涹ȯ-W|OIjnci ܶ4fą7m?f\h t] aS9F?Ys)`" ׷c@eDz1H ' oX`+S|6X1~Ё}651\u.G6-Qze?JO{VaCU LjXJzתmfנ z_:YӃmxܱ4w~nV7fya=؆ߝ"^v Kn{%1Z#4!:~.o;baHm,#G:MZ].:J8yZkIg>LQj TlGytͱ`?V7+*y%Ji4'(B伾Yr ې9{.Lq  QJI=S]i w6<<`9#x[=$ܠZaq{:1#q1>dE[V-N2 M@WM(R_e}GbKA 0W -fb5]!EZFTPzM8lm϶*j]ȫGr1'-wRW[3ZZWOD ˇSnU%DViAH1]sK뤬׏,& OZCc:";,Tn<{>| O20J݊eڮ9OKW:}F:{Jjǖ6nesɶA FRTģ &//t~b^{ݸ'FtǿJmg4D.嬈@ӄQQ|S!x!ӊ '29sp&t>e*D 9'7 ;{=zҾ4`@l+%DEH*<?..rG+y@_V}]ay{k4XeswWa2ݵh4_0^`SՅ&%^|qrӁWBu.s3f >g"aU(`lwaj11ynɀJ^vIo.2D=Š 0<Q/![<;T6v u9{ ^0YQR0j$9ʱ4I^i)xE0[ fPLm8PTpBl;hkot!E062„Rͯ Y;xt!jEͧ9w@ڳ'pϾ֛hnm]%(ȡ3%*lERө ֦'S:;I<߮ TYio_=QT繽pܖ͖oipcٻjCD`1Z5aH:1z#¼ɦJsE9#(DK$ʄXP1Q£`-磀*ʒΏT~^_Ŧz + HHۗ&`4?9|ܞaViwƆY5GFb8D#լ"2}ZYm1 }n4i?:)Dl m%"܊}/2)txq)nh$տmUxp\FYt !q6YHPt! \-Tam, G85ړ5Z<{zgך{eCAsC{gf"VV@ .I棊1^)Of#ϗyS rJ"<_a'3̽ >'M't[29vz\H$hw&ag~+q, #~ki4ڨw @MMrh.wubh\ÖJ羂0_6's:"&%og!lqxC(Pa L͵lv h`K͗6?ݧ2P7 % 2N9 d-0|+U#+`` }RCz ߧؤgH1 Ѱm\FRD%7tj8}T8U$30)m(V3mBs:;v#iK M9U% Iq4 \mů+7$fM,k I.C&f%rf=MM`=qK sw͜b7ް3l\bY`e(1{mR^$]Hـ"FG+ƈf^!?dYiZ~( Z/;t%:%vr]WAy<',6BE{*%R,>@)&cꄘP' Ҍ8Gpj_Ƨ/$%I֣g|>jqgEAPtNsRYʨmD|^< z{#z˅ I5DbK2` p$UTȆI W/8Vt&u3R!RP;Dy 0SqJ@$b!xAFPh{KGgA|hwnWv?x}zn?n>ͯ?#^rsܿaRoI *}4J*ai.d-Yh6KR7/2@$8?S8 ![qH'dIfH²1 ε+RE'4$GɞΧPrMflIpLݸwc4bb$$B1S qiBX$L \f='CoQ|G=-mBE ]wi BPT߯SM!;;*7 ^<*CUq0#EHrd*f4EHAtHeفSdf:<|Ǫ fAo%Drs<e ?i"t'YW|A4J קƥBcMx&*$DOHA~}b!}mrR&MbȒat20\8gJ),i\F3bDY >onR32U}q탐FCZȬi=Y24)?`@%"YM@Gq@iFoqo~V:!q@JLڱp,#0pj+K83k#9xKx$e@B%d ;n x_ɲ-ہIς^4da;S%GT:zD:#j\'P W78.a^S-V V6cŁo)4oL}n -B!~ &pfߛM8A 6 N_JmD;H'@V`Fm8Բ^*wg)3N[,,2UH1zBRAGtta'9E|imnx'L[i8s-⿎ At<]7s@F6tMiY#/;x͢dl޵c2t 7ߜ>_-WSePVբzĥx.f暴GAM:a >ӝԑV"EGŋ_6^XF#@.+]YA|jd et) ,wrz~(U *}y^;T*w *rs g QW7$y'6Z68гK6i}iDVfh~0D`6?M֢^Zwn!.(v+oNEV.(E اEc_ۧǻ{*9 tKs|]ֱL87^ImF\* >1lj/H[_fdEv|(jޝV鞻aOݵ_`*~P7'wonYxqp),ؖEFϡ ^cJt؞\.Qsv[#8RV#:$#' v|"]9Hٷak(ůbPMJdc ºrѱ,5b6_?].d=5ݵB_Wi P?|mF E=~Z|>`eJ+su_Cֻ>l5ÍM.WBs!5(f< V*(Mu݅jL@cFV m+7,4"0'kM?_7<,4IƩRG7uK ln6U+W; ?|0VC1b^Kvg‹&_.檁xԆǎpt! 0VF \5 h ZSz-jrKJ$"3yOo[0Rw 0( = pndnAq pQ e3qT!UUKйö@(CCe4B_=ކ+_[;O6)_On=g|M<z'E#a[ⴃ`\x4G$/Y$~"'QL'Ӥpھ ge<з';͋Wϲe_=˖PXɀYDs@*w+ZXo/HN nNw71'`|6y~*a^4e~QZƗK8}+'̅?_3G,a'] ƻZBHñeM"Frd#T 'S4qU0 ?QЋ.=̬'Fŭ%e:GF,Kr0";^oW LC 9}PM{}(I"c,"؏=[`x[.Tx$$pQSR~j!]wd`^`O]vT7fYY"6^дTjzT }T{iߵ8w x1..>3]G#GL+04fMR/S@msN?gDY͋';/ޗBCK4Z 08mr;PK5(r0=_Z۟ [QO׺m|$nrL݃>dVI M;k_S>E؈`rݎl uˁkWQ;-4FmMބkf?a`k4z]Xڴ V -pp0=SlsU 7Na#^X%JX bvLYTAGQ헢np96?a7gxQ _B/yWB/oj-FnOǿY떻e(GB %ۻlF)lZCʖor!DR)pʸ>C3FzeY8Unlxd)^w=@KPDk@_֠ӓ_ O1מms!xv%w$"~SzA])g{q6:BkK3<<)4⢮YB/?I4 l$) 7*UP4,HzpV#CG'3D@7`Tm :nt7?cJZAqdVT`fAXfJ&r+o`n#SiS"4j|JU_tq<"vࣤ;$in,/\ţruq\ޔ@^O29% i&|Q" |50-D6嶆kN&vG)X[kr",4<4@Sr|TMWE *]|T)q*" <ӈ. ksG4H@KyL*Dn$g :smX< I0]Z~{޴th46%jkuJmBlA1V3xfXL)&N<&lzi¯.Ÿd9&tc)&lk ] G<Z:)[u';;56!5eADMT׷YCkfjR-IiiM$]Q%Y>=AAhbF,AbuY#BUage;NӪהU 'ˋw[/M̕{ u|/dΐ L'/ScW$"`4(:V%l=:$sMi]CS˾HY BHR6B;kVeYQͪl&CPgeߑ4{ nG׊%Ԋ=:(HtQkultmlk gFQev8-fv #w |W]"|:oܲswR;\0QQ3;?ufSj) ?|ޯ搣Mo#|ԑT?4>ȜKREwaDԍSDbVJR`$QD2'v_ړqn]FFg~sUzϲf0HkOb@nУ9OMcdQ8A* Riw0 ]s9&.v/NkAzY-HQT?Qe?r2\d>S;D۪(][sbuuI{l^w~:h'#dWF$$)@X2Gd;" G|縵tZ i `7NӃvl^C>Gsݙ=u*B f}W&/=i?i6o?y|`G?k"͑dA+g ~e2KA+b.#O;W^y츤|Bf.o׿qk%\H<gtXSiVPgKޥh֌20&t9k*"44G0@52,]]GD9઻Wq:UgB^t֋σWv=ɲQ5#`kۃuPQ$)>R`%P)l4Ǒlol6' +nI!angV҉#g ִr (Y eXb]Ў`LQ?lp6̋ڧ^8ag´ H1'9W?(w&ވ$Q1=0ZRmu[!QUj⪅C䣧* 3TET}kx XOڋ n8&^ kWg0n]6M+sDF͔Y!Cse˘E4t1GFիnͨ3\ñ"8f!yK$ L(~ ɨh=H[y&\(x<?*iV KP!/;n~y dW Q,5x,9K@!YvC6;'l Q1bMaBqV1A: AMzta3 sosӿk\s\1Z@/A`T`L"(?L}%x,E9 OWdL`&|ɘ DۤQF Ʌ7K (t:Sz!H$=F)uMqz6$j3ޒf)rL*]q:[$\dkK"a^! GL"0R͞LgqSBElG-:m{-VXઌĴd8`)S]!j:{.>*D̊4\DsteGSΛSp6uQ#WbP ދp6<3}fvFaҡ}qFj Z?OnUg6u'7dYoU6^^Ygyu(@H\ѼMD\ϽM7—TV"M?j <Z~+){#֬F;(&.cmnՐW‚EG^mÏfydLj2SvIx P2*0Mٷ,+A1n6. \b@]Uu^p'*lyJ4~A)a6iO`WeZT3;nE;5@*ΉMtBlEpcpj  X^ׂb`ke<Uwvad(^c!˺0, FIFN(uGal' %(;K(xͬqbHW+Pؕ*fp(*}7?5s5#4*Xn {`oBtӉ1[BڜPz2U|11ǘr4$rO #wǻO[-*ߜ2)&/1GbQIx(ImOnjaƈ sEwBϤnaD 0T plU˫JȘV(OEiu i!xn!6m@QaK6)'xEW 'n ɹ=KXgHG0+P߹"^SjIKں ^mnh'#AL~CrAFɥ X[U{ل̧a2q8,rHv&ia떳URpWn BQ۶bm-BQe mԳ|HxtdЌVy(MMДSiϱW(:Ʀ8h1Ȉsy p\JaHwp8sWXqFaUc;m`lIz o~f"q#6ØŸU-}wHVq״OЬ/r}8}34pgBPvm>kt`EJn t@tm+/@H qQoGe-? pkLe|L'%I T@A!R`ij@`6XMyI/ Cށ\+久QEMg&oyyCɿc8A93h֬@Dur$zcO%9<*^p !q6GNd-hLyJvqq !'Tm/!@-6#44! s-uYX\?wmz[^766]Ln *jA_V8͝!^4e ٶn(|;RQA7mۭ(G%+=n^vǥQ}b-u>fƊLRXj;TvDh9.#nAU8-K<68*W|@gp|p]_AZd7c h8k[8j,璁4i~ל%+d?"+IiwyQm*=XzR!xTm~W>kk[ulpzc 6]^',\V|3,Y17+e ']kv9)21!4=K;¾y#/hG_jgr@ESϓ14n Yl IXvxU9dK^+k dc2fe-փMyho^ft+6[. LA1MxY#w=sV1!b}3~qQxpHtdsfd i٣LTw+ڡP 07ŷ1S_{u, w.8Lʢ<-#OEvelk-+܆+[Nmֶ;ۇ/5\އR^@YxrY [plȺһ^Uh-sEs! Ivi): R)~(0|ȋ:o丹7?Pp)XJ4[0{Qd*-WMđ%#t GT3K)8HGyĹ'" bϮ+v(FrݑZ-G)1)dibM,İuqƺDz^]\ŠZ)9`uL$rrj.AMޭSKâ{# -/蘚3Z2p2 /סY$#WI*ohNM zw̔<Aq?s8M$ܽT< Uށ]^$5BN|IY zK_n7w<~5p0=&}ΆoП[[1נ_~~ y{w;^gAP~McVMM93-nq )C2Lʈ8ThQߗT F} <)aԃx&i;ڒmb&&%R?IMطa 2Z!%EKU\~j\Am# [ hF'K:\eiJӑk/hFW0pE(-Υ o_?XUɹBYh|DA"mw ndF}` x/Tt$HhOmEcJ2Ntψy2|g %86^cܨ^ H@sJŅj3URR8zIf^)S:#6f*n0eFNuR46x&iۍP|8/ͣ/ҏ~飝;ootTPv}:ˣ>N-188,Dp b#po 6W39y $!, YTkfˍ/ɒ.i+1v<$ J])I 0 ʭ`*"F(VU,# T@{q4Qb# Ng,d{]B;J%mCth"f*Id:p;jq*>HQB{T:pd;~f﨎QbQ.Ys؉8d0a|%H1i– @ZLK88!*q{kWK*k .0>u5]%0dA@D0_LdQuMS*L2dOf'1xB+C#L(dƩ3= /P Ȯ[Ub1 G Q<ԃ̮$`([<(Va2KGHpSQ4 j:NS `ɡs͞p3^2Wg0 Xp&giCжΪr!I\ K;B +I ^@JS1Y-:.).p1k+l>HHGWҗxuý1(6c(u'$NF1l9HHXx,Ah:F k:Q7=R8p9kS gu2 Gu <کx 3Qxa*tnʅοA838:bLXVј) O%(*p8RLNhtT._+Wlj'Z̚l~l+ M?琳μRLre# $b<$E7JաvOY{m*:R B`0 C) E--2^0'JL5"#5Qh~L) aE0N5CM 4̀Zs1ȊL9t>&x,2EHP MEp>,W={k Cѐ)iG!B3# 9'sDqՄ9woq\1e+‹rCTU\Z܈6,T iF1Ә, y%<-e#TVYdWBr1@Q<_^EY)gq8v(=2X!1ͬSTIt[o,$!Eܢ 'lWbW BnТ$hѕIqZ Fq&Ӟu804&O%\ )1@)W1Loq g(.~버E9<.%^X$rF7ՙD.tx 8D@uYECi46B.'@ slBX; oHsNǕU&*Iae]Cl&N\&Ȣ)BxU%YLT Oc E9|璯e@9h%r]np(XdzY](J#b%両B(9;WqƇ6kZcK.WoDFS  hXdpH!@Mv;NTz)EGq @lJ &PYz:W7P=Ldv1bg3Є07𑑜HB1̉Cyڴ-qP#c}3en "@)0"Æ"蔛Ƈyz)"Z*2!GVz(y)1n 7jR.w`GTseȝܮ8fQ*fM*򥀤i<\o,84Nj IN'XSVp戕n/xES$>Tz'r5 0f!<#h->KJ}0Rӫ,FLj6H+yV(҈8IAD*/K ͊CIrtT ٙ[)pRCnʊPڹ.\!AXIU*> ˿V,& 2Y>6P "_P#yݨ*d$E$ΰ2|HFwxS-ZՔ8$ 2q q ftq$櫗$}F䨄PtaWKo`PdYic~a b/&ΦEn!'hZH0U5Y׫:lNw;tV KAT2(\5GuMXeTזw=Lt$yqc7ݫ-ɅQ8s$弸I,C)0ydv#弶#bi(2OԱX&Y/EgZ[:V#%' r+ƒ1$c?ę8J@Y)JRQ׾:|to-=yJCgVה:_̃DR~ɂ& g;Neg7r0B/ta &6P狎[%DWz6I8I,E]UOm)lFKu‡*>'eZg8 &wwO".8ʹ36tŏ7]\^y,#JL#[R4'AEuHRHftPg(x~لE߬bIN)CK!wVƣEŶ\oZ_<![\LKZ+=֖ƛGs) q&)n(dy|L Dk=n7+tpF-aino=S=dZ劂Mnܦ J֝9GWY1[q@-jI9\%su_d ݦ.4V.Xd'V\Cci5f7Y-\+6Ue xL, 5%R6 Z\"LDل= 5 ] / ntU.+4` [ _yx!K ?[ r}m  HmGE.Đ/Hm5T8$\j^%dRKd;VrcoTwZNӢ4* b;#8̢͝!%$sJZFvOuܕ6sx2tƞ} m@Yr~Ü0,$6b"4V4 QQ0K:=dՃ6 *q2(R;Q؀V2sTKъ*Ƅ?Z0FhL¸8&˩싧 sɩ &)߼1ߪICFuuA',A)I(E;VKQICoj.cs4JbTduzbQz?&uҢ,1)n 7aCaɧ38\婡ZaF9ocoh-bҳu$$9Gi:ņl6cUde9WqN. Ke|ICTcIy06stdej!G&=%:aѢ6P9 ѕwBXIѫ%ft;aC0l("/!at#D@)<^mLꊭ^_YŻ&Rt5a`$ǒq$@$JL9EpӡuMڵ);*ғq MWfWm B,Րe9Fſ<؄\qYcc#pZ ul%-Y0z8 8 dˆE$ IH4D/&f 4UZ$akJV3^T4QXgG+W6wQ D =p:y_1-V9Fb%a=c]d\66o6 h<5,mk1Tj%+)8qZWWJլm4#ެ*:f(sbR{rim"%ιB{jjA)DwN:U9_8KZPiC_⹯"-4>6s#"eM5li.ߙ8 fƀ[#]#)`8_b$Ȣr P TfSoSpD Q*;hd8\ O(%PFЍȺ_+v:pk4ܡ k5x52:TH,-NNzlfgDyIU>SRV A{@.c.P,|ʠXntV,nҫ{?#&ңwLtx*Ckո# bsw.2URؑ3<´M-ᣵQjղWe,@eĦʧ8\CldDÙܝcC#y;Pa]XV c!_%w1eY`9K~ijf"t}c,8bqƂ]S#hp=sɛj c'}9u9k,ce$XAv$|{SZL9AP!J1QD#z'#.xQg]* ۉtb@2R$l͵ nuJ{cj" wć4aKP+d dW2acU3H^PȠLIB,p RTkvy?\9LR7O%Y.Ih0却k߹ A}~c4TQF$;TPOʳFKY<ĨtWuh&&z*;U}j6I1`ʱ*A4#1km֕HHo\T,(/64 ai= +rs,َ35h)N_aGM=*Hk{N2~dL!L0 d4s:(ylЊ ysNDbRǧMnQ05VxвLpt i jXP6x."Br&BT$̈pZvX:Fm D^_N]咩I =YA= ^[gvQ:= 8o_1[X ޞv+jc1v^ڧi*rzv/89=siՃQ )z0VʏA#hw'N&ynNwbA}h&U`}? (KR1U1\㬥BoZ}Z'83O A %ٛvn{Ƌzӟ:IsPSlG&. \'Dg0D6ZPm:|67 0 q .VH r^# ^k R%:hij,$%H#蝴;Z*ǰ WH#A [@<% p "u@߲-rLy {l~+ߗm̨}h;Naka ftyQh3wN~B8W[Sc1$\3 ;>>hA;- e~~`/:x-TD(4̏pc>-(ţET sbHX.n /+S!zƼ|Iw> IFtגs*rCp$sILd+d0Ie|5$he IB(Sj!I#6qYx7.dt*L=q`d&n$I}3PQQ-BEv})jNNi9Ţ$iFduʴ++u!1'v@ClpQm2V(4}hy*V /-73xy=Po>?&` l d`2)>-ۗIYؾDe_x qKקOi6l=mn?zJ_}|$i_OlҞE峻|_kׯ_9>4x]736eU;8h\Hq~%Xy /EqݢuM[JōlfWdl+M2JyD9^C]*!YL2HavpІ {OH7)dO8A ى9f0ht60qTcÁ)Z6)O8]D0 qb(408q..FfE 1|PU[fCښ [LowQ@9 ʪ Y8*bw۔~8CB6ˆ'`44nCf#p~o{b4 #JP"(]›~Ϩܒ5C=W^Pz-8O:"\doKE4geBCcƼH#M:#q ;Vb)g=J1%:zi_9bOv Fu%xYdW(Cd0Piφ xF`˗Qt:D`壥w^43`G@"}Kla!iz/mѡȆm-KA$IopT48ie/{QD dBΠl# eYSnݐpOrr'/.  ޓH[3"E ؋8bJ䅔٦2|Xh M:m=MQalXe+/4aTJ Y~{gXt!@nC]+0\hKcG鱵#XG&w, #\QT swko]fK ?h4ݗ"y<}Ug|D&+ T/gY^򳽵)?lXnj)V(tn iak ezl BB#P*+2d@g{86 86h#c#V0=PT}3EL`!٪؆=No;K`<>lKrk؛vGK@f ٳl>+%ZV7?q nta=෣΃]qhWޡ"0WTs<`S3M&\\ b=K)UTeRv5cǕ ^6貏 3ϩlMF}4wwח$LǬpTԽe0dd.erpՋø2FH Qxn2>sdy\eIuDN{fJj>ealnDOϣ'n֣y^!'?٤0k0BweLޟY"$]/}=8is]Nw☹apM;/N$*|eԊm%63d6D4u"7xdp O0֞f36*_Vc n0@`}TZnaW@>hX8wэ~+*EiAq-B,(  /[ 8+7p2h2F=;V<^'.nr ,ljN%F=jm:q'Tya]q"$ ֑y$}P@c_%Q&+Jtb_25eF8H0&Z; sZ]>Rc8!INGC."Eao.mQc, g. $$r1d9@G5E2s=O=xuGwa%aSU*Hiu0}ro }g FA9Ǘ췁Sfyu| v`ы@S"D|{ 3vd{醨36?=ˊ0tn!Aᰔ錦'nwdB8!gY0ÑOO~9䟭_'p/':+6 f@*^N HT Q8i8JՆh5OඡtY"vσZl$_mSB;{ϿhǓWl7\w۩Î}m-GBϟ :ݟZG8GUgjU#X )@ߒnV NQUVy[#O'i掃~Cu3Et$u(JW(vRcˣE-HQk#;p#_ʺt.9jjΊ48,\@hU}ᜈG\U , I4 6yӯy۲6r6}"X3Em3w4>":dXRYB;XPLhtئr%U%Ew5VgƋqG-uUwStřaj*Zy ^q6Hgu 1/=jn{E#)xk&j"7oLt< @eְAbPɊDϾՎƒ}QDQ=8LC jEajAe 5QMP&oE^i:*.c k4n0;eEHTzBDIY fh4$'/~?#YSo5r*E;Cu9n54Z @< yODf VpM :t1@æVz4aCx5=(Jnj8k+Oe˸<[[ݨZxB$çspKpfـoe~iMa n!@r~&srCrkr{o?o Hcؾ qgX~@}/uM.QGp-¼ɾt4fYUJ`kpVR@&l"T?W8-c[ 9(w~5&|!3w3i_k~[CI&@hqs_E5ssS.z)lv?W@u 0(z@%Y]FsC?TVP쑵pP7s8҂W34pȇj [DPȒ -!%jAN6uADŽBo8!eCG6uvE26^[EgQ}F.dܮ0bb76=)&v'ѽQ^(BϔV"&4JmP sJc$Noklնj 6՗S@2f\⋲f`c.L1x8>8]\Qj5)G1cFuҹZ('*Q}-1|h%X^O<%¤tCçNz?4K1Ohlhvsi_F3Ita@w:'J姚wR⯈Ky+6yoS|~ځLl7Hhx1*uW'9cM\8[VS9UX˹~H |HAgA#bBeHd1 KZ)Y ^ ߢ+!s1A">j^ՊurR|Uidw1$۲ g݃ګBzo_U\_@/ɏ mwrV/j:xOߟ9D,;p'}F/R1*׳Ą({VaVe\]RF}Im6>MhԤ3thG[K̲.^ v;[dX"σ*{Z'~&blcÒkԔ-"!ѫք|m{$Z?2Nnb`u|+;;K5 OTԓ`8f V٧}0c+ÆIp:}׼}l#SrQL6 Mg/jw3cw,x˒ z!Gs4oH)O:qC[uxp))6G'[Y泔>R;M p LHT};Mi;"[LU?t[G/+K^9uVjaKo`Up%wpeWQ+o錘@-JC<&Mdgը# R8[gLIU|rީڜݘw'!Y SL :?[g%u05+Q0+g$>p2&:2@]p1ιAD_hg|dZr,+)Xd-9p!͝!K ;`Ώw%:d;6_,J%X4ۏ5OMk?#{a1!nLDP|W_ 9Ȼ`Yq nn4p ҅A%[$J.c%dyu$!he1DhT@uώ9mJ~5{Oag˂)9bDb ~=pbJjgIGĠOv }fR33w"2s2iѴVLPgqRړ)--+ dqP#fsH^^۹37*J*Tq6W v(%?S2N-‰o.e &6(+;Ajf{5=(M)NyIk妊 Qc*A5cjHN7p>bf26 (Jd!*#c+OMQ&QIe<W3HAPkyhzi0z&c`p,:d[N"4 dN'dԺ\n-ċ Ӛ)'-׋3zTOffPl7IF6Ue-:]'f2[gG xHf&ᇪ"^=C5ݴ.BKm&MIp.8/(VFOaIZN}$ $4T lZ_׸F<3ѩLX/Rb:T[=[%6Wƕ5UED70-eI#NIȈ9͊vr3o1FKfSL`Q=.y2$p(CFûQJ< y99:%)0w$a|S4$)S %CAIDFJs{9z‡$}挹XtQ"!r,yqrȃ7׿BW, h0iORf7<7^ @;/&Ub  #(UrW+g@ng4FeFwCD9 f(nRhZJY'١AYRC Ɖ*„"VrA2iRd"{L.Q_3[u7y:def- d 9 f^zwDt/8ڝIc2 +WȾ26 s]LGou,,ƣFK:ܡ\_gUBY<{$֚|qlO}HF6-=e73ɔ4n)yDo"Ŀu}Zo89u~#^o丧)I OgfM(uGħ%ogeӻ`%;| &zY8 ҭ#IVIkNl*zq 1d\8>Xh*,D+I2eQ]SVmX0s*ZWE> s!IյiC݄PޫC81P:K,lU77V ;p4~9/g守̯@ۯ?>d}UtǡQ=؅C˷5HFj7`ksD3iۦ Sm ߨw0mhNS~|ofSy@SУْJ?%]?B'[Q&_GiMܞ`3[M q &048B|&f:jCՆ 3RԵNp,0|nAi4B"aw]G=U$BbgM2s.&c>7w޴-O"*FK)jwckK$ӚY=89>:L+ae:P3Q)<&o:CL"$qL8_RXq>lT׮ΦCYKyvrqvSne oStxl7mlu6il׌]L1G7~]2J8L"{iLla.H ci^Apcu;Scuy0rظ|{'^:/A^Rpws1LՃ&.+jsQB%I/xZy9l0G"@>V2ZLޫٛS HL!q b+q~n$9!] "6N8odOIPBA1Qp/ro&vab$IM:(OKM!veO9c ^!;TJiv+1 B5)2Bȭad1z1S!7&~&\LU6l0` RtTI$h)H)CI1g( _$c\xV}O_$Iͽ^E0Yf|f#8K,qg֑ÐZ-vxq[/O1d~nKԅUf.zpzo~}lkxSj`+Ba㳣٤hφ*7.βT̯0GʏըU:Nk=,Fyditn4o(`܁exC54_ݿ|'Bd36ueĦBAS%TzyhtNekۥw d(ð$1$Oq4IJ0ưx19 !Hfl: S`C$Y0B<r;B1'^$*:iI`𢷱Lbc{RUV`vv>>F6J:0P&z5M̓{Z[M#զ(԰ [Qx45hröRQeYFp)beC d=طXS 4]>5ʡ<"FDeȺjŸ )J`Ncjg Q=y+/LG># a!͢)Hm9h.aW#/ļ:Gul,Kgv;n: NEcڥg^4]idq:j]m ziM]L Ѷ!!VpFv\62vjN}IWoRpK:)㐬cHg7 pAWpm==~r~MY#t^uOQk{zvGUNTxMb9@_~g/ԷJ=l<Ѧ+@F`cKZu`[3A9V%EiUNJЀORaA3fʠ- \IO2Q$YvDQ\jA'6j?muVe{&so:xT;up\^hZkV:=j#mpomP=*/=|Ciccr>k-LМrzLk.J&ۖƪ~K b=mk<9 Mx/IRC=lXA!u@@v1F*HFC lko@QgmO Fq60@<.QSKH)^J^uB2=xd$#TkpL<_-ԁɐk^oYxM å jUC@\K.)FiƆݬ BnS桐Zf%SޔLg.F'H4ZNU 戒k9Cfk0Ժ܈]EL ,/|KZNZHb+/z*]Offj|$iC׳p>x`Umi6rpP1%}ͭ-3CM:p<{ZQHwsjt6~9>3]^%mqR<0P#N>2\(Q䓿a5!5y=0`ñY)z1TxNvbG 1# x0kv4 [ '߁5$>iÔ#`!u#6cC:XhlE}-BsЫiSIҙG?[TMV. @n~n F-N1Qh+Ơcw'MSҮJG "B/.NJB]%.%ʹJ`Ht&U,O2/(Z fk>Gop^J%|p8DWH(W٭h`o8V<_5Hil< p=ʹ;wH1FWѓ9{X r M[` 'lA3a\RjXg&EYovWI%J|zr'UM?/k[݂ɂP;H vZ U#uz/T)]+wZ=wm*[9d[rE[حJ%mow "܅ѿf,Q䎱RjC@ 5q') J$rs]8'əI8mRaGk:UʵE槐XXpqNQgL !Spvi.>#M_s(OE]n~|w'# y*(gm8 bX-ek\jia,* ;'59:yk<;ĠBzIj^&ECXy86WNB$Jְ02,9Es~p(,]эM41 \i8mk {pZC~ѫL3XS mUsMJPHq2=BvA_`( '#uԐhp8EPXZ>FCTi(,"; F΢%Z/"21KflpFb-]jQݟ=_6|,S۰Ikxc0J[A qKtH| inw _7ܽEWpFp٠ )HO6P,v„c 0P)+0(pb1H%{>%Lt>t P G=-[o qv/tRSnZQTt˥&| ǭ!rj Vˀ,f 8u0$2Qn5vbΛkCFRu4x{99Me3ynmd?;Tx&M|7` tՈ_Qy D"A)M %UyѬWChƒ,\ ǯt1f8#qP*[yPxSak jS3OaD8'NWrN\~6cQ'["dDyނcpPKXu-*eގ7bP m dy.~eK| "pΨm|hbPt# Ab<cy)k4%AyWB&Je[(֔!SaYEW3(AjDWQT<pLiBz!Vv}>!#վ ά㏶Td^7Ǟ;۲el*mYSȚkǵl (RKaݶlZ9$00 2k;q!q1zDb *?x<ɢ2^=SLj ;E:W:$>`⬮FHѢךs`ɔHt?v .U15e`D1i9+0Xt^-]K-t l^$"zQ߻K{q:3fSv5ʑUS 5`iU#YgH͜UgMC&Q5^%b~TAzt C>>TL'O"=kZh̭u3I< !$?TQ]%N>54)K+rV}):qZ20-YwҶđ9:E@5+@,OE18$V7&چX)b|Dzu%=8K%ė6ՔgfŪN}+X\F9 4n7ʏEy3 u3`4Vt;mȇRith/{z<҇BsxA7-+;@OV5 /L\Mv|!/QquB 1D2u2u՚/j]AV}j`X<Xe,=wMc=F(j7&#tQ*ӚR杚u`j(j"eZ쵹PH(MN` d/?(.a4!dYܭeNݧT-kf)Be?CZ(evNskoHT;u8U<딡Z Fc2h,R3o͝px2N3t,J//1G< ֺ5} yx)Pggr5:޴l$ )I,_Pk\yJײQMr% Zg;t9@W~eas#&89FwCz+fB=Cp2+=8syܐ\Tw.&tjԹ7^migjs8 d8H{FHm|P%Tl`گK׺\@jW/DHq OmoѶJK;1詞jؑ'o ܼV0.Xs-Ʌ5a-ڲĄwњlzu%埸e|ڄp.ږŷO؇Klj" |S1>G8(!,s8ܘ.@BHIiG&Y/ahQҚf$xI6wWKMMSӤ^4 IfQy$1ڈp8m:6 !fh0*SQz=8JYF[@NMqAp4P$#>ݫ>,O]&' [2?S/$Gw? [,F9q)nzNٺ+<;6ʮ2Om$EX"4 v5,"[`(FKu"|&Ho.^1l:W~gTdٙQ5 hғh9̅kVvAHkNIz0l4̔!>hbtE:]EQ9gX`=3hYXbU`SǶO,ɒbDRBq94kNEC8k&u7*4pbV`+Jb-}hFzQ 1e!島SQ:/;x2:Մ'.M ?V"Q*Sa9cͣ$<,BΝ)ݴ`0]-y0ҺAlnB8äğz',g&#{fl$~VǞ*e|08 $KyƞB*HleX-Lxw32abIdi GT.3~&".S.U`Hal^hm[t(>>ۃOO G厊4 _ЛnuO7d8^:gа㶢%^q %#fS$S'`jrRš1xJEgom)9 HsƽdFgU?|%=4l:}gV6rO8]=x,_T^FhY ߝ 3dXԆE+9ÃHuua2~s"G|bb8}Ɣ=ҼN an'KY~;8U%V7ŝVKFTNNoE g!y-@ (')~$AÉQүe]јU4GJ` A0]nJ\'nWuPI2q|o4 2"+8,F ^:e 8q P?NlΟgNEW/@jEV9! ]Z֟Yd2y.::m]ND/BNo Eݶ"ҟE5n@:ŷu3p3>"G ej!ukR@D)20rm 7Yt'EeĶ@R`q # ltlO{{7+!U@Y 0vBz薊wCf]w6amWҚz?3}ww\Gq^·p|º_M<ܾZӳozoT -R!/Ŧzvd BR:첻rE3kྗ8غ͉-Te")뽲w$y ɧ]ŋ[&w\] VlnHf(b"LOA Z8D޲҂s3\Yv7P$J6^d,q=sP ϽdBm.k`Y":%cXQ/~8bAo@ۃEk j|j],ak: Cjwbkw8DǨFOw#!EY#4:1}b IY7mF&76K\*yLJ7oWiq=wW\h-uyC._Ee]\\B.yuvvbPY@WO8OY\W0740ETylNVrmzނM-CmԶ۫H͂= c5>z+k{~_6wV-Ps>e (q ]zf/v /x_C^|n<&b\z.k8F;$ At7hk^<_|JZp?t9iGn 5T/Fjrφ05@qE\<_emk o[(wo޶а/H$ͨ9XL)E2ʒ"OLB3\Kx\WUٞX9QbTِ $XPt@EU R׸exwd)\Ґ+ iȅ1u)/PUTe ̤.[;P `wL zOm꓍Sݹ>M/-p7yU7Mjʶshk/bʭmJkitJK3K'ݮdd쌚tAm㽀żKK5 ëbTl8HǨ95􀳒CT||Yxs=jf +XR%M(`v%ѵlwh|zJ\唘rp֝ۡeҬpY^X ̃Յ5?Q.iS0v J=>>Y׼^֞@S}$Oj֝3E/1I4O~簳C+56p$o `Bր-p]KnnX$Ǖ+0[!>=:~e5~UJ+N3.̘ōaУ<1ЀɈ0 p8kKZ$C*iL!(Pa躵sg"gny6 gSx%J.*r-Sb%kAE6E)oE\]tbbu& p`,ˢcMu' cMlM_38Th34zlPI)g:{8"a76(Ra|FM^s//h`l}8VN \9MѪht/L,1 c1n_iN#L4.9&(:kgOYO˶@` 0p野fN*]AiP8Jg({P6Ì/d 64W~—ZTc ӫg ~"tr5 +6eTd d%p%*v%7ڗ;p  CxQA4絪^ͽbȸp677UC"7e0yS4Tk3b>)i: /"Sx8e9Rl7LHLar'N A(%+8] YPY\TVJ^|kYXmv<[MTp>ޞ1\jq{S*wD"ytOf*+',R o M_~~|66I&S-7>-Gh1F[` m5iN+lm7͍棭תT.N^y $1ܧP8(Xr+ͫJʽlt)UlRAolUlm(RyY b.àFJ,d)ƜS6ˡ)'+m y@FWOB *Ck~mrz_9=Ow>蜶.d=]]GΎ"RSYRfQK h NL-^XM|KdXJ ȟȆ[ɳ&8L\O ;F%i!:rv|ꎨHWMRdi]V[n8: <Z >ЄA& zEP:FVA 8i{cJ}P{qIm$hKcJYs|)'p?B`m|~ N`+8bLxW|e2_89=>$Q) ڣ0#/EO!"oS΃ãVěѦxa+:Poz:qLWM̰U; T 4~2m5 Y^R5*Q~qUɜ=da Ak()J\` ͐\.@{St  +n1BvJv)H!*A7r]._X^f5ڴʝv,~p {TR9OLny<Ѡ`j9OݮbJW~注bԊdjBifP<70)cKlȼW? Ѳ9WpZ17~NYc>@@AG*"YZ-l+L2!n^ʘkߋr[L62K`ExYGlYoaAj,$e~OD9jPhXB&y K`y!!/s/PR<-((LɥguCwM]7srjtr,R81()QNkp4 \():4vc+s †i/[k#YPY@+xґ0Nٙs0H`0RTxd,%XOҠ_-_~,]> tJ_^x˲)jZgx?ϼzA-&gvJ2 U`uU䭏}F%N7J.孱NA>.؀O/4c69Vvƅ{H̲7Z‡>z_ۧu"ŌsIn+ :Noxˋ(C bU5>fu@u-\OBf>j'ny3_T1/ӹ/o%i4%Dm$'J8J1(E 1հ QƩ@)Q6iUP82(D]8}suÆ҂,JM̥dt̢#-MZ=ܫ_NzM*e2B)nT8]l%Y4c%}%2R4J?oH";ǣEH[{.mk!l\3͙cxld F<!Kdd[h6 paMuӖ5suHp42$xD&5UUM )V~+ JsJCn{ t;L|Fh kfU/n$?Eh*:<=tkeN)FoAV>-X:H|Y# "ͻ!\ڗTEj7*<%7$F ݘ7Mq~!ߢ씦sSWDN\Ƽ 0ds7ᨤz,Q9)v)H]C w6AE[scU}fabS~;v*iЯ^7,UĘ l U0ԍta?-,%&JCHI#F6mREO%Vs^1aJ^ćH <޵[W488@t^0W W B >Zu*wؒ]Ӆ\1J(0vԙLU_ @sЫ0@ ? @L(10 p°"ʿ#?.d~ 9 IP?T5R`\]䝔hl*u5@wUQFIEȻ"zyar $gG55~OWzj=y ;RBB )7g~=Y"(ۙG C5Aq#V邤9o5qz8,Trc}ҟ{t#!)JBSB}Z 9'⌴)K>+K+XPfMв@ $-͠pNZ30ifӛ* 譈8^ׄGVW j_sXEP3UTPB}fh ,vUE*(nbd6@B}2.6=rmH4:]oP = V%U<)0姦 =ZĪleW3@6@вCjOƔЦE t&*n(ͩ ^.*L7FB@kxQYKR 5IS$,D*"(J RiVSJT{jnCFGεn \fW}Th&԰1^X8ER2hto0p!#:KbM@5|VA䣄9/KP|o YfJ^ rtA\^LGCl-POYgx@tʰơntFwZnh9{`/2{8Lv/1 e.et)[/|=~S|i4E7bP,^ f1蓯Ơ_AzƠ}T=}fΕ,%2ZohrІ%!d י"a~Sa)E1WDƭk;meZ7ݺUPwooڭYvIK3`_o~c`u8+S]НyDs&!?H" QzLQqf|!@rp퓬4y cLk~*|cV裶42+iڮ*擒ͻI!(7f6k*&0.X#7 qJFEu+Rѐ/\?'_sN/㧏ף-WX_\srGXA?%+kOO\.OZSlc_ϓ DQ x09g!0M1}%nPk)C>”3+c$&٪pǸUι@+%NT"N b]HOAH,^XPKzh"`UL]bUcg־!$CCO7pu )`C\\$a)bSfbe:U5Q/[n24*SI# Hh$FBx&I4Z\l򞈜9Zs- /ce^g (S%"QcP ufd/B|*&1UN40fI8iakl1\f}x~fj$$^Ѿ0rARkR\ l&Z<;X|\귁qr]=qçDG@CphXU;Xn;"2[pz=6~__u"${;|B5ef׸׮ppyUP69k`|bNl)ĭc  h1Z` -My%S9맔W?opFƢ)y{)4(5|]߻^b6oЂ{sOeh51={҄$mi7, SWvZ`BNVm*Rfd-_nvOƹXs ^v( 6 |(%kp qc̨73{2+zʶ&-RU *(P|AA]x5H1^5~+VV6`TبI\4|f.aPT?5o?Y#:CWY ϔ~߬N`2Fb:6yհc;Úa,ÆVTV]&&IuzQXxO=4 +dFOA. ) 7G. xY7ZLQU6tWaGsE+ [FnHwcn$Sǐ`ǫzc778xeɮs w~L0]ңLded%T p*^tr~zwr`+Rx ]VG]}ob&%NeP@Yqwz^)V%4^h#/ 0FΞSPh@Zox7esiWh/8+ e9 K؉QmhN&ɍB>avaXq4gd`76lPBVz^T one6j\TJhxqEP_?Ow1GI͟;*V;_Ƕ5ZY.UU[~;G^/hIztKdX{WzHvL3i 7 7_0<k;[jeC[+ *2Elg϶h gᵤ((Me{>X(~X+4LwI*w9vrt9Uq{E 8yI9ۖX^C3}/~OmXۮr.X;:vvȮ,LtYOaCLPE;pRpx[ SsLQ- tmn9j1?d9r`@5;d|:l s 2S4gP~ 7<࡜b(SW\lD 1ÁfFF՘Vl7Gr31'| uYQ 7j!:RHx:Qޡ?ۧ!|k X,T ϯrcrwJv G&& ]񤌚{#N d"n7Ϋ8Rݔu p^WW ^зOOՓnE.ݮg0a,'wv^Z7FTE|$ES =f^ '_1FXi2o&ZDc-̶3%獢%g>iW1wGU;\(00{nЧ@_[*?jWs/./7s, 좃dy ;43 )V`Z h鸎(>CD# B۔0Fk9.ݫ#Y!#Uge=_tՏX &[4!X haK5A5wk *B?u/T(ޚ/JuZ: KYz<\[d'_Wk𲅬#Z\\-zX<%)~놝nt{n" @Qy^nJh=0>@ÆH֡k쳜A hؗTlyTsaG$6o&b%zD(;8-L&'E %q+oc{ss{m?ʟxTTm'-{s /#_}Dy 4'CG3T4\A~){hOɗ#(P0W ?֫'rV[ :z v$%{=ѧx!LɤNQeƫ'"%.dF,vpxk^?َ( SIl&NtQl[@ ?T8B- o I!!M>Fi׶OOV?$agKT('Vڊ/ځ|Q P`wRX'= vB=A=TI ; sȘ"2zP4?UY YDx`m#衔XKcQF}n),yPV,]v+gZ_} 㒬djEz{0_^EQ`noƺ%Q g^ԺMJ>WVέ)? t {A0UgoEX ^hekřobf$ oe}WWF[fd.p,bwZvS1}F34XwT 4OoKИ.R{ OO*"/~JRj!@+ޱ봎_"]~N5<`}V\POglX_9UlN1F ݡk@T962p/h~l،Sf!.7x>iC.36i#,}M`9^PNz(/<"x]HvTn@c:pM? Ca=&1c8߂pxoH]{L*t&Grd,`,UN.;kJTQ2WkB fAudvbck̄)R,U] 錠_Ȇ7Q!O;(ҋB ƂdPD%L(ni4E9= %+'[X^Zh6kqL.)[@aD 7oXC ojgArqtѵ|%M(1H˧GKZN4cV?l_!&u0)yu>ԫN$4=ux ېXK:mwq}˾ZoxB[kxOVw)<^0,o/'5FoѤɮvqbXŋEKYzd+uB& {~shV*aa:=sBkuVrăp6nC@tp{bdlOvhhXb*AЋڲ :=7k^r'uC< vAgPQM r>0\YHYAw:z׹o92C]A!7 A?dVgF^=?WW/j'A١ڛ}4jI@ޣpL2w4)~a^DG\8uaȨu؋2@X \x֞$T 7b,^ hap`|<| 3.pM2W lSɆëVbj8"acӳPC! D)ؐL74nay,}ꎖUtB"!k 3MQCda?,(m ]*o;k!=S<گQs@Bl0a )|t'a(h76u, n9:% 4i%qg&&wڅ:%1&PqyA:*&ixb Pp?ڝΘ@gP,Ɖdt,+ǷeP5pq€Bϭ|}e,ۋyM"Qs|uQ$vԍƑ[v?,M=i0T KmaX*ڻbgQ;d:D'-B 0% \&ތ-ȑErm̂"skv~mhބ[$ʫCA?dj Z[)PRq,ϲ\ןsSnmB,[ Ȏvy'1NoքNg{q~ K0ZUwU]|"/\i즿|3|_%&\Ġ7%ќv|+Q?noy1{yAnǧQ*.~Vx8K۩N08r{5/E@a:-6,ʬW>V-:0յ;C\_W(oah^ru (Lxa° _b{ 4IÓe=ԾM$=҇kS5cZbM[[=]"UӃaz kP;>;Wa2ӓzKAeaa$c5ƇŕOpئiq1x,.zU7 l_1(v(~WT/L|AI0dV;" ˍ,es-^sNbY´҆!$p2%  Ey9=^\ DڂxV Ciz3/z>00ƞ;Huvѥ8PٛGibgѢu {pUObҮJٍzW*@EƸR(`imD%o"t%rynX E) Ɗz䜐F;B L]ԓe5-&!d|A4"n׉rpm-PVH%͹pY,Y$Ho xr+a?4;(o>_o cӔߎZ]<i.ky49E rq8g+HUob&a?@1<?&hT>D7a}I`}Q HlT p6qJ JPLNi[kНPL6i!E?2e }|R YvVLa;ۨ~Q3Sl -Ӹ|#g6v^R Lϲ0>4-^ MMDs  iiQ3-ǭ N>۠j!} !?O9T'/rќn&S"3KU R+RV<*gK ˊW2ē88T#}:񒋊#`Qnདm۫C9S1t(#VXr<Ȗr9!'8yi;PE "$8ۤXcsI8r*Q} E0tߝ^5%zLVE!(G&dV6þ4$ 7μ=3E}0WZfqsI3wObBZfighP7ΫG-zh$ ÉN6X8\|\Y4"Ro\ ?FF!_RS@0!X8_L!nvsu>v#͌$z: >o'**bkdC^ X[-ؼ4ic ;IS0^+{ w@pN]P9=>+.V [u؎ oju={2%x+,lʂΝM3YmI ;iJ+\@ߠP-7Vk$%^hKA,IjŤ9<Ed0H&b9X JabFU*rc%d@v[5)ow>v`VY@Btzѭ[k'u6ޜ;!d%gz6 &b1s%[ƘOUlrNh.Ψ `Buo " ԽAeS+72}4g\sU!zbs>o=Ӡ}qC *Ġ 335Vٸ$P5~B\af 5 qUxfGɮa\v`SQawl@;*Î{2R~La u83]QW13+ x(w`>U՞",# H7muV$X px9 =CoҥGDhCe'{Q*%S>nv:*:NP itK[ 0.ߢ,K"ǻGou_ttEh6N LϞ៶AۂHOM(Y,VjɁ={Ai+v3P e1yL.OMD X cz Z.qs0,wŰB,A4.@RT`T+\l9[qdqYu/s$L $ `hGqn;1^6iv˂25@%πST_ %CcjGC rX~< iV*wD\0fy-"4 ./w=%5i:'Dls#kp9q!ԟ@T84q[AeB+FuaDlp276viȂ &t黳yv: b 0KJU -eARam- zFouMp@^A d(3`͚ ] ecۢ!6|\JHc7A!0>a UO&4*Z@ i 0p0nW;PaY/joku't~]N଀\ xUmBfuAӍ\:#k]Ir'Z˸b֖Hm5 bxbwxcC&s^.L"E X.GZ>`ZOsXC +NmqJ'Xh|ر\!f VnvaD|'Ń2V7 l<#XL\TM 1Ē 겁xS)p-.VǨr$|[c0KW.ىB]A#[?_8odR%>"L ź->p(85@ũ7d*iu#"POmD^2ׯ2-kH-1e I 5ho(D7h>WLTS*maaY+jƌ6 =r*PeuR6Ud[Ğq[2WZC!5HQ3pv-_KվF Y݂ʾ⓹@Q*ʅ\5xLM&Rorӄ} H5 GiN SC ~:$ب8&I98wAv}]]^qnz2A h mI~1#n8Ԏijoz@؂K+Z6](ѽY,ַr& b&!93#_L.3B(2X>ZH~=V@zյ#@|ˀ^B1RLUC4ӠA7j/۸^ ׂm2&lKC-Oᄢ~WB }N79cT'pIM=r D2?".p]@w|(hğ?D%`_!`3iJ@{&P5oeGe0tE ePI*hLh!Gq?O`QK| prl|,s M _7~DKAl*4Tr=[ qa}\ D*tf?/u/pݕW7q#.G*wڠZtќ\a9<ȧ'A෗߸!N7Pڒwp6p.Eh[֏(A\"_칢10'}2ذgW|0AOXWBL5!9̊\ź$*o<:MH.6{!b3UpA%DzCn>8 5A3\nUڮ  *I')}h}\H"JV.^HjAθ+fX(09q.Pט{ wȯSxr9:ݢmh#jGsgf^*ns#yk^YAØ)AbXk);tCk<`% 틢kaGJՒz!p$|$3$Ɉm>`P2B z*[Ɲ.L.GCp;Hh"N"Rm"nXNwPY ).(8XpV:ЊʡeiumA}(./U\&!q8tveኪ5TO;=/[,){O^?I⧪}Z;n 'MguV9jx3IgP62oc!A>̣~`11i @f,ՒxZ"9@V֐55j+G49bxԃ]L-[m`}H%8:?Ȩב84u\525 ,Fp?o!h5uyn @5m4p\R=x|ix/^. ?NԟC]"Pעz_K,YS_kE}WAW^UkꫨJꫬBRK zH!0Q/Uzk\Qo׾:P_Uu+Uߩ:ҕU:U_g׹|^}~ԕRW_?+EW_+7T\M-V_J}]U}}Е*F}W_} C8R_zMԗ^a'x~S_R_u'= rml0u,ƒC>Q7#70SԚG0ԛc. ˵8V =Wׄ/̵Y AM$>\`R^H I:I>W0+((n DP$<0h8igŚ7}aA\KSHAh!v{ QQ1}loQj[N e=yo v 9w (p=qխExV P67?>4Z5HJL|L^g j9>rU"0 % Y`Ƀ]7FС+;:4U vMWꖡ|:Ѽ)%=GX h~7V`5|ٱK°$BLB%`6HW4 L+ ,QHD^`RV]8.*9Qe)`,?g7j JTl†@b=(3XX互 ڟu5[op1se >UTzt D{ǧM0;zX)gQJESߙH *i+85L%#au Q?#j\[㩘3҂LT*Uo~[_n茬ƓZX D55Ѽ4|R9[*T$qL f,=魭]H׊mǪ$hJ S%;yٻs}KnOj7yV_CŰ}l%{7ot^M^cN0 rҮl9 ة >/Q.rJ ˃߯L31= ;L1X+|{0h, #5vHCE<7S0X5{4:½ɰ?\Ese뭈WLE䵞[hl$ՂKHf x1#Gܡ5"mH#bb*<5`V(g:Mļ2@U?fL`^{ PNxR&h!jCr!Li)d 0, AXNN54$a X΍\PvqWaaU4C؞0Q:4PyX&/d/.$5KJ?pTfe/0ODlХ{"" 1{cMvFmttL\{׎=-9tBϱPEQo~t P)=aLiJʯ4`ik5(Tߝ{/Ϭ;}̌.aa$[3a&JS5"5K8>,& ltp/znxRޙL# 9Gayj+&U\-az0z5^j)ᇑr&i>ؔl r"߈c̅w+B*V-,#*skAshvzo/(eBIHp\0`0 mW"rF]75O ƏL?A>ur$t3w'wvlkXָ灎7@S{ޘ5Dz]ǂW)[r|n^F#(sr޺d*Ta7G&"`Txfw$ma>`I߅6XQp9m.J fPr|:,}.0Nisi(`M`%MmڦF_Q#6CUy%#Гڕ>m/N'Zhv/4[ķ_5ʃ9yr"=4غ:&y:Lo-x/dJ/f/=Ϙ?dh&qZEb>//1n61Nkw0BJ{d Ft~ef3aM0i܂: L-D"!̹G_<Ψ km) vY꽩 Z-.ZʳdxPyѺO TqU;w* Ӎ5KMW7> Z^_;(/gŵzEZ肫.%n`jçY{JYy8*k3DoCGҩ=C%K8^G . ~]jMCu8^C{J4pP Dfnos2XɿYvh{ϲ2=v2}''̴jF((h*!pQCQF){*ȶNT HvP&Yd+,*64l%bލ<J^J}v~+x eC|tj_ EwmO].F|`5Yf)XR>p#wݽݧ&+U[;0q$7 ԪҢK]j"qWDvAZ|b~RvO"o*ef' -;G4:}i ]/Rs\(t)ZXLƂDem#}&ʣj 6W;$w mg$ψ*$)_.$oJơYD\Qy)0oCiA)ORc< gOgU:!t@A\~k$lex5_,g9WujrMF1̧O@'kۛ?T.o@_z=>FS俭u)m(mO{tw ojbamX-uBF܁Zd1x=^ޮޮWk~igGj{^|ɼ–z~T}MDjM7?QȂG ZA~@yB믿gA֝vq1!ж@K';_ўn8D]z1d4i/;^U2ߝW \HC<9;JapA e(rOF T ҫkы@~ޑ|QA1n- $҂7!(PF㵫 .}I(gynz[ ?+m˄ޠ+[ ^yM.`kEDώ^Y;" K\*ȎbY7lG2V<،s* 9ޠHBcՑ< TD=Z!܁xo>jeWׅ5`tӽ Io8xnFXI`OvZlGgz,l?FQvϰ*}w&P%[D=|Zf2n嬆e-Mjbη@F<:-,"Q"2ȨejPunF(L]|ϖܭaHgB|00CWQ{C@JWDHoO{w(}U%Շ7.i_[=`:@\1n`1ze}E.xuQ9> ?Z1n K9 dCC^[NjdMASً욁BwL;ڢo\Q !<50D .EbG( (5vzZmګMDtjrIZ}~;#D8;#|baee*o/cP[HTp1,*#%=jŖH2o뼔>q"ڷK'tE&L?K 8/)"0iYiBiV248*D~anKaZFwj/RO$GFn=CӉ\ zᅎHu 0:z$Ir_]6҉qa qwFAf]uExɅ@މ3jlmTKڹFT- OŖװf'g[/jm̶D]XSBAI` : 吞z­3᪄_#q RZnH02 c;zezg?^}r7!lny!cK(MפҰ&t[qv^.;fi8)  l}LP<jjvb`ԟ (zSLF6B%cT7 CG)Dկ/4)Zɇ'0ߟ+QUd S_iUOō \,7[[u2ggC93=?g;8ϸ&3|_zL#뒋vG4;ګ\0zIʏHe$7~HgƗ-mykqVTNnޔ'iO.)OUE=ܿ׳6DPQ+8FQlZ(<(rtwGDl&@F (\ ME싙b^xVcuSb~h#_ ,(TAгu)nI[dd<&`fVԥ߃̔{)X?EG\p'Q'&^@VLA-`(7`rz4U* 黓ƻ,>fWgt4w#;:]H0+vR7ꕷ7WモYDȾxmnR3;R_pޖtoIՠC ֯rUvdz vjrptfGXo˨a!T.ΐe1i=z#~J` 3ocv jm,#Q,Oy>[Anl\0p1ˆ?yb81n^3y['MXAj$WO ŇՄ`^$Ke'{>\~TQ[8RE0X4(spQ?kE*׌.Cac` +&Z:: "n ZYJKd#4!7]3Ԩ'޼W4*4Rgp|w>ʻ#b=>4 q BUL[Nz`mb=6mw`_zsTMU`F:qnalZGa8>5E VvrsƈNq"o=(̯&(Sb>G.օtzҨԫ'&7B:û3SA;d c7!%ILzR1ƂBc~&@ 6!VӊࢼrĪˣz>Վ)S; )_Z|?tYæ5,nh JlGn&۬VE5 AN؅#y 3"䱓bL)֪rM]ق'DiXq7)eI$ ':|D n0l8484|&Wd7_F12Ơe0pUJ PZ9y lYmCyF^ŀr4 \&يYm5t(Zew=?+n# ~}<.AM+@ڿ86r3WѸ1T/'j V^hC :3wfo@е#g*s_1^0w:v#q*md<%dDQ{$364du]{F-Kli"5Pdۃb!ɮCxhJekʶ"69m{z*ߍRe Obz$#ugӳU'v"<=3a6މ.!P?fvQR?B-8cɪ/"v]%d|% 3xlfbݗpҁʼit ws;ڠU0G8%$q;G7).3*;Jl.+ɉsӣӷz^ۿ xE~f`Qv9gbx,}0 @:/ek'Ix`hlX㲸MZFN>,Y[;G|˫BvC:pNT ř6a[2>> PCB<9e1VPjGD ຢ:w تAQr5k-iAWzIut ]˖djڥtmlԄn'&$+ BI*CؔbZF[J*`'+SKl ,(%. MԚypz_ Pk\ LlYpZB-0*&xD6g]s@ T,ct܁k㆒n9fcK323(gǤ+kQYI<Y$m8}~4HQ*j%Q4) qLH޴JOH+Ȕ _I-fd"-mU3^ '-o#6tޣN"S9ٱ)H%Zcr6)Rj'KصL7Y߂ԇgiEuF5abv}CNoK/euKԀQĮg(iub(ƒS>d1H>k2T쒨||c/U [v*empHhrj!E05zdٻ% ̹a+3F Ve,VN;%scu db}\>y6#G a>2-7,F eS=@3V CWo?1‹<\`{~gniْ &F,/S|6Ίm8kT늬oILH| NJcdLx:(-۫˪I:|1qL4dn%JI@G]Ls2bQ6S`oFcXB']&w݌"${VQG*-VVyJRM7 C$"yJ׿ņ̿MH2^+pڇK2S UtYbGzZeiՎrv'57Dn_?ji1/ň!l|3 -y -F@ {=WBJ<}֋moǩI5 悗lY[t{ ޫF<b^'$ǏC,dy5w9㳦/$xvg^1>7-oy>9>Mp{ óT<& '"A^F@JBD`ؑhue=i)7wރoε7N/kF}m_M(Ro|~4:%{'EJ&M%ݬJKL/͘Rrq{3/1hYVqXZ$)2yw܋9kO9 .q..Ҋy6H3OFl"n[| ޅ;'ϦI~;CsHЃ=#ۉ;A+Ľd:4$hěUoABIWpڜ~~>bMM㪋~d?9 b SyT^%+iޅ)nhB^Ԏ 9q7iȷgmCNO#:O Yܦ1bވ'ڢLHD^N1R-[)&?N2@8qM*`ZvbJaDN资4VoK7|%sXb'KYkD^K " b5TZAj&/`ڐͧqg$zK7gPJ"כf809jy$ᄠ'hAwQ|lmh zͦtlS]İٖ%B rѓcF]ߞѸ:[Ah5& q1RHFl,d1gvwWN.7 ez*6"x5a9Bdə)91>@v( ȁDm-NSfY6],ðlٱ+BjJ~^Td4F9tLfʩ2uΩXzďS`[Bi Bz;HuCQ-c=>'uқ#u„HyUsٽG~**'9hS՟V!<ՕbO2қHnrfkΣ"P7ЖAدX} 3 R:l3>CiW60c,6.t6i0abjg@n?Ls/8lK d$g𪸴'z -S#%Z{oɵ<?,\i`q$C$cafeSc˲;ZI(H5Y䬦+ev--UY1Y ӵDԅ@+w$GD&QMsUIJ 4]x`{$QS+`jnL+"n "u8^O# Iz*Zk-hR)B5D J4+BaPlPE`/$QEЄoi%ͤ: $ @T6f2Z3Oa |\9oqzOW#hbGVnԓkMOc$YR|ͦs pb){"yNqhu3f;" 0 H%œ K =ihҘGB<.YXW`oN &Tώ,mQ:G婾A%g UQѢ!^#ve׵aXFwp-54WLSPg"s}Of930FWwR[ ,ym|Mr(jGmvuƦW$C(0uW{ |PV-fi$,TȒYze^t!$:D5FG|`67QOL+>jL(gpA|Y2IV(v]=d1:s~{|ꊁ8bpnK楢L4*4TeM#W lUbrوcmQp@na2q"$γ %\&^(sT<f)XRSN/:`ə]gb; z˅V L$l޿hZYM"n" t;2YZ7 Koܯ(.j7nr_'^_&\~qpu&rs'V/^ɼnq WNf{DfuεoM|SFW xɂ{{9I$TߪWIZ|n!j-|̡dn^z܅"uc<*k=ޔb)br1,hlכ 2Zh TBMs۬[PyU]gJ\;:dT]ac*F&+jF%|6S Ly'C!K4kv+#tJg#-hA҄B Suڌ/4D~@o3 ͸~7BEڛ&  48,YY1g{Qd_;[ɏ9{fay`61lv}v">g!xjzgN3S/+8pyPBUkca_ v6&vstB̪xE/ H+`t ڂ~ GXg5ׂ,q4.|{Aɬ-㌫ ?鈙#zL·\SHuq/hy@^\nI #gj{Ѱ1+-n%icBjlTk'z{{N4^GyuEHvmIdsccvSvELUNRp dYv?;nOWp#_X@E@"ٜbC5ZU%pI噔\qa jKc-ϫ4ߩ I3PK5׃CY]ʊ~pA^&/mu' ܂e銝I00ƈ%x+Qodߍ13FBe:89)=WsOc$F c4K7<|hdgk sj.RrZ*0geJzeWJ,"H\$ ʷϳjzsꗊ 7Kԍ i,*TƂQ81wh BZ HR迫f+.bArTf1tI"GĒDY9l3=fS*T=Z,[v4ݞd`o,+PؖyLxboI[,+t'ޝ7srm-xBsx׿ġ)!29%<:7ׂ 0|b*lF*Grn*+8 켩(Ca=Dy8HѠ_:a}y'w9u@s^:˄Nc/XBKB^Vu4%Gmhm}V(gyr4=i~3dF)6PEd\SaqRNBAx?rxtV%OxU;Ċd9YւIS& = ++*)VTfڐnDі<*k~8わi?9) 紑Kyt^ +3Jʆ8hw`3~@Aj{BCR\Gٞ^X$=Fm?>v/UTi9pT=.vQݯ7 $1\ r`!9&1X1(U`aqY(h [hD pۻš^N7GBgÍ[ᾊ QAWaw@bE:b"iЛt~t(q 3#Rn)AxvNȤ>@ 6gLIJa`H\ /p}+(teWWT⯭ɓc3熃,Tփ'I5>_9u #JFm<`uyIi (&QVodN -zS,G' l'Dc7"ȑ ލ h~ph̓"o L>\L}[c,&ת !Xte nϻ]yl>M|gr]DksF4 t!' eŠ1q4 t4j+Z4ݟ;W{nJ$aYE_=TM?J/tˬ EmwgG F\r ϒE(hgm=S4*z6]݄wͨHddO4&~4+҄_y,2e~jTD)Ϧ9}؝D6mrX#=GP}_;UǺS{u } p.,q !ӓ^uI%QǷ8ajcBKjFj0i>(JXum܍"ac,"Gg٩P y5! fDrj}LOMIs&f"A+j)_-Q) ;ְ0ҝoYZLk+b>cJ[{Ff6l]3VM,V~VrrAc$xy3;.G $J< >Xy/ep%NXn&'Pv#jk9ONNʍ7vĬcO5VwW̌-lyCJ%î xlpmlsuz ԍ&H|^T"" /f3gk'e OܼIBA%v]&? 5Z3>bIְD,P3dӢtyv^=,K)Dr60b{4#rHtZ] f]̆g$.ߤ&ZŢ>$|琜N0*'yա6Th`ӌI1&ۧNfc߲4-צn\ax5%rPM%p|ՀAŲRT:ݰ!!^r7cxfM*-[.iJ֮p-rȾ1&-:C1t1o:k2oYO lt 4l$./ٌovLN6v0³qO(.\q)5e|-4A -K(5bQC}scsaN<_Eu3ӄu=2Yjj:x"D@eq%&#]EcW}40wr2be KRˌS -Q:mbg40%~gM*!?,*CJq1s#F6SsJ]e! J"q M dH›sᢋ"jaI. q$CM!uDk6oYo,XۨKSezF 6O# J$E1"ƪ{d3n~93qHJmt8F{[%Fni6~A.~:W~q㻫A ^5y$EhpJy]s~wR[~pQ2 V._~)mpkFBݢ#Pi[8naB_Jj,xZҋRcƀhEc7HK`aXI% XMэğ-C>xyC%(*wtr'b禜r3g+JJ~ ّ|+a:}ww/Ȁ`גA/C&@F"rm Jj0bhl<ؓK71FȗFtO)7eN)fO1ぅ= 'xX8jd$hL)E`'po(;9^\`ɓʑz.*|$7sRzg !L{qpm̒bX0t 24R\G:?GK\]I|D?U|[0HuW#lc=92J.ߡ4uG39bOO8reYԌ֡| 6Ҏ0:h:_֠4^~NN8Q4K! Xyy8#dCKbiŚ1nyQ]##TysK@Pi&QP @jK6_4 :5dA=ϱ^x&-'i8ч4;zr›P'd>r We z#*4{6xP b@Rɍ'3x8=-@+qDڮZԨ)1 JvD_"fXb&p~(=iƻX)H<+L瑽IF=&" Ӟ0 =Yث`Gxn.Tac/MӦ$_L\cēҟ'b@;LK+cJ#ƛy|BY̺B(&.bZ_Dwρ e >!6pY=?=."KrvA5VSٿg L bQZ$oxFB,3cgQX8J_c~ۄ;}8{樶@F@@oW&|J L0Ԝ!Ή#Zch P0:aԙ0)%2c,IJ~,c޼*PHgA0ghꊸBV =N^nƻg^ N&֘O@qK84S 49%QyH"̢BMZ(7^HJxiǑv2čTNY_/T*rM$v"I}gzƃ{G_9{T<(HAiDH4 z0LG1Z+& b#/ J.6.)Oy>B?ߪ2g;5QS|q؟9MdXRң,]c1ÊL[gG5PtK=ϻyRSo>vz:Kmyw" L^F-Haqz8F8vwZD O>\%)rU.zjʓb\uoڬ} Kܤ4xv8!2P ^^aG5 fċ}ϧpN4SG!QjO걫h8R+ z U445o^\T)>Hn~zЅ9K0fTyz#Zb.MW#o9E{AQ4'7$a*$H^|5{Ӿf{O+v:nd]a fkٸϱuI7W IǞunVOZ A/bdIU$6s2 ܓ[ʊ;3T\9\oǹ^9%$+u]m }z%=ѕ&k#W( ampaor,9-+Qc۰ލia`'̪δ7}Q%H6oOi};Ľq(| 35W1ptōD"AOx5;L\OA6ݳ q 3>ߛ.jT˨zH/brft:}>!N+f]a/j^׍Au#fO႟Q.M}1)JzwyMiͨy=?}wf=lFaKμ @NA~i2 qJډ5qc yv9vcC~bϻɾL^;,.fu} ?iM_'z*D {}#޴s:}&;v<`&k6iz֖ z,2Mk?W[|pȓP:Ͷa r*O+?Uk*`l[$̢晦(e ՖAH^k1twaG#Iu|ӊj; K: h%s<6}0iOTy˃wЕ6Oޛcoٽx)>MPm\LMꊮj_>z9zjgʱe~XY Qfրy3vq}WNSٱX8sjCD:m[ɑ3'Zj Lg'L^p[o0ěh?b*k>90J %/YM[avF{J|3) &QJdpzbRHFW"re 29'k(E츼pgnܸ0G1Y;$)'&2MQERgan/n!|m99;==h^Hs3GPD 04^E8by{Gp47oD*>\hĿVc9D]ĶO\d}ƌ:& 贘Ѧ|7{Vǖ4R;ki<5Ϙ˟%$j#>N?_~pKG'&xjb%t7I< ;plUci 'xDٞ)$ mɯ.&m4PrlC+^"~2J z}%5`$n, oA7P$nL%v@A0^y?.@, (sV0cR0 G%@ [Q?Ajb[A{2vZ! }D^ZacyidC |Reۺ(#ZX-޲n.9N/AIV9Al>sDެKC͋I;΃ ۴-ًMCMZ {o)qؤ;w1jr"@qg>ni\rY؂q&6"'W{$InVNw!ftnWDz0TLyWo-dė7痢:OaRI$Ie5ERHI#$|~-m@s ]PH` *+>_E3$Ձuҡ>~U_&ɛXsyFƻČ5e,1"4oyz*1~(pQ=SR'.?yc6\|רWz<^G<$} ZF;X`陊Aٍ sklڵъGXiw,/ɰsdv3H0pbg^0\(Rp gOXf=#!@Gٍj0lW9NL^:B0|I r򙵦,(N K9E8 1r %hoM"cƏ^DI2ű8,.vCZIo$qNzTX"3hDh2ztrH4AoY|XCϰMJ-Qԯy"Z0ȋ\™!ys?M&ٰ>E0 ֐ Y[Td3uH$(sC5E_'26jV@MNN1o ?[َ *ܪuM;Xx?iK\VϮyzL_IT;l߈G e|]GCkI1fYXYQIؕ~ ^(-=E2_< - @vadQ[K:.,W y`XY߁(qsg6r("9~'YF[JGֵBGTLOb![1#2Otb]O(c;?=#Ho,eMo|=}Z0-ဧG;D7-?"%@!.Yrr6d6Se+`xؿ(INώ??w&ީQugyV"#i$UsVNYqVEgCc;sl@0A:AnowxZ:lW7d@.3>vFj]{-=]]Ќ@OmWMdֶ m)SRۆ4Z/6Bh6Fܬ),w17Evr#@hl^йaǡI~V2`m!ZoeHwlR@nΆXtRx`M3i@^ܹTFA͝縺g&<PͿ!/FN֔O= @ #Q)X4%4De fUמKR|[1OfSNg*qѷ&MK\TܜݓKѰڛ:^mUD Yg1~YJ5?GaWfXt6iIJ#e4:V@ ",f JR~ JZ{%]Ă~sQaǃqN#|rURl]ИFY7;ώ$9ѮvdvYOl +n:;Th̅n(X]rįPz̋!s_]ysQO.LmˋY5c,/> l-F(G6ӤiD~`/Y|Й7yLrD=x!IĻ⛆q$y='pK< y8&zџ}]UP;bwm0s*3VVK]2&2捲C} DdMmK3VTTk1*15?u;ɨP\-u;͵ }CĉuZ+Eڠ᯼]SXZ/[*Ɵo8?rM֖34('3wazdsAigEWwL~a엫ax'9 npן;#n0^{?۝;LxoF%ɻ018괢p$\FF)N =8Cd zЮSpl,C@] Ǻj|z\mu~]Jm Q0En>%jNՃOI](9F 3Atn4 1 eO+ojG08OyP (#9ޝ^TW""L2:IA/v4; 'mSVRu+xE&E]tވ^F^>Z`s'Gxu1~!`b>xq%RT(jR2ZIѸݎ.W_[@NjϗB3xyB/EŨ1V pp7fxcןF <ȓv;LQɍ[D&,oTb,/$.',s!h[s i,,$DyR $qDE j+!xN1Q>ZЀo >wIM=VзS;x ;k1FŢc}} @R86 $}[Q냸^|ۿݙz-۹.gRkjID]j1Nda-4qщO:~u¯r',+;U5>ځPY9`caN214&K ufmhm#9l(ggRub>Ok<{N%;^:Lw%Y;`śܹS5KEu3Q9̪~ f ^U*KX368x>}9s!˲hN^!&68)xw'=OM4j'GZss֠;a``qرSpQLuQ {l@ZiZauvS pmDvᇠ!Y$e5Em):V P(x3/tK.1J["r9HVgSyi[ޜ#5ke~d ~X2)Af:B-O0?iC;bWűGpu=DeGgpnw}&@b%}:6\T]q}҈2e.0ORwS1w@@E\OY9}N*4 nߌUd5 j\ܶz u(n.Z :h"*Ԋ9^ cGwF*:]Bi:vQ<6ܖu3 ^^&}iZW[&殺gTЬ5;DocR 䙨G]5G"3)t|Lm؈KՓDjx@$eop@{1]ag8ʓ(( L508**h]i7vDx=Nbcx }EyftXgN(9>yՏ,džt_1v>LW1gpM_BӅQ xrJ(/  jp\X{I"*({ 0@!4PE_1Qi[bP,#06(|<>'=H3 ei ɀ_:PweCi t`]sMYmf 2B1-t-lhߌte/"Ƀ2Pf4R"vcx+ ClD!*w-̓S+iQR,|A%uaG 9Y EJDU2̅!I9VzW5m"˿ߺow>vf4EL!4xIxBm&OSCsܐD˶27P5ȡ짨e oItDU=Op[ N]\FS na~H¹_8A4k"hD[$ͼڢّ !8PP$M"APޭ>b&xj!.9&WVLZ&A%<(eN3"ƼL`S+XSAv!p91|"ӨoLs_z&W0+MҬ'djM5_[u1AX>J;2BY~2؅S% }%M+%ˢsI8ro }&%@&%+!YŎ l-7W#E3qzD~A<;-<))#}Z< %~D g[[FURBccQ4_F0X+THBREI5CT*ME)u_0uS7[qXVi˘+<dGp-*,"ӥ<[w@ iwCH'@B'=;SJÊ]ap2NOfH-R]fLl"#!j^vab5/A?b[Y.  ѨHf594o܂Rc+BǷ)B 2Trc%s$1,{dл5+R52 w'+-zR?Ѐoj"rUC JuVckAtb A蔺Xcu[ s"2̫@K~]@HZy\7X%dؼ!p VgMap L+:2x4mz(4OWWO*4F{T;y|&nC \'O7oz]*m͞># O6iD).;bTmʻ<T `>`PZ}`4&ьU\PM8>0WFVMGGHN&eh@Z9/=7q(^Al#G@0F %nx Aqٵ@cRH+j) \]?dcJ +I;7mDž ݃~Gt4VS1P^Ht\I=|EH&V %T'ea(1f%7g|UF( pEm$5 |hn+ }>BW2);R& 4Kaa5m5aiB-H7 ڳcp)13a&:\@ՠ Z0Q(GmļZFIhÀJkk)(J_~e2rCuKK?3eR)_5C6,=1"by58YHz, zi֚Ps}5kkL$;V(x!_>X\Vʣ=h{=̶VPn6j:͚fӠzKcR=P9tDžNO-q=h7Or<6lP5PD7ZD\ML oys%TLu+ͩe^mfit2 |$}7컑'S. 9S@l3mիԾ?="ce #*aPS=$,1B¶Ăw&V3cDl)DDرJְ b D֎AAhI̙)8i˲p00lϋ݌q兂@=(LhwһA4|-ս3Y۞lk=pg4f7e}p#yC_*wEQR>?1sPXlG2)=zl3KvAC2_ ); ~۞G  IBrB!3Sqa`p۶~T%JPan$pgAF0 /1K$)9č D˗@\1d|]r.TmA-k3b+xdGT%$~6& ,D#!eU+ҫ8'NYj.2E)/Y+dq u8ެ=m"wsmI0ϔK4&MoVˎƒqcjp*y5:3u2Cgtk|OF;}- X=f{22=S~>d&WۚR:޶'ބ툁()pPQ:Ura4*&K:r%PŌ%CB/W!!&[A4>w2rՀ谫iQ# 'ͣPwt$VV f$PnĢT q>eG 1rϘO#PڻZwP6-nIj:EDni`!WIl4mjHU[_̐z/]ƻwHI_}svu2=)XveUyB Ww'7!qT c.Pl$%Fl ɓ}zy7 tC^qɿ mv6;]Bȍ4̏eMkMGDyS2K޺jG r_&4Fv*rMiBil`(UQQ2~Jj&c'g ޱƟ?w)Kum~oX*7}cw.Al;/7m'ڏSsƿf[mW'^g2 1hO¼}Hak5>+_~Yޘez7㰹n!tRiUF&SDhM}|?>ML M7]<_*@',V< ՠL`mh1/PH$tkX/׷jP!LZl] FɰEA!X[#n/זMz(B1E=?M{4ȋVW[/v, )@ [eM%Zjѱ?z{vDy㳣 Zz$*[G}92!Le=_)S:(l @ǒ+a|+h]h~X`|΋ϗ j'5+~*7Jyw35n[Hmo"JFj(Z( NTJ EUZ7S[mzY4S/M+U[.mMn94a(7"ebŖKEh_(Z"ep- Yp޶Zo[QU]( o[VrcÜɍM.i/m7ZfjkS_XMNoDM35ެ`۸1R7&672LLnrߛKN,ֺYv)ykJԦIq[͐S╷eC^RMllELdi(Rw﬷_;[\%X;&JޱVN(FӴ6֯-.cnԶg,8y~v.ԐC+UL’>,Їe}n]/s꺕ʽoY/8[#Rnns/: yFM+mX y~Bk~&ݴF侭y Vi 4-hZ3hZ3hZ3hZ3\+Մ)i2D7M77-o0D;VZ-XؑB3ܰR_p^-4ۜjb3Ҳf\eH$Բf3ҲpboYomuٲb,b,-j[L->[L-{؊"+m +mJJҶfymkQل,(<-nf<{LlxvҰaTkcS--kLMV,SQza+ܛE-SSԲjsoa]d[ֶck[ckoǍb=Uzw0A2F0΀{߄+wJxY*Ũe6(| >K R'V{W9?̚}*9qvlCϝe B91o/~/ &c\Y*3댡`R2X r ֬D|4ZvyWҕL-Z,D&kF$#Pl@'轞u}D_gWҨHTn'҇JMe\8uA@d{ jw[ܚ\[l xP{nm"=7o?TS#6ޢwo不%nя['ϯ:p`h1Vi,mo?ߓ2˛t@(zC&h8ĴX,\m~^ī]=J'_hJM3Yy5C@A}QޝEwDzi9ej;*g_XR AsQΎީr=㩩WLJ%5ZW٘ʋ*G'qM֐8r$Fθ^71~W1//iEH"u'WۿWmܯc;7~ k'Yl3=[sMg~ӳ}پl<6W%} 3 w+ԩ?L핾*AnIO-?w)XTSJ|Veg?Dz3X*2X*icIش+yL JD=c0o V'4ol3DvpU7zU7^vx=["?~7z?Uތ76_Is?w.{Ǜ902ODt24bQ[Q7VGUf2%FO+9W ݯbup_"'⧋zQ;枽{sTOʥVI\ǹjrw ?2Tiay}ΐVWAZV?=clYݟsgδd逋ļӳzb8g~wZv82u]`|03E8}|cÕߞW) íGz­x܅eNA~ 尕vW t!iʬ2R;Nz?|i0h#MTϡ,_.H08UTD9EߢbG3@[UA)`%{Fzq֬,b`Mm~ӞPSB(Yd bFZL͊kcjil6ƩM?)\o}'I-S;xzzzzܚM;(<$x_*=ן|'IϕOB=؈*Kz-%d9mYQ5\T=Y!4?d'i:l?!.:C0߬ERo[V4j,Y rFOnVҕv 9+q/>sɍrFJ;b:ڑT\&Q#gHsPt,|1 J& /gKEXP'5Xcaw9%HF^w'ؠIب33u1gڏjlƹQB8AӋo~ۿŷ-_=+,qfBaC<e=GnynL[6EGqa#Q|"ťRNGN:I"J|*F G웟؅"h..wp!fp8DAS?_`L")Z_jNpJ<{zH@{h.bY`ph_,(/? g_SiK ju̲伦M 4퐪њOYڮ2!ES)3ӓr| ǒ_".c \D+^V 'z&1q" opu8Z8iC`> 7s\ m-Ҹ\4K hZB>97Q#/%Ad=`;·✨u>u*Nn3c@d0"] sᧂqg-UI^Vi饽E,+xk 9uupb5 =Hny6o6ڳöMVҌrcZOz>^υ96 WBL p^D-:z@ʳ)f59? Ƽ`ْopm7E{bƢl>jQثFFcNCX$wYS%z1sy"xWMB/xn,@Mu _\{zʎ( X={vfVϕp|(Kg6K9ن|_f>l0Mrf1!h[#$/0ldc $AzM!T8XR}9i,Sm.7E8 wËs 91'la s`q 3~?6r?OP@Yce+M+[XJDMaEI3Kf(4j]j'HHXM0~# Un&>]PՓFѮ/G/j[Ɲ WD3]Ybx&7?ѐZ0*@G`Ivz*[NDGnb=lK)G1?}}'ϣJ8TCxXI XE3r<th;*Q=NBT{% /|ƌGTS= ԍOZ׉njECi0bfeɿ̨TwljY?(vjQqx2egt(rA8*HK^x]_\{n'ΣbFׯƀK2/Yb `^8|?*MW>zu!9Ai 8RYRn/Zt[ OGy{!`D IsAx4kZD*ĕ0c:!IuTg&t(o+/+R թs9`(Xq!iX@:U~WʄWbLK-cQ$>:I ?A,~7Fa'/'GY@S72݊(Q3MD/VۢpM9Qb37wIakA-Nc$c >;D$*GOjK q\̽45ww"bTvvbZHG`@MW45vΝM3D6SgF_ٌ$cݭ$ Q/N۹? g]qXJ6 !\\V<|Y#Q@lYyV͈L޻%:$BV:} {!݃~?syymUcYmmzUN@ ڮбy hA3׎AOHtaQmEY2Zf%u{Yᙇw{P? Qxs^[XۑF闇ޛEK%fK㚚b!#&hI޳ -U1f'\ ]OK=^ؚ:) UZ0F: p݋&f9¨p%)W ;@yGiGJht?"EN6;RuОzXuoSڗxJzJwӤHX*#EVUg ]o.Ǘ5#v>l>NSxS$\yN8]zLDxʥPs[͜0d[J3-dm=1yzQkL{93fJLu #TSҭZptG󸵧y+RZ ~0Br\pa,p !/qALkVwǫxb63w{N0ш:2ZzdaƘqz2Noicqg|]FC$iӽ7p3W$;'Sam3ltĤ 3p/ǝJ~^{D)m<XGOl? [I^FG2X7ʬW>عEЍ>F݀_<R b8O(,=/Wze&v7qŹ'y)h.^Tx! $ l{OyN]BAN@ àì&3/uڏ|xH,U/zB|hqj@,nJ1LjLa,t5jX,҉/cy.ƕ F \>HrD+'Iq/s:gzKAPTxKv(R_%{a :2(s׽ FmZmapuf.F q5sNMu&7M'h5G4;XL*"Q4Ȅ:qѲO]E92Om>Pti3E0෠`=<I3 >#6̀e|+}7H^HdN3?C_qj @)2Q*8뚜PḤx圀~LW)(dȣ6xx0ZߡSw6=Zmt؏ Rj/dɎҚL܉r"M`2IQDe㦉v*uD++3lq,8#lQ]Ȯ^4TG.sÂL3YB<|.$I@RKҔb۽U 毊xiKrh2p~n m5yAeaFTL-;خ{WO1l4E[#(+,Jv< ;bG= ؅k0>!l6aIہ`9vq3YLoSp̸'5]ʥG[ Xl!-G<_*.1/WY}%ҦR_YW]_ @*rG\QͼQ_@}UarwRX賒gjjH}]gdkORq%{) 7+CrV߈87W0KQ#\@.9[f}fs@ҫ%hK6uڎS@z&6h$$U`Dm\z>Ð6^zTD j짚b`!1Gchqic62w;w/KSbun`R,,s,Pz`be%+~e%g)F:_NP$ ցy ku;nJ%.$6`BvYFOoxS&1Q*]ԑW#]VQB}_UTL^ e-ʹډIi)-ݘYyGq1QU,X@)͡ zOFʨҼ䀃)NhYr8\dM)1CR 6܇+t } &oIGQj|=fsҮ3s? t0%= +6t4(w~P/!fښRt=|$iK 8::"yBo_csvzQCv(M \E" j NnzBI~F+Csua(654q{'=5-YG`yNz8QF#$w'l@DQB[\J̸LFji}iExMwR8l^?mmmпοbisTSXZ/[*׷ 3 nA_q\nZ=yLy:7@~?/}SQwCئ"UJ)no{u WE^26<混Ҭ1_fo{sc婘*x6aôp)=+P0N'@ǤLץ}s&~o(_xc_Q7|_l[f,_7SQTUy=\x (^VqNOQ~{ʌV[7G!?2B~xF/-m1f?0WʮXKǒJuc.a~M,Eq]v ] Qޖ!GUo -? xJ.woThKlY".?z4su劐$WwUgaP>hl*aIeJ|e]8ak[_w3~]LĽx8> ֗_Z5M >bC$ % 73Cl`.l,_"lH>%oOʗ~|Y_"ݢ$>%%%/U]hLeu8x).o~ݢL|e/vOnsz ˇN9-/|>~ M9p8nع\PyQ 2/8 MFQ0_oa'A+èɋqka\a .8ތ0x{.xa DĒӊz(B2B?/CM mc4r; CA@b] Ǻj|z\ۼ"qvv1d]N ~տ;}W*'??T+'vHӹt;Q 9+ojGOa~ROσJ@`U΃wg (Nr8tG0ԟ`Fts:$G(9vp7u+xE^n a^F^>Z`s'G(8놭((M4ƢǕ (KRvw SsNQ 'wzڊC&{b@ ׋y=;o "wIs %uA}<8X5JwAa;E-:@Wj'"Wtpտ;'؝ X]T |T0jaPxPbb}G? /Ni-9;-v3~g%r 4 Ҟgu9Y7<|${ 8X,ל\lߕ9e@~M(m,n|<הqؽɘՑ8UP*`.(:Y ,J[9p^tzo,bxh&~r6Vy罳P뱄knuX"nJ%! Ogڛ'A|ck1Y7ǝuVO1$g1-8 qn~oA){L/on<_d/-ʣE; ٛ-K^;=pU|b`V 73r%&v@h Q20@9oX+̋ƟRcbnn[I2dhȳѴr+΋qҜeT|QnRrt ם|}u!O>x #,}:̽J#a.#j%( Xހ̝NLψEK əf4O5q&DlQ <"2/D& ( mR9h8ٌ7Yp/ %y(,XFmK+bܬ ClUJyb f̨'(s8y?4ǧ1y(~:HY)p^evz(O9lC$ytK:JM\3Yr.;ȉv^%gm,qphF¾<. ? d&dA5 e9TIW`Tgt!5:=Pm3B7b0odD`+Xsb bFK>;r*7$N#`HGT4;.)'v;r*^7^8!؊g0D?7[oUd5.j2lES{]UEq(M|~B`ZZڴW$DFsѴ>w{uNĚG`+>N* oATXVi˭b+X*E+Izޮ)(Y'gT0|^->q9 G9O*ʉ{6$saѨ"Khr#jB%NF͆%ؙrtkJf\,;p8Ln" ևLlދ7 7I rND. !kme 4;$y:ȸ!yǓA)kۊ7h h=x"szy@Uq.8ws.)յG(V 4=ZɽsٓO*Hl(/ebRdG OӞVEJ0 #/c<Q]84ߥ kƵ/;w 2g1B|tѓQ<x'(ō""p Q+nbc8+(ftI\/2d^h?>׊iJT*SWn_D ֧bYP8?^_ (:Ojlz[@"jk@^ :q;3 Je=<.(⧃bN/%>¾ aO r,rY,ǟ/n;ui>-FoοWcS[#3n/8CٿNʜ:csUIba=hLRP:}pY&7|grgB:Ms\יrsSij9YD4P/qHޤ6gxV^.iII7wi f+[Β{b :m Z>%ɿD(';z:\p!tk|`]%՛~ :rGDlXBzرP {J;XA)kPXEz+r7+ZWԣhE6;$c ׫/l?0QAQҦPCyFr# TԽ,A5!̷C5S[\C#]ˠ-d8_8C}8]1{BVPeqG@ ꪌ+ K(َh9ٙjw >edž,&U}Wy@/rI6Fl. ./WArlD/Eip͉1tRhCKi.BQ2p™#VU~_%]9y]&O\t1o6tP([H<7E/})#Y;h.!Tx]- G _Hk϶R)'L!=B)}*HKzxQ,.Җ'"-;~7 n8IYFc9wr5 F5efQUcnd]I3D*M!ɩ>řf | gwRܐ3QUq'x:0t{>-Z@"Y#_CC-}K N8b=D}vJ3ىN}:x&~1j0jocB NЋ,L +-T=U6/ڲyɕͩ̋>TT)':U*'"\Qwq?a#`FK Kĸ ~L Kۿ5QvIF3EBFѤݯȐIΓ ^*wHjpj9aiRQό'A3ӐHI){l8g tk hp Bs۫l<³ 0Me;2>Un %$ }[X[2P`7DڌVnh`_l83ryAƂャ3ш=r6)"5SޮmҜD. 0,f4VoxnQB1Uܼ뼢ymKƏt+Sv$NTwwɪ{r M9Yp+YVh#n.%1N~t$z7LJ8VWWWUWW#0~‘1ˍ29ECgHaL+̹[TFO^Vo{;t&<4\bFCdZۂ8ՅDrwQɱ^zRzqf$'H>|d3@v71 [*3ǒqH38\ʵ]2f"ь97kfܶo,:}zjM Gox'dp0 [7a&~nOxly= ilw>Z+M:&shܴJ,JÌ&nna2NvYWI"M: &hqfEn-gЁȎ{v8 πijW#d3=),ȎO"JXw``䒯s'\!kNޡhVuRryYK6*hk%f+y&٘Sfu^-'{p'qRJvϚvo3L暋@] k Wsͭ«Cq]$Zr&9:YP|dcf':FFޜs<"vfaCgq8 A8 90%1?3G -FԌSʫ7W3Oxp{YtE圁gK6fbSpeSx.50Lk ٱQMn-+w<怃l7qm+"cF#֫ J{nJsWo%uOi?&eRTcÈ#+UƉ TԑJe;ysc'"G'^#i{pΘp#cD]]Ԛ*k|tQѕcSN|nv/ sp+N9ϨF7y iߟ._O3i?wu2|RQoBGK,ug"UAGg1Jj"pa"\SDްeN> 5sr hW vZ.ˁT!~"+%}N!Ӎ5[sUPg$>*蹄3?;+ 計-_Y,ɮ3]K*P"rϏ 7͋gG/4/-* Ɂ-G%T5F` }bjMu1}{ Xif| VpLT꜁*.ٱFhr]9=;D eenNw Z)^6Hz^ϴZ@.oEa*Qȥ&3A@<(EohUf$!IYٌmXY(znfRdD=ْd$ VIoo68.!ʭhdiQ57rɔ@3kAbQr#+ws-'{sg,{+ږo(F#gbOxT* x..1i0# G- b½ٻǫOMIfW4q}4m}ϼR{vgNd|6 #DXۈArܞ%016NkވREu G]kY_|٩ш;[u_kv}kZ8+#6jZNze)+]@$lXVQa'yJ%?uackvsl!4xpp /܀EU]2̙5inG ˷U"pVL=}>XBs'ԥmXXGlOs@a*R.{>Q=DdEsj @JOMw L}z7gx f` ؀ LD^VY|p+by$Roٰ|d=dK6d6!̣QҖ nPwlz6 X$k=0 +pוD+H]׌jX(MNg5dIU(|tpi0-xI}'ɆS$pVmNU{mBxd.eLrXhhg٨xLN!0ʳaR/zNX -i:ڵL6sPŨ VCLFR!'ao>?dz fgG=MS$*S5咆uB/ZƓ0>CtOcIYp +\ў9 a>!+jWN8ܭIUE]Q,I]S}[b'F7&oS\8n<6$s%?X2`"lU}ASglv!K%ѷ9 1>9xpe_p0ŵF4,L~m) >J64r?֣Q{ 37Ei4w?b"Bv4]ޮ'H5 [BtIt6 .pC?!`nhF$b⃬HKѤp2돻h_*Rg' A/a!v1%>gޑճj%`C|֛jL~M F@/ٖlehL50Bz:V S{cahk 4"E}T AY }z{v~QԖ"ia֑:|ytxA*N%>LMؿp9`r9BMmN2`{iUDP^`gŗU4ŖRV٬5egUFyJL p,{/w;H+^퍇+0EtcCk,Q[RB}N{)L o@f.@9 ed nGgr=iB.F=㩪boE޼A)QŰ07@ͲVtj9$۽ywC&{0qhN8I4pDtpQj+ i DAaxLz153LGL(<@003g.\T"ԓ_2Uk]C.FR RN=̨1)xE+wƐ"~0(d59TP|#Rmbç2٩ tt=zE:>k\~qxS~Q%gp,VwCj5egxֲ?lG>va['"?5J੸VLx/,hͦ1-H!} ;\N}BisEw)L/^g.8BׁE@U53Fs\|ieUB`WG3m*J5Frxp XdQ9-"?d8w+&q|HlР Oކ&Cz>J3ht녻Zi׺6SzQ$`*eC>֖ipͼՁv:bný@Z:`2#yWx:C$v9>&-JI܆b!CfT\A{uTϦf虱-$cNs^@gJм!5Y>IiM6ٗ3K+}`h[b9ވ$ӓDR3@J"9ܻk)=L5,LMp6onպu*їUQ#+y N &%%nW\q fR#'b>$>G 2SȒsozGynmUbXdlNJ`*1-dJ7ܽɞQMБ+/"@N3Δ^xF#$eOP.uN/ANo3CIl/7@b᷐"2  Wz~WΟ2Vxm|",L+BT4ըު#$ܢ =*:3.}oiOnW>O'eH /ZhfȴnUW85Rvr4^].$97 YG';a߹ŒiQ_VMK6n ,g]apuǮ2[ٟbeRڑR _.&_zژo҂3:7z!75yDD!a$W_Og:F|1 jp&l\p@ZY̏1,a8ʉOگ 5PqqAN5 Ac2:oL(ӹ9>X7ldt=~*s ;|(da쵏ʞǢv5b"_3Or ^b%:QPL懦~hEh|yjebV|倩JKpvUyhꇖ~X+aU?  ~…c>}\t }ڨꧦyjebVӚS#S$Mps'#R'dɲ%!c4{ͭԸǘ ;s"1NMgǝ]̈́fXq1GU(uo@쵟Bk QhqC@B{dX9n(:Pf9Ǖ7J7Rm>|tow6MntV[#<GA\Kwwc+k'~ ?y=9LHi~E@rMb&Wh*QܽSkbgv;s{+jb=؟_׽3'uR`vvdͽ%>^LKhP ˡadQnj Z ]j=:Qjo~\>a/ra' 0K9d4w {W &9$4`^֚tw,cqeS,=w\CVy8wyEU5:ܑa;`>fWOWyZIz!(6 ͖-94n>jF,ZG<=CQU< ϟ9ܷdR)K~Ҫ}z R॑?\;w5ֲ4@?c8um})>SCv[Q_;mI䝷wl6oT=w-nf$x0:Cx2+y7tz?7B|] g9?fM (=>vr.O?Q˷`8_aİ E.V@;LO*㦈K2e/I6K~[t+їqtZTܷW7 d}nq1~G@B8}ND_4u0.# ).x#D?o $k ;fcwp?ZF$0T߅0|2f/-j*Eq)=?4qj}'{Q<>JHzWVzݣO쾮w?1;>m~r8 :C;Q槀O63%SS?xo/[Sl7Y}o'Z崢C*K+GV0㽴}3hd޷C^\_֜抜i=tTjcAM>mߟz ԉs7ڢ[Y;LܼuSw?\ݝ(V=DO`23R~عO ߾Ámj`wӝ"k$\ZC)WSVmʆfD7 ^b3͌/u%]G!H5歶 ~Q|z]&>h7z@㢎d.;tTFo`r,(I"sz,S\H Tq*R%\%]?e(oe f Y8uuttpDCO&fpkTY$70lYڦfS ++r [8~6 1wyg)t1&QۘZi4_rW_ G ٞ#S8^[{w,[/k{ks]?^`[{y?nJ;bW__ttM۰ywig΁ GU܀)&؂Dd_$0=\=ݥ:.ܾ0z=4׳c PYfŖ<>zuTᄃ*)ۙ?' j3sWϻl(v$EV^݋l߹ȓcyrl},[wDzuw˶ s݋<{;ٹXv>ecicY"+w/E\;')*"2]Ù7]l{n1-?HQ"_{M++V?@4_TUh̡ ǧѐ7'/N QdQ<k`6l"r+B7 1 ⅴYȃ]% 44aj$y  AȮl7T,%>8iwy}o)d+_VI V+IiEO SjaTWyFx>?>k>IbݳpMTseTZ:Hkcg2P"`bi \#u{l^Ї:0B/weSeKsi9P::S“o~ۿGv j>ZNVͿ/k¤1cT;w8osvP)byכc]? 8s\ $VqJm껭ij`&y70M0d2@oq8RQm*z9bLl:Eࡨ+_/ x8}H$>}NDB+}ncalwko:_H^pΔ=3ə>9xn~Kt);?uǻ/7@3m<M3+x uT0bPG>fݗ`N>}W_ZES iïC,[vBp4݆T7ᖏSKmSqb&{-geeKckZ),HU]t[q&Yr1WmNC,}f[T}υ = ‚>GRR,k!+`nB/A'enXH`'S+}'oqu_k:?L~h}InJo^{M5 0JK%j h'E l!89,}v++D//>Zg(/,+w!t!cC~k  x T/?rPeoh8aQևǛmO5qN9M[҆N _hoɳWz~ݿ}?:/ǟOZ^Y]{I1utufs`'#Mtӑ^gB$`SV >sEp &6p"/ rΨ{ux@UoƳU߁__bԄ^>ȴMu뻜MŨZ_XMB-Mg1"]jPyX9GSERGE5 ۠h` vP[,˰-v2YUXJ[a{X P%.& s_F1*AGpkFwD¸ 1l(0kř"L4wOg#z/51QTWkAw#w k[_OPGkED oy`xiҙ,F^`3\KO״ u6 _H\A&p#f6zpuGt] FG* +3h4'sQ8B2-H[0g2x+&FEjP̹!Vz{$^)ML>BU0k-ѳyO"9efRO:hB cuP+j!Ms̎m2JoӺeètǵFŮ!;Y/1+T-9Zi~Y-MAgNlL!Ree.7 4( =o4WKD;hݹKܹjf HC.5,)K5|=H'#iW~ч ,!4%@-=\;HZykJQ/,7*uD<°#MɨQ3Ѳfu`?.`4zı$Kg |MхT L0Ƽv0K2rzW[}@A6_l>+-,sMfc%0 {;G!(.·*F@KVt2HڒִA H.CGaq72`?v09;5pg0Ϩ}vf`%ncIU=iM-+*A'-$I3F0q4D =^6tmF}:;I|?!f*"Q4OpxZumdcM.{ZhE 0dA4ۺutў1r3rQ#5J Rzux44`*ycxq4X,0Pz5-# - XrWD}0wB@eZY :6#/T5j#IB A;ךK2Jy>>8<mmQVQZY\Ih_@bi%=66e]K7e9x^NY#zj=\y)n>5Í.uFxu R`y4(49ApBY^ - E3)b|$'l&i 9v$亘oI(}e4Gh hi3Gġ,oě*S /,is׳Ah(I)풁7 g- u٠_Y@ixl(kMgFN'GҬ %<@ &ޯ{|0#YUO%̉)> i8bdTT&UكD"O8usnoy6f+ݿ& ` (OQ@fNl`ȁLVєi~L X6@3 "`8@nAl7-U,.PJj\p~0FؑұO@iLj˘ B")pf0)!!'[B=.A ϧ0x`(⽜\FG%p90fˁPq&4|iIljQ(^2E8C1Β.ҠvNd3]x U%׍EsgL0Uƥ4B{ _=8i]mH}ɚ izTC荱'B`r]f 3Bkdz1 !#h4Tr(xI? !qEh3| Tslas5m8b!M(,Vfիa@C 0˜eYJC[0VaQIh =+Xe.shZ:k'R/"[*l@<#jR08f@dw'n /C1ù7hM,`'Fv4"M^ q h mE3ClϽ7h}q8`0q`d,; /:E+د`dm|nIK$|JUpOrl#> a۠mJߔ;a/Hj D4B4#ױ3j|AĹk\7EB,n޾e[?y@!G/^q5̯ufFE+SQXDQӣy TPH/e~OGXw1!Z^ a=y-8>,᨜Dcf9D^X UPdd&<9XLh5ͺp3- aq'DIe@\ÂA :g$,6$ Y)#[Cɕ)$Y_<~E.Wtnԝ2Q}=^MыFUz榗C_/y|q/U.ieOa,#=N%#V-n*Bt'/ ɷ5hHtU5mhCM3`Asf]Q3) ي[WBX 5 \F2 7&ߪC6]zTЮjf֙fYӷyQ<^w{-Q7  e3oA$hY+xZb+|dl&$%rq$aEv7@bD'΁ , UK\ZO+CےiCca[Cf1iLߦx%sƖm/.$9={3 TwZ\q#9̫g|^J{9Gp.;HNE= G(n!j~D6K 0G !dIfբˑ^N[UB*Ռ4iNw`OtzD¢H8KlytmdHV]0k"umUݏQxɻIhljvCRïDb6e]LsDm>&cv,.2]@†K?^ ȕl뎧b}j?”Es":<ψPCA@ - 10qBiɪ\O)K{ͭ [U + .At4 ˀ08,rdB>Tt"oIM:l&EAlBb4VCʙ\XTRu]caQ|9ojOPe7rO LF!F_Xcۘ(E%yM6J:߮KZgtIs_Ҷ OljP-} UhPz(UErsA~ %7wi5Elh,Pf3 gd֥̑=P*Q%K g[Pެ;.Sv˵&wMntKt3l+l>L^$h:P l:/CHFy9qv r ldʩIaM*  mQzwSCǢ k걠MNmE;M۝g(T yH[ysI-Ϛ&؈t0ev\8fcm<(˩v(R;[!4s( LbGZ$f}?#z$(&dD2*,db'C̻q+hgv;G6N -v(Vsey+MUfKmHgb-pe**u+ Z@Wt h wAt$\9q5Q*q8+qCyԝ5%bΦOz+lOum8Xqc`PXQ6Z9uQ6Y"¤qIۇP];h$?cidl75>@ ZfB+eykeXR+|c>aM3dȼAbK%W%xbh: Fl 6GWCTp '|׬JGx6Iej-pn>J?F=W00X]*ң\d22t9yzK:@QQfJ~aJAZ Bʈ-!Sԕ55=Ëx+m˖Vvq R^] ACn(8Elmͱ\|;2pgW{\ctYpa491u.aN*rUNg 1 ܾfjw4UNcy+r h*@ÒQin~m5J_KR*cqN4JC”0!q/P0櫰0#y@ATi`"&/89AAL_me>i &!17j[#Yh1Ґ&q⛛ȧe4 ܤ㪾7H,-%kߙ.fXc'h:W8"ʖ>bD:q'*H{uh.[ʵu8roHP&z.Mʫ6 |:T Ye–\qU1eO W \X=,#攜 5- !tbw|g^&\:m8˓$c-*]D:Ud/B^݃grYq t_vtN.ўbvFcQ? pL-ιf d@@;C O uEZg>P}lӎklL%+Fy<ʙӻn>}c ^8\$6PW&Yt[΂ y)cʟ8lg@R[?`ʷ劜p:gd@.03ޝCrMmӤ[٦guKh G2her8֝vgU}6* (]DSV_̊rk=Jlnj&8tQw ՘ŻJ;%^ &W%02ܞKÇw3ݲЏU3 JZh;cQbb hb@q>j =l$\‚1zPvٟ؅+,kiC.[Ü {]yoڧT:xGnIM0=.ўUϕ3B6k:ьOOiE/b:fŸT\ ֤zk}h :lXSdHfh\i]T aeOCW3AyF5ŕ [&Z0J_x>M"tE_8Yh.$QZb"ͭEq/₞q;LaLd`53f!j : qzlşe ҟR?G,R'yzg<־?x[pʚY=C .fɂBp &c, Յy@)Qnm׳{3#&XgnwPEkj@oz,i~vW䍸(yBSϫ2OF6|֮0RlQ޲<=ǻ'tY&4GkLfԨt+ξyK)G|ާyc$veuc6;5L$0"=lZ]hؽ(zG1%5cb#x/L`n!㛉pdݛB2 :]!jf6V 9p=X|e!ALbZPCOh.3s:t´8r*5PLE5ƱG6 ,:WtcE0HrK;T Pu;G4c,`TFtxBW 29|qH&?n=p*!.ɳ9|Qv!!.$؅쪓Rwca :ctN ji^Ր| VgW;m3!QZ[)҃6]E1 אW{KȣF%,HȾ$c$3bOs=l 0u&Fd, x8S힐|6GK+_%܇{L!ꔴ:}YMr=H)Mݕ8jg>48J}'B!cF)_CT#Wsc%ee+nlgnܩWY5,5(Mjlln#7%Hr 4Ji &WU136ꙅ͌-zY 'u!cnTb&1Keq+;0{Rj4SCTO;89-EA:4Tou Mʉ^9S7CH,/R!J>s|-6ǖl8gg>"/$b?-7}|pRq?a4cwc/OC;4M8;ryr}9w!_p9~K4}^?4閌§sngj]Vbl-~+m eb˙~E5L2vE`pGS'b]&α̌t\ME={!!ސ{|3mmb`2Xy ({.zڥSp6vr%@d<|<^zl-=z9! \ 옿='.tQZ׏Mزq>5>>OJZv &IJ&$4P"y]C7S6޳B E01[V(iCМHQhѣK,Y&0m&d?/>_[ևW,e cRʦof%77Xx8 EHuueq8ˆ0E5M.`x%b5MU&dMkc~_[YM]m7(F8]gNc{w_/OG+h55Zq~ m ($.ȚE(uQ5@?6J MZ 'tI{=O]ye]{k}ԩ47TVg{w3LuIALM#U(롄5@#xղW PWjOjuAq7kLdtZnJ߼CAqB6AF ^xLí~UNh=&1 &UYЃt!;#ʍdЗy r>3qUg Eq 'Ushr!4 }fnX 2sR= pY@Aպz#Wla*]Y?cXnY%;bx ʳݽvwE TGU@=q멣k#9G,ëAsz1zUCHe~Wׯ-`>?hw)='n}ur&w-ڞlܛ_pBx5$\,mTÇ=A]RQWm?"㕼jC&yMKs&^pX7QTTSѦG/  bjV4[2 Th#/Qǣ9+F+{oi5{ّU[ܶ`4Mu5{uɟ'~9"Y˖>ph{p'HaƆwHdU{azj6JOհztwSVT$r݃>7R;3b8i58E-]=!}'kU=>~JV ba7>ǣS t*k鴬rUaEǭP,b+ShR*뽡ּ ZXØ-Áa6ո#_[ؤSo?|hlqz-[FdadNr甥ת Yao?wsT,XK.KD eo=o}pc`Bn1=G?X?̆:@eб@GTx$NC.`*ëpP} F9=}{ yۣ]]-H NñL{wq 3^b4q_9m~ O$8 aLt0U^Dc6z0CflyE}?H-#98ͽT́]6ޗw'l[BxS~)(+>h>am>x?|y}Y [G;{Bz;#<i[;HuҨru4zTs)UtzBqCF1.-z$lj2FdWb~Gf ֭93e53܅ ln ޟ2(+j0z"~>>?鰭b6 ^[@ƂӋ`7҉w;t6sf5ӒB A}맢 nܘN#򍱟r}ttp&Zg@AR"vbܬ8wCF.P ;7KOf|s9U^ 4 Բ|nuh"jsL@"@ZxZ4uOZgoJ\Ԏ>v zwTKP+VURUIzAH8xʪqsC,{Pj3qw"hIC*=:SOs Da>V(*\ߤN8$` 캘hݬQ5c$K*]Z57Hy.sjqt':m4rV|:,X)F9w$o |ܢ.~ngL\P|pJ*m^謪fنrc2c5a$d::{!&܊!;k=ކrR7*kBvdeTϺ Nzٜ*%ԗ;>ֳ絒NṪDq\xhZl>#ᾩ9_^#Խ<m LRʬO]h; SNM'J9*=7 C\]]Satrwʣ_y Ƿtÿ b; Q{:-:sod_ɀ~p?Nv: nd*{O/>b]sG6Gh}wOy; M}JY+ "lr5uIw݌pʒ5M=]Ϯjr E:l /u4jQd=G"hʽ/QYɖI7Q{Byƕ?8KyJ0igbj} L5h[FFl(q;j[_гwh 3\xX鋮Kw{w9BVF f?xJFbcY%\v#FjM%%2Cm/"P_D/.EYҿPߜ~I`/CR%dŅ/IB#{Kȹ LGpF7.‹hrECB; -*`v̪}a}v YXў0;,[=ԤZ68ɘ /#wP$z?$pp L Fҡ9:P8/80Fv-rGA6x{LNLsK oy 709Na-{Nxu . :n\38d>䭮M#%ChU1P3lxh :Ib̪ l:j$IBN.pBC/qܰ4eU.\2Hс!ANoN~;m^#FV L)'/wU9(Qe? @Q:zCΝk+GLF4bem ];04 q0GJs>H I u;ALYvЉ4yZ".}ec,:@')Ҵ2xF!:4d P豴Vu0Y-9(E k @hgNʼn!0,tmaWP0@m{:-C\n.FD&;ͧ2_E}}{̾kRxr!ATٺ]!5 D~n+RȊV;6?5uKIL (:J2Zt<5:8M(`+Ut\Mwaʵ* iJ"귥ő+%np\=4* XEriQ&9^lRݶŞ8/: :fڂT BN Tm&ԘLoh~)*qNIQo#cq6 eZ5<?=O4C~4 X>aok<I^otj6Wߕ_翿q񔣳|Xi ^)9S'X/gB#:oF3Wtt<6 CHSb+)RYӴ)vӇkVyA z\LP.?;SX<Gswߦ^Puɺcnfޚɸꖵa- xr(q%YO~ ~x9U񏓎oA~ŞÃç/I0k?ԫ?~H qGp\Zc,_6jBp c#7ip@.;2(zt̫MӼ/AU-Y8$+WICL²Va0Gf0}vЈs~lC`]4*}-˴VAqcվ=D &md;J2IO>PyrF%jg3B*PtMC#4Cܒ=7-ru83DW rQz+fTz2L\EsN58lQURy18DbO* F)0,M#k{4dA5޼OrRaA4aCQc|Ez]>}{wʁl}}rXT߃U!Ln!<$a ,17+2C](."VNҢй܂(peXzѩf OLӋ ttRe FkHyu/z1>R f]7KwT<"sBLgvb z!agc NMҔk峫`9;2pp91qE)Y"K8$sw*^q p s\:[TR1IhﶏI"P"a߾BZYW0biܔbeR?JkCttebꖤ-1]lt 2auhlA'C _ZG/'.Tj Y@G>rOH$0{x<ciTِBX23ϼqHZK{`$jpWB#6`7,sIEkPjĽ`GעMXhǶjrm?'m:Ocj~6i\(r\v&9Ce l!4;]ig!q?ȯ &i$X'~q %ߡƭ:e~KgaQ59h)ɹ>.bՆeKt0)-΀ɣPֵ7B ȫa݋\RB*xq)n$tC6u!ẉi6`BOٙ}:eF,gwKo78~x*| -0/=/"q?itYq u?Kt<}.:[I\]xM&Ì^H;tCJ̃8 xK( ɻnkhU#f^;N#uiHt$q]:^gsEo$A(IfE`+ha!3&FVߙH[kazWx,f"SK\V|.Ѭeb:ӺL-VܽdE**ftawB6*_g$+sk1D-z>M[9RAS+o6z7.G˼Z*z[ݕDLd#g!칿5",yZp;tIGi@u77ɪh\mߢ'$5lz1•76l=oqBs>w2\B<:8R420hyLR }?${LHº)Qx0 Z՝ !@89V`jf 9i2ՄW0qƅMpʅ#<2]U f߰ע"M#b +l}2ﴆ1; 3 k!f2C eT^lHQvr*51ǙO""ΐ>=ݷ ugq`qtO H<˿ĵ˓#=Yeuנp8PLsw̴IK(~h[BBo:ŊHU9 kWȺQ (5%S[oDe|Ro o.vUT ߿ M4eܱ )"PR/0 b ZAzL䑇* wCI~ٞa u>[2dS:Jc<2JN]䏊 v5TH|1&J~74FPK7ZqaHtK"&v( N$ĨtȬ-eUјij^>y2KԜ1&t8 xo\2Wj&@31=ҁ)m;.z D/MʟǬC$b->pиѵYy?8KL(B?جܸ90u//o4ޯ>Z{ZkeA2ER}<~R}Ҩ>iVOOVO֪OVAM`om^1 O>XWWd=9 $i=(рTвMwh"4xRvhPզ[q;^%Q#߾%E0%z>~y89-F5iog( ,Xr) eX 0\jd1 erwE:)hmk$^G<`T$f tF񃑵_H" FqHadL#"B͛Z0 DNuE3) je#Z&8?XǨ_r` h3,}] IAgh΁ĞyPxL'ߦ.V`HL;NDY ^1 #e8l˪3[ڸuj>~[mfunG̭X $‡ gaxmhn- =aLHS/͈ 4 7&#M-E"Z`oA}t-KiHd аH#ſ#UY %cHJPЍCS6#SUvFcv YǙD*hhIG U?V"(+^`is?}"}DEXh="иf'?>GSjH%aA.`(6RQzN rqM7F_ ӂ *! '`Ć\!K4+X(ND$yN ًӛZ<Q( ]9\R(Xe+WS"XVR% \V6PdE|eO-Tgp/G}w| o"8Fŷ^|QE * u<0[ҤhJ+{p4rțɦ}@7|>,v#/kc;:Ƌ[jTzZD(?cWE" Ƴs.v/ZJ<'crSy&t>=єr^tg? Fy"r&T#2&QiT:V4)6}\6sO/ ʭb=7I znHA]^l5w"kXT$g5WP堢6VO|$)> cj<8 :,Bמf'Nf0J3L y1 *>F_lE|ROP(5Ms3?;>V-m&r9X~uܖ*ON4WbHM:&ƀi6:\Z4*R'3r3^X&{DiC燭Cq9TdTPOq1q Hic|'׬!ֻy|$A|'RkWѝe*:ǧI5'y3RrnvSԭɾ!#J {}I b_6ӽmŊEp#hNt}Zytj`60N|m3#vۼsrOGJÎx1>sfv$WB>+R=b>zh Y ysO?.􀝞vHo>Xٓ3qU8o}=H[-h|H #nz2w))z{mOgY <@+P/0rVh42Uǐ”2AR$-W V7 rǕצ `E/B]ƳL}M%;gãv9[ULy5$uI^KftE^LӲ wlRm/w~:LFv·?dN#_Q_g֪k-4ẍGV5rn6^vزb^cJÙ"/.YpkK]Ķ`S~I"o{.){'cG};:Hbx vgΐ 4M>bV;^w. g⥯O$ўXպR&lFWK8Qp[(x-Rlu{ f4sJƣFkH: >W[v(w=÷a.` 8T2do Udpp >ٷo 'ӷt%Ii(:Ja<dǯ(3bdLTwoPE!Asv3E¯8VM*o1R%-Z/4T"VV [>% uwqKl7,BX\{$j }= >֗9$ÔVP0"ʘp4PSKdvVFg: 'ڃb:`¹یxzϙTV(D0fI^P-#i"S"K<(#J#W` ʂc~We_a^n:)W[%vIՄWq-Z ,;2>[~0xZyq c#=c {ʆ#_Idì *Lg["P+͖k`J-t׌K[S1Gf̹_[ kZ_?1`:y`rН7g{^kйj6MUowǗ;\e!g*2.\d|ڏȷ%^xᄋrz޸-FN/vEf=эVLͬ^!}gq*uNzxsJ d`:1fum-1FZ2!~Л2iѼ-D. rYvN轣}lI}9I̘[ycΞ@"Qٶ2>ǫ xRk=}|;X e|Br^Vy)9ZS};〜V+3 ӊNkvT{^֫xY'K*G)^tlUlNaf7U3oT1g p]kt \6:#5~%&cI^w<`h5 ku[Y bgzʬmzl>h߯0Yqe)sט0|>7ƫ9E6le^gWn[|&wh޾;>~+)Vk!~5Б{DpZ*_{D^w֖ćm:}3:Yk@N~Ս1 V5zDɑu[FW.U/x[4=hZ8iZ0G FYq?PO/wgyZRN_~+D)HO([8␔aD^4)"B r0v^IԿmͿ͆Q5V)`fU#h͒ 3ukýU#{fk^$0$xӗn3zEfd,h7녭>e\m)3\sg쓨z6@@x>DSd5i8,~aD!=+N.;Mj0uhoK)=A 6od\=PB$asRx}?LL}N&}?o`dG0\Sу5>)r<[ހNJj4rYKވk֞<du/OI>ZIH:8fL S49RI;SEh) Xbȣ zY0$_rx}-lk1 /虂h!Sva:&=h%o@kl};<  ď~eI}3LUma&)zkKy #gZ]_6%FRkr۝*jW4랜4 .":{_rƪ 0WðrK3򼁙iyY4#oD鵕:\[`+23_]NyYtkK'+m4ChoYȋ꨽m`z:d$f(p 8*Ӑ=.y.08ƨt=_y\-D!ask8_uOȋ2H{K}}'Z_R E=.~?Z*WzTPojgÅVz vσ}7eG5Xc,7|9* _Zl6WZMTL騋 {@)O/ZVh$Po u-PalJb fI  1a :]pP®g>/0JNIw]J+%UmDjl $ɡc2z.hjj:Ly؍bw tHg̑)/"^gfA4=gX4 4%t=zu6_$1㞍 %|pŦCGX2áx>qPbb8th &ɫ1(N +U(E{tO% cDb}KY{޲~gpAPH &0ѰqbP[y+c3c$/. UJG$f}hS7]Lpcv\aW@~ꭶp1BѼ%)E0Dh b ^:A0Rm$w  9ȡ+4HĻA_J]OK7 n7d4zxo{1 tFܡ{Zr Wӝ\y=ayJa#arM0Mu-nY8FO?D^T` LX͵}L$4l|BSk)472EX'^`f:. q< zz2aNge<!sd".#J:f]ҙn 1X]~D mp%ɡ 6$^^c.r\J-Kv.Eyl?"o*kŠsep pn-y+F&Geښ6d M#D!IxXI&E1+u<Ï0-,g"Ied(V^nkDGHKk[/%{MS8;Oi>})*5i [/Le^lAݽ4㋽Qu22 ^鯕8 DivkovRo7 c,7‡Tj°>?qҖ2ӗ[GRY|`v_?JJ"-2{09,JJ:ZgD<Ą9Ƌxw+];`_YB[W>u UEu0+I]a0+bSdv9yR.L8I#^ ,NPܚ&5-Lދ!.J{зa פlJ7k ֣V+,ί8wFr~;z_'/}K}J'|ˠvpRl~K:]Ȩl,@P#?72 YZo3qEf0""i7*.Ihg|6BfTC }fTɠՌu㔃~_(1룸Y,V HI/dYU\i4S_EsʁX4 EXx"oOGli~t|tޮA_k4S9Yə GNT@؄VoV ]t\x}%`4MΛjuɌ)c0i [kVZeB6΂w%Y,*A(Z>H]wLJUԑ(: &EtQqqiSMξtVI1XvrDB>&qT[`1TaE\KKtBpZاh YJ!-Xl Gx) P$^I~*cW`P-kX S^j٦~4U_qו$MVg*3xaR5Uȩ`I5tm'h:^˘C d͔G]J!%R~QmTє/O{S]`b3ysZcax!y bQ7WļT+J.ɚ#{`<Tm] )FJyҜJ V.B#wB̊W p#Tj$9< <3;sb%kDB|Xvs?3kq%_onTkҲ:=Un2ͩf,3LD-CM̸ehY{T8vsXn\?Zε'0iSeoˉ:ƹCgco՛sG?-  ,/ץ61tfk9ϝJcw`7DfMI\YfD(#ؐPckw#ӜjU0mS.[oLź&/~ptW9`ЪTqcvc%a;R͗tY̬f^Ijj5Q;e.A"%ci| Shl?k}3f>5`tK!NTXh\Ėܛ"9s*.zL' >=c" o}r  zm.0="ɟ߉,'f"V`9!l'*;jׂ HDFbZ*.pHUο, ^| g tZ] YZЄ0_}`ι<*otn6^0Ƹ IPҏ=A=զ{Af'!_upN7A߱4 chH`$K-d \k++R<^_ <6xS[ guUH6flJ ONhev9A!4iuMК &VwjszjR"#3U 5Vi"sgvXmt(ɲVa:8[d+>$+sj-_] ڕ$8!<hgm`Sۓk|Rk5`h r˴6Hh5Sl>j6״_+6!R|^\=Ν9H5m ts1mV}mͱ-s(eB vqȷ+@B2Bҿkc i4fj-ӿ+*F>ӿT 5DK`Aq;f|o:˭ҩÁ9U kڿ_cn6M{/|ת>?X4XURг] )Nrko{ln*R'υ+[H:i#$}(/Tb6$c#Slnyڊ\a_l$[z%`O * f͇?T6 k๜v77CYG6r3,޽vJf WLVj|),(W2rP͎-!"9WZ(y{\ؐ<+8NB!fP*PBsƦt9erЉTJAzGOXe;6Ki<{ )Ig1StG 듛!bW'I5kNW ]utˮ)4H(wǷ|6u&|ӯEx !It(~' O /Oj+x=jv˄fGBm|.^P,AJ\||@X@y1t6nX{Nr}Jb/e647hŃą2bQX), ߖ(,`oꋜtnyΫ~cP %=80PɒL:,UTd*Q_g+H`n^ױCL7:í#ٞ>DkCO=\nӪ h׉[Ol&85ߩ_~)JtjY!db< NX^׿*iAWYDl|ϔ8NQ;n4HͩAj![=UݭN:%&$Co;H1,{̡;X/nzEU,.hE>t@^5 s5cL4!@s:/wE'~Uyi6xa~7wqV"%C.vɟ<9fTL_ t2;up bq\K:' +QXH3SA_ s<@Qt&IM|nxSjڹA*eWFYWH_\gvАR u3J&!Gٛ3\Z/@䦐ڎ7Tп (c$2)(ʫ-ȳT(TѪ7V_~q%TUك:t+BR,.=# B3J]#3 ^/vp2 9z\0N,B !dT<eƔIe̘w/ v_vZae`d{5*royj~/m?|c{W/HuN9CEo}^ OH.Zl[Czv(vy%^g_A*Ԉ'f^NG]3@feviNVq" I35m&HkK׃YZ ;4vl$KgeAt+)WμRp<#n>3( \md4x25؄V1KI^YD(6)Yrۯ#Zi¨k@RP1'g@|Gnu ~{`N[WZJ6ZFk6u@Do G^=}K2a6rjSUE5ʒeҪR-h4bh%7aq<YVx!7 0n䙍՘>!&O]b߱崥E I8S^DI'ëx T 5}lx3p:eA6Ml.шn)gߵW$"=Eh0H#$1~t"o( V˃>yF> mO?P?gTjI//a%}!ݝKR>e̜>a`1\,hh(r2qB̄&]h+fG0Wb6h$)XnZ4,,$^9⮰B:6d]ab؃iaʖ?w.(rA:7)q؂ɈD1U]t+5̔a") BKcjofwxٮ[JmrbA)h;Ōj@aYZb5+ 0mU%jy׷g9@Øq!(T{WkDG2"DQ92n=gL/_ `& ٻLO, Mށ/tg_krAZOAxe|مѹwxcA):qnoG1z,(sl$qlr9﷎ x*DvRvQgrJ?35 ͍<})T0m(=P:9:~I } B3W %EVcѬSJD{,|Pm[i+-G3J 7`-4"9,^Mu/-fy( ? yL&Pq˨|a $ ɭ:/^,vWiO*Uc.1KXB* op&G$o ESVNXu;o[7fҒ9-G}^2Z8|b.nE/ Bď4M^W?޼,-^^*W }<$)O^;K?3C%~7|0oWn2^ [4:rB`Yi,]mN|ub9h]QX>'0 (X2h) moe;‡-6Wt1hO!tGTxqy{4<&%_c,W@'[DMK hzM1l!U_Nn= /+@;\t8s5tH=)~z0xNBίUWƃ?M%4MvɇȇXW?hJb?v#&Ƽu^g6nD Ey/B{!O=h3(6F'BܤbSEiUv.#<=4 :xn\pKx0& Ztg0H(CV!cFnK5]+ c`kL?H$$.ddu^Q~0gV*glc. < Bwh_UG\"Eؽu(FFD?6T0AMY&jl08L݂nI_xiIMo} l-u6[.2GqaS~2MsyЊhnqxKD_z]׻({Og/S{Qgt{wދu_~Ï?Uj}5Gg)hWV=~+ مbϫ b2pNhB2e2ܬYۆ}jCZO[fψWL"2+=lNE%-}q1셡jՋދ6,7k'TX?15Wukclm$ucwՃ7<%K+nt\x\y{]]RMj"*=pVV^^7_&jjG#Y0Ǣ6{Kޝَ:<v wp?e+R؞\{@ԂXnӅJj {`C.C UcQ VC4aTkZaKA\ñ*Bj&0a\ETNiowT/ǛlV^QjŊVp^-{[-Vt5}BEHpb&`+JIgJP6S|?&+%X~[0k[^ TGĉ)]y@~H?55dԨ֭?,EeM$m [FS_6dT-v;I 1\%qĵ%tIH`^t~.$UۦFID#'ZrVE V8hF|}! O[G9kovGDHhϵ 4Vq*9̙9D ck`aĝa8*艊,}/7`p#=Ğ\A@Fg<+MlLV2B^<% pfͯㄹsx\Խ,IfHޜ ̸e{Ipiij9»m`4H-ՋF#M.RMjԬ#6loql>N'KX}$oy_Yol,VT' KQP~`jDvv3L=>UE:ʼh88)ExMܮl偍5ȃq FӹsTNP/H el"*zC{Dzf ?kI$"߻@eWЅ'$Q vwt xcfIrG7u\|8ߏz}qM' C=tA%FI=E<><ΤY$"B`}t0bHM&bD"-:Ƨ"q$qOM0r/Kvoa1t :#s~2PfWɐ=wtJ"]HF#:oLa+B7K~vFn'kBWKQSSɥT4~q2~(9- (%䂒E_a*K^~Ԓ#7d_ y {CIi^;}zo^o~RL 6kJvNdN}d@7Q0$:&ɮw7>Cvv/{$^s@C CŃyq(%Ks9I?^?ڽ=im|(7+ J?7,nF魾5 e%ZߠhF3}l\O('BgxN5ԓèѹAL z4OA~+D Q\ts_gh6f)RfI?oНj>'-[QFh/6zot{Ipy?X.Cݐ'$5;/z+/7W\bg5L$j̓^np1淿Szi(j5)af^^&PEu?V?Fn'>Y458Q'v};5g(OqV9Zmarm=j 9 fTDR&l͓~H1iѭ{s_gh;υ=gO>'(Ey]L=%.꽹/fb>8tf,Z B2!:8)gفn&*Z291\STFk~Չw{30EslnJ2Ҥޛ' =2b6lZ;;*GQMǩ7y6F F!{pSǜB wIN>'?{t;2S 6ٯ<%2fG;AejSh͓~~z8V<IA>'+qIY'1&G|ѻ0)љf7=5L!ȇ^%yIT!1fCP!(=J̀ R IJ4& 56u*K|Je^"y3ҲRlfo+IL} 9-8XN"gdNfTdBr$v2V"p%G71\Jf>'w.{_t/v:xt(Ͽ1߿gII?/e)JK>'}S+}4OA~}0Ş]@d/γͤ! ?\$ےLH>'&^8-f3+хΚJI&dgٯ|0'cz^l`=05%͓~D&6H>'IZǚqW}A<MԶ'fz%)~vy20-ƖT"h?~X Iқl͓~cp{-VT0lWmA,gh{,E?J0ŏw8[eExL*_\&O:S;QvG2+ '*{kWs%K*A ؼW}1ە=G ތƶ,{G~Bu6+.ͳ}{sY#\j憔{_p݋|v񓃚4A~0)Y yݥwII.gi?0bg_(2i0 ZpuU iީV` GƁg\)dCﺮ ^pGIZW ڮߑB9km1%d k !Q]p L $ *z~XXbqҵuGɘtMN3F!mA발b3IwPM|C;Ælguca> Bͺinc jENVBdQp޸.@(b^ k5ii]($N5tFc=zoF(O&ѻpd aT˙\=|S/^BY0q$;9T҃+ΛuB؊܀0/lӼf4}">IEH!2MHxao{RE㥩ly=U7YƝ{)_=H}s7JgΘ1]/$W.Ч|#%rrlu[:z5;eZjm@J2Пz}YiYr]r g}œfcrQyVÆ;m[!{Hoi物֋ޗ:GIñStU2 U#yYH%L:jcx2Zr[6aKԹ  %/w ɉtC5`?_GQ]XbGc9:Ca' F64E'$ Mr}?0,Ջڕ:`EЋuLs9NnqjN l3N0f}H9P}361.NXd):{ǪSҵ HsI33t5F{'"x5]!F/ a;vC>8i PG6xo(Rtgb}kjAvY֢YP bxZ~0rF >B%xzšޠWomR|-#?D /Dm@JUuڗ/T' aw#X"`4%ZE]w!+l @'F ?\3@9`*RDtO=YUثS^Y1z81R>az_tS7'2,JǰBْ plwy/2BԐ> 766y `q>WPFX5 7H!&Z.t3gz[ěB! $/ 2 ;8PXzk2I~& *y!\xT[m~fonsgJUĢiTXR`{rmTUg{ZR?ԊY̑gBtzHY5$ TisFw/%$ 9%!c $hKMg$AE1rqW2E/8$z@̮ 658J 1X+ H?$-ɘ_Z]O8H~0X& uBqF5jXג ?Y6O׸ߌ3I(EU8D:|zޢV8 L3vO!TYPa^3Ooa-UumPm?O A[|ѥdͭoTW7n3MTl\Ju:{BQUULe+@.sVU<p%'j9Uy^qLd@Ob])^֧ WHw\4QUg<"KqGgvw%v7.n1U6 PJjj+G5b *അ1.7 -}ntS+B fa|;D#o[T!gW_|ŨII <`}x+M۝ϛMAut/Z_{ m{qv=&yu}&5Y&-=<௪UrYJ4RZ*:Y900޶o%'0QTaps$3Fџ Z.>VסHo[s`*Vɟjıl~% kX|@<DCs`QW%FdD4Bhry(dgzx]]Gm0 r$anI j}D 4՜_5kx ǧd * ݪ^ U}p_:B+XD eq) 0Z}RG^rqꅌ<_?Z>ylUVeTA.M@yV۶,["ӷ:ulXY7U*˯a)aJ۷K/|]'_~Ֆ*Es=-V-gNKIv,뿜m@j-+w e}jeɚ )} g$nM9$ߒ  Xf&ei餋AN.`+l& J.ݰF ab hRط #IK6$aNٔʞ Z?c}0ǮgӤ;_lQ2wI*Ex g(НQ`$Љ ٪zB&dj5 lxN/<1%TW/)mE7ă.G̭ph8`hcBSUӧ jH%yM^׍f y`2#n9Q@6ַ!Ŧh(k%59DD8y >8 Pگ)۱f$:)懏WmT/DY]>+!!zh8lrՆfx^ E: ['S+tXm VЖha-Z37?.ʻi: )K E3Ead_iu_|MDQMoF7}>o__ύCX,\B_BԆ7.ug҅X8ːX|,9^,S->,y[yIa0u4oJ]f?%zFS;8|lEib!OD¨{I4] _0VIqoq1:C@79Tz+Ho!\E-RKlN 5a!Eg nCK!񡠭 ]CiP2K7Kl|uhM=ƒ=AEiA36E #7%6"Wқإ5te]"N (:R{/wڝ?V!X:H*nF>@Z 쳦s(=ɔmC12aP^4A5RLj$!,"@xrۮAs.*0\w[k`ܯp]NM*ٺZa(l.(Ca!yYΟ]&6 ;8-Os`f )o?Ơ| t:6^eo5[פ;LJs(TL((="lf6UlطLņcөhPB ٯ׀-՗40/%%??{Ʊ,L" k%9cls/9G 4F2pl=ݳh8 $izfSCCgzuvY]NBQ,Qj>Ggi -"k5xoͷF}02ZbFOT0U&BQyHp 5CeH"` :o,3?JQI{ܣo78N>A?H DzB<ĴҴGwpS<u۽a뵅ƅ./Jp`^DRE߯qt%>ںuƠ8Db $̶vFt aeTbU5E^$6RM\8N& -UДGʥ 1&Q,K{99F};>-~gmuf?&Q`]wK}Y-o#ޯ" ZC.7/n܏+J`#sб/<g4$VFEl I u_-I' <ܜވ$9T+ .#n>Vv˪PHiJ7}S\,ϷJd_kN,,}U{;{Pv]TGG%ucYڷ~wgEԳv]CQ`s.y%ε|:8Jc˞N[USh Ws~_?HN? <7]|ږBl~Z(1Z2K3 %R=ǛYFY8 wPʲHqKIۧ=`MQvH<[z}i3w/(> Wżf.yb%%\D<wG]YJbϞp6PrOPdPzmiK+{ytsvG7nxk9cc^3#]Ƹ jza6= )] W+bf#cOJu`n) ?J!ޫG?P?SkAkᅪ_5`i7UH$4c? Ki .ϗ[\\ JIK%Rs)K"[ɒpp;86.7)7';CϢeswHPknk=s"Oev&X!#4E,ѥϣNq%zaz8 ATN i̽㟠 [k~/DYfէ`؎_؜C ˪sq֒ZQe/lo5t8T[;tLiͥNKsU(E9LA}4GlZ@#Cp@WaR)W7oR;)n`Vho>9>!g*ۀ(ym`#NF%ЯJ2R`=GN9d0:*^cD/ Z6 NDj1g/@{s?"] w2sB0wvt ^'JfqGD/ףfh?mʣC"Y9: bo2"`1l+cȏa#nWĉ&Į!}B V8 (nW GM7K7.eé{!]Qđu``4F<"`A ƞ0rp7v8I;Eڌ]*p"=lA4W]߬m~]X7KC?N *y#71PvndO&1B-e2fW1$7%gqBPTP[cbXrj%Z(g'۽y 0NZ$ǀJGぅ{[K/j̧m np}wag B[{rOxvDV!AP2&ؓ| 8@.:`22`"zy'G) rwz:X%s-#*nL0C=#C?x-[ƟVY3iV;i±H<1@#5YfM F3ͭLlV5@0:\nsHy-yeaz7{uoDϧʈX0yrz/SbGOӢsW^{8 ᮨ1($Z 0^#+ɷpRE%V3Fg :vp::'Qzv&T;t,%"(St+c`$|^MQ;eHiE īIӦ;[@%_t0}t♔WYSݿ J韼nxC10?* c0@Q}/kU'][;DMo97`h † nM%@pt  jc(񠖂~)+ EϾgcug#X.?hX8]BÒֿ4i $?E9L-HKlPq(#ڙk^^sSts{Na֨i,#Ĥp舄7w^['-<[gRT[02,yi[T̉>cgYTDWz^y=X2+ɻ^R=*~/|-h>:s} +=/#gBp(?B45W2p =xB^]6]ɩDF5|m[A{ 8Lqx*m=@.i/y :yhH :#I5ï/@Sh'}Z'QvZHz~*e6:H$Ϙ`D1m=g 2 ˹btI"? $..\;ߵʿbRyXȘkn-TFܻK._::W P>/'&#\<3AZ^únj=WW_5^ΛwS&y|w0 )e{-G( @/ /Җ8Tfe h KN 㦄]曃鍺ikğ&=t燥R!.~Mb}3M3u=smfQDL*)1\ϝ t*8zKz %֊QhnQ:k?J;q`Z3P!'26DN|cR\,mJ@eGBZEkviX/ܭHsS{r]׎-AhIΧ{Y[ޞ9̱+OO\i , ^\\Y5s9Eo`Am; ^z+}?/Pg}&z+E8UK#P2Eh͙f&Kkj-r걵Rv]a1p @Y7C/ ӫ1sk5ZHqN{h)MryfS h7ɡ@,5o$9Ӄ9…$O엍͝m <=˽ݝ yvo,P-o Ѷ9 &-2j"^srx${ i#=TUBNc4 EhIy !qt,;Σe~S;/6_676āl׌\C|D=xs(w7%#zLd=ktxDVa%k1\7ʋwdǞ}I YHb6]%&[{l+Y(ױs%Y"'޵6Si{rTF¹/&ȭް}怮)<j浺mݓq]c2waS+H6zqFi"ahg *o=<*; e>- ( ֔N/jbX(fEuY T@TSKn0ʌ} `u@mp+e)e%ΠILyaN4JiBP6pjOǮd\/$Yӄc}0>G 7BYQi*VDB'7Ԉo:{;C#3w؁'1nف*Υ/an}3I#q l?n{F$sƁn 2zGv|h-vL=|uv1MQ::C?5QvӏբCҎvQrF'$RBJ ZuW-&Hd 5~f?]ǮjIQ]PqԪ^8BD +5/5&W%("%p|؉N6d.ڃGV3Kn;sN)'-#GhJYIbY@t  6}Yo >bz(B23#H_Aq"(3] GvuJ]u`e׋6#"\|*MxKRT]^?5<&Lų}Y[ 7N{PӜ1gC:'L㢳֊!P@x,M7)'~d_A::(tZ] p!3f̚#7#4fw%+(ʿ O( oIPT=zUL*2ٞ1kq%@]yulPE↸,ņ}2=,m&R N{F 9b .QqU*8ǎלQ(ly,2&2X9t㌾{>c})7 g"vV2ɧ47'wM Jvu{h(,.Yrs#6F#6,0([`<<!ϡ^M#?g}E~xX.cg UU3#`g8:6&! yC"혮wIk,ap_1}l loWjYw0n;r`*@h6̆bayM PzA ^Wq ~i[5 FEqEr ) 8IM!IM9Eql2zۙ!SD @5^SzOM:q?+iCmcԑlyTgGv~1GqJù`)wMQd_{euԉD b!),nخղ0:H9KemB)4 Gn!Av3SۤcW}崘k3"n`@ʩ-No9VU Eƒ}f)_OB)%axq-Yb'v?X a=u2&tW/66 80o@yCxl]N"r,)F>o0a^$o# $[eWm&+3pQ«zDo\S[ˈE+S[RJAVo68?ȱ۱=6t٨#}l"hP/|M%pa52/9U&ãJ@D]+iX:-XجwWfpEu0Gլ)#xNvm?R[xiο-gY,"2ITr̘/TH%R:w eln듚`?w@Kdl44i51=Uau1` }sHIf>k(wBw( r}ݞ&*6dPʱqm, I6%>;L olIZ?,bpw_P uDc#\vQM̔. QMv`Zpn Z!V8x e2CB¢iHt/q#40ILz[-TK5CU@%=֯he;lwT/kl锢L4nBBs07uh&ܻ$Y%@'fP%)a/o0.{!Ocb1͡/E $ GPhFkܕAx:I-UY}`k`S_64.;/f{i.;Nck0s V<3Bڂ3N/vv%\1EJuhXiaM8/ ^ReqżUz~-չ>{ׄTԲbR\(MF'[cഹPjHUjt{J^^dRlQgz:`~:#\e ʚ*v߼yxo61~!^\DDO`beG:&pf$rNĞG{;o-C-X20b冀/k[" Nm$|\Hmn{Ka\lmÄw^EIď8KTNcNMsb_D  rk4D$C-USem_NWUX{+oQ;-~*Ol*rj I~p2")>͏? @k^-[L+C2Gcr lթ"A1@x!NІAt'f8C4Rٯ-Q]tFqЋsi .p&; A|O Dpjaj<{0'%A (ˤk=lyڎ~(8Z0֖FI7Θ")-pʼ3^kY;󚺡ނbOԋ% wș!a)aAM'5vT~npvU3"+" ,ap vP #^/D\v(lyނ76BTpdH;gw` Vq=h5C:Z#9)PfW(\gtn_AJz{nh_JkN29v=K7<>*S=uHI퉛QuTkLЅ5&,ӕ5㏖HC;>vۘ[bK`3sQf9jk+z"քUjت`8HZ b vs`|13msN N%:Xa+ 'Q|=51-5Q5?xh.2x@2K > \ܯ6'h'(bDg׉qKBVcƅ 5='H06z<$'`:*0+Ӄ3!"Q@}t(s Q:5 jj[{MIY0I]r)u6whbkkN=|`Rz!Tl^j N P1{q6`Ti;t ^Cv5o{`y#) ӌ:`z=]7|X4LYj,@ %O"z2ث]"#YMm*TCMCV(8XQkUՃAUoQ,-S- ojq ?ʕ3s#A`DRnjb\)G$BAQKbQp;e4؀ (6 . ke̲粰 /{C"i "nX>O&nv^myX&BffrhSZ k[9&ng'c .g$b F9X7@BL1h~.ApL ?lr!Lcb(FR !'G@Pӭf,hO`8j"T2}ͤchD0灌HiaɧvS/0`(h ցx߀At|`0VTIf֌Dυ0#?SZd8Lxÿw߿6Ÿj[el/y?^ӑo]P 'thD'WX S+Ma? ^¦y joPKdoA߹0b(DxbhL_A,TlިlmDi+BCԴ<=Vڜo^ v/Qc\cS;EaEkD;j]G.0R}ꐰC2=Vvxx( KJ؞l՜ھ<|?Qvc 7S(͂0QOUIJptiJd\|@+EEwd+U G=e6A*V8UHMQՒoJKc!'KWN67ZwQY݁# mD64Cr)h/&n#DYZ\(.giDF)J_J$ lV 贏AR}v 8 ebWcr$m 2Lc!s=n3LZ.Vޓ)E2PlJބ5A&F9 :@_r:` :WsB̮|E}L`(`eUPߩŋ/(|Z^Ĕ`sk׍bHpGVo*~fwW[UR^ERQVB(ꮘn`PbҊ ŒQL3 g8枎vg`bѧV)(d{yJ1o0Vls6ˏVl߿_TjZh2cRYO~)栱a0-zˠ=_r,Ow頡`n\0jv:=r㳴70*:nj,k<VD2\`6CWk7|x9]QAY FFv!Q\G* z]"悆 -,Gj+Vpa㼜Z#!~En̛: Ԓ>j$5LJ)9l8&taw۽\kr},.?Rt'G !gi`U<ߪ}{]8^UǕy ʃe@H=>q%^%k|;G 1l+J*T/Vo=|~rPҋ1yAmO^S~l-,{̇ 37FƒٔrRBË,bA}I舱$89C?eR l-cPeŰzE\xCvkGsMd}Hn|za.AI ~D0f̅ ;qВ/.I"G t֪b)(@*|'E`?;c`X LJO:`h =/4VCb8 -$!rKqRWd/Wpu յY۫>zPY\RϪKK'?T_F1b Υ`H):dC|uDa{WD\_ $cJ%.W bCꍺpbxysl(T}@c 3>d]ȯ47nNfH7b^oNC "^ؚXI\ <@5ٴُG(0,#g$9!٭ܟ y:DFl lr 9-HqH8.ohxGrSn/D.@odKیqz-*33qyË4vY'.ntrq8h>qx@bz@?J+04DI2XGwF&mCm"桯NYkWU".5I5q(6^\+0n lT霳Bܸ~Y( 9E>11-' S8v&=%EjYdkԶ(&pI+t'xvSLծ3Y@L_wRaɤLĐJfno4^>85J&a~HQ0*af fBO`鯔M'L/A]kAJLy(b`2tWKuN뫠ظ#x!TD'%ߚҙULۢZ1vf'x~ob컋BIB^Wv%_Mח}}Tү__D6ljحbB p)?L 6L#LYȲҭfY(/8a؍a*K )4̫7ҸLqIMp<&{H~`FU(+Kϔd_ټ]2M$]Tff6BcxKM<)'Ss7:8;Z.uLx8OBٝHɴLIҳ~έS~1/f'do< {cxV܋W?ŋW\ߋ$xq 0FuK@wL)MlX+}a;l#gT?[cY 0R̋RΎOpˑHĘHXdREBnbD{h"߷{bo6C Lxi?"y9ʊ]M(˨ O6.8 r'AHe %>V+o0H3YZ萏}ZnRY}痯?/&80bSdYۻ1 zmw i?ƒ%Ǽ8ФQpꃶgJ[t@˻N6,7Oz3c^n'GMWffLa w&x\M0l{[Ar1csgfP:<=Wf2wZ #: &`{A*?y3⯬ A&a!h03yS})l+B52\)M~]~".)t8SSNY ASD,V@:CB!3{9;7w|#.3|MDQēQ11$X/@^}|+D0*/g7t-./u!+]G8.{}1=ꙑ阀ͮb\eOĭҳ-g;e$&sOmƘ6woK!u.xN}mS"$MCOڧ=suQ'd1(NvU;K-L[༇;q=NG/e)42vƩyJzqsos"c=NNcY/MڧhP2fWqn>}^!as@6N^:ƨF{@DMToϺDgXh791Z<V^^HA1./v "DWg J^mhB5M$WBC.q} a<l<7JBo)8=sI,UO?'9D#嶾*(ʚS @ir`NY@lc8G?n<~0~d&s`632GuBn{N!W.V.خ2Mut%8#u9eKB0O#Z{ft-|$MB@Gr2cY9ij6;{78խrҳ F-@ߛ/7׶<̓@R^P2j;>NG.6{:{*sپ8Pk}_Mj$S:S6#(""zy;&!7>؂+촻!.9 wiXWOemQ"i¹&z_G;`$TRSK1dËЀbf"NR8&Nvb'>a?Ǐ㍇a?<\:>bX lnic`m HT>Pٶf~t=ֿr7[fc`~ãu??/ Vfp}yfpCF@2]eÍFCAOZ# dM+eםeBQxp/Sjp"UivVoP3Pn#q#|ͥ"9G:bg?l=vPa]R?)+opwCG0`= f;g{ G_ȕ鏣jF>,Ք0AK,NF)QP(wjkAv^#SJ sj.9n-e撍.mc->WrWCD*-n*@zP摑LEf{󗍽Ƴ7[2KP%CnDN Px!╴=PrR3wSHYm]Q,ڢXWԑx}k8/Hn֗C=]7YKr[*rF=Vr2]$'$^"m65yEQt Iufج4NhN\N`vk 2iG''ЩE%N> @u:Ohɬb2$qv4pXPEY)o1xe8(ĥrw!}= ƨApY4@C}r LjxVՉ'@` AN0Y¤=}(B< kcLB tA{?]YۻM7;lm\LS NSŋϤnB0 .^z\t6_5v3B=G韬"7βl>)}WUtq:eHv)AìN&XeUOt Vr'k>w (hAw^#w vS r[(cE eA$7Qmo GAׅ`B&2>nF Ȏ>Khw.ҟu~g⿜`z^NJŖ7y&M1%dU򬂳ٸ";wY KS=~*0Q 3:g]Ǭ˨ay͝ƫ8Mg{(NV)H`-۠"IY8c'Tg@6X ~ktȡ7̲cU 7vrǘςI\&Y-Q{AD "iC9$P>i3#&/7|+ΆJzmS=.._]AjX\~}w;ar20XC5Am aЗot naJP{mlRAçQf֫ڷ5W4>JGyL䣌m)zm1I]I Jvn UaMkb*ja%}V:uLL%{]S݅j+K@(J4bx9<Q9qÆY3dƎl_ Vp|8XտJ;/6_Ƃ4UA_%gָ{֤z9!cx ,3@9v[7qGbᄚ✅?YM_%DƱrDqTL*lB-$"k n}ZDAǎAl>^*ߠS?rp\rriˈ }eK앻˒CE`X7%MJbUkM2\?¶@(^zA#tp5TWFURGBD{N=䑔f)f-Pcô㣒";:E;DhF֥Ar /ކ8ŝdhK Ln[R/#ZEʕxxv%G*GF(N>" H-?VOjU+5f2G)&XX](4#^QQ/gj,/i|T.. v(p4)Ec*!Xi Hiԗ! 4]1F]}(ǹvXiH@MzwVWGԖ<ӥ»\ArY&\t;@BjH|ϼNMaNyl3~qð4!a\89--Pmh"@8<IŽt~8HVW KZ;J4nƏ!C 2,|*ce\QS7^l(4BRӐepi@nc{s 7kszgCɘR֛,>xHrc{Ն2 ϣB7^L 4|B`e~U hnð1>؟bͯ9 |U ?*e1M23-w@ݓ7`IqMRWMi3cisc?>;ם)?Rɨzvwzݓ,BurCݔ,O8`iŧ~#KKKu|8yhwZH)3d}>;1TSQ^jt 4۷pl,;5 =n쳍Ц XKT\1k]I,9ǡlKL+;kČI5ې+2\~-tR,sD-w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w -S(20]3`->!ޣ'@.I1 GFj3go9 G(C=*Sc'Ǝas#79&b~q)GH(I`+/{!0t;"ܞ >{F DK59C9Ud͚g Vs b./1Gk/k~[V3%T/(ˍ2B|vж_?hNVQtuZ a=I5{~o?x.Gz$:= Čޠ`8} T>t`.4?P(eֱ O K&Nj"CН: 8JAcsʱ<աTޔa)/uF3)H[z<I_rP$7˯k{@ c(֙kרS=1۲t671hLE=?[}\RDIVB|Rk[5_p4HGfiSdNU?P5;Zɀkح\ydr@ѹ`oM| ?O>kyE즁 >’[LC q/_>jo16ZmBos$T xdEywR4a19AdDR")wbI?1kz-"@ń°}5 P)& {ܧd^ 4/TN{x$ pz- FV+Fe5,WM~CJ:Q)<]eM _wiupG9-Tf@C'ܭ*3=|vUTN!5t (1UV4Fsp_#tE¬PsK'>_wih_~TܟXƫL[*0'p;p]=@6Tb'0E}9ĵ4@l_fl_ J]ڤnWJL+>~Oָ> z?K׽4q=:@dtQބ? 7M¢HgG WZ͙n~ǔ:D@flX MD(h0GT*MvGnn W mUb3&=eN l9 Zmπ6-56%vJn+dQaEb7{##(Epwr;9ܝ}MNwr;9wᾢIpNo9;akS]$5ٿiͻAt;S6Қe ƵUl?i1 Wo,$Rd'I.M' ã:4β)%C5C|yϓ ݍm`7^m<1wXb) KF*޹Q gm@<\PZ4IӻOoUpc Ipf&3~py-R<ܽE"9-QRVc2RK9v/LzO4pO|7!C!-v>V3ZBٞS@W@nxVU?G\Pbɍ^tF E;Dc1ULGm}jxJR hrb#iEfw?72;@z\ﶜZ/ n!q ŮpK'O b?uX]OlL4#;p#['ÙmZK2_?ճ|RMZ?gt3FO\X?qD ,*wV4gW3f!]J tljhr.s$%;d¥d1lM' <ȥD~qhF_ ^Gi Ќ+I !ցh\6>;SLSM'b3i"ImImB4\E/㚑S9 ^T̴>Mm'I" .O{Ϸ)J|FnŞyH9'WouAnMdRbPQ7#?Ȇ!察 c._6[ Ȯ9_zh@r&ЊC_x+Z|IZNߪ7ϼhd^'A0S\l;oEC88iUBuL 2chמ6 cRtL*ǀ:M MmJjB},g:h'k硣[*hGј+Na/kgoom$rSL,JvfOHOZ5o:pDdV5e*CXRQ1չ,qj5ԩoc+Z׹ϰ(܇"Xcп`Q'h~'+駞G^}"t)sƸN`vw7*t+m*b!~*>Jq ¶,>?b,ҔC&Jx!oȀ<= D{]?xHS1=ׇvpDĞM&ءߒIt -UBu)8YPR?[ZB Yٝ͝^}gqvgqvSwF9㦛GPBis6j &لd 2b&1hȠa1e5f f34ޞA8U4iW2F f;ޚLW3_ݵ_lekd=Xm e'ʪ1uxIYJ4@3\b* a;7X _WIPH`ۗ'fAެF {8kiewYIJ\jƶ .lur }aY /--'Ĩ4ўB9=DjeE-s*h1$&"jڲӪxOxk''7̘#7B]Bgv77Q ۜ4nETN]y.@|}ǞƩu05J0ߒNqe6y3676\ |'ܸCU>"DB-T\ol4^<[xu Nqo:]=[ܷX16N@`_YNbi]zšT=0KP >~ٍuIG2G"AxL,dtp7otq9ebtcw5Cwʍ;vܸSnNw-R4nGX@:DL,UgԀ:Y k7 { qJߢVĆ;F3/6V;Ґ 'ȭ#I3QOy[opF6'zb0$$.j4{ kNоG8]Pa^22@ǵusNT61$᠉d_.vV*[n1 B牤u{@f0+A1L Ip( C yUʛ M߃^I @LgE6{fs ?76%a>fA C;]`ȿ! qLYK@Q 0D{aÌ)6VOC[ϭ;t`mA]ӝg螿1^ڬY4`0o@-8;~BVs |.fNF@lF'n|Pf/ʺws0O6K q#sClF:/X%Nho]0R2X]&KVcockzu)f RǴ"+ROT7ۊ@ɴtCci՛yq>Yngy| L+^²cZp,TQU=،4~ܰ.9C*\QiL澧^|"'\x-ڜ4}DCESr(rVxOzz| Ἡ"3Sv;f畇ɱ*jlC:x!ZR\GzNOИJ|G ޥz~=e[i ^kyu7|>=ްyFg"0S=l+SYu&_уzV]ZaiD "nCa,HɅRhnwSJyW 3Z̚,8G\v8ozsIHLכPP!dt-vXum?Le)MNniʯR+.">X2eo5NxR'.V;G.SaƖVyeOoj@N p) XE3G‘gQN1IUdhbC;oCDF=}$c@ϱ89^y@0TAܻN22S龣"ej-;&|'¸ZyDfPŋr^KZz1wzv'=JyĦ AS!ac23(c%( JvlӏGDOITDJN+i]=߇3u\쏎ՅzhG#+3\-UWl++U U-WPl(Bk:^"Es:MF 8Zu^Q ׼0< ;RZ͆@^8:ί:'g&uوO%Leߨ,zД ֒gZpHP@{wu(O`\,ڇ36tG+ԑAz~Xfc _!tM;, uc6XwKO4 rwււɵwW`|&i$gňػ?ȴ/{tc#6;(bIX 6ZD>x @F!g-#&̌U0GC>=[&9>[-||Z8'"-EPYn$<5'#D*zŲ,E,ಾb!d;~iĐMRzq[ vP{|kY_Z&*ޠyF{ijirJj&z(;zN=zSީGԣw;zN=zSީGԣw/SܩM&wj;ɝNmwUhҿ.Kҿ.ʥo:lޢ=h >̐OPYHBH^!Q_}I*aQlh͠iYE~;h=س0`4had/x8nFtc@0YKVb:2M=mږ,5Kt8n) gԀ~N|q%M kZI90ɒQls d@/,c\+KJ@rhVcV\,Y::mw66zK[|g>9#;Q Ɯ4Iø' :odOHRڍ,L0 @h0> xHzXvEVvnFfQnM^1þK4Q.]Mܝ;# F4%_&ZySymlaz40]`1]/eMZvekv8f6~I]i^z7=zPw&If8h!&fStD3QUaڭudÌ2c ;+lvˎhߊiGbdAv|$ r@\b ڥM4EҦ(\DQSInD hñA(3 SJ8͖'D*VƳ7/_n&y±5ea+Vzyux`8/WF;b7ʂKo0o*g^ ʯ|!TDPW~~@.oʯ^ Bߣ/J7GPRe*+ ;yU N9-"ސeKTO5•'t (eegR) J7xzzyP 0D񆸴io lU46O4źawNUO$@ALM?+y ΡqS1Ĉ`Fb#J=ezPх3j Ch ]@CLLJ$uiN AE ppI d8f[~ȁ (cliPR稟9u@ = QU/<-P`P2P`@ţRŐ#,f [Эγ8`sD!, pGC"^@*Tqv'L?9i7۰32D%o:/`Ry5ڢx"8 L \b TSs>=SY;aԃ~5]YЕb(_V?*.?nI*yUx/+?4/ՅR_82, )> h~8?9~#EQxtsenq*Eq\ 1Q"M3AFF؀|iNP4|xMwox\ݩB^;Igfbb'*{M^PUe){̂ށJ(`xYddZ<8!J_ pt#8PBu?( SYN˼7U ;07kZ+ 5`G%8 rs:Q=C8PjKu\2s?/7Jh6ljwgIlkYwY3 pp+v"~^ǗVό@S'|{|MK6>V4T@B+ YE.0CChʓvf`VUܮa5o7@% h,{-.5=KAlt2|TΒ7OMtãiLx,b69P@>~Dn"Vh;v1;zG;~[50`y0?]r/礤e+/Rq-ޭ M`x{# .UNF|oH/y {0)Dm8ZVc5ɇ.ܶCL07?>-Wb׉vPʿCͮ뎆.Rui1*I 2d"bbpiHk,9w"U#]ԏhZ|2]X`\Ugp\|t[Ei|j.GC~`?n?X;x_>  |cnl=٨3z+#<^@;mgPqZ5gh[EI:D%YrQ6TސNn)Q/MNi _D"nwDKkd*kr$ghX1wS]`tZ#kX!,(GCr^ᙸVä9rV zDTP gYX 8wWZM~ESt#+$˸,S|`MW|?")"_K$BG1Aj!VgL4ؠ=j[*@6̏~X1ZV->/44h:-eQQ^3N3igOձ#!۾u A51NRԈ1C _dqtдTl%AEoH!EbHGԣ ~4p@%WOT'򠺨4K Pð*ձ\]dRZu$, ڬw)١|hP,y&!6hR[Zʑ׭JivPf#s1+:Ou_',E 6a~߃#}>zíK ]-ɵ0Rt!k PLR@RX&> /"D>Z(kjxs!$HI`Y3Gy,Usr(Sp濈*Ob}~~pae'T@-A+m66k[{YVSW?@%Ee>2<` @lW˦0Bcn3;ӢJ'IAF; bB[i(9B8ebdګŮ}jʥ&QG`@V'#Ot,% a$Y.R![nd~ EXcF򌷋BiY  keHe4 RQTCdg]?Xwn9_#iõ(}uk5D--*0{hy|c&x U׵oT[/hjBoa) .2<Ӵ&{+6|->=t?W?oþL[#[4AjmU^8BFZַc?@yS$=2Vz;nrzn/>-Hѭza/_m[wv_~}ۿMQ:42i{/.-?x@ȎBr@p\ncNc=3w"ǟ\G!Va 6 M`La:wOZ 18҄"~qYRJ:S`Zj [v{b`=6ߪե#T='!>@ ^GyS/|lĺ3Ԇ/jvU92#^?˙h*i=LW/P=[STv̬̀E@CXpE S8ۦFaauU\RyJC]7 +d=W$ * m!C2vFC>5/p/AX+È2xJ̼ ^L !;$uv1{0"h6q |OGR8/%"RY7kodepie'@WXH\9QgP8Q9<3t< f؊fttûL*7'TO롖A+X=vu3_-2*{? ^];ڂct[,58i6`u B=`ItU|Jr=kIeRF;' ?^<̒1d H`nwAsz51ba ácfW/Ha[ [5:#ٰ`V9[ﴬj3bqY}U/m%Pe=U PCK $X_Ŏpla j,O‹ ՅM*?,=eCX4H`,`wz}tas=TQ$b*88X=ӆgvץ] }lƷ=1&vw³Xok3N2-h$T68ٞhxR L2V M7ϺAKݿ7V1ZX*0Xz(Qڷ$ jLOF ڻ9C;Hbskc_f5&6kS. TubfV"?0ejM Mbu過%s 7jm4 c} ]ۣfq?u(*jc9v- Pr&5*H%OgGl0BhGMmj߱GmT؈V4t3@$R*-Az#'.`@ ~׈}@ue!"xjЀlqػ׻[ka--ogZ ##!KDwhvS+?r۰[[D>r4p~ן9u =im=5ʆb h^*w;EhJE#LMCE6ʊD:8 FG!(2IN_.XhJQ*(tQa,!qIR^ۀIhU&,WBAS` Y(I4=GI XEg9h>_T)aa*1> Ol '|/-~&f./1}ťoJ0=]ܞqqLyU`z݃%v.hP|jcADkB!3c"]yc mӢb{ҼųL,kc߱l?_Cv|;zh>B "4wfnCG)ךx2{ #[פT^UdJgf-PeCRyt6ɤ ]BJ ]vp m>R#*n, eN{*zdD$cpv [+h @tlCGccxNb破(Q@ ܼ 3Tr +cSNX7+a V@e dMS9RA-e@-=]E [/a/cвUsfGQ ?'O%-c>d yӐ$\MUŜ2|5HTMTm8~,c{㼺VG$%Wn?$$H(8 #J )mFZBi`dk7PaY,jH8zр Mmiu7qhN[+RV+_D,qLF+ 2b3\M8x:d_‘R/|M{g3s\YSUi F#ŕAՏt,0a3󵷵~^V,ۣ\dB1C=e%6!˼yk:\k˶ 7}|R7J)it_C ;S?1w~.Oo`k~_7r+0jOX+DPїJC OK?:,U9 #A!}?z 厹vX7J=phy,p}̽_0@-ap5DY{P*WH.ʪ'*ø q9|&%h;P|Ɓ#8D%wZ!^d{zXVQEXN5P$Vߧó"| WU[A×Kb=3wP h I>=2.@TF%K>WtEjDuK|4G𸲲h`K {kڒ0!U]nm|Ωu8ϊI|8hG?zOHȚB+l g0/KG}Ad ,"}29JP5&0HE,'rE<˿ښp~-rn*&2}X^c Vb`ǞQz~Paf`щ)ڊ#@>$ݏm"’Czr>OoN_.Ч: xpCʡxrʏDGz2,ĕ."Vo9tuP\c\20Q:leQY47|8Ch4r=z!ɧl )~5PxZd&@pܕV$ARf +H8bU=>/ztva%)a{##G Qtfy9k Gߞz״:Ft-bT.t3C!e:MD퐲z..o0h] ` /;CQXlm ɷ08;dC3!1|2(e0h5~1m9D5 /}~5o>QbJ$B!a㒭J5rpX:,XzP:,1$ˋ.] ?=|`UY*/+VcqY{zM{֌cKKiw 33c9}; w!XTs16 9\v:c1;rK8 9!miSMڔ}k|,␙ H(b${p C򚢇F8uN˿[fv& ')1=2< Lcv]0k#i1 Y[/\B H=H (ImUZU kj``?SLѫe5d PS[=fwJNKhLhBT7#\7k2" ?WsY}>- NjA_=E︨i}2F}ӃI:Sh8P׈ 8%3-iex7Fh'9gsС"6gMZ7'>[~vq5H+ XK8VdOw?Z E$}x  hPEƂ*@ά+`6=ȯƼiuuzU,Mq܀ՒF8:,2DXIQ#]:Oujk J?.p5VZ;%_L{n(~ZpsMzX>|i)FioZEb@8Eyşݓޠer[Y\źKg&\͢ Qi 27|΀.lH٭m_jZoV?d"ہj\duORꤽRnXW8x1X?zfj"](Li6z6z< &sbѫ]#>pqH7AsrQNTbpi~nLӟk.}o,W/?urYߣ\HUBfbQ/| ZM9̗N: sA(3:!nڝ8B<[zƋϥ5a:yA?n稗M:I97cTb}qA+{bA^^/"JwXwIyY5n?c ?YNȷN -E BE`e5&UGڝVQ@ nɘ8/1Rs딶DGnI|Ɵ;OrA2Eܼ{+C8񔷍U8~Wg}\#N*7+f_..QTpo<5EOy]=:4f;Pg;B́$Lr5q)/Sj.3, K0[J$Yr_w& %c;\Lj?(RKj1 WtV-93W+t`  `{eup_́r,2w1f;hZp4E&rᕕMmɄM3rw 2h8[TVI?lOtmhWElv=+-04B9VTZ$Am۴HrqƢ!-V8z3h`$Y2"yl6R4kMgҽ{`ŮĻEoI#^AbI˟Q^-j:s3λIX8T_ *CQkefvu;;*n,!"rd_bg5q9JY|ř:¸@% G=X,0Pu%T) cV MZ~^N0u윂Bs!2\IlC ޠDB6yu &@c+5;AFL5k<(Y%&7)Z  n34sl:]d[#L%gd@M;^/hQ!<h@Z s$FeXLosY18ď?EdbGV5m/|ބLȒ]&U wFvd6+Q~YVG狎/r ܖ=HL_ݵЛI,昩Bi;% #ߣAaefgS"j|Mtg=7#,(ԽH]7ZAYŘeB:(0/:@|tGG~!Q[hs(RisJ7iT(k^EbGbŤm iMF@9ЄHPAS,44Mst~YZzdgq|Kt&33=Ph]nO|Wn \DZu#XŇKO>| G-f'~&bu@^~Qd <`T_Qr G+cq..UrYo.bQM~ itd4`D|2T&,'0(^D8 YQ aJpvGǝvSm~#,@$<#$3.|AGk\m@HC[KzÑ(&jMUxӆ$>}0U42#7jm7$/ֶ~[5),)w$ast э![U֞mnm%_llo;{jMlZSovw7(JqX`r-o7<>@mVbɋ@<"ndhM*e M,+VǙ-Oka1׽ˆ҃Z5Pz}BV{;W{bLn( yq|#Pv!')=uKTc/l7Oàhӈ,^5P7)N9Y>M(w6~IƱBLXu-3TXC1 +1 }8(dcVIŋ"2%?Ӎ*NE9 w0p08t۪7{[e؂>)z%7]p&$ Gmq+9֨۽TxZxP?mt)YjUhU/P0jB G#@r|_ǘAqPenh.Sma%Ofoũ*SJP ^8NQ=@hIvܸ޽gϻ-%:ʛb/A`c`_p'@-q6Ć2piBp MΛZ0S>/e5 &e@U%ף +Ūxt$Z55P\՜~ʀxWt#D;#'y͡٭R ږ4^v5v jdPKxY<7<_C= \|XJZ(b70hzַ9jn ˉ&6_6~o^_FyMϗ~hloǻ[wm_F(Ի/t0-][kcgsrE0'ް>^|9\(.J 7CTɎ=2㇍u[6ߑPM)lkgo.ٳ5RˀW;k[\9r 7ąwI~gJ/3_jJkVI[k5p"y,kpR$޴FM>XÁe&J@ 8~'bUu7j5zielij~ `h Џy9Ue;U8z`MA滭al!0"b i; ʌ0խ<@A>5 5.fROFzFzi:h?{g _& 98 a%`cn) 8}j gH-d7 Z0TK=U(&Qs5aKÀZa?A]罪q@4 #llKۏg8NMuSOUvq;<[;/W٬c;f47\tf+ܯEflJG$/C_ O*u3OYAQliJ]f>R$"|`A*)]֡V@ϟOݐoQ3AhYGK<~'?ϔ?c};;1ҝiϵH(hd tDZF4͐#vJ /j)22_W>0}xA%t9Kc[LzY{mͭЛ\#&HCt5Ū)ńc/aC5FF)'\@/9*kXtXdFbMLd{݃Wm$-%KTx]^\*![17lC{b[ϣ'`vv{/ց~eG%-K$%0<='4r ccF  !I `鲥}_a.p ,pm>fmYerh!5kƇ1w0q"˩rpu plf8ǽ9|otރMrfEIf8%ܸY2J$:;?,sJޣ!UoC=~ F#Lô($S h4?/s?Sj+@!dd8>œ-BHX%ML}Oø =e^EۺXSW B&NGK(:g٤J1K+h #a[(ֻwfDe`>8󍭍 -䈓Xxpyȯ5Og )HlY:jfZe4S$X~6IDQ$yg3 7"0cHd9Eqw E/3pB,,B9-N%ZbggZZzb$9NR<^ť)$e!qQV 4l6`>i7yg3#]L]`ҟTDکGm@蘮b2!VA]MyG0H;ƂyLTSI0עtgti *c x+z-E%a܄"f]U EJ'ZS`d; ,^Ra//E~z ?z0~, {Q5 vvv\ST{Җv^߿xٔQ.ǭQXWߗ⬦;ӓ#(]Y2`ښX' lY4lo>XDM{ I m)wj#QRn.(2YitC=I XCv2 `fq--'ݡ[*^ouoPc2Ԛ:}'k)>1z.=jHQE[Fgptwˏ_ufвِ4G2[3=2ͪnQۤA Ajhϓ0;:R\ xUM_WsnYD`Lwa~\Ʃt<SːHH6);ESE몕EJ- 90| QDZԌi |p7[ڒGVk d[wzThlTôazAb.^Չ &Zt Q9O{Lbߝ刯 ÎC,=sQëdOm~0{ํ7m1$R9~'ᕊp $Ek/Mwf'8LAzk9O{'sINR8CYܾȤJ̼aE,M2*8@s|$)D))-ZbN ͐P,%uKI0$+̯%WXiIfelrm^kܻ c,ۖmK ,*h)Iq@4ֹtemzth$f9Xxi8EH3 ̉矣)띶1%#Rڌn?[A94Tm'^XrULE ,V"˞1L$K=eMQC(C[IRqwX .uB?8(@8WYُkwn촽^'ՖK,&}l*鍭K :5RI'eifWkSO/P9G4-[jH#eo@l;EKJzܣ~-qfebb3gOު$%dq]?"zz#kdRdUpP IZ5v-~>{e(u."F^n_!3QiWvޢ/}@%y ÛmH>=bg>q,&HR(.OE{ЎOUL=X&W~rXsJ=XJOލH:M>3V|(Eussvƹ+8',Aqhv®㬹΍3tY8B\ĵʊ\ V6#ўduP؊Ft:oIᖤ=v襞"ñ.uoBվx. 8Б4 vTM~]unnĈN]ll8&I>iu*;alN߳f qC'Ƀ}=iN^LX' VͥV ܤ#GYS WѤ؃H Da@y0Fn=f+o6K \E;$u8nκL $Ly:urREr'hɚ`Lq !na&nJp[r 2NR)3LD2bGnƴH2(fwEz"2D6dO&6}>u4 qf3=>k (ڱ!#f/?i X/xӈuOkv `Y[9O z1Rܖc|W*D⿗ {ʣeN 5J$9\߲Gσtu<&ҕtXso\(߰L{F`:Zo fWUrhsNJ-j@pA>&LA 6?<-/ύ{{ x wx^?R8&¡8Bq0ya$GL'c?¸u;>S5IFDn~IEӈ]93q9y/^_?UM}+NaäOjZn&: a'5 -1+Ż1b"М:y)/l:*H_j|@ *fGۊꦗbQ̍<M@g+J!5࠽+.<Da(,QGE7F[h~Eۏ̻~7]P{ܜԤ?\ I L* 4%byQ>F"mr[օvGj` J*P-7pJZ}gAC+``"On\ݔcsN%+vV_O -:d:/_AO H+w4gȍ6s3k!9Qϧ82\8:@/*U;ER.ˊAl^hHofmř2{y喋h0VH)ȷ4E҉L/r"mlos2vBp,6lbg0#0ܡB>P1S7# D/БuG7vˏw쏓G+2@*veq+$ry,ђu$E/Y!;} 3BU&sUDh"['v% i"8QI6 -M# ;sQĊQY+N9t:"ɧ]Kɚr fi%RՂ=/)~)b:<[ -me͍ƒYʚvUM>ݲ&AcowkG^G$w6 V^:SuU9/ 4ו3QhJ.!#ǁ"Lb~I<)2)fSo6Lp0^6ʛ\)JJIHG.3#u6v$p4nA`eeQf37mi`+t5|g/BƜg2"`=@[c F HF!>,!eWؑvNfk>`XQGm]/o$Z'`:l`XO, d0X`oQ [%Cs*-%<<?Syv:ߨ:ԉ*ΙK7OVtXr UFul5^!~C>`qR@#j;HD!)1j"P=8,NE؏aFDHs:iig5t&Mwe2DB@.vtѦm>?~>U ߗl|#M'}'瀳?Z\*/+ƋR0_:v:m5ʳy"I*LJa[.8Vg4+SVqokI *X-Z;:DDzqN\<3yuu3!ԃ*㇋y^(`SDOeޗڟڏiB.{mcJ_k3p(Ui:"M2S %U܆Hla;O5"?1Kk{BK8/_xYЌ̠|xP)ƶ \df57H Cp}XT#QfiYtDIWzHqM:Phm>,+&rk~cc\0sE[bjm;ذd|rp:0"_/ЉPC]P4W:]lM8>aӓ8eVFmد\j`'#+*R&8t$.7MpJ)eKca]1M'tiۍoC-q^I;ؖGiu2Eck3u1yKHťIs/=Rc0D$_?dpl/mS"NtҪ* F(t,. Fz|RN,6K(_O;rZ( D%j"UL {f^ WN+Ђ=>Y~Mm#b 3[;A҇GVy|xh]?'aw>|Iό Y:g#p{X^WBEfvݵ HR{EX(ǟ`z,|$+h 4][-lؐ+l"h.ךB7v>{I^cJ]aT } ȉn4vv}TrjXt]zR[o?]t;K<0> iFÓ觧y[H0b@™rryuKĆ3RGniMU Ce,pt"H? 8Cȴ[ i"1 f^h֦!L Eij4C&ǎP-Iv5? jĒHGo-7yi^4,*OgF:"nduͯTM3U>- h ++J.àAjwbϳ~AYjނB/9b3m駟( 6:i,5WuzWT٢8óY@ȂDJczLݶ烀Uٕ"a); 5Uv7' jR8n`زB-jk'“]Y`x2f4zI,Jq1Kn(ԖRX"#c^"ǒ6YK,-E6kw[#sz^~Zdq7tӭbwaU${6>ܰBcAt5GQg<:IDH$P+-'ߒzjMv7y`Fh>b/L(Z1b -*l˂VDfZi!iw@UgHإkUI< HeQptTc2+i݉{+bhДgӽ+oؒil]Qh$ñψ(:+mUS{Xjbf!fW jT.Nf`/u7Weq2=NkCQχ6Z,'B׏Z?]"1'Ob)4/jE>0=cJiUւgOfʦ n>S^t*䷐;s# G3!QiSoQL≠Bw?80s߹xxo]ӅǕF(z6v@1E»33SMMn.]W^+ρEr04x#%EJ7(wq.U=EwyB"*<#>F)<'D3v]4]oSx $M 9Q2@fW bFlPjD'JO҉3FG#]4ď#Kpem͆<@ >:'#=s|/EĔG+zG'v>P(+3w W'^yɼL۳^XQPEj[4-Qd{5SYW0uI)mGVsL7I+mݜ܋R<КDۅsQEFZ9 iэ7 S?KmShʲ$_;i]A؀nCj,/XwoihTX|Oǻʊ^BɘkkBl~z;^ Bә -ć>"sGNZ;=Jt.%ؗCe]|q:NrG1˙֌8]KLZ;W8`]d|+@Jfƌ7SAc>,9[`A6 ̘3(  چCYo5~o55zk!s l#|Oww݌@7@מIxcR#R{i§Iܒ : 7wrn*28NUcdzQsY[p&zgmWyO*`M!;7MGI6X)tcEE!LjsKzYH$jvX=$<]|V˞[+C)*&<0`)X;K$]${h}DadW%M%$pF;9- RGHO C2DHP08r㴆rّ6p~| M2ru LsMAUk[fR5@!b?) 0a\s=3܊}5AWX:j[m<~PuلLoUFY%G95~0_y nўdNT!ThRǔ[ B,`ʐ'NPu/^SܱDHVjFWs'}##*`5Lj? +JZpHB=LWt5z,FnMKMb,f WY:JY j|7IV%a֛ݟ/Xpq0=.)]a )`@hJepwÆБw9mml:mD5{?ݚJf Mttr 9DơшOlLlepS~X'І|" T l5?Aěw)笰Y9Wky-E;-> skܞI7`C:eTg0?FGƱkixˆ||E ţNɕ@X$@mK Gn}+ݟsx,|b %CӼ?R緺!'âR:t(3O(] mQJ #69ḱ] running `{suite}"): self._skipping = True break return self._skipping class Test(unittest.TestCase): def setUp(self): self.rundir = tempfile.mkdtemp() self._ensure_litmus() def _ensure_litmus(self): self.litmus_dist = os.path.join(testdir, 'litmus-0.13') self.litmus = os.path.join(self.litmus_dist, 'litmus') if not os.path.exists(self.litmus): print('Compiling litmus test suite') if os.path.exists(self.litmus_dist): shutil.rmtree(self.litmus_dist) with tarfile.open(self.litmus_dist + '.tar.gz') as tf: tf.extractall(path=testdir) ret = run(['sh', './configure'], cwd=self.litmus_dist) # assert ret == 0 ret = run(['make'], cwd=self.litmus_dist) # assert ret == 0 litmus = os.path.join(self.litmus_dist, 'litmus') # assert os.path.exists(litmus) def tearDown(self): print("Cleaning up tempdir") shutil.rmtree(self.rundir) def test_run_litmus(self): result = [] proc = None try: print('Starting davserver') davserver_cmd = [sys.executable, os.path.join(testdir, '..', 'pywebdav', 'server', 'server.py'), '-D', self.rundir, '-u', user, '-p', password, '-H', 'localhost', '--port', str(port)] self.davserver_proc = subprocess.Popen(davserver_cmd) # Ensure davserver has time to startup time.sleep(1) # Run Litmus print('Running litmus') try: ret = run(["make", "URL=http://localhost:%d" % port, 'CREDS=%s %s' % (user, password), "check"], cwd=self.litmus_dist, capture_output=True) results = ret.stdout except subprocess.CalledProcessError as ex: results = ex.output lines = results.decode().split('\n') assert len(lines), "No litmus output" filter = TestFilter() for line in lines: line = line.split('\r')[-1] result.append(line) if filter.skipLine(line): continue if len(re.findall(r'^ *\d+\.', line)): assert line.endswith('pass'), line finally: print('\n'.join(result)) print('Stopping davserver') self.davserver_proc.kill() def test_run_litmus_noauth(self): result = [] proc = None try: print('Starting davserver') davserver_cmd = [sys.executable, os.path.join(testdir, '..', 'pywebdav', 'server', 'server.py'), '-D', self.rundir, '-n', '-H', 'localhost', '--port', str(port)] self.davserver_proc = subprocess.Popen(davserver_cmd) # Ensure davserver has time to startup time.sleep(1) # Run Litmus print('Running litmus') try: ret = run(["make", "URL=http://localhost:%d" % port, "check"], cwd=self.litmus_dist, capture_output=True) results = ret.stdout except subprocess.CalledProcessError as ex: results = ex.output lines = results.decode().split('\n') assert len(lines), "No litmus output" filter = TestFilter() for line in lines: line = line.split('\r')[-1] result.append(line) if filter.skipLine(line): continue if len(re.findall(r'^ *\d+\.', line)): assert line.endswith('pass'), line finally: print('\n'.join(result)) print('Stopping davserver') self.davserver_proc.kill() if __name__ == "__main__": unittest.main()