././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/0000775000175000017500000000000000000000000013135 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1672760869.0 pkginfo-1.10.0/.bzrignore0000664000175000017500000000017200000000000015137 0ustar00tseavertseaver__pycache__ *.egg-info .coverage .coverage-* coverage.xml ./build/ ./dist/ .tox/ .pytest_cache/ docs/_build/ .mypy_cache/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652972322.0 pkginfo-1.10.0/.coveragerc0000664000175000017500000000007500000000000015260 0ustar00tseavertseaver[run] source=pkginfo,pkginfo.tests [report] show_missing=1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454784.0 pkginfo-1.10.0/CHANGES.txt0000664000175000017500000002215500000000000014753 0ustar00tseavertseaver``pkginfo`` Changelog ===================== 1.10.0 (2024-03-03) ------------------- - Add support for Python 3.11 and 3.12. - Drop support for Python 3.6. - Declare explicit testing dependency on 'wheel'. - Add support for Metadata 2.3. 1.9.6 (2023-01-08) ------------------ - Fix various typos in docs / docstrings. LP #2002232. 1.9.5 (2023-01-06) ------------------ - Add stricter typing checks, matching those used in 'twine'. - Fix typing errors / gaps reported from 'twine' CI failure. LP #2002104. 1.9.4 (2023-01-05) ------------------ - Fix packaging of stub file for Python typing support. 1.9.3 (2023-01-03) ------------------ - Added stub files for Python typing support; verify using 'mypy'. LP #1876591. 1.9.2 (2022-11-29) ------------------ - Drop "universal" wheel support (should be redundant with 'python_requires >= 3.6', but just in case). LP #1998258. 1.9.1 (2022-11-29) ------------------ - Restore a deprecated alias for the '_must_decode' helper function, moved from 'pkginfo._compat.must_decode' to 'pkginfo.distribution._must_decode' in 1.90. - Repair unit tests broken by dropping Python 2.7 classifier. 1.9.0 (2022-11-29) ------------------ - Drop support for Python 2.7. - Switch to use 'pytest' vs. 'nose', which doesn't support Python > 3.9. 1.8.3 (2022-06-08) ------------------ - Specify supported Python versions in 'setup.py' using 'python_requires'. LP #1977981. 1.8.2 (2021-12-01) ------------------ - Add fix for installed distributions with '__package__' set to an empty string. LP #1952946. 1.8.1 (2021-11-19) ------------------ - Add 'MANIFEST.in' to ensure example files used by tests are included in source distributions. LP #1951553. 1.8.0 (2021-11-18) ------------------ - Support new standard metadata location for installed dists. LP #1865286. - Don't overwrite header-based 'description' with empty payload. LP #1885458. - Add support for Metadata-Version 2.2. LP #1928729. - Add support for uncompressed tarballs for sdists. LP #1951457. - Add support for Python 3.10. 1.7.1 (2021-07-09) ------------------ - Use Python3 to build docs, and fix doctest examples to use Python3- compatible syntax. LP #1933322. 1.7.0 (2021-01-16) ------------------ - Add support for Python 3.9. - Drop support for Python 3.5. 1.6.1 (2020-10-26) ------------------ - Adjust test classifiers to match supported Python versions. LP #1901127. 1.6.0 (2020-10-20) ------------------ - Add support for Python 3.8. LP #1869854. - Drop support for Python 3.4. - Update tests to match setuptools' change, no longer reporting metadata version for installed packages w/o explicit metadata. LP #1870197. 1.5.0.1 (2019-01-08) -------------------- - Fix broken 'sdist'. LP #1639585. 1.5.0 (2019-01-07) ------------------ - Fix 'console_scripts' entry point syntax. LP #1810734. - Add support for JSON output from the CLI. LP #1700580. - Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200. - Harden metadata extraction against unexpected encodings. LP #1780454. - Update tests to match pip/setuptools' use of new metadata version. LP #1772274. - Add support for Python 3.6 and 3.7. - Drop support for Python 3.3. 1.4.2 (2018-03-14) ------------------ - Use relative imports in pkginfo modules. Supports vendoring of the package into setuptools. - Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields. Per https://packaging.python.org/specifications/. See: PEP 566. - Remove support for old setuptools leaving ``PKG-INFO`` in the root of the project directory. 1.4.1 (2016-11-07) ------------------ - Packaging only change (invalid sdist built for 1.4.0). 1.4.0 (2016-11-04) ------------------ - Relicense under MIT license: the PSF license is not suitable for third-party libraries. 1.3.2 (2016-05-24) ------------------ - Packaging-only change (automate fix for wheel built for 1.3.1). 1.3.1 (2016-05-24) ------------------ - Packaging-only change (invalid wheel built for 1.3.0). 1.3.0 (2016-05-23) ------------------ - Update homepage URL to point to Launchpad, rather than PyPI. - Add support for building wheels. - Add support for Python 3.5. - Drop support for Python 2.6 and 3.2. 1.2.1 (2014-01-02) ------------------ - Add overlooked Trove classifier for Python 3.4. 1.2 (2014-01-02) ---------------- - Add support for Python 3.4, PyPy3. - Add 100% coverage for ``pkginfo.commandline`` module. 1.2b1 (2013-12-05) ------------------ - Add support for the "wheel" distribution format, along with minimal metadata 2.0 support (not including new PEP 426 JSON properties). Code (re-)borrowed from Donald Stuft's ``twine`` package. 1.1 (2013-10-09) ---------------- - Fix tests to pass with current PyPy releases. 1.1b1 (2013-05-05) ------------------ - Support "develop" packages which keep their ``*.egg-info`` in a subdirectory. See https://bugs.launchpad.net/pkginfo/+bug/919147. - Add support for "unpacked SDists" (thanks to Mike Lundy for the patch). 1.0 (2013-05-05) ---------------- - No changes from 1.0b2. 1.0b2 (2012-12-28) ------------------ - Suppress resource warning leaks reported against clients. - Fix 'commandline' module under Py3k. 1.0b1 (2012-12-28) ------------------ - Add support for Python 3.2 and 3.3, including testing them under ``tox``. - Add support for PyPy, including testing it under ``tox``. - Test supported Python versions under ``tox``. - Drop support for Python 2.5. - Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs testing extras (``nose`` and ``coverage``). 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fix bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replace use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Remove bogus testing dependency on ``zope.testing``. - Add tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Add ``Project-URL`` for ``1.2`` PKG-INFO metadata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fix Trove metadata misspelling. - Restore compatibility with Python 2.4. - Note that the introspection of installed packages / modules works only in Python 2.6 or later. - Add ``Index`` class as an abstraction over a collection of distributions. - Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fix bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extend the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Add support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Add support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Add a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Add ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Make distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Add support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fix packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/LICENSE.txt0000664000175000017500000000207400000000000014763 0ustar00tseavertseaverMIT License Copyright (c) 2009 Agendaless Consulting, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1672930468.0 pkginfo-1.10.0/MANIFEST.in0000664000175000017500000000004000000000000014665 0ustar00tseavertseavergraft docs/examples/ prune .tox ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/PKG-INFO0000644000175000017500000002556400000000000014244 0ustar00tseavertseaverMetadata-Version: 2.1 Name: pkginfo Version: 1.10.0 Summary: Query metadata from sdists / bdists / installed packages. Home-page: https://code.launchpad.net/~tseaver/pkginfo/trunk Author: Tres Seaver, Agendaless Consulting Author-email: tseaver@agendaless.com License: MIT Keywords: distribution sdist installed metadata Platform: Unix Platform: Windows Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Software Distribution Requires-Python: >=3.6 License-File: LICENSE.txt Provides-Extra: testing Requires-Dist: pytest; extra == "testing" Requires-Dist: pytest-cov; extra == "testing" Requires-Dist: wheel; extra == "testing" ``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distribution (an ``sdist``) or a binary distribution (e.g., created by running ``bdist_egg``). It can also query the ``EGG-INFO`` directory of an installed distribution, and the ``*.egg-info`` stored in a "development checkout" (e.g, created by running ``setup.py develop``). Please see the `pkginfo docs `_ for detailed documentation. ``pkginfo`` Changelog ===================== 1.10.0 (2024-03-03) ------------------- - Add support for Python 3.11 and 3.12. - Drop support for Python 3.6. - Declare explicit testing dependency on 'wheel'. - Add support for Metadata 2.3. 1.9.6 (2023-01-08) ------------------ - Fix various typos in docs / docstrings. LP #2002232. 1.9.5 (2023-01-06) ------------------ - Add stricter typing checks, matching those used in 'twine'. - Fix typing errors / gaps reported from 'twine' CI failure. LP #2002104. 1.9.4 (2023-01-05) ------------------ - Fix packaging of stub file for Python typing support. 1.9.3 (2023-01-03) ------------------ - Added stub files for Python typing support; verify using 'mypy'. LP #1876591. 1.9.2 (2022-11-29) ------------------ - Drop "universal" wheel support (should be redundant with 'python_requires >= 3.6', but just in case). LP #1998258. 1.9.1 (2022-11-29) ------------------ - Restore a deprecated alias for the '_must_decode' helper function, moved from 'pkginfo._compat.must_decode' to 'pkginfo.distribution._must_decode' in 1.90. - Repair unit tests broken by dropping Python 2.7 classifier. 1.9.0 (2022-11-29) ------------------ - Drop support for Python 2.7. - Switch to use 'pytest' vs. 'nose', which doesn't support Python > 3.9. 1.8.3 (2022-06-08) ------------------ - Specify supported Python versions in 'setup.py' using 'python_requires'. LP #1977981. 1.8.2 (2021-12-01) ------------------ - Add fix for installed distributions with '__package__' set to an empty string. LP #1952946. 1.8.1 (2021-11-19) ------------------ - Add 'MANIFEST.in' to ensure example files used by tests are included in source distributions. LP #1951553. 1.8.0 (2021-11-18) ------------------ - Support new standard metadata location for installed dists. LP #1865286. - Don't overwrite header-based 'description' with empty payload. LP #1885458. - Add support for Metadata-Version 2.2. LP #1928729. - Add support for uncompressed tarballs for sdists. LP #1951457. - Add support for Python 3.10. 1.7.1 (2021-07-09) ------------------ - Use Python3 to build docs, and fix doctest examples to use Python3- compatible syntax. LP #1933322. 1.7.0 (2021-01-16) ------------------ - Add support for Python 3.9. - Drop support for Python 3.5. 1.6.1 (2020-10-26) ------------------ - Adjust test classifiers to match supported Python versions. LP #1901127. 1.6.0 (2020-10-20) ------------------ - Add support for Python 3.8. LP #1869854. - Drop support for Python 3.4. - Update tests to match setuptools' change, no longer reporting metadata version for installed packages w/o explicit metadata. LP #1870197. 1.5.0.1 (2019-01-08) -------------------- - Fix broken 'sdist'. LP #1639585. 1.5.0 (2019-01-07) ------------------ - Fix 'console_scripts' entry point syntax. LP #1810734. - Add support for JSON output from the CLI. LP #1700580. - Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200. - Harden metadata extraction against unexpected encodings. LP #1780454. - Update tests to match pip/setuptools' use of new metadata version. LP #1772274. - Add support for Python 3.6 and 3.7. - Drop support for Python 3.3. 1.4.2 (2018-03-14) ------------------ - Use relative imports in pkginfo modules. Supports vendoring of the package into setuptools. - Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields. Per https://packaging.python.org/specifications/. See: PEP 566. - Remove support for old setuptools leaving ``PKG-INFO`` in the root of the project directory. 1.4.1 (2016-11-07) ------------------ - Packaging only change (invalid sdist built for 1.4.0). 1.4.0 (2016-11-04) ------------------ - Relicense under MIT license: the PSF license is not suitable for third-party libraries. 1.3.2 (2016-05-24) ------------------ - Packaging-only change (automate fix for wheel built for 1.3.1). 1.3.1 (2016-05-24) ------------------ - Packaging-only change (invalid wheel built for 1.3.0). 1.3.0 (2016-05-23) ------------------ - Update homepage URL to point to Launchpad, rather than PyPI. - Add support for building wheels. - Add support for Python 3.5. - Drop support for Python 2.6 and 3.2. 1.2.1 (2014-01-02) ------------------ - Add overlooked Trove classifier for Python 3.4. 1.2 (2014-01-02) ---------------- - Add support for Python 3.4, PyPy3. - Add 100% coverage for ``pkginfo.commandline`` module. 1.2b1 (2013-12-05) ------------------ - Add support for the "wheel" distribution format, along with minimal metadata 2.0 support (not including new PEP 426 JSON properties). Code (re-)borrowed from Donald Stuft's ``twine`` package. 1.1 (2013-10-09) ---------------- - Fix tests to pass with current PyPy releases. 1.1b1 (2013-05-05) ------------------ - Support "develop" packages which keep their ``*.egg-info`` in a subdirectory. See https://bugs.launchpad.net/pkginfo/+bug/919147. - Add support for "unpacked SDists" (thanks to Mike Lundy for the patch). 1.0 (2013-05-05) ---------------- - No changes from 1.0b2. 1.0b2 (2012-12-28) ------------------ - Suppress resource warning leaks reported against clients. - Fix 'commandline' module under Py3k. 1.0b1 (2012-12-28) ------------------ - Add support for Python 3.2 and 3.3, including testing them under ``tox``. - Add support for PyPy, including testing it under ``tox``. - Test supported Python versions under ``tox``. - Drop support for Python 2.5. - Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs testing extras (``nose`` and ``coverage``). 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fix bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replace use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Remove bogus testing dependency on ``zope.testing``. - Add tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Add ``Project-URL`` for ``1.2`` PKG-INFO metadata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fix Trove metadata misspelling. - Restore compatibility with Python 2.4. - Note that the introspection of installed packages / modules works only in Python 2.6 or later. - Add ``Index`` class as an abstraction over a collection of distributions. - Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fix bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extend the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Add support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Add support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Add a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Add ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Make distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Add support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fix packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673196033.0 pkginfo-1.10.0/README.txt0000664000175000017500000000102000000000000014624 0ustar00tseavertseaver``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distribution (an ``sdist``) or a binary distribution (e.g., created by running ``bdist_egg``). It can also query the ``EGG-INFO`` directory of an installed distribution, and the ``*.egg-info`` stored in a "development checkout" (e.g, created by running ``setup.py develop``). Please see the `pkginfo docs `_ for detailed documentation. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/TODO.txt0000664000175000017500000000054600000000000014450 0ustar00tseavertseaverTODOs ===== - [X] Catch up to latest changes in PEP345: * Project-URL header * "environment markers" - [_] Add APIs to ``Distribution`` which expose the semantics of the requirement versions and environment markers. - [_] Allow the ``pkginfo`` script to process URLs. - [_] Allow the ``pkginfo`` script to process requirements specs. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7637973 pkginfo-1.10.0/docs/0000775000175000017500000000000000000000000014065 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/Makefile0000664000175000017500000000447700000000000015541 0ustar00tseavertseaver# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d .build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html web pickle htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf .build/* html: mkdir -p .build/html .build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html @echo @echo "Build finished. The HTML pages are in .build/html." pickle: mkdir -p .build/pickle .build/doctrees $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) .build/pickle @echo @echo "Build finished; now you can process the pickle files." web: pickle json: mkdir -p .build/json .build/doctrees $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) .build/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: mkdir -p .build/htmlhelp .build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in .build/htmlhelp." latex: mkdir -p .build/latex .build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex @echo @echo "Build finished; the LaTeX files are in .build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p .build/changes .build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes @echo @echo "The overview file is in .build/changes." linkcheck: mkdir -p .build/linkcheck .build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in .build/linkcheck/output.txt." ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625835642.0 pkginfo-1.10.0/docs/conf.py0000664000175000017500000001371700000000000015375 0ustar00tseavertseaver# -*- coding: utf-8 -*- # # pkginfo documentation build configuration file, created by # sphinx-quickstart on Wed Apr 8 19:26:04 2009. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If your extensions are in another directory, add it here. If the directory # is relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. #sys.path.append(os.path.abspath('.')) # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', ] doctest_path = [os.path.abspath('..')] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pkginfo' copyright = u'2009-2013, Tres Seaver' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '1.2' # The full version, including alpha/beta/rc tags. release = '1.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['.build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # Options for HTML output # ----------------------- # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. #html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'pkginfodoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('index', 'pkginfo.tex', u'pkginfo Documentation', u'Tres Seaver', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673196152.0 pkginfo-1.10.0/docs/distributions.rst0000664000175000017500000001205400000000000017523 0ustar00tseavertseaverDistribution Types ================== The fundamental abstraction provided by this pacakge is the ``Distribution`` base class. Implementations exist for specific cases: source distributions, binary distributions, installed packages, and development checkouts. .. doctest:: >>> from pkginfo import Distribution >>> from pkginfo import SDist >>> assert issubclass(SDist, Distribution) >>> from pkginfo import UnpackedSDist >>> assert issubclass(UnpackedSDist, SDist) >>> from pkginfo import BDist >>> assert issubclass(BDist, Distribution) >>> from pkginfo import Wheel >>> assert issubclass(Wheel, Distribution) >>> from pkginfo import Installed >>> assert issubclass(Installed, Distribution) >>> from pkginfo import Develop >>> assert issubclass(Develop, Distribution) Introspecting Source Distributions ---------------------------------- ``SDist`` objects are created from a filesystem path to the corresponding archive, which should have been created via the ``sdist`` command from distutils: .. doctest:: >>> mypackage = SDist('docs/examples/mypackage-0.1.tar.gz') After creation, the ``SDist`` instance will have attributes corresponding the the fields defined in the PEP corresponding to the metadata version, lower-cased and transliterated into valid Python identifiers by mapping hyphens to underscores. E.g.: .. doctest:: >>> print(mypackage.metadata_version) 1.0 >>> print(mypackage.name) mypackage >>> print(mypackage.version) 0.1 Fields which are optional under the PEP, and which have no value set in their ``PKG-INFO``, will map to the value ``None``: .. doctest:: >>> print(mypackage.keywords) None Fields which are marked "multiple use" under the PEP map onto sequences; their names are pluralized to indicate the sequence. "Multiple use" fields with no occurrences in the ``PKG-INFO`` file will map onto an empty sequence: .. doctest:: >>> print(list(mypackage.supported_platforms)) [] See `Metadata Versions `_ for an example with a non-empty, "multiple-use" field. Introspecting Unpacked Source Distributions ------------------------------------------- You can also introspect a previously-unpacked package with ``UnpackedSDist`` either by passing it the path to the unpacked package, or by passing it the setup.py at the top level: .. doctest:: >>> mypackage = UnpackedSDist('docs/examples/mypackage-0.1') >>> print(mypackage.name) mypackage >>> myotherpackage = UnpackedSDist('docs/examples/mypackage-0.1/setup.py') >>> print(myotherpackage.name) mypackage ``UnpackedSDist`` objects are most useful in conjunction with distutils to produce sdists that want complex behavior for determining what metadata to use; these sdists normally break when installed with ``pip``, because metadata in an sdist is regenerated when pip installed. You can achieve this in your `setup.py` as follows: .. code:: >>> from setuptools import dist, setup >>> dist.Distribution(dict(setup_requires='pkginfo')) >>> from pkginfo import UnpackedSDist >>> try: ... d = UnpackedSDist(__file__) ... VERSION = d.version ... except ValueError: ... VERSION = (version_from_source_control() or ... os.getenv('VERSION', '1.0')) >>> setup(name='mypackage', version=VERSION) Introspecting Binary Distributions ---------------------------------- ``BDist`` objects are created from the filename, which should have been generated via ``setup.py bdist_egg``. .. doctest:: >>> mypackage = BDist('docs/examples/mypackage-0.1-py2.6.egg') After that, they have the same metadata as other ``Distribution`` objects, Introspecting Wheels -------------------- ``Wheel`` objects are created from the filename, which should have been generated via ``setup.py bdist_wheel``. .. doctest:: >>> mypackage = Wheel('docs/examples/mypackage-0.1-cp26-none-linux_x86_64.whl') After that, they have the same metadata as other ``Distribution`` objects, Introspecting Installed Packages -------------------------------- ``Installed`` objects are created from either a module object or its dotted name. Note that this feature only works in Python 2.6 or later: earlier Python versions did not record ``PKG-INFO`` for installed packages. .. doctest:: >>> import sys >>> if sys.version_info >= (2,6): ... dotted = Installed('pkginfo') ... import pkginfo ... direct = Installed(pkginfo) After that, they have the same metadata as other ``Distribution`` objects, assuming that the package on which they were based has a discoverable '.egg-info' file / directory. To be discoverable, the '.egg-info' must either be located inside the package (e.g., created via ``setup.py develop`` under setuptools), or adjacent to the package (e.g., created via ``setup.py install``). Introspecting Development Checkouts ----------------------------------- ``Develop`` objects are created from a path to a checkout containing a ``PKG-iNFO`` file, e.g., created by running ``setup.py develop`` under setuptools. .. doctest:: >>> develop = Develop('.') After that, they have the same metadata as other ``Distribution`` objects. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7637973 pkginfo-1.10.0/docs/examples/0000775000175000017500000000000000000000000015703 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1637271178.0 pkginfo-1.10.0/docs/examples/distlib-0.3.1-py2.py3-none-any.whl0000664000175000017500000122011200000000000023451 0ustar00tseavertseaverPKgPzS7]Edistlib/__init__.pyQN0 +,j cIՆZeڤr]n/&7H]flBCH`-}Ogla>A?M-2)3`|@x=Y]?]k3F0 @K?d-; Br#B^6*#,}};PxT#W*Ii$4 fcR7 8V9zko0u5 +RB ;RyTF~dq7( HβPKgP+6+distlib/compat.py}z6=Ԟb9%ڲsveڑ厦cIvu"Y#Yr'߷OVo9p_<<qd͑h޾8.W*mDp<O>=>eE*fdqZi"R4xnnB>Rl$j2 >`)M˴hyoNO^ͻFDE"^^>s-r)E۴U:l*+h~]yۤs'/kJէz]5hOwqj)rRUeu$ľXU2:E M+L,Z 0yV,Wp9Т9=SH<}7UZPQOSzܤz"F`$FXge}>n '_jqY,WQU#k#|_np~wAmkV9uR)~jeVЇzg|L-`yv@JB[K[649}POVQs[D˔IS-@)NA([%SA 1'{'IXpmW0#C,&PW$ (WDfz̑|mA,ah \*|\<Q WDhv~" i  jEY|kĨ^ B|UQ } QuZV,<e&yA]16-wt#-x(YSb2C X8H&O%AR˿W. ,CqXYs)@ KtVG; L$ƨ?!M= O^61 o1;So[*[q7!6|(mb.#A 0tx`zq8/㻴 olD3P ,.'~N9Bɵ9JcQQ)B&‚cT8tTwM 2> XI*3AE[Zwh^&\p? Ft:D ȂaBJR "Hor|b~oޜ>y>DPzSVZtP1hȟAg>˛:0t.]O[$ ./$ ؂ XyCKn{f3U\Ej_,5x' r9D $E99 +7Ȣ4?gk?i?q U" Q"yT=,;pڃš m 6FGO(RdZM?s;ҋo%2tԊ[7~ .lCczɤ?0k0 ,!`OUA@'7< 4zidޭMs og!&HH] J63qXg@kɲ͛ E]ј2^GMip>O*Re\mTHC͌=ɧ21 ^ceV_|Ro]"p>HzvDa9&\) E`TV*("2LF B {iB"ebﶆfUY!^ aQAW{ @P4 z{d4q D?= 6=wި39) Q""@@۠A<ϊOF>oGwDw(5]"K }LaV=v= #$HSd_r!1LGhXzT@f;]1f$ieu?\Doi-6kpY*M98hpW=*Qk^Frj&JB)Nk Տrڒ-d9GvzM2$KɴyvjIC hKE K@.;3-漁u)~ЄlCI*lA&F)ƺ5fgZ/h59թ`)Qe J@X"EƋGGwQ< ߎIkk'5daF^ֵ;Cy-\3 !{\^leWTG+Je_Q5MC,5cRǓawUAY@wcwqCk`72l %='^b*a%,W[\I )0@(c2 m)ƀ083?*X!l0C6"n룃!$[n])llv@;{E2S[*krsVFoǯ֯cR]EWٲhڐ:_v0HAXv]sЇaBTꆉcߙF Jl). u!eCJ F&F@Wq(n@ypɴs2v=j~ _MFv" E*n LmOb= xGc$tx0BّOLBBHKBUB:).-i5Ir0`sSuoo.^|ΩveJt$KU쥏ˣՏȐ9,9JQN *Am?to$tS_qhg@hclD*/tFl M(\>ұh1q0rNq&FFht B#R8hV/o!)M΁ h sE `a#tu)jMST2 )6^y@b̉&KgPY|Bj^7*pPo'W˙e/n4`\vȊd8k}\jZDg$e)-MŎ>Q=\)=ja<;?>=%+8eUUNJ ~b9)w >-k8R^f5M/$]=n}Oկ㐫x4Ր)T.ΊØuO:>0 ˾h-"qz%œ\;d*re7fr':f`O,f@7N$mL]Qw{G##ב3ltDĿ]([tJ[JG,?i9T%"܍11ǚӥ<>f{!6{(>Ʉ_-l!G3h><0pL `Ì^TSZ(/ٛ= Mp)li rD0M=}f[va ϰ>ɏp_xr??|)9ZH8ty<Bk>bw#PɜK ө@Dnm܍̰ FYmDַA Vz Z:bqyA--ޝ?q.pru}PC0tc[{?D!1K) =1XRvQcxB<\ `W쬪yzih߶a%fJY 7 غUiW(ڏ!{}L ֢ Vmh -mFN8TFĎ#XL'& 8%ei^i' Lo!hGޢɫF>aps#nJT]Ò[Y-Sp =sFYCo%JE~3VoLtWBUci@-\d L,3Ģ/x *΀vf齑/^Kgu8b,x:bFEZ 6iTS"G&4}PM\'=B7A+I…]r}%>h+&Ƹbz,lF2u@9U4âq~8 Vi6o @.ar7V Gvjz0zb(aٴzO'׻8Wy1| _':NI+wFʠ' V& 0fyj|֠j_*=\yH&z0nBí\}L;Zt P;7mbYkRMN%@p')6^E*Zw79)ױw2)y򬸫9uN5\xA %tʑ5HAGu`w(r ?%}* Ak-QQPu5b9&o !W !ڨb;ħxݡDuUvjj2;Wn3$PG@B#].Thϯ8;Z<}g 1֔E5QrhlOl*KQ&lmUsʗCb M8gQ˟hq oTl[pd{}kě$AIZ<)ˣZI ǗW]ZŶ9Y>zɶ~CH,9/(^w`1h֯\?͔?;8 eF+ {$KP·L&KY~C[19*Un$jw/rz|xΰBs^ɦYmL/i޳}|k Ӕ8^{(=lӹ?~gE a׭`dCvyԟ#͝wֽ%RmkSR3,k;k@hBwm'.H-0t̼_ b_9}q\̰۝/LZ1'dNJ:y-ܖ(G"*]'6K=ą.CyȾ݂&FxLo`=gOfBnC;4f&%_X!+E͘b{QҀbgTE%,2&ho޳rF5s :8e+oT Qݤ= nqlGDqP-t q0$\i{lyLl7Db7XTH4z7 O +xC/=H2K/Cqt+%Թ)]0eɝi݃vKIY}:hgdN$=R469XںP$<†QBcd;l{T Vy{ pH $\Q5$I:y:sNW!ӏBKbfF}_|eJݧ@r|$zDuQ+iұb6B$nǧ/_Lΰ̸g{97.cbUmFUK^ֻy)+P5 U fR LoB@QZ2H&N`nSBr\~;U1BwMUYޗvu, ۿyEVy-/O!oh[&ʁ? Ɲy!F3CޯbNŁVS]K njr2v=bOf䭢Cs}teI3IbA{_B[VXS.#[HX1wEMˆ':#{ճ/K :ݗs^}29zZ_'3O]~ 08O&lxCӗO~uiϧL>CB:Wog|ڍmNjj{j&O2; pd/C,LT0ϋw(,]pc{PKcaߦ{ͭu/%Swt@&dFfXU5|78t*(7٣i{Yu7"g4%Ҧc+){ el` +u2W{;XlvGnO6MuhC\)^S,?5S`t_^5o}*xj wqKSEq/K((F.u ^em8E2.|sHPC},*b *uKYEdN=c9|0)(]hT#`ǕH%&Jl Zh WL n1o#J$3L L /l@ mrY2[qێH蹅ݞ}hy ]6LhytQ!PTEov(Z<,~GkS)6O&JWJmfn댐H.G_ll[!hώ[="UYUYYQ6oe}umgzۖW}6z6ξ/?>\n}Vd6zQeSO{!/~6ٳ7?{?yv=z{6dj]{Omfߴb66Mg YU-@>,:Ww[݋*//Ewm}+@+E~_5%';Us|^v8\qA]i碓- F>m+Ϻ5g}_w5*Vgm۴JCz^&٫O?ξ}髳Iÿw30o#V)[I6/`ٺm֢J̀Ffr[Q,faw쮅7_;x.Z|؎frN-/7$ zh!C{<&Ϯ^f-PP愄&Z)Km4cT`g?}{bh x$W=yhKU5=xj8}]ٳ7繿7=;{IC~y}3;qJS,0yUt]6{2j.~|Lc!+OSQ*k^.la@[%.lԉj)( H \L +n6kj-60i8;B_ϸW} O+QCky ZpXﲒ2{cSp;d`bAЎ%Xd8k3c+ŊZpKjȯϵYձCs#, ]mXku?@ʢ^Џc}| wb +άYD$ Fv]ΉjA1''s^m@iL#̓A"1V⪘o3BJEFf7 )2#2o:XCs-Qn4{b^.KHC9dq la~h70n]vweU$hnu kam-qs' +Thӥx[%R+2L-'-p݉h`};2?Qa{, 7ˊ8Od6[3hryTQt@smEFtQ(춨6IϟZ14RFD'aǞ;HG,}@R0ԸD0[xږZ*bs[ $<~Y-)`v<#w"0ihu>+*TM_y|N,=^l$WS~\\EMo`g[wcD0(`Xِo_`J'ٲQߖmS= ?Aimr>I!,)zSig~DL(1@p8ܑyriRQb ($dAک^;)ruߢ`>!x|4gN ELZW4T5q|0jx IUh#Oʾ[]m8(iMYNamV6ig +{hŧ7%3ס0`EƤy8;3%]Ƥ-_o1)la Lt H]Ոi8N%竌KAw! _7_wAu kh(ϑp@RθhjnHJpd9't[jv$"` O4fW z{˯9H̯ɳ8:1ovg_LϣIt<{\[ɵL l/Q^@7 5@m5 Jmq['/ Ϣ]V04N4Nl( Hs?WwAjBgraG XxW%D׎С:T( MIXmya>1Tm0" >_#IBi: zǖA' !\o]&<qtEOuK5%)P9ݬ  ,=&Ʃ3B\$h0-c/p!.G=12 `(EۗMUx PpG:Qk}~g5 KMHl5$d %Rck{8#m'o>K( #jUBI)4H8yX{rKwmfhP*B2n8&(ȅd ˬ{Eg%+6]b. |%;"b'^K?$fαjK//FHzձc `C-q`KZ0#YG;%0o.d>q(vZ釗 Jƕk`e?R}$ĺו[ ։&XP 7T0 ERVD]_c/JP#4C[BjF?rd e`$_LD_{Ʌy-ZX S $cNubqT`V$mZ Ч2i:7=?89=(&M:Վe[# )xJk (-7(_U7&UC xƪLd)rQk`H!2Ä%SAW(TvnO1.Mgǐqc=| ;jk3ObQ5<25Q<b\DyL>Z5 VbMX$]mH1-7wOZ@S9Hdc Gj9Ï?)85D{)_^!0ੌbbUYv)4'٫_ǹ HP\ttLx{IbS+p=fKs_ 2X. 0D(nT':OrvmnO'2 oH# o_y0@D+uUP`M3d;њ7q}m/J͸]R.JXNg-y=A򢛗e$I# :&$Yp|&$/#P_GF po,V.P@W7x|AIX 2D8q~86MEr jG؏g:'&3/ύ+;D34MY':E;9zDrzSEYa+a+ Ku~=eL\8l]!zΩGt`RS)0/;4ROn8 RD{D Z*lŗJ"0'D9*~tQ HO&K;Tmw'%z*c* wֱPE|,@AJ$)v8Ekf 5\uxy߬g֕{@F7Z{>ڱf-i/sڝe$|7Y,FFQ1jye y!diO D"pa,!QY 2 b[8TF[BRs / Tw G`PBy+ f[P/za;CӉO˦B`r\ɯ81Flyq6mb;_ёm@ zSsib*Yd]]^tw.*pʽJU~KՀ.U޹(eh~p.LI!e% YmwQm*QН)%|8;Kӷ/8VZu-KF1>+F'dL7YY6&͂p(LkJ%sh.u 3xev LHJj_I,OY?>xdF4$gqEDLI{&]+/}RYGRf%A!Q=V [e?..Fj!dyIn [˹1q9CM=XޖLcK>sa\6z-wƄ$/vѝk,\G/j @]`kuS^ie,RQVuHu)`/ӌ̄ 5xm "$tmns*Vku,(-n!+p|Uq) a哦d0 Lvtjǭs,s6oECzӳɉvR}o)n(5@10 1509|)+v~u_U$B˵EkwҤ,E#Bp|SE;]ĀTQ 6lvR1/>5 8! OMbf}VXOc+ Vsb cB7 !)ؓ;hRkZ<.Qd۠c%}ﴰBLvldP4;C+ҕ|utF+d9ח#<+PY6ZԹ dFAԬbe"De9S >W)r~K/DXxxѼs^!éRMJ]ge3TY J8rpia&% X2v-l cQt&VE'd"قVg#i'9ͮqO' eD$EqDXJx!N~һH=`1v8k #ߑ0:E,r[!sV$|Z^"_(DҚy5Y'zMs:9gbJ+F4-T&+% [Z /;;$'e@ljx.tBBAM 3ʲ7esCv5HGhή6\6f/jf(!h Ф(߹# 4= UTʾ,\88:Xjq>hFNE;wR,LeV~-qfI1q:({ނ׺MXM;Q7 fDWsAoX ч-pߘU,**g9i4f<8D̳{i9+=4 v;E3@fc} uaT2W:*/ɟ~ 8Ѿ=ڵyS8O<D~7D6KcgVKeI%KVxuMJk0vg8Mu0VFёpv-GfdI6xn*G;tK6GO,mLs5 |Xֽ0Z,dXDgr*F!'rXUSvGF½U}OQstH0Ljm#<_hF7&;"`0llUސQM+0i~qq$+ ]`V2ޟc#  /]~1#V3LG#!N:M<\p28N|x,GYf+?nn@u&J/$Ͼ"\ iJaD&%8?8~2iqRѽ]WvH!.E՘Xl*_i ")R"gt)5%vp~MMu,*CICٝqv`ܭ/^6K(wݚ֦]EsdM+\Ԭ wӾ0kA &:^CMRoЉY9*ݢq~su߯>MY6SБEc"P0JA|5Q !^^ 3 `F qq?;·~rDJ/ւj FVN ,% a'dMF⛠VdV$_b8?՚'^kuK@3X}P0Uh(~/|^S ysU*kKЛa[YJqP[$KZĆwKU"O) {}bHAƥ؞Ȥ'uўE*M hjQ"fW;r%vq_rO0{h&&/ke"vKc҉-Yś}j%I)!TН|j؋L*zkcEEDc*51'/U;ۦHW٠g*UsCa<ξ}3E۩D-Y.70~m"QsCC}&oBu;)Z; y$d(\^G6~$Dwg+#kIV|89x9b|"܁ߤ,"y$C' 9dRLO=L: ''M< 9/=uFy9=3cqc-<67kzLXf}D(TexH{E/rj dy~Y0Ml;̜({ K 4ō nl_qIk8wTQ `DmR+vKďm cYPS"wYbɣGZ~䋌.Ee|C Hb^ &3FcXIywKh >I~AwwX/nmx%AZ9SQN$Q(O89=2†tID*`X\F~`^&Ka`7@EhiƺЫmQwK3* fo4 w'5#]B2k""pHfݔky/MO&e%?Kr ;r(^?M;2ep a"?e(L-8$$sT Yd}Mߵ:w*d}fv]V⼗Ac*n:p<.ל fhi96XGfX3r_Y!O@ngU\ YfЀˊe'{CbqEv.QCҫW1- H,5 =岜"@HE5rT[wv(zaG9kZz ~KE >Ok^ vjÓKzkQK 72Ղk[s[M|3Bv%r>:IF87x)و3zhb,V_gڥY/njǙ͈<6):/rlOeCɡZj+I鱎_-SdVT$VA. >1•. !ܞHo?w *%rneFAlѯwǮD h ] ݸyH=Aб=aƨ9$ym".I MŻVVRpb?+C;1*cΘiݣ !]t$b]}Ezcv|ke{Y(E bʹ9w"JA7ХG[%'6EaxI}yd|q?QqlOab{k[/|cgb. +*qckJd7Ͷni;$TVu pDK>(6ynU^ћgef1*Ok|E&NtRYUQԓ6;uݝT, ?2ICf] e Fn'G-/!R!4 45faD+$3EԬѿ =AX#HAۆ ]yZ hVWt1x%%`Uf1: !ig̿+X!AcC:j*'Hh_]yTz\-$B=kLOVKf&/LI o6G+@PKgP.3JRdistlib/index.pyH^hUHI!U v"d8I9HBup;{S*1w;8b J1>"Y'E*iF`2ᆥiQ bOF"÷#zFx:a2\s+^ w 0 xPRgʊDO\jh<h}~qsg4"fë;e€@O*'Up.€Bemxӟ# hBK8$ԘxׅʤuϾW(%$&090!hFba04,ª FhUoQRЊ3|bވ'JmNn3Xɳ@%ոPyL#?I‘C!v1ABl%߲eӡҌ"sGeb F4pXTU1X%P0Uju &&ų$NDA-!4ri ΕD7-wNb,8&72Rl6k,5>١ {j Tɘ:]< Y^cxLؼ=֖ t{N`P 8 x;5<".Ⱥ!>=$[[+vOorhw⽟8}QE(яC*gv&AWPK!H8/F0ֻB-qvk0n=0iL7TmqC7`E?`If}JMT,0::h뜖tXO $+:{+nCS (b9|`WZ,P;jyW i;-#h1Zg;υKr T(FEN!2de&V}|"(rz:F 8ח/fPeU`!h!rB h, _|BA@bZ H[Ȍ@n_I7LUO[;44\h<_@"uo".~c iRlHPGw1m ]:z[5e7`n^#Σ75vtCN4O UUdؼaGV(`BԙX`aw6$M@ϝ>>k3^ZA,BJ m0?: HZbxخ^Tmd\crx*xOUo_ t_נ^P϶ZkA? 9ƂE Ԙtj0~C5p>$0B\%u`}a*zg.꼭/R<s\uݐr'9d;d.>~}➕ {5Miq&j ,Sz*!*t$VJbG anb+ =7iGۥI'MQo@mk!nm\fi{W"9x r6ifDb~M)l]k%o%$\7[tG!0,+* *[ף)kҚvøPK``IlE $eOiBh"] yShZr`S(4* ϻތZULHE1&=\O' ^P] k׸Er>6Jb=gF:6e_9Nn9{N%`jп>:wgV9n9v]f8S7gկaM25;}:RF1z23w/Aغ)cP-㇏-*7m %x?@ܾ$sxx vQcK~H[P:o(Bvē5l{h4gV6(w"v_w%$'-Gkc/9ڵL.ӥ'Dkjc)YDgIH)S'ea csxJ QuKd=_VlW2G-pּ}eC{y]fM]E4֫4 WOmy<_—P [eyY߶uZ=QgUX,`kQOޮJ(Ӄ܎xU}U1 };Ku?-ˢQ.*yIKrY "+mMx4MV)(g z r"G|XeҧM|> OzD}l=n uSX=OYOZuZ&[&biׯ_LLgw0K*[\QPoke ݪ%^~Ox MFַQI*c Gӳ&^f *RO,]d]^z94% ˦L'2ˬ̳eSHkO@ׄPK@ WBh"DJK,B\~ RV {PȰ7?A6MLl^FQUlLp!]8N=~ӗE˔P_7xÃ'=~ko+DD 0??w~lדS)UZ033bfކW鷏o Wu,*}$P/DviE0כ2R`V Rpy0 2`o#4ɏWk`˰TbN,Uq8Xh,0vcկlavXS < ,oe ?cbS}=RQ|>J9Ydzx(sI˥Qˆٲ`UvB+r8 n:Kh Ŧ2zD[2ptP5Uq2]6HT hћ4&1O2 Y}d\Ps$ `-di:7*렊ux0H}iςe 87gsUlIfyPIM$7M5".ʪjG'|M4pLRd&OUu#RHY VeUA峢I]nVeʀVbOa|(`P~z #g%,yzˤAŪ;,e=M ȊҳqF9ThnqXjb9sI?+hW!b=QZB_" -*2tg߸GFvo&]Vi'B6+ K}Iگ>jP]'8UGQ3$~%\ a,G>:$bSthuh.8T}wUfۀo "ܶोLߦj)@_n*d> V X0:{ͮw`[lU\Ϯ"b: TGz /,jbF+Y}uh+0 [ /-X"p'^&M1yh!SXEt~e&~0qu=I`J¡$w˵aoy.)hdwLQ🸆;DsU nķ&#Lni6IDz pu6Mʮ7bjV+wʣNL_ "V-zAEvs /A@& zMPj9tm5 0м;7lMO$V\yfJU8b͋7m\"ljRh@ MNrtjj9)0ۦ VcE y 2ěQ*[s4OfDrgR+SRebc!nj^d ؑe**k?2A15;X"uLvmjtdԸ8Z ܤc_50armV$ax^R͊2%{ e?k4c'BH]L)J~t5MʓtFXv<ڨ49gN^uߛ҆u. ɜUvgi д%ixttB#ElS˩=T-%7XK4NrX<b2Q g#ɑƀxm:=.Mf4n 4Ц ,fZK%[Bj `1Ttt!^ҧX_1<:ylG WiMlģū$nUi,k`-lBAc8 [1:_^Pk)~i_x TieIjybp3k h v=w6~>(Ȅ7 r0 \wRp2 ,Gm\>T88߲bck ݕɣ"gHţ 5ݪikJ[ v t [< wp7/Cl;(pT5pz?"ٙDHdQa=g Y+#٩P1䭶wtP߳'GݬJ7c/Iu ֹӤZFƉϝ'>G°Pd}Zr-nVav[l[U+Qnz[a'NK9\' ay۱ 5)6Yޫ8Bٔm5t$pք(lV2 _@0r!RE$P'ݶawDxx5❰JWK綴-s=5!mH(TK^UU(bF `x9]v:_3P4 xcJl W4GBǢ44C*+tuqG):.Zc-{O\_j0n+cKqa)j"OڨUKS\tkL |lb]; hUkO*pnGG3|B6[o(}[gUK'|Q7!NKWChX^kS,$-?k^%dZM['/N0dǦs)ufPMs^>Na#YD׆%/MO<͆f.6_epgŅ`#D-)BFtc/ua#eUx/ _ˡV=G~uW~}PAuֶ0uXK:)Eʓ&3@Y>>THT*::hߓ ХZ-1!Y=V/eHAD3QAo=|vQzWK<( t~lJ,Shy;I <_!*irNKJ ꛤa{XFb$L-912V"5~]C0_G^țSx37wx>|<[is66<s{ zs;̴>4:v:nШ8[;|tڝ!v3?jxzck4Phғ'Difkp.wmAN\' ';_/уg_Gttoͻ : QO }Lhº.mz!_dP<-6JCLd *˛E!80DR)SgK-AOŶК7)-gj0 "x5Mb޽{oы6tV34+tq[+OI]AW+cPMIxV͑p^VXe88^`jzf{+ڷz%[X yU5:Teni!-[j.rJR> =K "nOr֨mTȏEQFz mo`n{K&԰Tb=+e+I/eu;~srlEJV$5!l )3V5>oVD{FȲ(jwG-&kʗ3J<̴FQk~gLRTQ'&HNJ+:Z2l ^L1<ך\x@@Rյwަۚ?ĥnT8q!V5ġ$S&k{K)n,lR\p(a\t"uc/1u8_HTA!lk*/a >+Vj>}"m-C~3NZ"*Ҭ6> Ces-M T`aak\]9kk-rGeOcT6GDN]\w떃['&*U<+$Lm 9'37} ұ>줯`̴^(7̀rFΞ*UNʩ6YM!:I ǛL`䥥|R=̴8jh27DLY|XJ@\Ѥ骅@߀G5: jIڎYR/חWvpɃNs?ҬDN>n451k|wD $yɴ)(n0tpu]JyK'dnd,iӱd ٓSm>6ɧ)@+>xA6,㖏ȪJL:l^K:8'ĎZSIˤ2nf|Q"mR}/D%F@̜NC|gWJ :sUR$:#=Ӌ>k@gY"e @h<EB:x2tC)-B vomݡ~X4 ֬`wJ2 #Ueyf*]`9̟߰9x7?1VjH"wxBa7+Q9>h Ž9b1b2pjhyWH X}<FN)~V;!w]2ڢ(Ȱ:uf^& C%eAG)=:*0G|u?-HIWv^\G~r j :`{8 d7's1FL'p 0oBU858Lrr$wOaoDyXc &gэ$>(wEgpNr77`ཚ@Q܏bf ;xRIbpt.V8*F7831&#t֊Ù`67-ԶG䘤V[<[VmQMQ 7 rE&wqfIU+1\um򞏑sJ%*_M콘nUpK0鈽R-P 3GV{=HRY\C]%EyNTGͪa'l$ &;_ـnuhͶÀYNnoMM|DvXG ~՜z8zv\ Am3r&=k3f)'_F[(ӽU%ڹ[9OY ޏ }s?Y;z1/ hSI^"s~d>Qjzˍ%JXK^Z}P3}UyKPn Zy_~"IƵQ-Mf2ngL!#nhm-< :u (teTFt:DB@ ͝ ;x^ T5RʳbܛcQ3Б ntՒ E5Y![ͬ5INɼϭxb.{MOWHғ)6#;$<\inЗD03nNF #o$?MٗT7]emוw$Kc0[+y S..xAH{%2PQE9 ?2]δgyP\ؕ\Q$X9SaİOP cBL1[D ϳ@Ex 潮N2sIc{M0^{ o jw7Ypm2o$$a:Lci)3J۹tQvOxdlӑ9^G j3PZ”b^Gl(^It&_PHu?NgVf1.l%WuOlˁ kvtIA>CjUm ;oӆ l8͊!Frnl#f? *ߩ(]Hhyd=mߣIC ֝m7 n]32jޡfl3o)>KPS~[fu(a#I݈n'?uw^ӃBx{I>) tF;ޢhuJĒ“zvgsy/ɣ @U96Q u_4ԩ-z kѷ)of3mx3 _et +V{w" Scqvww/\mJ&^;{N*gm SNz0n w10r)Ui!oyHI70}Pf-vNcS1) K1S-]:Wh٣Vg/9Id/2er-#LrQnx1W˟Csa1bL}붪>bzV{\ڳ0; H<сyEG?PSQnIxD²ڶ f#qUjlT.d-e1)O*G0`G'rσӇс\^1:~$U|Z#շ,*\!zg0z].)ܐz&Pz?O_z˧Iv73Na&/C> JaSiQ$]אYW*]2Fo]Wt OК%FEzAc$qخƏׁIDu$o4G;J()krMޝDW-DBfv&8.NN63&\*#>zWM[OKܔ;K`LGհUW3[^u#*µ7' H`Α?W(RM74|ݡ 2]wGz{I\Nw]59|8X;*!xӜM{r+LѦ= -h#yN.e-_(G+)%[xbC.ڔj i.tԼonu \Dž0U;**AD?0weKm4.bmPs+Jg zM?yN,+<+*Q:* dyao|YdY8l'cC*Ȑ&BGeZDS2conدAsm2*x蝼!Ά ${s  η+` 1 6od̉/@w"[-R${no)#˦/P쎦^ㆴKdJMμ-(lߋ#*f3P5&׶1 пՎ$ϥf;AJ6yli0::z,b5ֶIF;szȀ3FkP4Dd<[~ UX5Z# vג>ܸ}c"S@De`Zz9՟N'>r99i < 1㖺@ Q@1wq:&[+NU!-=4I\^T"R{ڥӽ)-8<{Am%Hu"dcB_ _[213]bFen(ss7J.~ii9 5\^ya./ k9tyIlH3#D9bO ^s81KuQK;|*μUWA _^6y-W @On`.duM=N!XWEwloayr5y~'Nowzb`M&ck Cl qP6! I639t. 02cތ1r jIsa۰>nkyyq2R*бAk+7#=cEs;Ш3'e߄s=rI rFpi")%̬f)Bl9",g ӻjIݡ7Hpk / Z'/T&fn4|X/=tٕp =%'!\$Sb+e9m1iM.K/oTZI#ʼn(>*VUGM閳"B^ET鍛uU3Uc\ONӯ9{vQ\ *i=OFfB;۲3-kz UQT Uf[ %]IΔf<ڏ5.7D1|DzfJ [TcS$}1GOGv |»tm{'Nzl#r=@x".3! ۜ~GU52h=cvi],(f=[Ƨ-)y=ާ'WGD{W Gab?Yn{?xKTQcS(> TؚE|p8=l(*ځJ }ʮ$5U>F025Ex7Q0-eQūBlPPKgPx5gl9distlib/manifest.pyis6~o+13dgi|;P$$ -k?~{HmLLû/@;l;bl6fe1 v;@,y2=޷/FKv."cbZœHDê هÓC/X??^_K7x d9_\X1,MdĔMKd,d1ʓIv^&wa kX!hFR \=d0z)-s1IBoXƳEXDs5` irnZ\,w]L#Dp$˰02dY3E 4 Ϯ0K\`^k,/>;7pCvͦ"MŊlVe'ao.'40puڽΜ!>pak}y\gO/d zWr7NS@eZe)P"3g1@Aa &StmA5h*r{H^{}=p6E:jf| ;.?= ~:<8:E& 7 l*{ xTx(ۖjO$-hؑ/S, "Xrq]' &dZAVV0A`@1N p%O`.'"Y3<$9EE0^y 8cv (|x) 9oswDƧ`>ڄN$uL zA@d0b&(p,P\opD0:%}\h S$Y9I=;ү+#*(J@ ~(n؈}hpXBeQ|@㗵NMsHrK\=|8a;M5+\//zR,q:\/%Y\j槵;rƀb hsAc=D@+iJ4VD!-jTN$1=&'h~+dЄX Aav֢|ҁDKik|r 6^gb_SڙL]YK5޼;ީQ%9ѫvD[UƱvR m &E`lepG!壌Ƈ "pr'^P4"\P^U@-qf[*t Yq4ɯ_[LrblOZ L9&HLTRNWHĸюUa*7űs4:7V_ sэFCo ϸi*yc>)ga ,tPS?,fO,ڵ=CXz$iR$%b5JW3: Rt<ñP[T.Ol 1rjTuDҰBӖ{8O;Z:\5,q\; uJ BzqMwSko0=%$FSNLC@]m@i<9S31 Gs1Qy&$~9. qVY]'T!QMr.4FwD$T͖@Ёu%`rťd@ 5|̋b9~<g+hϥ(w^,m,{9fOUqdrM\L@"WΤ A~ZS~V9aլKtm0HI<$\ŸL: ܂Ss/f "Jx p0R6 )|% dW)o:(Ck9dIh4XS +[[`V *&a<#Y zgx %B5P$%T|6 dNRTz0e<5}$Y1wwlvdu:RӰ=Q/rS6C&T :F=,N%EKZTAԦF45!?]4;Mh}/c,0}Mmhmg{uaKW A^'T_\|URhqE-|6uSo*4|-T" քXuԳɣ~u+X~Ӣ5 { D˨R)eL2/5(jţ(zO v65ا2gp $Ag喌"0yv/K" 9B N XqFy\6 >Gr;TBjH% =_m<ҝlv'AZ`BnQi"U[k1}8/7J_(dyBOAqS4C~rq~M1eX'4ΧB}9G nor;hZg@ʱ,u bMcZ \zڌW]TgZ۔u3gB=jKG':2nw*uh`x]=cҎWӕ}lMnu+/77ף} YR8&=ćɬ' oF&5-jz0 2["V, }P?&2S\pl2,d.ދ)$]SKG-:uסPP#hF~̒,L(rxzfr/B9age@*<+ԕ r//D\ 8YcD6DIhC;,TTYlaۑc&Pα=}r-U IݚIwNXw4!0b+(@S13׊FjVsp)at_s_5Tz$hTplt@C6iJnmѡr 5" &&<4*XnRV2TGl]P:`⼖`X7iLf{/I.Dt T%a PzL5R[v9DU ,shzE~9 YȤ{1Hsjw~ ݗDZD+/OYu[G2} Â'a Ó EtN(mK&o@oتBukS˸a@OEHz9m;wkc8z:NszVcu3SӪ"(Kn8^o]nH  *^o_,UvsJIvxzwvo|MҮ݇C|(`cjBT# $Qj]RRoT)6G:|5!ŏ"z'o/@r v#;rT][(dk_Bx!Y iCaL:pibUC!3RGWNy^)tVݸyV) .n+:Ky0;+wu;]P`(\u鶉U.C4DґdtDwoE}]icEzP]k ( :5hTٚb%5Qk *xFU֧J//7R7ୱ؅yٌMTة( YSXK-@&eU0`nTx8]"[ ;l[5j,KmvnЩ5ah}}tU5A|c8F#/~}&o t4]rys]PjhڞrWPKgPf#distlib/markers.pyWmo6_&(d+Vu-sE40 TFm62TbcX"SN,R9 i-$19VʐYF^|u~!rA~udB91#W[\˅ysو95)B]k\\rtt\QxL]1N`2>.fL ^1>"ؘc7Hj1x6!,H0 v5ghD9Il^~i!^)tJ‹J %_;=1q"u%@[˻A^<`c/ugO f$oڈ!yS(\s} 0es(橬ӻ}C%;Z-c]2^eugn=Uowr%ߴ;/Vn {% U$,@3Wڹ}vXRA"l ^d2ej&J Ӣ^i= LSy+u&8Ppg̡'c_ܠ7NϕMs _ (mvWNzb=EސpMjCf 4F? w:F]5;eY(V$ mc;8N{h#Sv?&|T<L=3h/X[n mSm3GfqR1uΔPKgPA`ߥ$2distlib/metadata.py=wƑ@tHZbVmNte?IN + 0(YM7vRJw|E󵳻[(iV\b_dckc+xV. g`3 NX殹*฼hn/e&MVctXx:n>6ARׇ'G_=y}t|9+A_&pIpQVE2N.YŢ:H< 6]Ԛ'5ղzX#^/Y%&>0dMLD#Y׳+!ӧwӣׇtc{ͪ`Ov _ҳ(dt!fyR׊^eu eUUVQ*ݍ>0@ğYR Yym6geqgf%aE4%4pm`\ƅ0I>ج,;NUH-V))_,6sP$yKdxU,Н`H2]k1L>-{i( Aۯ9MKϰiEPaq(Z#\7vH"+$T+v*AqM`$ bt)#M0=H$j:~̚bp"-:@(hn*fYSkFҕ 6?$F[;_&S!qɳ8(g%Zeq GVqqpPe[@&gp6T[Q/PDh1Kŗ2g@ G`B :9.8؜9-`/5r5kl\Xd5Xx! =}wrΊmUa~D鏛g 6 [B%et&Ux"BY{d=njT[VE`P^ܩ㩥Uk⫥挠CzI(LE$jIURՍ$=3<Q0kha9T ߣQt艐o UR܃%ZMp~H9~ךs@]:SRPZ6^$y6)ElCLp я1y82 o_c|Xl`#m&8Y Ր͢v3IB{ȹuُvږ\ual H|`"6hEj#|eH4lR%1@"/pzcy=ؼaXeyce˥zn)t ["d$HHj) Z$'k"9YICg $?H~&?z-n϶twqZ`sgbL\\$(aOH%#+d)9MI!I*u_?- wuY9X P 8 )w}F _`p=֥P5T\TҸ(X#`N 47 $ ͸~JWqrN#i&npu hX`Gu.5xu.XlzX ${{q R&Ưop(<|1E@k*_߲*!&]C(3&?kVe뚖nh)˼ 7tSff`>&"8l |VuP $iq AhcAn(̋%ωsbc@$<-bIq 62=bRțnSnWfbL(hn?٦8TO5QqK;pĊ;h 9*jExAqY]>I͓[h瓭,8''GR909&pEjHy2chslƛ]zOF&}AˍO#H i*ᗡgB@Zy~ldjɜp?=‘],,bq|b2lv//Z7#Ve1C_`hU9"j}rjl$ӗWÓc|o~nH;D bYyGV#e Ccxةq,|?oD.IMHXXZ^Ja“,j0ұpVA ?R }rB6v],Oo 'N``Ãlqvh XGR > m W:/_3qWř`|aOxԺ8 5rf=yo-̜Y%T'olq -p]DrҘ gR{Ʌmf<~.{y]",O9r2+LqV[5а.LԦXL&ZCZ&sYmOYzh{Z) |Q$ ȓE$LG=٣ڦBȭ_,Ƴiꦍr꼾:۞&: eFO+VPwxâzC"j7MzLL,$VbwiY j 18Oz)$(OA}|U]vr00C/s`V)D{\/؊!8DL~΋9FX RxJHD(~&!nzy_U?L/ewJ(;̳e!g@Jn,OsS|a&\dOM#ȵA/RWh^!yQAcm*+c优u `آ@]gX,CrA-jo jGEF׀fg EC 6D tcD[V+[*Z `9w1=F<"f??ʬseo?rYO-{z+-E;i {/|@H*~]kh:! 5fdyZ%LJ?MږǦ<61 wǬY\@> W+vGVRY?`U>좫"plLu Q1/KZH\@3~C]g7Z+PSड|+*`۷Jj8-q%ʎZ#אFNnA;0CJc Hk]!HC8"߉l6-)IwSĜ=Z1R|t#-L(;HX$N&g}1  UP؄ M' *!0*(jj>١(GT 5Z gY|)h&a>LeYC7iތ"rUILs-uPl|v/9i,}QV׭| lޗk3Ud]hשyo1]koI(3T$]2wY8+1 xVE7N}r,(Qg9lp(_ܪ$`hPs8xj7W rmrHB$BpYs:( fW|GuC68F=#.-$m("cJXv$?>H]),x-+GQ XwKU=c+گnmZxe&ydj%,$۶W\&hQ쾃fIa_#==5[0l䮢񧭌GGym'ڒthv`6V5 ys6=xros^hf3u1Yd=#]ؑ SlR4ctA9|NkPd\B#tZ=h'XAݻwA}Ja:#+hST 8-O@M{{\&sT #+BИ҅xY ٠N(K8ОO(b|+:ZtǷ ݵ-1MS,iC:syۖ> Jᔈg.\e[qzl* 7mp.Qg:CDֲVU=UMSϨϒ=.%?0ZÒOpgn?71̊ ?YCR҂(ܓ!֒pjD_}#9 rk1 ʊ(i[sgC.h<Ph83 +7GB`\omHfg]P(M)ԝ4{:oEƀNn?ośg4(wJ'kY 0-cLn3'<=49Saِi,4vya>rSy 35xڡ&U8'=e:$7h'1ϜYd^qri"~5[ bhgBYYyؠHk VhZwD3+ӝ:D[,s~W *w1?-Z b˰fj'e퇔H= 2?҇~hZq?ԈB:_fyZM]LDjblmwk1+n2Inpx.ntkva .Ĝ2C:8bpUkF:/1 X,Ka,R>PhYbˠogU,,\m2hcYaD99IbDF3UHYuVF-Z)%/FE\E~ ue8җ`4)6}yjxNd@Zn-JBǩ[|GI]go|߆ /Y)+YOU§|:B90񎐇$})d6dr]M(3:= $ 鄟-`AZ2PM0))wM7D$p)b<lOlhCs#NQXIWlFb:Y 4ۤ³!JÔ\ s\Oe@c~P1""Xa7Qy _s}Xq⬴)Šo/1p_/Q'a~2MA2'h"m R튦Tg")QƲ0;p3pshDAO:)2][$Akm։)mDrYQqd~Զ})>I27zlMČL-+9EBc*_&)-k4^ 0mo>̯M$Z* kH@((2jG:[4w<5Jk͆΅4dU\) ߫ o_Cơ9+ \cڤݹ|b0L%O/)G@#AU!#[5jʳvSww{w;t?nQ<e1k6S'5"ݭ(D+CzpUuN(Ҳ=S8I@aǠZmQN䫕 aU11~WE":R̤#zGtR!?Vu=Ѧm/HU+D@Ch>:(»-r~os*6QV1'Di ֔Yeh"׹}vl_`i)FֵaNCo ;"=uL,g+pk"2s:)M65Sܳu=2GWTU4w,~ Ra.Kg=x+3RXនkRITE'zk ~H&*\[HUzg)YHzjtDcZ곝V*goԇ̭{ʹIFth}`6% ToHhj!+~i[fWuǷ1cC1Q|#5yOYH`/jlPPR.?cϻJ`B](02 L49plWn3QP zd7sR0Gq'o4֛DucK8 Fx*NGP>|T r~UW0fY#q Fܐg߂M pr4S;shL?HR!ϸfMVEݤb)*`Co`p1! uQB@]Mz$߼ko 38U g. '  bϼGDG.j5+Qm%/9-+L χtAu@ <+cfL  O8gtD-pIOQi8l=2Vqr`"J6pSuwO+Ra(~Ht;Ǵo{+Lڧ&m3=M`QqL€JuR9%g{gm _V^nl͈ p*?vUEϼ^3:Vh k]g;㌭o΢8E@xc`mDi:h]혴b|W)[cb hWk»jy~*A`X'7 +(($챣W?ܵ^05@/I]Z3C78(9d[+gL͛&emVҌiJZS[LҾۚ+K^v݊Jv%BW|O V~Z_g\Qak2շNtۼ (RFqtT!OU֘;[)C[ >kбRMNy}עϡ!$|r`Y=#yu#\]c?Lxe~ێ?Aly7-W3g[HJ鷩uId8-DTwB{#f}K1M{pPv ˹Nje]cT5!r,M١Drj,Th= /kGqqWxPY!Xqc+L_)>w*AemKH%$%IFCTh#B}?6$A`Qf,=_ܬK;Q\MVgX 5'0JauZOq6e5,%jj 릊z^ll+xk|zj#~B?!>FUtJr G1=/d*c#ә/ K[cA<D=tW,q 2(AWM om g|kgbЈM6 0fRsaO+1, 0.jV%U&鸅|[ h%j޹~FqrYzٻ~gLhQAoG03;y]bɼnU!qnW.w㨭!ܪ(q\ Qs̽5΢;M'?tۍmvL6rRc%XˊI=2b![\|ڛgpQ>מ2cM[֭y6ۇ:c؁kA3r$MC&;(Z2t,zV]yu(k- P*?1^3O90tح=mD/[+Lbd-ۘ mխPa桜8/X} }U C>kYiGY+f@Q-stPKgP݄ *distlib/resources.pyZ{۸ߟq|K_0m4)!h C-, {gzxw53<$5f_u|;g3>Gc(^O_\b9?k~#˵k2U0ǣ9.6W-yʕgp!*a\UruPm+!"W(Z7A1?{OFس$ԡI,*%LE$TY=+YwWYmQ۫v{P2.;::u,&K}5 VZera-J4y2-ɚw"Mʪ(E3*ɊbJv*̳TV3/G#&,J@hD@ߘ+8~'r 2^쓨C4FDO#KL/s$E1  =fz/*Xȷ>)pQ391/@ rBM!(]4Ѥ2sw `(3ܦ*;Z:τ1ٳg]M=Al)϶`IK^{3gzNNe+6QQ%͈WАV$y[ Ȯ@w6OIwc gҤ>pU WسEc=X2Y)R10C{ a 9u}5JlXo$Ÿ Zo(-?)CtAʠc]iRJM&q3O"=PH s He 4@jGuJxJ[ۑt]@_t䓓E\·Rue}mduTXZG-5%NGν .Enf9cdx6QidwLwO4WXA CxZn$w`E}4:#G FͧLVBՏC/J[Uޡ}8bA\̐E&iByQyMPZ5hA |'vyK MU¨{.u8 !.s2[-W0@Qi !J96EcTBߓ'N /n1 3 E0.1 <[ u蠰\M@fJʡ ;/FѪё `{۬XLg_>]VOBI]mgzLAJrhZoL i٠KVP8# Uw1ZueƖ1F v%_7y82qq,@j,_neYDŃM@A%':smHY G_/2 &DKP|BضȡD)׍<9ԪIH6a` n Cˤxau hpnWdJU(d_Ldmb1i?k98d) e9k ]WMN 7MӔ$⺄ Ӑ0!-YXS?E{0rAm-gJmޓFPT'YH&)EN+ %}B73PnG4Kll,8ZhOy҂ƑPPդM䎨lF`I`T30}0pK`z˲^ѦZ4ba mR%ОR@iq.4Iu-6*fA- q2+YDSϐ&.t# (i/}Ep_'_5D%h4vKU[Xe 䴪 A\et9&c;=%c Fw,<' "UB_ E SH/mt]` rΰ "K|:"He Ag i\tyMpM{b-׎FmWxssklaes[Wlxdi!|p.5b=X "Gwp= ɴ 49'TljQ 3eh"SH%=]'-W͗%PT0V׋Hx r7< !p4U(:+OogPUЫ]ȥ t!*zKImЪ߆\ )N갍&9`tξDiD>a>Eu4'09+k~bw)Hl0 yi#<p$n<C"~ ò< Zg8s(GY@0C?%uv_ӻ|J)XOn)Wn}9X {D,^ͼbB6$3|\NIHqo\CJ' C g?yH-+&AlaF"} )!xpfEG#71hkw^A[o"OL_iI :u gxf9Lr[Z&󷍵l&S]zoS^^4\hty>c/Eн9`tQCzȂG KYv~0]6D=g3uz麷0i>6g?*z ޞUD msĉ,N0zO,b찷 hb"+ֈےa]iݙ~~u9&KΖ\=4 &vVQ6͏%+|'A|:e߱O]0v֩ q-)cJ YB,^'tҜ<1Cksd{a{?,5mݽ1o>dAח7&\Ƈ05R4Vr1q\~ʟ(r^ sYڊuHV\rB.\Ny5`egQ\SnV-d/\u<ؒ{|e u8_EȖ"l>#]n6Mx'!S[ hSEs\2(Rl8D@^${|A)A=B*@\XO91IrϊdA,8n<vd.=fJQP0ER#Af$"hWp ]}dQlfz>8;9 Μ8x/ >w/pw۫Pm%&m;tiXܫtU7+ՁAuJ4uI˻>]b;s g??tg`* >('\롖z!_^H%7حo=(a r&@ن3`3p<W3/`Q!,JF0Ga+,7_y}@!B[9?LMmV) lD4ȥ@hcxǖygfPgM.tz,&z JTN"Hs+u^Um]d|-34Yz-_RaiDr:ub>iuڊM^i^$3401O1o{P> ؃,` #A=2$$%ϓv[Jx4H bD:"BTxc,(=`d4L@ E iﲭxE!:BS:q k|IU+ף; .R ڲo&@ 0,q"pV@1H4Юkq!׆Ϛbn>xBw9HYވ\d zElr}d x&9 X娈;E|2\6cT2kJ[w-o#F*& S/<,%2' gQر褲*43klJг 41Xeɱb0G'UbNMfD. W}BT+ :kեcg/m8v uN?뿀p +\F wדˋH EϔN-I+ٲͿ};5ch#?bQ *Hb==[)='RI4c㍕is9`@ M"0:ArL<`zZn@"* i%A]yD |t3qfc${{eloG3j6WxID&rBHP̥|ۘf7VW AKRfDgH*Y86=UND`:Z\=CUF^Ni!gc,Ҽl D\w>H<`ljI)G0:a 3CRsGN V|h^"?Ö uZG @Aۧ^cj&Y3+co-@`US:$+= D17nel%{Q6  δ}wh4RX5ݱ 1 5.DۧJ3Z=pC hE-F}tRc%H͎~ :w5q8=E >f㥝)>fu(33Ȫ01>k [WظM\ǥ1^`@9cRUl~ )\fs+VH:8P_6t !RqwYYY;AQ:@g&TN9cN HcRs ;rUH*aF _a=Ǣz4B_#jϖž VBlOSyo,C^HARG;(^X-/ja?UYGFEyxj9l9mm;jfv}G [}( @S|3M8SMl_3fl$̣=*G4j( YdF1;ڣ2+ !d5SZ R]0tm@S7ۛ3߰ʰ6&W<=s灁jG,Y"!l;,F1;ѪJZ)خiwku~)(lt"vͶJ Adž̭<LG12Rn4}6HA3 sl(!ܫR۬٬)pR Xt?90z)CHlp@E,P ljvIRủ S̓FN>kuף2Պmꔊc4ᶼ_~\ 12Oj sXgrbWd!B4P5'\o:$ցcMOOzUO–JjOZġ>ylI e{Dm z:D+a7 TMMn rD[`L#qҢReRzc;a";N;m|RՖQ.u :{J:#Y [qwɏ5=p΄oL>ZQ Ac7HWW՟2"Zzu; ѐ/T ۄ7`TYk~ЀĢaUvW#{3Y|U1켮%ErVoV;EHpGc8s%aG1}σx._6ޟ -FӇ@ot^w p9s{tvׅ;[ʃ9*CH 3ƅmL4u;~w&b4kjIyͦ@?V1h?u<f QP^c + Y06]ZG<$ _)YՄ-Rj3 kgvovaIBryr{E7h("`(!26R<Sݥg4ݺZ-N$RYa't D֙%5oFB59kG ʕ -86Z ^)r[_Ż;8؋2OXi-u'RPZ*US~Rb.beqv.~QSÆ@M}&l~+ jU$a* oR=x!xY'4<SPKgPzdistlib/t32.exe|8<+$ A.(q nL6D%K-f+ j[R}.٠B5T:<JH29wf7 >}hv{s={9Sy60Ta3?'끿ie1{~wȺ }=࣏~ѼG+*;]zNffz^]˙?mx~P63F fF铝;xw4] siU?o{yȇ]fa,̖k/Hu3FC!aN ZfDl`0@O@wl|&_aY ̋o@jA31{7g=Fe ?_z0yЪ9 q}i4뜣1oLp%\hNú L }fgsV.~ဖfavL/aoIAeWes5WU <‡&YoAz Cąnr ~8r.L#&?i`tM$j6bMLC9P)Q\zj|0FsBW1JNsQ+ - Z,A<; "5J=~ ^d~WɹIIٛ0K.bRUpT}VrF8ր}fR{y?aRb{:9K-],"zj|+Xosc۟Vjmk rn2nPU"{)DҜ 9})_VĹ^7QgO=U"j_F٠ Z|%4'Zb%n 9hY \՜2 s1l <4JͱA#*k(C4l>ݻ da"򱈖nF $j,?j']Tp [{2[݇.a!ڦ0~KasNYT4~/ [}L= 41>gd+j!SevV 7$8!sU>-ЖܾTp.V0.P{6=b*F|l)׋3r??ۗ mz4X_"|'t ]VX:rQUs0ٟXŐfjNa4p"@fJ~pQս}CuԘA\<~ٴb|γҞdFD(?/#𬗬wkK)3]Pd?E XF~ѵ.mLӥLt)O-qt4|sul#m{^`༧bq^ͥ<r<4k0SMMp>닶#IK JKS0"yOWj)!ԏsDB\[r+͢/` HIDq Y>l} cs˫f|T΢puFM />ceto[\&VPVu^7!fS W"3iIn()x_hmY1d.:{d`hqH KN$ J=_O;dJ\rJ+a bN1zH6:IX_/,DiXT6x}8 eO) QXEfP$Gb]gRS6U=\ =|B̏=<JF } *ZODy=F9a}C#-CAWۇ!FM˷ &D]($ GA*8r-$Iv%Ġ0bbUJ4C?RI?B1 b`y [x #cqx{l<qMU B$*Q Pn>@!G2Urk CxǁJWdOON{<$WZGe]ѣNQ'i]DZ]|PAX'RHU6[PB]W,Fd\u!ĩWUlgEt=8śH*\Uo+2#l2p95JLr@@ɮ"ErD)6+a"Gr]E)%ޘ*''6jSf4HtT?qY]~U,Zhjy!s&` p"M ʗϧ?O@A*:y3inw4_\ 6Jxú ^Gi<Խa^AGE ۖe ӼQ+ 9/ t;oCCMs}O7+pA+JH{o7ޱ"a$B$f]A;uUq|bB٨k0Ʌp !Ofdg6P `]/ܽs7W/QI(W= `ʯzD tǟ wF"U@neiy!WA]7VJ>XX-;Kωqcí4 v,#O2G*c$j$DEćb]3IkNb*On-fzյ٤d.rLE^mLQč͹sU$ܧFn> :u=ȝ Vy 9JY0.B6d55IgAF|\Е,Jf|FudUP>p?+(6@T;kD1Ap8;ɜp'DYo ~ȕjq@U~!+*5lwcv C*5ȟ\+zԨl[p+Z`tsb`ACW]!NV,f6 O_8(7mX!62Wqawq}z尒*G0)8duѵ(G q@ΠݕP@&t]T= +{E~: ꊷ{w szA \C4ZU%W-!CcO#k-/b-ZM9 2e88$L`o,닄\Z:"ZMڱ8zrj2w|DGȰMSh<=ͯb)fSqs-6%Ty#@2Enԩ1T⌽EZ*tFR#%EV]/)KG$1>"XgħŸᲥX^[_I:2]fSL:l1݉-<՞fx d4=(zITzK9(^/&t?X#u Q@<{h%lu&ZM(6][?WiRe]G%Նh<J7*YSd0C0/Ns} ![=rqhCh D!b ֋ET9/ ̷݄1fL 5X\Yd*`O:d,Mi$p+pE+͍&ioV ˗#m¢Y[ !9U (2A_N"IeSR?,fs1G:t[`(q/L#.(ƯH-hgkZ^kսxAt(<`c&Zk!߈"Nk%ɋ`ebMJZtX'8YOqb?Og^[POEI 6k_0.I^K+Z< 9kr ֡<SzNYtX09dMVr`,M{ԟԏ\k7(G/9WijyU^)?53Rmj UT3!; ?e&ug%:猒@$Z޾>-:Cvh*L5VYg;Gdj噍鲫5Wuu+c]Ef:DD , 9ܙzl=$cݰk/`spVA T'[`E&y*U Ԛ=K8fElU&'CP.0GN ?]%?4_Oꀾ!-mai! 6Ͽ4蹮%>̕LRb?R/e!,&6қA;RDmbȽBHvX]˭D('-/*dy @R_mcjh0h @B7ڿd " ܼcūTjͅᴸgGv<*ϐYt>L=FӈHDMD-F%;[ &h>CE;B=QKs0o E-sJ+  ˎV< A5 ER[eԜ,x^B~g V &.ecg  /kr') R4>ׅON=pϯ>YAR> x@ed`Y wևS LsP PJ%W l_91 m[c@6JzQQrp䅿h; o$oQHt}^6=yV2dUFohQ{ȍHTJ6 ~\xs/ِ\f~8r2Uf[gЕ%L"DԠee9.X}*^7)imENf:/7e6iM-U/\j50Q%W|V#\N^5,0Đg hӐA~E˕qW'[OY\Bx?L-r-@@/RI Hx| u8?^ҥݎ$ $ϕ峫:UXm CCʘ+^͎>69Z,>af>zy_^eQv]y@f5S f?v;zW-rյVu !Ra&媏"9:!3SV_q{]U-99 S]R tU G=^?sϳ,%a^-g]dϐ^>$5\T:Wh6P*Kߝ=V@}_XR .sog^G1Aȫ"/.`y(R2 'xHmsUE>oc,SO7BΉx?,zn:‚ERk#jJr8"4v OyFdէ@7no']w?=d!E۱z@.u<*%.vS|`eq?˲ZY{g;TڍMH{B>z1l sf10Jb;r^~)yKL見A omb!}2rc.[D3 "(@Agco$d{42n9xMA^x0[ J-%A-Cݟۡtnߑ`۩=V/aϘM]p^Z0BB콢H|}j{Ÿ/k\DlS b!+\Ft^,MtI2iToՋs\ݬgoJf_Yv f %pIaVq-#\.2Pwh`#2q-x i0d4-J rKTo!k Л&Qf6 c "\b8/JI ([SPé1Q:ȉcgᵟe!b, U4!U K > 7JߌgBƎPH'{%p{iKi!=Bk^ *m~ϛ:c!4_R_zhkDkfDk*WhޞL)";Z(bn>GߢBݺ%{S'Z/4 B룴Ō/YM0bװͽ Çy&9 :>G~nALAkQZQ3sOP??&g!~ i:$p[M&_ W!K"[oHɸ5jA)%JYmy9ABNt hDڹ,F& BFT^ZDÛS4Li%ͷ{hL{-G'86r.%]+3BP6L^4(uN+ mJ+p)g)rraIWOxxrȄ)"y:lMMu$D^q0F\6b)h@;c&=/u\#[kq-sŀyײ ˀx"(Z $آ!:d6d X4p!/ A[42pa<> 4)p|U@@^7KKŢ) "5kr  ! Hl_ D*7/S)i\)T);ZV3|2N /xKl‰B۰1ƛ7(Y ,PRvl^M-v׼@:paXoVs^.K}\ҮP@# ۿN0 tt޽ko[A[BIhi >7ԍn#WiCe,d/d"҉S sbEo[]XM_g5-Nbkjb1}a#QynMA)?ʽab~u4,?,L6u&lHoZ5\d&lk^piwM13L&ީ3ϣA/Z 5 oжHn'N3 zI8G/'zԜ]rCH%|؉$-:)Y8a*-(FZА05j j5g74vweaHrJ6<Ƽ+NyB{ټQ[Vz(KVԲOcl!KѮ'01{h!kykvChOyJ.da=艺՜W(u+D,qC>;p ZTM'q45~ E~\_-Ҏr)GbfF <|H$tF)h+7$ۻT P42(Ͱ_܈VM Nuumbr-#SRkBA7KbOG(2WY>,~3h,vew R3rUbyƪ@VG<g.p_;t"dDVvdk N4]qyƜ<[.QjZ8y0mhˈr|ϙ`J_gPL R\x$ ,#y&yJ.ƙ~W@Ԃ^,5 O)s>}Zw.=$-zyq^fAS!41mqּk0!%huֵJgmlN6|QlR?Jh#NBh8\"L1 yZ*RX ."oMba2հ# teЍ3<<^'fMɍ/G2%4\鎺X䛟4٤O PjNGlj%+@IÂEBu%l^T!Yu˩;V~#~n|Жx$6 "r'koW876 ^E&@N~Qa## o i S~0݀SM$Y_AM#թ;a~j#?-hTSl9/p۽DơHܢ!q ȀFVcEfQiQc&V4bG.t|ǩk$ 25n^[ћ:]IlCK 6|-HnaL v *pY:-5Rj̨9xFsd`ZaFԜfuo$ LR%$@_";`qz$)fbca.Ȥv,g}/QU xChl _OZiw.-!c[OG GZ`Ӭ| ف~ y5D$9סЃx4amP=0fZ6&3F:ͣA*FćaN'fYR4D!5x-(qP:)"x1ѸꯐJ/mq)GM#ŕ~~-ޞޜ[V5ho*mE1FTa fxG8j>RCչ73?|QL-,U:\?r2y["9E&5[ɏIlhF^Fme /zl&|t/eڋ!=)##i?^,.&nbq A\Y8Zt(uԦNȝZ(=i@[_"0<zRQXmjꍥu2\ U;ԏΝY]矱Iz.MQZ<{JZFWTVjZ7gѢk]#OYz)$~5XfxqsfM!j1e{pChQϖ:J]A V7{KɆ, y3ZH̯T/ u i7/Aб_npB{dt H/%+,s 4l=,z!mV!nF-i9nr)M 9 {zLl7;k9e6z>Or5`T .S71~C+yC AS#891C gu$,&f9K|XcYr1]g@ E[ag\_hJxn,$%vN>u^ 8: %~ecnrEU-J^b62 T- ?C$_q{+Cb%A_v5ڭZz׆Cr%밾r$Aor_B<_yUOHPckYSDnW%USY3D;bHA~ jR*h Ŀ֛qοׯqFߋA~硹%:4Q(CJ㭉DvaЪ(.drG{~ӱP@+wyek~PxI݃]ɸg|<[ 5WuU/8LUsP)q/Tj.jjawE<,;7 * [k[85Ksy)k"Whse t }q2sah?힟×-2mwd'zXNy##ރn'\ïк[ĐEPNI*LƤ;{kō !З^rlR,S#ixy f{-Yp 滋o{}N嬓K--5aTQq;'yaz>_'3FdwHՃ \־XT c.UGT@2F=I0@$x,]Al $T` 0Iv&P <iВL /Gx>jMNa+,N>.."S@<_:'U$AN1Nl6^/Yx ?lPl)J4 R0?v1}k?\\e>M"th  d,xdEb![K686h*owQQv@ٛe6q q*{`)Bo~&&5'pujҾ ] FA%Chʪ2y?6jATt;F 5Fbۥ)ߦ $G| p4^-]U![}%=ьT{ BT9F;όT/2RLB3]R w23SMHǂf|S .kùї|C3']T걩2| v.+Z>N2e@[78rDVO2:.KX{H mlr>^/o% %fגE!A[qr-Mt+ R$ ~dgUUKɇ>qW]τZ*VVNj5ixRJIT6Od..Yw\W |O#i=؁&`}oo2sJK)Z ׂtxXTn{(9Zx jx\@N2]tOA<֬ԑ4Ttmfj-`7FJ۠oY3P"e)T춉![ ߀a.7Y,?LrAL"A:|/I@BX$)JJ՘ ZB׼-A띜 rqB3B6}fӻ̊lٰDu|ݢ \ZymePg5 U5 !K>߉SBːTmk{Z0i5}7I ":FJ#`\Ї[TSJXwH9 :25Xb'T5 }Ye^_Bkt1o kJ[SӚ!sRnK^eI2׶8k&(9j@g 3)5:f'@̤]gd)t-sSԜ^]khf8µ~JUj &O\ nAMtĚSSހ\ۃ'"R-,U.N\QHp؊bYŁe lr,p'. S;7&jO*G{.l AAJ;DFωїq]K0d+@KŢt!% Q vٌ:у?JT2^lg.LH)q \L9,tzT 8@Ig^x"XO 'h"|/ (˨ˌ,-CUi:G;Hrοu[̏"K;\~ >V ѓ\@lE|`;!`׿3#^SY iH:L*>ёSefk.\I!' bft$o "J:W aU4ȗd}QZz:HV]VnֲUIJj}(r4ėDuIVvچlXpA}}@i!BHnW*(nm&Kov Iw_Ca_uYK}C?~Y*Q/ߊ6a#P[Y>7_B!K,^B`AwE?xkT1jcOw0>lx[)3)_5/*X_s<=2|zyc<ըȥnenQS;M+kqGh*^={APPI(MHb=e1|q->!6NR~m}+m9ε<0>i;ZA@nh[uG:xkUeU 9eUf'#mVa={(&P ALbhWuvU]@ d}2lUa1d1&CR®Z* 1 O cS#( 5#(t;2{gz׌.b)bi@rE/Y,N钏/km d&UQsƗhPE+[6~[d8/,L n6=a@kQ۔̻`)K-!Vq-|kYr-S,lZ2e*nAzm03=&R-tWO8H PTvu}x]`F*h}Z,KX_/W@:VTpAn: ^nktPC*fHsfƟfF& I2U˫9hþSs-C *ʹ;tS;zbGQA)&O=[>Ӣmѫ 4;.=R˨-i +jVw ѷg6'i=r̺T15iԍLfj-7j95[Cxj F4z@ `Yy @eэVfCQ2BKhVf VQ \Aݢ:e@+Zo)~aLӥ(:N"F|6SB eZ@j0o(E9aNEۃiT̩.T-3U JѨb_ c)vu)梦TQTMIK,xjT؏X9ч\ \O-6ӤeHK fOEiGG͞foQ XsQTXjN8e<5w;Tsj5hHSQӍF҅nLEԠp^[dTʠFZRa5KuK*4T͒uQ%D3K{t5zPTn}|%cqe{a4E'F&C@8Цpicu27ŊGcS|tTe5(yr#P5 o0};tq [:Ev JM+}Vޖm# Bm;yv4Г֠yn_ jF m@9 TosOmC %L?]%QBdYI9wZ^n+jLh9XDsp[7jUk!non%ӲJvB sf+hLjT ~,v! oU5/t݋>)PFxxy_b sX:@6sbp('ՏtbAMQ׀qB׍hR'7$ʝ9^ܬ>,}X=‡Raaqtԇk1>,bFxxռo&ԋ[s , {}G[ASoR~+b$+53{"jX {jLgE*YCY_Yq@Yq:}>+@%{MRJ IsZ9iE4i+4>ӊwpZ3uZ1<'% НVt|ӊקrZ7n5_֜Vͱ=#|> :/j^*ԪƯX4UKE| VE^*J^*'T=TPVmOxkBJzyP EHzםVPMN+F0+V'yӊuB͸^&C_CYX<܈V w<)Y҈O hh;Qg (;} QܽSEӨmdVNfEy b7N~Eg;rx h3BFHN6)fo!t)CT'!УO琧an ݪտ@_4NTق>W|C1lk7ލ_l;_lur[A(lIpezڷG>O7{Wb+Bdt)4ux(_rWUU_7kQ q_UoA`zAsf&m̡Na'zvX/| RYgv&ʶA9>^yk|y1U͋:L4~@oRyF?och"]I gwjL#"σ:8Zv5WETMBaJI v459GQ{q~"EY:p(/G]#QZFi#]6GWlXȇb؆+m&7~O,eUmେ)GL3iO^/n|ٙ]g>j|dOGj1| XөCfw3N}q6r-7bdF9-R_뽎hWa 3ki Ex(vF4c;`TUrҒ@/\gk+UE,CXy&$EWwes{3?ZLW+Q?,)&;^VR0ކS gWozFڼJI.ŗ뷵Ir쀊L" "/_1f)9/( KcT<(*!nЄ f2Cѻy`Փ_Ĩttr e/~{  kg/&ʕ*{#QԄfpX4u~35ܳr@MumKi5!U[ۦr{#r2Nzs[} _TZRTP@u-~4[҄_@I;T tk1/ ҄r4S_=.6`?UK/bkrCYQ2ѵ0t:}8Ev이r;CGsA&ܽ _8sCnAThlKiSS{d  Tm-yP?ΧfŲ2غ K5[4I(Ot݆Sh`b~DHҊ;s$ Ճx*K#.*Zo_wLC?7͜#py:=i\NP?"OCI>鉥X`P}]_ P,~)xŝ*GrjbC;?Mn}AxAAz XOjҗ<4=`JF;dA̳E(Cjqum%9_X +cf §w/(=C5'! څ a{fώO}̱"8ԃ@Ɋ-p^c1Lۖ#Q'yX 5g Y&sٚM=RmJzuޒUnҵH"Cُ+M{| 0*:ZJTT  @( DBa+[Y7u1JK4D}9g8 uk>k}ӥ(?faM_ϋ]Q~oRr(EDۂmR:Lvu1 V}%<^JQGd%{FVntN75v' | uW Dė,bA#[0M#OLE! j$TM6idvEL&E/"23yQEnMj3*y BߘYļ9oWT vJwnvD-ҡ%{(wT%_{8_Z=[l m6|?K{rOJ@p;J@U͒רnw.Y{]*GM .LGwvۃt>K,03)Ž>❮m]SO~W|_t=9~j4`_z)寠w T?.KKRxDE|0u91ݲ8u]XP,jjxn/XQl,HCaHU5]wzĿPH=,"(cG::([-:Юe"D/qXPzQ@SY}AX: KE] ƒ[q0X:Q5UTg6mWC/nLƒX,:r<_)5cI8a"0bIhIᩳoS@ZFAp8a|0S%{9܍%S`{;T YG @IɨkcBr~BxI qkRQ 59˃~ҍv@%r}bY\"G j⻝(g/ U._qT,RpGE ͅ~U~'})jaqU`)z%PU"ʱņ=bѓ,p7[/DWB= N誨Gq Λ͇z?.ҫZᮏ4TĩoGRL_8:kI!a {]Sow;HmP{ 0S' Bؾ +fױOt-7>tivJkOhCEB (aO=QX)[PX dݗ+S@C{ ԓkCBr:mnߑq[ (ʥx:LHϊ%.!+EBL7znIm{|\i]]h_ek++cAϬ~({-!w笧d 3 sjC>HpߎHTe>vQ4s7 }Al+h Щiؑ/|7 qIPG&ѡg706CM},wbBvK>?WBDWBD#c%3~-C]E^. ep p, m&[`eC \qVffnlbbI h+*˄z`sMuM `{ *']36Ņ68#|'OH2uit/Yd}L]3/0 MRK/Wu}a|ڐyFCޭa,$ z%IȮ;>7tX\n ,a,.W>ܧj'tjÄ>tB:c3"͚^$d\%tѬ/]Ӆ,/i0ШU=#,/ۋ2 Aϥ8PMebu- 8l O'ROHj'saIDQ[X.z9Qu/6i*Ip"r|GIgf,mS ʛ Ok5.'>Jĭ}0mҝAhC6 ܲs#!ɬqU^J#ݮ0=U#trgOPաc~8tK]5#wLnj4Q؂VGIC@6KG/qe]]_ kX1^܃ׇ16ٴ~ѱWD(‡.6TtJLqj*Gݬf!XНH΋#dHY90 ST;bQo %͇J[]/ Ψ b_qrA܀(+<5FlD&vdŃbV^Jm8E #MQ|**5]Ya^gb ]w'(hn,j4P;ꕘ6#OLI69uRQ,9΅bIljұ~LehAnn b 4cEpA7-tpAG~\ \@,#|>T[޻_W|GJ*ӏNb]b%nCD7Rjaq+yMQ+ +PVbF)IQQ:+z R)0H7 Wj-L?C_\Rx fF^$fi0K*-nfaJ/ s~`hfipV 3ZZ&8X aN9Eti0gIS&%3Cfdf*L4X a.^zt\_~#".sŠ];ae阰>ºַ9X)a}NXfZJa`%9}@XUS~)Ex`(MVťa=]Š^F VlKIA J.g*6k? ~a PewLX:&V,K+Ho*(Cuv1a%8}) kva 5KX`MNPXPXCu$AjFzF꣢9HGa:#:: 9b:9,TKIJ|&KBYq2䕡d aepi]c}M^J!rJ~&hť]M^ ˕y¥kR%(..&K+Oq,Y^v1(..&EKm*V\.qa% SԻGMbrP]g|IX}ʈdr'wک3npPܻ&%+C ;FƮ_Qe=6N&v~>)P@/m"H} !wDާ)[ oD39i#)ܱ]cI:(U^.f=VJ{""]X u'QQLS~ɐIu\C;M Zu0/;$'97:3L{Ue f.AKNJ*7ma[tT魾y`iWi^XGޫ|^WO|-[>փ]6ñӱK$ϝ8թ;sp@CP]:.Ӧq-,#|~Z"|bjug*LWG)fRtT hwE8y:ǥK/U5` j}Cd8UEQ-:B՘⨒ZqzGjOJO5ɏ~C(>4UZ 8_T\Gw *6{$ }CZ9QBNoN}|@& 6d"ܣQ_.h2ї!_OW-b޸ubN9XRzhZ[Lv6rKUJIYcT45d/ '@ G]% [{~ ډ{gk^"=A}0l##ANn㊗6UƅEXT9Zhw/4 T; Y~][-c,U.(v[: (gO>L7?1=m1xђTLYndI)R#T+K>Pztf&iQ}!l8IDu?Sr)ԭ^*12e& bWF+I\"SXH_ӝ5XyTڎ;I<'#NA!Su.'6_tr=y'vi)7.H6 Q&nJ=q}=ןN@ζtbwVI{kaihϦ:>z|1\zb9na^zfNN?++v`o)ޥ5*eQC8Y]UB+_oFhR73/)u.lTW\=%2t4}|>)y~(* S]zb;K'#w0uWqCں*U'EEzZbY7<{/ s@JsYh-a*#tGKɋS#OWu/FlF\;KGv IҊ5 %kbXP',cYi4>ZC}\x8׵JgQh9o@X;;E""([g|>2 D*)7Υ>ry@rk*v;➻ B&_XcV(. w߫HH2p!ཞ~$Cv|^(+< uR$*V.K%H4a7^WYfB |&yM2AmBpt( @Ƨ" Y,mED㊋$]Џ&MOtgԅ ~UDDHq&"}.R1:~q[H5* (x8>grVNMz75t($ci z(xnj;%) ]־9 9 )O7®~ʒ^hn:H hYߐom$kfi4|(MM4 !(Y48 Fz"FﰜbbYrڰK}im-}#T\~7.U`,f^)dqZk%_ViSZM~UWkx%mB{r dZM*ZM,nƐQS U5(EM(EM0EMEMeEMew:Ehs

Ҳ M؍VQ4<if; z2 ~"?qߒ>xwK{vjHmm9KYur0PYYuFպh!aqO5&UE]ϫcA 3Z2w;KZ%Hb|ydmۍa$r0t&]JwP:,Owv(^tZ}H|R6RL,\5̑&qC4Mnh4Ψ';Ks/g*px5:W"{o^'h@@HpZ' '"m1]⚢/ H^>npSW阔Le0U. V5J!\#َۇ)7bh!1!IzwH̺PmH31"4 8>n!Ӫo[ܤY |xiDW\kb9:{m~16CL3X8|yHyu'47_e)/mOS?4K "U O/Y?3yKowI`g~p6Te?6ѨӢX}MWH ^!\Q{e$X `te'$:gOV {S[ǰRco0U)@tX G&HٵFR5Mkntw#bPbmqa4c|M_nm]p NIkG7> mR&tqmyY$՟ڦŕZٛo\mЕu+6; [kgTz\:t߫kd#UR:Pmqa>V 엒YiBr^ZI`:NX'N9BsQ^0rptl)$2}edJj5d׶ !a=ˆ䕇{^[Kéz6$'k 1 l!?͘,LӍ2\^f;]Ri)Q!M$m;&ށ}`?FoƗu_^DW\b,oRde7$f:Aх\<% iQ^ ҈RwK%K+n0=\MȞ2tg/t ɼt7:/pnPW͔`*&uQ{0oyk6:AOV4 .U(VLU0(Y;a^qq](9pa}^ILNcI*r\W~=g䓄Gz =?Z7*h?F7O|]OX2Iם0ܞuSzG)z=CM~ߩeQ~柘[yurwI]inጒ3XtDфy(!m8\\㲝O: ېH$NPuJ2.!Bo0 `3$Bj8|Q"U窱pL\d|R؆E Ss?GUqm0 * J$BmUuv8>5])e_b}'ջT%`&r.PΨ۝/@mR;yiҽeބko5J :& I:?U^&u%֊`@d %CK;$2/LfG].o_͒uWk躴Cj8U_Tݶާgq)l3ч3LsQ\9:ݥ!| h;DA|د7a5QҷT7E{NjN)K}Onn]鋛[@)q6iK}oB|PQP 뼇fž(u(oطS"MԳmaHwWwDZ:d"fIN6bqU M@LvBK9NUcT{=)KdDeLH>!l&CL!t6ssH- a3wqy̅ t>Т2Xo(c!h+)+++򋵟u4iXakyKYHc?CO[+;.~i̔oa3`\7/E$m?? g'?!fi赎e[,]F'Y D펅V;q:45u{ N%߉=1j%}%xA!O°lA0ؕ}/ܕޝa3 @xR2wNf.#IVdA~IR8U m&JLUυ^%f-}Ms}[Zc׺۱Sإ{ķ=<ld9ℽ `<g [+l qǥ/\ j#[AD3F@@Z 6_l(>O Uq~mvC[ntrKtR:-l;yxy>k(>/<;HO7حwD`#{G jXG@UN$x`#m!('8BPCOn'^+ ԙ %0L$IMA $8N#AA.:֗` ] V##$J0`"Ae\XLteEw]̞I09,cW}]kDejG gs/'Il,B5!l8cQ""x)\oG#(~gvY1>HR\K1BY(kn\Vm*jjr> yy TJN~iJ [׸%S:izIJO8h$ ܴ既9?55m5=55>7oD`4zBzX|A E& T9y-r-pϱšhɳ|$lF=GTdx5Sau?l=*IV#]Ҡx #.Tݚ*kIvklI˱(/->7G8$3Ն0gwSHE-.GA]:kX`&ZlIvaggQۼSchպovF7u[;wڭ=zاon?`C:la#L#G5>&"2jػ0abIS;m)RgI̺/{^Nn|`iQ"kZiKα!ްX4j** ϰ&L1;NNB @1ìY0 o= |@| ]M5_I C,nOԸs}fOsFzw~~u?IVn~E\Ê,u>2r׊ZGcYēO=g֭vs텍/?7-[_ƛoλ_^r;w}?:pLJ?Ϗ|q/o=u索dz5~:狗j/r5o/L4pC o_j6J؝zƎ TaƾJc_YcDcǥd}e1qu,93'-w~-ՖY9\<,ljKͷϱeXryM~ab\˘l2K+x?X1\Zˋ$R*T/4!,k4 xY1b$edd > 5ðspptr2f 5lcseul-5;bZ2sS9s2,}EX9GlKZ-7 7ϒ`Y`c"XNG(/nkړPQf6&戵|&|3~TOlS_s-6*L[4K@nz@;P̱=A"M+Eʃ%yrjrPZ楒j%Do c?3,S1;3Bud32m9to=:hvf KNA?5b#~D39,96wF Xe椊JX,TǍj {X;\ w4ϴe mVe3ASۙ6a,ʵ|5yקۯwT{pJ_~D[vv|$؍ѹ>NYQA)2,l ok9R Ӥb%@eXQ,r Y/r&ܰ(!11ebbdۖ5 zIIfoA1H$ԅi?=?s^^%EGeۦB6[Ǫ06Q'g^48HTt5n-O۲~-вA- nO3bHCr5>H#Nn{8I~j-2[g9fJO[\ԲZs3͗k:{]Yږ1p[ol厖+;~w#/>t"{vG}:κԐlܩ)r>ǚ|{?s֨NUG#X2O@ NHe$M;!IV,dEV+ jɩDȳ-Jܹ2b9ٖ5;bc7̹9J rd3uc"yH:zk|n=2${R! 7I\x{-sBeRnrf%"#XNESafȢ0=alJLC$%D58Ӳs1D'  $$(]J1Dn6##$lE~dQ9$EX3mHv"Q& 󌳤XsϔiRMZ\l/H!`zʰrX?9'C`%!6wŚ`Q!tS3hxxNZb^fND@4CZMCҼ'ڲ'琠 Z:Y5tBϒ3j'ZN ؝(Q&:4$Y]ƛN msVQz@'e`.CS(e!<-*jW2`04c Pl $P$dvۼO̶Xϸxb ?<'&"3`U@^TKGQƛ`oB{ xRU֟` 6͙#IY?T&eιO~oa2oR&/JlaC2Jmc5պpXD\OG#^ּ!T2ɺ $6ƞN;c4}H,:ւj]1jyVܓ[S~ILLcY6>]X)`Mܺ(smr?cݦN>,u;7qtw_~T^TL'}uw&bVhnV4*)n8rp喝SÕ=A3QqOTd%Jي<.6ΑLU[ _D1*ſDIg5N^Uy_ 6,2>~>@LٿͶ]uPY!9g-]esnbannh&%dӬ[o0|bN<{.ҳӚOza@Ȅ3YG>#_ؐrLϏ" # B  &" '%` Dpq#$G`A9;[6#X_EFM0`AA?AA+}O~FP{j$# x`A1A6AtIq# '$FБ'J8;|`#%y &ԝ3 |[/'?]ǮW+F]86 pƕeO^ܚ[[ݛ?ṿ>ޥR:҅E53T0"~zz^إ~0Er{%~߾;eK"Ns:MY/[nEkPlJ޽ Q>#X,G:l;;@!V u/>1$T kxDX k)X ?0i_m݁rW'_['ʷZ.E# IFxg-̰LydoVףghb$3itJ8m@/f:O#A>Sx|С,>>%&&xZg[lEW'W)诧q~%pɓ'7%2S<[SbgMNaE|['#7W""u&&O-уSa|022rjyO>,88 <5Qv&L`IIIlԩlƌlqX6w\͛ǬV? zh&V gOZ%#?cKfmk·f7ǂvΆlΆ}ȏ8O8(g,`7M9'8}%K0V^qvZSOuֱ^M֭[E_;Õsm>`{agb| ;z(/G8;y*v˜԰K. ^1ƇƼi kM|ӆ{;j&6al+})H{QŏS)\g)S_N?4R|3ſ(J"NQ#+-ůg)EMA}KOMW۴/ҘVI?u??fU/jw(`ŏVM&_HS)?)~'#r ZQ|WpwQ8ڱv ٞl f; ίa1!yOxb|kC_kP?Ϧ (JLߣ(>8?MkS wS CJ$PӞpvagj.ٕC+@GS/(Z7o(q_oPJJ{R?ſOSo}T"?Z1c>=O`^}ǹ}DFF2 _>VS!o!KddJm0n\;=&ojchbXV!3in|JDhc'گ}X|8cG or3$[J?1&j؈FޚhbG4f FޜG A犚&eb6<ײs'Nb8‚ز(,bXM2sџs,3, cO>${s='d͛7 y§/'IDŽ;G}$dS|;v)V]]Μ9~:wV?3z*[}WM?;IUsh[H4[wag4~hӀ@3<lW)Ri~FPqr[.JХKuYv3h ХkVνgP{?mmKQ~= fz4{A)@moֳOР6nUnd0Qnj׶-jc0n{Em 0ȯG'OAxB7{t6[jLgȗtw?[~ MU=}jϞN]XTz& Dy}hAZgoQtxkK=[G(: g}[jE=PL%%TPO!a%G=J73$Ӹٳg_… gi^zڵ˥G9H_IGRPPo۷oo2QVn0iF]?i}sOg}*_ss /%I"ZO~(3fL Gpnazm 鎰 q;Sy68iy}%o ?oO>Ϳ;~A~!qHF)̫Zm۶B٢ȕ+W&\ p<([n q:q(; [?<'Yfu޽Qxyy8 'Տ'NcǎwФ<$pܹZ+/~~~5uG #V"oş)hPuWP*4E Tnк~+{O۷ GupI& 6P0Qoh;w^??G=\vkzBu6|oŋ!}~ossN2h(Ǟ={ݻwra oh'#[r>#·|GOS[[V#~%AE\AÎꫯ2Gy_h(g8sǜp~>Cv ;8h.|q-S_ூZ*vv~IqG84P DC_<soM.]/ EPcStQ# .B 4D0⛼#29|Gn7?\4q@:Q劺_7T:g{ Dx{X4:y~o<ߎ?ū3a%7_(c\@<3'Q%1DCѰ_FsO4˗93 4T4EǕ+W7/O??kH瓿| AJ{&=r{F==xGnkCEy 4|nLJ x|-#( xfTq>U!k/44(y $SPԓhܷҳ){1_WhԺ@{J~?_Z8m(,4р'Dc72 j{ j{F4d{%緁*7| ڜJJ hxo[Wd''dr>h8O>-gI3hP3hP3E2v,7TQi(hqP0\aD=*9'gOG4~~IOaÆ"_  yTZV2D?D;ksU7TNBk*1/BW ܀J ~נX {KCD#E&2и=e17Er^ Zc"c4? xNxu>^+ceww7-DgBZU!k (hHӢ x'>hg` ظq#饗8"uR;z*?T^ḓhhҞ'şE4Zbz>)\#cln*L-[MCc:Z:~ #49'L|p̔i#d ^{Og9'L!pE{DXxA_V'0Ѧϱz>[@{.SsEQ_d 4DGKu}Җ7О&(UVUPSRR?1.sWX!_~)BM16,y~xc=}Q4`,8ҁ9 h@ >XT=2:χoxa͚5իҥK{yvv(wW ^ hƴ` 0c4 #0d$hi!/2?Lmw]^^ӟdh* ~;?ڎJ/0Fwڹ7m/YXh"Q3O2E@ Ab.|E_r^ џ{lX ƞO~hu'6]dΟ~ KGI>d, ^$o{J'Z(LZ'9?p;D?w7Pt~S{ͷ0L߈}.`Mk^O7ҥKS}$ 1, 9~&bXkc@s/d{s/h:ܤ}_v~ʶ4t9ۈDڳ1ߕ5?ڽ&ebC{|ɹ8he4DFt"']6Iă6bk¯?{?¹puHkC~6 .)**,`}{MPτP#P͑ᱥx/0b {EXڸʏX &aX8 ?װ!9ԧz* m} `~!Sb /)k( h^a%]x}4nP`^}OMs6}&OVG#;_]{\UU(d4jd$k}{sE1(7A#,h!ӐYڔN֤%MV>1ZY}~9垳>k]}Aaatѡ/5̈́1_56hHɫV!q^\q /;lX4{!yl k?cO6mc=|Xp{hQ(Ha'>yt ÿ}).+\0onp.^[9>Ϳ&Nx2=y;q1##c,rH`7׊"WE{ƃ9!Cq.v^|[#[uGSG6"?s(KǺG:^cA^ n#f8_y啅Vp0yC0v`.] prK-1[.}3cƌ?ɣGˆ#3 yx_ƚ p+~zW$egg؀kU"1СC~&m>q7o\#6bɫ)B.}_%_G81q`['KiOɁ" <^O~igMu-|jQT\-zf᳻+_F^u`#cKJJ uzڵK֭[w>6l ]fM|qqqƍl3{ zڮ]0-Q wccM nOܮ*\i<)IJ??}c`D }Su1pWecb{˥Yuaʥ G_1VX@ kQ],`8^a܇q q'0Sa ▥>/`c6 o gq-C_}]7Vu#Ɓ7l0΍|޳:vIoǸci\> _/_Fj8(/Ww~zov+삋[X-Ŷ9_>cY9oQQNq.qKs[뫪\_[>iñh?Ϳ& B;a}#.8ny"'٘Ok1F۽gϞˮŖߤ,&_KG&__dd;pF>gwpWb{C'iWΌtYҙ.kM|VrNNZ)33QyENJzZfrN@JvVN֘n)Y"9'$<>0&-'whZvN kE(ټid}']W椥er\ NTRicrlue{0IiӎJΉ?)k\ZvTd^ &_#aGIIV\=WnlVV21&1&66~@K\gMI RCΓڙ0Φ7Y3YMWRږEhօQf06ϒdV R,+fV#Vþ`9p&ZV]ԘKЧj}fƸ`C3`3wߘ%| \75?ӚnyQ.HkPQ7R-Ѽ3)x,OO|bí}VeMY7bGvJR9U~.Ü\g|:҄8I4NTb^^2^%O;fce_Ֆ gjw0ޣާPj:MO/ogUEZвYJ5[?F+et6zaD#H62lt1Xxm7GFQ j65[{p~+y Ϗ^F-z>"Q<$txBc a&FYlknn}kwqvL2^f\9{iΓN󞃛0@ڐ$@3 ӛȧ4@j8:.-0=FC-VցYMIT*ʍjԑbYw[4^Fyh'*qniw_ڣal4n+Ifj:S2J٩PP\W o+У4r\'C򔌀àGI;%kj.cq?Ϳ?7.Y^#+NG9;gQս3&1d ,nTZ*TeGR]PXN'U1g47An4c1Fs;_om)"K R{;ʾ2Q9P\tI&+fRIt%mz0uƎ^|R{qj.wc y3ڿƲ[r m\*<#CNc rrқv4)>N Z شrzX( cX6Ζ"Vֳ2;:+DQSJ$(O)+bTYV, uR-Q+ԏ3j72` ̛y'^&??io"|Bv|X !QU@vWWAڛR56hoh H+*d\xn-siM"k8`@Rt<v]+ 8Ty״ZVZPk}^kmas4 _(b(폶Xv y+*yRnu|u} ȞvXM FqD=L4NΤ/ӝt<,E4sZ9NWGu,'Ip;ÝT'e|Z\[,r|!$#dYv h'@t:$ @ZzyNb`يNV|`"]X^ xPobV42FNf'ޕr['X8Vg0O(sd>|/|إb^2^_/N9ȫy `I^\>*D3.Z6g$ "TdK"N$rIb%RED.XiqB|ɟ28<՟W5 퓡2L6Ვl#HAҒ=e e.e sd9Mșr2ޮzޮe?PKgPy!sdistlib/t64.exey|U0ܝN'MYhQ0$6htKt$*h h0P-0"$VL;=3<:3–Dq@H{ι՝fqy>~g*wb2OMzWhT:qP߇칤sɼ%pVV-ǜvP\(/.rjnLW!4-R JL}A&n½]63E /s9uǵa LV xy%Jpm#R?:5.] ýxbCzfFuHI'Ҹi+ k|_J_R&Z`g#5ۂQGZlރS.'l6˺ ?pqsYTO3ec':u5P:l҄HK7\}5nz*7* AkS4\WoiK9)<vjָJ0[ 0q`rU;9)dejduD}~yÔU.!< wz7̺cԊL<|-egLLKyS[H܌i܂9ā3*Tz*nWˇ0o!=ӀtieP7Gd*2ރٕ$#{f}S%q2yPV&)MIbR+ OxDr<Ϥր .Zr󥁩R)JdԌc5)-I=7`!5PMT3X߱g"!˻9+Hyb&Y*`_HK-f͈c8y-\aU 폼KG^#Rr} HRBEAlRvIiH%}^'RaC L[P,IFèC}ʎ$N AV"ۙy!C]שpͧp#)`Z#WWkjM%$5 Dۋp`@tZ1 S 4IoܭU_kP>)q@A79gM0MѳLZ9kT( T5%9%28,;v!+7TI4[Pff{l[`Si%TqĬ)HAic*R X^gk\lo1Jc>‹#`En[|H!&f3Ύ:#K;G15!p3r}I8yMԏbTFķ87HMRY`+${tD &56)I8R>D6z>ϒ4RKG_̖ pnN"Bf9G2Y'z&֏L? _-H{hؿ abɝ2`IF]$o= 56迁# &ak^ͥoBm³ (Mglk$h Q0< W0sϙTG[!UKIjQ0x)$oؐנMŋH\q^MDT!B Dc;%>#PM"gMWS$ JSBy_nmH{نT _R I Ij.2ѱ'֙iK`*A]!܌|Ol{1 ;QcՇ<^LSV}Ąe Gnr7U(Ū4werDSR?%58ȅ+]rv-0+70@AR?YEv(Xj7 r)ѓ<)rX\8'gF$!>MlN?{zK>J{'1~._9 u#QQ5:jPNQ)J)ے|z+ S.mrZpJ`AcKr{.${̴RNYN>]w:5|LEöxcLA農L¡lN"VM!#R W!zG<7+jLH}&Y6`Moij=*4I7I孛[!zƋ@m}H)!{| xZ?1$qY5)<,)rs$} :2k_"B8N738 l Nߪ|:ǒIKJl٧ҁ+WN b)-IOo}z[_Pm)SnT=s&Us vL"hq ~M0IN 9 )gwHj<H`9fW `,h:2TIw?ZkȧG(vu%nxC.Dm ;SwZWN6?rv&/z^p6BueP6)lM'?Li-E Ʀ݅&Adj_ _ ?]?zh2;$bU 7J1nL#\@yML n Q;?0H[7UXʊqHn&yeJEUtd@7 'Lsb^U<]`jX0JҟTU:]9RD$w4G~=K;)y\`-w?z~$NB飏pYZ9m050 CH`8r-! .)2 XէgCh0  V 2XA+yȎ:NPD '[P R_' կzWb`cGБ|Hzgp/R4.)Ie6:cq-D(d\c\š1q"p$+VhP &Ղ L[ɩ2v?kD%dR! W>c7?雝A&x\"nU%!X \f$J6oW.jQsf~wCw}󻠺+m"k^"娒9UzPH9R1xe>Z a=.m^vL;a'|}=cZ޺yǠzC^9ظM_VQOFjϓK[].҄ Ќ^K yD?! /G*n(sRG0 }!k@Y\=?% ;Jx蔟}> \ґ4?ۖש X0:Aïv5nOOM|A@n|OCQ)Z$rHi%_Jl13$>,KŨU&);uP'F"?]79=K = 'q9YZ^U(om*B'KD5NZA}lR>(-,YF9 = n.Ԯj 2_Z(bPk>KFC_-Pމ}ݫÆ{QnC(]EцHq QSp#\si#ZGB LzD8{rڄdIp~hȮzX.j`ƬB]cL9ο7@1!#zf$ ?1ϑ]c6N[0Fq7#,GKB],EF\Ө_|r*wc3d_8'xELasAKO"xxʆtdbv{":Vu; { -g5G'ّ@%G479K, $Л8K׀٪@NҪI x9(8# v:e^:BMa 5Hw󔽘.fZ9,xRcFvnL"]:Bh:WZrc #C2PaEY693e {V"+73' Pf/xnHb#] ՈOסKT`wXi7ox(}.[%mxY$EWs'x jEdWgŒya/zOE.W.]@vf/Fۡēj8_b,n\lL,,誘.^h 1I<͊)>T.9_ R;cQb%<1B"Ґa)pA0p^9On1Bj'2xӨ"Xbu,_X)b^S!՘-[MHk|=Q4D&iTY?I*[DT&H(u*}eߗ X&*xeic&<~mPQ|0*ȅ SZyBn@s4Cv,7ȺڇƧl(9M9mGj(W} q"m';g]~9BP!;ȓ oD9~K@F[kˇIؿ^ecsp݂yo#;'@J2c̀ FR@²iHϪ+t;☲wS*@C|*GAҞZ)<9sȚpg?fKEqk.|R[nU(PJ̸"eQ0;XU")räIi ЛttbV4t޼N?ké<"ٰ߆ ls!VQ3K6 V$}g L{ʢ= 6Z8Үt~zcF([--b"ߨ.6W;[[IsB5 9SiC˧,06H~ /~)Y&G}k](7OdF;dQ_|/YSw@˗ʭm;x4Yb$*e(( }rHp#<Uh/Uf:'MIUvɴi<뮌iLeDzY0+Zdz~<~ږW|m/.ϒv=z퍰G|3N=u>j$Yq.J[1VlORM&z$ '\X(Ug~s40Xm4Wָ M$)/D$ܶC][qDD1l7-Ts$svA{雇]4Uy8HfI+"h,Lfh@#bY̏{˃Dͧ@]ڥ a یJ XYZ Q7 z=$I65Xs[X33xK~q_;oCKwT]fxPf~o/4^D۽DHa1[m+fәcs٧~vHbW+sOHpVI濬%=3BVVt_#l?;9 >Czgi; ûrӦu|ԬN[}q~0Oq$9"P]36ew&ˋiJ`=?"=YtO ]Ɏ#C0[F6μ#紼yN̵1Ppy2C"KDpK/e-<̛>v߰b7I%'[>k+{CGdǝ#O3m&`q0w1w3[liX׫QP2KCp]h)% 3qsuQ 7~\^1n {: {9W鯒')+괔8l%ֵ( ,2E6 hC('a}"B Rf]ruGŜv!˳6&%%_D1'eJ= MjP!)K[I'/(ISJ( T"Z'UChd 0bZxasU;Tlzzm̀&Xa~-LSP2TE$Ƀ3 {`5Xo![]' M)+L!W( &N@4ftcvdFYlFO>gCaZdYIYPol(dOA□~T#v*U@Y>dѭ'Ftd=@C;b)\s%rB||lnށtdtTrgQd6 4^ʌ\!4[f@ #*\&+LcwDA,?pX;'JJmzKt5 rS)n vVJֱ`U~w50AbOQk'մOؖ:m\PꎭېJgKԝ񧑍B6j=P 0$=/2Oc8l"ip|.ݱ#qz_BxzfE8sSr?RbsCpRPjw=U^C1Z„P6wPă<+t}-NlF y kNynԑ3IR%EdQ.ic|, 5PYSdËkd% 35\"Un@hʢNu-trW cH8YgvigtsNS tX8髤j|sXúRF . q(83?uu aףJu)$L|wU9]bޗ<ՓAyhW"cXB/;%Nx+z&Ty"jɯPBip7tw4a֭|*hʷImRQIC22T2DirmBp~k.%r$ PtCaR"iI6?_9+#w"r6#snRcBWx#:q) II7śF[zdaNL -Jv,!ྃͲPu<.~Xbdէ)!0d=PM8Uޜ>ON gZv3ČYƉ4@<4wZ1MeڔK*= "E-ꥯ}@bEևck}$Wݳr5԰v2i+{1] ,gqL=צE٫6@GV"U]u)Ub|^ѴD|I/ƴo4 2IN%Jh2BJrjKzT@X`wHEFL=bFr0m6PR_UIRdJ+3^^-G ?*<(#"ֈt< )5N &'rS=GzrTC4m0ܦH$PD P[؊Y#uP6bW&T,VMN0%&QMz^LWL|Dw|?IfS_IFRB6mV׬"j3!I ϯŎVOH^ m8L28Fu#G^hz{Xa(& *J}ڕk%$D 2i،|29ёˤX7R#pXyRf g)㴸 ]7ok|xx كܪW[ o5t hŵNMȕc_5MaG"xrrm`!?\ps9D ^vyЌKe"OȜX&OxA? Rd歽h%yv}D$U@KH6 O.5^\#mYKWWqF5Wn,%(%]\JxxwU֚hTubuW3p N4K*l66xVs5'N.LZln U.5-dE3ө=JBdcwe@ZV˸?66SS|S}|cW`!) (=輡-ۄ l:};t OAYzt` "^V=}XTYo qTKq\|hVzNuTL~(1]IwZw&j^ rL`$j-V&komr Lȅ5%:[1Շ*X?zJ-$`͋?|!xQn0;֪hE=J0&]w,_ coG,jzMߟ)Xr ^_L_j󅍒}r#!:T쳼8I~Vm)r˄MPAlw1E9M%>ن)|K'\a,mRd0&͑%fA:$шU{9qN=?N7~/$s#+>*g1W  Ecd-fbnwǓ/L[C_[0o5а$dɔطC{-?g?L7t>'o7% a3yd;*to@`],rYiZa`&5oN] /Վ : Q[úEB0Səzᘷ+O'A>?U, X7`UYE#Lԣ 3|ݸ8У[zO[B\zoi1-`NdxQr2@;+x?bM>W9e}!<8چCʴ i-.L8[?FC>as~=pCטC]y; 8Ӫi&>FR>vZ%=юr$Iʪ~}%' ݣWmY=Gl1IY2<{:9ѻ w%w/3=#ogs- jЛR$W2Q~LbJ(@}W0xGF$#өOWyٷxģ˙8+#! <2@Y_k@V>EDSK kP-j (=Drie GF⟠A>[ \ &^+|4~/o%'$[w^W~m(9GҨCS_ &Rz?b\?S]bmwK0I.@RB'$aߚl#ČȻRe4IXwI8F>`Hf9ܫ#;dE]K.{w"ٿ,3 mL0p\uO x&FJ`]sxvh2hYqe>57Eaya6@VX \ Pk4mbV:* gބO^\C$>enJ,pw)yt|*4 (Jȭ}ҵe~j6Ux d׃BZbr*ηL 6$EAr"?| SL9^PvL8n⺁B"%^]}Ns:zagۘc6֢oRX  ]Sfty ^^,ߋ[`etG/iyoɎĮDMw(_LDPiRre%0ދlkkA&ϛ>e}zM˾%6sk u 4= UݶhDž6 z8Mi<(]CM1΢D|gn?)UjiJ%`{naZltswI٥d5v43 ?Q" /mBKqd3wAG0<C6)1f^PQ1Dd(>,ZZ;Qccb<@*/]: }R$8ߞȋ}HCOC'Έ3ЉC/sQ>a\ťQ ^Kث;^EI ;Vt?+D| PGngK/=ޙ%vD3'D[~†/PzdY]A" -xζ2~H*?}k̐!/:g'rҥf:d~J=`ys=l`%&I1ehL,lEM'owԙ#Ȭ{n_׸Ar5}fV?L"?Fi֍Dv1.%5*3M[YCoבj|2iD90\ a-$wi㼡#Q% Vq ) 3f:F~՞A)ZaHn8k<|J(/"beq;MAZ"}3eL*o8YdT *U"RX?#zބpӮ5m{PoU\΢$f `ry͌ gL a4bm("l+ns Ewa~8xqG`b:U'SI#B R[Y̅*5Gܖ=.OK୦b,b2kVoYNcTA}3 T`)Qﲋ L3(~!T/ 2}Ჳ&-EgLקX2()[+)ƙ8ٞ A3c3>ܐ0W ?`ױ\VtuId<ИTF4+v@Na#jxdey ֛5~[՝N&' &H}+)F)l,Ŭէtk C*5Cmu.L =roJBקy//֣a7qV>HoGW?;-2ߧ.Q#؃dX'5@XXPmQ nnaȳzrރ!⍭BG&ҷ1dX;4VFTv_.7S e 6-^o"X@Y⪄27bl(3f /pbcA!4c:iu0zԢ5_5]LKH&  X>tk& &?)Vߔj\[f^k;+c}f)U)X8^g(1Vb%r&݄Ѿ׌R0f(VYldЌXcZݱtWQ0AIK䉞I{Kk=Ӈhn@:X-iZh0;uLj};벀; P~LɀmMLlW6炆a9_V?,%PIkC/&USFC惘C}2+&sac,aKЌOwB=UvԪ7A$KpCSʩ5[bs)K.mO w~g9S=lW1kFV0d9D|b"!: ؂n Fg g[krBs3nN9B,orCI_P&“ ѽ]Qh! BvX̤{`Nj6?68lR #߄$Asʙr>itBzoW- bekިkExv,Բ i @a4z N-2biǞ"dnK/ |JrІD0(vm>~[X5ia X+M1J-VgQ z,>^yj^јƅe{7}F\xGkE$o򓊎mh-R-N1D/{g m W~և A] |^:%;mʧf$yhPSKō6#;hi3v:>(\w.';]G:w:Y럚P9G/tN^a*zCѽ /Z~GiO{֘!?zs*W[Ulu g^1q'{!E$ydrFn@xiCi%؆XȺe:t+_'`1sv%I jJg[ݾ;-%! x;cdv{@\P/ܲOo[ݯ+-aw=lЕ^,2w^oO3/5黍z*ܓehP_,x[hPIN '̆w6)ߜi6@ˆ7k]ݾL؊o_pyŲ7s(5Pݻ=۷PHM:kݵ%aXX,\ū~f^~(fM*:1s1P_g[} 4D󡏐 j@GtnQ\OH4-{xmg%Ot t9H J*!_}*[+<F_iL|#Ԝ08 VO092u,gFKb( ۛ=\1rZvmn9Bo<&T[{D);4JrcCy.R>2VZFo z4wSZ4='?aiT_Ӣ04 ?3F4!8?UU,/lFOn.Vy8PPB+0U(2lyghD~a\tnͻM ; xӟ"3j~ Հp rԣYyzȧQI3 1-}{;;*KJ ʄMղHEԻ,!' $85A|JOb4+}1읿8 ;})\bz,M>h:%y!}mĎ{46Q_ooѨ{ WAМBmc|\*Gv;ϬЦ 1[QcS':@_ G;hYF*DP%̩϶aIXhI]%BX!w4a?>8ND5ۑH]D P>2"!`y:Y H#>gh3뤐Xzf\pի}R0#&@ x_(rU- L@I+B(lMHIUʼE߭c.S` KbWWj?j|FdfJUc>Qd!8PNMMO_^l=WY16ڐ<3CRziRK݋hmVg27V,'~,Tm$Di**/~ K_z Y 18@!Q걿DžT0&, aiz;m{M{שּׁB|ώlnZ]CV%]גؗ"Pʳȷo䕋ٵUHvc*;gQ9çiE$tb7}QeGp(+#7L.Wu<)]ChZP%pA3g̨?Ǜzp"T%7)ɐl 쓌o_oxS^vv"G񄇛4({mx"_4)_$6iQd?(Y0C?K3bc4OIVS[ ؈=orq2m ^V Ph#l^qk 2pzזFr{ҿUBQ Q 26*{ MD!= 0F Hu@漨@fcg0$ I } O!!!hDOǣوGcmEzH&$FQ]Ѩ}Qje:1ţQxq!bSD*:uAT2OQT$],* X?d6,A2HT*> |;CR-:'$Ս.jI9!4(;ѡP(5?(]GcΆ:W-T 2:V/"(Hm,,՝FXa.pkfD.}͈i5PU⡪R+Tf#TfBUm4PU0jPUO UPU 0BUCZCUDuEr0URta"ƹQh)J2(U$34+qA,nRu;ET(U*/jYg*JCdly!qBmr pmFږJX9V֬1JGqĆ@j^CT5-a(R+/S>p`Ri.y_TDQgy𳼍r3}ҭ!Qa{AlS8)U7wҙ/|)9o/vڅÎذpۧD=d>(%2Lg[ sxj ls+64 ({tHbh8z鎿By?dZ%vڋ!Y6g@R`n9mx!ұHfyjj9RqWU 7 @~b{IĻCo 2l\Ts(eӑ&~q ItUVd,#`PPx$xad7:DT<500x I$&1ͮ#xT4&!f1sF q|V]]]}UЧj9{ͱī՛Mqܞ82+>0vJM#Ҿ3_ >%CF.zyޘ*~U>6r+!îkX-3m-Z^4}30-Xɀ74;([/ Z2&ShV"d,eH"<%[3XGo’ [_w]/+]so3يx;L=O-T4߸v{ѿ).E#_o: ]K MzjxĮJC@lݴJSoaTOiv麃WPW4[)תS[uT~nV_V)̒Gۖ4Ҟ%)C&SN#U}MꊿϤ&KbHuy{ҵVOטa0Hu|; - qPz~?)D :Hq)*] 2A)L!qk޲s!5\ :MT>N JKIoXuLn e{h8Q J"'^PͱyZp4bDfT"#RbK#f|KJ}a:=^##i4,%gLvKHn:Ut QFi-5un(]tfL,uۊvs &fS &f8o)Gr,*ЛP7NpJm - %`#P4mej:ɻS"^.;/qP"_ɮnzfNxj{;v路T?,ĖKo+.Tں h1K= ">ˬ6mCC^U>Ty-8UF0_އwm_DrYQnJt, şA5Vi4\x-بoc9ʋ{}~g9%Q%^GPGI9u6{tqEMb_j_ǓǷrB8j2>'HkKes3Loޔ%bfy|qG&Pɏ/#銛Rgr YY,Dg79t ɾb<dj6z7JQ.vێ!i0 /ӟn*ю@9p;VKp ! *xB2O_{Lci5?~)KV`am %Rzb\ v;S}."eS _CsWv_㾅KiB쥼%B/\V!vVu}T6s^AaAK8_ݨrSIwz)2du7)Rь%/z `G BMQ0R8}JYc&N%d(lrI'F `j@elltz<#_V`0ۗqSLca7yMJ~Ȧ%\~H]xcnT}M$GWӗZW}#g^Jhb~M }u1U`X rwZܽ%@G3u(%EoznBn Vכ+'C:5 mƀm9a8\cI3Ns3O\V Y"-&iN%xCZިܨbxB0J!Rh_L^.J0Khv^ 4k_ 'bo1.(D)%:W%aVBS.nۦEBɦƄdSq_Tbm1mW9VHA4w(zc-*]tNgRbRΛP'#D(}`bوE' aajxz>QqB!t!H pa[IBtܣ0;j0ߨ}V%oIP;$Q-\u_e%MyF~THWBw,7DR)yncQ1Tih z_NS搚%`riFnf&&߸*\ؖP/FQwJ u9P釀㧠) S*AC̨%t%m ໍcLV/rja-Y_Gz xrSyɦj}h!UQN\19B{0;bG$5A«5#/}1N\d-P "*Zi)޶CJ-N`b{J&w SI\Nt)b_ԂMx8MqXlkY/zJ+ P>P\ߓ4Ra~h+AB[EtJfRWJ;nBier<-fIC׎e6v1 'Mv ^ G؛(xy'^rΩzR[fŖkܤUKxR!L1q1jXt:~8Q9shEn:ӑX\j1N ]72SKZ_t.@p-30-?=L  dGXdՒJ~RUt*k#H2trVPníu<2遡BKG*5Wl Ɓl.+x`T24J\9<뇻82|OH)KCCf񎰤=D;NI/nqEZ4T*N2g9(UAJTkhNyO$3f*mwq> $!> .#wψp luET˭@{V|lݨ@-Bc𡸾؞sM:]a}޽ը{Qv/U}$.鋋Zqy.Ζ,{jMÎûOP]x|/]=ޠ? D~uzZOc·L`}\p4J{G9QjE ғG9 M5,J|Ini90J2Z"爿6%Hz49u :jsrHo*qBl( fQVzyOF LJ|<0?*wR>`ĒY1 NL "]l7!Q<8ۿ?"Ucab`^ wW^sNvj9#c L1CpAa*w)8ˤj5_Ǵ Wܵ: w'LL q _xb-to$1t/_8V/ד 4I%tSfs1\V@wPN~ it<>B#$jKkPTCyMNqG3`,/0- 7b6$A4MJ|Tű|bڽo!? mL>'2g)޶`R\NF?5揄𜏨(茸yJ+m6AfA J\uBsiDYZ ܜ&qPMb_QPj@[_vm0 [rP>$$b'yy4%JI.%H-%a|Iz,Uq11T>݈at8T.]!ՙ$:U$hÉIQ]ϘzVOpnZlE@_\ND'=gZF qԨb+z FyPN.ʧߡt-NUO>A*lcA[ˡW_{Y#27?C?L'-ɧqh]lKjL]!.t4b& { m&ZE̱kǩ\e|HpkUjTNb7p ;ܸG̸a&K 6L3 C6. cOKϢ?kA;Va`4]n8jAzўeLFF @-TM!fi9Jۡ=;VSVPVIN$*A4ӴU ֏ɯK1c9'mp!,RxVOҡ~ůeu^M~*C }NF;vhWv/ZCX}sОUVs Nq<m::yR SR%aH#a8>#g8}wx]\pm #F;p+-/bx>9eG3|x??x"e8Ό䖥_`8Z^YAxU~\20] oA|q[Ag8>. B[< UN&|urT`f< &Ƀ/N9ܟZB)QMo2!~>zs#1hΖP1vآ%kB2!o⫵A&RQ< F1 yDNԳmbM^xLQB ̨!W)'}3&z;VbEEgN ./^ъ> m:Ӧ EOG:IUH^"JAljR`:w$9{VǞtvjž0ZGCTmp|O^}Kx rg<{(GJyqR ~+eƗ&@FsѼqhׂ~ZY+ڃϗr1>tͨt vqi,T(BixZ]DN*g+tJvG1ʷR;<~N/\T7o}\k9ε#%Uryѽ?@_hgs )vTG9uvT>¨P0s̽>IuJuo{7.+amց.=μ+媿[QR=|sES^^abg[˗ !4lKF%T;1Nq!$4A-tHW1tX:'| W9Lq෡N@#M)k0{衄r:zE=uwH<dLfO|LpBB y8(Y2X,\y I^|l˞Wf1x$bkwrw _9>7`{΃p%G l'd?A4 xYQj[uN|G ԯy myj{ˠ.NCs}9[uB|NA|J#ǥB<<-qu:b(=<+a:=Q`q^( {]+;]b蠳KEjaSlWz>ņ>x0*1$}djl20F^ik{ 4^፝PcU/c1<JYd.cpOhmo5_TIu ?bl2u10.Z܃?w^f;L?kEi؎zTch@5^D DL(G3"t'jH .l Nb+H]ĬlJ7xi;Bb 7)U 3s<7y&D}QGV: ʍܼO«qrXQXrMRM\^ ILw7c+6|l%uJ36lD7B[.S~^km~7w('zqDKqx`OFPtaprd[O+ۼ-@;.AoQI6ô+&i`B_ ɪjyU,"!QHJӎґ4s@}qZ(\*XW:<F0ԯUxdxScV,K|%,Ju o\[X,aFw|~-L[F/QpF=  ~~ҵWhlͶjl6l!~8PT8R5# -X$+yJw #}E Й"*PG+屭[;Ab7܂Ptcl~'NŊ~vI/,敮ZSW~߆q~fz֊}f!zJy*A .X :2ĉMh,x)ÔdK S>wKqD9r_Ʒ;|[_09ætYtY5ulg5T7XLInﶺ}sٴ!}jQ2mNsdAE;ϪHƵz_ߡ]3WV.xVO׿^[ YdN_4N0+xEs9,⊠{A?zuwz 5:Eש"vgWWߩ"ANEз")w΁J"h>"L 7E3A/ۦ\G4ecHUAHIEЛ(,HPrwkA9O߭7:ݕ"Z(v߭.CDLUd kEvr캊~sEMn4Fߥ =o! A>bh$&D_O1zb2$R#Na-u"!!r 'PL7tǺ7⪡r7q=jn\57W :Q 洢t7:'W4=z ܊L`jwNwsTCӎSUL+~U5t/\5j/TTCVUCW_O54+ @нDgsw7ߧj1s!G\,XԡH$}&X z:`ԃA\ʡF:Uʘ:o12p?~^n59{|sMY`#BE~f/u=rЊFT)}D/x]H`0]U|8:8{A+\'|@3MǮظ[vнsh"6po&ˀ~BDQk%QsO-B4!Ğ1_9}G)p'^ZӐ%|aM]^G/5*W|fGs&T _n"N-2fw[vvݨ3Jhe_ Eucu͟ߣ Y+3>&6y7 i@-ͺMLAso@cֵeks](:s~؍wƨ.+Psya 3VLQ+E0VD,)+;H K}h\?z%^Y! A^wնT'~m靨K*7}`b*0&JW?Q$PӗJ<^~(]62C}]>ȵ͛;֊IB7׍/Z4 &-T[Jb 'QPpp(qzd1%8ݠ/K)ӿ7oBC6c=>g;U 1DOߤoLҧdv7oUb:?呔r)Y.cWIJ}T/y@i"vRU/TP}*m;kyͨo-%6ݧs]rS ? i`"*O@UY<#dzVo YbF4n*$ŨY%ĎL\4,w1:\RRӢ?+|y*IBEgs%>T癤~oPuBɸޫ4ˀ^Wьq? \GlˏO4#ݧ w\*idgJÜl\569 tYC0OǙUhC!Hމ||Ԗ-zMxI:+kb_$o2O/z?mb@&Ǩ0T"ZTyw`2~+fADW 쟈F *REςTRG \ 5w Dܙ[Vggv!'wgrB/XJ"%KpkW-KgxVwe-Kl)o)GE̴Sj _f Dm*TxK߬e\9vpOP-s-8 f3/E2l'>gϗ,?:[NYɈ1dI:/*蛯`cE΀z' a #Vpgl,1X)=vw{hrйU `^th2˵7+PEӡ81P>G]a(F]rPe8 f%¤0p+XXQ^va,,Y\&a09n(:?QQtt;d)BE Jy@"R|x q늿$'>u7@&Ԫ [[śT)c ZT&>0m j^鑨U@% ~o^29"AA&m\;jn{T4iΦ}Uj(wV%9(M^KvL 8qRCVf( U'? D^-Own3G&z9 h|}MPM Q="Njl(!Lg8~ԟ>m>H*-r081 fdek%.PɔvݥUec雂-C .q&v^A?zrTT]ȁ,f]˭ ʐҐ[ь_|у'4C/=\"K. $! wk;`lpH4:iI'}(|AstD{_ΜYN4TS{u-maV$izJ-k9Cj-_LQI mqŊxژ;֯&XA!uMD pS4AP~| \pCuRRܱ*%"'uVKtb`g11'.+N翲:vP,9䰞9`?c8L0Í8I@X&;R9!͕'wzvJG 6i^Bh̢Xc]!D9Z+HaxسҪ5\VQԝ+um[$\s)m;#"]PүwA 8h /T5O8&!צsg5v*`$mŨJќLXsj-^1du;RݱW\Cz /ߞ0W6*Qyqc|~%ռ̢-NcOwLG)Sv([;EZR>NL:6lm%]HƣXY4nwds^'5g:bX60g ttQ;5aaү)AlSٗY A؍ss7@ff7f7W3M<7Pcf7|3Sͪ<qUnf[|9};KPX@8׋'gn/QZÙZ<ϭF?B&yV.\ ƷrZ* 1W+HOj$!9Ǒ 7 xzo mBBEB\GG&DF.L(R2S|uŇkuO_Q'}in=V?SwmfwsF8@qmZ/Mn7\d^-o[;!]Ef[viGo-v>v=ȣ{=O>3_x|O_y?p7zC>vݚ'O՞>?sϿob?_KO/tsC 4N߾@ֵ [{fw̮,{;:`f|Z3M@>aUf箝'Y9h??j|5M4dWS<p41k5)氹$B̩+rױ<QR/{xyDW\\ Oa1I A^.) oˇPĺLgͶfFÝpl*[&I]Qs<=UL6X\!+ǐI˴'QOv1אki1uys2? 3Rm1:tTvkj!ÞBhĽ!#L/HH,frȟ w9Y9+ 4c׸YE͙Pt-;+P]sbtT:tg"c4&Gʲ: a];nm_aY!-7j0ԵvkmYivi*\%Aa1xWN j)d6 {by`c2Y5ϖf5fVahG}֜505eYmUmXrRi%CAw9rExC4ez5mc]?h-ߺIKp|[*ip[ږm]Kҳ%Q~wp@zDs1l~_/?I7sp-3-4%$`|n"s\~4~owdѓb7+= (?w##wEk__C$?'!cl>)IH#0ݗ֑sCkռ쿙TGo?/oZX91!u2>\Oɾ?l^z-GXF' M.|H4,ٟAYv/xt :n=\(MNo,ߣ2q\[Կ/O: &C1C2_cڞ!6M/]O%w# kYi&z(ʢۖ|auTBy= ~h׼M9ԃ|jsǃh o$ (؀r;ҟ ~ &] iѾ&5rSWM$ `J'JW59M5t6Im)`x!oR-`䇱6!V*o-&$﹟Oeڠ1V OХma4ݵ{t ~ICʛUp??VmuB^J%d$H7}雜DF&}53 h[{~/M#l^K T:H_ < .ׄXۇ|NäkxaE!ow_?CnЗO˖P6Hwt^{K=՗R#׃1¸wlFFsf y-?|}\ Cyàa`u`|lKQ{I"W7W +4 _ZFVPGP׽]<8؛CmaiaC l\Ի·i?$s~6ma=kCʻۂS:5?C:=Yn`k:cj_SX۴{4=>v_޻V[ADFkg QE!\7ٿync"UsGؑfVB;d8^~ +@knFcTՄ8FȬ۬[:q y,7A;߿޷֧˦MLTi{?}Mggc/w^>!!W>l:6~dcS:Mwt:6U{J_˗dr[d^ LH|Ѵw6rWl }Sl)I_3Cj7%u!o5 ^{A;8jrmUy];GSxujP>飉Ԩoe5@d@zQ72m|Kd@2TJ_!C&C5?P,2h ږ#$nL vy[bnvs+h܏qjfXx6Lz!γ^Rl*l/+gE] >svm k !=1//kE!9-IN3n!ͯ0M,P|nu6&;ӳFyNKɹ ҭv /˟U<1]΃8'R+!H1b1vrKsTӬ%XƎJV"Hչkh٬i Ifhf($n962O,4&i=km {F\6!ߓjgyP"\R'k56VV;]zIFϴs2i֥YmBگ }t4癬+VXIvkP\1{A]tfY\vUtG. %>&:]uH 8=9P lIgʉu@p-)7 F3n)e۷gf ;Q~G ,^bst˷s^vȯPZ ܿǯ?SاΏ|8K g2*;WPۛ'xϮ[/x>}}q77<,B=79C~79x~ y󴳹j'ˇgh<>s[{!w/:<87? O9n$w0Z41wC{[~]b]:DR%w>yzIdZ%kKkwxty;9Trގ7)?p]ڿn/x1cQZyFfyyK*R3Q" Ƒ" %7kHz ~vՃ BA{S{8 &67!,o `M~ $o8nJ\?x X;A\e'C]pG3|?BA3}x?ndW*޷74|9Uy#XDC ?#gA!{~IH&76|SA ?qee 5 $UѬe$UA.WCc o`g Lx5಩P3r+!U_.ZpM+K98!.!p9`|u _X N*$m,~_d?@lF[s?o?҂ )yoB^0Ep;?K p=|6/hXg aaRB7 sC ݌>"˻mo;~_҄:,qg '8~aS@xi7J`YP,Kd#s'#5N | x@^V{*{y_מ_:OxU }aq0u?J!">zxpg ߀HqfpF|G`Чpx+*U}8qs|#>$qC'md"N1SW~&u Gx86|x7`mMsdu pW`PW'~m2k?2%2'BM d@S\yp2A] 0:/1ى|q3~<C?rDț@A/q|/@fH ,hfOwr5sna@B<ma&r?89{# p<;?pzGx8#`W,np 8W8$wcw=p`n6χS=OpFP<}E𔏓0wޔ:sNέjua 绰߅}uu]˝:l 랂~19Y y^f.?6W}H#0}m4Tj.jnA|q47Я5̘1,\dee**?]v{8p?dO=MޚZ5R.^vƍRsR U`ց"ڵhOP3࿋ vcV*y)] ȸ[ͩSU|gU4CWg S̢gfH_QS55]=u<Н5Wk04]bW!~0{y,5H]K=.xl؁]}1158̠?Pd=kɧkZ/O)/iJ?зawB)1 9t9iޘ3m?L(R+>M>aMswk|> Pσ8GGGD2o!#}O?ECC7 ill$͔W1Ƈ$Bite Cc ؠt'S1d2W"k_Yڟ?GB)o+ :%l! |9?p ?A;  _ i_? "or ?z(!IF 7vo 9i0Qn Q>C+Gƿ-|ǵH?'Bx\ӀoA?C $h66|!@~Н(S!?_] |M?jhKr?-~ÏgY W1z{8_W8$?> ߄[0|g ?W1?/٬je2Ìfgsƍ|}ts^5Y""f`0-6mܨ[rs_l7 ݺyk-p7 aFk иv="2h1&^ZX"i)Vx7xb0X |vC+6YOթSO.plHF8Ƿ>:uzt7|o2ZA 1[ ^Kyԭ~Ò둢%n n X"#Jכ6E-ȮO{>݀ZTMb 5k0n'o9YnD$u(P]֩Sop^Ow*PnUVPp9KѠNF3kU 4X#οlajf xĭF/xa6:[;Wͭvw(FZ Hw; lSrDESr۶&VkwU&+F0ߝj-;?Qj( u,5{[Mάk_mkw42#t1Y\;1u(yY̊ޮe̚c'ˊdtL7V'y'RJ/5KQ .\y'n㽤eVlhIY?-\]t(\äDQs$>.\PYtl2%##CYb֭['?P Sr˹B~~_왓ʙ3gg*/^T~GϗEnp Ν;J/}t~6]tlqȁnUJmZJ_*PFSFǕ5t<>O`;÷gP0@3~ïen3O3O0{zzXOӣq@@Os/5f=׸qk5{=}6mv W6 hP#6P'/~Ok_x{5Vq?iOxzmXj5WxZ<yԳyǪ^OVu֠z7Ju챆5WgiT|A9_M7ey}}_qLg(q݃`?,n.Vɟ } >W7ſnݺmfϞ=g-΁#lmX Em@8Bn|Ȑ Ooqm͛aHPPP1:ꫯh֭2'Ι .:p/((r4@`'pQQ"Dm?' 'Q<~ݸym=1}F>%!h9 z ϐ'Dg#Q~{:|IԦi'j44CDo㩊ϾفR?/ϟ vtX zi?Lt6ѐ}D۝ /@iƗuah`9=k6Poƿ1D!k'MBF۴0+? ]e"|,W Ilz]#D * ]uJ!m."?ƍc9[J^~8}:6 %`™KT3%e믿Ǚ4.(M&q-ڷed% pT@bD}GQ$hFg֙`iϟ dj-6N,g9m۶/zJzJ=:zzoB0eB&^>'z2Nݿ3h||ͪo64}}}1q"HYp.i(dL&t!Ӱi@f"ПiϠA3|RϘ5 -lbKßTC9I4 [~rT#֙LCXD/_d?3|]{ ҞAg$b_\!pAvW:JI ڦ)iNjgz?i߅n\@Si2 3 :{hl,T}RWj|>)pk~Ivr2/ y$-VexÔ1#aLöţ*l~`:X&AҞ񇿐ߩS&W ܀M*6ӂh Ӱ!NL՞>)-HsGѬXMj)4g:qxAcrg/I Ga[>^#FdzB#a3Ӱ~2{ 6 A09ib4N'?|bիWn'EeRܹsM;wmSuL='e ecBhQćҼF44Lc&3 h9? K?uA? 믓TI `]3:PӰi4'I{NgJo1 LL?YƘIF]bKܹsf͚hs6޹>kӃhfkuBaFÿXRGivJ18>켈_(l si}G@rrA_ )5Vip~3ǀ=ٳK+7}!zE\f4~x' QL'WRLY4;iӦdZiʕHcǎs oA.T- Q`{Vۿz#sӞeXl ۶m8Ŀe˖ ?xGl6ݛ}Yz7i…`4  NH: CB̑?L7iwsj{OZ 9úv6lp _$b C|\!#WRu:r.VDy:v`bskL)))E 6f͚w +-)96|W^m &P:FyF!˻-3f\KKKiӦ0`9RוB@t7J ѰG`#Avz<'$$|~?iICi„ BroG|Glj}KSN=;X,4i$!¨{4k1{#tu 9g_F_~|Ezls 5ƺ҂#_|Ez~.;.Aqe}ecO*1t~:#=ƍiɒ%B n7 Y?`^ʕܝ>6===].ڀ/t H9?] ۗ3f%"n+#C3`IBLk4Q0 g8`qA{&ZkCj-#z?~n:'$}D~>j5Pc>9?}Ե\rDxu? 48@\ѠLhR:)zQz<07G4۰7pϚ߈0.]6WL81~ʔ)W} 5ek>ԙ }D Z}i /+pnu~Zk 9 ]aO{R/ jƥ?ypW1W7>v͞=;wމ-btnzUr@}”hzڭ^a[j<>uv |xqVQ'tBg3dS4Є>/r?KI3!r~}E_U3*V7qHj̙F6|xu|nxGmΫwm4}Z9IgΜ>̛7O=]>]OgХ3&\qY++o~s`OICWc0}ǯ$珊:m0ľ+jӱop@JVtA[ųRm'ųljBBBڄNɣ^yiĈb855U]ȵx#/m?\c2nl9{DG]%γh]e#|s9Z"#""+p=z;H{R8N9rPDΑnﵦ )j<أ@}㲳^K=ψ#ǪߘXy}~IQq%1r;{A쥣 ~>xرcRsFgddD57 JԫW/!%]6CQ iL>}8Þ|j /1.p/x x/ix>vﺇߓ@<3f xVU+B^5O.,,\us1KCk֬e˖bF9ɚ-<2B@a{. cq`iӦM9IE@g \%lE?yІߚ?`}˿n{N-~NQWweЫk˗l7GrZq8yQYYY{̈B2AlӇܹxSaXC_sx 19(Kψ6Ix F'iSe5ִD~ c.ؚ\sKx?77}m+(mNX?b*VZx֊59pc#Ds`Kc`-~XaN0ȩ70{C.Rt59!gP.-{k"zl1^un0T~mL"֓ݑc݀nbgOf,]TxFu5⚋ݙ+Ƀ97q\~ 59>߾Ȟn_mϵo {GvQpx; Ge0G#ɑXHwv:6;#S"GCɮ={sl9rsV0-}ܔ|H%Rllmlն\f[ٮ؊3=23232 >9,3!3)3%,gkPKgPR(g?distlib/util.py}}6l9RL;[M]wkb.KK͚"K_?x$ӯu$ `0 c_ߴA7^zdc{Siuާu|[-iUC, C4;:<;9)>rl^m0٤ٸ|/l@fYWl/Փ掫^եӏ vY<䷟ߋ:/ϪɤBaPoM5ڍ~#7F0mp@O뺪w`3, :rT *;y]MF;91Q <@>6x,bYڧaTkiBQ'iY3.a,ڼuz|S*{p4$$d 4բE]T/?U9|i9`5 fE=W?۳EV&۫ʫzQmO"Vfe ʷi^b Uu>AϿW L =Er`cY8/YEIR,I&LPykxbc8sq|PvóoOpb.DuC4>?.^Λ`Ӄde/J{Gߜ'GnG_?~㓋w'ZXmkkU{޼KŰ/o0!޾](:?;wdboݿ ?~?Ͽ8_ 4ʒYZ€? OgϞѿX0H.pu.^MsiH*üCœ@E!+c<φyF-=UU,)ڬeZD/ ^ F:Aà6qFb.ʦP; 8 }2c +B Z(0e:-!aJp} SwyzYd X54Ag1P%tÁ ˡu@b!3*>&fOHjEᢄE Ђ* Q4Mfha |$`xYAyI2Xy S!?yN0{k ӳm{-xDqfQT韏bS2n;yC#nCz@P?t>G>#m3dhth|3$\51bz/EZ_P.Y4Sw+` iX'` H2s>ƺk( ܃2oL vְb%^6ւ_h#J 벤+*ao,[ $㷆~}hzDYGAFjOI5q3=]bL!=U)y+Aކ(>^?{W%4Bۯ4IAE4}Ay,@ 8?NaЀ|Οim"9/s0'4ir^myWCg;ʚ2}tdxkB]^Tbij`dݐ g7(Q7XMm\fmQMk A*+t`:k)##+Qo w`*Wuub ސ2?-#!,Eur1Ɲ -/ jذXV㌖D2 pu`BL" TOęYgO7/˽"Itzie=mZb%= 1 qx5/۹3ϰda5 7E5Q] zBspi볰u+k$I}z>oHq~;wBbEP΢A:lFHM`??2G`4}n# E@qDKLC М;ط:XEFTTӓ)yڂI0񫱣])3MS@jldObioȢqPFh[|ęvuita\iؖ>Qh@иJ~M(mLe`\*R9"}Gyk(%Ƴ Au!I)!Y7Y]g 1U5 aMo"=HuԐEf]Ɓ e[?C;i1<2𧬍+v:*I֧~kVll$h%BS]F KPʻH,P&m5RCS.E .@6ػB#}7I!Añ5tV IC6YܤP$9O޽pv$I`)'ksGs,,?!m&aٴˠH4fY)d]qT(zmX]NS\"42$CUI@{?txdf98Fq9p٘Gf}c"orX@q"BA[IBi5C'05$rRU h0\~|7dHh-ef]ϼL9EkY*4XàKCq2vשV5A$Ptҙ&mrf= $D b!3P)X7 -P(.O} cxBxJ_|@h*P;09Kg]W:qU(Ъ=EL#Rx~&-ѽju{@6 `UmQ¥ߧG 8trbȮ#RLB|@-G"X16!(w*?? _cbPqJRËq8'|,ȉOWCY"qHCc9$qf&b0N*WaE5=.#! =YB?NCȍojrVD]_@ na3|V~M`XRU!U@u$h53ʮ%_U ~Ll݅ZOR,$yH|->` 2M ^*bP0 cj,Cwz50L,R2IW$Qb `Po4kU-oi8Yq崅1owJ-W cjGb]b#PQ3TNNv@ѭii)b56%敕\us X7CUGWEzQc$7>ZUkY207rbNdm|BYZ`H'≬i^KS|J+NO=Y1 x`IYN+ S~8*|!/e)?F8[,|Z.CbhU9mF>„RP}eylE/{5)@)*skQu+9.iI= EmBt2TDˏj!&ɬ. kZM! Y:Tv5$!I"\ 1 !lm^lF]P00$XCԲ*K8&x )In\ V.%?tG9PEB(߄QDpPUM4Z耹سDPۭ#X9hx[Qk >\PT<,jtYRN֪ܭBMҊ ]ͤA5Ae,`}(A7#t b ]E5I e Gg=O#x x -I|4  n=ifH!<<mM)2Dqx=A[~L~$J\ݠ{|/EV PVe׶5u2zF\BvPlbf` S\z -" T4`/l Z.큢Q+N*T|3fo lZ6!U a~A;geDJ<zQMA'ex>3_u)ɖV%7.bXn_PBZ,p$yio($PJZ 3CI2X:wXfj{UCe~'.O\lQ5S,as4'k4rv_jkb`s `6 P@ر '\*VC:SJсLpeU1>h?c@?E,cXRG0-m׏[(`ѝƍ41.)QG dO F#9 l9Ű8;\bYD=]˛"/o=Q/9G̰SZ! ܓ74OU:^iMه 6uʎ_!.ȓPB1t!( HBBw@_>T9[K4Ԙ:+'& M !2J珳la&_5`3D*5<~OAl@Fcm=Sd143LRzHnX[}Z<}:RXc_$"]Naقwv>lTA6FұdҊRس n1*:+ְ1CbW'4OEo{b'QZҘ fkgQ3a]0Z >F` ethJ^j1 7-LjQ(hEH>vBM8#ƃz9ϫ4/-ԥ-P>2&ؕ =( Dx5j.&q=g]"ji@fY` 8Pd$@vxpdG !Łb3 KcyWr),nզ$ }8Hrވ,<]/a#+^譑mv0$e) [.v q'u6Ei5EK%3 snGx>`䁻HhTb3UO\P4^1 L"+jI[J]W7IМL '0N'9q-a/_[ˋ˾͋U&Pƈ^y|^,Em} |?|Pu/~~Ie/l[8 71nv/@!-:tsreFy*9)q T;!'co-BࣞLE knhdT$;;W}[~TɕV\AU(i^ֻ=8:ZVwtU+P_}zAa8pD,Sz'^ұ;oJKD9G#=>&8s aSC<Лp8Јpf*0r4!>>VD^q cH( @2[^N{0Kػ7 "dw>L! oŌ#,@6lrIyG)$IĎNε+K:lJ]K["TOv>4xGIDEZíD針6Bm2 s E_V)̂VqC~ ;To;-o::CЬgt$]Z7Q'~+NC k{|`Չ!_Պ uO  )t!K)~P)d/OK0$)X"1 `YhhVyIz 5Q/~D7oD4BEI.6Ӿ&ɝ@Ko3t Ψ&G|x( s:䀡SFjS{ȥ8Bf*!(P x[ eʼnMVbuQ 檲pfVRe+^hr(-+``Op36=f GPN~QiD"3/V( yu GOhg9ByALX\3u_ȐMƄa%;Uy&Àe鐹Pr)x E_gy (\>b/۞ [i07`HnbN(옲 W$ ?G}kU}drߖGqu;Yv#͵:%Ym U͉˜"H gK5'kGJJiڡb,Y`[;(s`΋-;$lQKPVjRIwRYfA$E]P^pOľo@ī@qiF'ȌriE ^J^Q,,-fc%hX`FW KWƐ,$TAh&EHO>86!!3҂6 iA&5ֹ-'&KL1ݸspivE0c5!/ۭ3Bͽv5>cloc$] U(v3uR8H&2QDR؀i"pI*d=FIjt٢ #fh$:-WI4>H 0ȼ6?O8fw{0ݚTG`{8Ϸր)[YѤ ϛmO dL궘y}"(2zp 38BfJ_Ko=oVt;{DGa{Ìt%.@@ϿXʒьy R@$%`VEũ! JHR1|pZڗFEYO9Po"&w"tbMyJ>ƜPYtAmXe kP+u b`"Rl''nvƏu}L!)ѝf _uTwzwRgT#u~ qAѓoų ;In݆[cɎ}]1UKPKaI|ih*XRڛ;9[ Pk',@Uck{ҍjGd2G ÏqoC0!TE"FX+Ea֘ЯGLSt0_\¸l7KLds){-!8DկUUemwE«9=g.+DfWWZal+h)j݂{ aC #h 4{7 ''yN[a)-&yN' +,i R)y X'ɘP^WԜqb|HJ7Z焉WdWQW=lé'~YW ,!<4,Q;%0e1RzIzM}/3-tEuidApp6ҕT:%UpO40T &qxDN1} p}Ro{1A& W6c,-sSbc38eFl]cBA:9:SஜE fJ#}z9"P<πld !.y@vAL9N64S,pZkPHkBwo8$8T,|\&;2QI56*gqɄ#iS"p;0 Ʒmlӣ#>L<:d>[,RFXfS`j݃wH%Zj"=*ړQuP` s4D׉eeeUy"ֲA.nmo@EjD}Qw^JA˰gPd8s.W7*ǝB1`<; b$lJHR2TePޖ})ucThie>i2OJ,&T>,14qM>g[Z|7BuM TxI^Yܒz^Tt#OîzGO}IV fVqS$+=Չ*-^A$r K),.WX/W$dܲ$v^VNڰN5CWŏGɴ<PKo3'FrN<6m] п0X&nnoC7|M4m}?p8UUK9TYP%|fEb\P#[[5n V<+ 0j|!:OÃgdiw'<#[aKu&z Χo?\|kFzW^j:\.mIn<[V7E/[71[Cw8e$A\D>8v{Owf$ґ]!몼N1j :`In Vz/Q7V" wMwʙ]ϯ>; -+Zծt ͋!{ff w8aŠTS&CŹ"K>Ta$mZP0_-) FX\aDأ n:hd7˗!-cfT?{7 <J@NƝ}`)Na,8xe}QzP N>iE 1'JZ7%<WY˯Nt=">-n.I}( ;2cٮNNo.,#&pyw=EPq\5*XG;5gqB,* i>~wxð7tF|G;,qw=HPO  tx&0ŃB)48feE:oݎb 7v;ͮgD?2N.u[!eFDatޛ"@[hZ¦ ڦI9)Z2]:Sr/v9Uak _p'>8\F[[gN!׺Jl1ɰmgaE,ԱJO oJD~j5B\0ykW7KNwP wA7[j @QWO-r UXwJxIơ0ʟ&"g'Mn}]#&ѶkJ?iVڥѶK i+>?\ӅU2ٛJ% w R bu\4O/ {tqҠk VDj.ftىo=_k4~v|jڕZ(j;@%NY OӚjmeε>z:uDvԔ9yZIrs2Q:Em~:Ί ǚRE$Eu<9{_]{2'HU}~>_?3ht̮_.^/T*p'^:BJǗWT&$!y>-Ry(3=m/n B"x^BOУg/^< fMJ F6߅p   )-|:z=\bTp>ICVvcgČeWC]UCֲ0%i/W=a~APC8*/};A).qDCN{Fm4g݆u4HIȳ$p xBWP = '.l]Q| N<^U\2"<眝"Ojvέa7 }af*76p}mDQ%9DoΎOz|6 -}>MՐsI=ǜ`\ܞ \e5lIW٦ᴚW> P:E~[5LdqyRe\K"e ;yݕȞZFJ}*")yeSz)M/aW Yr{0U%4E ? 8Ac%3 wEm ͤ0iY`m+T3/ EVdpʻEwn%| u༑:g;J#K7ErJppS/ãu:Ox"G mW7~ϴehԷ e&b{|rtvw.a{C12br1W2vlyt)m11b\QVs-f?[cUM*wco۩ LGytBIh"ˆ^T oNÃ%b$8P]());NK(H_<._!~̅5R5IOokTdFY@)KzҠhΧ}`ovGh0ȠqtD9n^ȁ˹}?6!ӢsǾW3d& )F f䚘$D917F>-ʭlK|O (B>e%E])%觤Gxva`(b#25۳dt G@0脉ECD'/Jɤ*LME~:%Fh⢰jTFlPշ /o`)XK[(.y1%P4&Z[tAm=ZɅhZ+.RfdfȂG(w R) dQ[v;^ur'rH9L>Tb)*QV/ȑao rmg6_Ehm7dj fY Fvm|{^Y8פ1EU@(*?G#?8G91|=̊z>Ag Vū(u_FzM[m蠵` \tS7FZ7 >/V,E&2esI~ -%Q4]YTܬ\:mxp!K졙wvZ :˞HWmR:_TRϗ ̶ÙLg=4T^,qH𲶋EzD;밺1BdXoݑӫ^+݋=ɭ?kM+.TcT7=ڋ:.\߸$ST꺵7[<㳆!&L΋cmDK800oBx&2)믠[,l'!N֘-Mh) BJXųkHCkXm; Gݹ2kSL>_07iDY4MvC2?V!ỏ;҂UdQnԴ'{G'gRC3_|a{Ug_f2 :yz:0K^YKtt s{ uU)z4J|i-Ȼze8>}Nr(Yi)RMӬg-%'3 e_(I_2pjϨu*nHW (ԛXab]xyMPp{{69M,ROd@=F7cɽҀs]4-pG4ȩNe=qшLQbFC5.ƠK~ j+7 IB7}MIeBJCLd}nP -Q٣OЦ\ЦĂ,_^-*(/+niXtv?{L^:Jr wm5XdvH/Ȇ+/B%Uޓ9T6H.#{e)DWťVuɵ*/Rd2v!5& LEt%/9w:+#Lokupx M> J&z3x-APtO"H,'CZ*A_un*JB:Ow<0!є!Iվv^;Ç/y|FX>'2Hh5ŢZbďq݁L/ۺJK&M%ź?m 1KOPWN" v>f3ЯZ2tmϳyvj|Eia64,n+/^"otPKgPh(,N_[distlib/version.py,q:ɲ$Î ^LݭILCRʅo̞NcoɧSl T/ZqztF,U3lUuS "a%P;B Maөhe,qba9kj;F֫TJkkU[@Úyܦ]LFǢ^~DYmyaiR{{P ưoՌc9)aZ9PR+hs+(MBڇiqҺ ujMǏ¼@Cv#  9.f\Чl%h8$)$ <k1>f#0I]ڥ}y;/aK DH.]:ZEBgE%]b!N]_8`K Њ yBTHf A7tE[ 2@ߴ(!UHvoZ{7ģ WD-'ϸWWҨp"5';]X7z~r4fmd '!¦@\Pq- Wʟ-r%ϺÈ7,=`C2JU" Zzs!F#"_ҿWK_}.\֜^W"\CH%at5z ּ9\ R63dms*PW\y ʬy2GeX"XۥxLˮ(uv1 ش#^g-vd!-64b*j9a0Dg^wHSY:O|jZ> KGʁƷpOVB_j~簃>xOsvrvtԟpw'hrk28x҅Ƕ٭;;m̂v*]=A8^^DG{s^&:<`5l%JTpM[mSkVH6 r%YQb2^;(DK6nFaִ%7tC ƽ7WB_B#Ӕ'U{&`'*1:UȖ]V Q£BH"TG/&uU? Ey`VW5,݈KB_cw1߀h\lVvТTEN\P%d| J5gEvynXG}5n{`C ųWz&G"?Yd^ .Py$ jpv%% heU# aCѮ6oɰ'8BA%4m@̣vFwB$VYFlw#$/Una=Me0c&Kh{g(ԗ ٜSQoTZ]VA |q1PQ8z%WwAI}BA=hn[k*79] =i* y[4@#/.\2Qw#ޚTt-VzG nQB-:Ijnw?Ƽ@kad*o;Vݣn, kOnh<[2jɊ:iU-զGl+o"E `L-Kjr jG땰9:`KD(>,RC}jp yk,#59P_>hk\-+Ӈ{)2ň] o8Q;e$"dN"VUX`U/S}@paJM~1%Vŝ?y$5_>7hkc 1oBz4)}ltՂ6/r*VԾ鲍b^Ef߈yn97,:eQJ0qT nWn=n*fE $oiKzUЙXkUZj]faԼ^U X?Y*UeKJEy^#)i#3>yG\GXPf{ʱ,߯VJTzZ8iC Zqܭ5}7(a+<2: " ^twGg%"TjeW+iwj1:쌸 7 NjiU N'ҫce=}uƜ=F YmҠ'2)YhA_/Ҷ5I&0}Sӟ˯ҧn~KϣF[mPth»+Nu&9 <"%"X1W{f…d= AP0^ܘ!)"Iq6Ю̳3aЦtӅy)8vZj{+׼re|OPݜm\MQ]D c(c;u@k1$ژX#ک$I8q7G]^TUCzx`N%iE b]6^,ٺ*Gϙy0 P9{粯 ǂ2.Bl^.;~cX~v8|,ZҨP/gD:g歊zL֦1?*_r@ƪ:_ 4Y5Hu|rIvXo+g0FrSYvUE8H yXBȁŶ,=%酙SƁԴA)g,DcAYm[$C@e:$wa۪犾)MJ:8tuLjx ZJ(~kt)4ʡKÑ։AZ .a3~`ڃL|?AHVܛ{ރb0Ҙ?oDW] _v80 w{ m/{R8pl.Cs6 Sz0^v|xwd; ?2=6-abϟ3;2}91׏.gt"NAv.$=\v^~$\eSۂ>߅-b*H2Um#!'[Z+[^hྶ-t3da>) kDw0S-Q  1@K?$=P&W^hRmR;|@@b,rw BZLM(rH!QӭhOs3JVfOL#|_-,#ofܶʲ Zao|8V LzLڸɐm`E*hΘR>侬9hC>ƲF)šPo.¢lcvW3PʆA(3r}<냔;)Lo{lpITm!fkyF1}P D1?[*C(!t)i8`v| [ g$UmcӋ(r쩋afn}Pf#58P4;yeOR6}:)=0|c!#U 9ЯSy~}-L A MLR)Qa3|Qe0zFR[V/;%Nh,/QݚZN+Z<Wꤠi.JcVXp00!|^Xqy^L!';`i^w:ʉ *+Ah8 J+Mn7*tw\^z??)Ryet8hUBC. &Pȏ#&oJFB5Rdt xLr8"HR X[tQJuTP[u O}V9}ίb´~~CvqXr4eoZZz2Ktj,;:& s- >[v5}CBDl$v_JOB-?}.?x@ǁ~Cykg}{4grC`ܑ9(o\g]v@[Mo~yW p}Z et7ֶh?;2q%w5mN$h,a)؄ n]5`'Uǖ0"UF㉴wGGP"W;c B][:V_/`aͤPKgP7`distlib/w32.exe}xE8󑤓L$# jt$A  ̐ qt]6t;iQw/zz,]| 0I5 YAnVk@BwNu$}yyyHwWթSUN:TMdL ØOU s0>˞l7>hX+}n4?e}~@֭!++@Gş3?=σ >?ߥ7{~9=O0}>we]NYjHa6]nh4d0̫xV+VԩFIa 4=f($;) &ggy D}L}7~Oza zopP 6h8?\膆 ߇oVh3#߀a?@&JeooɿUrǷ3.t0r.~b&&*HU[K'f2Y}bV3jVj#_Ge, M7ͽfavŌ59,60/贺T OCwb]de`*d am9YUaM$RGPv}!XN~WSz|", :#EARA@s(KۄS6PaP֬۴z>57r0~g<ʥ殤<0 Xr ȧ/6hC= OCK7McRKAb9^T^0U]t .xmqj<2qkuH5h jc(4'@Nj _^y^2JF/#;?vA:l5l^l+-Gw=Zbx?&Z>D yTuAY9溼^`7WRjn٣BFbؕ˃; mrׇ;Qt3|Ay/"Z1F./(pPs ‼=Uե" z\zCUuǡC7ɥ*rO";,RS]4C'YYHL@( nKy1jupzVF'qR1DTX_*|'$ `mz)RF3`J͟pi"^3k hk0jxjmF1b 97Čz3b6]5kG1+o&"3 ZTvZ"fs`Q9:V5C7׋ ff)5]d9ч6S 8,!&,9>P<+; 0JV4o?D(?[GnxKڴa AtQq5A oػ6t14]P96hAmo0Ֆ/v *l!y3sԺEL55}/y_I^Z`KӅOi7Uy7:+?!4ijGB\ےREh}Y_. X'>־12@wnKT!@mG0ЋREΥ LprBߺ&X"Y`!#Agˇ!㯦 a:QQI:_g)D@&"TX "r#|mJAm *3OF liv5ŀR@^/(lu~Y0 W7jh*g:xzBl3KCoIb7*qP`T q&h Rt%hVAݐvx[4* :F\?WI) l>w8d-6Z.,d)#o@-%v>!".5jJ]f5AV0LIw,Rol QR(Jj )%.>vJ.UT~u {q2cV>:wRݣ@c|hhekո܍̢)γ)Fmk DE{ZOdcNĢFg1'z!e(5>5E^|ɨ񚒞!ӧ jʟZ`ا`!~\Fa@+qQ%*ϵUXkUUKrOZfY-~! B3R =eK:$N!S2%ހx;`rĪ F(Ġd,`v1fF#@5oʵ@ϓI$@"@%/WFX\!wl6i5FTKZo#a NsSqj 3ss[aqxφKkt$D>t-[ڌ "*`Rg*ߗ- p>.<-ʾEТNk- ANb:°2h5In7K!D2dEy6Hf9be-(pRWR|Lʧ"Jx&45/T?7#!6r|?[,nvf]Oܑ!5 +|&sx<+k_VӇʔى!|&3loQGF.TQsGw˷~R8fO |5m#ky>VP"a>T g<(5a| <(7_XO+ŨٝlCx9]+jOiTpy!_/Qͩ$O-(vU`T,o"uͿvỤ8Jv33V ic[vr91nl%XΖayF~j9Y"O QQ!Xr ,R:1#Y˱^uC<:-ǹ)!~AOu5 ιIFn F[{H]SfqHdZS )WԱ?CrF㩴ɢ?& ǍV T; jؘ9\EMqy*D0YQbUgΦ!`K5pl1gb.yVȓJZُ@|9m g)%J!{WTaW «G\ x6a1^!kƾX w ?eTlJÃBV~D *Tٻ69y =!;;HО0r*v]V  =P,r0-ƪz%c@zJ+c_W" S`u9ב?:bej~CɺpzX <\vZqef|]]P-t&G (`qq^~n,lhE>jC8\/0R0w`3;pfnأk303fN)tMahHpaxkJhsxm]RX0$a%~/@C(%CAK֚MZ!"^DB&-4f×&]j-S䜧 '3Ÿln鄽sUkn`(~+ȃ.Lf-'|A'{- Tc^{LqYMGC)PRp3X&XZ>Hg5A)˕ YS޴ C0Na7T&z>`Lr) (f|e `'$WтT3(aJ-;M:ԉ`=#q+ `z6\oMvL'G;FG PvKɁ$滽3~;k=RmߖE׊JK+} rQE:ND7) D꭛v[j|+OݚpXjm{dmjuϖ 0^ZTg2 ]nRrN(fbzMO$NM&S@m.ʷpτDbU7aj~ٴ_+"> 4^ Vd昌~ T9M 2O01>",!bQ f d-|I rW.JK $0T&6=wȵ+O6Q/e#Ns/6f"@WZjGx²G{9*Ty#􎭣d/ap<,U3tmE`SVr蛈:Lp3L Tۄ~po2r98Zb1"w7`q)0{; |*hsɟQa[ȆJGHukTCAvʬ.Uu-'Sqy-?zTDfx5Pxi{|sT|4:+k}MWfu^x"ed'{.}w 1{:.]{.)L73hJGm)Yv,|?.@@hQ .]$i"x qkd o+` ǭ:4)4m7.jv?w 7{bL#_VMHO^]FˈWIم(4qIbfg:|4O3Ÿ4X`0tdBdZ[.B$hYS).@ [KXYL6*h} 3G6@ٛ'o/ar yi(b[> _Y,Ɖb"kP:-U<>wiYFsЖ:|Eݮah(ETAkyEr'yh%3],fl'ݨv/VťU} wE<{"1#)Iiwm 5}Aɲ J+Fu,ĵmewsO+lmI>2WTe"IH\`U88N585wT8hF}{&t:13 5E8#I"YO$ټ I*t), ؛GPlc~&;;}p"fg\ wVtf[bJډ\,5&k~)Y&SVU .>b[(` $!>Z 0J3)9K&[1(3i|]2yؖf T,l<ǔd32T_]ӳCnrR_L,rEbH[XiTJWV_Nun@i;CwA8ЍHFũN |yoI Qz.,V\0.ҥZeg":o܂+54,8@U0yF򚶧lIb$A۠5ժW}/[ȅHT[Jn~'6~b U/ۜZ f~s{.kУoVX Nԃq!D԰y*]^.ajW-%7|MvN-F1*_` _arsKZOT!Sg>:|o5kqIoy'.Y[mNd!+|lzfY@~!{E`3vs&߃,F^qh_\C`#VهM]EA@hc{]hhԨ2|zyӫU.LЯ. \?KU|_&?s*ЧVL 1bNUJV[>(ߴh:"ZZ|@*xD;mZT},$Htc[Y`ΑZZli:iEj&,oċ#6U΄π(cNy9P{EbFypsxBlW=DnN2TۣdJ4/y\WkդƎAe"d]d&Rt::<)c n"]jTҠS2L~)4}:h$A# I9ރw1u@ 7`1 ,h{[C}S5[goLd #m^A'5P)hיsXSg -AB f\] 0Vq>Uwnk7r\o ԸAոRT^>uڅeal.|(uui 㦪[HȋA%4pAC,-S!0EnTy7 ;I՝urV;x98|hl$,T%cUY}Rj+su3eSnBg 9:^]^q3QT)U eW/Fjqh́] Oug,)Մ=IK0Vمm.3 vY*ӳێE68ۋ4)8Mk\grmi▵=rpAYD,rM>5$:c7bGq=t+! o[t?v Չ@P@_ Ȕ!M#/zB9NaNJe# JWM`GTꉏP/N2** tuێa:6]H3t% qPZ}-4O jrh?jr-BG U݄`뭋zo|GM8 bYAּ7Fz^zGmCY^:KTNڝ ox+#7W%RUdg}/^o ѾUXfCt2ﮍxbt}O{cq}U4Ю4@X\b7Ybq+FpdQp4DS0㫷ܱ[B8 w#k 3y\i%"n? .rTոM642ȋЕߗK}4jĨ.O󯾛]S_xn sn%hnބ>i~{:r+b {UD {ƪ a#=ѓEK;O Y!v7U+8>V.{=껻ie,xмH`3/K d?o5Y:y/a@|hSlyTB#*ꞃ}0>ɺʈsj*ɱ)ң :ᓵue?}Y߀+)P Mt5 I}=*yT>zYR1Zhj,q{?NYə"7Z*BC:h؇2nCs%jhėdl]ݻ^vԀ%^ᗶjUPZ Jh).eߕa2cS6$؜QFWm'q#D[>F!X嵾@\f8Ć)Iͯ]>Aw#z=]Lt ؇h,\Bz@ J" h v@ xyI ܳ@ht==s8ጜŌ]{Wt`oq{ȆD>ޒXBi޹@XMy];QP7qJ}N8X-̪}dq?YC'07L}F+~M=]pj_gq3 a=ލN@HTl}Z<|䎡<~v(TfF~|f|jxʒPXjԀ`\?S$f*d*d Edž#ǙS7X}ǃS.Dh6YY3m/\*u31Zw G!14e`B5NMlhxr6nh2q6;uأ ;h[#[B|Q/ 77O, ;\Y_A׎(3cKH8 ݵ O.C&(e#z[!o2 r`x,:9 пScN,f l೛Nx,*F>1 >SZA?G@_(:S dc3|qh挦ӬJxqf ˻[ xvC[b->NoE+Mz~~JZj>quR-ڋ6uト~' =b>ɞ1∦*z I>BC6>~\z.Z3za<##h ~@vwުBq0~,H(gđaa<9̣1̛&;.mI_˖-Tu$CȖ#O8mp f lJdz$?Œ=boiY%P٬跏nrE꥔Z< ${tP`-(q˦z\AʓCfid19|J/vdtp-m8k쯀{ qQ$ ?_"F脎Sb 04(-Z MTJ]PjD߫o0s.S3/5M3;M~p<,2^IJ%LA*Y$mduPT).)~+q!]MN t Ɓ0=*Y%x}N~N^fZ0F\ Z* ec!!^E1Hٍ33v,6>JRmHꛨZri;Ug*6g/GK+=1̻sp)cwѷex tT1hY%hBhJ)2Ac֎yS[[7aBLK+%Lk>QMV{ɊWNJO8nbDqhAelF!-\ȪOHY\͠3i]%_"x)a3~:'?V0pplॱh uPIOE(Gj5+S]:=k@rjQ@q2t3G Э'?U<{#U"^n܏Hfy2UNPSt4j#!-c9dtȏ8]dȏva/HFu꡾D:lh$˔c61AOoKqFqrT"*Tv/WG0ZRF=];2#9^iPGC>EL Nt&(FtM ί@'=5!m671z,z6 ܃̉%̊qmElCjTM\6s =Z+؛\ˣ_^^2Ԏ+PB.44Xu^0i^;KAY?ܶN} ?W~8t%?jx\Ůp-'_+ț~Am]7fk\s uH&Orqr=u7QdaYr$`\ll.s8q]o7h}kƿa.79[uc?7$>B S`["mg6y)S2>ºP_%ц#_ mxʚLfp%3}>H l4L)<;@WK᜶<-l?L)؟\xE+ԓ^04T7q 2ԍй{|y;X寠1:6de="eK ۍ R xHK.tB>BN>! OYM`%/D~YyQ e Kefжi^z@.j=JEPT~xa(ŔpwLZ()۳3s>7I1gQ< <JQͶDZ1X\ܛ(qOh]8M%>L2Hd#r-_0H^.)|zClGwsvr5Υ@TuSuiԏZׂntaԕ*, =ia"0A!WC OR@2tQtJYi\‡4tˇ9dg͸ mVRk~bU Yӡg<;U^EǽdVCL!w̑IvVlȍwlle-Pنd8.$ 9& 44͋']iORw,-25* Ȭ"޾yTokI$`rKоZ _ꌷ:Gá*TN#*+GxYOXayB+Ix?y̗ Rn0INn;#Gl ^ e6-37)?n07nXd覬ʥ1EUo~7Y7lE0šd`OkuB} 5j8dWjnw4@R]Vh*Bƈ q(9$gw.r)U '^4jV_EYѩ1w4;cE+E$|enYmj`d}wUPNBP犤pX|etn>9ez1D'`}r >K|CR&~^wQ-.9B wQ\xu1B6\qAӒl+%-+\sc_}L>/g>賟>^D1$a$dRP愪6 A ^;9`\%#y>NnxOs-MctY+9Ƕۺw(io)S\ҹ-Eg\'0ަ4,>߈#D bsM?ޮ1')Nǭ"Dba>\`?C.o߆w3Y#$X>ŋ 2D`E@IJi} rS ,&v}x)^Jb#cZK@}C\8hJ!˻~a jWlؿ'cSib|0^n')g~qz<⑲؝4uRA?ZJǏyCZ e&X͵L-8V)Ei/-)֗7{MF<;bDn <*V`i\#0fţQMIjXk#xﻥC};p,&=nMXU Xt t0;ČMx- v$׺^^3,=r-(q]fYLTه=>ڳ#&4?EvޮO톊 6>vΚC?P)7IZ^$ӟHXdH@E~:Hpl ,%#XEu jnnJ}8ziZ#5>֣cTڱidEv0R.<:s&dN:>K4t_MNonKci?Ub6KH$CE xՓ,"yRRοFBR/ QXS2EP4' $hZm䲸ƃո^aojAnoSn m!/)Gu,帒!ÌI#IL.;G;]݇#;|Tןd R)'S~"W4Fy:lMMx+!$Dӭ Uj424KH6r- Soj8-E+;Lw5/-p-[уlq$C!=ņ ( 0<:ڇC)V܁᧕4 -ozʓO ~Vs q`x|ozOBO]M)hE*hhTC"Q!j: 9)h{*B˔ Opy. I<⅒m 5{r(@DmzP4}:t8ۚn_r&ژ"e!|%>:; j T|!Mmxt4h8`B%uKY|'B*0 Q=PL&%6+Iv|eZÛ}G>z):kȣ_%o>52-E/pˑ;+,MO~NLg#SƿL'$st Ae-hn+P=G)KG#~U5B{ -XhE*DhѨUj_7k$_I2J#Rm)Qڈm@ hhQg_ _} ݤG# v۽;:^57Mlg. G×W^Tz]2ykQj'v_qZȈ;RjYS{ٮIɺF٪MR3+,x&uv=쪙BU-_7Zv~13'$O?/d^@3#kl'oV ''UXƹ{ VۤFVA6EnԓS,JpBi=zr>ZH$a؍Gm5qǛdYkm ?6 21`rE-K5Ь0d|u^ WmKB<T3)DGa{BF_NP:NUli+mWr;Gیwxh;w;.<`Eo* ra*na3UbhSFoS:U.S&IsdvF-o˿xꇇ1Dn!mFZ`WZ{U[͝xUbPtlga9}X\r)..[}"bE^[jt|*]~U00 X%^dtuv 0jEVx׆daдJY _\%7ӭi#@z R!ȇW1~wO$Yțw*,#8o(R u6~2,&r<"Ufm]DwS)~u0lϿ~q"%<*]\m`" I,kƼѵk"n유~2z ({]tij 4! LkꀣOIVz(:?]rn8 ݪ{^UV^df*oܰBfԮ[}y Y{?p ]kr!lI0(-UzBM(Q8doX  _z=Zt_'Xr9Um F*URy0$uI(9):-_٥3V8ۥCLxBO]@ <]vkewl+!KeϱGhӯFv=U ]l$_a/n7b=4 ---lBp_P#oK\W‚~ji]fmJgXD%)4UJ5ƫ\eD] EO$¸PDx3 K_pqMݴϪ'km@.@kL~z< gR|L?tn 7-!`肅3t[G@v `Hwv=X;VWa•2,')qXɱM0zAhϨE0< P~Fep[/HxdVH3g>*Ũt݅UR^&w!TפצWW/n[#_ʫ,Q+8tN,M٠iLtq&3T3 4Fy,;s# 24\ڲ#UuZZ Pr^KBP>4.`2ݦ28¡\KahBjr~WЩOPAVAj)k~*7-6fл~- CӂYSh4p"s%p]A:sA~# Uca:_8×rC.E^Mkd֎Th85mJt$@*KẼvI> 05MAc ,G0zYd۳O鿖rxd<:m$ Y^*f`ƵyIUøvI8T)^.vľnM?5͜=0E <4 K U{,&Z6ꉙ6`@ĦόEX$yR+ޟF<'㑜V/pf*IǃJ**% ‰@v3*pg<Ũ_ͅ; 8e4ȲOZ eV §v ݔlaWs">'h^C9l}A!Y -k(nkfDf<-c)Q݄ 򳸾jwJR7O,9^dbJHtG$OW@@#ZjW8_vx-wM?H%UG迥]v2I1YYGy!5{xR Qw>t>h2)8@֣-}1ujG.U9QgD9DYy-[8x\ݏսp77ӵtVcӴlğxC*tw*cJy[rZ $<݀mi<]no hy ~=-oIxUݲOdҚ՛"݉|Ł?t%[Iݺ1 | ۍGg5Gj5P= ݒ*w3Fo5GoҚ֥F!9Xn,hojԴRUk*l7q-{xso݀ć -P.H/U5R.]0NƮ9 LLyܣԓr>iB ρ}^h8yvVTHI*tpVKkKx V9G J .HgTd˵HOB=RcxF󃣂aVǵvwB)?7L{cܔ-͛ x X=#6k*.P[uc,RIL3ǽ4g3uh{ky7LAgS:ոM{/67|FXzw{^miىҹ\dj`"ghKҨ3}JG!LP&I]HB<VxFi}?Y磠Q/<(dMkHa,/\}xl ґ|m(\=" iYC5}=KL++\M̅ɌZ.s$F%ɖM E l0wrQTDI:c2Po-$|x|l ϗ *A$s6UU\'=$_N+xtunoBʳ{[ ~JY'J0rfoѮpKcV m䮸c/AnFA %^4sJ5#K ^VHV砿 ]*~fV(xQ".nO[B*ӟ&KA9Mܹp}o7ӫ誆md7욳Bv 98_ /+/rG|OW]+k9xwZUT;_0wydnA][WG,a8MjGBdn~ЌurRRh"XaW2˺}U]kjk53jg_"1598ȼh{~aɍO#X{{f@f ^)'~G );0`TN8f?6؆k?Saz=I'"nb6gt%ۧա u8Ů]u\dN9tat%q1v~9u%`/?:NȴP^yZG&R]~M/qZs{%Vp S3/3!$: A(k(Ȕ] |̛saowcLFISEQrUKS>㤚*[eؑIsk {~ޱ_:w 9RӪd &Dmiɋuf\9f^f0갩Ǧ$ IXT J{6WLlT|ldU.˜nV P6*ټ]9fr>6)el(lZ -rEy5lUbsRfR(ec;㕩lޣXLS&9EffæMLn [a+ˎJK[q~rXe+b( [W%[W![º`}8zu*e[R)f+nP{@C+UJ{`ԭSJ[Q,l҇ {|NGKV1l=zg+æʗl"![MXCǕ7*"[[º`]V|7 |:]ab+.URk[{z[C`5>lzm֡Q7oH"Xq$R1bxXXZ:üec,OF}C5NVqx1NWfz3'b) N"ofZܱo|/iaq\WzBoHZRėQ7.Əըx{\o uNnTnNOn*WG[cvU8vz6>iIٮemwgdZ-r'Z)D EN,|6;1CtʅkS2tT:X;[fxIzll]2?vl~?RwI?5PD="lrUn_܅5~گm_m_]z뗴`q+ aߝD7qb }U嗽Ox{mCܝ (BR1sEJP;[ MӠT4lZlK_6/ߵ3[BD/شDXmen++E"2_28c[ +7-0>n,Ck gql{eCj2`xewx7.{셿fݱS-|gAu6`B/8w>}}`۵}`;@\;]EK%,:)_k][toYV0 XX(͑FjV<_n'y\x[o{+.w-n+n O",NiSQvSQ73ME`1{ b/egr=P/*0upJ*~'D[-UV)m+o-oJRmoJ#j*~ƋMi/P@1Q޸Uڽq5?6wna2qtm8{@-J5*[QgAx` ͫX=#Td:Z=3%'(m;^bѐ-NG5G5[,djn ж+wh ЋkkqFiWcpykX_T]&a]m&[þa\U^m-K+lQ O'j&8$7A0ZKkT1nNڢ [Ŝp\,%6]vLh^'QUw;kW/-慿MORCَmD0qbls3Q79%k/8yNm^ߒBx.).BS܌ZWwmh1ζVl8;Θjl' O7faߌ ԍ)БXa|JqW{l@P)5^g,4j!;PEsĞb܌c :UE\м\ΗmT/`d6zee # f@m.ӪSe=]8e,t2TˀtHn;@,_Y kgX,9*UR*\'HNd1G{~ρ,/Vvom'B{Yx*c! ujuPQ`P#U[`64Wj!;krֱSwr^ػl2ߩ`xkk۠9p`΄X+h]zRېOek5i`T:W;o۸T f/.;͹Ye2޲LҘsB8+Λ7]mu18f>gر*;:n@YF@8ơcfx{iDnՈkߜ564D e{mE Y(%l\Y/:Tg[`1WVnuӴf'YW[Z"x`7Acr"N. ׶¡;*g5v})J<vu@Ee6 V\ar4?(dž7W~[o'pu~ZG|f[7%(/~ #B& )$7c(p/lo,_n^.瑊uL0/m3En+*Bi8/Uf  8fۓfu6Su/JFl|ĕù%mrm_8GW">kOk\S: 9<7v?+Kpb].QszW.'Sx/Я%k(ͅ[ͫW7{gD&$Ż&gKIy>i2E{H$evJ }< MEqGH-YCRh\M'8=doOfx?Bd aLE 8 |GY‘JoSbMtB;n9>H.L&4)|1%^8_Cv.P#+RGp%l'SPҡ$#R6-Q ALRdzƟVZ0#}YZlu!B3g jD9No #;K!-%Ő͈hZ|6Џ !M|W螘sMk%2GDH7My/FSWn6pw-8q/ JJpd7ew+brz3T|8Qw OۭM$HPsz QlQ 5Qf%Ѧ3$M!!uZ 2Cھ4UI 'ٺI~/| BiP HETdZoMT< -]-YF e.cpnz0 ! eaɅHxIpW1"ۻ|ik <>Pwm6̦KZ9cf${왷 ˠ?KYەաl(Cuv$;kKx3FV!׹{|ҚD5H3ԠOJ2)@ YZdy,OH`yQhi'2$A`،a_Wvhx' 41q܌w+U:f!渵wp"Ym-Pub=z/DStƱ0 /4( ~;?@=bk!dDRSo [1/Hq zdb-4W0^񺖝:2,ȰkRn#XkBqG%8ս#wo$[ٜ^̎g6u6N7{eSCOn7Ud+$_eύ Qm#6["̶C'Cn2al,eؽT:f5iK3 exM[yNspNԼ6:ΑįIdzlqg3a%r/(_̨w|5"pNe8Tt?7 ?V O 𙕲z uW9Kl W}B 9ͱck&w@>nRfƷTx'Q|Lfsׅ4rp'JaWw6o?wᬳBq8Yg  $ZN6_]8vp< ܽ_.N?V#Pnu@cLha~C6[$fM#1<OI;q7(ړ.vܵAZ2f k8$:1j$mAg7g6ϛze<.&uZJ)v E\dE!IWn8K8k4ABU3CEkծ9x=s}=0TxQ vk{%+h\遣V#VXz_J7ҴMT qT:s:)Z#ks4*嗽ǽ~77H ~s~rKK0=~C[?rf(Cߘl;?/[Һ43~q潰uPorc಑#ogq(%; V6ׇSm]ˠUAuq-շuշ7]VkPmfD%KY=3Q9pa&KzRڭ{_:YD͹)@JvU1Mqc_9Ti]7JypCpSґh¬^c*7,+n5_Q*| vNof kk>P<>q B"*u/y1yXچ9=-PadLPc)/jsUp}_qq92kFN:p~Т'fU2a_٬HKdž]6",=t;yUӯҗf=\#B~=!5_d;[lÕ2p(r"1co驼[WqҶc%A~{ Z^j%AN>\5ۤSY D]6-6!p7}~sF,vi;8Z`XkRU =Y)ʣMK- ud.ܯ'+O WjmH/; ,IBO/Iw5wBR*(<w7ZUww5 b7X|kH2RR'RmM@*TőZa_M_'*rpq.UbrçȾ%|/44Txwk1Z+88K㻸WiĶ9Um3-}agM|[$'fR#:wt͵4b%Q5uK J)n1]ٍ ӻA' zT5nP \geo|?]@R{X-i){k.k%~( 0U)u%<4U)5v;$ڧVV\xe6TE%4m/S_;@&9ٝa 0=}@agq鰞~3]+v_{RYPٴƧbv>a.0(jZڈYvWoΎ/PX {X2cDAw>6kw*U&NUNW9wC!W24rI'+'4q%r̀V[ʟ_5qmN/-q0hTnk꼡鞥T{_swʄ]ob5?P#;7,+j?;u7}zSu5/r_0֦$#?ڐl_;cZ ʧ ;k3QMWsSҦ Ra0+O#SK6+֦ zO9K{\F$&'eƷX2'ywe?S1 {϶ĭ .9.g*UKD{)?bR*Ls?yB~c&.۽+ :ϴnqzOCYu}y$}zǏok!"L^IyEl"8@ y B@Е `"~Ep` v8 _A/h162x>\(<-BBMZ`T!{c℞>¥$jy)7;3ù/\1O,S:\!tUA09D*eΧnLxAaYt=5R)z98Bz&q1.ybF3N7\/^Φ6ldL9RIZgR3Ѻ~GQ:rsa^;.A.:ttGAZm۹D'j\we}%^՗_߿4/Ǖ_.ҝN(Өu&E=N*f2=4RPrz)^OzΡܬj} Ngi?rl$, 3Wo{tj\׸מn*NzWoN2Pk{4s.ycI ]Zv·+1,b̰G-4 i>dlKO,Q7Ýd,2>M,27y 5r1"3FA[z%L] #D nbk|Bߐd5U{H^ Mb\5N;Vjן'7f,O{voYƊjFs-V.P< ut%\"Yj܎6aˎvC;5,$0LYOy5.*::^:>:zzj>\yy T1=QqּC{@|[2הl tQ@MDʴi񱻮ԩY8OYii=fq& TI֩\swNh͵鎑|?88{6ddn^aj$.?<{j&5GHi!Af! G\6{^Z*18/m5dkZU{eWm9hT"#_{xzy6jįi3ZӶM77ҡc@]z[ݺ+wBBa3xظ;3aQnjk wܓ:qR5}{fN˷٧Ϙ9gϙ[ ?+o(0W+vy?k3Ɵos?= +t]SKjܯFD?Zҟw$kt~Vzk·lyE,XXȹtez+]zc] O>3>^|i˯-[_ͷ޶}GY]ٳww;Gώ}ŗ_}}7ߞ{.՗.rGpCM4;WK&Zx=5;.K 2};. vHM?bœ3rf$RmC|kޝ3l9yS#Y3,59ɖ1ݚke7]MFSrf&ѤbfxW1U}϶geV܀5b-=cbb C~AA >ݘD{C3sgK!%×|t>x>P82x-(b*„…kBO$$ 6s…KP6SL;#7VXN5|j'FꞖEJt _FeLm%clrd?G㚢R1yy9ylT{)VěNȲm9\k::nKt6,K3fSs)PO&ϚfN˙J9x ƛDPu Bi|˙HQk7> h\vCèJ7y&Z&ڦ$ifݐ6xD7|3,cbfQڬPNٞG]ۯɩ9y5gY&SlkŎɲFbkQ)Z rjw f5yQbfjN9i,`eNE'=F@Ӯ,[ƠY6먜4kԔRkIjQ[F;O!Ɠ坓7؊C.nS {z:iX/jguF2R4p-)5/Ôd!c6Ҫ d.tkfUj4|0H;^9R覺ҡ=uҹ߅ [tL)+\ 8>BFXkbA Ӥ믹{4-{=R{8#5DL坥OWpj8C/YNǴu>ܷj}QyLҽ!?!GjmE\ {oFixQZox.($x~黁:{ϚתI՜q-d _zsλ|#5s ?'ڈSO(Ok86:>f)22_Us՘oDkx`Z+$XLPD0 `cRZ|H1K1{)͛'JJJ#<"V\)V^-֮]+|I.M6͛7s[o#6?IJwyG߿_⣏>ǎ_~8s8'N`|'U*q<=H›wInPeoF,dO1N4B.#yXoOEK߁QK'SXDWS)~4L-.oK('?LR(⟡ {t,4\\fbC>K}.6hO!!iB~\Ȫ WN)A)dP (')ݔ J?)Or)~}YKWŏ#)$?/+)S5_PJC|_SߙNR1_L;(1COE%1춮:t<9(.66::.*""2:[.]: QO!:?,)"!f?.>*&.r;t?6EW ?۶1{w5;A|J?..6".[?B#"9*.mU1ur}-9-fďo$[ a!?<..&. hok7 9?JM)`bcc @]nGGZڵ0Y\K G~ϰxbq|L\<9'S{ZBf-ZPJ_K`8kFMbk{CG _ې>&6oW-eYESaqR$}W+u)>7rHGZtg 3bĊ(ѹ>)Iߨ:L2~aj*fn:a^}U|M>.{Z"}c w|'Z|7ɓR|ΰn/K.xnhg{`CJ?^.D,RGh._=v1B\~!^2ħ1F.GQi_C_)~M?=?zzJ hӦ /Y6:'1iӪ-ofvԥS[{[:vBa#Pp[75ќ4kvtڣI7kfszu8^׬iV7֣oF^^~Lm}`* ;7jԈZ>8GQKa-]k {dw:s̿~|?"sΝq/{:{h4')ßu;wH&x7n\D_zO?]JhcyiIO0A%kIo AR?(D?A ΍BD\kI> aN|kǿ5 H_~7ސ|SN_СCqHGI/;Ǐ9&HadO?twJS?|?~oR}C8,A??S_РDӡuK ]`twڵʱDhعs'8v'8NPfȑ# ((7y!r|4>;Wßp?%uC,!!!!˷zKRKҙ(3}q]9z(A mQJ1)#>~){1^&w|?J?ۗ!~ (+AYwQ_}9 |!x('2)-JvP~ G466);)/^g_,t+CJ14P}O^DCR2A]Kׄ  ˋ;,*+h.#X;x2@ҘsAI9pO4!=qDʀ:qS!O-]W Ӂ:9ܣ^&R'H04Q]}]wy-^ީS>TKPжGd!~TGA×R 1DæHG)haBf@t2΀Pen|hxhxhx{eP(WF-riVt  9D:Go??uhyƍkCqïʝEdh@&΋Z?%D"h/6)ҠcZYu … ]4ԥj\T-O?*Y%w8B[Z}~P7h4hђ{#eIJ1F4+(s1".;;]:0w\(_T&0Qꎱ{>K@}.sG: }Yֽ˔ӧhW+-[N٥K"|I~9??_l6xb_~%;Ѕxo@[](xP>eտxctW}uZ}^FuM֭[촴JjGx ywDYZZ*~a2>_ЀN0)}!팖> w7L1:3ڤGg?σ/q͛7o:,OΜ9SRx;XGxwX;pErae:XSl}zkW\ [˲xʎ;[oUn͸ #Lim}DvgU@(m5?XB]|?/wubӸe 4^N:҂9Ð{Ѩ+8nБPv+ 2ݵ_grr2Nm&g̘>C_&C>8Y7-?Һy}z'gϞA1cet c1א{ 2ڌ -G@@@^{m)&f/9vQQQbݻs9qQluC7!Gh WhQvk]`}@<,B}޶m`ސӐ* Ʋaaިh]uu &/S:EZP?{nEk>>׊?5?:_/*[I*@-IXGz}>(xW^/"/O mM$B]ߠo0 uuSrJu75o]QP/Q&d>;E<ПvqwoU e.‚ $YO⠝A[1sk,.u]v>:oAw829}eXׁCsԡFGQK Ḻ?^>#,Fp%:w}}5%KACGv˖-Gey0tsЛ|㿂 chavZ_NТNSQޯPbH]}S_C 堯ɡa-kPS*},u2~X@`ٳ]QH73Oj'\?}'G;c9{>r;|hhLDߍ;ٽ7$ƶ !$GIGPЯqǃHn7wQ=:3fT y9bƌBDT&fC34SM[ jf߁fJtLLf,Ln0k1 UtE'8_gwԝlA^H >?j }?||Πs_/ r(oƆ`)%gj8v^^^hl7EgsBmKSt'H${zt }:B~tVʃ?I*Dmzq=]D?tg=BHkXo:W0'؏IykZmvz>`pGVC?Sj ƃNic}sXc11h62=ƹz4xy7uZ]ZkUM]zԑCo_?:&v$<mpR|&~CXg '2} _SIM2~ \r*ρa>szS=xT]kkTX:8>=4Ϟ3gNq[gaB~qn%b>:hhև5&c6}c\+\l'OWcϝN6Ǥ:kXgqRʕ+x o9Lm?/N`}khhu˦?S_c;mxqNL^'&m~}N`ɩh8ay||qvg,Ƶ;֌|XVWD8 w:=Xֆ}\7< GÃ﫩ɣAmcϞ=;{SKrv}YD5H'T'cVkjO<tc.뮅exgy:<'5hUs"zJ]?))DDDϻbm:##C.ZwIo ޜU+pD<>1k|\Yy )lXfsL8qoPP{yxɒ%F9ɓ'@9|pMׇr.W^_Cޜ?Dp82„ xa/e@o'V]ם2I?ߪ(/tM>rS2oP[}x:/,׬Ysh1礯)ż9%Ы{$paO[nտy迖9P3hPΛ6m@(_}/o > #{ =ƽxB}}C~$Q?kOvڵ_x.OC9Sig8Nwcc4I\*UpR[ 3zB[R~HjMオc>yc".:/[6W}ǡ79n8I;a+ Xi%ᅵVɁ;>;7u4[uNMcq0øwBNnM4O0fPNoPz -{kBxcNcoر΍6 |8{R8Ǔݡc܀#k)!ZA|#u5%䥮.~|s&tn~-/܁GCgpx {h!(ˑ#G2ON,|es;o>۷og]M6t.S#./7?O"G' m㣝HZhB$8}ݻk3gc?@\0>&|ϧ=57o8o]\\<NZAAj넓ּf>g[ iS|Dxj~uĬYSteϟ4:55ԌIy99nrO͟}z橩|[5/?#'{@݃: ll֕kL-XG1yY;Y)kZB^,dk×"ìӭY,萚==^k^=#r.!=5+a`x"dޣ{5hzs`BdBdtt!ch}x5 .}P KPBAiA ** ZlA]sTO[=_F=WثQ6L ;wR޳{KէK>cLS}^FOsgf}o&}}+&_A52< daҐ !;B4:0%:ԿCX¦ %·o :|Ԁr7`=pz@- m`@7 |~; 0 [" ܕ4&hVFJޫ8~]g-?".xCT/Ã^ ,H Ԩ=ֳOO qnqχ{;ߧ3_ZJlPGe0ٟg]44&ƢE J jFL!LJ&`X10N¤hD!)A q\;s_{ygϽVLB~Wn\kq=n­q/ o2"dqȃG$$ɋ|!r 4: &)C~Nd pgƭqW+ρ6{Q+Tw˛,S#2C>!F-)v|^m=G6yl6eMs4nsɌ;mMF~|Z*j<:NթwqZo%hZѳCQ.*w$PdZR`^_ү]:`MKmͳo?fho3$| $Zԍnux3~@fOYD&i$R^Ox!gb+?7a<{)lR'ӡȠL(dx4.z|V术 ݕjo]el1!x{]#7 #6H'Fu:ev^rDX'f8#.BzA-O^K9~Uw=cPϲvbKv;dGmd ׍+s*:΅vӯY(m@u0jC#h2 }o,l{avky;]Ir.հ,RUR}DO?|~?fI7f9j~s a3jCԔ2[]Wi;`vGV :XE(ehڈж1'BˏP;:zPƠ!=d8?!\K^1jZJQO h=C?cnv`S}bUw\-e̓BA^nEԳj_H1-&wf|>əNoxAnt}6t <ztL&8'D=5y]9_z2lrBlkT~eIa ˓Y Kei,d,%TrY!+edA6f*vܻYyOPS2T4h Tǁ'TPg,` !$E)(@ZSNիդ:vա:U:N:CJ:]tn֭1_mMI5iɇn "SlJL]xxx?ƿPKgPgdistlib/w64.exe{|8>M67f,K`EFKfȮF@@QAhJ+4VIlmjk[o-I@!! ! Y4($.9݄}?>dg4#N>6!33mˮnmlz ?MsM_ҳUx?MSkZ)*s=~"/>Axd!xͅa&{!Wq{ XG}R$LZ؜oB^#MD|Ykޘ27O(t[AXrМV(AC8vy`B mN!/W'lB\ ti KxF#UȀ|J; ̍po= X sEcx|{&E i/ f:g/m 3Q&AvoC\ܶg.̒W7c/c Π\GcY|8>=K24>4e'X\M).zɬnZYr @xyqch4CJ6~@vJ_?LqɬAfs]9O;Y2vc4K-'/nAEî;$:\s=-=,u"d_V OJrѢprG@qxU(~m([2m~조@lڴ/v(le&8^ls.sLn4daZ.4 \%mX^ga޴w0N;+BKڋк>ji\Cc(4 pי}'(Hf5i'&z7LV$'x蠵}`m_q셚.12$^cE]?p0 1<\"囕\Ďђ-u?{(ϖSKKo04>\8̍{!Z{MNQRT^&uM:,l;ޱ&eʬp|~cӹH}7XGUf8Qvf+d n9|oN po'Ud`jc8@S5Yu˸G5[*,?QJa1lWPy{puj L_JVB~cA1JtL!'Ćc0{ϝ5!ouj G +kCf\%di0 %uP8iڋӁNtQP d6 f=\E]{ WWR" Ld.`z{IWam[o*,.-'%U:X!o#zXH(0>"7bmBc̢5WV ǽH2XejC mZ$ `y~:fYKVWW'g5M#>Pl[:řb4$[M.=yGّP2Ki%#}KnSVV'4 ϙ8ƈ&Lbbxhar!|'jcZmeR<~W:u4_fx.LD-lt71]AƵ{F!: <v˺iM!:GXabUck!r/AZișf:pwVGD+wq@G`؋qa8OV-{zJhq5?%e&T]C)ރ5HdLx ZMy/a37f/o`IF%UP21 ZL,Lagdp]@%X;z3qkOò"szPBΞe΅L(q¶l u' A釄r L-$A PK+Ǽj kn𴿫+@kg#.&UJx1 ̓`ZU=BT>!l"ob`mLj^Nx >϶=Ė*"j@&Nj4tT,voÒ({ꗧ5eH6se0rmS@"jiFG$|1n&nFNڵ/Lg"60!Yx@qZ$CX*=C{lxbR|l+h՞? \ED;i(\1XA+``1;by}x8QsQE jAL<% l+OҦ1 0* C~X8M! Y^WKfPHfۊXw2ȡY%Ê\EkE8 9:NXPX~j:4/VV{ `='r3dc/G~]S2H@Օd/ғ% i HH#R/*;b*3>3iz ]- vMbثM6`/99{*>Vh|0-NtmoSz̶zW7= _=}oz'pUw\ǚ}@wUQCyA?" ]ZD=T&hIf"\Js2r%Lxfb‘fhUx dQe9圏aAh:q?k CNH %,?;ExlE`YBNp5ޣ=m_{n Z ~vOlOCNAjz= % {͛euD4@<x(j@h)p%9M"V[djR`С-ȏb5$bu8Ct>T@X+"Nk&a"[̆2*Y>ɼ: B@buR:hv*/BK˙T.HmhpyrHNĐt6|3Oِ6`9%Y[ln63k rXcdJO@BI`_DߩE+@Ue/Fצoh*Lļ,KK絗L-_mqt?{hq~T.p@>g?t2Q8EC 4L9Wb' bVȱD,k@>h; %~uX};*랼2ހٲ;I4 _*ts!>,ཡBW= $~|$,eI,J*0{u-"@=dQ#Q{:z4T>8d; =:L )$qҔBn[,,D6K[>#/FeMnNc/ڡ)k/yǃ3)V\RcMNur_mǷTTM{i}d%u&G#N*ܡ[ JP2 8lMfT{Ikp?ƲбB=fTfn-aOӲSN|rRPܴAu2*] {W$IEwEqnm C0N>^Hw}Yb yVwIDP|693p-0O⒌WGMFpPL!a^,r@;rA\Ȳ֏w41 2x Nm?Rd~; 4-j]R r+-A%e_5gK!ISR۵mF[v#M0cjt@SaӴ'qɽd]PLc9Q(jG.mBrb)ٿ!JׇACICBmaCуtQ^~O>([m|2x6= a!~R_ xzO I[3M ī!{4вdz&Hh= kDŽ:筧m[}Ԧ-KJʍW+B+-">W6KWXNkIPEE|;Fb(]n}LA ʷJq8wpȽ$kc3QZ:31C|7[+?}HrוGH [\ALNbֶ ^^$LPl oY:yZz-F13YMPk-nnTPdݒP.Of(Ǘd'54IcP' &ܶtl4,0+< 3Tgm鍾ʓQnqGF`q02Iw 3[dnxKSÅT2QCṴ}_a-gbVa'X)$VOh#YBM@9]6ɶabO(R3 2j:iL F dֿ]y|a=xi Wی_ "vPG KnBP>GB٤QT9tu+/(2pz:nFOP Wurn\,mr}p]{@H\xk:'=a@Q:j3ߏjtFK1jt2DܫSfLHmS*Uw&a}k;bEĢHtku='H9ĊT$]b(w,5 U-|(_cm.{OX|)HMb%buWAd jWBtRpeyuW} T|* XR~Dh:l{ڝ,VXj }r|Y\OP6grf@NQ_f,Jln>Kbs#*KL}-̄?^x4 ϓԐ7s$V.) oRVnh\4å,XD;d@5%%i~~QWnPD)hBگq,՚HHd(@( mqe#\܋qEOPxI{YE~Ϥɹ&A wrD1CPJdf,R  jԾfʬ\mOԳAW|Q,bo!ImFSId3ZO[U27ݼu qj-[) *(Q,k8'yԝF-FJ:d#b a 4Q02 W ModJL_ 1#<1Xnp hFpŽGy[I9";7DEpO6xO@aзLTZs\2F<ю | UڰJ^s<&,`K`9+3gLcrl8Ac49Vb-jM6i|!Ia٤DB~~Wc%'eI6|(8wZϴvt]@67~iA8gH+G]ޫd3 3.yҔonSK K'h5ȑ{` )jI]u [\h9)T<`czzQzF<ʼn< -LF8sL=3_ a<%)0.{ho+Bh/_!b ,Xy.һM3:NpWWōA42'R2EQ6W6s-nW߂FJۀ&:$[`CWҷmr,`2sd`XOL|ģkO}p8.;{5M%Ԗ@0p|˳+xJ4J럱0[3lױ%s4حgHD!{5oZ\~/Ͱ!A~u`-Qvf55a"j??$\д7A#'3=Y Ik.k,o%g?689<īC@ ڙ̶_,p~jp:`<ny9=W]'o, ]}& >! z=[&=%V av9,VfYB9,VB^F.\T}YipZD^ye.NBEێ6m9D퀜? ,'Jīk! "9n7w izwB9Γ.4I#i1\Gacy>+'jiU0bWCIAɡ u?3S ̇Tb +8~0p \w kN 2xJ9ƺwPDd1MI׵&{m?1UR2Csxh-a<2xh+!:vGpůu&!CߔItVqsD#yڤ dΝW*s;UTrPE: < ZIVSrl'VujױypPϺHIhy|u5-L/7̿/ `$p[ y#|hQv-'iwgi7QcH*5\'#2&nW`û9ADb#"#D?X-3=NT5Kgh76&{Jcn`܇<8$sʞ}~LˑD0QRF8T; fu5OB`ڨ/>ܹ鱎}x]W'ͶбDŖ{+-&hz G(0g? JIM1/'fw]y>dg&3m(&ƥzI.$Y>MGϞ4&̛nd=~->} z?n'h? SCetQN{CT!RBAVFuGL1RAM l}m.ҏTv5:2[gZ%z3 ka]wXO:;V+2!7jzf5XY9f~U@\H(7W+jH6_~ӱ;84тA&L3XI %7C+/렆G,͘Wi D'.I7S'@R-i{2{g&qf`P|ص(1yPac?8;g HRj^zHƨ5t$@>y_.UJJc3Ϟ)-w]n9ӸXnܕ 19Tr% W<>y1Yͨv^eV'"phs 13Z@r%las31y0S sZJ _~u_>ÏgFfZzĎ>B?:B cPGlNk ޮeԋѼP:w˞&縨c8Af3>܅&kF"jȩUϝBMq!aU_JHF(x2+f- cܷ!Qhdn528H߼3JfmĊLܼo>!uj4RnhF m57~W7;QC,r+E3׈Y'aC-3Q꼹ysL8q]N6y;rvAeC,~^XR^V9|Zāe6߼=@ˢ W#h(֠Xf>2j,6TP oĦCj;`d\0Lnpe 6/8~??>iauv?k0)׋$mP7eKk̒yd3alym 49WlE9'`ʿơaO1euL |h6mrtCgS+;>V"L؊?goA, 2yi ӴB__KmX0hf?jظB^vSh\Y6{/>mj(c>@E3Κ1 RcQ~vhW(;%'76i)dd۝Z-YZBV/(%#d}_/v @ zֺ!oS%RB^t/aO~L/?j dY:brU~;e8jU]k*"Nh?s#k)#!݄C9%ㆡCaG#W˸>PaFfO<:ir:૥7Y7ā$r Y$3ar}aiTL;ɱ#OPefG=ȑ$+z@X-Fs}ɯ.tYRa[Ys/ ezYx2݋mk@'|FÙO!a+?B5OΕoQ.JA@,W1J>ll2$aDyv066٥mqM<o} b'\4Li~L") 3O}̞?C 3,"q,Vm6S"x(ɉFuB62| +6&R`AzVnCC$Cxz;ޥzK޻t }t1ӵ'Hedd%x~Z*A=k0KGQ7UM,,Dq4Q.Qԣ%!_{y]Y*tq牄SD)_Us6>O{GZ]\qpps+ZeXQ'p"Qd#_="X`yD,#+ e髵EX;Doe;zC 5(p8k+ט"pgŜ!M,\Kk~@g)_ej mHTۼCz5> eV&^Vm@7D 0賶o/=s>B\hƉD |N`D N/{?*vUl{*zМy'z Hûzf3A +8Z)Ur$p[~4Ts!Qg+ZgO~@nDFvb9fq'tl#kƕsJ6v8 5f/ }*!-lTGJ\ <[MngTpE_n3$A>/[MUTg eF!*-Q|P66C(ɗ.dCexn(en/K \d7ҽcO ų?jM6mgBdSP_`Zw+,xsph1 cklVHJz+_uE;(YVjN2[5&^ߜ*$Ak9Mb6C6S0jUVEo]P)&>@շ>_Iz* ˎr([$VN <NsA!/!E!л,3O{OX 3q]dqc CEl?B= jy6Cśes>@SU٤טsճecM9@*ޣZgR'5/k-bM~Txapԩ}gNcwAe@~0u@|g,2WlT2K @> t[B٢c E `L*ɷS!@&Q/v 5ŀ ~c3L\gnnť@ѕnW 5x[k|efޮAkIh~,ܴi @3`+yà?<{)dnW >| 9h"y(6?gW {Gh)Gk|ݴ7Nm#~>BR ՇiK4ޢCrD2^bc5{\ܭHދPvKz0!m|<  .x!W xLe.ؐM=jR(F%ⴶJp ^ͤuB]wh}/^tQ:T7僄Zw1Z#I&'zet3F=;h Y&x%dܭ7'":@|PIjƍU[eϹXdd_}ous^;䶈g@A3ۡM L;QN>DGt* #C>Yݜ*ww%M !*5 BZ14[UZ(3ﱀyW[Y&@S\7&AgI$x(vn@$^d)2%l~~2>M>kBQ$VudA0$PWs|FPs9Ǿ .ID~N(ie,Rx@c{NoV Il/$"k;{Nj#c`oƤ}0`Œmq=q?kǫ~bVޞAnIF=Wn@X*bU{ 5w_~UuS,* g1ƾ WWPwMBu pC N-Ls]pPD0]3kF2׮L/y Bϲk u]}Sxttu育ZۆltNԵ_e{4LiyD;i8:_VX=Nb{|쬏m f_I*W4< ?|4P0Di_̶%' ؎GE,m ^:?e6)U^].<9W6KFT1+X6gAa؝\H}Eؔk :(Sm.s* O위%l?k8R-*V:Fπ/~|z=u[Ouc?;E+UuvvC'*]_H|dެ#}=S @1/%l:u4ߪFt5H)]LK"/u5\Pz$%>e4eaaBF5# H)J$5`xHX(>Hj;xS"5$ Ɇր\0D"ةoX>cu{Mb#cf0d:CىI TYt؄^)Q/FJ,&GZXG}~.@3hjǘL^pFz1kJ5:F6/ؘe/PMUwI/OnO*b?3v%!:E6*F6(Ze \[Jp7o6qEl"fEKpK\4q(BwKX;SX2\&1) U\I;$:Une9Oachf"fm0^YaVEݓzB0KO۝tdw$ɡ`z+[r <<=bEIӉ|@'w-٬%^+GɺEܝn`MZGau]N{> $(>b ޭN<"(fd*COԒLgG7[+4)cFhޥG48$)vm(ODA̡u } N"K-b6t#N#i}4ʁ ̈́H9v6% cc"Q?W.o4[[;~  5LsΉՖQ޺_zrF.^e;A\o?-i驯nI DBbYAAoںJ|1M^7pl;z֍16'#eN|؉[cv -"^:ү22'xZQhO_MA^ <iy}N[x]<divu n^@,ͿrH{70Mc)&r5>Cևz5s Cz& rW4|+2]>Dd65rqQHx{*}.~[;}$=4Y"Bmzǜ tAx0^Dc8rWQ`W嫜&x5T x,8kc'2DP"^({ pQ@D U S0mi`vg2D˜oXH]cMEZwW졾ۊFr·X(c;Ln gܵ$]1&:edi빚nְk d L+co(Q?7Hkxt-vzl&%KwB% æõ`E ڄkTFËM!3]׆Q^uLCf4 ~%/*TG+,9 OQGI2I() |`ׯ3vſ}7[:5Z "?_g0Q"4/@Orf3$}:gB-j fB~.8Ofa~Svޢ[BƇ&Vv\j]NP )*fW~Y3Acvؤ/%F fTO_gzIy~O3woyġ~Gy/juI3Z}py4;!z7(DOÉb~ !q%oy~}# T{rfɢ\Z7~J3:V:ץk#DD_6sE5\^&u3:.;hDb8.81A"5/&k@& {!cca;SRR$Z44FDﺹzC{hYHl!oV+ s*L@*OigqT>ND xf!" F27x)ITbY+') iۧK; *ANP&/ZǨw7d D.w_E_.Y" >d8}]]. 3]qǚ xBw@kmkqsrձ7\wMz}?nOk/f^mv=tM*:,zKL)'$ω`sztQWodquKt|@엍5|xסvt9_:} "|cO\ ; (k^̠^| 8-yN< g2;ZfwMᾝٲ)ޙ3LpC_Ր ~2{FxIcck\Ò zL.o=*.2:Hbm9 35Gu$w/_ܑ暴Km?R?&%(Π^G_(qiWRߕ)\CK%FHO!;t4[A2:X%֡ih* ~޸ޭX_ư\=WGm"Khw~ϲ<9 C)zk蚘:!Gr{ݼ(!/U-RL:~/.7<6u4=(#8)JnbGw#>a uRJvo/z6xc\ݤrk*b6w95abM=[C@ Wt.e(B ZD"Sw "q`4azVEIG H'@Y ģ'Ohdt"! [KL1=frmr,)<6M|k.T9~rf5Y\d`D!vqD {BH01˓ENfD[,mI,{#+.Sɵ9K-)cB)dizDdy&x7fַ- z@+#^@֊B _!iZ@Mz)gBD1$~fZ(ǘ7Qf'\n">:/RM~y42Q>(rbSW>Y2=o rBPȭ܎[%D7-9e|^MX4P}\a*ĽO8>n׵?4M_syL^z] ZQVkz?2^dBwe#Wd:1MDv M^45TVcʦ'H:NJQbj4W 69߮.Cl!0_FH.s|rz7o@<^&&E<8K-TSt1ۄ2;Ņ&zf~亙GF.Tڄתqmĕ>j}GԣMysc%t&ƋEpvȕ 1AjDjL ('r߈ d (u A'7<uP{9}ky{~߷+]<6w>I+f IM;:KUZA_80dWb⛨[2IrQiBE_0&*#~h-aVxއ$Na4G%ZWjZDqU﹊Qc.dKy,op/h\h)A`,yvJ=z͔5c)Mq;}p;ԘMo*ЗrzP9kQW/9h;0dRJ~mٳ%l3⥑VDxgS~!mc1yo-ֱ碪_ġy߼)|uC4jcImؾ;6<ţTFMκ;xAnvh!qGx DC6B'ey$Z+Y]ňH *Dz~zl˒-VyE{]k37Yc,ڋD$}Ԙtyeamؽ1*s|&Qvg-uT zeBY0*O Q0 Q~' I=T 4\2aVabe0,VfC) $ eJ2e0mQ)J7a&(e>%ťLlSzR)DŽڒrPKJ05)ʳLgxL=ELQ\)-|fځU*9̕fRqX)㖶*KZڪ.^I+idXSf>%vʷR]E22/ڵa&ie0o$aL'y1d$ȼNiZ2;@Ί+iHdaV@.hA.Å1sݲ #C?OYVq0P7rݗ$ ?B}eZB\"?TgPazwzc{D[Rk!P^BFPbshu,S+azV[ li4MW7_V(o=ڞ@5S_i[u^3 wPh(OʂiI. ~O6o~$$xyj?3ەO5!K{LU4`V.Tc+17{ Yʀ;SY5] CBwIwi5DF?BH lzlZVMf}ÁiR0\CHۀZ|6՛VsڹMCf ^Zjakh(pSW315T9]#{yMdvy}k\JWP=k$\/;L/2/j7goYú; .axyDX^!^k dx2:% !DŽP9y-zDzH%"ae'93H-KgeqVOѤiKҤ{ iuKݹz&NBfM A$qAGAiG6dE"{Kv?H̼lt: ŐU- > F3K;|yQzK/ iPSkL`aTf{16%e&|sQ`ihRYڦ2-RY: ךd{um&8x hՑB-%BA7qZbÖ2C 1hV 4[^>5ɽ3֛SfB}kiЄ!p A㳓H{9~w&}fy%ML V*tI{+FP}&~]yv+6Q}ynrݓ[QTQܭ-o2"g5cm#n8uΔ0{tB{W2}ەD򑢦j6snҷTy u|Z$$IW<&5ѕ(SEtMT;VF֨$۽jPD/b:!э$inR84='Ҷ>Ky/ Aju -mf!!˝_GR07io !v0RϨڱE;-o*ݜpM8ϿIqOR=B!} U7(TZrPLg_ѹȒSjፆk1z6s$fN҄DG2* Q|~}Zxջbty$sB3ckQ*lZZ ƶU(WY+(NڊcOcwHjxwUƸ߮KvwoܩFqHw䞏 >^E*Mƕ*;GgbhLʡzl2<P-qH 9ʤ(qO ]lqJi *xh=(5w1ps* ~y67i885o8;5E.~_Lp0WW&rCPIa5G0=p hAp~K|F G@7;[i)Mw?"Un;Ss3s7ʰJM>{)qԷw #0B1%$zo>UEB)W䴧w+OֳBmCO^%薦DZŗn~nuz5[$]KFNl깺=^JIх\+_{oMYK4RIqTNMqOp|0'yZ)JWy)KQyZq;P]>&-t`Sg}IdmsM]8'-lZåK\F<٠7"15?jzR4*+x4jDҤ gmkPouSH-tos7$a0lڣܟ$$B**iM)807-,WYCU%zjχ6 7*Vtf.z{ֺ\tËfЂwx8udbUޢ3Q1+φɣxO*x GxcyI%~{HV!՘Ppjʩ.bVDMS?]Ui"~Z!My=:ȨuTvn´AZQgsJ@y͡]>]ti6-cK ##{ ߍn|vy .7L0=trTq^*ɔՊRs TgU-i {w:R)t.;1ܾ&ZC+O.n2Rb(h0S#'c RcL`(]8@S9Uf0G# 1 8}W+.~=x];fsqrQjGw#iFLQw$S+K7mp7;;r"ג Y )t֣ݭ[t־g~{'tޖCIi!is݄{.~`bXu}DN`?r!nW*VD b:pŚNk(NJE@Ƚwy1TįCYs(cVC$&JBMzڼYgmGi!u]~k|bŨN w3(7|( H'OBJ:9'u;{I*JݘHKNU$)_`\Ƭ)*)¸/ph>?(*7VhJKHCM^H6\uypzwJ]p \H5ZC}o Vڇ;U_ o*"-aļ`|qWupwC֚ny7KM5K8Nlk 8`z 2HRq`f8a΂$y4=X-JU=H`MA;;FBic"Chh\U)'>̽Y6Mf<.g ED4W-wBtT73CξI=ޓyM:I1wwN:2Z}ҿ{pQvߢ]S滋DyŪ1s9hՁ޷ #{R4 W$MH-5(Ľ3 ;F+~uI=,+&|Bޣ@ڹGaӟRI_d+i TqfpoEpHw]g[hfZsų_y뗤=BwBҳѡJ,Z '|{2R1\e19Sn ,˄5]֊C*r'5*w>67sAo!PIIkӾ#ZT빏[U{} )O,`i iS+gp>&~dсo~ʐǿ2=M\o֥L2};9\b-)v~XJռKcc ,+ꙕ;fy0х*DbnI٩2~L!W$:}Z<#Qi{Ko{D_fAX@|W*m:Wu{!y߉$ 1a'z }> % w*\윊W ijB7^qt| %U@׮{=rO.~Ouku e,&RU1Klo:4Z3[Ǖj+3gr&[=WP(~s$fg'Ҽ4z!oVM7n EE/:1ԁ31gߜ(.ϟYr$)y̸yOOߩS@W! $b(Y2vl$)#8;Ȣn$Gnm vkfRc@g0ңo/N>u9rG{QjQ֤3VkT_ǵKOEFdEH[+۫ʹ W,l*V&1( AɌȄ͏oi=E&LQOSb(m^v}Cn,HS6n`û$|H¿JX/*^KK)| Q _ ? $"u,KUMJC½6HxBo%/`O H8SI6HH5P@)Z%-apI%lC ?[ Y^pi aKI?IX+q ?II0K_HX,Z ?P{d̖l=#EnT ~mg{܃OKކ.:pA8-elgI%dv gUCIfOAp8[VC+./>WnJnh)\>~]iDjnHJ~bs).k)S[WN"<%7\)L rnxx\ƧaK8_r=xfq|K8;G[%Ѥw/4ҾNjvoLㇴ/ғ5|#쪴voN>/l>i^:K%}2 IDPWn(k¾\"ổ׀ekqٗa/+ xP>gFrǸ{"wO.(>gQ|̼NꁴPrtHon>ѓ>-v/jZ]E~45z5:54z4:Dz}thkj\>:yJ$N}ͬ(TipsxPgX>338\/_ç^Y[R_3hc$ršp   lҵ[Uc{ջO_c;_x񥿿n_ơG<{{GO?S>>ŗ_}ͷߝ=r;5 O:ܱ p ?P67~o}mt6vNkZu]08d W0*;.Ş(.(q.s$g喺Ly¥sns"Ē2sfhx8VYg_u.^.*h؉u X,NSٵIIsC0\yv9s`A(ãGz=mYƓNw)Gw߹[p0RBA'%gC!S#>&!!ŋ!e2 ]&v7:j"0k%ԁd$TtWO΂؃\,׎r]EFY4ryo[Xd7J%{^fsri+Yd!1ؘ@|ġU zxpN{nY1hly. cfB^vENvϛ|0O|0;jg4OؿR&Ti;[@,afm ]Ƽ|о3}9~'BJK V`%K„R#΁]t}a. vgBԑg7NDw3qaaqx`-rZ(5,t/؝K sycm݈o=ǁ|ɮgY3/Yk1URW%W<2L;'ڡ?+oU?]J͚9iXJ3x`cբ6)\`䱨d!ueyAs.rSؗ),0ڗ8\˯ʔ B<̙ľDnmqcl U&>1vG*_i~|JF!-1KEEߜ_XꚿlLpGB3UϺGtCCdmdػ؇1;FWuXI:C3$wb^aWJz9cjХ6ן%a+ =fɰ;cj{ wŹ:/F9;55`pHÂXǡ ױp\-uK6n#;7F4!9)HRԀ~MCJH"cV0 cA{,舝. ұ ݭ떯=!D_F2Ver5ܣ ȏ1Lo u|~IOᡬw^;y{uprn y `!y|g1.!,]}S'1&<~$0{`r$>kstck0XQA+Lxa`~o2N u'SϱYq6/o7~uedLc׆Z6kn`l؉*cfǰp?fqSY.e@J{$>XgYgX6%B|dؿh mHc۽ߨ] CZ8WfѝX4Ҍyy>BKO@t;p p=GcZ>cn>sz^-n!ZWX}UЎ6Q0܃ݳ9n]9QټO4OmA߀7BSGiR Hr߰HK_Wԫh(5aN AH/A3 wS]Guvg@4x9u >&ڡW k, :DG:Xu:u~e_&8PW>c܏㫩glW~ze}@gGyFqD:1/ 1\9P0շF/1fh3bރ0ioK៥GۨM}0kSTQ'0'i r}YqwΚy; `:G+ΎȜl]\ 6 )RеiO_]շV":1]nĄf= $n:^s]֎Ha=]ɺɣt=uI:mE+͏B]M{\.A߳A ݷW";n;[,o3c9Zm׬?Ϲu[?^lw%pVsXB ;mea`߭,Y(vpb$ݞUI_tim뗱}R]KM<'59xQ]bZv'b]" 5]L%%|$NDR||JEIErP'`y+ \3K:ٯd}pp[?ڛ}lA |'|7`H%e\`r,t^TR٦X`v~=k}IR{fp9^Cbf3YsL; ](ve]jQ ܢzg8 Kܠ ɿހ7&sv6l34ۍdEUN|󫏯ʙig=|KEq9HW"/{lTRn{- ǟMY1MS-62G@ea>oh,10+݆dxBN]uR] Iȟl"/YZ7^tIޡ-5%Qv'gIq I,̻UR.may˾>ĘJy^`bA3v[31/chY/|DnFɺKPDt:>)gf: it;Sn#W˟Z JgZ@> (Q{$Msؕvv# }o6)8jDYZGjk@ɇdd3Û$|=r##:ƿan ϴ8nd r|a~0w˘0gHs9i x:[G.ѱdO( a<_= =@5@LJĘ@x$1c)t*V0c(܏7Jп ɨp 8Z=phrO¬q0WZAf)Hxu3|:[$M-q)L4fS+& Dg`L?C'oܖ.lfWEZI36g`/ax^vxkALN<9I=ɨp,h >q(;nB)')"^,M ۀzB酢< =O3+DZ)»i5\x\ IKd%NNp ] b/"|3RaS.WW.\' OpZgີ".AW0[+A.U NV8뗂os?(F-DY\Pv09im|Z|[i&#AItԈLpݢK {DL#ȻXp/ ̋|x>+ӽl0l[6?z s<D=Ø# AE4>80|Q2~ pV+{ ?/+/M"071v\MM)pp(wG?`N\g?#QgߊSw>}]n 0<"-SY> S2:Ip/`6V. oJQ5oS 8n=$phpw8^Lpƛ_2C{8ꘘX#(P}z`L}_0}nDp pwa0ES ޭ0? vIr$$}#L֡.WJwKwK3Lki&yB 0i&.t)kVi&X'J_2D'At'f:gi&W㏐i1=-rFN|N Ğ +u@fUN 7AA W0IK>Zq{HWSW:p܁wt^߁ܕvi{1Fy'0y&Wu_[b ny[ `jGV{:J[?ұC3#._gllΜ9nQP/g7ofO<۹s'ety`X>X -;ĭ//G\\l z!9x]˗ edW@]U=x׼Y jEvEWs1^o_5*~„ D̎=ʎ?>cͯUzľsy577sBO@"ITLM8{g4`څWGy4\mVaϩOa?e?'!xB◩l=oA"~-A~!~߄.Ŀ 0CoB/_AX_Pױ6Hkջ;uJ4#L=6Lcۘ=Lm~gwC# 񁫹#zuO#MفPC|?͘Ĩ.L#gY66ۏmd hc!f蛘:iw2-Li>U7"B_w! ⿌i>Bf_0 09Ze_PٷTv6GeRU_8:!R_EYߍ}K ~CA?Go@@4!Df2gR\lÇ L1!sA=bCdA "g.ڵ47 1ݺv2H)~|M߭k)k(_0d!3Ӓ'!۽U({^`-L| ?fδ̶I}zaYLOIh\[0Hq#Rm`͒i)h #҈L9iR׮]`Li$pLIO7R:'Y26pyR_ޓdp424am-"ilHO Az2&Qth+($mPZM׎N L4MM<=ܚt 2552 $'fV*XZxt mRQ/kTX |&f kGf\-Q3,k0]ƛe^xjCFL$j5ل6hӧ*d㉲ٺB LgϮm[Ůǜ>! exG}y>|\'ol\a޽7s'>b'N`'Od^>}}՗|nw߱~sNeO~{~6:v1r twc{EϲlZnSdﳧSwMk`q(A4Dy@ⷎsguiٳg?="Ȟƞ=c{oT}Pz2pQ#ao71!1͐a92O~$ #!$C.#{v&1\ `ԩ5a7&D?ޡ؀ M@70.|7H?W~MBB|BB^xLe~VGphTbdsx?D:2$&zL߾}ʿAYUΟ@O4@7g'H~ƝO08s)/.=?~NK7n\SC"ćT40w4h@U7v޼y9w޹hu׮]g}bsC.i'scc{q;I{1uۯ{T.\~߼[;?䓏y |އ64EqQ1|/ѯ2^_ˇf޶y^{Qߝ={l@9G<޽O >cn'M soA*7j;^S5:*4k֚%_f=gD T@T6ĆI A!H H (oIR@@FQ/DZLj {=ᦨ<5_?}/3gΈ!#7"L?plݺU1a~߿Lh߷oѕ* =Gж{ODbcH"iK7E^Z3UW .w1u5/T{ ? eW h1?|0|L}&ݸ#mtZ-nkW>qj9 Ɓ#8,d9 R:1JYh" 4إ`p6Im j[1:?<c|zQ` VImL?z8f`tbalYO"ǺŐMN<&0D1QvϸSMS /)ؤhY-cdAZM9 0]1LQ /CWY0r'xB X8;ebت>+l"I2bdaz< Ó*GӒzBIqBߵkf͚U!G}X~|{-!;gDVG׻yai±q2;9ab }u.߷iiioB+ nj'ѩ+h&@r9h@?ի|kך؋Xfْ]>Mڐ}V !L]Ӽyv픛nI "VrffL0A ^ l(}~wuU ov>cT۶migK۶m;92mĈߩ5|())x@/O=L5Vs ?C6?3J>}k9}EI~~Oϗӧ4h}׼ pB8P#htzy$#; 8Yu(==t0Ltb[dĉ [۱8m͗܀#vϞˬ[ȿRi>@O#'O6|w] vb=trD-b*>֭[wڰa\r+d"Kԛy 9geeѣJv xsq-a+1 v[c~]ЩSp|yCP`HLL}Zrfy ׉Mbm@'.6XioٲedϞ=՞@ϧycg]wcI=[؂>(E>=z"v=_^|>~ߜ^>Um{T}dU}m'hlo?Bo~*&HMM5Uu7l m=@/ rx\FI{ nYu˰[ \0sLQe{@1r"&kŊ˥~~P8oln' S5}C?1}YbѡE^~c#}l0, .4w;?qvC;US\alȍݴi,Yȳa&mmȌ,mڴ?B{ naܱM};*+"~wSDM Nr?w=|]sl>;9k(M٭Ow-}[`]Zy_ϫL;d {*?+y\vNx\.Lx98꣫|l8GU:6 kDc1tkqbW>P|]Z?H_jýYw?kbNAOjs| 3H 5qjQVӧ'.X u|X8xxbNjwckh}rA4_c{\%fOlC}+p2T8$f}<'_"3MЩ;.2Xohkp#!QzL§hqn> O -SM z05y>/}OmF6z<#=*z eNgǏk6eʔ1~g9[r{Z"\?$N^=&`'qJ¨p@=ԉc24 AL;8ԧ3kxx7sdoJ *t{/kC'w'4iRԩSǸ{@݄`P_T3QE1ۘ&'7&!* NWԳfnM-c=۱'T3LtS__ Ls>TG]w~6?C}w}jgtUЫWr^k\bXΜ9?|̝;=.,"k{N@=:$)q5ǧP砦_.҃{a7b~r] qi@㿌1uWzO-7?U"gę{zo@|=}zKg#CèQ[of~?k//qŞ@Иagƌc5y|>6£>jzeKLO]1,kak cW{ nlW_f}Q[c(:l /MHpm>X,KB2F͛}Wv @3>\QQ׽ Ot]W8ѯ[|#Mj}wvݭ9r NzONJ+6QU^zu-SVVvB1^0gz{(//7> >NrO?mY5BɍW ? ңR|&)lِo9F؃f-tDX0x %nM&Z;*p'w"$%W W\iEڑ]8?iT^~}䝑wSA7vACҳ5sur6>=[[{zĚĺefksR:M>S,|؝iJ=f_}YtGD^c&2&FO[RƋrAPM6럲G)|衇̞bWKd{s7_);vXޏ&S7-<Ɨ[{~G \|4ts^ԓ8<߽gϞZ2rŵiLO=~3&枰מŵ&[F r)ODD:Kk͜OYaW֚{33RL IMI%s̶3e9q]3Se<2)n᷵ ic#!p4<+#y$繾4>KWI/#9;9%iTRf͛S}RR-<1wZIaYqׂG&d&GG䋋{hj_ZG/_\Ϟ'!yMQHIuɒ%--kʶ+*.;[vmy6G*_T|Kc^#(tMiE]J+KJVEٱz~?PF^%O3OTתЫU5OrUߵ0__/K r|yE"_oooW;y[[mH???ڟgk-]}Jگ@bGPShKQUQ^.*;^e¼mXo/o?oww7]qPKgPh'distlib/wheel.py}sF+h]m ~7Z>ٖ}Jݕ0H%D$@׏yE%Ikzv{d~h{_vvwvE&^gO~cS,%+c(&)Z'ȃb,JE>I ~ Rh/olh vU 1y΄azfb_0t;=9<}#wyE0ĕ/c{!xZx-=C &EE $"C5T1 X٭HQI :COOVɫ~-n'Q8t_yzma|(9;Q8|aAƿYQ5]%g;;&GPo0 w=s>{;{6pO#rr#9C a+% w;8wO^axlgzoُG/itT뇻\c1|}#}{o/} GQp; _|ox5?;o!kQ;}jd[h~PXK_@f9D@,-F1n5Ib6 ~a_D*ht߃\#Ʉ@ q# ܵ^q 0MnD12*1vjTBA".2t-0 ܂2|H,닛K4'ɼ,f b6c!:(BX݀T5mV^QC=:尕6Y?bJ/ąyeJ3I# 8uf(Uk t(ĉƑ23Ⱥ/> q QV$|`U]A36ੇ2ߠNR'}\ Sqo/vfK2VN**3?b >zT =}F/QY_]hHeHz $ɩ5laL̕=yڌ#UlݕZWUM65:ns N͜FfVYuJpFrOPdC͚5\y{ے~z#'YjD!fpW{& ܧnO\ւ7dӼaYEHAŠI:L˃d,.B8t)vL:iSNݲj액GܞdSG{jس͒ss$h#k,V ue6 ,*ekҒ(ap|eQX@c&2uY e.B9f iI͢t/M+ۖnD]RzΓ`JE[~~~97U=2NSB.M/D5_T!.nМ2aQ">UT56+If,ʦb?`EtJ+ AҶUEeYt⠤PZ q"5Wo#Ɂ<\f-7ht?Xcb iy&&M^6ݙruٓRnYra~[BiKHЩ16(ͯ,VP3yQ[nuL<]+ȶ$6R 7}u.~{8~ ;+LB*">CW U{Be'9g-d]^ $\ɢt ldo1t|6VIMN5Rbopʹ]zD5JܑUyF{4TUKUM%C Pdz T ʠggB1-T6iU }myqtoXki0f[ж7?b P 1)Æcg3 Yq 9HgWEvB4oe,uyqTfu:"M*°Ap(:( ze]X3%$ԯꃌA!yz#(Ҭ\ q/iƭDA-#UbFVnvʽ_Ŝpt vڌHNA]H(quKpDLw׊L`%v% !HxBV#<\NriRk?Yށ Q1 wǧξ"_(sg5ɐ5<=zN=g)EPQl^)MU#LD9Y/i'-ayȸo'~sx~+m;E7`;U\|/Pn xiUԾHbGu^]x{( EJ1Φnn5K~%6kzY>0PMa9zc&F_Ȋ>ḤrA&Ï+XB<0Z:A@`lb–h"Ǽ]z IψQqk=Zl¨ vzpO)6p-a!whnԁV ǀn{' ]X]&=t-=zUy?N ^gqf1:Ccr8G)&4BB55~ 5u;Cr0>>MD\cAo,-#Ae:髧Jc_ qP=Y;7=km$9q5PC<ȓo}"oSN GDS |gўgk٧z2oiJbzۣ6\nZegW0(k9nwVu%T1%Ì#ٶYh*8g?lhsn2[|ӰNoAۆ]QtC.vi&7HD ˋwYg8N/xAo^;r{6f[&Ⱥ^z-i] yzGW)MQ@ !-)M w`.z2&&YC{3 XOE8.*ͼ\{((vVk_m&h=qpX0%HSV"FtQmȋյYL֟\wֹm# ߝyst_~<<=%K-8ﶶ毹YQç㊽p $~0!I g*i:p="SR4X>`V99w\/+Ht׾}N׹ 3g'`|uϻ rpW5^"q'-ݠc ke<4o[$0.3ɃG' Kd'r^V]IL+YAg)*8@gUǭ *Ax3`X._uhY F\eL>Y _PFyeZcNN '~jP凨` c'RR)[fӑn8( $P2rZ@S%zJSNӠ9hDhɈIl*M0Ji>^bzmaK4!9Meφ dX4& GT Ϋ` i },MR~Zf+y$~.FxKzm0-PEۈѪ!IbdCYle] OFA4c܌@3w Z#D/eg kĄZKăO|?y |N@o3?}*HF\8ǩB O\kjT  hik^lT-A*~ǁ(}ڪn Ά?ҫ6mvTXO{M[bw4O9>mmڭ)#r~sxY5!u ;u7[pHq6]88]vmԩ+n.noڳĚȽa*聳D5hJxtC1|P%mӡ˺ݥI^N?wO'Bֱp@!,XJ [P'-j"d-1i羉v v]QL`(7RRU(P(%c"J-x&aQ UйV 7.8^\REJpQajK0ՉzPⱊ哎[gYT7Tx~3-' A4A[@;ϠtTLLE>%TfuUOJKodyKN_,Ӓ-Eϴ36AAרr48?$%;*2N(> w>.ҏO_!HͳBwi *>!ˇ*t K,䆃`?t`icmt&C֍;nd6p=Z}%|݀#MYߘie"n R>6}nL]aY] h}s7A)OB*0W.7Ӷ#tSE+6"ٕ8uctymmX;Cٯ2fؚieJR2C&a;M\6VТ 䱗8 Adkб ^h#c6QYz`E\́fٖߋ'ђooYˢ6,W¤zOaՁ*F==6._ٴ(@=[i67d\ð1G봬+l,ƴӖql7 }`+f>yyG|"D|3=@,HJ+c@y'V29_ aS)RqONsIGF9G&\c<$3AR¯M){&>=sߘQ Hvj~iYۏ1̴.f-Wln am#{QLv2EΎj Mʓ;|kھI,dnKm\Vb|׋)|B6:tQx8KN c$\*jݿX$۴:&c:r,ksx(0PTZ3#(}ݖc-|g((lRҮaf#(G:fX_ugmz'$UC)l  z0׃ ]9Zד_,&A6CfrHBa=P`mG6}ؼtѭAo'i)lHܒ5#3oV6M'>2t{Qyim=Z=T=߉W6TNW{EeO[%\8CM 8WV!i~%(‚~ l}X"Q!SkNɀA5(s3YҠF2WOdz: $o:7G mjl^Uvb?R  +d|_U i{q#mPq5o*!=Ɋ)NhwXy|y]͊Q:㛊C@>e -&P :s~'3 W}'FOC{GR4:>ыpyN`p`9.=HtSD9^{9g>.UX. g7D&)?TX_@PׂuS:'˩ Msy :CS˭1''3eV'|b6MneS}'\[c lZxw|1J3 u葆{>+05uNri'!(Ek!ek'ɎLGC4cI)-[0tf{2c)h~V7<`th˫1\_`̋Ze[x=rJ TbmOrSU|6Ts{W[PC軮KT!J`7BUQ}% ]G?x%ļ-r~դZbX'z@ull\&s[w &V K,T癯ܙ41-dA6ydc*}i=| |?u1'28L9p px`YG RdL,O8.W7٬ Q:)(iD (C.(OILIz}a2QwstUj+h߇]Fuo}|Ff6p\GeUhoz,{$dg y1An&e =>f0)RaixqLW1%NPC&=LxIcdI+s>7b&jxK7ݥ 9sbh+UKbV*QE>RVnL$yP>U1:!}ym *f]pGv1h+ISjk0_ 9TńRg=Dd.`\t i4c?$ }ݖduf+X"nh1'0OlV%HGҽ=+Uv.-S}l*}5, ?0rdOj6QU )P |i]fdDVi<*]|.O4 {^<|5ȵdTnFb,p@gq*`IJ%(?J5TEYaTI79߹Ѐ+ sfVJ.ՠOygzdRXSB?_o@}q/7PKgP#gdistlib/_backport/__init__.py%N1 DQ= (xS=.͌<G+S:ö.8A-Kͣ2`'}hHnJҎY*rU}X.yyzƂ\~}XYKξ*j/VXGn|(x_6 A{Ja[6LnV囊)n;J!PKgP/edistlib/_backport/misc.py}Sn0 +-19AҡIO 2hS$C'QtM==>SX[2;h^|6eSX٦sp$W3Gop_lk*Aʚ"vuZowTz7O]L>6LXGj@JVU+4H-Gc틀`L"O$]=7ͪZ_NNON͋juk3spmC{]}ioښWUW6&?[k޽o޽ad2E̦+W81\@&f:6yamvVMzrO?bεU9m iimW1Pfg l|T~jc'tFdMI[9(,f˕}E,ּ_uUOLﶮˊKuLN!]Y V"(/?ەn垀9u v7{prW}ErnQojDo>jmYvZfryr*1DU%茷t#t`Ʈ-VQi+0 &379XjctĦT &+`(}GAx083 AvIf󽝑t{jXvhVUWi5t~ֿ r)՚UV D0q7%%C'oshqH noh?T !p7pݘ@ǓMSfnڹ)lmϟ~'g "A.l N}\7a Xြ <}tcm+"^}n,'7\"&0r.bu0D9Em\2RY*W'f03cնR\:\׍=z>ءq/MF̬ꆂ\RL@QR0$UXx_Dn63BjfX~ F Cd\=jH1-7D<%x3gS4-lZC Y)cU0%+PUX7MفM keC 7YnlAS.Mg,_~7 F.g=ނY7F>#kX|5+z9!UQd[: Ȍ@Ґc2o;6౺)NGs?eR7&T9vtMeG܀Yml̎Q8NCBT)/qpV1j|"QH`IyvJ:4WbTGEJPo"߾jƚߜs)Tы̝V9>$(Smڼxc0|f(Qk70(-Z%FE% XNB9¡6{%.H5csbJ2wp@?ĦHRa&ȭ&YL@é#!lΖC|-=M A렿Eݚn`>OȒ&`#Z/wL5/} 'k+.S:B H뺄Fm, x$ꦁ99슼i)` j`iB -$XeuVnv Hgr.(z#:]4`Y!C_o”K=I%AOA@bRYEp XQbg!,lYٲ҃@Qenq o\U%Ȋeq^AVv*e%WʄH )zZc+p,ڞ& GlvLK!N3q PHxDŽ&Puee7@7ڈ8I!lsgAƌl0嫘@4JbF#ưu6Y+ѶlA'JP;f<<ǧ*H7sW`)RKe5sA*!Hx59Zd( X@)Pخ52+s<}ZyGrmU;ѵ.]c3$%Ey%,lk %K38tz5< U (BU%uX_.PEVmPhWahR: L\"DbnY6qo|fXk*Px{z@\k w=7[Q:ڟS>@KE2s(]8@oܓh~2XVt֧gB0GwHrAhYv$X v zh`4br2 as%dlX:пS5G}A%H@ά8 ;HVSk8-dC.4&s=+U; LNb0`0P^_tlN͏b SW:#aoQDS62e,+8G5XL1TJ Vdk] `ۡ<|K6O.9zx? lGpc<̚I^,XX(*vuK nG{Ƈzkw+ ex+הc>yL̐\cZ,?$4)wʊsŷDzכ.2\]GdNBgq k؟4Xu&AUčQX`OAuy9t|vwF.iE6ҤIXppvFfs1,QB p  6Ja\8,Dpzu;|ݓt'lkfEzrM]".مI/y:.eyH/AkWXAq`. hQJ nE؁?笟 ,"!JHU&`5Nम6O5 ź2q4TXL)\E(+8fMU&eI{Z4`^ov^nqCqԨpi:p.A!/-gȯ >Y˱=&6h͎Z'*ȂQy)`qoX\7aO I~¦jW)X?^a۝nD@)8nuTB5I%9K]u{ %p{-@^c?CO$3߸C..OxytR. z-ܼc d -!I6.8aLPK 8e'FaQw%|[8L>vkTEH%v=nʅ?ʵ*T*)+घ ۦLل~DL SSac DL/w8^aȩڐ4|`0}]}k-g@x'(YLsKq 8 1|_t5=u;nO)/̲IrZ7TZb[U`E<>nYt ס ! xՊk?/WҞO/|<:ѨIB}HrÓLDte9:lI?SȠௐ\K|ɊN-N8zM Q>v?Qc3_&)KmjdN@(q({! )Ad=6|X)\dv~#Ƕlm' #0 Acg8hdsgnd%2`6'3qU6`dQAY-<`*F|DG(3R^*͛i$ gsYR+l(}?|yGy zxMP!|5 #0VY=B4ce΂ lmv{y9PO67q3WwX3TLtܓks)'k6DqwDkB X26RЗaF?'<.})?/=("bbrN;0YP.o Uj b;OAjhB <[@wgzC'kh=y9յ6X3Ā_`% d+U-poMNfY!Uq=ѧX91;+(B1T#(q"Mp->`2__YethIej*tm.IB n9Ip+=2Rz G+@d?*4t[Ki*yWS#`м<LtƮp= @@V@H ER!CW"M˻fo`ޙE{/׌fxo%F^76z).;}Oճhx>Bh,`j[~9:=_1ŘY}EizpF ؁Zd ui2DZxF)/{3\C)9;zRNqr7}"WU ySq Ά)`o퀔+»2 3(flBdf3%_+(|;A+7G/ʆZu8Zx^a?R%Ec?J96ʕ'L]׼dnNas$! c|Vwk >hD  vHMyV={L}Y(kkIǓ ag4ʻD,'(Iްx| 8qBµ5Oh>a[n=\\9-b+nWs`.Dﻏݬ?9/9ɛ" 5 ߀fa¦UV1>/^\%PĔ͖ar w"` eb2W t.4 Nev3axc%Eei0 lz"'MFo*FDxo?(gkJ/_85q}y/najDr_dHhF$lDl10B-ސ_q: ޠN=(9E>1p 0$Om?}>lAkeMCE'yժzS`ZOEAs9(-Q2M>a8 /9$EGސSW& t_&APÍFs)'B !77;D+:Ig6t`^-2_ Lʰ&="d9[{j5/(D>r}P=<j,/|VLC_uڈfHxb$1u;ty0KWNg? $f <&`/akТnMꈗxP@{U8QW*e1 o-j~Su%Nt; 6l!hJ"jơᠷ֌\bфkVrJ$֔N&LgF*t>, :-ԫy4+|ՈAD9ޘ=[/}2O9h?+,ۭ$ \94f{a $ J[yՖMf2a@*ld|x6{*Ǟ , z)gۯ.OG'( ǐɇy S62^`u`hN૽=74k_'ڔ'ڤ/ DŽz CO>cQ{g PA~KOdzTyfs=@[? Ceq`+c=د=%jLT"@ yriR77t4t\mH?߁pd#T i5 IP:gplMԬ s56!i!?Xfm6 Yánw#Z&e ML¬_.DP|jzsZdw??2t3V?:Gv)!z⋰u0DN1QC]$@Lm|x9 ֈXoyJH`Ie=zpy"8tf' ɛerXe?,ÂӴ, "#pu@FY;V{|{0Lrыwn4nGj#;82S+S(J#a~%tW[$sx{ף{W[v{q-нHBaaiw XӧǞ4?.;޳6.mthꠇR_K4!"rXޫ#Q܁NDuLpX)0JТ@Rfa$u F„H2D;X*d\mŖhS@5Ѷ$m=,cw\<g;?x6P$Nɹhq%@u `(9տ2\e"H3h(c,[D _.Âs1 3ޣ͢F!gqXP~ȶD'ۧ=yeTC> W)@}c U6C-m&^kL>䉇ρg>TW+VTPP'fH!{B1\|82!)Es]Qf_;2QX41h,'@{! @ZKʭQG#[i!E;44WJj3W/Fl(za ,A/ѫ Q@LT=C= hȳa'\RZP4P"8cZO/''\nol>{*H#֮%(+"9/F9LF>,z fB#eAk #i> todv3r2]SgG n%9Zݛ5{_z>J᧡J x%*ECc Z7F#|*rY4dSpo<Yp\S0HuL[QN^=o٠D;5vemO<3:Si ;{|(<&fw_?6,K7o/Ey `SWpmVEo};vS|UZ,kNߪ#r iKm4ΕWWMPpyZG*=fzg${UC: ̺-y `W)S8kʚ#qh T%h̲ +IZi`1ԓF Y-`kdn`[Dh\òW`Usj)i*}29əX;$exͿ5@!VI7&̹*Ԅan'{m :pIT^:)(_9󔴔4Uvt4V!{]Kj C5=l\tGl r[Q_~Z& !3U(.=eHMky95BZ(y^ nVD&fRSѬl:& t[(Y<]G% T42qz#E ^CA5/D^DIJwWF1Vj0}Kɪ+ߓx<7_ &Ӷ% srp*(Z} w&.W2_‘9n+Dߌc?7 l^buy|\ Ipa]DZȌ^5@~CGь)/&1G*0{9KH_Vuy[h`>WZwޙ e'pmNJ{t#"wҟe; I خ`ipеQm:4\PY'M|׾\Bmhz4!|xX+X :Q\C(lldW47``LT;rgT̆{" 0Si 搁?B0#SEȉ*&-?] X[,hPV(#w;>+NbK4",[EN%]c1ޱ,DOH8E|ق"Pʻ0,K e)D$< >h1{$Ty om4ۙ@q I!ݜ栧C Az5AXb]0kbm(*i!bx0/6-|oHEf#&FL%Qa9(I^`.FB&ї(jQ43LҡuCt3B[޺oJA\5@ Uxh ~&#U|1-0XjB]/H}MGF IL-u4_'0 <,v42D^o5EkxDMab$t}} ]^ hTL0 =mp\=jmXLYXO^g < $0U t(Y԰>c8Y-Nlʝ@g-Ihef/mw\ Xvݒ@gw*PMƌ$獛k^<@٨j*ϙUw.\Ƀ_u3Doiz;/4凮_`L+Ќ}w?LCHDӘ}n3{^~wFaY*4 ~HG)ũۨ Y$<3=Ji<,G$Gm7YN 1kk̽wq%HA 5?:=VU:`|e,ysj|P]OXf]y <*%~<\DkүPW5GTb}R"}Wa=z 9c$PZo.'.SdMs[Ao<{jcS{fQ" {*">;@ru{z0y>l|YY$ O{$pXxNQMZ,Bc6*r}`O~(Z̬C*0:Vj:;3:jCa S !RCqޤ1W'?7c\ryhD0\5`^O&J_?PKgPDBCbYidistlib/_backport/tarfile.pyݽ}{68?W>9Yk9/M}$N꧎v6馹*%272CRqw⍔nc`0 f6UqqΓvc<_쪊{ntejYVq2Ns_3{0M~zyDʨHʤLMR\eYe]%E2fEUɴEEDQ~Mb*8IQUfi6(X<^_V7q`ie>IcM:ɪJ 4߭l\uz^4M9`!\(qF7iu/+=tXv2_N+U$)(`dHeߏizb9U?xYN aQ #(y{ ˛k8+"`ܨ+s8#TzMxd{[\_@xNLFQW g1cwU /U@J_1\V0Qvq-ӗߎ^:?=8}»C90^BK8P 2({~{_q< q/ rY-d4khQYO3ZN,Gʼ)*A" $^\UsRhTQ?Β)x'o"Ԉ O5u 鞱]DO>~=oàj'e1xE~9N:M>~;Gg)rit˦Ms9 *͇2gm4ZIQdQI]XNt1dE{llT< `7Ӎ$YTaQc(4Ki~S"*z2؉8-q@Lp#Ru-"G݃J8?*j7U"`9Nm`'G:7SyHo98ǀڛ" 2KOJ?MT=5'ub 6g:ZsBjZω>t.%._Hj bB;DFe:R\qɏr6 7|'MTm-Ag*  u^W~ Lj{םNludKeaƓ*)6>Pp7Pid wEOAɧr ^ƫ]$Nގ`9zN"_)y8,DlIcIw+e>"//fōÓW?N^#Ýzym I|l ]V@U^nW `?yXW>cK|~z}Ǭ|ux{~qp6)sO.~ētak5VR5nv؋×o/u߾6l' #vrDu_.$m}t#skMKHX($RZj#%H8CZmB^Rho2lچoH>kR{M"k"FQYN"YD J9:<~Atqu*L'i;:e:ŷ3DHpŗaƷմL*GFwh-M#p'+GUkĂK)H}F4*h/q#ՙ]8M@6hh #u>Ms<_&4doi|tŝ|Ra͊m!K;vIK*‚\ "`A`_\]/0-.`X=H\xhF)dcы(vLtI7·%_ɒ t@W~] C2o^h<"TL -`xP!`dQsݴULZ&h1꼪Y"2+Jֈ6 ֈ<@D< 2(i FD5@|MmbRzXy%n'yNs~x̬CI7^?K*2ߖJ&9Z份oy\#e6&ic\ϺYG >w:y['Ѧ].T}b_I"&I})GYC`Hec-aq|Χ]%KU `\xՂi -x xxT&HA0ޜzxlZ,>) UQ8TT]|k.di_ӲaH뽠(G+_ؤ^/'b()|{i$/?>_bz^ s± Wu:i20ޓy\CDRXv.!B}B!(P5WIp*8V W@,5<`-34C)/5*;蕲.s 'h`(?^ ^N&sX|(3i=O?%T5{IzQݚ`MH!CvzG]5m MF2%jwM~vMu;I`Ƞe@%h68̑>lOQs|-vQ<N]uE mQKk#tt[=Q޾;÷ѿsT/ԏ'z }4nѳ_:&NkarZ^ .52gnCTŸ{Ic3XZݎ)qf;q3 ^-]c}a5m;| ;kaqƇG{p RH nՉr֩swGsʆ!н2k<"QL[8y ;2Ms@໲T|s#&sهŐx0Nvp*?k@k8Q:Fu6xї$ evr}ŋ×/wώ.`owS9:ʕU6O~/<zuw3:wu, 8[ؽ{L퇵|>nTƷ%\/ %to)K@7NĽ>!jZd1ћUǁޑ{JułF*6b.%e_uf_*vydW Ls)roϒMRVoEf@nYaJfhD}/ةA7t8fVr[|\NixWƘLA>GX %7q1-W`WHfYtEP(º/˫no3iw_o⇯g@BȔg}pw-ըTBxYᬾaGJNtVNRVϠ὘^tǪqmԙ'Q9k& ZȈ&|H!}44  9OA/>=_^e_ݏ~7VJc`Iha~%)CDm|zp3r)^0 K?[Pt X"9“RVNڄh NX4ML *$8;!n[{J2i !;u J=n1ww{{jaYìXg$!xFI  O!$u9gx Zmz{-=b葍՗9 iZm n遀)э6Z#$0]a=>˫>BI^U2VkhoZ$&uG o+g|np~ S-dm=Qzf@51@ 2Sz%Md;QWzokDm->]I0*yQtSahrv˥Pd);^b_}pyoVgPh/Kp|OeB"l҆%ׯA[NjĘ>&]:^%e3tg+_|#cY*wk;gƸ(Ns!jrx) A\B=4cEG]C !r`>pf 9ͪ5Xd[t=E-`= 1Unְ}:$;)G<\L.m ,eA:XG`M9x9HޕI9j-Uj]~cXys&=}4'vC c\:ͺLc@<ĔXj?6"v/.^ze|G B@0b\\VN`9lUi<Іu.̚gGy'ź0nNoMwKfT _plF/=)t{?WƴxƆ*?OI|e[给%"4n_ f8Rݞ}[TVH_pOmcLMV@# i@vջ# S (ޢM2* z8hs};hSܬ7b|5.i,- m~vͭ(뼬GD;9Or9[sYJ<W8Ky!Rzj8je٠e2~ ֽgVP̷͌ЂjafmeOyC`%9uqtɁ% GD\iLBS= E4KL(}$Vo!{ssH;V_9$L.Sѡm-5NXE[<ɵbvLU:ZFC}*l7Knx0,`;y޼NS,Y+'Ot ;DiY#iLiHZˑ 6F_-5D3G )b^ߨk+|x!J򲤃h"oF<[]uA[c#T!eBWP !uR={ abHd0r=؈E∲PU0Rsʍ|UD.9 ^Qء/i.ɹ-1,nͪ(ud} v RY_W4Mޥ >+|/; ! btsSW5E/]ME 58@QP呸7ԕeGfmZ8UgSmCP3S]#UYQGQ)EvtLRxR~7.L?5v rzBiT`~m .@/8,(V]f_3Tx!Y:`,0z޷0yOý2W):3!2і?7b4l)0OIJ׮Y Rֹg8rO4T ;)kϞ_'6mF÷,^o)1JH~]·/ɹ2"Ev `Eu"zɚ}weTg@1XlfKR)$#*D*q f94@ O2 FbIU2 `S. ʤċ`e1;l=%}8I`ie\0tf*, (l ]H9a+uCux̲W6Rgz[H9MV!S NCrER AɣJK$2rZA.G`\5zBl9ɌXn4h'ÛSq I ΙSuő۝Jp Ή΄ӗ IqmJw7RZ؛ft.%Y Y^|$WS2@8̽mOEϏ=V8Q3gn~jۏ4׏!Lh,od6.9 |T /c}#0:B?2[ EC9<6E"!DHdUoKRk|A\&ӢzȲ4ޤKfuoDʓC„J\ ywri.6!SX2+T_FEjEIJcya'^, 2ဧeJ {'IJyT&(%ڜ-:x%$/mV{m9;|y| &6= z]; ۃ5vPpth/Y KVAo3Oi73'ɞ55U^›yFTip'W)tV ~<̡IŢl@.bOjՖ^mtB֚czgw,/!VUCmUJn)p4d,grgÔBמ$Mݕ-ٵgwmqGl@VD#k$R^=m ayEj`(>"SNmλ ' )-tz0-C1K8:"}}g=i}k7j:xmd-7n+ڛL~WП6gJkS!s,/i3/o ^ώ,eC@ ;nz?8F ˬbķ ' `Og2#PeUJzӽ'-4e*$ M$0PJXc_Ug=hbպ y)3 w9e)U}7|Rި'*UW)Oӱd>pSevܪZ:v<~u[~ၪ=|G8GVЀ{ t;6Cآ [6KESL֑c )+(@ ୨C˘xqp^#JOdHRuȾǾD]~{+l L¼c?J<ՠ$ T( ٹçOK9G^\a':Tc+ oR hїXT8:R["lIu\H$dWJ֒sS(;|Ӈ{IuD7k֪%<vD FiN\uruUe2!&ؖG!#PHgQڬշtm╊]eKSEWٸ4վEX]6Hެ7-y^2W5b1̫-Sg6!),LTFђ7B_MSt]Yξm5GU=JKhBד$7oN._6M1? Ø|0bʹ7ԉ6GС5 I:[&;1MQ'JB>X'vL5DF6f+e"vɴE@Ϗ%L[VAȥ69'S%Ba1Ηc>,K{E[Dh(utHhFe|f#LaXyZa^o0_!tl/wؚyGY]us eZ&c1_RpB5ĽÄfr, 8*OIÆ^ܪ(iE[ҕ<\@9@=uY--ȅU ŏOT8tkO0hwW= mlZ Yjg-g BMrRc4a([}pRMyCGqyzbI+IQQqZ"fWInD#.m޳Ӑy!& +h7v74SyH]F2}ޜ+x󼾃vu\߼sOf-0Bk o/^n?+%SL81IlʲHko#Y\_#Qc&qt7h.2rAcSqP&;.:NN ϯ_YK @#{&R{"t5SqBM *0ʓ#y]*:,6*R/ ުߊB\1)Ώ΢ΓGO"ho Xoyso1Rhu!t_-KҨ3`hI1#p)w`4a7Jx/`}dz7ЗXMRuKiV|Iȓ/'3,8 Й0u"ܸ@3۰v#Q`ta"X3ds&GzIbi.%i e=vF^KO*[9ˠpP٥8{»` vd^sWR}WYų)Ίx9TQ"`ӹFc.6o,(#؏݇HbQlWne}qRbaw*v`@)*0~lWj GvVRāvI9Fc؂ԍJ{F1Ie"dO՜@;ߠLݤ'^Ȃ1*ȣG/e-zmE{:mUHoܘe>*7Oǫ2oa ">Tʈf:WD7 VKPe^#^;.}jL'@ngv|DF1$k4 EuB8tn6\k`!SUjxy7;ڤ=xAKc; yt$rKl>;};KX /OϨ'V:ߗ;yT8k8M>6H@W}P+qŮ"n?6L[ #x V 15KJ 5V='Z+7 m(*ai3_Њ*J4tN 1yvM;l8}T}k%_=?vx>~aooc_0_mC1l!5a!cWFʽ۸͝2hߏnIQ.pU~I9]8b:]\F\]>w2m9[.Ed4݉Y}?~Q$|i]2kE^ )G͸0ĆGj(W[H 0[߈hMJg@G}Yc4G,u#q_0lȏZ1w}tKSX ݄A֩Bi^OfV4zBŨPv K-uͯt;v[L͡/^S;4TVv˜:tЕ}K[un`R 6 #8e0eg% ΢RbxcEfӌ*2u9+{aE0V/|&ʫLn9z<|L;۸ *qQ΀IgY^$# QE@t`fDTԶ,Γ ^(1IwcDgg 1 0bWaN{wGl Ooe\*xSj b;S :TIQpՇ*١z1)]=JxhW):q*E@q tAc.ckW}%CķoeX/2p&M@h@Ң<â3֮<1<ҁ}hM-H4@E7z JwIy)gr7A 4D[ #e @m[tɂH]v08rC&*a; %L*5 Ќ斱Vo2AJFC=\lv|ׄ'MI`2tWGϸn$вp]Wq679s=oҍ10$SmUO sɳq\1_?;ӿS- ~wKad8&vR_u-3-ZUipR$-嘣hwo mrh3U8TAؙUD'yn2&e Hѷ&Ck\@tE5~Etao4Nh3,"?KǏE>(jzL(Ԭ!PN:@.D1hs;WDrmprZ^yOBgD83n@HSݚiKϒy~CF2maTbX)*Y%nujS+8//߫sվ:@Z,t%J%",l&&eS %E/k;kS tB7>[βT5:*ʧoOF/~kxZIN%2C!R^0!h^cmt3hVO"D9"Psq`ޘ6.t .vWT!SG]ag%ggO^p@?Ŭ Y5,+Sx*tVbR|Q86AZL q*GP?.oQ7-2 'P 9Pgk67[M[mP} b쇮_[+uo3F,(5j4qr0܄=g2g,1 5IKTzC&0xchx4s`8c;5eSݎ4CX!3͉l[+b"KWY '{';e\f2EY/h{_6O }7Ep,}WlHsw_>c&.ݭ*R[_#B+lqӛW[D殖zғ^}ҨZҾyXy:{-_ qDH |~|9A|گi%q?Sud+[@ l8D-%?/*YM^k/ ?Wx\||]4 {%p6&|'.@k'_/K>i7 [b7 Cc,EjGǃrM(KָD=6N TGb9TѬa$rZc1A#'FbѢDXOp53[ӕ<9Pڃ9F׎݇=|o ^?/M&@# /Hknn(ܳ0'ZasM iT*RCjUOᅀiTgQUڌs(9Z ,dUք!AL]|;?4C>]׀dwFhRŲo1(;r3Ұl:YvJAt'I6KKp9qc-,ڿS`͙8 Ify;pFu8o査EiSQ/1rzu6mߘQ(lMN^xw@cot`-۟[O JLysgssZN*+W_sCe'S+9"qD.nO~ܔ :O(JJmfpPyVL1A6 x>K 8,yy:5*ߞuR #QV~Tr7fl#B Vn 0#r%8(bOrsfT"ucnys iǚ$,S/R΂ sDaPeFCD ϏtrkТm c)黶Cnj_l ;+\ GHŹgy9 X AKDfsizykuJÙS"V|0o)9qMg+*$LrbV@wm邗VJUq!_e:סᨬlM=EaBbHŻY y0.⨒\U1\K2a^rZjZ|1ӕ5K˷PjɢYqpϒWCXy]u9 QjՈכ41{ 'Vl_o1+F+oVYW1G!65Uv=Ctzu OGOpƪ 6kS4IYnzs岺o Yn8jp>::?;|n؁^ x7aNȈ99^2v|gFW[xbq(o@>!Qt@N~I "q TV+ M[c̈ztd_vaC|d(+kIo2J$??~jePIf/Bdi ;-~mk1 >ںgޱ>;nCмfuQ/[ Ao#ػZNk/;Ni0xfF!3^DXls*<&;G>SfU R_ͮ-nNXJv3Eq~q5K5lT:̊QI-3+f>Ǜ~?^۫06~ ;ed6@_ݰ?dr#Ief!76CoVu-߬=P熒h}NR-p,}^e]J2EN^ g+0#"A[1>S}jؗS~䜢:%nuvHيIL>{ XUAcYnϋ:I+ _[@lHsR IEi4TadikH!S^ӧ L'+6œ+|] xM־0.fKʓYGb sYU#J'|' -ЯS}5$C ?d>b`l瀛@gmM=ngY˕8SYYϦh d}<hO}*Ωy?d;De*N; ToNOɺ$_W }B-]rS ɶxgX-ln1^˷:[.&2"nv>%PwKoծh˔~%{gӉ 378֮M@h8WvSұUS{&N:.Ph7EB8O P'U4c h4CIx͖nIl\;];jwef,l)1߭`iHd.jj};!(> SL$E8!j:Ȓiƺ`cHZǛh= &jf ё~mj jo;5߭٣^?^M'N,{-&4ro=kkg4o\ USDI" N}XdKO &Ԏ? 0M/JqAT $.% hG]@G;&ۦe=5cB!|MMRYF 5*"SsM^5->JAw< *p`L C+mk2Qe9[')Qλ)l<\L߁7§|@7 NGSe";rcZi*hqu[x+ajmTXfY=F|*J3Թ8`2M;층#yRm(KUB ˊ<& B*77!Osn̺TWi x'ӢC ~ ݛC>Q) M)A lv-ɁcB1xDg ն\Ͳkffo+;LG͘˻@[ϳF6|'wrymE7 ʪ6>&iXB }5Ú׍?;nmMGx@zwxR{gDY(r W($n+X:B-"鵤ߌr+xVFPe{~ LPko1vx trqsDP0{6|矄#i,_i x2dEo xzňE)e1weܠ2cUhu<̬H*8X5 +@i NH7E\7OXjT6>V7|,kbZ*`v7s ȿam1% k1¥jG-^=iq>IrQt6m,vH*1HzNz0}F\5U5,D@}}u[+e))OJŨ%{@y9*O3-PĆR;%]kQ$ Q0}gu꺋[t"2D nt -RE/J$&Cy2o | 8tG~~fvyiIvbZdJ}l/0sX?tN\F93߆@ɭk iU Cl|],tm3N <\^XpzvԿe:ۍ@3K;.#z99E gVO̼ P${3{, &˯C`i \AS2']+?m|Л(.0^K :-X'qGڷWٶ!QrPda枆ڑL!OF35"07 +5o:PvodaTL}=e56uΟdɣlzŰ/v|C[:8apU2#939xt\u\b"f:`6VT ]~Q'Kޜ)nVMb%-k`0 I3*#ܴ{cGLr~{|p0ۈZQ4F+UvROST: gtm_mGv˹.yuWel:l_ǟU*Ѹr2<Be+3/c=7.%߭h[hUNm#k2-K6R '|j8e!@<u}vHъd: vo`Դ]˷{Mdn{Kw+u,F09חQS:pC!Ќ^, .o o>x 6HX(JbXWia'&o矴Dz Rh`oALad;o#1`Mps t"ذ!NA4V{ yk-rgS:`R+" n0F Ic4SuL'79hVEO[36e;X\U.f':\WĘoSb+_l,0fF\CN5vji{L%kssg/Q0dmS۲eΧM`2y"Z$5!5nHsrQGi\x`o؇ˠ{Z*xHC@]S"k=52jDeW$".gv-c(<^fc֒hI7+~WqQOF90~ rk.4v4uU%D?Lt1)MsNqk:g-kll-/⁢\)ˆrFzQ7nKe FOE#+x#J?jXDWWUL#3Wˊt;c6 .z@_PKgP?~Jh distlib-0.3.1.dist-info/METADATATn@}+ 4V%9iQRC>ҞF茲F;Ieia/u0$ r~Y{ wL $WdߌbևʲݎBa\_b\*  -|B9VO/ώD.̞ .#eGs| wv3rf9ɴh衪r8#bS2Ў/z/G n?ʚ;7i$Q"xTgjb7kXY gن:&j^496fSH6#&;:ѹޡRIP#_v4~qizbrW?]NC~UZ֡["9Ѡ~oQ$?0?|PKgPCX]jdistlib-0.3.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,.LR033KI-3 /, (-JJY)r$[)T&UD"PKgPEdistlib-0.3.1.dist-info/RECORD}ɒH}f@dT LmEtY܎`拓?UES aq 0p_l-~=8GO^"e8hC)~RI[ߣa;_tj1%$!!B9}Hiitwlx$}fӡB6Fod|04'}dfQSVCf9<#8Ap͚ϩR&Hy9# E- 5# 2+CC1 9l |kr瑢 Crڗ{삓WKeN ½NuNkS]g (N-``ٸuk`wa%퇟`d 3[r[S>@'#zELbdѴLh&#m8DӌWc@"ʸau3H". d܍rߗHNEө S >`6YqH @[:ιP j-NfZx?|؃z8#8=KULXt:amx*C]p~,SCgE5(}'Ŋ6YsX.;%*F;#NﻻA?mS4Y.^?%[E}m)ڗ #P끰PK%ȵN3ao//!š}3x+t+vsopQ^+#oC_PKgPzS7]Edistlib/__init__.pyPKgP+6+distlib/compat.pyPKgP@c/s,distlib/database.pyPKgP.3JR]distlib/index.pyPKgPUQ*-s3}rdistlib/locators.pyPKgPx5gl9!distlib/manifest.pyPKgPf#distlib/markers.pyPKgPA`ߥ$2distlib/metadata.pyPKgP݄ *distlib/resources.pyPKgP8Cdistlib/scripts.pyPKgPzldistlib/t32.exePKgPy!s0distlib/t64.exePKgPR(g?distlib/util.pyPKgPh(,N_[distlib/version.pyPKgP7`distlib/w32.exePKgPgedistlib/w64.exePKgPh'Odistlib/wheel.pyPKgP#gwdistlib/_backport/__init__.pyPKgP/exdistlib/_backport/misc.pyPKgP9Qkdzdistlib/_backport/shutil.pyPKgPo9 distlib/_backport/sysconfig.cfgPKgPy룩hOdistlib/_backport/sysconfig.pyPKgPDBCbYi4distlib/_backport/tarfile.pyPKgP?~Jh distlib-0.3.1.dist-info/METADATAPKgPCX]jdistlib-0.3.1.dist-info/WHEELPKgPEndistlib-0.3.1.dist-info/RECORDPK^././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/docs/examples/mypackage-0.1/0000775000175000017500000000000000000000000020140 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1/PKG-INFO0000664000175000017500000000047600000000000021244 0ustar00tseavertseaverMetadata-Version: 1.0 Name: mypackage Version: 0.1 Summary: UNKNOWN Home-page: http://pypi.python.org/pypi/pkginfo Author: Tres Seaver Author-email: tseaver@palladion.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Environment :: Console (Text Based) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1/README.txt0000664000175000017500000000011200000000000021630 0ustar00tseavertseavermypackage README ================ Dummy package for testing ``pkginfo``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1/setup.cfg0000664000175000017500000000007300000000000021761 0ustar00tseavertseaver[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1/setup.py0000664000175000017500000000046500000000000021657 0ustar00tseavertseaverfrom setuptools import setup setup( name='mypackage', version='0.1', author='Tres Seaver', author_email='tseaver@palladion.com', url='http://pypi.python.org/pypi/pkginfo', classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ], ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1-cp26-none-linux_x86_64.whl0000664000175000017500000000343000000000000024534 0ustar00tseavertseaverPK{C^- 'mypackage-0.1.dist-info/DESCRIPTION.rst PK{C )$#mypackage-0.1.dist-info/pydist.jsonMKO0S+S*N9>$*"g%{SwCof3g8T[0yμ(MoXnoj]_LAE  Oy*&Ig $gрyD!ٟ76EVݳYj+;"1F[%6͘.PK{C2%mypackage-0.1.dist-info/top_level.txtPK {C`ggmypackage-0.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RHJ,./Q0323 /, (-JLRHK)N ILRH.02K+073PK{Cç!4 mypackage-0.1.dist-info/METADATAUN0 @ tCr I@Aꀳպ]$OTG??/$أ`A)[nF5ɀ_"vgI-7z{Lylԁ=UxN"u\qi\:GVS1Qp*h+%;v2]oe/d0g;X*h&She` B?16qX9dvWGaZ߆RPK {CL7mypackage-0.1.dist-info/RECORDu;s@ AZ@XA`qPvW>Ia:[̹I]p<0aouּ<=8M\Ă$4ܺFoAIJj&RD6ڤ!40gՄ}2^f8CTؓzRC> NQ[SiQN93cEGG-INFO/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPKIN:2EGG-INFO/zip-safePKIN:2EGG-INFO/dependency_links.txtPKIN:sXn`>EGG-INFO/SOURCES.txtPKIN:2EGG-INFO/top_level.txtPKIN:$1@.>EGG-INFO/PKG-INFOPKIN:2EGG-INFO/zip-safePKOC././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1637269959.0 pkginfo-1.10.0/docs/examples/mypackage-0.1.bogus0000664000175000017500000000000000000000000021167 0ustar00tseavertseaver././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/docs/examples/mypackage-0.1.dist-info/0000775000175000017500000000000000000000000022033 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1385588458.0 pkginfo-1.10.0/docs/examples/mypackage-0.1.dist-info/METADATA0000664000175000017500000000046400000000000023142 0ustar00tseavertseaverMetadata-Version: 2.0 Name: mypackage Version: 0.1 Summary: UNKNOWN Home-page: http://pypi.python.org/pypi/pkginfo Author: Tres Seaver Author-email: tseaver@palladion.com License: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Environment :: Console (Text Based) UNKNOWN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1.tar0000664000175000017500000002400000000000000020644 0ustar00tseavertseavermypackage-0.1/0000755000175000017500000000000011167256622013227 5ustar tseavertseavermypackage-0.1/README.txt0000644000175000017500000000011211167256274014722 0ustar tseavertseavermypackage README ================ Dummy package for testing ``pkginfo``. mypackage-0.1/setup.cfg0000644000175000017500000000007311167256622015050 0ustar tseavertseaver[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 mypackage-0.1/mypackage.egg-info/0000755000175000017500000000000011167256622016662 5ustar tseavertseavermypackage-0.1/mypackage.egg-info/dependency_links.txt0000644000175000017500000000000111167256622022730 0ustar tseavertseaver mypackage-0.1/mypackage.egg-info/SOURCES.txt0000644000175000017500000000022711167256622020547 0ustar tseavertseaverREADME.txt setup.py mypackage.egg-info/PKG-INFO mypackage.egg-info/SOURCES.txt mypackage.egg-info/dependency_links.txt mypackage.egg-info/top_level.txtmypackage-0.1/mypackage.egg-info/top_level.txt0000644000175000017500000000000111167256622021403 0ustar tseavertseaver mypackage-0.1/mypackage.egg-info/PKG-INFO0000644000175000017500000000047611167256622017766 0ustar tseavertseaverMetadata-Version: 1.0 Name: mypackage Version: 0.1 Summary: UNKNOWN Home-page: http://pypi.python.org/pypi/pkginfo Author: Tres Seaver Author-email: tseaver@palladion.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Environment :: Console (Text Based) mypackage-0.1/PKG-INFO0000644000175000017500000000047611167256622014333 0ustar tseavertseaverMetadata-Version: 1.0 Name: mypackage Version: 0.1 Summary: UNKNOWN Home-page: http://pypi.python.org/pypi/pkginfo Author: Tres Seaver Author-email: tseaver@palladion.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Environment :: Console (Text Based) mypackage-0.1/setup.py0000644000175000017500000000046511167256621014745 0ustar tseavertseaverfrom setuptools import setup setup( name='mypackage', version='0.1', author='Tres Seaver', author_email='tseaver@palladion.com', url='http://pypi.python.org/pypi/pkginfo', classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ], ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1.tar.bz20000664000175000017500000000157100000000000021350 0ustar00tseavertseaverBZh91AY&SY¯ǔ@ߊ` P @R2 4ji2a40@ #L04TQ@ RM4i@H@$eOiħOQ==G!??viwt]2l0^ .i]@Y-r)wJWV\\A0$`x弦 :YAy6k-;2 ؅ְ+:Gnŝm礊AV|&. H h1^1*0A1Aǥdw|}e)ϒL cq(q-2SCJvgooH +8+ĥHHD?2W/lİEtt3*dlX d`+ f H%~V Y"QTH:O#?\(((K ,`#HZZy=@P{V~ϰ[CJa1dp"@iً5Fi}vpJ;:|@fytT%ݱ?& 7a:jb.979[BI&;IppZ`;\e2b/>#o4{( -B> .~V`!,8yX `91+XY)rfiq'a2';uy<4{ka I2%e0u'Ffb,))j2-*-u?O_?1.8Kkgi_{"UU`;sWuMm:d71x:C 7 p𿁰~W?Y{?<:H 'fN-CeQx><$:~.T$) ’mފn),g s8W8GifPe(ayG,eKIĔֲ!ij'#4Dž#Da@pO.Ě렘''[gF=q >}#;_^[so: MavAHaSO[J$UtvjlQŽ̞ƄjF5aAϒIԒ=ZaËR4wk޸_mugRRR TZ(././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/mypackage-0.1.zip0000664000175000017500000000375400000000000020675 0ustar00tseavertseaverPKB:8Jmypackage-0.1/README.txt˭,HLNLOUrutuE\\. 0eiE %%y yi z\PK:DV2;mypackage-0.1/setup.cfgNMOKˏ*ILO*IQUsRKRl0,/(,83?,PK:$1@.>mypackage-0.1/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPK:95mypackage-0.1/setup.pyUAk0 .`at/hoe *m[ Ϳwz{BSbd2X9ɟT;E=g҇ꮔ`s,\s '‚KɣuFK[DZt#F.78}ܢV4׽ن>:N)mypackage-0.1/mypackage.egg-info/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPKB:8Jmypackage-0.1/README.txtPK:DV2;nmypackage-0.1/setup.cfgPK:$1@.>mypackage-0.1/PKG-INFOPK:95mypackage-0.1/setup.pyPK:25mypackage-0.1/mypackage.egg-info/dependency_links.txtPK:JyD[,=mypackage-0.1/mypackage.egg-info/SOURCES.txtPK:2.mypackage-0.1/mypackage.egg-info/top_level.txtPK:$1@.>)1mypackage-0.1/mypackage.egg-info/PKG-INFOPKS././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/nodistinfo-0.1-any.whl0000664000175000017500000000167300000000000021663 0ustar00tseavertseaverPK ld= EGG-INFO/UT  L6Lux PK IN:2EGG-INFO/zip-safeUT IIux  PKIN:sXn`EGG-INFO/SOURCES.txtUT IIux  rutu+(*N-)-KNK *r+ SRu3u=9M"Z\]K]I~A|NjYjHPK IN:2EGG-INFO/top_level.txtUT IIux  PK IN:2EGG-INFO/dependency_links.txtUT IIux  PK ld= AEGG-INFO/UT Lux PK IN:2CEGG-INFO/zip-safeUTIux PKIN:sXn`EGG-INFO/SOURCES.txtUTIux PK IN:2=EGG-INFO/top_level.txtUTIux PK IN:2EGG-INFO/dependency_links.txtUTIux PK././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/nopkginfo-0.1.egg0000664000175000017500000000167300000000000020664 0ustar00tseavertseaverPK ld= EGG-INFO/UT  L6Lux PK IN:2EGG-INFO/zip-safeUT IIux  PKIN:sXn`EGG-INFO/SOURCES.txtUT IIux  rutu+(*N-)-KNK *r+ SRu3u=9M"Z\]K]I~A|NjYjHPK IN:2EGG-INFO/top_level.txtUT IIux  PK IN:2EGG-INFO/dependency_links.txtUT IIux  PK ld= AEGG-INFO/UT Lux PK IN:2CEGG-INFO/zip-safeUTIux PKIN:sXn`EGG-INFO/SOURCES.txtUTIux PK IN:2=EGG-INFO/top_level.txtUTIux PK IN:2EGG-INFO/dependency_links.txtUTIux PK././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/docs/examples/nopkginfo-0.1.zip0000664000175000017500000000167300000000000020724 0ustar00tseavertseaverPK ld= EGG-INFO/UT  L6Lux PK IN:2EGG-INFO/zip-safeUT IIux  PKIN:sXn`EGG-INFO/SOURCES.txtUT IIux  rutu+(*N-)-KNK *r+ SRu3u=9M"Z\]K]I~A|NjYjHPK IN:2EGG-INFO/top_level.txtUT IIux  PK IN:2EGG-INFO/dependency_links.txtUT IIux  PK ld= AEGG-INFO/UT Lux PK IN:2CEGG-INFO/zip-safeUTIux PKIN:sXn`EGG-INFO/SOURCES.txtUTIux PK IN:2=EGG-INFO/top_level.txtUTIux PK IN:2EGG-INFO/dependency_links.txtUTIux PK././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/docs/examples/testlp1974172/0000775000175000017500000000000000000000000017775 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673196305.0 pkginfo-1.10.0/docs/examples/testlp1974172/setup.py0000664000175000017500000000107700000000000021514 0ustar00tseavertseaverfrom setuptools import setup NAME = "testlp1974172" DESCRIPTION = f"""\ Package: {NAME} ============================== This distribution exists to allow testing wheels with the description in the "body" of the metadata, rather than in a header. We make it long enough here, and with enough embedded markup, to try to trigger that feature during wheel build. See also: - https://bugs.launchpad.net/pkginfo/+bug/1885458 - https://peps.python.org/pep-0566/#description """ setup( name=NAME, description="Reproduce LP #1885458", long_description=DESCRIPTION, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/docs/examples/testlp1974172/testlp1974172.egg-info/0000775000175000017500000000000000000000000023561 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971081.0 pkginfo-1.10.0/docs/examples/testlp1974172/testlp1974172.egg-info/PKG-INFO0000664000175000017500000000104500000000000024656 0ustar00tseavertseaverMetadata-Version: 2.1 Name: testlp1974172 Version: 0.0.0 Summary: Reproduce LP #1885458 Home-page: UNKNOWN License: UNKNOWN Platform: UNKNOWN Package: testlp1974172 ============================== This distribution exists to allow testing wheels with the description in the "body" of the metadata, rather than in a header. We make it long enough here, and with enough embeded markup, to try to trigger that feature during wheel build. See also: - https://bugs.launchpad.net/pkginfo/+bug/1885458 - https://peps.python.org/pep-0566/#description ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971081.0 pkginfo-1.10.0/docs/examples/testlp1974172/testlp1974172.egg-info/SOURCES.txt0000664000175000017500000000023400000000000025444 0ustar00tseavertseaversetup.py testlp1974172.egg-info/PKG-INFO testlp1974172.egg-info/SOURCES.txt testlp1974172.egg-info/dependency_links.txt testlp1974172.egg-info/top_level.txt././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971081.0 pkginfo-1.10.0/docs/examples/testlp1974172/testlp1974172.egg-info/dependency_links.txt0000664000175000017500000000000100000000000027627 0ustar00tseavertseaver ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971081.0 pkginfo-1.10.0/docs/examples/testlp1974172/testlp1974172.egg-info/top_level.txt0000664000175000017500000000000100000000000026302 0ustar00tseavertseaver ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971081.0 pkginfo-1.10.0/docs/examples/testlp1974172-0.0.0-py3-none-any.whl0000664000175000017500000000236400000000000023402 0ustar00tseavertseaverPKtT|,N%&testlp1974172-0.0.0.dist-info/METADATA}Qn0+VXHFR)E}qKlؖ<>X33Q#bU0-&j=U ۛT}7 %=}׹!X`0gW=2m|Z/6/b!o|f{w)jlmG[g@:;γ!,`C)5цFYw.j7GԟhG!с"BMPj-m% r>FꑆN,5iҢr(I߶' !(s u"WR#0!UeY6fטpeضm|y)k~B*žwƳrYPKtTP2\\#testlp1974172-0.0.0.dist-info/WHEEL HM K-*ϳR03rOK-J,/RHJ,./Q0363 /, (-JLR()*M ILR(4KM̫PKtT2+testlp1974172-0.0.0.dist-info/top_level.txtPKtT@$testlp1974172-0.0.0.dist-info/RECORDͱr0g p4C#(.H)M:FC<\g2:TOKɌpN_e(pK*EL~V˪ZHL=>> from pkginfo import Distribution >>> from pkginfo import Index >>> index = Index() >>> list(index) [] >>> d1 = Distribution() >>> d1.name = 'foo' >>> d1.version = '1.0' >>> index.add(d1) >>> list(index) ['foo-1.0'] >>> d2 = Distribution() >>> d2.name = 'foo' >>> d2.version = '1.1' >>> index.add(d2) >>> sorted(list(index)) ['foo-1.0', 'foo-1.1'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625835719.0 pkginfo-1.10.0/docs/metadata.rst0000664000175000017500000000232200000000000016376 0ustar00tseavertseaverMetadata Versions ================= The allowed ``PKG-INFO`` fields and their semantics are defined in a series of PEPs, each of which updates the metadata version field. - Metadata version 1.0 is specified in `PEP 241`_. - Metadata version 1.1 is specified in `PEP 314`_. - Metadata version 1.2 is specified in `PEP 345`_ (still in draft). A given ``Distribution`` object parses / exposes the attributes which correspond to the metadata version specified in its ``PKG-INFO``. You can override the metadata version stored in a given distribution by passing the specific version (as a string) to its constructor. E.g., updating the metadata version here in order to expose the classifiers, which were not defined under version '1.0': .. doctest:: >>> from pkginfo import SDist >>> mypackage = SDist('docs/examples/mypackage-0.1.tar.gz', ... metadata_version='1.1') >>> print([str(x) for x in mypackage.classifiers]) ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)'] .. _`PEP 241`: http://svn.python.org/projects/peps/trunk/pep-0241.txt .. _`PEP 314`: http://svn.python.org/projects/peps/trunk/pep-0314.txt .. _`PEP 345`: http://svn.python.org/projects/peps/trunk/pep-0345.txt ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/pkginfo/0000775000175000017500000000000000000000000014572 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/__init__.py0000664000175000017500000000041200000000000016700 0ustar00tseavertseaverfrom .bdist import BDist from .develop import Develop from .distribution import Distribution from .index import Index from .installed import Installed from .sdist import SDist from .sdist import UnpackedSDist from .utils import get_metadata from .wheel import Wheel ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1672758422.0 pkginfo-1.10.0/pkginfo/__init__.pyi0000664000175000017500000000054500000000000017060 0ustar00tseavertseaverfrom .bdist import BDist as BDist from .develop import Develop as Develop from .distribution import Distribution as Distribution from .index import Index as Index from .installed import Installed as Installed from .sdist import SDist as SDist, UnpackedSDist as UnpackedSDist from .utils import get_metadata as get_metadata from .wheel import Wheel as Wheel ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/bdist.py0000664000175000017500000000225600000000000016256 0ustar00tseavertseaverimport os import zipfile from .distribution import Distribution class BDist(Distribution): def __init__(self, filename, metadata_version=None): self.filename = filename self.metadata_version = metadata_version self.extractMetadata() def read(self): fqn = os.path.abspath( os.path.normpath(self.filename)) if not os.path.exists(fqn): raise ValueError('No such file: %s' % fqn) if fqn.endswith('.egg'): archive = zipfile.ZipFile(fqn) names = archive.namelist() def read_file(name): return archive.read(name) else: raise ValueError('Not a known archive format: %s' % fqn) try: tuples = [x.split('/') for x in names if 'PKG-INFO' in x] schwarz = sorted([(len(x), x) for x in tuples]) for path in [x[1] for x in schwarz]: candidate = '/'.join(path) data = read_file(candidate) if b'Metadata-Version' in data: return data finally: archive.close() raise ValueError('No PKG-INFO in archive: %s' % fqn) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020164.0 pkginfo-1.10.0/pkginfo/bdist.pyi0000664000175000017500000000036700000000000016430 0ustar00tseavertseaverfrom .distribution import Distribution as Distribution class BDist(Distribution): filename: str metadata_version: str def __init__(self, filename: str, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1672758781.0 pkginfo-1.10.0/pkginfo/commandline.py0000664000175000017500000001636700000000000017447 0ustar00tseavertseaver"""Print the metadata for one or more Python package distributions. Usage: %prog [options] path+ Each 'path' entry can be one of the following: o a source distribution: in this case, 'path' should point to an existing archive file (.tar.gz, .tar.bz2, or .zip) as generated by 'setup.py sdist'. o a binary distribution: in this case, 'path' should point to an existing archive file (.egg) o a "develop" checkout: in this case, 'path' should point to a directory initialized via 'setup.py develop' (under setuptools). o an installed package: in this case, 'path' should be the importable name of the package. """ from configparser import ConfigParser from collections import OrderedDict from csv import writer import json import optparse import os import sys from .utils import get_metadata def _parse_options(args=None): parser = optparse.OptionParser(usage=__doc__) parser.add_option("-m", "--metadata-version", default=None, help="Override metadata version") parser.add_option("-f", "--field", dest="fields", action="append", help="Specify an output field (repeatable)", ) parser.add_option("-d", "--download-url-prefix", dest="download_url_prefix", help="Download URL prefix", ) parser.add_option("--simple", dest="output", action="store_const", const='simple', default='simple', help="Output as simple key-value pairs", ) parser.add_option("-s", "--skip", dest="skip", action="store_true", default=True, help="Skip missing values in simple output", ) parser.add_option("-S", "--no-skip", dest="skip", action="store_false", help="Don't skip missing values in simple output", ) parser.add_option("--single", dest="output", action="store_const", const='single', help="Output delimited values", ) parser.add_option("--item-delim", dest="item_delim", action="store", default=';', help="Delimiter for fields in single-line output", ) parser.add_option("--sequence-delim", dest="sequence_delim", action="store", default=',', help="Delimiter for multi-valued fields", ) parser.add_option("--csv", dest="output", action="store_const", const='csv', help="Output as CSV", ) parser.add_option("--ini", dest="output", action="store_const", const='ini', help="Output as INI", ) parser.add_option("--json", dest="output", action="store_const", const='json', help="Output as JSON", ) options, args = parser.parse_args(args) if len(args)==0: parser.error("Pass one or more files or directories as arguments.") else: return options, args class Base(object): _fields = None def __init__(self, options): if options.fields: self._fields = options.fields def finish(self): # pragma: NO COVER pass class Simple(Base): def __init__(self, options): super(Simple, self).__init__(options) self._skip = options.skip def __call__(self, meta): for field in self._fields or list(meta): value = getattr(meta, field) if (not self._skip) or (value is not None and value!=()): print("%s: %s" % (field, value)) class SingleLine(Base): _fields = None def __init__(self, options): super(SingleLine, self).__init__(options) self._item_delim = options.item_delim self._sequence_delim = options.sequence_delim def __call__(self, meta): if self._fields is None: self._fields = list(meta) values = [] for field in self._fields: value = getattr(meta, field) if isinstance(value, (tuple, list)): value = self._sequence_delim.join(value) else: value = str(value) values.append(value) print(self._item_delim.join(values)) class CSV(Base): _writer = None def __init__(self, options): super(CSV, self).__init__(options) self._sequence_delim = options.sequence_delim def __call__(self, meta): if self._fields is None: self._fields = list(meta) # first dist wins fields = self._fields if self._writer is None: self._writer = writer(sys.stdout) self._writer.writerow(fields) values = [] for field in fields: value = getattr(meta, field) if isinstance(value, (tuple, list)): value = self._sequence_delim.join(value) else: value = str(value) values.append(value) self._writer.writerow(values) class INI(Base): _fields = None def __init__(self, options): super(INI, self).__init__(options) self._parser = ConfigParser() def __call__(self, meta): name = meta.name version = meta.version section = '%s-%s' % (name, version) if self._parser.has_section(section): raise ValueError('Duplicate distribution: %s' % section) self._parser.add_section(section) for field in self._fields or list(meta): value = getattr(meta, field) if isinstance(value, (tuple, list)): value = '\n\t'.join(value) self._parser.set(section, field, value) def finish(self): self._parser.write(sys.stdout) # pragma: NO COVER class JSON(Base): _fields = None def __init__(self, options): super(JSON, self).__init__(options) self._mapping = OrderedDict() def __call__(self, meta): if self._fields is None: self._fields = list(meta) for field in self._fields: value = getattr(meta, field) if value and not isinstance(value, (tuple, list)): value = str(value) if field in self._mapping: raise ValueError('Duplicate field: %(field)r' % locals()) self._mapping[field] = value def finish(self): json.dump(self._mapping, sys.stdout, indent=2) _FORMATTERS = { 'simple': Simple, 'single': SingleLine, 'csv': CSV, 'ini': INI, 'json': JSON, } def main(args=None): """Entry point for pkginfo tool """ options, paths = _parse_options(args) format = getattr(options, 'output', 'simple') formatter = _FORMATTERS[format](options) for path in paths: meta = get_metadata(path, options.metadata_version) if meta is None: continue if options.download_url_prefix: if meta.download_url is None: filename = os.path.basename(path) meta.download_url = '%s/%s' % (options.download_url_prefix, filename) formatter(meta) formatter.finish() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020708.0 pkginfo-1.10.0/pkginfo/commandline.pyi0000664000175000017500000000210000000000000017574 0ustar00tseavertseaverimport optparse from typing import List from .distribution import Distribution from .utils import get_metadata as get_metadata ParsedOptions = tuple[optparse.Values, list[str]] class Base: def __init__(self, options: ParsedOptions) -> None: ... def finish(self) -> None: ... class Simple(Base): def __init__(self, options: ParsedOptions) -> None: ... def __call__(self, meta: Distribution) -> None: ... class SingleLine(Base): def __init__(self, options: ParsedOptions) -> None: ... def __call__(self, meta: Distribution) -> None: ... class CSV(Base): def __init__(self, options: ParsedOptions) -> None: ... def __call__(self, meta: Distribution) -> None: ... class INI(Base): def __init__(self, options: ParsedOptions) -> None: ... def __call__(self, meta: Distribution) -> None: ... def finish(self) -> None: ... class JSON(Base): def __init__(self, options: ParsedOptions) -> None: ... def __call__(self, meta: Distribution) -> None: ... def finish(self) -> None: ... def main(args: List[str] | None = ...) -> None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/develop.py0000664000175000017500000000305100000000000016601 0ustar00tseavertseaverimport io import os import sys import warnings from .distribution import Distribution def _gather_py2(top, candidates): #pragma NO COVER Py3k def _filter(candidates, dirname, fnames): for fname in fnames: fqn = os.path.join(dirname, fname) if os.path.isdir(fqn): if fname == 'EGG-INFO' or fname.endswith('.egg-info'): candidates.append(fqn) os.path.walk(top, _filter, candidates) def _gather_py3(top, candidates): #pragma NO COVER Python2 for dirpath, dirnames, fnames in os.walk(top): for dirname in dirnames: fqn = os.path.join(dirpath, dirname) if dirname == 'EGG-INFO' or dirname.endswith('.egg-info'): candidates.append(fqn) if sys.version_info[0] < 3: #pragma NO COVER Python2 _gather = _gather_py2 else: #pragma NO COVER Py3k _gather = _gather_py3 class Develop(Distribution): def __init__(self, path, metadata_version=None): self.path = os.path.abspath( os.path.normpath( os.path.expanduser(path))) self.metadata_version = metadata_version self.extractMetadata() def read(self): candidates = [self.path] _gather(self.path, candidates) for candidate in candidates: path = os.path.join(candidate, 'PKG-INFO') if os.path.exists(path): with io.open(path, errors='ignore') as f: return f.read() warnings.warn('No PKG-INFO found for path: %s' % self.path) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020146.0 pkginfo-1.10.0/pkginfo/develop.pyi0000664000175000017500000000036100000000000016753 0ustar00tseavertseaverfrom .distribution import Distribution as Distribution class Develop(Distribution): path: str metadata_version: str def __init__(self, path: str, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709451189.0 pkginfo-1.10.0/pkginfo/distribution.py0000664000175000017500000001114000000000000017660 0ustar00tseavertseaverimport io from email.parser import Parser def _must_decode(value): if type(value) is bytes: try: return value.decode('utf-8') except UnicodeDecodeError: return value.decode('latin1') return value must_decode = _must_decode # deprecated compatibility alias FBO twine. def parse(fp): return Parser().parse(fp) def get(msg, header): return _collapse_leading_ws(header, msg.get(header)) def get_all(msg, header): return [_collapse_leading_ws(header, x) for x in msg.get_all(header)] def _collapse_leading_ws(header, txt): """ ``Description`` header must preserve newlines; all others need not """ if header.lower() == 'description': # preserve newlines return '\n'.join([x[8:] if x.startswith(' ' * 8) else x for x in txt.strip().splitlines()]) else: return ' '.join([x.strip() for x in txt.splitlines()]) HEADER_ATTRS_1_0 = ( # PEP 241 ('Metadata-Version', 'metadata_version', False), ('Name', 'name', False), ('Version', 'version', False), ('Platform', 'platforms', True), ('Supported-Platform', 'supported_platforms', True), ('Summary', 'summary', False), ('Description', 'description', False), ('Keywords', 'keywords', False), ('Home-Page', 'home_page', False), ('Author', 'author', False), ('Author-email', 'author_email', False), ('License', 'license', False), ) HEADER_ATTRS_1_1 = HEADER_ATTRS_1_0 + ( # PEP 314 ('Classifier', 'classifiers', True), ('Download-URL', 'download_url', False), ('Requires', 'requires', True), ('Provides', 'provides', True), ('Obsoletes', 'obsoletes', True), ) HEADER_ATTRS_1_2 = HEADER_ATTRS_1_1 + ( # PEP 345 ('Maintainer', 'maintainer', False), ('Maintainer-email', 'maintainer_email', False), ('Requires-Python', 'requires_python', False), ('Requires-External', 'requires_external', True), ('Requires-Dist', 'requires_dist', True), ('Provides-Dist', 'provides_dist', True), ('Obsoletes-Dist', 'obsoletes_dist', True), ('Project-URL', 'project_urls', True), ) HEADER_ATTRS_2_0 = HEADER_ATTRS_1_2 #XXX PEP 426? HEADER_ATTRS_2_1 = HEADER_ATTRS_1_2 + ( # PEP 566 ('Provides-Extra', 'provides_extras', True), ('Description-Content-Type', 'description_content_type', False) ) HEADER_ATTRS_2_2 = HEADER_ATTRS_2_1 + ( # PEP 643 ('Dynamic', 'dynamic', True), ) HEADER_ATTRS_2_3 = HEADER_ATTRS_2_2 # PEP 685 HEADER_ATTRS = { '1.0': HEADER_ATTRS_1_0, '1.1': HEADER_ATTRS_1_1, '1.2': HEADER_ATTRS_1_2, '2.0': HEADER_ATTRS_2_0, '2.1': HEADER_ATTRS_2_1, '2.2': HEADER_ATTRS_2_2, '2.3': HEADER_ATTRS_2_3, } class Distribution(object): metadata_version = None # version 1.0 name = None version = None platforms = () supported_platforms = () summary = None description = None keywords = None home_page = None download_url = None author = None author_email = None license = None # version 1.1 classifiers = () requires = () provides = () obsoletes = () # version 1.2 maintainer = None maintainer_email = None requires_python = None requires_external = () requires_dist = () provides_dist = () obsoletes_dist = () project_urls = () # version 2.1 provides_extras = () description_content_type = None # version 2.2 dynamic = () def extractMetadata(self): data = self.read() self.parse(data) def read(self): raise NotImplementedError def _getHeaderAttrs(self): return HEADER_ATTRS.get(self.metadata_version, []) def parse(self, data): fp = io.StringIO(_must_decode(data)) msg = parse(fp) if 'Metadata-Version' in msg and self.metadata_version is None: value = get(msg, 'Metadata-Version') metadata_version = self.metadata_version = value for header_name, attr_name, multiple in self._getHeaderAttrs(): if attr_name == 'metadata_version': continue if header_name in msg: if multiple: values = get_all(msg, header_name) setattr(self, attr_name, values) else: value = get(msg, header_name) if value != 'UNKNOWN': setattr(self, attr_name, value) body = msg.get_payload() if body: setattr(self, 'description', body) def __iter__(self): for header_name, attr_name, multiple in self._getHeaderAttrs(): yield attr_name iterkeys = __iter__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673018532.0 pkginfo-1.10.0/pkginfo/distribution.pyi0000664000175000017500000000323300000000000020035 0ustar00tseavertseaverimport email.message from typing import Callable from typing import Dict from typing import Generator from typing import List from typing import Sequence from typing import TextIO from typing import Tuple def parse(fp: TextIO) -> email.message.Message: ... def get(msg: email.message.Message, header: str) -> str: ... def get_all(msg: email.message.Message, header: str) -> List[str]: ... _header_attr_triple = Tuple[str, str, bool] _header_attrs = Tuple[_header_attr_triple] HEADER_ATTRS_1_0: _header_attrs HEADER_ATTRS_1_1: _header_attrs HEADER_ATTRS_1_2: _header_attrs HEADER_ATTRS_2_0 = HEADER_ATTRS_1_2 HEADER_ATTRS_2_1: _header_attrs HEADER_ATTRS_2_2: _header_attrs HEADER_ATTRS: Dict[str, _header_attrs] class Distribution: metadata_version: str | None name: str version: str platforms: Sequence[str] supported_platforms: Sequence[str] summary: str description: str keywords: str home_page: str download_url: str author: str author_email: str license: str classifiers: Sequence[str] requires: Sequence[str] provides: Sequence[str] obsoletes: Sequence[str] maintainer: str maintainer_email: str requires_python: str requires_external: Sequence[str] requires_dist: Sequence[str] provides_dist: Sequence[str] obsoletes_dist: Sequence[str] project_urls: Sequence[str] provides_extras: Sequence[str] description_content_type: str dynamic: Sequence[str] def extractMetadata(self) -> None: ... def read(self) -> bytes: ... def parse(self, data: bytes) -> None: ... def __iter__(self) -> Generator[str, None, None]: ... iterkeys: Generator[str, None, None] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/index.py0000664000175000017500000000100600000000000016250 0ustar00tseavertseaverfrom .distribution import Distribution class Index(dict): def __setitem__(self, key, value): if not isinstance(value, Distribution): raise ValueError('Not a distribution: %r.' % value) if key != '%s-%s' % (value.name, value.version): raise ValueError('Key must match -.') super(Index, self).__setitem__(key, value) def add(self, distribution): key = '%s-%s' % (distribution.name, distribution.version) self[key] = distribution ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020314.0 pkginfo-1.10.0/pkginfo/index.pyi0000664000175000017500000000033700000000000016427 0ustar00tseavertseaverfrom .distribution import Distribution as Distribution class Index(dict[str, Distribution]): def __setitem__(self, key: str, value: Distribution) -> None: ... def add(self, distribution: Distribution) -> None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1669746756.0 pkginfo-1.10.0/pkginfo/installed.py0000664000175000017500000000467400000000000017136 0ustar00tseavertseaverimport glob import io import os import sys import warnings from .distribution import Distribution class Installed(Distribution): def __init__(self, package, metadata_version=None): if isinstance(package, str): self.package_name = package try: __import__(package) except ImportError: package = None else: package = sys.modules[package] else: self.package_name = package.__name__ self.package = package self.metadata_version = metadata_version self.extractMetadata() def read(self): opj = os.path.join if self.package is not None: package = self.package.__package__ if package in ('', None): package = self.package.__name__ egg_pattern = '%s*.egg-info' % package dist_pattern = '%s*.dist-info' % package pkg_file = getattr(self.package, '__file__', None) if pkg_file is not None: candidates = [] def _add_candidate(where): candidates.extend(glob.glob(where)) for entry in sys.path: if pkg_file.startswith(entry): _add_candidate(opj(entry, 'EGG-INFO')) # egg? _add_candidate(opj(entry, egg_pattern)) _add_candidate(opj(entry, dist_pattern)) dir, name = os.path.split(self.package.__file__) _add_candidate(opj(dir, egg_pattern)) _add_candidate(opj(dir, '..', egg_pattern)) _add_candidate(opj(dir, dist_pattern)) _add_candidate(opj(dir, '..', dist_pattern)) for candidate in candidates: if os.path.isdir(candidate): if candidate.lower().endswith("egg-info"): path = opj(candidate, 'PKG-INFO') elif candidate.endswith("dist-info"): path = opj(candidate, 'METADATA') else: # pragma: NO COVER continue else: path = candidate if os.path.exists(path): with io.open(path, errors='ignore') as f: return f.read() warnings.warn('No PKG-INFO found for package: %s' % self.package_name) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020138.0 pkginfo-1.10.0/pkginfo/installed.pyi0000664000175000017500000000050300000000000017272 0ustar00tseavertseaverimport types from .distribution import Distribution as Distribution class Installed(Distribution): package_name: str package: str | types.ModuleType metadata_version: str def __init__(self, package: str | types.ModuleType, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1672761434.0 pkginfo-1.10.0/pkginfo/py.typed0000664000175000017500000000000000000000000016257 0ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454015.0 pkginfo-1.10.0/pkginfo/sdist.py0000664000175000017500000000445300000000000016300 0ustar00tseavertseaverimport io import os import tarfile import zipfile from .distribution import Distribution class SDist(Distribution): def __init__(self, filename, metadata_version=None): self.filename = filename self.metadata_version = metadata_version self.extractMetadata() @classmethod def _get_archive(cls, fqn): if not os.path.exists(fqn): raise ValueError('No such file: %s' % fqn) if zipfile.is_zipfile(fqn): archive = zipfile.ZipFile(fqn) names = archive.namelist() def read_file(name): return archive.read(name) elif tarfile.is_tarfile(fqn): archive = tarfile.TarFile.open(fqn) names = archive.getnames() def read_file(name): return archive.extractfile(name).read() else: raise ValueError('Not a known archive format: %s' % fqn) return archive, names, read_file def read(self): fqn = os.path.abspath( os.path.normpath(self.filename)) archive, names, read_file = self._get_archive(fqn) try: tuples = [x.split('/') for x in names if 'PKG-INFO' in x] schwarz = sorted([(len(x), x) for x in tuples]) for path in [x[1] for x in schwarz]: candidate = '/'.join(path) data = read_file(candidate) if b'Metadata-Version' in data: return data finally: archive.close() raise ValueError('No PKG-INFO in archive: %s' % fqn) class UnpackedSDist(SDist): def __init__(self, filename, metadata_version=None): if os.path.isdir(filename): pass elif os.path.isfile(filename): filename = os.path.dirname(filename) else: raise ValueError('No such file: %s' % filename) super(UnpackedSDist, self).__init__( filename, metadata_version=metadata_version) def read(self): try: pkg_info = os.path.join(self.filename, 'PKG-INFO') with io.open(pkg_info, errors='ignore') as f: return f.read() except Exception as e: raise ValueError('Could not load %s as an unpacked sdist: %s' % (self.filename, e)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020224.0 pkginfo-1.10.0/pkginfo/sdist.pyi0000664000175000017500000000061400000000000016444 0ustar00tseavertseaverfrom .distribution import Distribution as Distribution class SDist(Distribution): filename: str metadata_version: str def __init__(self, filename: str, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... class UnpackedSDist(SDist): def __init__(self, filename: str, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/0000775000175000017500000000000000000000000015734 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454592.0 pkginfo-1.10.0/pkginfo/tests/__init__.py0000664000175000017500000000255700000000000020056 0ustar00tseavertseaver# requirements def _checkSample(testcase, installed): try: from importlib import metadata as importlib_metadata except ImportError: # python < 3.8 import importlib_metadata version = importlib_metadata.version('pkginfo') testcase.assertEqual(installed.version, version) testcase.assertEqual(installed.name, 'pkginfo') testcase.assertEqual(installed.keywords, 'distribution sdist installed metadata' ) testcase.assertEqual(list(installed.supported_platforms), []) def _checkClassifiers(testcase, installed): testcase.assertEqual(list(installed.classifiers), [ 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Software Distribution', ]) def _defaultMetadataVersion(): return '2.1' ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/funny/0000775000175000017500000000000000000000000017073 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/funny/__init__.py0000664000175000017500000000010400000000000021177 0ustar00tseavertseaver# sample installed package w/ .egg-info file. __package__ = 'funny' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/funny/funny.egg-info0000664000175000017500000000005700000000000021651 0ustar00tseavertseaverMetadata-Version: 1.0 Name: funny Version: 0.1 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/manky/0000775000175000017500000000000000000000000017053 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/manky/NOT-A-PACKAGE.txt0000664000175000017500000000022000000000000021455 0ustar00tseavertseaverTHIS IS NOT A PYTHON PACKAGE!!!! It is meant to be added to sys.path for testing introspection of namespace packages installed via setuptools. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/manky/namespaced/0000775000175000017500000000000000000000000021153 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652969858.0 pkginfo-1.10.0/pkginfo/tests/manky/namespaced/__init__.py0000664000175000017500000000033400000000000023264 0ustar00tseavertseaver# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: # pragma: NO COVER import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/manky/namespaced/manky/0000775000175000017500000000000000000000000022272 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/manky/namespaced/manky/__init__.py0000664000175000017500000000006300000000000024402 0ustar00tseavertseaver# Dummy package inside the 'namespaced' namespace. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/manky/namespaced.manky-0.1.egg-info/0000775000175000017500000000000000000000000024257 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/manky/namespaced.manky-0.1.egg-info/PKG-INFO0000664000175000017500000000005500000000000025354 0ustar00tseavertseaverMetadata-Version: 1.0 Name: namespaced.wonky ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/silly/0000775000175000017500000000000000000000000017070 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/silly/PKG-INFO0000664000175000017500000000005700000000000020167 0ustar00tseavertseaverMetadata-Version: 1.0 Name: silly Version: 0.1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/test_bdist.py0000664000175000017500000000434700000000000020462 0ustar00tseavertseaverimport unittest class BDistTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.bdist import BDist return BDist def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def _checkSample(self, bdist, filename): self.assertEqual(bdist.filename, filename) self.assertEqual(bdist.name, 'mypackage') self.assertEqual(bdist.version, '0.1') self.assertEqual(bdist.keywords, None) def _checkClassifiers(self, bdist): self.assertEqual(list(bdist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) self.assertEqual(list(bdist.supported_platforms), []) def test_ctor_w_bogus_filename(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nonesuch-0.1-py2.6.egg' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_non_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_wo_PKG_INFO(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nopkginfo-0.1.egg' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d bdist = self._makeOne(filename) self.assertEqual(bdist.metadata_version, '1.0') self._checkSample(bdist, filename) def test_ctor_w_egg_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d bdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(bdist.metadata_version, '1.1') self._checkSample(bdist, filename) self._checkClassifiers(bdist) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1669748748.0 pkginfo-1.10.0/pkginfo/tests/test_commandline.py0000664000175000017500000002671200000000000021643 0ustar00tseavertseaverimport collections import io import json as json_module import sys import unittest class Test__parse_options(unittest.TestCase): def _callFUT(self, args): from pkginfo.commandline import _parse_options return _parse_options(args) def test_empty(self): from pkginfo.commandline import __doc__ as usage firstline = usage.splitlines()[0] buf = io.StringIO() with _Monkey(sys, stderr=buf): self.assertRaises(SystemExit, self._callFUT, []) self.assertTrue(firstline in buf.getvalue()) def test_nonempty(self): options, args = self._callFUT(['foo']) self.assertEqual(args, ['foo']) class BaseTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.commandline import Base return Base def _makeOne(self, options): return self._getTargetClass()(options) def test___init___defaults(self): base = self._makeOne(_Options(fields=())) self.assertTrue(base._fields is None) def test___init___w_fields(self): fields = object() base = self._makeOne(_Options(fields=fields)) self.assertTrue(base._fields is fields) class _FormatterBase(object): def _capture_output(self, func, *args, **kw): buf = io.StringIO() with _Monkey(sys, stdout=buf): func(*args, **kw) return buf.getvalue() def _no_output(self, simple, meta): with _Monkey(sys, stdout=object()): # raise if write simple(meta) class SimpleTests(unittest.TestCase, _FormatterBase): def _getTargetClass(self): from pkginfo.commandline import Simple return Simple def _makeOne(self, options): return self._getTargetClass()(options) def test___init___(self): simple = self._makeOne(_Options(fields=None, skip=True)) self.assertTrue(simple._skip) def test___call___w_empty_fields(self): simple = self._makeOne(_Options(fields=(), skip=False)) meta = _Meta() self._no_output(simple, meta) def test___call___w_skip_and_value_None_no_fields(self): simple = self._makeOne(_Options(fields=(), skip=True)) meta = _Meta(foo=None) self._no_output(simple, meta) def test___call___w_skip_and_value_empty_tuple_explicit_fields(self): simple = self._makeOne(_Options(fields=('foo',), skip=True)) meta = _Meta(foo=(), bar='Bar') self._no_output(simple, meta) def test___call___w_skip_but_values_explicit_fields(self): simple = self._makeOne(_Options(fields=('foo',), skip=True)) meta = _Meta(foo='Foo') output = self._capture_output(simple, meta) self.assertEqual(output, 'foo: Foo\n') class SingleLineTests(unittest.TestCase, _FormatterBase): def _getTargetClass(self): from pkginfo.commandline import SingleLine return SingleLine def _makeOne(self, options): return self._getTargetClass()(options) def test___init___(self): single = self._makeOne( _Options(fields=None, item_delim='I', sequence_delim='S')) self.assertEqual(single._item_delim, 'I') self.assertEqual(single._sequence_delim, 'S') def test___call__wo_fields_wo_list(self): single = self._makeOne( _Options(fields=(), item_delim='|', sequence_delim=object())) # raise if used meta = _Meta(foo='Foo', bar='Bar') output = self._capture_output(single, meta) self.assertEqual(output, 'Bar|Foo\n') def test___call__w_fields_w_list(self): single = self._makeOne( _Options(fields=('foo', 'bar'), item_delim='|', sequence_delim='*')) meta = _Meta(foo='Foo', bar=['Bar1', 'Bar2'], baz='Baz') output = self._capture_output(single, meta) self.assertEqual(output, 'Foo|Bar1*Bar2\n') class CSVTests(unittest.TestCase, _FormatterBase): def _getTargetClass(self): from pkginfo.commandline import CSV return CSV def _makeOne(self, options): return self._getTargetClass()(options) def test___init___(self): csv = self._makeOne( _Options(fields=None, sequence_delim='S')) self.assertEqual(csv._sequence_delim, 'S') def test___call__wo_fields_wo_list(self): meta = _Meta(foo='Foo', bar='Bar') csv = self._makeOne( _Options(fields=None, sequence_delim=object())) # raise if used output = self._capture_output(csv, meta) self.assertEqual(output, 'bar,foo\r\nBar,Foo\r\n') def test___call__w_fields_w_list(self): meta = _Meta(foo='Foo', bar=['Bar1', 'Bar2'], baz='Baz') csv = self._makeOne( _Options(fields=('foo', 'bar'), item_delim='|', sequence_delim='*')) output = self._capture_output(csv, meta) self.assertEqual(output, 'foo,bar\r\nFoo,Bar1*Bar2\r\n') class INITests(unittest.TestCase, _FormatterBase): def _getTargetClass(self): from pkginfo.commandline import INI return INI def _makeOne(self, options): return self._getTargetClass()(options) def test___call___duplicate(self): ini = self._makeOne(_Options(fields=('foo',))) meta = _Meta(name='foo', version='0.1', foo='Foo') ini._parser.add_section('foo-0.1') self.assertRaises(ValueError, ini, meta) def test___call___wo_fields_wo_list(self): ini = self._makeOne(_Options(fields=None)) meta = _Meta(name='foo', version='0.1', foo='Foo') ini(meta) cp = ini._parser self.assertEqual(cp.sections(), ['foo-0.1']) self.assertEqual(sorted(cp.options('foo-0.1')), ['foo', 'name', 'version']) self.assertEqual(cp.get('foo-0.1', 'name'), 'foo') self.assertEqual(cp.get('foo-0.1', 'version'), '0.1') self.assertEqual(cp.get('foo-0.1', 'foo'), 'Foo') def test___call___w_fields_w_list(self): ini = self._makeOne(_Options(fields=('foo', 'bar'))) meta = _Meta(name='foo', version='0.1', foo='Foo', bar=['Bar1', 'Bar2'], baz='Baz') ini(meta) cp = ini._parser self.assertEqual(cp.sections(), ['foo-0.1']) self.assertEqual(sorted(cp.options('foo-0.1')), ['bar', 'foo']) self.assertEqual(cp.get('foo-0.1', 'foo'), 'Foo') self.assertEqual(cp.get('foo-0.1', 'bar'), 'Bar1\n\tBar2') class JSONtests(unittest.TestCase, _FormatterBase): def _getTargetClass(self): from pkginfo.commandline import JSON return JSON def _makeOne(self, options): return self._getTargetClass()(options) def test___call___duplicate_with_meta_and_fields(self): json = self._makeOne(_Options(fields=('name',))) meta = _Meta(name='foo', version='0.1', foo='Foo') json._mapping['name'] = 'foo' self.assertRaises(ValueError, json, meta) def test___call___duplicate_with_meta_wo_fields(self): json = self._makeOne(_Options(fields=None)) meta = _Meta(name='foo', version='0.1', foo='Foo') json._mapping['name'] = 'foo' self.assertRaises(ValueError, json, meta) def test___call___wo_fields_wo_list(self): json = self._makeOne(_Options(fields=None)) meta = _Meta(name='foo', version='0.1', foo='Foo') json(meta) expected = collections.OrderedDict([ ('foo', 'Foo'), ('name', 'foo'), ('version', '0.1')]) self.assertEqual(expected, json._mapping) def test___call___w_fields_w_list(self): json = self._makeOne(_Options(fields=('foo', 'bar'))) meta = _Meta(name='foo', version='0.1', foo='Foo', bar=['Bar1', 'Bar2'], baz='Baz') json(meta) expected = collections.OrderedDict([ ('foo', 'Foo'), ('bar', ['Bar1', 'Bar2'])]) self.assertEqual(expected, json._mapping) def test___call___output(self): json = self._makeOne(_Options(fields=None)) meta = _Meta(name='foo', version='0.1', foo='Foo') json(meta) output = self._capture_output(json.finish) output = json_module.loads( output, object_pairs_hook=collections.OrderedDict) expected = collections.OrderedDict([ ('foo', 'Foo'), ('name', 'foo'), ('version', '0.1')]) self.assertEqual(expected, output) class Test_main(unittest.TestCase): def _callFUT(self, args, monkey='simple'): from pkginfo.commandline import main from pkginfo.commandline import _FORMATTERS before = _FORMATTERS[monkey] dummy = _Formatter() _FORMATTERS[monkey] = lambda *options: dummy try: main(args) finally: _FORMATTERS[monkey] = before return dummy def test_w_mising_dist(self): from pkginfo import commandline as MUT def _get_metadata(path_or_module, md_version): self.assertEqual(path_or_module, 'foo') self.assertEqual(md_version, None) return None with _Monkey(MUT, get_metadata=_get_metadata): formatter = self._callFUT(['foo']) self.assertEqual(formatter._called_with, []) self.assertTrue(formatter._finished) def test_w_dist_wo_download_url(self): from pkginfo import commandline as MUT meta = _Meta(download_url=None) def _get_metadata(path_or_module, md_version): self.assertEqual(path_or_module, '/path/to/foo') self.assertEqual(md_version, None) return meta with _Monkey(MUT, get_metadata=_get_metadata): formatter = self._callFUT( ['-d', 'http://example.com', '/path/to/foo']) self.assertEqual(formatter._called_with, [meta]) self.assertTrue(formatter._finished) self.assertEqual(meta.download_url, 'http://example.com/foo') def test_w_dist_w_download_url(self): from pkginfo import commandline as MUT meta = _Meta(download_url='http://example.com/dist/foo') def _get_metadata(path_or_module, md_version): self.assertEqual(path_or_module, '/path/to/foo') self.assertEqual(md_version, None) return meta with _Monkey(MUT, get_metadata=_get_metadata): formatter = self._callFUT( ['-d', 'http://example.com', '/path/to/foo']) self.assertEqual(formatter._called_with, [meta]) self.assertTrue(formatter._finished) self.assertEqual(meta.download_url, 'http://example.com/dist/foo') class _Options(object): def __init__(self, **kw): for k in kw: self.__dict__[k] = kw[k] class _Meta(object): def __init__(self, **kw): for k in kw: self.__dict__[k] = kw[k] def __iter__(self): return iter(sorted(self.__dict__)) class _Monkey(object): # context-manager for replacing module names in the scope of a test. def __init__(self, module, **kw): self.module = module self.to_restore = dict([(key, getattr(module, key)) for key in kw]) for key, value in kw.items(): setattr(module, key, value) def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): for key, value in self.to_restore.items(): setattr(self.module, key, value) class _Formatter(object): _finished = False def __init__(self): self._called_with = [] def __call__(self, meta): self._called_with.append(meta) def finish(self): self._finished = True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/test_develop.py0000664000175000017500000000147700000000000021014 0ustar00tseavertseaverimport unittest class DevelopTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.develop import Develop return Develop def _makeOne(self, dirname=None): return self._getTargetClass()(dirname) def test_ctor_w_path(self): from pkginfo.tests import _checkSample develop = self._makeOne('.') _checkSample(self, develop) def test_ctor_w_invalid_path(self): import warnings old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: develop = self._makeOne('/nonesuch') self.assertEqual(develop.metadata_version, None) self.assertEqual(develop.name, None) self.assertEqual(develop.version, None) finally: warnings.filters[:] = old_filters ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709451189.0 pkginfo-1.10.0/pkginfo/tests/test_distribution.py0000664000175000017500000004640100000000000022071 0ustar00tseavertseaverimport unittest class Test__must_decode(unittest.TestCase): def _callFUT(self, arg): from pkginfo.distribution import _must_decode return _must_decode(arg) def test_w_bytes_latin1(self): TO_ENCODE = u'\u00C9' # capital E w/ acute accent encoded = TO_ENCODE.encode("latin-1") decoded = self._callFUT(encoded) self.assertEqual(decoded, TO_ENCODE) def test_w_bytes_utf8(self): TO_ENCODE = u'\u00C9' # capital E w/ acute accent encoded = TO_ENCODE.encode("utf-8") decoded = self._callFUT(encoded) self.assertEqual(decoded, TO_ENCODE) def test_w_unicode(self): ARG = u'\u00C9' # capital E w/ acute accent decoded = self._callFUT(ARG) self.assertEqual(decoded, ARG) def test_w_object(self): ARG = object() decoded = self._callFUT(ARG) self.assertIs(decoded, ARG) class DistributionTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.distribution import Distribution return Distribution def _makeOne(self, metadata_version='1.0'): dist = self._getTargetClass()() if metadata_version is not None: dist.metadata_version = metadata_version return dist def test_ctor_defaults(self): sdist = self._makeOne(None) self.assertEqual(sdist.metadata_version, None) # version 1.0 self.assertEqual(sdist.name, None) self.assertEqual(sdist.version, None) self.assertEqual(sdist.platforms, ()) self.assertEqual(sdist.supported_platforms, ()) self.assertEqual(sdist.summary, None) self.assertEqual(sdist.description, None) self.assertEqual(sdist.keywords, None) self.assertEqual(sdist.home_page, None) self.assertEqual(sdist.download_url, None) self.assertEqual(sdist.author, None) self.assertEqual(sdist.author_email, None) self.assertEqual(sdist.license, None) # version 1.1 self.assertEqual(sdist.classifiers, ()) self.assertEqual(sdist.requires, ()) self.assertEqual(sdist.provides, ()) self.assertEqual(sdist.obsoletes, ()) # version 1.2 self.assertEqual(sdist.maintainer, None) self.assertEqual(sdist.maintainer_email, None) self.assertEqual(sdist.requires_python, None) self.assertEqual(sdist.requires_external, ()) self.assertEqual(sdist.requires_dist, ()) self.assertEqual(sdist.provides_dist, ()) self.assertEqual(sdist.obsoletes_dist, ()) self.assertEqual(sdist.project_urls, ()) # version 2.1 self.assertEqual(sdist.provides_extras, ()) self.assertEqual(sdist.description_content_type, None) # version 2.2 self.assertEqual(sdist.dynamic, ()) def test_extractMetadata_raises_NotImplementedError(self): # 'extractMetadata' calls 'read', which subclasses must override. dist = self._makeOne(None) self.assertRaises(NotImplementedError, dist.extractMetadata) def test_read_raises_NotImplementedError(self): # Subclasses must override 'read'. dist = self._makeOne(None) self.assertRaises(NotImplementedError, dist.read) def test_parse_given_unicode(self): dist = self._makeOne() dist.parse(u'Metadata-Version: 1.0\nName: lp722928_c3') # no raise def test_parse_Metadata_Version_1_0(self): from pkginfo.distribution import HEADER_ATTRS_1_0 dist = self._makeOne(None) dist.parse('Metadata-Version: 1.0') self.assertEqual(dist.metadata_version, '1.0') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_1_0]) def test_parse_Metadata_Version_1_1(self): from pkginfo.distribution import HEADER_ATTRS_1_1 dist = self._makeOne(None) dist.parse('Metadata-Version: 1.1') self.assertEqual(dist.metadata_version, '1.1') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_1_1]) def test_parse_Metadata_Version_1_2(self): from pkginfo.distribution import HEADER_ATTRS_1_2 dist = self._makeOne(None) dist.parse('Metadata-Version: 1.2') self.assertEqual(dist.metadata_version, '1.2') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_1_2]) def test_parse_Metadata_Version_2_1(self): from pkginfo.distribution import HEADER_ATTRS_2_1 dist = self._makeOne(None) dist.parse('Metadata-Version: 2.1') self.assertEqual(dist.metadata_version, '2.1') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_2_1]) def test_parse_Metadata_Version_2_2(self): from pkginfo.distribution import HEADER_ATTRS_2_2 dist = self._makeOne(None) dist.parse('Metadata-Version: 2.2') self.assertEqual(dist.metadata_version, '2.2') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_2_2]) def test_parse_Metadata_Version_2_3(self): from pkginfo.distribution import HEADER_ATTRS_2_3 dist = self._makeOne(None) dist.parse('Metadata-Version: 2.3') self.assertEqual(dist.metadata_version, '2.3') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_2_3]) def test_parse_Metadata_Version_unknown(self): dist = self._makeOne(None) dist.parse('Metadata-Version: 1.3') self.assertEqual(dist.metadata_version, '1.3') self.assertEqual(list(dist), []) def test_parse_Metadata_Version_override(self): dist = self._makeOne('1.2') dist.parse('Metadata-Version: 1.0') self.assertEqual(dist.metadata_version, '1.2') def test_parse_Name(self): dist = self._makeOne() dist.parse('Name: foobar') self.assertEqual(dist.name, 'foobar') def test_parse_Version(self): dist = self._makeOne() dist.parse('Version: 2.1.3b5') self.assertEqual(dist.version, '2.1.3b5') def test_parse_Platform_single(self): dist = self._makeOne() dist.parse('Platform: Plan9') self.assertEqual(list(dist.platforms), ['Plan9']) def test_parse_Platform_multiple(self): dist = self._makeOne() dist.parse('Platform: Plan9\nPlatform: AIX') self.assertEqual(list(dist.platforms), ['Plan9', 'AIX']) def test_parse_Supported_Platform_single(self): dist = self._makeOne() dist.parse('Supported-Platform: Plan9') self.assertEqual(list(dist.supported_platforms), ['Plan9']) def test_parse_Supported_Platform_multiple(self): dist = self._makeOne() dist.parse('Supported-Platform: i386-win32\n' 'Supported-Platform: RedHat 7.2') self.assertEqual(list(dist.supported_platforms), ['i386-win32', 'RedHat 7.2']) def test_parse_Summary(self): dist = self._makeOne() dist.parse('Summary: Package for foo') self.assertEqual(dist.summary, 'Package for foo') def test_parse_Description(self): dist = self._makeOne() dist.parse('Description: This package enables integration with ' 'foo servers.') self.assertEqual(dist.description, 'This package enables integration with ' 'foo servers.') def test_parse_Description_multiline(self): dist = self._makeOne() dist.parse('Description: This package enables integration with\n' ' foo servers.') self.assertEqual(dist.description, 'This package enables integration with\n' 'foo servers.') def test_parse_Description_in_payload(self): dist = self._makeOne() dist.parse('Foo: Bar\n' '\n' 'This package enables integration with\n' 'foo servers.') self.assertEqual(dist.description, 'This package enables integration with\n' 'foo servers.') def test_parse_Keywords(self): dist = self._makeOne() dist.parse('Keywords: bar foo qux') self.assertEqual(dist.keywords, 'bar foo qux') def test_parse_Home_page(self): dist = self._makeOne() dist.parse('Home-page: http://example.com/package') self.assertEqual(dist.home_page, 'http://example.com/package') def test_parse_Author(self): dist = self._makeOne() dist.parse('Author: J. Phredd Bloggs') self.assertEqual(dist.author, 'J. Phredd Bloggs') def test_parse_Author_Email(self): dist = self._makeOne() dist.parse('Author-email: phreddy@example.com') self.assertEqual(dist.author_email, 'phreddy@example.com') def test_parse_License(self): dist = self._makeOne() dist.parse('License: Poetic') self.assertEqual(dist.license, 'Poetic') # Metadata version 1.1, defined in PEP 314. def test_parse_Classifier_single(self): dist = self._makeOne('1.1') dist.parse('Classifier: Some :: Silly Thing') self.assertEqual(list(dist.classifiers), ['Some :: Silly Thing']) def test_parse_Classifier_multiple(self): dist = self._makeOne('1.1') dist.parse('Classifier: Some :: Silly Thing\n' 'Classifier: Or :: Other') self.assertEqual(list(dist.classifiers), ['Some :: Silly Thing', 'Or :: Other']) def test_parse_Download_URL(self): dist = self._makeOne('1.1') dist.parse('Download-URL: ' 'http://example.com/package/mypackage-0.1.zip') self.assertEqual(dist.download_url, 'http://example.com/package/mypackage-0.1.zip') def test_parse_Requires_single_wo_version(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition') self.assertEqual(list(dist.requires), ['SpanishInquisition']) def test_parse_Requires_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition (>=1.3)') self.assertEqual(list(dist.requires), ['SpanishInquisition (>=1.3)']) def test_parse_Requires_multiple(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition\n' 'Requires: SillyWalks (1.4)\n' 'Requires: kniggits (>=2.3,<3.0)') self.assertEqual(list(dist.requires), ['SpanishInquisition', 'SillyWalks (1.4)', 'kniggits (>=2.3,<3.0)', ]) def test_parse_Provides_single_wo_version(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks') self.assertEqual(list(dist.provides), ['SillyWalks']) def test_parse_Provides_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks (1.4)') self.assertEqual(list(dist.provides), ['SillyWalks (1.4)']) def test_parse_Provides_multiple(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks\n' 'Provides: DeadlyJoke (3.1.4)') self.assertEqual(list(dist.provides), ['SillyWalks', 'DeadlyJoke (3.1.4)', ]) def test_parse_Obsoletes_single_no_version(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: SillyWalks') self.assertEqual(list(dist.obsoletes), ['SillyWalks']) def test_parse_Obsoletes_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: SillyWalks (<=1.3)') self.assertEqual(list(dist.obsoletes), ['SillyWalks (<=1.3)']) def test_parse_Obsoletes_multiple(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: kniggits\n' 'Obsoletes: SillyWalks (<=2.0)') self.assertEqual(list(dist.obsoletes), ['kniggits', 'SillyWalks (<=2.0)', ]) # Metadata version 1.2, defined in PEP 345. def test_parse_Maintainer(self): dist = self._makeOne(metadata_version='1.2') dist.parse('Maintainer: J. Phredd Bloggs') self.assertEqual(dist.maintainer, 'J. Phredd Bloggs') def test_parse_Maintainer_Email(self): dist = self._makeOne(metadata_version='1.2') dist.parse('Maintainer-email: phreddy@example.com') self.assertEqual(dist.maintainer_email, 'phreddy@example.com') def test_parse_Requires_Python_single_spec(self): dist = self._makeOne('1.2') dist.parse('Requires-Python: >2.4') self.assertEqual(dist.requires_python, '>2.4') def test_parse_Requires_External_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo') self.assertEqual(list(dist.requires_external), ['libfoo']) def test_parse_Requires_External_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo (>=1.3)') self.assertEqual(list(dist.requires_external), ['libfoo (>=1.3)']) def test_parse_Requires_External_multiple(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo\n' 'Requires-External: libbar (1.4)\n' 'Requires-External: libbaz (>=2.3,<3.0)') self.assertEqual(list(dist.requires_external), ['libfoo', 'libbar (1.4)', 'libbaz (>=2.3,<3.0)', ]) def test_parse_Requires_Dist_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Requires-Dist: SpanishInquisition') self.assertEqual(list(dist.requires_dist), ['SpanishInquisition']) def test_parse_Requires_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Requires-Dist: SpanishInquisition (>=1.3)') self.assertEqual(list(dist.requires_dist), ['SpanishInquisition (>=1.3)']) def test_parse_Requires_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Requires-Dist: SpanishInquisition; " "python_version == '1.4'") self.assertEqual(list(dist.requires_dist), ["SpanishInquisition; python_version == '1.4'"]) def test_parse_Requires_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Requires-Dist: SpanishInquisition\n" "Requires-Dist: SillyWalks; python_version == '1.4'\n" "Requires-Dist: kniggits (>=2.3,<3.0)") self.assertEqual(list(dist.requires_dist), ["SpanishInquisition", "SillyWalks; python_version == '1.4'", "kniggits (>=2.3,<3.0)", ]) def test_parse_Provides_Dist_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Provides-Dist: SillyWalks') self.assertEqual(list(dist.provides_dist), ['SillyWalks']) def test_parse_Provides_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Provides-Dist: SillyWalks (1.4)') self.assertEqual(list(dist.provides_dist), ['SillyWalks (1.4)']) def test_parse_Provides_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Provides-Dist: SillyWalks; sys.platform == 'os2'") self.assertEqual(list(dist.provides_dist), ["SillyWalks; sys.platform == 'os2'"]) def test_parse_Provides_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Provides-Dist: SillyWalks\n" "Provides-Dist: SpanishInquisition; sys.platform == 'os2'\n" "Provides-Dist: DeadlyJoke (3.1.4)") self.assertEqual(list(dist.provides_dist), ["SillyWalks", "SpanishInquisition; sys.platform == 'os2'", "DeadlyJoke (3.1.4)", ]) def test_parse_Obsoletes_Dist_single_no_version(self): dist = self._makeOne('1.2') dist.parse('Obsoletes-Dist: SillyWalks') self.assertEqual(list(dist.obsoletes_dist), ['SillyWalks']) def test_parse_Obsoletes_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Obsoletes-Dist: SillyWalks (<=1.3)') self.assertEqual(list(dist.obsoletes_dist), ['SillyWalks (<=1.3)']) def test_parse_Obsoletes_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Obsoletes-Dist: SillyWalks; sys.platform == 'os2'") self.assertEqual(list(dist.obsoletes_dist), ["SillyWalks; sys.platform == 'os2'"]) def test_parse_Obsoletes_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Obsoletes-Dist: kniggits\n" "Obsoletes-Dist: SillyWalks; sys.platform == 'os2'\n" "Obsoletes-Dist: DeadlyJoke (<=2.0)\n" ) self.assertEqual(list(dist.obsoletes_dist), ["kniggits", "SillyWalks; sys.platform == 'os2'", "DeadlyJoke (<=2.0)", ]) def test_parse_Project_URL_single_no_version(self): dist = self._makeOne('1.2') dist.parse('Project-URL: Bug tracker, http://bugs.example.com/grail') self.assertEqual(list(dist.project_urls), ['Bug tracker, http://bugs.example.com/grail']) def test_parse_Project_URL_multiple(self): dist = self._makeOne('1.2') dist.parse('Project-URL: Bug tracker, http://bugs.example.com/grail\n' 'Project-URL: Repository, http://svn.example.com/grail') self.assertEqual(list(dist.project_urls), ['Bug tracker, http://bugs.example.com/grail', 'Repository, http://svn.example.com/grail', ]) # Metadata version 2.1, defined in PEP 566. def test_parse_Provides_Extra_single(self): dist = self._makeOne('2.1') dist.parse('Provides-Extra: pdf') self.assertEqual(list(dist.provides_extras), ['pdf']) def test_parse_Provides_Extra_multiple(self): dist = self._makeOne('2.1') dist.parse('Provides-Extra: pdf\n' 'Provides-Extra: tex') self.assertEqual(list(dist.provides_extras), ['pdf', 'tex']) def test_parse_Distribution_Content_Type_single(self): dist = self._makeOne('2.1') dist.parse('Description-Content-Type: text/plain') self.assertEqual(dist.description_content_type, 'text/plain') # Metadata version 2.2, defined in PEP 643. def test_parse_Dynamic_single(self): dist = self._makeOne('2.2') dist.parse('Dynamic: Platforms') self.assertEqual(list(dist.dynamic), ['Platforms']) def test_parse_Dynamic_multiple(self): dist = self._makeOne('2.2') dist.parse('Dynamic: Platforms\n' 'Dynamic: Supported-Platforms') self.assertEqual(list(dist.dynamic), ['Platforms', 'Supported-Platforms']) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/test_index.py0000664000175000017500000000511400000000000020455 0ustar00tseavertseaverimport unittest class IndexTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.index import Index return Index def _makeOne(self): return self._getTargetClass()() def test_empty(self): index = self._makeOne() self.assertEqual(len(index), 0) self.assertEqual(len(index.keys()), 0) self.assertEqual(len(index.values()), 0) self.assertEqual(len(index.items()), 0) def _makeDummy(self): from pkginfo.distribution import Distribution class DummyDistribution(Distribution): name = 'dummy' version = '1.0' return DummyDistribution() def test___getitem___miss(self): index = self._makeOne() self.assertRaises(KeyError, index.__getitem__, 'nonesuch') def test___setitem___value_not_dist(self): class NotDistribution: name = 'dummy' version = '1.0' dummy = NotDistribution() index = self._makeOne() self.assertRaises(ValueError, index.__setitem__, 'dummy-1.0', dummy) def test___setitem___bad_key(self): index = self._makeOne() dummy = self._makeDummy() self.assertRaises(ValueError, index.__setitem__, 'nonesuch', dummy) def test___setitem___valid_key(self): index = self._makeOne() dummy = self._makeDummy() index['dummy-1.0'] = dummy self.assertTrue(index['dummy-1.0'] is dummy) self.assertEqual(len(index), 1) self.assertEqual(len(index.keys()), 1) self.assertEqual(list(index.keys())[0], 'dummy-1.0') self.assertEqual(len(index.values()), 1) self.assertEqual(list(index.values())[0], dummy) self.assertEqual(len(index.items()), 1) self.assertEqual(list(index.items())[0], ('dummy-1.0', dummy)) def test_add_not_dist(self): index = self._makeOne() class NotDistribution: name = 'dummy' version = '1.0' dummy = NotDistribution() self.assertRaises(ValueError, index.add, dummy) def test_add_valid_dist(self): index = self._makeOne() dummy = self._makeDummy() index.add(dummy) self.assertTrue(index['dummy-1.0'] is dummy) self.assertEqual(len(index), 1) self.assertEqual(len(index.keys()), 1) self.assertEqual(list(index.keys())[0], 'dummy-1.0') self.assertEqual(len(index.values()), 1) self.assertEqual(list(index.values())[0], dummy) self.assertEqual(len(index.items()), 1) self.assertEqual(list(index.items())[0], ('dummy-1.0', dummy)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709453054.0 pkginfo-1.10.0/pkginfo/tests/test_installed.py0000664000175000017500000001271200000000000021327 0ustar00tseavertseaverimport os import sys import types import unittest import wsgiref import warnings class InstalledTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.installed import Installed return Installed def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def test_ctor_w_package_no___file__(self): with warnings.catch_warnings(record=True): installed = self._makeOne(sys) self.assertEqual(installed.package, sys) self.assertEqual(installed.package_name, 'sys') self.assertEqual(installed.metadata_version, None) def test_ctor_w_package(self): import pkginfo from pkginfo.tests import _checkSample from pkginfo.tests import _defaultMetadataVersion EXPECTED = _defaultMetadataVersion() installed = self._makeOne(pkginfo) self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') self.assertEqual(installed.metadata_version, EXPECTED) _checkSample(self, installed) def test_ctor_w_no___package___falls_back_to___name__(self): with warnings.catch_warnings(record=True): installed = self._makeOne(wsgiref) self.assertEqual(installed.package, wsgiref) self.assertEqual(installed.package_name, 'wsgiref') self.assertEqual(installed.metadata_version, None) def test_ctor_w_package_no_PKG_INFO(self): with warnings.catch_warnings(record=True): installed = self._makeOne(types) self.assertEqual(installed.package, types) self.assertEqual(installed.package_name, 'types') self.assertEqual(installed.metadata_version, None) def test_ctor_w_package_and_metadata_version(self): import pkginfo from pkginfo.tests import _checkSample installed = self._makeOne(pkginfo, metadata_version='1.2') self.assertEqual(installed.metadata_version, '1.2') self.assertEqual(installed.package.__name__, 'pkginfo') _checkSample(self, installed) def test_ctor_w_name(self): import pkginfo from pkginfo.tests import _checkSample from pkginfo.tests import _defaultMetadataVersion EXPECTED = _defaultMetadataVersion() installed = self._makeOne('pkginfo') self.assertEqual(installed.metadata_version, EXPECTED) self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') _checkSample(self, installed) def test_ctor_w_name_and_metadata_version(self): import pkginfo from pkginfo.tests import _checkSample installed = self._makeOne('pkginfo', metadata_version='1.2') self.assertEqual(installed.metadata_version, '1.2') self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') _checkSample(self, installed) def test_ctor_w_invalid_name(self): with warnings.catch_warnings(record=True): installed = self._makeOne('nonesuch') self.assertEqual(installed.package, None) self.assertEqual(installed.package_name, 'nonesuch') self.assertEqual(installed.metadata_version, None) def test_ctor_w_egg_info_as_file(self): import pkginfo.tests.funny installed = self._makeOne('pkginfo.tests.funny') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, pkginfo.tests.funny) self.assertEqual(installed.package_name, 'pkginfo.tests.funny') def test_ctor_w_dist_info(self): import wheel installed = self._makeOne('wheel') self.assertEqual(installed.metadata_version, '2.1') self.assertEqual(installed.package, wheel) self.assertEqual(installed.package_name, 'wheel') def test_namespaced_pkg_installed_via_setuptools(self): where, _ = os.path.split(__file__) wonky = os.path.join(where, 'wonky') oldpath = sys.path[:] try: sys.path.append(wonky) with warnings.catch_warnings(record=True): import namespaced.wonky installed = self._makeOne('namespaced.wonky') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, namespaced.wonky) self.assertEqual(installed.package_name, 'namespaced.wonky') finally: sys.path[:] = oldpath sys.modules.pop('namespaced.wonky', None) sys.modules.pop('namespaced', None) def test_namespaced_pkg_installed_via_pth(self): # E.g., installed by a Linux distro where, _ = os.path.split(__file__) manky = os.path.join(where, 'manky') oldpath = sys.path[:] try: sys.path.append(manky) with warnings.catch_warnings(record=True): import namespaced.manky installed = self._makeOne('namespaced.manky') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, namespaced.manky) self.assertEqual(installed.package_name, 'namespaced.manky') finally: sys.path[:] = oldpath sys.modules.pop('namespaced.manky', None) sys.modules.pop('namespaced', None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454524.0 pkginfo-1.10.0/pkginfo/tests/test_sdist.py0000664000175000017500000001317700000000000020504 0ustar00tseavertseaverimport pathlib import shutil import sys import tempfile import unittest class SDistTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.sdist import SDist return SDist def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def _checkSample(self, sdist, filename): self.assertEqual(sdist.filename, filename) self.assertEqual(sdist.name, 'mypackage') self.assertEqual(sdist.version, '0.1') self.assertEqual(sdist.keywords, None) self.assertEqual(list(sdist.supported_platforms), []) def _checkClassifiers(self, sdist): self.assertEqual(list(sdist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) def test_ctor_w_invalid_filename(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nonesuch-0.1.tar.gz' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_wo_PKG_INFO(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nopkginfo-0.1.zip' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_tar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_gztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_gztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d sdist = self._makeOne(filename, metadata_version='1.1') self._checkSample(sdist, filename) self.assertEqual(sdist.metadata_version, '1.1') self._checkClassifiers(sdist) def test_ctor_w_bztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_bztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d sdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(sdist.metadata_version, '1.1') self._checkSample(sdist, filename) self._checkClassifiers(sdist) def test_ctor_w_zip(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_zip_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d sdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(sdist.metadata_version, '1.1') self._checkSample(sdist, filename) self._checkClassifiers(sdist) def test_ctor_w_bogus(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.bogus' % d with self.assertRaises(ValueError): self._makeOne(filename, metadata_version='1.1') class UnpackedMixin(object): def setUp(self): super(UnpackedMixin, self).setUp() self.__tmpdir = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.__tmpdir) super(UnpackedMixin, self).tearDown() def _getTargetClass(self): from pkginfo.sdist import UnpackedSDist return UnpackedSDist def _getTopDirectory(self): import os topnames = os.listdir(self.__tmpdir) assert len(topnames) == 1 return os.path.join(self.__tmpdir, topnames[0]) def _getLoadFilename(self): return self._getTopDirectory() def _makeOne(self, filename=None, metadata_version=None): archive, _, _ = self._getTargetClass()._get_archive(filename) # Work around Python 3.12 tarfile warning. kwargs = {} if sys.version_info >= (3, 12): fn_path = pathlib.Path(filename) if ".tar" in fn_path.suffixes: kwargs["filter"] = "data" try: archive.extractall(self.__tmpdir, **kwargs) finally: archive.close() load_filename = self._getLoadFilename() if metadata_version is not None: return self._getTargetClass()(load_filename, metadata_version) return self._getTargetClass()(load_filename) def _checkSample(self, sdist, filename): filename = self._getTopDirectory() super(UnpackedMixin, self)._checkSample(sdist, filename) class UnpackedSDistGivenDirectoryTests(UnpackedMixin, SDistTests): pass class UnpackedSDistGivenFileSDistTests(UnpackedMixin, SDistTests): def _getLoadFilename(self): import os return os.path.join(self._getTopDirectory(), 'setup.py') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/test_utils.py0000664000175000017500000001526300000000000020514 0ustar00tseavertseaverimport unittest class Test_get_metadata(unittest.TestCase): def _callFUT(self, path, metadata_version=None): from pkginfo.utils import get_metadata if metadata_version is not None: return get_metadata(path, metadata_version) return get_metadata(path) def _checkMyPackage(self, dist, filename): self.assertEqual(dist.filename, filename) self.assertEqual(dist.name, 'mypackage') self.assertEqual(dist.version, '0.1') self.assertEqual(dist.keywords, None) self.assertEqual(list(dist.supported_platforms), []) def _checkClassifiers(self, dist): self.assertEqual(list(dist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) def test_w_gztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_gztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_bztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_bztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_zip(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_zip_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_egg_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_wheel(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'mypackage-0.1-cp26-none-linux_x86_64.whl') % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '2.0') self._checkMyPackage(dist, filename) def test_w_wheel_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'mypackage-0.1-cp26-none-linux_x86_64.whl') % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_module(self): from pkginfo.tests import _defaultMetadataVersion EXPECTED = _defaultMetadataVersion() import pkginfo from pkginfo.tests import _checkSample dist = self._callFUT(pkginfo) self.assertEqual(dist.metadata_version, EXPECTED) _checkSample(self, dist) def test_w_module_and_metadata_version(self): import pkginfo from pkginfo.tests import _checkSample from pkginfo.tests import _checkClassifiers dist = self._callFUT(pkginfo, metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') _checkSample(self, dist) _checkClassifiers(self, dist) def test_w_package_name(self): from pkginfo.tests import _defaultMetadataVersion EXPECTED = _defaultMetadataVersion() from pkginfo.tests import _checkSample dist = self._callFUT('pkginfo') self.assertEqual(dist.metadata_version, EXPECTED) _checkSample(self, dist) def test_w_package_name_and_metadata_version(self): from pkginfo.tests import _checkSample from pkginfo.tests import _checkClassifiers dist = self._callFUT('pkginfo', metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') _checkSample(self, dist) _checkClassifiers(self, dist) def test_w_directory_no_EGG_INFO(self): import os import warnings dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'funny') old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: dist = self._callFUT(subdir) self.assertEqual(dist.path, subdir) self.assertEqual(dist.name, None) self.assertEqual(dist.version, None) finally: warnings.filters[:] = old_filters def test_w_directory(self): import os dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'silly') dist = self._callFUT(subdir) self.assertEqual(dist.metadata_version, '1.0') self.assertEqual(dist.name, 'silly') self.assertEqual(dist.version, '0.1') def test_w_directory_and_metadata_version(self): import os dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'silly') dist = self._callFUT(subdir, metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') self.assertEqual(dist.name, 'silly') self.assertEqual(dist.version, '0.1') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652971664.0 pkginfo-1.10.0/pkginfo/tests/test_wheel.py0000664000175000017500000001053300000000000020453 0ustar00tseavertseaverimport unittest class WheelTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.wheel import Wheel return Wheel def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def _checkSample(self, wheel, filename): self.assertEqual(wheel.filename, filename) self.assertEqual(wheel.name, 'mypackage') self.assertEqual(wheel.version, '0.1') self.assertEqual(wheel.keywords, None) def _checkClassifiers(self, wheel): self.assertEqual(list(wheel.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) self.assertEqual(list(wheel.supported_platforms), []) def test_ctor_w_bogus_filename(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nonesuch-0.1-any.whl' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_non_wheel(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_wo_dist_info(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nodistinfo-0.1-any.whl' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_valid_wheel(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'mypackage-0.1-cp26-none-linux_x86_64.whl') % d wheel = self._makeOne(filename) self.assertEqual(wheel.metadata_version, '2.0') self._checkSample(wheel, filename) self._checkClassifiers(wheel) def test_ctor_w_installed_wheel(self): import os d, _ = os.path.split(__file__) filename = ( '%s/../../docs/examples/mypackage-0.1.dist-info') % d wheel = self._makeOne(filename) self.assertEqual(wheel.metadata_version, '2.0') self._checkSample(wheel, filename) self._checkClassifiers(wheel) def test_ctor_w_valid_wheel_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'mypackage-0.1-cp26-none-linux_x86_64.whl') % d wheel = self._makeOne(filename, metadata_version='1.1') self.assertEqual(wheel.metadata_version, '1.1') self._checkSample(wheel, filename) self._checkClassifiers(wheel) def test_ctor_w_valid_wheel_w_description_header(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'distlib-0.3.1-py2.py3-none-any.whl') % d wheel = self._makeOne(filename, metadata_version='1.1') self.assertEqual(wheel.metadata_version, '1.1') self.assertTrue(wheel.description) def test_ctor_w_valid_wheel_w_description_body(self): import os d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'testlp1974172-0.0.0-py3-none-any.whl') % d wheel = self._makeOne(filename, metadata_version='2.1') self.assertEqual(wheel.metadata_version, '2.1') self.assertIn( "https://bugs.launchpad.net/pkginfo/+bug/1885458", wheel.description ) def test_ctor_w_valid_installed_wheel(self): import os import shutil import tempfile import zipfile d, _ = os.path.split(__file__) filename = ('%s/../../docs/examples/' 'mypackage-0.1-cp26-none-linux_x86_64.whl') % d try: # note: we mock a wheel installation by unzipping test_dir = tempfile.mkdtemp() with zipfile.ZipFile(filename) as zipf: zipf.extractall(test_dir) wheel = self._makeOne(filename) self.assertEqual(wheel.metadata_version, '2.0') self._checkSample(wheel, filename) self._checkClassifiers(wheel) finally: if os.path.exists(test_dir): shutil.rmtree(test_dir) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/wonky/0000775000175000017500000000000000000000000017103 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/wonky/EGG-INFO/0000775000175000017500000000000000000000000020236 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/wonky/EGG-INFO/PKG-INFO0000664000175000017500000000005500000000000021333 0ustar00tseavertseaverMetadata-Version: 1.0 Name: namespaced.wonky ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/wonky/NOT-A-PACKAGE.txt0000664000175000017500000000022000000000000021505 0ustar00tseavertseaverTHIS IS NOT A PYTHON PACKAGE!!!! It is meant to be added to sys.path for testing introspection of namespace packages installed via setuptools. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/wonky/namespaced/0000775000175000017500000000000000000000000021203 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1652969876.0 pkginfo-1.10.0/pkginfo/tests/wonky/namespaced/__init__.py0000664000175000017500000000033400000000000023314 0ustar00tseavertseaver# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: # pragma: NO COVER import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/pkginfo/tests/wonky/namespaced/wonky/0000775000175000017500000000000000000000000022352 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795550.0 pkginfo-1.10.0/pkginfo/tests/wonky/namespaced/wonky/__init__.py0000664000175000017500000000006300000000000024462 0ustar00tseavertseaver# Dummy package inside the 'namespaced' namespace. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795586.0 pkginfo-1.10.0/pkginfo/utils.py0000664000175000017500000000337200000000000016311 0ustar00tseavertseaverimport os from types import ModuleType from .bdist import BDist from .develop import Develop from .installed import Installed from .sdist import SDist from .wheel import Wheel def get_metadata(path_or_module, metadata_version=None): """ Try to create a Distribution 'path_or_module'. o 'path_or_module' may be a module object. o If a string, 'path_or_module' may point to an sdist file, a bdist file, an installed package, or a working checkout (if it contains PKG-INFO). o Return None if 'path_or_module' can't be parsed. """ if isinstance(path_or_module, ModuleType): try: return Installed(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass try: __import__(path_or_module) except ImportError: pass else: try: return Installed(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass if os.path.isfile(path_or_module): try: return SDist(path_or_module, metadata_version) except (ValueError, IOError): pass try: return BDist(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass try: return Wheel(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass if os.path.isdir(path_or_module): try: return Wheel(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass try: return Develop(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020398.0 pkginfo-1.10.0/pkginfo/utils.pyi0000664000175000017500000000025700000000000016461 0ustar00tseavertseaverimport types from .distribution import Distribution def get_metadata(path_or_module: str | types.ModuleType, metadata_version: str | None = ...) -> Distribution | None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1669747427.0 pkginfo-1.10.0/pkginfo/wheel.py0000664000175000017500000000306200000000000016251 0ustar00tseavertseaverimport io import os import zipfile from .distribution import Distribution from .distribution import parse class Wheel(Distribution): def __init__(self, filename, metadata_version=None): self.filename = filename self.metadata_version = metadata_version self.extractMetadata() def read(self): fqn = os.path.abspath(os.path.normpath(self.filename)) if not os.path.exists(fqn): raise ValueError('No such file: %s' % fqn) if fqn.endswith('.whl'): archive = zipfile.ZipFile(fqn) names = archive.namelist() def read_file(name): return archive.read(name) close = archive.close elif fqn.endswith('.dist-info'): names = [os.path.join(fqn, p) for p in os.listdir(fqn)] def read_file(name): with io.open(name, mode='rb') as inf: return inf.read() close = lambda : None else: raise ValueError('Not a known wheel archive format or ' 'installed .dist-info: %s' % fqn) try: tuples = [x.split('/') for x in names if 'METADATA' in x] schwarz = sorted([(len(x), x) for x in tuples]) for path in [x[1] for x in schwarz]: candidate = '/'.join(path) data = read_file(candidate) if b'Metadata-Version' in data: return data finally: close() raise ValueError('No METADATA in archive: %s' % fqn) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1673020090.0 pkginfo-1.10.0/pkginfo/wheel.pyi0000664000175000017500000000040700000000000016422 0ustar00tseavertseaverfrom .distribution import Distribution as Distribution, parse as parse class Wheel(Distribution): filename: str metadata_version: str def __init__(self, filename: str, metadata_version: str | None = ...) -> None: ... def read(self) -> bytes: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7677972 pkginfo-1.10.0/pkginfo.egg-info/0000775000175000017500000000000000000000000016264 5ustar00tseavertseaver././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/PKG-INFO0000644000175000017500000002556400000000000017373 0ustar00tseavertseaverMetadata-Version: 2.1 Name: pkginfo Version: 1.10.0 Summary: Query metadata from sdists / bdists / installed packages. Home-page: https://code.launchpad.net/~tseaver/pkginfo/trunk Author: Tres Seaver, Agendaless Consulting Author-email: tseaver@agendaless.com License: MIT Keywords: distribution sdist installed metadata Platform: Unix Platform: Windows Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Software Distribution Requires-Python: >=3.6 License-File: LICENSE.txt Provides-Extra: testing Requires-Dist: pytest; extra == "testing" Requires-Dist: pytest-cov; extra == "testing" Requires-Dist: wheel; extra == "testing" ``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distribution (an ``sdist``) or a binary distribution (e.g., created by running ``bdist_egg``). It can also query the ``EGG-INFO`` directory of an installed distribution, and the ``*.egg-info`` stored in a "development checkout" (e.g, created by running ``setup.py develop``). Please see the `pkginfo docs `_ for detailed documentation. ``pkginfo`` Changelog ===================== 1.10.0 (2024-03-03) ------------------- - Add support for Python 3.11 and 3.12. - Drop support for Python 3.6. - Declare explicit testing dependency on 'wheel'. - Add support for Metadata 2.3. 1.9.6 (2023-01-08) ------------------ - Fix various typos in docs / docstrings. LP #2002232. 1.9.5 (2023-01-06) ------------------ - Add stricter typing checks, matching those used in 'twine'. - Fix typing errors / gaps reported from 'twine' CI failure. LP #2002104. 1.9.4 (2023-01-05) ------------------ - Fix packaging of stub file for Python typing support. 1.9.3 (2023-01-03) ------------------ - Added stub files for Python typing support; verify using 'mypy'. LP #1876591. 1.9.2 (2022-11-29) ------------------ - Drop "universal" wheel support (should be redundant with 'python_requires >= 3.6', but just in case). LP #1998258. 1.9.1 (2022-11-29) ------------------ - Restore a deprecated alias for the '_must_decode' helper function, moved from 'pkginfo._compat.must_decode' to 'pkginfo.distribution._must_decode' in 1.90. - Repair unit tests broken by dropping Python 2.7 classifier. 1.9.0 (2022-11-29) ------------------ - Drop support for Python 2.7. - Switch to use 'pytest' vs. 'nose', which doesn't support Python > 3.9. 1.8.3 (2022-06-08) ------------------ - Specify supported Python versions in 'setup.py' using 'python_requires'. LP #1977981. 1.8.2 (2021-12-01) ------------------ - Add fix for installed distributions with '__package__' set to an empty string. LP #1952946. 1.8.1 (2021-11-19) ------------------ - Add 'MANIFEST.in' to ensure example files used by tests are included in source distributions. LP #1951553. 1.8.0 (2021-11-18) ------------------ - Support new standard metadata location for installed dists. LP #1865286. - Don't overwrite header-based 'description' with empty payload. LP #1885458. - Add support for Metadata-Version 2.2. LP #1928729. - Add support for uncompressed tarballs for sdists. LP #1951457. - Add support for Python 3.10. 1.7.1 (2021-07-09) ------------------ - Use Python3 to build docs, and fix doctest examples to use Python3- compatible syntax. LP #1933322. 1.7.0 (2021-01-16) ------------------ - Add support for Python 3.9. - Drop support for Python 3.5. 1.6.1 (2020-10-26) ------------------ - Adjust test classifiers to match supported Python versions. LP #1901127. 1.6.0 (2020-10-20) ------------------ - Add support for Python 3.8. LP #1869854. - Drop support for Python 3.4. - Update tests to match setuptools' change, no longer reporting metadata version for installed packages w/o explicit metadata. LP #1870197. 1.5.0.1 (2019-01-08) -------------------- - Fix broken 'sdist'. LP #1639585. 1.5.0 (2019-01-07) ------------------ - Fix 'console_scripts' entry point syntax. LP #1810734. - Add support for JSON output from the CLI. LP #1700580. - Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200. - Harden metadata extraction against unexpected encodings. LP #1780454. - Update tests to match pip/setuptools' use of new metadata version. LP #1772274. - Add support for Python 3.6 and 3.7. - Drop support for Python 3.3. 1.4.2 (2018-03-14) ------------------ - Use relative imports in pkginfo modules. Supports vendoring of the package into setuptools. - Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields. Per https://packaging.python.org/specifications/. See: PEP 566. - Remove support for old setuptools leaving ``PKG-INFO`` in the root of the project directory. 1.4.1 (2016-11-07) ------------------ - Packaging only change (invalid sdist built for 1.4.0). 1.4.0 (2016-11-04) ------------------ - Relicense under MIT license: the PSF license is not suitable for third-party libraries. 1.3.2 (2016-05-24) ------------------ - Packaging-only change (automate fix for wheel built for 1.3.1). 1.3.1 (2016-05-24) ------------------ - Packaging-only change (invalid wheel built for 1.3.0). 1.3.0 (2016-05-23) ------------------ - Update homepage URL to point to Launchpad, rather than PyPI. - Add support for building wheels. - Add support for Python 3.5. - Drop support for Python 2.6 and 3.2. 1.2.1 (2014-01-02) ------------------ - Add overlooked Trove classifier for Python 3.4. 1.2 (2014-01-02) ---------------- - Add support for Python 3.4, PyPy3. - Add 100% coverage for ``pkginfo.commandline`` module. 1.2b1 (2013-12-05) ------------------ - Add support for the "wheel" distribution format, along with minimal metadata 2.0 support (not including new PEP 426 JSON properties). Code (re-)borrowed from Donald Stuft's ``twine`` package. 1.1 (2013-10-09) ---------------- - Fix tests to pass with current PyPy releases. 1.1b1 (2013-05-05) ------------------ - Support "develop" packages which keep their ``*.egg-info`` in a subdirectory. See https://bugs.launchpad.net/pkginfo/+bug/919147. - Add support for "unpacked SDists" (thanks to Mike Lundy for the patch). 1.0 (2013-05-05) ---------------- - No changes from 1.0b2. 1.0b2 (2012-12-28) ------------------ - Suppress resource warning leaks reported against clients. - Fix 'commandline' module under Py3k. 1.0b1 (2012-12-28) ------------------ - Add support for Python 3.2 and 3.3, including testing them under ``tox``. - Add support for PyPy, including testing it under ``tox``. - Test supported Python versions under ``tox``. - Drop support for Python 2.5. - Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs testing extras (``nose`` and ``coverage``). 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fix bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replace use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Remove bogus testing dependency on ``zope.testing``. - Add tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Add ``Project-URL`` for ``1.2`` PKG-INFO metadata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fix Trove metadata misspelling. - Restore compatibility with Python 2.4. - Note that the introspection of installed packages / modules works only in Python 2.6 or later. - Add ``Index`` class as an abstraction over a collection of distributions. - Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fix bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extend the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Add support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Add support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Add a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Add ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Make distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Add support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fix packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/SOURCES.txt0000664000175000017500000000475600000000000020164 0ustar00tseavertseaver.bzrignore .coveragerc CHANGES.txt LICENSE.txt MANIFEST.in README.txt TODO.txt setup.cfg setup.py tox.ini docs/Makefile docs/conf.py docs/distributions.rst docs/index.rst docs/indexes.rst docs/metadata.rst docs/examples/distlib-0.3.1-py2.py3-none-any.whl docs/examples/mypackage-0.1-cp26-none-linux_x86_64.whl docs/examples/mypackage-0.1-py2.6.egg docs/examples/mypackage-0.1.bogus docs/examples/mypackage-0.1.tar docs/examples/mypackage-0.1.tar.bz2 docs/examples/mypackage-0.1.tar.gz docs/examples/mypackage-0.1.zip docs/examples/nodistinfo-0.1-any.whl docs/examples/nopkginfo-0.1.egg docs/examples/nopkginfo-0.1.zip docs/examples/testlp1974172-0.0.0-py3-none-any.whl docs/examples/mypackage-0.1/PKG-INFO docs/examples/mypackage-0.1/README.txt docs/examples/mypackage-0.1/setup.cfg docs/examples/mypackage-0.1/setup.py docs/examples/mypackage-0.1.dist-info/METADATA docs/examples/testlp1974172/setup.py docs/examples/testlp1974172/testlp1974172.egg-info/PKG-INFO docs/examples/testlp1974172/testlp1974172.egg-info/SOURCES.txt docs/examples/testlp1974172/testlp1974172.egg-info/dependency_links.txt docs/examples/testlp1974172/testlp1974172.egg-info/top_level.txt pkginfo/__init__.py pkginfo/__init__.pyi pkginfo/bdist.py pkginfo/bdist.pyi pkginfo/commandline.py pkginfo/commandline.pyi pkginfo/develop.py pkginfo/develop.pyi pkginfo/distribution.py pkginfo/distribution.pyi pkginfo/index.py pkginfo/index.pyi pkginfo/installed.py pkginfo/installed.pyi pkginfo/py.typed pkginfo/sdist.py pkginfo/sdist.pyi pkginfo/utils.py pkginfo/utils.pyi pkginfo/wheel.py pkginfo/wheel.pyi pkginfo.egg-info/PKG-INFO pkginfo.egg-info/SOURCES.txt pkginfo.egg-info/dependency_links.txt pkginfo.egg-info/entry_points.txt pkginfo.egg-info/not-zip-safe pkginfo.egg-info/requires.txt pkginfo.egg-info/top_level.txt pkginfo/tests/__init__.py pkginfo/tests/test_bdist.py pkginfo/tests/test_commandline.py pkginfo/tests/test_develop.py pkginfo/tests/test_distribution.py pkginfo/tests/test_index.py pkginfo/tests/test_installed.py pkginfo/tests/test_sdist.py pkginfo/tests/test_utils.py pkginfo/tests/test_wheel.py pkginfo/tests/funny/__init__.py pkginfo/tests/funny/funny.egg-info pkginfo/tests/manky/NOT-A-PACKAGE.txt pkginfo/tests/manky/namespaced/__init__.py pkginfo/tests/manky/namespaced.manky-0.1.egg-info/PKG-INFO pkginfo/tests/manky/namespaced/manky/__init__.py pkginfo/tests/silly/PKG-INFO pkginfo/tests/wonky/NOT-A-PACKAGE.txt pkginfo/tests/wonky/EGG-INFO/PKG-INFO pkginfo/tests/wonky/namespaced/__init__.py pkginfo/tests/wonky/namespaced/wonky/__init__.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/dependency_links.txt0000664000175000017500000000000100000000000022332 0ustar00tseavertseaver ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/entry_points.txt0000664000175000017500000000006500000000000021563 0ustar00tseavertseaver[console_scripts] pkginfo = pkginfo.commandline:main ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1534795612.0 pkginfo-1.10.0/pkginfo.egg-info/not-zip-safe0000664000175000017500000000000100000000000020512 0ustar00tseavertseaver ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/requires.txt0000664000175000017500000000004300000000000020661 0ustar00tseavertseaver [testing] pytest pytest-cov wheel ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454837.0 pkginfo-1.10.0/pkginfo.egg-info/top_level.txt0000664000175000017500000000001000000000000021005 0ustar00tseavertseaverpkginfo ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709454837.7717974 pkginfo-1.10.0/setup.cfg0000664000175000017500000000102400000000000014753 0ustar00tseavertseaver[easy_install] zip_ok = false [aliases] dev = develop easy_install pkginfo[testing] [mypy] packages = pkginfo exclude = tests warn_redundant_casts = True warn_unused_configs = True warn_unused_ignores = True disallow_any_generics = True disallow_untyped_calls = True disallow_untyped_defs = True disallow_incomplete_defs = True check_untyped_defs = True disallow_untyped_decorators = True no_implicit_optional = True warn_return_any = True no_implicit_reexport = True strict_equality = True [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454793.0 pkginfo-1.10.0/setup.py0000664000175000017500000000354700000000000014660 0ustar00tseavertseaverimport os try: from setuptools import setup except ImportError: from distutils.core import setup extras = {} else: extras = { 'test_suite': 'pkginfo.tests', 'zip_safe': False, 'extras_require': { 'testing': ['pytest', 'pytest-cov', 'wheel'], }, } here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() setup( name='pkginfo', version='1.10.0', description='Query metadata from sdists / bdists / installed packages.', platforms=['Unix', 'Windows'], long_description='\n\n'.join([README, CHANGES]), keywords='distribution sdist installed metadata', url='https://code.launchpad.net/~tseaver/pkginfo/trunk', author='Tres Seaver, Agendaless Consulting', author_email='tseaver@agendaless.com', license='MIT', classifiers=[ 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Software Distribution', ], entry_points={ 'console_scripts': [ 'pkginfo = pkginfo.commandline:main', ] }, packages=['pkginfo', 'pkginfo.tests'], package_data={'pkginfo': ['py.typed', '*.pyi']}, python_requires='>=3.6', **extras ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709454613.0 pkginfo-1.10.0/tox.ini0000664000175000017500000000157500000000000014460 0ustar00tseavertseaver[tox] envlist = clean,py37,py38,py39,py310,py311,py312,pypy3,cover,docs,mypy [testenv:clean] basepython = python3.10 deps = commands = python -c "import os; os.path.exists('.coverage') and os.remove('.coverage')" [testenv] usedevelop = true commands = pytest --cov=pkginfo --cov-append --cov-report= deps = wheel pytest pytest-cov [testenv:py37] deps = {[testenv]deps} importlib_metadata [testenv:cover] basepython = python3.10 commands = coverage report --fail-under=100 deps = coverage [testenv:docs] basepython = python3.10 commands = sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest deps = Sphinx [testenv:mypy] usedevelop = true basepython = python3.10 commands = mypy deps = mypy==0.991 types-setuptools