diff --git a/.azure-pipelines/steps/build-package.yml b/.azure-pipelines/steps/build-package.yml
deleted file mode 100644
index 81a6160b..00000000
--- a/.azure-pipelines/steps/build-package.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-steps:
-- task: UsePythonVersion@0
- inputs:
- versionSpec: $(python.version)
- architecture: '$(python.architecture)'
- addToPath: true
- displayName: Use Python $(python.version)
-
-- template: install-dependencies.yml
-
-- script: |
- echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
- env:
- PYTHON_VERSION: $(python.version)
-
-- template: create-virtualenv.yml
- parameters:
- python_version: $(python.version)
-
-- script: |
- python -m pip install --upgrade wheel pip setuptools twine readme_renderer[md]
- python setup.py sdist bdist_wheel
- twine check dist/*
- displayName: Build and check package
- env:
- PY_EXE: $(PY_EXE)
- GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)
- LANG: $(LANG)
- PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION)
- PYTHONWARNINGS: ignore:DEPRECATION
- PIPENV_NOSPIN: '1'
diff --git a/.azure-pipelines/steps/create-virtualenv.yml b/.azure-pipelines/steps/create-virtualenv.yml
deleted file mode 100644
index 5f6160c4..00000000
--- a/.azure-pipelines/steps/create-virtualenv.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-parameters:
- python_version: ''
-
-steps:
-
-- script: |
- echo "##vso[task.setvariable variable=LANG]C.UTF-8"
- echo "##vso[task.setvariable variable=PIP_PROCESS_DEPENDENCY_LINKS]1"
- displayName: Set Environment Variables
-
-- ${{ if eq(parameters.vmImage, 'windows-2019') }}:
- - powershell: |
- pip install certifi
- $env:PYTHON_PATH=$(python -c "import sys; print(sys.executable)")
- $env:CERTIFI_CONTENT=$(python -m certifi)
- echo "##vso[task.setvariable variable=GIT_SSL_CAINFO]$env:CERTIFI_CONTENT"
- echo "##vso[task.setvariable variable=PY_EXE]$env:PYTHON_PATH"
- displayName: Set Python Path
- env:
- PYTHONWARNINGS: 'ignore:DEPRECATION'
-- ${{ if ne(parameters.vmImage, 'windows-2019') }}:
- - bash: |
- pip install certifi
- PYTHON_PATH=$(python -c 'import sys; print(sys.executable)')
- CERTIFI_CONTENT=$(python -m certifi)
- echo "##vso[task.setvariable variable=GIT_SSL_CAINFO]$CERTIFI_CONTENT"
- echo "##vso[task.setvariable variable=PY_EXE]$PYTHON_PATH"
- displayName: Set Python Path
- env:
- PYTHONWARNINGS: 'ignore:DEPRECATION'
-
-- script: |
- echo "Python path: $(PY_EXE)"
- echo "GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)"
- echo "PIPENV PYTHON VERSION: $(python.version)"
- echo "python_version: ${{ parameters.python_version }}"
- git submodule sync
- git submodule update --init --recursive
- $(PY_EXE) -m pipenv install --deploy --dev --python="$(PY_EXE)"
- env:
- PIPENV_DEFAULT_PYTHON_VERSION: ${{ parameters.python_version }}
- PYTHONWARNINGS: 'ignore:DEPRECATION'
- PIPENV_NOSPIN: '1'
- displayName: Make Virtualenv
diff --git a/.azure-pipelines/steps/install-dependencies.yml b/.azure-pipelines/steps/install-dependencies.yml
deleted file mode 100644
index 79684d4a..00000000
--- a/.azure-pipelines/steps/install-dependencies.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-steps:
-- script: 'python -m pip install --upgrade pip setuptools wheel -e .[dev,tests] --upgrade'
- displayName: Upgrade Pip & Install Pipenv
- env:
- PYTHONWARNINGS: 'ignore:DEPRECATION'
diff --git a/.azure-pipelines/steps/reinstall-pythons.yml b/.azure-pipelines/steps/reinstall-pythons.yml
deleted file mode 100644
index 79647925..00000000
--- a/.azure-pipelines/steps/reinstall-pythons.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-steps:
- - script: |
- # When you paste this, please make sure the indentation is preserved
- # Fail out if any setups fail
- set -e
-
- # Delete old Pythons
- rm -rf $AGENT_TOOLSDIRECTORY/Python/2.7.16
- rm -rf $AGENT_TOOLSDIRECTORY/Python/3.5.7
- rm -rf $AGENT_TOOLSDIRECTORY/Python/3.7.3
- [ -e $AGENT_TOOLSDIRECTORY/Python/3.7.2 ] && [ -e $AGENT_TOOLSDIRECTORY/Python/3.5.5 ] && [ -e $AGENT_TOOLSDIRECTORY/Python/2.7.15 ] && exit 0
- # Download new Pythons
- azcopy --recursive \
- --source https://vstsagenttools.blob.core.windows.net/tools/hostedtoolcache/linux/Python/2.7.15 \
- --destination $AGENT_TOOLSDIRECTORY/Python/2.7.15
-
- azcopy --recursive \
- --source https://vstsagenttools.blob.core.windows.net/tools/hostedtoolcache/linux/Python/3.5.5 \
- --destination $AGENT_TOOLSDIRECTORY/Python/3.5.5
-
- azcopy --recursive \
- --source https://vstsagenttools.blob.core.windows.net/tools/hostedtoolcache/linux/Python/3.7.2 \
- --destination $AGENT_TOOLSDIRECTORY/Python/3.7.2
-
- # Install new Pythons
- original_directory=$PWD
- setups=$(find $AGENT_TOOLSDIRECTORY/Python -name setup.sh)
- for setup in $setups; do
- chmod +x $setup;
- cd $(dirname $setup);
- ./$(basename $setup);
- cd $original_directory;
- done;
- displayName: 'Workaround: roll back Python versions'
diff --git a/.azure-pipelines/steps/run-tests-linux.yml b/.azure-pipelines/steps/run-tests-linux.yml
deleted file mode 100644
index 185a83b2..00000000
--- a/.azure-pipelines/steps/run-tests-linux.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-parameters:
- python_version: ''
-
-steps:
-- script: |
- # Fix Git SSL errors
- echo "Using pipenv python version: $(PIPENV_DEFAULT_PYTHON_VERSION)"
- git submodule sync && git submodule update --init --recursive
- pipenv run pytest --junitxml=test-results.xml
- displayName: Run integration tests
- env:
- PYTHONWARNINGS: ignore:DEPRECATION
- PIPENV_NOSPIN: '1'
- PIPENV_DEFAULT_PYTHON_VERSION: ${{ parameters.python_version }}
diff --git a/.azure-pipelines/steps/run-tests-windows.yml b/.azure-pipelines/steps/run-tests-windows.yml
deleted file mode 100644
index 1730fa14..00000000
--- a/.azure-pipelines/steps/run-tests-windows.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-parameters:
- python_version: ''
-
-steps:
-- powershell: |
- subst T: "$env:TEMP"
- Write-Host "##vso[task.setvariable variable=TEMP]T:\"
- Write-Host "##vso[task.setvariable variable=TMP]T:\"
- Write-Host "##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]$env:PYTHON_VERSION"
- Write-Host "##vso[task.setvariable variable=PIPENV_NOSPIN]1"
- displayName: Fix Temp Variable
- env:
- PYTHON_VERSION: ${{ parameters.python_version }}
-
-- script: |
- git submodule sync && git submodule update --init --recursive
- pipenv run pytest -ra --ignore=pipenv\patched --ignore=pipenv\vendor --junitxml=test-results.xml tests
- displayName: Run integration tests
- env:
- PYTHONWARNINGS: 'ignore:DEPRECATION'
- PIPENV_NOSPIN: '1'
diff --git a/.azure-pipelines/steps/run-tests.yml b/.azure-pipelines/steps/run-tests.yml
deleted file mode 100644
index 011cecf2..00000000
--- a/.azure-pipelines/steps/run-tests.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-steps:
-- task: UsePythonVersion@0
- inputs:
- versionSpec: $(python.version)
- architecture: '$(python.architecture)'
- addToPath: true
- displayName: Use Python $(python.version)
-
-- template: install-dependencies.yml
-
-- script: |
- echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
- env:
- PYTHON_VERSION: $(python.version)
-
-- template: create-virtualenv.yml
- parameters:
- python_version: $(python.version)
-
-- ${{ if eq(parameters.vmImage, 'windows-2019') }}:
- - template: run-tests-windows.yml
- parameters:
- python_version: $(python.version)
-- ${{ if ne(parameters.vmImage, 'windows-2019') }}:
- - template: run-tests-linux.yml
- parameters:
- python_version: $(python.version)
-
-- task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFiles: '**/test-results.xml'
- testRunTitle: 'Python $(python.version)'
- condition: succeededOrFailed()
diff --git a/.azure-pipelines/steps/run-vendor-scripts.yml b/.azure-pipelines/steps/run-vendor-scripts.yml
deleted file mode 100644
index 2aca1fe0..00000000
--- a/.azure-pipelines/steps/run-vendor-scripts.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-parameters:
- python_version: ''
-
-steps:
-- task: UsePythonVersion@0
- inputs:
- versionSpec: $(python.version)
- architecture: '$(python.architecture)'
- addToPath: true
- displayName: Use Python $(python.version)
-
-- template: install-dependencies.yml
-
-- script: |
- echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
- env:
- PYTHON_VERSION: $(python.version)
-
-- template: create-virtualenv.yml
- parameters:
- python_version: $(python.version)
-
-- script: |
- python -m pip install --upgrade invoke requests parver bs4 vistir towncrier pip setuptools wheel --upgrade-strategy=eager
- python -m invoke vendoring.update
- displayName: Run Vendor Scripts
- env:
- PY_EXE: $(PY_EXE)
- GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)
- LANG: $(LANG)
- PIPENV_DEFAULT_PYTHON_VERSION: '${{ parameters.python_version }}'
- PYTHONWARNINGS: ignore:DEPRECATION
- PIPENV_NOSPIN: '1'
diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml
deleted file mode 100644
index 46b2e799..00000000
--- a/.buildkite/pipeline.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-steps:
- - label: ":python:"
- commands:
- # - make
- - ./run-tests.sh
\ No newline at end of file
diff --git a/.buildkite/project.json b/.buildkite/project.json
deleted file mode 100644
index c6b1b270..00000000
--- a/.buildkite/project.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "Pipenv Test Suite",
- "steps": [
- {
- "type": "script",
- "name": ":pipeline:",
- "command": "buildkite-agent pipeline upload"
- }
- ]
-}
\ No newline at end of file
diff --git a/.deepsource.toml b/.deepsource.toml
new file mode 100644
index 00000000..902f3dc2
--- /dev/null
+++ b/.deepsource.toml
@@ -0,0 +1,16 @@
+version = 1
+
+test_patterns = ["tests/**"]
+
+exclude_patterns = [
+ "examples/**",
+ "pipenv/vendor/**",
+ "pipenv/patched/**"
+]
+
+[[analyzers]]
+name = "python"
+enabled = true
+
+ [analyzers.meta]
+ runtime_version = "3.x.x"
diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index c9efdaea..00000000
--- a/.dockerignore
+++ /dev/null
@@ -1,11 +0,0 @@
-./examples
-./tests
-./docs
-./news
-./pipenv
-./.git
-./.buildkite
-./peeps
-./.github
-./tasks
-./.azure-pipelines
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 18e12434..00000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Be sure to check the existing issues (both open and closed!), and make sure you are running the latest version of Pipenv.
-
-If you're requesting a new feature, please use the PEEP process:
-
- https://github.com/pypa/pipenv/blob/master/peeps/PEEP-000.md
-
-Check the [diagnose documentation](https://docs.pipenv.org/diagnose/) for common issues before posting! We may close your issue if it is very similar to one of them. Please be considerate, or be on your way.
-
-Make sure to mention your debugging experience if the documented solution failed.
-
-
-### Issue description
-
-Describe the issue briefly here.
-
-### Expected result
-
-Describe what you expected.
-
-### Actual result
-
-When possible, provide the verbose output (`--verbose`), especially for locking and dependencies resolving issues.
-
-### Steps to replicate
-
-Provide the steps to replicate (which usually at least includes the commands and the Pipfile).
-
--------------------------------------------------------------------------------
-
-Please run `$ pipenv --support`, and paste the results here. Don't put backticks (`` ` ``) around it! The output already contains Markdown formatting.
-
-If you're on macOS, run the following:
-
- $ pipenv --support | pbcopy
-
-If you're on Windows, run the following:
-
- > pipenv --support | clip
-
-If you're on Linux, run the following:
-
- $ pipenv --support | xclip
diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md
index 8a30d5aa..e02f479c 100644
--- a/.github/ISSUE_TEMPLATE/Feature_request.md
+++ b/.github/ISSUE_TEMPLATE/Feature_request.md
@@ -5,7 +5,7 @@ about: Suggest an idea for this project
Be sure to check the existing issues (both open and closed!), and make sure you are running the latest version of Pipenv.
-Check the [diagnose documentation](https://docs.pipenv.org/diagnose/) for common issues and the [PEEP list](https://github.com/pypa/pipenv/blob/master/peeps/) before posting! We may close your issue if it is very similar to one of them. Please be considerate and follow the PEEP process, or be on your way.
+Check the [diagnose documentation](https://pipenv.pypa.io/en/latest/diagnose/) for common issues and the [PEEP list](https://github.com/pypa/pipenv/blob/master/peeps/) before posting! We may close your issue if it is very similar to one of them. Please be considerate and follow the PEEP process, or be on your way.
Make sure to mention your debugging experience if the documented solution failed.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 0e1c095b..325d14db 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -7,7 +7,7 @@ What is the thing you want to fix? Is it associated with an issue on GitHub? Ple
Always consider opening an issue first to describe your problem, so we can discuss what is the best way to amend it. Note that if you do not describe the goal of this change or link to a related issue, the maintainers may close the PR without further review.
-If your pull request makes a non-insignificant change to Pipenv, such as the user interface or intended functionality, please file a PEEP.
+If your pull request makes a non-insignificant change to Pipenv, such as the user interface or intended functionality, please file a PEEP.
https://github.com/pypa/pipenv/blob/master/peeps/PEEP-000.md
@@ -22,7 +22,7 @@ How does this pull request fix your problem? Did you consider any alternatives?
* [ ] A news fragment in the `news/` directory to describe this fix with the extension `.bugfix`, `.feature`, `.behavior`, `.doc`. `.vendor`. or `.trivial` (this will appear in the release changelog). Use semantic line breaks and name the file after the issue number or the PR #.
diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html
index cbf7e5f8..335315a6 100644
--- a/docs/_templates/sidebarintro.html
+++ b/docs/_templates/sidebarintro.html
@@ -46,23 +46,23 @@
Pipenv-Pipes
-More projects founded by Kenneth Reitz:
+More projects founded by Kenneth Reitz:
Useful Links
-More projects founded by Kenneth Reitz:
+More projects founded by Kenneth Reitz:
Useful Links
diff --git a/docs/advanced.rst b/docs/advanced.rst
index f410006b..e48d94c2 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -41,7 +41,7 @@ Very fancy.
☤ Using a PyPI Mirror
----------------------------
-If you'd like to override the default PyPI index urls with the url for a PyPI mirror, you can use the following::
+If you would like to override the default PyPI index URLs with the URL for a PyPI mirror, you can use the following::
$ pipenv install --pypi-mirror
@@ -58,7 +58,6 @@ Alternatively, you can set the ``PIPENV_PYPI_MIRROR`` environment variable.
☤ Injecting credentials into Pipfiles via environment variables
-----------------------------------------------------------------
-
Pipenv will expand environment variables (if defined) in your Pipfile. Quite
useful if you need to authenticate to a private PyPI::
@@ -71,10 +70,18 @@ Luckily - pipenv will hash your Pipfile *before* expanding environment
variables (and, helpfully, will substitute the environment variables again when
you install from the lock file - so no need to commit any secrets! Woo!)
-If your credentials contain a special character, surround the references to the environment variables with quotation marks. For example, if your password contain a double quotation mark, surround the password variable with single quotation marks. Otherwise, you may get a ``ValueError, "No closing quotation"`` error while installing dependencies. ::
+If your credentials contain special characters, make sure they are URL-encoded as specified in `rfc3986 `_.
- [[source]]
- url = "https://$USERNAME:'${PASSWORD}'@mypypi.example.com/simple"
+Environment variables may be specified as ``${MY_ENVAR}`` or ``$MY_ENVAR``.
+
+On Windows, ``%MY_ENVAR%`` is supported in addition to ``${MY_ENVAR}`` or ``$MY_ENVAR``.
+
+Environment variables in the URL part of requirement specifiers can also be expanded, where the variable must be in the form of ``${VAR_NAME}``. Neither ``$VAR_NAME`` nor ``%VAR_NAME%`` is acceptable::
+
+ [[package]]
+ requests = {git = "git://${USERNAME}:${PASSWORD}@private.git.com/psf/requests.git", ref = "2.22.0"}
+
+Keep in mind that environment variables are expanded in runtime, leaving the entries in ``Pipfile`` or ``Pipfile.lock`` untouched. This is to avoid the accidental leakage of credentials in the source code.
☤ Specifying Basically Anything
@@ -126,6 +133,12 @@ Or you can install packages exactly as specified in ``Pipfile.lock`` using the `
``pipenv install --ignore-pipfile`` is nearly equivalent to ``pipenv sync``, but ``pipenv sync`` will *never* attempt to re-lock your dependencies as it is considered an atomic operation. ``pipenv install`` by default does attempt to re-lock unless using the ``--deploy`` flag.
+You may only wish to verify your ``Pipfile.lock`` is up-to-date with dependencies specified in the ``Pipfile``, without installing::
+
+ $ pipenv verify
+
+The command will perform a verification, and return an exit code ``1`` when dependency locking is needed. This may be useful for cases when the ``Pipfile.lock`` file is subject to version control, so this command can be used within your CI/CD pipelines.
+
Deploying System Dependencies
/////////////////////////////
@@ -149,7 +162,9 @@ Anaconda uses Conda to manage packages. To reuse Conda–installed Python packag
☤ Generating a ``requirements.txt``
-----------------------------------
-You can convert a ``Pipfile`` and ``Pipfile.lock`` into a ``requirements.txt`` file very easily, and get all the benefits of extras and other goodies we have included.
+You can convert a ``Pipfile`` and ``Pipfile.lock`` into a ``requirements.txt``
+file very easily, and get all the benefits of extras and other goodies we have
+included.
Let's take this ``Pipfile``::
@@ -160,7 +175,10 @@ Let's take this ``Pipfile``::
[packages]
requests = {version="*"}
-And generate a ``requirements.txt`` out of it::
+ [dev-packages]
+ pytest = {version="*"}
+
+And generate a set of requirements out of it with only the default dependencies::
$ pipenv lock -r
chardet==3.0.4
@@ -169,22 +187,41 @@ And generate a ``requirements.txt`` out of it::
idna==2.6
urllib3==1.22
-If you wish to generate a ``requirements.txt`` with only the development requirements you can do that too! Let's take the following ``Pipfile``::
-
- [[source]]
- url = "https://pypi.python.org/simple"
- verify_ssl = true
-
- [dev-packages]
- pytest = {version="*"}
-
-And generate a ``requirements.txt`` out of it::
+As with other commands, passing ``--dev`` will include both the default and
+development dependencies::
$ pipenv lock -r --dev
+ chardet==3.0.4
+ requests==2.18.4
+ certifi==2017.7.27.1
+ idna==2.6
+ urllib3==1.22
+ py==1.4.34
+ pytest==3.2.3
+
+Finally, if you wish to generate a requirements file with only the
+development requirements you can do that too, using the ``--dev-only``
+flag::
+
+ $ pipenv lock -r --dev-only
+ py==1.4.34
+ pytest==3.2.3
+
+The locked requirements are written to stdout, with shell output redirection
+used to write them to a file::
+
+ $ pipenv lock -r > requirements.txt
+ $ pipenv lock -r --dev-only > dev-requirements.txt
+ $ cat requirements.txt
+ chardet==3.0.4
+ requests==2.18.4
+ certifi==2017.7.27.1
+ idna==2.6
+ urllib3==1.22
+ $ cat dev-requirements.txt
py==1.4.34
pytest==3.2.3
-Very fancy.
☤ Detection of Security Vulnerabilities
---------------------------------------
@@ -199,9 +236,9 @@ Example::
django = "==1.10.1"
$ pipenv check
- Checking PEP 508 requirements…
+ Checking PEP 508 requirements...
Passed!
- Checking installed package safety…
+ Checking installed package safety...
33075: django >=1.10,<1.10.3 resolved (1.10.1 installed)!
Django before 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3, when settings.DEBUG is True, allow remote attackers to conduct DNS rebinding attacks by leveraging failure to validate the HTTP Host header against settings.ALLOWED_HOSTS.
@@ -237,16 +274,15 @@ Example::
.. note::
- In order to enable this functionality while maintaining its permissive
- copyright license, `pipenv` embeds an API client key for the backend
- Safety API operated by pyup.io rather than including a full copy of the
- CC-BY-NC-SA licensed Safety-DB database. This embedded client key is
- shared across all `pipenv check` users, and hence will be subject to
- API access throttling based on overall usage rather than individual
- client usage.
+ Each month, `PyUp.io` updates the ``safety`` database of
+ insecure Python packages and `makes it available to the
+ community for free `__. Pipenv
+ makes an API call to retrieve those results and use them
+ each time you run ``pipenv check`` to show you vulnerable
+ dependencies.
- You can also use your own safety API key by setting the
- environment variable ``PIPENV_PYUP_API_KEY``.
+ For more up-to-date vulnerability data, you may also use your own safety
+ API key by setting the environment variable ``PIPENV_PYUP_API_KEY``.
☤ Community Integrations
@@ -276,7 +312,7 @@ Works in progress:
Pipenv allows you to open any Python module that is installed (including ones in your codebase), with the ``$ pipenv open`` command::
$ pipenv install -e git+https://github.com/kennethreitz/background.git#egg=background
- Installing -e git+https://github.com/kennethreitz/background.git#egg=background…
+ Installing -e git+https://github.com/kennethreitz/background.git#egg=background...
...
Updated Pipfile.lock!
@@ -308,17 +344,17 @@ This is a very fancy feature, and we're very proud of it::
python_version = "3.6"
$ pipenv install
- Warning: Python 3.6 was not found on your system…
+ Warning: Python 3.6 was not found on your system...
Would you like us to install latest CPython 3.6 with pyenv? [Y/n]: y
- Installing CPython 3.6.2 with pyenv (this may take a few minutes)…
+ Installing CPython 3.6.2 with pyenv (this may take a few minutes)...
...
- Making Python installation global…
- Creating a virtualenv for this project…
- Using /Users/kennethreitz/.pyenv/shims/python3 to create virtualenv…
+ Making Python installation global...
+ Creating a virtualenv for this project...
+ Using /Users/kennethreitz/.pyenv/shims/python3 to create virtualenv...
...
No package provided, installing all dependencies.
...
- Installing dependencies from Pipfile.lock…
+ Installing dependencies from Pipfile.lock...
🐍 ❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒ 5/5 — 00:00:03
To activate this project's virtualenv, run the following:
$ pipenv shell
@@ -336,7 +372,7 @@ If a ``.env`` file is present in your project, ``$ pipenv shell`` and ``$ pipenv
HELLO=WORLD⏎
$ pipenv run python
- Loading .env environment variables…
+ Loading .env environment variables...
Python 2.7.13 (default, Jul 18 2017, 09:17:00)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
@@ -344,6 +380,21 @@ If a ``.env`` file is present in your project, ``$ pipenv shell`` and ``$ pipenv
>>> os.environ['HELLO']
'WORLD'
+Shell like variable expansion is available in ``.env`` files using `${VARNAME}` syntax.::
+
+ $ cat .env
+ CONFIG_PATH=${HOME}/.config/foo
+
+ $ pipenv run python
+ Loading .env environment variables...
+ Python 3.7.6 (default, Dec 19 2019, 22:52:49)
+ [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
+ Type "help", "copyright", "credits" or "license" for more information.
+ >>> import os
+ >>> os.environ['CONFIG_PATH']
+ '/home/kennethreitz/.config/foo'
+
+
This is very useful for keeping production credentials out of your codebase.
We do not recommend committing ``.env`` files into source control!
@@ -355,6 +406,8 @@ To prevent pipenv from loading the ``.env`` file, set the ``PIPENV_DONT_LOAD_ENV
$ PIPENV_DONT_LOAD_ENV=1 pipenv shell
+See `theskumar/python-dotenv `_ for more information on ``.env`` files.
+
☤ Custom Script Shortcuts
-------------------------
@@ -388,30 +441,13 @@ For example:
$ pipenv run echospam "indeed"
I am really a very silly example indeed
-☤ Support for Environment Variables
------------------------------------
+You can then display the names and commands of your shortcuts by running ``pipenv scripts`` in your terminal.
-Pipenv supports the usage of environment variables in place of authentication fragments
-in your Pipfile. These will only be parsed if they are present in the ``[[source]]``
-section. For example:
+::
-.. code-block:: toml
-
- [[source]]
- url = "https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my_private_repo.example.com/simple"
- verify_ssl = true
- name = "pypi"
-
- [dev-packages]
-
- [packages]
- requests = {version="*", index="home"}
- maya = {version="*", index="pypi"}
- records = "*"
-
-Environment variables may be specified as ``${MY_ENVAR}`` or ``$MY_ENVAR``.
-
-On Windows, ``%MY_ENVAR%`` is supported in addition to ``${MY_ENVAR}`` or ``$MY_ENVAR``.
+ $ pipenv scripts
+ command script
+ echospam echo I am really a very silly example
.. _configuration-with-environment-variables:
@@ -451,7 +487,7 @@ In addition, you can also have Pipenv stick the virtualenv in ``project/.venv``
Pipenv is being used in projects like `Requests`_ for declaring development dependencies and running the test suite.
-We've currently tested deployments with both `Travis-CI`_ and `tox`_ with success.
+We have currently tested deployments with both `Travis-CI`_ and `tox`_ with success.
Travis CI
/////////
@@ -533,13 +569,17 @@ A 3rd party plugin, `tox-pipenv`_ is also available to use Pipenv natively with
☤ Shell Completion
------------------
-To enable completion in fish, add this to your config::
+To enable completion in fish, add this to your configuration::
- eval (pipenv --completion)
+ eval (env _PIPENV_COMPLETE=fish_source pipenv)
-Alternatively, with bash or zsh, add this to your config::
+Alternatively, with zsh, add this to your configuration::
- eval "$(pipenv --completion)"
+ eval "$(_PIPENV_COMPLETE=zsh_source pipenv)"
+
+Alternatively, with bash, add this to your configuration::
+
+ eval "$(_PIPENV_COMPLETE=bash_source pipenv)"
Magic shell completions are now enabled!
@@ -571,9 +611,9 @@ at all, use the `PIP_IGNORE_INSTALLED` setting::
There is a subtle but very important distinction to be made between **applications** and **libraries**. This is a very common source of confusion in the Python community.
-Libraries provide reusable functionality to other libraries and applications (let's use the umbrella term **projects** here). They are required to work alongside other libraries, all with their own set of subdependencies. They define **abstract dependencies**. To avoid version conflicts in subdependencies of different libraries within a project, libraries should never ever pin dependency versions. Although they may specify lower or (less frequently) upper bounds, if they rely on some specific feature/fix/bug. Library dependencies are specified via ``install_requires`` in ``setup.py``.
+Libraries provide reusable functionality to other libraries and applications (let's use the umbrella term **projects** here). They are required to work alongside other libraries, all with their own set of sub-dependencies. They define **abstract dependencies**. To avoid version conflicts in sub-dependencies of different libraries within a project, libraries should never ever pin dependency versions. Although they may specify lower or (less frequently) upper bounds, if they rely on some specific feature/fix/bug. Library dependencies are specified via ``install_requires`` in ``setup.py``.
-Libraries are ultimately meant to be used in some **application**. Applications are different in that they usually are not depended on by other projects. They are meant to be deployed into some specific environment and only then should the exact versions of all their dependencies and subdependencies be made concrete. To make this process easier is currently the main goal of Pipenv.
+Libraries are ultimately meant to be used in some **application**. Applications are different in that they usually are not depended on by other projects. They are meant to be deployed into some specific environment and only then should the exact versions of all their dependencies and sub-dependencies be made concrete. To make this process easier is currently the main goal of Pipenv.
To summarize:
diff --git a/docs/basics.rst b/docs/basics.rst
index 8cac8971..4a5e5f26 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -10,10 +10,11 @@ This document covers some of Pipenv's more basic features.
☤ Example Pipfile & Pipfile.lock
--------------------------------
-Pipfiles contain information for the dependencies of the project, and supercede
-the requirements.txt present in Python projects. You should add Pipfile to your
-Git repository, and let users who clone the repository know that they need only
-install Pipenv, and type ``pipenv install``. Pipenv is a reference
+Pipfiles contain information for the dependencies of the project, and supersedes
+the requirements.txt file used in most Python projects. You should add a Pipfile in the
+Git repository letting users who clone the repository know the only thing required would be
+installing Pipenv in the machine and typing ``pipenv install``. Pipenv is a reference
+
implementation for using Pipfile.
.. _example_files:
@@ -131,7 +132,7 @@ Example Pipfile.lock
- Generally, keep both ``Pipfile`` and ``Pipfile.lock`` in version control.
- Do not keep ``Pipfile.lock`` in version control if multiple versions of Python are being targeted.
-- Specify your target Python version in your `Pipfile`'s ``[requires]`` section. Ideally, you should only have one target Python version, as this is a deployment tool. ``python_version`` should be in the format ``X.Y`` and ``python_full_version`` should be in ``X.Y.Z`` format.
+- Specify your target Python version in your `Pipfile`'s ``[requires]`` section. Ideally, you should only have one target Python version, as this is a deployment tool. ``python_version`` should be in the format ``X.Y`` (or ``X``) and ``python_full_version`` should be in ``X.Y.Z`` format.
- ``pipenv install`` is fully compatible with ``pip install`` syntax, for which the full documentation can be found `here `_.
- Note that the ``Pipfile`` uses the `TOML Spec `_.
@@ -216,7 +217,7 @@ To make inclusive or exclusive version comparisons you can use: ::
The use of ``~=`` is preferred over the ``==`` identifier as the latter prevents pipenv from updating the packages: ::
- $ pipenv install "requests~=2.2" # locks the major version of the package (this is equivalent to using ==2.*)
+ $ pipenv install "requests~=2.2" # locks the major version of the package (this is equivalent to using >=2.2, ==2.*)
To avoid installing a specific version you can use the ``!=`` identifier.
@@ -371,7 +372,7 @@ You can install packages with pipenv from git and other version control systems
+:////@#egg=
-The only optional section is the ``@`` section. When using git over SSH, you may use the shorthand vcs and scheme alias ``git+git@:/@#``. Note that this is translated to ``git+ssh://git@`` when parsed.
+The only optional section is the ``@`` section. When using git over SSH, you may use the shorthand vcs and scheme alias ``git+git@:/@#egg=``. Note that this is translated to ``git+ssh://git@`` when parsed.
Note that it is **strongly recommended** that you install any version-controlled dependencies in editable mode, using ``pipenv install -e``, in order to ensure that dependency resolution can be performed with an up to date copy of the repository each time it is performed, and that it includes all known dependencies.
@@ -409,5 +410,118 @@ production environments for reproducible builds.
.. note::
If you'd like a ``requirements.txt`` output of the lockfile, run ``$ pipenv lock -r``.
- This will include all hashes, however (which is great!). To get a ``requirements.txt``
- without hashes, use ``$ pipenv run pip freeze``.
+ This will not include hashes, however. To get a ``requirements.txt``
+ you can also use ``$ pipenv run pip freeze``.
+
+
+☤ Pipenv and Docker Containers
+------------------------------
+
+In general, you should not have Pipenv inside a linux container image, since
+it is a build tool. If you want to use it to build, and install the run time
+dependencies for your application, you can use a multi stage build for creating
+a virtual environment with your dependencies. In this approach,
+Pipenv in installed in the base layer, it is then used to create the virtual
+environment. In a later stage, in a ``runtime`` layer the virtual environment
+is copied from the base layer, the layer containing pipenv and other build
+dependencies is discarded.
+This results in a smaller image, which can still run your application.
+Here is an example ``Dockerfile``, which you can use as a starting point for
+doing a multi stage build for your application::
+
+ FROM docker.io/python:3.9 AS builder
+
+ RUN pip install --user pipenv
+
+ # Tell pipenv to create venv in the current directory
+ ENV PIPENV_VENV_IN_PROJECT=1
+
+ # Pipefile contains requests
+ ADD Pipfile.lock Pipfile /usr/src/
+
+ WORKDIR /usr/src
+
+ # NOTE: If you install binary packages required for a python module, you need
+ # to install them again in the runtime. For example, if you need to install pycurl
+ # you need to have pycurl build dependencies libcurl4-gnutls-dev and libcurl3-gnutls
+ # In the runtime container you need only libcurl3-gnutls
+
+ # RUN apt install -y libcurl3-gnutls libcurl4-gnutls-dev
+
+ RUN /root/.local/bin/pipenv sync
+
+ RUN /usr/src/.venv/bin/python -c "import requests; print(requests.__version__)"
+
+ FROM docker.io/python:3.9 AS runtime
+
+ RUN mkdir -v /usr/src/venv
+
+ COPY --from=builder /usr/src/.venv/ /usr/src/venv/
+
+ RUN /usr/src/venv/bin/python -c "import requests; print(requests.__version__)"
+
+ # HERE GOES ANY CODE YOU NEED TO ADD TO CREATE YOUR APPLICATION'S IMAGE
+ # For example
+ # RUN apt install -y libcurl3-gnutls
+ # RUN adduser --uid 123123 coolio
+
+ WORKDIR /usr/src/
+
+ USER coolio
+
+ CMD ["./venv/bin/python", "-m", "run.py"]
+
+.. Note::
+
+ Pipenv is not meant to run as root. However, in the multi stage build above
+ it is done never the less. A calculated risk, since the intermediatiary image
+ is discarded.
+ The runtime image later shows that you should create a user and user it to
+ run your applicaion.
+ **Once again, you should not run pipenv as root (or Admin on Windows) normally.
+ This could lead to breakage of your Python installation, or even your complete
+ OS.**
+
+When you build an image with this example (assuming requests is found in Pipefile), you
+will see that ``requests`` is installed in the ``runtime`` image::
+
+ $ sudo docker build --no-cache -t oz/123:0.1 .
+ Sending build context to Docker daemon 1.122MB
+ Step 1/12 : FROM docker.io/python:3.9 AS builder
+ ---> 81f391f1a7d7
+ Step 2/12 : RUN pip install --user pipenv
+ ---> Running in b83ed3c28448
+ ... trimmed ...
+ ---> 848743eb8c65
+ Step 4/12 : ENV PIPENV_VENV_IN_PROJECT=1
+ ---> Running in 814e6f5fec5b
+ Removing intermediate container 814e6f5fec5b
+ ---> 20167b4a13e1
+ Step 5/12 : ADD Pipfile.lock Pipfile /usr/src/
+ ---> c7632cb3d5bd
+ Step 6/12 : WORKDIR /usr/src
+ ---> Running in 1d75c6cfce10
+ Removing intermediate container 1d75c6cfce10
+ ---> 2dcae54cc2e5
+ Step 7/12 : RUN /root/.local/bin/pipenv sync
+ ---> Running in 1a00b326b1ee
+ Creating a virtualenv for this project...
+ ... trimmed ...
+ ✔ Successfully created virtual environment!
+ Virtualenv location: /usr/src/.venv
+ Installing dependencies from Pipfile.lock (fe5a22)...
+ ... trimmed ...
+ Step 8/12 : RUN /usr/src/.venv/bin/python -c "import requests; print(requests.__version__)"
+ ---> Running in 3a66e3ce4a11
+ 2.27.1
+ Removing intermediate container 3a66e3ce4a11
+ ---> 1db657d0ac17
+ Step 9/12 : FROM docker.io/python:3.9 AS runtime
+ ... trimmed ...
+ Step 12/12 : RUN /usr/src/venv/bin/python -c "import requests; print(requests.__version__)"
+ ---> Running in fa39ba4080c5
+ 2.27.1
+ Removing intermediate container fa39ba4080c5
+ ---> 2b1c90fd414e
+ Successfully built 2b1c90fd414e
+ Successfully tagged oz/123:0.1
diff --git a/docs/conf.py b/docs/conf.py
index 90e16afe..e5aa5953 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# pipenv documentation build configuration file, created by
# sphinx-quickstart on Mon Jan 30 13:28:36 2017.
@@ -18,7 +17,6 @@
#
import os
-
# Path hackery to get current version number.
here = os.path.abspath(os.path.dirname(__file__))
@@ -56,9 +54,9 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'pipenv'
-copyright = u'2020. A project founded by Kenneth Reitz'
-author = u'Python Packaging Authority'
+project = 'pipenv'
+copyright = '2020. A project founded by Kenneth Reitz'
+author = 'Python Packaging Authority'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -87,7 +85,6 @@ pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
-
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
@@ -155,8 +152,8 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, 'pipenv.tex', u'pipenv Documentation',
- u'Kenneth Reitz', 'manual'),
+ (master_doc, 'pipenv.tex', 'pipenv Documentation',
+ 'Kenneth Reitz', 'manual'),
]
@@ -165,7 +162,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- (master_doc, 'pipenv', u'pipenv Documentation',
+ (master_doc, 'pipenv', 'pipenv Documentation',
[author], 1)
]
@@ -176,7 +173,7 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- (master_doc, 'pipenv', u'pipenv Documentation',
+ (master_doc, 'pipenv', 'pipenv Documentation',
author, 'pipenv', 'One line description of project.',
'Miscellaneous'),
]
diff --git a/docs/dev/contributing.rst b/docs/dev/contributing.rst
index 0fb0c36f..d43e3ec5 100644
--- a/docs/dev/contributing.rst
+++ b/docs/dev/contributing.rst
@@ -8,13 +8,7 @@ contributing to the Pipenv project is *very* generous of you.
This document lays out guidelines and advice for contributing to this project.
If you're thinking of contributing, please start by reading this document and
-getting a feel for how contributing to this project works. If you have any
-questions, feel free to reach out to either `Dan Ryan`_, `Tzu-ping Chung`_,
-or `Nate Prewitt`_, the primary maintainers.
-
-.. _Dan Ryan: https://github.com/techalchemy
-.. _Tzu-ping Chung: https://github.com/uranusjr
-.. _Nate Prewitt: https://github.com/nateprewitt
+getting a feel for how contributing to this project works.
The guide is split into sections based on the type of contribution you're
thinking of making, with a section that covers general guidelines for all
@@ -29,16 +23,15 @@ Be Cordial
**Be cordial or be on your way**. *—Kenneth Reitz*
+.. _be cordial or be on your way: https://kennethreitz.org/essays/2013/01/27/be-cordial-or-be-on-your-way
+
Pipenv has one very important rule governing all forms of contribution,
including reporting bugs or requesting features. This golden rule is
-"`be cordial or be on your way`_".
+"`be cordial or be on your way`_"
**All contributions are welcome**, as long as
everyone involved is treated with respect.
-.. _be cordial or be on your way: https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way
-
-
.. _early-feedback:
Get Early Feedback
@@ -75,11 +68,9 @@ answered promptly and accurately.
.. _Stack Overflow: https://stackoverflow.com/
-
Code Contributions
------------------
-
Steps for Submitting Code
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -102,26 +93,14 @@ When contributing code, you'll want to follow this checklist:
The following sub-sections go into more detail on some of the points above.
-.. _development philosophy: https://docs.pipenv.org/dev/philosophy/
-
+.. _development philosophy: https://pipenv.pypa.io/en/latest/dev/philosophy/
.. _dev-setup:
Development Setup
~~~~~~~~~~~~~~~~~
-To get your development environment setup, run:
-
-.. code-block:: sh
-
- pip install -e .
- pipenv install --dev
-
-
-This will install the repo version of Pipenv and then install the development
-dependencies. Once that has completed, you can start developing.
-
-The repo version of Pipenv must be installed over other global versions to
+The repository version of Pipenv must be installed over other global versions to
resolve conflicts with the ``pipenv`` folder being implicitly added to ``sys.path``.
See `pypa/pipenv#2557`_ for more details.
@@ -152,7 +131,7 @@ tests, the standard pytest filters are available, such as:
Code Review
~~~~~~~~~~~
-Contributions will not be merged until they've been code reviewed. You should
+Contributions will not be merged until they have been code reviewed. You should
implement any code review feedback unless you strongly object to it. In the
event that you object to the code review feedback, you should make your case
clearly and calmly. If, after doing so, the feedback is judged to still apply,
@@ -171,7 +150,6 @@ a ``.tar.gz`` or universal wheel is not available, add wheels for all available
architectures and platforms.
-
Documentation Contributions
---------------------------
@@ -190,7 +168,6 @@ When presenting Python code, use single-quoted strings (``'hello'`` instead of
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _Sphinx: http://sphinx-doc.org/index.html
-
.. _bug-reports:
Bug Reports
@@ -205,7 +182,7 @@ be aware of the following things when filing bug reports:
to check whether your bug report or feature request has been mentioned in
the past. Duplicate bug reports and feature requests are a huge maintenance
burden on the limited resources of the project. If it is clear from your
- report that you would have struggled to find the original, that's ok, but
+ report that you would have struggled to find the original, that's okay, but
if searching for a selection of words in your issue title would have found
the duplicate then the issue will likely be closed extremely abruptly.
2. When filing bug reports about exceptions or tracebacks, please include the
@@ -241,11 +218,30 @@ be aware of the following things when filing bug reports:
Run the tests
-------------
-Three ways of running the tests are as follows:
+Two ways of running the tests are as follows:
-1. ``make test`` (which uses ``docker``)
-2. ``./run-tests.sh`` or ``run-tests.bat``
-3. Using pipenv:
+1. ``./run-tests.sh`` or ``run-tests.bat``
+
+Note that, you override the default Python Pipenv will use with
+PIPENV_PYTHON and the Python binary name with PYTHON in case it
+is not called ``python`` on your system or in case you have many.
+Here is an example how you can override both variables (you can
+override just one too)::
+
+ $ PYTHON=python3.8 PIPENV_PYTHON=python3.9 run-tests.sh
+
+You can also do::
+
+ $ PYTHON=/opt/python/python3.10/python3 run-tests.sh
+
+If you need to change how pytest is invoked, see how to run the
+test suite manually. The ``run-tests.sh`` script does the same
+steps the Github CI workflow does, and as such it is recommended
+you run it before you open a PR. Taking this second approach,
+will allow you, for example, to run a single test case, or
+``fail fast`` if you need it.
+
+2. Manually, which repeat the steps of the scripts above:
.. code-block:: console
@@ -253,9 +249,26 @@ Three ways of running the tests are as follows:
$ cd pipenv
$ git submodule sync && git submodule update --init --recursive
$ pipenv install --dev
- $ pipenv run pytest
+ $ pipenv run pytest [--any optional arguments to pytest]
-For the last two, it is important that your environment is setup correctly, and
+The second options assumes you already have ``pipenv`` on your system.
+And simply repeats all the steps in the script above.
+
+Preferably, you should be running your tests in a Linux container
+(or FreeBSD Jail or even VM). This will guarantee that you don't break
+stuff, and that the tests run in a pristine environment.
+
+Consider doing, something like:
+
+```
+$ docker run --rm -v $(pwd):/usr/src -it python:3.7 bash
+# inside the container
+# adduser --disabled-password debian
+# su debian && cd /usr/src/
+# bash run-tests.sh
+```
+
+It is important that your environment is setup correctly, and
this may take some work, for example, on a specific Mac installation, the following
steps may be needed::
diff --git a/docs/dev/philosophy.rst b/docs/dev/philosophy.rst
deleted file mode 100644
index 3f4c0bd0..00000000
--- a/docs/dev/philosophy.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-Development Philosophy
-======================
-
-Pipenv is an open but opinionated tool, created by an open but opinionated developer.
-
-
-Management Style
-~~~~~~~~~~~~~~~~
-
- **To be updated (as of March 2020)**.
-
-`Kenneth Reitz `__ is the BDFL. He has final say in any decision related to the Pipenv project. Kenneth is responsible for the direction and form of the library, as well as its presentation. In addition to making decisions based on technical merit, he is responsible for making decisions based on the development philosophy of Pipenv.
-
-`Dan Ryan `__, `Tzu-ping Chung `__, and `Nate Prewitt `__ are the core contributors.
-They are responsible for triaging bug reports, reviewing pull requests and ensuring that Kenneth is kept up to speed with developments around the library.
-The day-to-day managing of the project is done by the core contributors. They are responsible for making judgements about whether or not a feature request is
-likely to be accepted by Kenneth.
-
-Values
-~~~~~~
-
-- Simplicity is always better than functionality.
-- Listen to everyone, then disregard it.
-- The API is all that matters. Everything else is secondary.
-- Fit the 90% use-case. Ignore the nay-sayers.
diff --git a/docs/diagnose.rst b/docs/diagnose.rst
index 5cc47f4c..92a1e264 100644
--- a/docs/diagnose.rst
+++ b/docs/diagnose.rst
@@ -29,7 +29,7 @@ usually one of the following locations:
* ``%LOCALAPPDATA%\pipenv\pipenv\Cache`` (Windows)
* ``~/.cache/pipenv`` (other operating systems)
-Pipenv does not install prereleases (i.e. a version with an alpha/beta/etc.
+Pipenv does not install pre-releases (i.e. a version with an alpha/beta/etc.
suffix, such as *1.0b1*) by default. You will need to pass the ``--pre`` flag
in your command, or set
@@ -58,14 +58,9 @@ distributions, with version name like ``3.6.4`` or similar.
------------------------------------------------------------------
Pipenv by default uses the Python it is installed against to create the
-virtualenv. You can set the ``--python`` option, or
-``$PYENV_ROOT/shims/python`` to let it consult pyenv when choosing the
-interpreter. See :ref:`specifying_versions` for more information.
-
-If you want Pipenv to automatically “do the right thing”, you can set the
-environment variable ``PIPENV_PYTHON`` to ``$PYENV_ROOT/shims/python``. This
-will make Pipenv use pyenv’s active Python version to create virtual
-environments by default.
+virtualenv. You can set the ``--python`` option to ``$(pyenv which python)``
+to use your current pyenv interpreter. See :ref:`specifying_versions` for more
+information.
.. _unknown-local-diagnose:
@@ -101,18 +96,6 @@ This may be related to your locale setting. See :ref:`unknown-local-diagnose`
for a possible solution.
-☤ ``shell`` does not show the virtualenv’s name in prompt
----------------------------------------------------------
-
-This is intentional. You can do it yourself with either shell plugins, or
-clever ``PS1`` configuration. If you really want it back, use
-
-::
-
- pipenv shell -c
-
-instead (not available on Windows).
-
☤ Pipenv does not respect dependencies in setup.py
--------------------------------------------------
@@ -124,15 +107,15 @@ for more information.
---------------------------------------------
When you configure a supervisor program's ``command`` with ``pipenv run ...``, you
-need to set locale enviroment variables properly to make it work.
+need to set locale environment variables properly to make it work.
Add this line under ``[supervisord]`` section in ``/etc/supervisor/supervisord.conf``::
[supervisord]
environment=LC_ALL='en_US.UTF-8',LANG='en_US.UTF-8'
-☤ An exception is raised during ``Locking dependencies…``
----------------------------------------------------------
+☤ An exception is raised during ``Locking dependencies...``
+-----------------------------------------------------------
Run ``pipenv lock --clear`` and try again. The lock sequence caches results
to speed up subsequent runs. The cache may contain faulty results if a bug
diff --git a/docs/index.rst b/docs/index.rst
index 26bfde19..8447c468 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -32,7 +32,7 @@ Pipenv is primarily meant to provide users and developers of applications with a
The problems that Pipenv seeks to solve are multi-faceted:
- You no longer need to use ``pip`` and ``virtualenv`` separately. They work together.
-- Managing a ``requirements.txt`` file `can be problematic `_, so Pipenv uses ``Pipfile`` and ``Pipfile.lock`` to separate abstract dependency declarations from the last tested combination.
+- Managing a ``requirements.txt`` file `can be problematic `__, so Pipenv uses ``Pipfile`` and ``Pipfile.lock`` to separate abstract dependency declarations from the last tested combination.
- Hashes are used everywhere, always. Security. Automatically expose security vulnerabilities.
- Strongly encourage the use of the latest versions of dependencies to minimize security risks `arising from outdated components `_.
- Give you insight into your dependency graph (e.g. ``$ pipenv graph``).
@@ -48,15 +48,19 @@ You can quickly play with Pipenv right in your browser:
Install Pipenv Today!
---------------------
-If you're on MacOS, you can install Pipenv easily with Homebrew. You can also use Linuxbrew on Linux using the same command::
+If you already have Python and pip, you can easily install Pipenv into your home directory::
- $ brew install pipenv
+ $ pip install --user pipenv
Or, if you're using Fedora 28::
$ sudo dnf install pipenv
-Otherwise, refer to the :ref:`installing-pipenv` chapter for instructions.
+It's possible to install Pipenv with Homebrew on MacOS, or with Linuxbrew on Linux systems. However, **this is now discouraged**, because updates to the brewed Python distribution will break Pipenv, and perhaps all virtual environments managed by it. You'll then need to re-install Pipenv at least. If you want to give it a try despite this warning, use::
+
+ $ brew install pipenv
+
+More detailed installation instructions can be found in the :ref:`installing-pipenv` chapter.
✨🍰✨
@@ -84,7 +88,7 @@ User Testimonials
- Automatically finds your project home, recursively, by looking for a ``Pipfile``.
- Automatically generates a ``Pipfile``, if one doesn't exist.
- Automatically creates a virtualenv in a standard location.
-- Automatically adds/removes packages to a ``Pipfile`` when they are un/installed.
+- Automatically adds/removes packages to a ``Pipfile`` when they are installed or uninstalled.
- Automatically loads ``.env`` files, if they exist.
The main commands are ``install``, ``uninstall``, and ``lock``, which generates a ``Pipfile.lock``. These are intended to replace ``$ pip install`` usage, as well as manual virtualenv management (to activate a virtualenv, run ``$ pipenv shell``).
@@ -106,7 +110,7 @@ Other Commands
- ``graph`` will show you a dependency graph of your installed dependencies.
- ``shell`` will spawn a shell with the virtualenv activated. This shell can be deactivated by using ``exit``.
- ``run`` will run a given command from the virtualenv, with any arguments forwarded (e.g. ``$ pipenv run python`` or ``$ pipenv run pip freeze``).
-- ``check`` checks for security vulnerabilities and asserts that PEP 508 requirements are being met by the current environment.
+- ``check`` checks for security vulnerabilities and asserts that `PEP 508 `_ requirements are being met by the current environment.
Further Documentation Guides
@@ -126,7 +130,6 @@ Contribution Guides
.. toctree::
:maxdepth: 2
- dev/philosophy
dev/contributing
Indices and tables
@@ -134,4 +137,3 @@ Indices and tables
* :ref:`genindex`
* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/install.rst b/docs/install.rst
index 6aceba0c..ec62edd1 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -71,7 +71,7 @@ Homebrew/Linuxbrew installer takes care of pip for you.
===================
Pipenv is a dependency manager for Python projects. If you're familiar
-with Node.js' `npm`_ or Ruby's `bundler`_, it is similar in spirit to those
+with Node\.js's `npm`_ or Ruby's `bundler`_, it is similar in spirit to those
tools. While pip can install Python packages, Pipenv is recommended as
it's a higher-level tool that simplifies dependency management for common use
cases.
@@ -80,28 +80,25 @@ cases.
.. _bundler: http://bundler.io/
-☤ Homebrew Installation of Pipenv
----------------------------------
+☤ Isolated Installation of Pipenv with Pipx
+-------------------------------------------
-`Homebrew`_ is a popular open-source package management system for macOS. For Linux users, `Linuxbrew`_ is a Linux port of that.
+`Pipx`_ is a tool to help you install and run end-user applications written in Python. It installs applications
+into an isolated and clean environment on their own. To install pipx, just run::
-Installing pipenv via Homebrew or Linuxbrew will keep pipenv and all of its dependencies in
-an isolated virtual environment so it doesn't interfere with the rest of your
-Python installation.
+ $ pip install --user pipx
-Once you have installed Homebrew or Linuxbrew simply run::
+Once you have ``pipx`` ready on your system, continue to install Pipenv::
- $ brew install pipenv
+ $ pipx install pipenv
-To upgrade pipenv at any time::
-
- $ brew upgrade pipenv
+.. _Pipx: https://pypa.github.io/pipx/
☤ Pragmatic Installation of Pipenv
----------------------------------
-If you have a working installation of pip, and maintain certain "toolchain" type Python modules as global utilities in your user environment, pip `user installs `_ allow for installation into your home directory. Note that due to interaction between dependencies, you should limit tools installed in this way to basic building blocks for a Python workflow like virtualenv, pipenv, tox, and similar software.
+If you have a working installation of pip, and maintain certain "tool-chain" type Python modules as global utilities in your user environment, pip `user installs `_ allow for installation into your home directory. Note that due to interaction between dependencies, you should limit tools installed in this way to basic building blocks for a Python workflow like virtualenv, pipenv, tox, and similar software.
To install::
@@ -149,6 +146,27 @@ If you don't even have pip installed, you can use this crude installation method
$ curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
+☤ Homebrew Installation of Pipenv(Discouraged)
+----------------------------------------------
+`Homebrew`_ is a popular open-source package management system for macOS. For Linux users, `Linuxbrew`_ is a Linux port of that.
+
+Installing pipenv via Homebrew or Linuxbrew will keep pipenv and all of its dependencies in
+an isolated virtual environment so it doesn't interfere with the rest of your
+Python installation.
+
+Once you have installed Homebrew or Linuxbrew simply run::
+
+ $ brew install pipenv
+
+To upgrade pipenv at any time::
+
+ $ brew upgrade pipenv
+
+.. Note::
+ Homebrew installation is discouraged because each time the Homebrew Python is upgraded, which Pipenv depends on,
+ users have to re-install Pipenv, and perhaps all virtual environments managed by it.
+
+
☤ Installing packages for your project
======================================
@@ -159,36 +177,44 @@ tutorial) and run::
$ cd myproject
$ pipenv install requests
+.. Note::
+
+ Pipenv is designed to be used by non-privileged OS users. It is not meant
+ to install or handle packages for the whole OS. Running Pipenv as ``root``
+ or with ``sudo`` (or ``Admin`` on Windows) is highly discouraged and might
+ lead to unintend breakage of your OS.
+
Pipenv will install the excellent `Requests`_ library and create a ``Pipfile``
for you in your project's directory. The ``Pipfile`` is used to track which
dependencies your project needs in case you need to re-install them, such as
when you share your project with others. You should get output similar to this
(although the exact paths shown will vary)::
- Creating a Pipfile for this project...
- Creating a virtualenv for this project...
- Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
- New python executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python3.6
- Also creating executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python
- Installing setuptools, pip, wheel...done.
+ pipenv install requests
+ Creating a virtualenv for this project...
+ Pipfile: /home/user/myproject/Pipfile
+ sing /home/user/.local/share/virtualenvs/pipenv-Cv0J3wbi/bin/python3.9 (3.9.9) to create virtualenv...
+ Creating virtual environment...created virtual environment CPython3.9.9.final.0-64 in 1142ms
+ creator CPython3Posix(dest=/home/user/.local/share/virtualenvs/myproject-R3jRVewK, clear=False, no_vcs_ignore=False, global=False)
+ seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/user/.local/share/virtualenv)
+ added seed packages: pip==21.3.1, setuptools==60.2.0, wheel==0.37.1
+ activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
- Virtualenv location: ~/.local/share/virtualenvs/tmp-agwWamBd
- Installing requests...
- Collecting requests
- Using cached requests-2.18.4-py2.py3-none-any.whl
- Collecting idna<2.7,>=2.5 (from requests)
- Using cached idna-2.6-py2.py3-none-any.whl
- Collecting urllib3<1.23,>=1.21.1 (from requests)
- Using cached urllib3-1.22-py2.py3-none-any.whl
- Collecting chardet<3.1.0,>=3.0.2 (from requests)
- Using cached chardet-3.0.4-py2.py3-none-any.whl
- Collecting certifi>=2017.4.17 (from requests)
- Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
- Installing collected packages: idna, urllib3, chardet, certifi, requests
- Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22
-
- Adding requests to Pipfile's [packages]...
- P.S. You have excellent taste! ✨ 🍰 ✨
+ ✔ Successfully created virtual environment!
+ Virtualenv location: /home/user/.local/share/virtualenvs/pms-R3jRVewK
+ Creating a Pipfile for this project...
+ Installing requests...
+ Adding requests to Pipfile's [packages]...
+ Installation Succeeded
+ Pipfile.lock not found, creating...
+ Locking [dev-packages] dependencies...
+ Locking [packages] dependencies...
+ Building requirements...
+ Resolving dependencies...
+ ✔ Success!
+ Updated Pipfile.lock (fe5a22)!
+ Installing dependencies from Pipfile.lock (fe5a22)...
+ 🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
.. _Requests: https://python-requests.org
diff --git a/docs/requirements.txt b/docs/requirements.txt
index ee44a2ca..0e349f9c 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -20,6 +20,7 @@ six==1.11.0
snowballstemmer==1.2.1
Sphinx==1.6.3
sphinx-click==1.3.0
+sphinxcontrib-spelling==4.2.1
sphinxcontrib-websupport==1.1.0
urllib3==1.24.1
virtualenv==16.1.0
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
new file mode 100644
index 00000000..219984ec
--- /dev/null
+++ b/docs/spelling_wordlist.txt
@@ -0,0 +1,87 @@
+appdir
+ascii
+asdf
+backport
+bashrc
+bundler
+canonicalized
+cmder
+Cmder
+codebase
+Conda
+CPython
+cygwin
+Deduplicate
+Devops
+eval
+filesystem
+Homebrew
+ini
+installable
+Integrations
+io
+js
+json
+Linuxbrew
+lockfile
+macOS
+Makefile
+manpage
+metadata
+mingw
+misconfiguration
+misconfigured
+msys
+natively
+npm
+parallelization
+parsers
+pathlib
+pexpect
+pipenv
+Pipenv
+Pipfile
+Pipfiles
+piptools
+powershell
+Powershell
+pre
+py
+pyenv
+pypi
+PyPI
+pythonfinder
+resolvers
+runtime
+runtimes
+sayers
+scandir
+sha
+stateful
+subdirectory
+subprocess
+subprocesses
+subshell
+supervisord
+tox
+Tox
+tracebacks
+triaging
+txt
+unicode
+uninstallation
+unnesting
+untrusted
+url
+urls
+UTF
+vcs
+vendored
+Vendored
+venv
+virtualenv
+virtualenvs
+Virtualenv
+Virtualenvs
+zsh
+zshrc
diff --git a/get-pipenv.py b/get-pipenv.py
index a5d30e38..88d82b79 100755
--- a/get-pipenv.py
+++ b/get-pipenv.py
@@ -1,11 +1,11 @@
#!/usr/bin/env python
-# Note, this script is based off of https://bootstrap.pypa.io/get-pip.py
#
# Hi There!
+#
# You may be wondering what this giant blob of binary data here is, you might
# even be worried that we're up to something nefarious (good for you for being
# paranoid!). This is a base85 encoding of a zip file, this zip file contains
-# an entire copy of pip.
+# an entire copy of pip (version 21.3.1).
#
# Pip is a thing that installs packages, pip itself is a package that someone
# might want to install, especially if they're looking to run this get-pip.py
@@ -17,138 +17,107 @@
# doesn't do things correctly and has weird edge cases, or compress pip itself
# down into a single file.
#
-# If you're wondering how this is created, it is using an invoke task located
-# in tasks/generate.py called "installer". It can be invoked by using
-# ``invoke generate.installer``.
-# Note, this get-pip.py installer is modified to meet pipenv's needs.
+# If you're wondering how this is created, it is generated using
+# `scripts/generate.py` in https://github.com/pypa/get-pip.
+
+# Don't manually edit this script! Check ths instructions in the link above to
+# create get-pip.py and patch the following:
+
+#+++ ./get-pip/public/get-pip.py 2022-01-12 16:52:11.920161471 +0100
+#--- ./pipenv/get-pipenv.py 2022-01-12 20:11:35.816906142 +0100
+#@@ -55,7 +28,7 @@
+# message_parts = [
+# "This script does not work on Python {}.{}".format(*this_python),
+# "The minimum supported Python version is {}.{}.".format(*min_version),
+#- "Please use an alternative installation https://pipenv.pypa.io/en/latest/install/",
+#+ "Please use https://bootstrap.pypa.io/pip/{}.{}/get-pip.py instead.".format(*this_python),
+# ]
+# print("ERROR: " + " ".join(message_parts))
+# sys.exit(1)
+#@@ -70,7 +43,7 @@
+#
+# def determine_pip_install_arguments():
+# implicit_pip = True
+#+ implicit_setuptools = False
+#- implicit_setuptools = True
+# implicit_wheel = True
+#
+# # Check if the user has requested us not to install setuptools
+#@@ -87,8 +60,6 @@
+#
+# # We only want to implicitly install setuptools and wheel if they don't
+# # already exist on the target platform.
+#+ # No need for doing this, since pipenv already has setuptools as
+#+ # a dependency in setup.py
+# if implicit_setuptools:
+# try:
+# import setuptools # noqa
+#@@ -109,8 +80,6 @@
+# args += ["setuptools"]
+# if implicit_wheel:
+# args += ["wheel"]
+#+
+#+ args += ["pipenv"]
+#
+# return ["install", "--upgrade", "--force-reinstall"] + args
+
+# YMMV, so dig a bit to find how to add pipenv to the args passed to pip.
+
+import sys
+
+this_python = sys.version_info[:2]
+min_version = (3, 6)
+if this_python < min_version:
+ message_parts = [
+ "This script does not work on Python {}.{}".format(*this_python),
+ "The minimum supported Python version is {}.{}.".format(*min_version),
+ "Please use an alternative installation https://pipenv.pypa.io/en/latest/install/",
+ ]
+ print("ERROR: " + " ".join(message_parts))
+ sys.exit(1)
+
+
import os.path
import pkgutil
import shutil
-import sys
-import struct
import tempfile
-
-# Useful for very coarse version differentiation.
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-if PY3:
- iterbytes = iter
-else:
-
- def iterbytes(buf):
- return (ord(byte) for byte in buf)
+from base64 import b85decode
-try:
- from base64 import b85decode
-except ImportError:
- _b85alphabet = (
- b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"
- )
-
- def b85decode(b):
- _b85dec = [None] * 256
- for i, c in enumerate(iterbytes(_b85alphabet)):
- _b85dec[c] = i
- padding = (- len(b)) % 5
- b = b + b'~' * padding
- out = []
- packI = struct.Struct('!I').pack
- for i in range(0, len(b), 5):
- chunk = b[i: i + 5]
- acc = 0
- try:
- for c in iterbytes(chunk):
- acc = acc * 85 + _b85dec[c]
- except TypeError:
- for j, c in enumerate(iterbytes(chunk)):
- if _b85dec[c] is None:
- raise ValueError(
- 'bad base85 character at position %d' % (i + j)
- )
-
- raise
-
- try:
- out.append(packI(acc))
- except struct.error:
- raise ValueError(
- 'base85 overflow in hunk starting at byte %d' % i
- )
-
- result = b''.join(out)
- if padding:
- result = result[:-padding]
- return result
-
-
-def bootstrap(tmpdir=None):
- # Import pip so we can use it to install pip and maybe setuptools too
- import pip
- from pip.commands.install import InstallCommand
- from pip.req import InstallRequirement
-
-
- # Wrapper to provide default certificate with the lowest priority
- class CertInstallCommand(InstallCommand):
-
- def parse_args(self, args):
- # If cert isn't specified in config or environment, we provide our
- # own certificate through defaults.
- # This allows user to specify custom cert anywhere one likes:
- # config, environment variable or argv.
- if not self.parser.get_default_values().cert:
- self.parser.defaults["cert"] = cert_path # calculated below
- return super(CertInstallCommand, self).parse_args(args)
-
- pip.commands_dict["install"] = CertInstallCommand
+def determine_pip_install_arguments():
implicit_pip = True
- implicit_setuptools = True
+ implicit_setuptools = False
implicit_wheel = True
+
# Check if the user has requested us not to install setuptools
if "--no-setuptools" in sys.argv or os.environ.get("PIP_NO_SETUPTOOLS"):
args = [x for x in sys.argv[1:] if x != "--no-setuptools"]
implicit_setuptools = False
else:
args = sys.argv[1:]
+
# Check if the user has requested us not to install wheel
if "--no-wheel" in args or os.environ.get("PIP_NO_WHEEL"):
args = [x for x in args if x != "--no-wheel"]
implicit_wheel = False
+
# We only want to implicitly install setuptools and wheel if they don't
# already exist on the target platform.
+ # No need for doing this, since pipenv already has setuptools as
+ # a dependency in setup.py
if implicit_setuptools:
try:
import setuptools # noqa
-
implicit_setuptools = False
except ImportError:
pass
if implicit_wheel:
try:
import wheel # noqa
-
implicit_wheel = False
except ImportError:
pass
- # We want to support people passing things like 'pip<8' to get-pip.py which
- # will let them install a specific version. However because of the dreaded
- # DoubleRequirement error if any of the args look like they might be a
- # specific for one of our packages, then we'll turn off the implicit
- # install of them.
- for arg in args:
- try:
- req = InstallRequirement.from_line(arg)
- except:
- continue
- if implicit_pip and req.name == "pip":
- implicit_pip = False
- elif implicit_setuptools and req.name == "setuptools":
- implicit_setuptools = False
- elif implicit_wheel and req.name == "wheel":
- implicit_wheel = False
# Add any implicit installations to the end of our args
if implicit_pip:
args += ["pip"]
@@ -156,27 +125,47 @@ def bootstrap(tmpdir=None):
args += ["setuptools"]
if implicit_wheel:
args += ["wheel"]
- # Pipenv modifications here.
+
args += ["pipenv"]
- delete_tmpdir = False
- try:
- # Create a temporary directory to act as a working directory if we were
- # not given one.
- if tmpdir is None:
- tmpdir = tempfile.mkdtemp()
- delete_tmpdir = True
- # We need to extract the SSL certificates from requests so that they
- # can be passed to --cert
- cert_path = os.path.join(tmpdir, "cacert.pem")
- with open(cert_path, "wb") as cert:
- cert.write(pkgutil.get_data("pip._vendor.requests", "cacert.pem"))
- # Execute the included pip and use it to install the latest pip and
- # setuptools from PyPI
- sys.exit(pip.main(["install", "--upgrade"] + args))
- finally:
- # Remove our temporary directory
- if delete_tmpdir and tmpdir:
- shutil.rmtree(tmpdir, ignore_errors=True)
+
+ return ["install", "--upgrade", "--force-reinstall"] + args
+
+
+def monkeypatch_for_cert(tmpdir):
+ """Patches `pip install` to provide default certificate with the lowest priority.
+
+ This ensures that the bundled certificates are used unless the user specifies a
+ custom cert via any of pip's option passing mechanisms (config, env-var, CLI).
+
+ A monkeypatch is the easiest way to achieve this, without messing too much with
+ the rest of pip's internals.
+ """
+ from pip._internal.commands.install import InstallCommand
+
+ # We want to be using the internal certificates.
+ cert_path = os.path.join(tmpdir, "cacert.pem")
+ with open(cert_path, "wb") as cert:
+ cert.write(pkgutil.get_data("pip._vendor.certifi", "cacert.pem"))
+
+ install_parse_args = InstallCommand.parse_args
+
+ def cert_parse_args(self, args):
+ if not self.parser.get_default_values().cert:
+ # There are no user provided cert -- force use of bundled cert
+ self.parser.defaults["cert"] = cert_path # calculated above
+ return install_parse_args(self, args)
+
+ InstallCommand.parse_args = cert_parse_args
+
+
+def bootstrap(tmpdir):
+ monkeypatch_for_cert(tmpdir)
+
+ # Execute the included pip and use it to install the latest pip and
+ # setuptools from PyPI
+ from pip._internal.cli.main import main as pip_entry_point
+ args = determine_pip_install_arguments()
+ sys.exit(pip_entry_point(args))
def main():
@@ -184,12 +173,15 @@ def main():
try:
# Create a temporary working directory
tmpdir = tempfile.mkdtemp()
+
# Unpack the zipfile into the temporary directory
pip_zip = os.path.join(tmpdir, "pip.zip")
with open(pip_zip, "wb") as fp:
fp.write(b85decode(DATA.replace(b"\n", b"")))
+
# Add the zipfile to sys.path so that we can import it
sys.path.insert(0, pip_zip)
+
# Run the bootstrap
bootstrap(tmpdir=tmpdir)
finally:
@@ -199,19861 +191,26938 @@ def main():
DATA = b"""
-P)h>@6aWAK2mm&gW=RK-r8gW8002}h000jF003}la4%n9X>MtBUtcb8d8JxybK5o&{;pqv$n}tHC^l~
-I+Mavrq?0()%%qLSNv=2JXgHJzNr)+u1xVRS+y8#M3xEJc+D&`xG$ILLcd^)g_Juxq^hK-W7fVro!OK
-0X56!kJCu>>lSemZerjK`FeKt4O?bX9-iiWDY7!DYHK31t|U{{>
-PE#tZP_+VteGhH)eTGzMZy!aHJ(Q?6Cjc(3MQ0lIm@hktf`o4axNvVCTc)Ts4@VJ>@!hh%K`|2$iKE+
-HHx+6sw#7#MJW!3g|Y$%N)ur)tC3;}#CBEQ7CdI~xY=+?Ot(T=34r+9E$`%6N}j>;=NFf=Z&^bu!zEv
-3t>Ua&1Gxq!8;Ps7soN%ES($^#>_e*>Ru`El;Z0c`kR05XmE3{WT9s{ZCofrE;qGp;vO#hcs@DjeDR$
-tn@v;IglI6VSWzNghfplGqI!0gHwP<*5k}E|s-0tgq2{VgAu^rc%*@
-7HRg@?*fSPs9ypVK;PZfg`L*{@Wh4H}=)J&0S$#2!{sXR907wMxwCB>Zm0$&8dG^t{{SFIu9BwcKPai
-iS)37*53oHqWOqTV)O3RPrz%ERGmE0Tun4O(ssPA=8(oYCvxpzPymKk}-Q$?RIdE=IK(@bmxe)jVQYH
-8{VWs)8KiU3x%fE5{sAyYgujXSqq0M!Jcq(%y4NcRLa4k(bC--&}_#|G%=iwT(weU1)OKQ+;gdjz%u)
-oWwP6Kw|to?PIw?Km1kAC7Ms_kh)WuY*}FOiLCVc@zRudBQ9tsceu3uNfZ`pomDWvf`>KU^QgE|jC3f
-JeGPP6hUu>U2ZL8-0vz>6l;DW>Cpc;OqR~k!*C(#5^E>jBZX2(m7SL-6X;oqX)fNgKHx<25fw`lciam
-T?0Sq;<*0efo>>~_mb!wtQ8FET)G{S3%GLx;TuGy_0I*8^0_3ZXQ@aNJf0K2y8VP7S+U1FD)Lc1YZU5
-_=?sZ~~HXI3ze#a`M|s-Y_t#noGnybn*-wS~M*gQeu&v6y8yuxLY!d!A
-F!&;`Rs^bRcsWT^vka6lXVZTrPm;4Ks2igbSlrx(sRT^p6}=17w9Ix8?jmITqsTRyjGrANWtnsTD|j$
-Y4h<5(QWgT)wb!BhII2*G}|zk1yNsG$GkHLdlf5Gzaat{Tc>$@p`
-a+TwY7Wli;y;&R%LORzm+XNlE7>Vmn1j*;EP+Vbf#*@tWz5o0+$?;>TN2)pj76eCD51u1o>jxO7Rd+T
-^~TVJZ5V=f+fUt3~2+X?Q3%F77oSob@jkBylRQqf|H}cxNlq|euM|+Co9)Srn2x(&;r3@IQS4AF!H7F
-o8r-xn-D4>d|PI6qlSXmJ;9W|=O@}p6HPuvOHX05>OET{SlFW?YMVB^bOj7$3}o2vCc*b=Na9ht-RL`cQj!G22J9&fIo^m$3
-29+HJ>nF|s8yA0n&;d{IKJHp=j(V~BT0>~4G)GPEMc(VQAuvRl`;M6?1>952}1Ot5I~#MYk0Kxxi3Ah
-q0z)s{+ML0+{{$39}{osGDzV+%G3gnJXTS9DXfMe;)R!F^lZ>b%Fq4=Wdfk4}wCzJh`hBBYO~_dq4)E
-TcmM7`3(}e7h%A3)V?v$2PKRYqb~CG)@>9bn8D8{C!mRaF*M5$oJ*5h{7A4fUSurLlk|Ge9Dj35F+Yz8R+C*ftDqF;u_LZHS<>zfUP3#rrKI%~GDOrn(Geb3oa;V;xkn21A-6!o~;5)IrK3&>Lg$n
-YELmLl9n0XsGIFkW7P7W+cQbn<5G`uwYfk^6+2P*{9yc*!NCRzAqXJB#nGfJ}B!NvFOOhTfndqX%NMl
-ise-9(t=Sm&iY#gz#t1Fx4SUsz^%mm(E_;OVNHrzq3|yB|Hrue#yvyr>(@~yJ^SpJ4
-OF^(;kKyNZ_T@JUlux=BG5cWr9_}dO9aCTQY^g^RyvVq;_ugniS6F79aaVdkZH1IkocB$7G|e~a`MGK
-!XEswYXIAV1vyQFCC0F2wxgx`n?t@Ug!osc^vn#KqIIKVLe-1_p#*HV3aVasg00W
->1$}ndUjF>@ZB-R2u;rQ+EVZ$_M+hh_d^Rb?NSN{|#E
-&S)jskXLv=z{g*0oLz4Y%3MIH@hdj)++w_Ub=yY}Mo-b#g03!^1v$ME6ew7%D``6|eh~C_r=)A@uzIJ
-N=ON&A!*ch(O)=3CM}bncF8OaorQ9gI$?Nhg|T|4M#Y5=A{BwMaNvm<)f~Zvmpdn?c=+yAoeAhSb@87
-TMqdtzY}KDV&{B5+UyK14KGjFsSQCzTOv4hWZCpoO%X5b5|_B(AtRH1E(COJCKK$k!;-T@)v_JO?!To
-)%RJsP6QFy)qYW9u%;pS0F>J1x>2t;K8GzcH^9$#>PBA1lHjmwg*|^KH_x<*S
-=isHyhr3Ego`XEQrC#p5F9cRF;-Fkfs^?iV@3$}~Bb~8GHljaVSWu|(Mo1&i*{s&u@{2
-vB>ipRBhNi?@MIwmShkyR`VyPj6zz!LsnP`&@S*HQQ=7(&M}FoqXi;>q5?XVgA32$|3zK777d8C`@``
-Q>eL*?-`xmZezko^TratE%IrW;s|5rr@c=|$CA9;DDD_s0Y6IRO)eAR$E8qZkc2N%#@nudxO>zHZlhN
-2jBVZNHhBtEQG^Dy!P2rftr_IL518vqjU9{%mWwnSm9`zqI)V0jtcq>J>%|@n$Up{%CyZ>kbt$0eh+HnBqyweJn0Mr=_SB26a5@YX!F%-Jxjf(olZ*omrcHoC;?4Se^vyEI1TC~oScxJA
-ydY*9ir{^bUp|3fq&=IMai&S)*AlSmHC7Z!cjNpdQ`)7^W##r$<8wz4V*m_)V>32#VR*ohWuXOIH=
-sMUKJ;SFsX7PGyqBJzH9agmUcR4tm!(8=?0d&g_`7e6Mm)jWmUWC$m06TLbvadj&v
-W2y^Z;Zu-6cO2gdsaIxnc_KJlF8^$0_h`_YKC!7uSl|V7|pGHx0EY)4x)chSpS2a^%2D$kE08mQ<1QY
--O00;m!mS#yyNu*^n0RR9<0ssIH0001RX>c!JUu|J&ZeL$6aCu#kPfx=z48`yL6qa^qhepR4X$Ov65%
-(yx$r_O+A$C>v?Xk0z4RXq#_nz%vY>qQ1WfxkqQ3~9gVkXcZ82v&-nOOFrzI{72-zy%~$-fkObx$UHf
-Pxf%%rxUd8a|66~GLQ3R8vL7cRBF~PDAlJ+)moR4V01a?*}x!0kg`h%(L#G~Xb*s9h+(`5M8UCb&3ZG
-qcoGOQp;VW#N-&4rFgQZvZ8g0VLYnU307k(&=&*eVS1J1Pdg6a5y1w?^{XcI6_WR=6a(m`zGIdXf614
-yQS7FS(g!rYKD_V)ETsH=luY{RzM;)7bdFi;y4^T@31QY-O00;m!mS#zU7>o5o4FCX!E&u=$0001RX>
-c!MVRL0;Z*6U1Ze%WSdCeMYkJ~o#`~C_-MPNDSC{2p%hXssYvX9niy1Up%+rwf(&=PH{ktLOsyz49S-
-*1KwiJ~NLdg$W}Br8!f!{NM#WDo@JndIc8*lt;#kT_#f&ImpVp0SF<-=eP4oXa2xj#i@B5=vKfRSQlj
-Nw;MoD#Dhs$m)ty{eE<0#WEu?*t`{uDItC9)H?fWAWIpD}6Jz1HSc9wXX0B~C5viTIHdBUG
-8z!i%>vNb=)LD9lwMa&eMg%fp-Q_vdW=q?pi%`%?vT9l-C%(H?e4dt}F;Zg#T7KT5?yzI~o-?PLBaz+
--ptXP(*na_kM#Ejg*tp4B;Iq);Y4EmMeyR@j~`#Q~%(^RP8X)C8FF197BNLTnYN#p9I$XDsQg87Jbcsty96bJg;U%%|k^yG|c|#i^F%)%Dqri_5zk`u=Y5
-;gp^(t_{x7w4E0$I%_6OcqzCxkr`R@ik6~S&q$6d&C>sH3PRm@xRH@=yYK{71_J}~(Fov0iSj3d0bl5
-j3$!U3Z+QIi=;(-25FWVIoZL^0?k5j0j+23^=2oW>aQQ)vg_P!O3$6%uaHO2q8ckR%f8lX8JyuddAi%
-#Ua<1NM36A0pY|;c)03+utlX?gyqp}j5Z6%C{0e`BFU%v*|1+^uxoM1+}V_b*;_(0r*uOLpOd0J5#N}
-jD|B!w7(0+_2A3}5)uhDbj?!Ysda{9&TloE#IR5UH20!%R?B@O|<^k{5D9UXai#Fr3ab8ZLe6p{=Zz0
-QaDkhdw4t61o8hszVXrtL1o5IHzSBpS{mu?XgHL0R=^AQpA*cfL3MzWglCJPe;w8B4HeQKH$sY%a@Im
-r!CqS)>tHwo1)GV0?Q*N$dalc)h3nZova}dlnp8jssU;&3pJo;RBC8e9>uIoE9FPww97BVbCe<)mrVk
-ZCh;v&4xL5Ky7P6G@D5n6HXJ-R=YnOH{RRTY?KEu$iMH$`H#($>aM+Q&18L}LsIGoo4x10tA+1DcH=X
-G$Tdu<_F|t#sGmUW@!^RBqaV1hN=jgICQl(oCKB(RtUoyC`);48%D`OCC=3y`Ibi-X($O!*NzZ7X6T2
-UxmNGPC>U{h6PFrD`3q$|<`CmdX)jWvy=y3(`@G=Gs&^C*G8N>R|X>=Xu|O9-+okFh}66ta?Y3tNd=f
-&=MMS6_}XeFx5vaS{V0MDLirTGluqiHhcEW;JNDL2wt#MRn|1hZ27TQ9fPmwUsxZ1C!p|e1Q5Zg*-wK
-B3-4Bl=$FW3W|3=2jIeBy3(__YWJcGG{pWaEqtGbI2NKJi8wWB^_URR<3Y
-k(YH2p-{dA+jYpulE)CMz&?UkuYgp5g@feKK_+}zuaUZ{B^X(y8IM|vfvKtGPW>HHD`0om(?PS#Zy@?
-jPuTVEz|`E}wr{$w8YHP?%ZyY0luC3ds^x+nK2YNYu$oGL9f%;%9AONxv50hT?>TaIT~w;=1pnsG2ms?IwmnX%0kp6#2wo?A_d2h$Yz#Ny
-8QTNmt*H4QDJQy$#J|$z_V$T*hsPPNrA~ZrF|!Wldfl)Wj?SumPZ%M3}gxDi_JJs5WYkiS8ibV(FOcW_Za2SDQ
-Z4Bc|%N4c4B3{?DD!NUIm}C3Zet!gi{Y?=28}>3im9d;*k`35k+2
-;R1ySivda|oxZ7Mj^&?cpG%G6cWQ@_*Ce#SKK5e#eX|QM)LLHAkDsArvJQr~)5x3l%DFiO;pjVDu}Gb
-%%>j-6|P(=Fg!iT=>gR6bDfwtsr^tJBez(8|VKh`DgY(gQp+$$S1
-fH5==&@-?t@ZG0YW*kkiF4ux3ob1u|G-5>F5q;7?4C|y=sRMz>G|Pr)C88)T8%nG#s{{V;?E6L<@a@;
-9?buIR4CAfn?d9p^F{#8JtJ^hKO&qMGgusvPif0Jzwn3~n+P-n{wXjo|82T!~B`}S6K&+4v&v&T+*5P
-eaWQnF74R$`Z*XwGrrEx#GT3peKOS-tYy1Sh`;BMWU$sj3J`br87AG{u>clPt*=JtlZJGot4UTC6Z(%
-mlVP#f;r%&`C({O;HbRf`q$4EO=f%m5}t?Uf^mv{DT;R03JHhv*6lhw$b1ZrBu$o%e*(fv!x2wq+Jy5YzVOwQZXP{$~?U54d`oj!W%3HE&P
-^ABgo1mtGTvf2MNZ9FUp88L)Cbj&f3IdaqhXeLoPI+f~dE04L|+{rmlILcdXk<~b
-p0&lacu7YiI*jeB7ESzJyOnPWV>QM3M~+au!<*UOR%y(Jf;;bxgmbyz}9{z}H56R
-Dl9dT#o@hb?KJ9Js
-nxpgPK-f8rw`apPk{oN~e_?b@<1L3;L}yU7GhCE4YSlfv2WeHI_pXzSb5gZZ7cdTAZBRe6gqdy+Fsbm
-2s#7CJad_{o<(gFL*l^gMTae*Tt$Nvuqw3uG#1>=5efWP2?nHOR{@BiZaCxvHyM
-VF#?l{_Ks%H2Nh_|ok(%Xbe$ecUVJtCH8im~DKH)U;-Rv51SEMZvs;{qA{km&mhbQiZrp3c}X(%&RgsKik=5
-UnXXOXu2&h8Xrz*Z2NpH+{w{dmi|EL^a@*Lo&he@V~jQ1y)Vet5@dxs|}OTMnZ!xAzZ5XiEizZlu9Zy
-XxFpMq2k!+4afU_>JZl{M0~DnUuR~V_ZmL^q07v`Fx
-0iVsk2kZ>AISVhm30$Ds&jM8VH{4SBodsn-__A5s2JF^sPO1k{Q_a;}$-_o$lj0GCGejTjf#l(%M6Dg
->7LH)cwG@snz2^)JpG^w9QKLfpgZ++46J)sB#@xy-ejXGpMRYOvF7nJJ;DTHn8=;}#?*f+<^0D`z{mdb^RlwdZ-?#AkkffWC`D@l}Z;Yr#9i{xu@Y*t~u0f^@DFJ$KPaSxA-@kLs3
-ZDY)Qj@3TdOu`W26Kn&JP6JByWn2Gn^a>oGtduj)ARb%(|q5HXU0M8-3b%Eu>KTm*NC+NPq7qI>dP)h
->@6aWAK2mm&gW=X57{yU}&007}A000pH003}la4%wEb7gR0a&u*JE^v9BT5WIKxDo#DUqP%9NJ`i0C5
-L`7>O<4K+!-h?!J+9F#}&8|cbBy!3M94by`ulUGklRqNozZ21kSEB9L@~q<(Z*ZtJUABVnlSBiuC_A{)0gN)M*(x{6D+COf7J&1Az{S{I
-7{&Mq!43Sh{kXp2s=Eq^Q|BR62rycA6bTvNIF_m|r*#cGWYZ!=g?)>J9-MKY~Vzp%RdBxFN1@J;;z<+
-mVlt63Gj&aREz-~;bShpRc0e+Ib~IWV~q;4yn3CtFXCpN2Ef(RIxFifzGtc*}KBq>9zsHF-_t4%B=7`
-r(M5+(!6wX?b=6tcA|l^h%QrBedqbmR01)^?u-%o1I`sl~+uak{bsecvhg9qNi!-6;M-2!7QYP&?jQ+vyj
-`6(6%BC(-d}6`NhEI8kaSW_?i&NRW-xqsoJ~LvnI7@claq=6PE9;Nt#@3QM9Wos~qS%;pY^(_FFo$J8
-9rx*@4!*k(Vk@O3(VH4NU1t~MK5+AwEs5N^7zLhS}6Mz;VYOmUEc!6Y5wE)>N;HgAq8zg19`(dZ!fEY~8|sLoY
-ZDzY2-UxdjN=#DM8h4rN;SU&G@p}S1|Zq6@xr64T5
-Kd0t=VwYPA^CdtsKkzXpOr4wom=iwZ*e@?~ZA&`$YWsX~cl+x5q>Suqg+wc_-HSj}@C{3b70$keOlR^
-D;zjd;w`O&&x|(b2efQH$u=>`nY>pl{j^OrdR{?5ocOTf6_O(_q%w2%KBes1H2opf~0+j8Qk?g&J>^7
-%=F(L18$Upax8{uD%n}dFsOe-e<HS7=*(Q(v{8Un*0idAwK1RC@-u|p0x@SUhW^xlJzrK_bG9QleEVXT6^qL!l$5M;
-EaejJXGCD(RYqJuO6T3Ho%&tLrgMLqg?>EuIPQ75A7YwAD339HBITZy4=$Vy8{5$L(hL
-oV>FZ4ubX_{Okx(E3dvdygcSHPgC2G@0+>lQcGVUMfm5mMU{=g+1XXL-pqqT*z!o}|g)&|ZGutN@K9%(kqOXm4PDzeLR3BWWR3CHzt;261sLi3h8%GodOv}Ynu0_M`8X
-4KO9AXo@oLt{CBMq@8j!f(qCJsg=a^e`;vl2?#Pkvm#kIx>tO4NgX7
-6)*}9oNTGuhtMNX2-_+MF6*CoKxu*lqxYYG{dD_t@#*#-ACuX^!dXQe42y~#TEHKRSRw3XFEO2>&2Um
-ij?5xQ+Mdiv?CQuX7KhQ8E}Sc&UDDb7EDN`QoOjiu=5au_kVHZ)u=GW~J%jk6o*2lWXh-!PvJnWO(%|
-(1;x}^n_A?}X0r0;Z00r904ji2{#10&f#!iZ(CvlC)0ViX`G_?!tI?09P8atItYPm77n&6_MYJFOa4k1f+<$vQnPJpV%Kk5U5Wp$ci@4ZzW%7hS!B2F%civg`r
->SETCAurYE09H^|I{RA$tW$}Q(q&odE9NsR$_w@i|V)XYlXkRSk9RQChS4L??%vA-_1kr7v&S*k->B|
-cFAn+|@Zmq%1RL4pjO+ZLjH7bWdu!QnWvD3i|8$h060XH`=Ddv5ZMHmya4T!iCCOOwaJQ!ZMw+RcPL@
-!IjZ(_koEda66EISihm*j1J4r+c!*^4E9Qb2$Eg!A|`%R*7!fde-^vd7_mSF=a&NeEYTkh~2y=T|pl*qDHEd(E3n
-WL)6<-C#?dW>cSlht?0A`#7+LZHwJ2I#VCTc&JW)02qy$rp!yicdcpVn+~edgi~N&cr(voIGf>Z&*HK
-vqFEK1)jq-0G97>2+TFcUxDzB~g<}*mC4jo?KtK7I?{Xk$udIv0i(XH40cd95-Xp5SYKM^z0PRRyJxn
-AZ=|Vli4}fFw3op^9Cd^7V*375oaQcC0^D)DDtBiL8Gzd3n(IhLN_A$J=vER0cPVs9g`c^NEUY(oxi{
-ms(*Z9Ng*>*U(x78*}IzIA=SL3TZ%i|yF|q&E<2fVzXNIqOYUDHRSCziq2P{jL1A;15g|L1doez
-zK+5wR@x($gSQC>iV<-_^?wU$kadY-mo@_E6_*5tpw$D50Va=Zu1m*v@XQq;4E;nRHyoWLnV#{qe9hA
-JW;GqKy$vo~MLj(~B5kY`yQ84<&*2c5A!QZ)LT}?}tCWX0BPG)cy^E47d<>W_Gxl;wUnwXQ+WAG;R
-OSJh4?X-cZj^f5dI!JE<2+h{_xRvCTBSkEe<$FoPj4g!7{^S(8C`b4#uD=w5y-zxMI4eYGA(rlEObxh
-{~^_ovPu-310jNh0F(<)(;VX?pVvr#k+MtEN3&go@6YWh2;MUWeJl+rx#d&CN>|`D}+tW^yS=19{nwINd07g#2`ib0*&6fJt-e&OO5T@w~J
-XO7RVL`m?ShBbD&?BG8gT5)kqspZLrGO*<(7x2uURQ!w_quGV-|SJ-1c0BZjW*|0r5aDe^!l7~HmE{7
-$91za{?z5?;zz-PM?;9nD}y^Nuyhd=%=aPWk{^Bl;Vd5j0iH-ijjDtES)gVDIMCj=SDtyxEZ{fNnJCY@Y^+6;dL$c%gE^B|4>T<1
-QY-O00;m!mS#yynKB`M5&!^NKmY&{0001RX>c!NZDen7bZKvHb1ras%{yyv<2aJv{VNCs4cU9PdS(}W
-hYL1`%O;ub;AXmmBr`X--iAQSw9SnyX+sEE+8vC7QL`j8=
-I$mwCQT#0QvGD{0C?%#|)y&@Y<~(35V~LT31J7R#zq#Ud7&Ea1Po-U@))sL@U
-KPn`6ag8Rb-58~x@?=aR%t5qrYh@3$hj%=woxg6k9gd&EwZL8bK`~q{y?srdtpJ^kL&zE2)sq6OvT;L
-H#fIecX#Q#s~>Nswr^xdKFPWOq8hslP$tpELVb3S#v=iLKa}-GHWy{l)MY*u%T1GJO`fiSHn~bSumhQ
-=>T{O23)OcQWjfb|thZAF;x)HMrB7?6@=3q!rd+6gdpFyg>%K29Gsz^i-9O)5-KH1k7w@jp%j?^zFm;
-wzHOScKep1`$+$3vh)~cI#cYpig{oC~2`Q5v#yU}O_VktKAL8Z*Hl;n84V!{zg>&Yo$j~v5)Zxyhs0I
-BeaEXw&`RMyY{nk>X@CO}l$4IGq)gk+(!hQ&25+d&hHShiN#LrMxK&(nFU^F_+q#^E)!W9;YI`?65I6kKW}=b+pOxIye
-IRnH6%qDrbQ=p9c1fSwf40|y=_p8{Lt#&w1DV8>TTS($AzG~;|1>xDZ5e)O4_)X^pmWBK$mQqdK|!*iegG@uq@$Rg!?gKrr1%@R7
-A`lzs2#-HGOiMki~Yqk#L3?nJI&vOukK;tl)N{h!k=gH-5M+){!C&(NrPqp;a;Su@((QrcK?dZVH`
-%vmaz`l!sK$t?0Hb$S2UG*Bx|$(BVX_in2y7s^U@CWw8M>FCJyBQ46s5)8gTcdUzlvOTB7qvRMgtOr|
-5)daeH2YQPU5q0I!4hxUIW5VNw#w;Y?|eyns~;6G4)ku>HdWgsc12WYV8wI;{p{1BlQ^g22
-Mnz6H2y&}8gxYxj~IW0^A6(wONT#>9pdk`JxfmSe7F@6IrUjLbXI^dsyU3rUl|D+8KB^|yp(`rrXWbR
-`5FrPS}SI93ecK0cmq{gEXaK?#ebjQzQ2C|b}FuJZ$I2Ju#4O4`|FGIA4OiSRxmDvMEcB3kR(797;;2
-yzzDPw^kcTvxpH4%p1IRgC;j&Z%oH5$v#65II`YU8-9Q7PE`<|p4mNN{Fdq&%;01<47eKPZXZjMP0^E
-G_K)x7Fa3{AYXY?Jg(Lw#KPG(h?pSOoaYDQxMEc}*cTPZ}K9;_VuLLJ>zD$~m?kc?LZ?TYpejji~ID)
-SVBsi(z%exm*aS{|_x{PZLuUD?!{Jc2`*+ED|2=C?7ndPnTv_{jbwKkH4q5kp6e9+nN*jvd8E+Cu3Y10ju#%7Sf&!+6`vyp+R@fBz=XJ)mEZ
-FQ&{M6l08N?(PMagCop`aAX_P$Lt`3PRLDl5S)f{9+=re(7d5zpg^&ZL7fVftP&BM$0Bw_add#if(?5
-}e2HWZ4}^KpRcdV@T6Y5O}e9P7-;sIk~02nKdvGs
-(lW6qoEeW4Sl?ZHvSgb8L>@>4NXCGsO!msgvPx!w%{!
-hlAeE7Wck6zm#1=M$Rr)38bKKPebHo2R(E%$63A}-Iv8=DD)^4WSS#(IJdBACSS(?nPJ?|cFtI3^Ira
-x!L-u$3LR162+nK7Il30xr7w2N$VycEP$sjN+AhLM@J~VOb#=e#GrQs4ck^*zZ9?19Wrsli+BNNI|Ktw5{{QgwU*
-xY4i+6^JlfKG=F)d=^zf-^z-eH1KMDUD=~Ug9sB2LooH9lF^zYY@yEkSV!R;+nE^JKA}Y1f;
-mfY@@YQRSC9_eV1BQrP1IxY=Mrju$G0*N!?uCh&SK;Av9-X76?Iq=K0O_M1abcg4`*w0Ckm7PcHQWy~
-Y5FHTwp_aG&&6Gc~nLJDMHQO{8*Qg3pK@r4s-&`xHUXiGzw`pO#_nT;U?f9)tX;EMsU<#mO5(!p7b*@
-D7?hiV#&iX-dQ$GpfrJTWZxU1(@dGWE)+MtoOM%Y`2_`xfqxpH}`9O%=ns=U`PxxrqDGn%LmGWG-3w6
-c(It}x_B^5KulnOl4YlYWCBN|G~%c@EcqbzFn8pk2lllr@5Ck)HjIaMvEfZX-x;(IpE%T1-k~E>CdA?0Zi
-c#(e1|(`hytK_?a6Y4X7W5;G!K4M9hKcWgLiZ&M*G!{OwgV;6ix6(H#d~9CL&Yfg>>^Zw9kz1C0I6`0
-&0q^E5!%5g%q6Olqx5(;O$g9X-R*JB0T^nU~PLqw%{BclYnlf4Vxt6Bjhq4}7tO3!$d63xgB?s8HIcZHK;-Fi?3aYioZ${n={^BbVx>C$B9aqyqN_^P_#MTi}`V=ui6pJdua^$lHD?7Y7?0a&gf8ja(e
-c(_0!mL1zULz_SY($=&GPAtA=jp2{syJa9;Wq*fim}>n_Slu+2
-62+RbrGoUtYDr|ei_585}IVzh@tTO41w1zeiJfFI_&0v$mlk
-S4E57dv+rw%gkIA@1IKD>Vng|7LsNYD*=PZfXRZzqdOMW&^VOZKXITH4z6uy6d**T5wu9*V8j#hS`=wvpf6QI~n{$W7mU0vaILi9(xaU$C
-M$7@(O+B*?_Sibrc_PW#XWYF<7W(!~sc6!Xp`qy87Jw??9C`!oP#n=}H5R5FN(NXk0+ZZuU
-!KrF&>P=pr0N*e_=|9^HKn+GG_E<2{ZqOLF0UfS8K%D<~yk4H>O2%AgFIQS=Sk*M-GY?cyDs*oy?a@}
-5LoUIB3~&hM`-aq~<02r|vr|G0|94xo$RjOUhEs*r(SA81>%J=%9>l3^rvvnF{)6vXhqPvxb=
-@hU`)+a7HfJ40km?p(*C;)M0Q%w^-PZSt;XcPdXM7#S?L!WvT)tt~B)4;uQ9Ix-VO?ur*LrK{h>%Fsl-FR4gWHo}w}wFAo`Ld922t+NNVS>
->j}{4o+|Be$ShbdK%Tq_EoBO{DbBk2dW1lopRJY2qK8qk@Nne^b#5&c<&qeC$*F(+b}Jy??y$-8kvOA
-%j#mL9@pJkObMAw|*h;K8YJh*bv&T#AQHBg`V7zK$FIyFBn9Y-RwccIH;!$e8i|9ZZG!HW#HQt1Sb}<
-k!Y>|h>loS3Bi3wBl?%&`Fsp-CDzJBhm;Lu0S|Dij@1wV8aRr*X#U`+cvx6KwO}gU)BnX8^N7npoG>`
-~^Fb5Cxfb#WzvJ1Qk*Cq#&ptTlKKH~1-5SqF2YaG`wm_u2vqzpk9e)A`pX`oXn%OARq!r(19p(s6a`C
-d6@uYpc7{Gm5y_LPKKxw&kOW1ohU9dVv$AyX&!$Q+zcn9^EgPXws&;ZdOqV4D(j`eS!WW8!RV&?*cP9
-Iz4+SMaF0rRiqNV5T>#;DVU=MnyIA|b0-Ft^|WJD(z%ky&LS#l9QKWxj+bgHs~#MGoSuVV@@P%kup0E`C|nm5VqnM$N(C@6>A?1P(L
-}lvap`41Y{DHYvFnk{pXAo0ZSlXlIxHps!`6-`%xFSzJbg$nvK7x<)}K{bx>jf(R
-?e8?Aski-5Tw&@EJF}j<0iHJF_!LP0{lumQ(3KazVE0vBm-WtK3R}nVxo^f^p;Z95b1ZU4G-xk730M0
-UbGZbNV!m}mojPlVv(L<0{{GFsp2~T)P)U-+;?;ggmTwbBF(zY4Da+u&*t5H^h!D;=y9V*z7?S;09Ei
-R$yo31P6sT`3rD(9IQLBudVhmDgpIxPxqL)^YPOpVJR9jqfllEwZr-qhgiu!5$|w3FGP2_n5Y5WfT
-G#bLkXKYzwIv%oaFG^77Hg$Q9#oa3{SP?e4x96!aFTBo+RGsWC+8ObsO^9<~{=Mk0AGSMQB()?kl-p@
-V;})IRm-_W0w`nC^%~=z~RdfcM8Wml|~pjJ8Eqx=AOjWXNh%Dr~71WiNc0Ncke2?BXzitnO|oFGzi~k
->?P03YjiBH+~MjH`4paew?IO!B<^)e0_+_>K%`QVt)5H8C*nQ~VYO57R7qKMnITqJA+*886XFG9n4~U
-y7>AFTz)bLCN8+eLNNMTl>!UL*Q$5uGgvf800|GJ|z-7HtL&qU-I;Q_K85yU^-
-soA3e?JKl5_cf4F-8zJ==J{iUfgy>GBJ+dDZQER60OpD8cy2Lu(n9(1pm#7jh}+W+b+Lj7Eo4dR2nQL
-BgQb1n@J`84`FI;ut5-;UVwzGoO6)=9pA-CePuPl%w3aKM^{PqV(jEMV8(>w9lUU%mw~*5t#Y4((~-L
-W9Zf4xcBQ_ug0hi${sDq-Hv3_v>QxR#j;}7u9l^mrL_?ov&rH-ALQEvY$3Z+AOMiZNAsid{QeM&3@b3E{$Ao7I
-`5L4w`y~)@vd&=fxMl|O(RaJ@$f@l<_i3R3?gGiQ$v1IwE
-z7K`W0l{=>*`vnxUGvKpP2zSX|1G4mEgw-eZPPATK=t-s&N45Cw2t@ih~YMAg@YgAe@$}NeiGMJfs;-
-#fwy}e#q52ZRV@4>$=KhVY|KAzB%pQ(W;tPk=hh_BX66jsMk#`zXmK%7T;1ccx@bvAo7pFfyPoDqz-Sbyxr>|d~O~oAM-L3(JIm|dw?QB
-z5bE(uMm`NgwvTPD~8a7n2X*W$(6)
-Ksvd6AhOXV2fgfAjA3>z8NA*^AR3!fs3026NLEKf@;KA<^ch#dm;YQKi|Nx?0vijBisQdHC>blb7C9i
-fW#E`{<^IH3u3M5`L}I`byTcKwX#Xxor#|dwV?C(y+|1>HC~uUdL&cZW>uznBS&KKILbyh2On$iI$it+RO+8Q2{X?s
-!Zs#b0yWs(KU}agVyveWSclo^8(;wL*)4{<(k|2{OAd}C>NLYlMAV%JFo1!LyKmjgp{}c@*;qXJ5q`UXxuQssHB42@mKY}dl
-Ac9LQl@Lr)Dviy$%SYYFea>h*+dgoUZc^7e!m5AQxB>W+kbspsumkF-w~i#{OWD
-9_6f5WIZ|-A4Z4(d>FyAG>LfHrr;!ZM1ri`H5*AO`OKC0}8nYyhtSBn4VT
-J2!x>gZZ1TP$;Sh>4Hh)T^KhJtbB25&PEN%5*&Bj7KDJPHbut8ie!HhfP-Jnxu|XSeoq?efs3ZWn*;?
-x6<)Q)sP)HCIg}jypbzJ0SS~xxNr`HY890YfM{M!rL6GWl>OgNuJuu(jUf3ET}^2R!cJsaIl(9jUKpi
-=vTcbI+}Y5y%;)d%8Pg&i6x{s_`k{U0p%XUcul5ZkS8Aq_d$2=QdO!W{kVVKaDeAY6rJIp?r
-*pFm6{av^K1Q!)R!dPIt#su186Q6fn;t?I>Y1D
-$U4&xJ8LE@`(Bbu2AoGWSb%M6ThHUC+;*WziF=(;0Et+V=O#u9dkCTo+`XKtiwH*8e=(>kLfCbYZ0cN
-+#%iaj*qxq)wf!LM|#8W95-T>UQ6^%looWLnqbd?t7z_-=xYcYSj6P6btK=`vk@goKAN8JVs23l_2XyW~j$-x%BM*xc{IBB;YUcDP#~@jfE4fuC=%8y3LtAHFq)Le&U@7zOs&$%|)})V&sSm_p`vuIR
-1W1)PNfLo}TucQxhU*O)J`A>_8orM0TUcK19$
-Mzvzv^o8^zPA=?bx1~8rla&Ogw!&+{IT+d{d0laxF(Z$TuqEiaG{fQnk=I?P$zI!zKS0M1?$@$^q3wN
-+HJs2P%ss(*C0f?ruZ(JOPhSt*fn5f$N(_mBV+~Fv0MUrMl
-HH&r09zc#m+t!z1_~w4_>s53y}g4i6{~FWJT+oT-b#GwNgQU}E?Pz~VSFlu3fnN3P+`X(D)TA9x0
-^y~sr5PH8l9h(zBfNKMyAnd%G2lm3G{
-cy(K-UUcS5ggXvLn|OvM*pT-~JgQcYYV_9vK6S%Bn7VJ*@b3K9>&DRMf{34|}LIBeFNv?KxabL&v;fe
-=IyplMyT%N5ZZc(Y9l3(Vah_zX>;rd0{X`NVHdaNy%$8T91T=D^1pu`MeMgabtZ7gh_M+pH>~&;;Ka7
-%V*dcpwm8$=m~lI~51aEz}%u0t`_&rod1)ckF)q_C$11>Ac*upf=tcKo1pIf8wDCginXB7L_9e<@?W!s>Ok%Q
-+oYlSK~QMuSBjuU2F-3noj81bM$v3c*TIueu=kMq>gcO}6X0Zc1>N_A-qux?FLKfdPTEyFU*J#4h){;
-%k~OZ*6!*q*-LSXgfzr|>!R#x5vx(Svi9sfM+|3uZF>yI&{~m#do0p^h1XeQ5FmH1*l(dLG^!EAa8KZ
-Fc4#pZCdl>c8f422YSuUFuw6{~G^kcun%TzUoKWK_UdqX_G>Bqo|bJhZVXiEcdOzYVwBl80}Dul`P)p)ww;wUZ|fR0y1bS1mO=m+=@h36kv9~sA=*%)+5v?|Dmqk
-iMh}32UO_M&S}mxT0vj%J)PkkPoj?+}*n!8x^k7FNHWO6>DHopYz^%3p0MG#<-7ikflBHgmWGBq0vP2@^Gq3ds#fY6$ss#1X5@cWU+X|7T
-EwSXQ5=h&XuB6Hv*)2bMzy15Tq?I0LWhoa`IH0fePMMEwU3kFZgJz#Ni9EDAHv->Psn~(Ej@Y|FWUI-
-H{JCg1mJ2t*1|u<23B-i;TnxEb(Er@pfH+&tPDI
-CFdUftVQb{;ezw($raOGEAPl=qo+oZPsQnL`Y;J&3E&duq=#VRfLXrtP*<>@<`g?#vZ>CsEM8O&wtT(_AelZlDTS70$;{xjVhv*!UHyYDy87p$?_PAS*Qy%RbsUMf47-J*5WS>Y*JYU)40YDk>bbqg#{sVh~jG13l(t~)BcfXyK5v+USg&OzQrvea-2!MeFLL7(M+Zw5RXvvlct|JbfY?Q!N*NBT)+z3Zbp?(Vt`8O%!
-*BQ?n;Ucs7AZ*V%m$1_k3LnM@jl+v=q97KTd!qps^fq&uJd`YemDvYk}OhGX(vbVlixW-AVChnG>#aMePq&Czl3;Qp-B+eC9_$DwWm$D-&(=z18t+I9f4w^v?+{4-kG?Pz>EMGw!+a$}5KoO
-a;}2NI|iu36Vc0_a7`x?Rgj$C$W<@`e*c@D=M&j~_h}@87-zmsmN_ZX~jpqFg+-QrHaDnMuQsuW`-mD
--;C4Vau{2_QA>(5(X|X7|vPtvPZBXGi5*FNY{`6h(-oI%4NEcCp(*S>ktz^|4+sh#oBP{pg7bZINboi
-1tIpyE}4L9fF^T!XciUCKuru$~B2{#=oO2_NGP3%fLbzNQwpI`*8H}kuB=MK9ij
-kLi0-_sI9NHY*tmKt;KyV##7Sd;I8qkg|5-ER$fI_%YkK~Z7a8=OSd=qYyH(D`FFY6;JFt+T^uI891o
-*!l9@^Fou0174hz#GYCH#-3VIEMp-z+Nxw+|((P;EX*=Pqsrx{U@)8_jc`4yu}Os*SY*!S7$G>5H=p?h+id?`HY&3_^&+6K$~*l3ANT
-*)mZ5P@kU<+WWeq`%Q09|V3gq^7^rZ@0;ysWEs6Fr{9udSn5H7MQ{cR~4R2yGTE
--YccKtdMKg}LE5i=d1^T0pv*fZ;~jeG4CMHDOexLB7enpv7qG~tNar#d|MjnUn&Hvd&zIOW#3Y{rpKq
-09H6FEq#iVzXZSni`7d05zUs~~{06eLr4Div2|GE!xzqF$KTU#}97!L;NtTW7SCtC2*U{PR!@+Rt$gH
-w^%WRF4dKzx7t=O3OQgDOYjk+~k|RQ%CNQO!OS_w3bO=?oQYL$s|EHnXF_l(I>ca!F5&c|Z2Q-KY#jy
-(vjXEywk2JVE`x@MmD8*ok}GE?U55NwY}rNOJ)5^>7~bUc57YMlmQ#Cje4L%yevYEHD%C5R=#ufS))b
-#+ka7)Ld(EaL~yc%JId(Q5%32)#Lw&kk5Z5mH8{epCE%klhet;zzz?)Kl&m%PY-{&nEdru+l`e6A6tq
-j^JMO9sa2*|HcC4gvfgg0_RNiH8X^`am+RX)^;53HcXb^*U1U3l`+Xi4q?pwC
-&}!3H2w;0JSbY5~u&*7JIDUv-+t`&`Z}6&uDhqjcRF_r@W@AQj$-*dF)C3#$dU0`(
-*T&s-@T))uPcv7&@AC=o(j6tAf5n+C8i%Sn$-9AS9+pWJ;J!@j)_BqQyk)`aN)~Lt&*}J=6Wc?Zna*d
-ZJdk;EXo8S;w&Q#1{F2oCQe>1lEPG)WVl*PNl;WlgrixuUbBN%SzISm&Z9I$MSI3`p|&1G)_N$f$I#9M|p=-(I4YPQ7>udQ(D!A-Y+s3uG-ya(&pEp@Z)7m=FMCGvL1ddFURS(-HR`+iM
->54>v~m-&7bwQO^qBV#EV?DQIsr?!a%!66ZN}oP@1o25${dBjNUd;1SVxF(bkxQGV#Jj`Kn%Y|5*+6G
-diNEoXc^i}UiBY@Lw!kZQNDwr|1u
-Io!^hEW{UiNvy9rkkb5@-o9nHP{HiMKyZwyIfHX*)%hdGJR5>ro(m3%p0amiEb&
-t>VuUupgik{LcB>q)k-i|pm^k#Nu7^1phIplzVIxe=*P5ZrA|)$NpAHg>u*hV4s^uyrhr#wN-JScrVW
-@qJdqJP1c}LIkT~d$I_c^T=<$59z_{_Xe2M2u!G-(Aoc*eN7VGIxKD^@Wqf%JDbBBC}4S-A663%e9+)Z8@-vzrgZ*+$NDE
-FDgDrL##-cE_2C=5ffVQxJ36Pm67j+bt{nIgnH;809UV~xUPjdauJ
-AEdyVy4kh?y9&U-?%DywhKe!n4*SsLp(R?*v=TWfQBf^+K(H8esaD(zoVMh+3RVHBcD)0DnXcQ^S~2>
-3l)*;!g93UUsM5g*!f-t-4qnT^Fv#+(=JU4JX8aBSJb#g98JZ5J`tiBB!Gy(#4g%}|k&$6Z83s&>byU
-TqF$%IpzHGr7={vF9|4^KvyUBeNqYtFa=S~40U+X|A=yV4dVX2jyC@Lo$5MCkmF(m!Ga7&m&INS?16x
-dF3y=k^Ry8Qh!**$oH{JeFRe%CDafG|g@IFm^ktZ)j)V);wH*$IOe{+{!se2$)|Jzs-~OB{V5pk)Rj^
-qTa_gc*rSV`XVT1$TGyfG{yM&A2e`G6lIsr&&3_y0hmnRrbz)2dr87H?enJWQICRt5K(Mv}Eu&{)I2Oc^<=Y+ScP)`)t+F{+i?1y9DCpVP8a
-VhD7*&HMy?BZw8ktL?kYgSy5j|9skxq9w7k))9w24pOL2?dUNQH^L6Aw;|cKDuf=pIBF$In1SUxF1mg
-YULmJp|rUMnjX_$G}JZ9%vsp?J_xQm(kd5NOloN{>SW!nEab=1eh{IzzhR6I@nDP-)8Kr*8a6uL8iRl
-APA@0Kn1%<9WD5K%r)nv5L9C@?M-HgnEJZ6p~l*In^&7H$7Z@5S(p5BTxD$NdH~kzGp(Jl69tcaD6s)
-=Cum3C1No>z*d>oiWnoA83T_B&&oJk&=9R4k%=f?0N$S9CMUH~4!tp}Y0qQ#wg!Ro#rmLl2O9LEi
-vo&~cn&)b-;KWoP&lu4g9{0^1WvHm?5;(+qk}RuXE4X{_jLDzN_UQ2$p`
-EID%P6`s~3}yxhp4dq=9>eG}FcZZ}@b!R5O9#|8AcFm%|@T4+14_b<;f6WY<()o*tm&9w0B5o2FRJ^+
-^#9X7kJ6zpx*8(iQ%R?~3Mj@&-~d>*~@j{VHuW?O$|cW*YBDVTc6{?x!fh3WhuLI_Ij4bE5w#%K%BO_-mdUZN{Cf2q39_-`Uul3@SM)oF(ygI~(lrBU_^_W{v88jarbZouxG{A}byla
-ZyB%fEEzES>MN-=}K3Bo<^qo3_=;9g$l+B{ls&h2SmY=#noYEWjq!Cf;@K9^pL*62ELU^&5ic9`Z*;|
-=Y_KTv9QyaN@K(t^6TuLHF-Kq^-s1rNO%#`Q
-K{@dO^*L2lfyS0++KFwbV~7)?UMgLDmPT1j)nZcrf;3t2j1FAWuJ+cC+}5ufVO#tMuK~ZDsi16mbV=*
-k)oHT^QBRa<#mPBrp2P8`Lcl8+4qaHxE$IpoGdaB;eD|3Syt=B4R=oRD5AMCN
-!5^cDI+Q@j++-&XS5kmqH5uNfmg~{^vID
-OJy9Ao@WrS$z;VJS`U=PH$nT%&e*brPdJvB+Mc#e?v3=eNtT$|b1HWE!+ajNJ?Jk9XBeuBCQ*7Fu=U}
-?IiLrfm+ThyWCY1azUM!y?OB;y?O?p|p9r(uqTo;CWk{Cy$63Csm{#lHIBTb1d;&q_tQn;|C4p`ZO@m
-)uG@aWIfob|Q$fF-jk+tNYsS*7|EFz81vT0L0Zy=38W>N_uyZJa~>y-J$y8mbRt_lBwQu^7|+Rj@$gk
-G>bvMdCgB#Gq>Q(H*+a*qi<*m~k4V6aCv>qt?Hb%V2U>nLeSZ=?_@zPXQ>d)9!AMHNYchl$+l52=?eb
-9>Cjut(le`^E#*8`M@ne*k7LoeyDWPd8rfenD*-RfH7i=nsZ|s=N|XOvx!)KVBqrtzH~s>G~<0ey)yv
-pM-i<3a=Oq_1$0k;e0E0P92%l#c88n7{PiCW!s>+3SR}7j+Sxdm({-s@Pk12=(*~6n*KU%zjwVik%i-
-Ss_&%^-r(JAGhcg14gTBE`@vNvFhVY}iJFFlyi2+#={g(1$)t2Xiw=HEttj43b()KdP5^BTqQ5KTV
-EK#{p(lOuce)nk^7Bvd0`!I?dOAIOda5%d+O4-@qBQ)EpcQ%B5erl9X^Su6a)7FAg;oitsAlis~S9xK?h|p&f`(ZaU#j(-e2cjEbhkr480z+BY2S27W0yOe^Hn?k^j5!|en+s
-rvsi2h-7i>%9b{?@SXj{|=E%!7mDEx~%Eml3M6>nyCPB9p);TZuVC-Ij>M81h<7ytkI=DU|ZL#XpIVv
-lsIxMG)T$`<5vD&*Pn1Se%!yK|DNL0ts753Tk8MlOU;O>Z2Tm#Qa7#77*x>Y*hK(`R~sxEW4=rRsKeQ
-L3#S5z6m689*w>=#q^fb1=<{3MJ`oTE3y-NlrHMU!`;y1QKPlZzy~V#wa8_bQGYE`sdC>WU&iX*OYbB
-V8rUH_`ARH-KlE!~OxppX9g>=d-Fd1jVg#q$_Y%d9BMD#fxeq7j03PaBT1H2?j-FDs*_C%Z>T=9t;yL
-a}4ik!ns?90^}ik4VT=~?%G!E*j&!8$Zw_V5&{TLPoE{II^3-)$D2+j
-!;l{bb+)GhVPzd@2K)|2i8fdJJ#}pB**iBVm`O?5R3?D{;oWno9V-|DtG0;4nQ!x#64F2pp{d<4Yf3M
-kpr^&y^#P>C?gErgt_%Vn-yQgVLgV+-_*Z}Js#^x9j7n>LrWxu0s15A!JKHBhjVFH2Gl}LSF#2X|kyw
-DisI*qEY)}O%y;mgwgaV~>r=JeQyuG4Pp)XwyPILAjQHcdt{I=b^^u3bEa9}RTwC~9@+1VW!z0LqRsizJ>tJPu?OWtR7^O|PQ(7K2KO3*`yxQbbZ`om0)3rb=T{i=F0DceZy2aOMrtGp;M%hkREdCH{=x*gbF^5g621FZpgfh5R3&M4G9L$R<=`Z8?Apo4I!^X5Go^w^NWz!|H~=YG`|J0
-01Efewa=f*tRaG2O0ve5n?$@uO%gf98W1@;uTjNFLRVvDjv(#i}YRrxp
-vL^TN7P$fdVgRjNgJz6j%Vsa$Do=Idd}Mrtz_YgjIp`>}AUP_iCf=wiCqDwA3__4=`%Lq_l~_ZJrzNh
-ZA)pL8*I&bnda@@RG;@PdP{rB`H0sQNqdx}JG!d?~X`(&xcMZR=p+oifVF>|j8omD6S|bZc_k=oh2^7
-qgW)XZWr5rPIrbKL23LYg?Igc(jGX5_eM5!R`M~Y$=vXtjLNet?)46S9^?f>aR*Wl`B)W
-m%lrF?5}mEK1t_Q*xs|9Sl7FzLBb|UMN;^qqsl+x|5_W~vV^|CAg$${gCM!o9EJeYuT-KWhFCZwgOw0A_=o-6*>aOzil
-{LJr_5<9l7AHiHK@b+n*3}Lb`RuXtr1QxKdH6njQ2SSz%$KPYY9`dwx>Uh*J)U-%WIlT37k0Hsh}TU`=EIi7v1nUbEExO6qUBN
-JRlO4!n{JSTqZ32aW67JHE^WFWj@TDPOLu%Z%+#wevAdj8C|O1fem8^ZpH`b8kLiGCtogTc_87o8cZp
-io-e+ereR*~!PiikPIu6OFB9i~V5-X`Q)Lo))Fqvldu31d3B?YN?Fm`7qYim=nfobJ~le1(i!N7E?Gj
-U}oeuWP~%i~&wiTy&rEceLp)k-Hwhdn5>wW-8n{k<4wcBdT5O0dEqGlp5_UZ@BsQmecfpz>H^6tMyxv
-}9vSE=gcirqIS9tKw#SAR!omYrq#W0V(Kxr6{)agA!lgd~R%{ib6=4MAO&6CRHdoJ6&$3;wpnT4=~^(
-V}?}a$dxS%5E(hL)t5R6AWd7SQD6czoMOTN(KGFs0ug1l$mE_jvW4=n2-Q;K6!!wGyl+-e2X%$oQ*J=
-w589+*5lxGr7S6;ywj9HtRemvE;*ZnoHCQU>4YU52e*6x7xE*4gXh8EkQ|)1y~Ln;6LLceU!jCK3NewZ4y
-ve?aSsvmxHi3b=P)l3o+K7C#)`8?czWKWc4<-;5JSo*P6rGae|6YsfR)a(B}ZE8%%E3f{_XQAoZZ@o&
-hd;n3Oh7Z*rGy;s|D!i0c5t3Th>BBfZ#k7sWmDw7j3NigfgJ_FZ@8fh}_cheZeL7+hw6P^}_#df~i1m
-1ob$W4UF41b+pbC=X#8K8{&Rcqv${HaD(4oWEQ}kUZV#*Ya>(TOUS<`VFgYB1K1c*A*mmP%8(_4$}qj
-wJT+)o{A=Qg$Xn`T*bw`H#;*d^?m%i3Ejq=vSF94FFr7eTl~5QHzegJ9lcgj@)&dO~TZJUuDUd5sDl~_+g$zUsh(yOjSui2tm`?3?;m(i6SG8Z(=d#x3B+!
-*t(*AR^$>)GX~)$Bwq`Nd`bH%R{Q-yliScJ}@ErxC@FeIL!jQjw;57P09;MzFj`RfL1zfXFCy0H~dUf
-Pnjnr6-H$$UV09|}hB1#dOUke$h_BoL%aHhPP1dbVUjZCgeMmqItBX_U<@H^K?xDE78;$8D>puX^^VZ(^2
-{dBNpnDu%Z!GJx|;xfevILuK^{zdl&fuxDeMqylYf7-kZrLSL0O2Q`Lr9XfBbZ-imb8YwEt=uAh0(V1
->#EY`M!lv&WYF1z>ZVryWij~sQ8iib#cua~Tb&^uBeIjTm;qB~
-w*u>NWz_@s{cO>g&h5+xz+A=IZl}5Z{TnHU)Nxc2K`iXJJ^YK-K8Bln=dHC8OJZd<{CZWNYqhNICLAx>yDNf<`>V=<0p;hAqMm`c1<8vMyy*g3*{Av9x>Xwu*u^BsEQ`*%7Oc|
-*}_(COmMUg_Z&ou`G7rQ#3F6$8qn~FvHxZ?cStvI)5s|${>8;d#72UqYw`90c;EBe|et`o0bQ3FNPo?
-3EvHaM!TAl77a3JU(eeMK8GFNhwQp;e8lf-OYm2(4Z`Xx7hxGwEH;nRRF!HGRQ&v#mTjHx<`>bLJFRs
-2$yw3(i(5pr@NaM^}9qbl|O=WEAy*b)%ds@8L$T*{jd#r|vo3-^@SH#iy$`|G0WL|192q6dyj`i}zRe
-Z*By>6BM8L{QB$UXmbRgFXG)*;miDD?mz5B`+RQk>NiX
-Od2DE0lXsmg~+@1HL5UDlm-+u9Q?^0z57%%rU^5}N}w?XBr{#QiUi8{+1D(-|LzGwO_?pkE2pBWRLhy
-~QIf)iFohBHm}Si@xXcdZORRmp}gkNuQ+ZxqqI70bKCI%O8LG`MG~i8heN6h%Z`j_1r(FyLG~yVMnZ)
-g>^%IpferyRo6A#M|BMagF-V^NvK^M&78%*Op*;~nM0nhFL#P{5Q=@znxxj2bDeHG(PQ#Gpa+G}Pgf=
-V*5$hbB8DXY@;Usi@$--R$Isy)U_7W}ie4u!?CWlnXOEjW;fu`XC(>a%n|e^7A6e-~7(D~r`HT19BE6
-a*gQSV6WiV(MY>(j9Xmmc74)^x8^QRV#KL`vuQ(NIfw^dmA{4xz?w9uY{0|NyPdmc8h)aP(SCPzOQ9R
-DiyX^-~Q#Gfgj`|DJ}lbQ<>nItH#k!zzm^^;(^u2F0Ts#l`aNfuB40Z>Z=1QY-O00;m!mS#yd_$B{fD
-gXcuoB#j}0001RX>c!TZe(S6E^v9pJ^OnbH*&x0uR!SfNXF#KQZDUPjgq>K)A*~;@n<9U
-heSJ&%Szi9X7u{KYQDZeQW$NdMZJMe>Kf%XFN#LCtt|lavNm`c9SQg?^2JIPvu#sv0ZIFbX
-t!&?*IhReRo!gzb@_{&;m{{k{Mp;*-@g3e#q7m@zkBie;^lX*FDByR`!{dCd;9Li*Y4Y+anNj5$ZaDR
-InI^t!dr<$EnZe{%I(S19~r4(JvH@aSU^KnH-oof!EL^{$=#wbvc(PIsRTUCw)<{XSGJbCTga_PI*gL
-9%eHIE`3^t5uDfsQT~$oPe*mt3kWC9OpRF627yFl0+vPxh@bP8!9xzq>xRP@HO}UmxgN(56t9G|V;F7
-<3h$-sZYF+1rZvWe77qfS-0HtL+gIS&kMEtC)`49L9pNS3)h+71z>vIc&-pybRZLzJ~{`U0qF26Qoy_
-Vg~bSP6GkO0(b3Ut27~}y>|9(9zrkhGJ+G^-sn^4a7%n&6Y|*V}tGp`K
-a<&1Mm*ey-*1JMtfj2Y&`3;hGGrR(L7cZWF|Mtb~ySFd@^X2Oc1WUy9NWePnYG8U3v8vmS$V?EU=O4|#@c0B?$UWI*k&=-p^WR5Y87q1a-bx2;g?m^jmOn4_|QU29a&{{S1y`0R+Tt!fh8tFk@Q3$Mi2;866%LVGgT70qn`ZFdcmCgOJt<}JN8TKMrd&S=ogsX$US@JmL@)=u{*>D
-xU?FgGmJ*UHeHFq7inDm@#!bcpC{svC;XpN_|N#uLAIooFfvd=gdFVE#8mV8x60d9Z~yS)$RNS1x3&{
-kcPrV%mAM`*@dlHS&gwPF0E3m&~v~nU@iBjI
-&9yG=OGQ?K-*1#CN!wZcCVOaa*p}L~kA_GcKCItt|C(Fk^g&(hIkNWNG@jTx!;Vtzp~2Mvw#fiFf<0B(-7`v5kSx-l4S;z`;;Xgi=}y0o%c
-C-4sCd*E<~bnHa=yhN>S!|J&Gdkw@Y`fUXLM?b5mfs@H%4jd{}{8Fwr37vNkSY#K<*4vd`XQlOyD)}8
-XbL|o>ej%=htb=~YUaZv+v-WwZ&%QGG!Y-AOHKzNdOC8?D=Ko(AcF*_8R+B2uBp4>u$LM9vFov`4LG0
-EmVcV|jnFRxd$oM6CG`~h|e=%xc^4mc>*wtv8Zt9`dZY2d0CT
-vcmeb1?XDvNGGSQWs`|R#^k_B{h;TCP*3su}V(0Joc5}^`y)OBS^lFTT=p?utdVMAG
-FdZ*Rfii{1i}_xKQl+Rt{mWCWeEe@r^Xrt#D3SrJ1Xz5FlCo1ew)P)?r*D+^36kr9pe^d8>DesmG53%2wCNG
-GJt5h##2|bI*T=Q3B)6W(wK<6mnMU#+)C72*
-tTM9t8YmrB@J3aKXS+1A0Fx{}{ftIZdWj$<`%ubo&2C)#Je}iqg#f=Sk(6YSV;oeUhkhX^?9-{<?d-@N?q-@ia98M@c5>fO3PdV{_EdR@<9S&`g}Ur9*e5+rzgP+-e~{T)`N!Whzai{dhg_AGcYO0~HdF
-)Te85vze!x|6BSf@)b$aB-;abPcosbGec2jLfm4GLsn#Ij=mzA}R6!d-JJEZz@Dj35oJ+%R^sLj}=(l
-bXIxG+o$%#0EwX(MvBWkMN)%?9W+QXxnN(NP>ehq#CmYjpW_$v2_`8Vfc(;FX`@yA=iggoObZsrtxcf
-?4mmR`WMrNuAXRQ*Y%`EZS?~9?Zu5M>&PBb%$_faE?9lB%j8Gc|iLxCNng+;MU=PM;HsTm4IS^FYAaN
-mWwqisOCRkydY?i+J!lRO)e6eV|>xe4xE3rS)QJ_y1%it*Pai{TvZ-#Mp7{nE!isVQ9Ct!yN{@nF8ai
-LIhHIC8jdWW=%&m;0pp$@j_6sj+uULji?q8srTJxIftHR5o!SP9R5Qz)avRS0Qb9Z&McF_e{^%(ElE`
-z;a5ns5Mv4TR;W4^SQ(oH1(PUr%JmPiMpNQHUYG74)N7F!6}O3h5n0br>K-pVNr)D`}r$JVez6jft{_
-)smtPr>tF8=^{?k8Z7JuYfE>%wQveyQ{UhmLRF;Sd%B~4ma=t|f2ctsAg48f9H(0a0c3f2e)R7ku^Lb
-oj|lNl&x5u20n_?mY2tez+u`GOh5PU07I+Be+z7IM#%RU>mxF?vuQLHHRDUWq&lDTjExd)ELE*YQbD@Bb>~?YQU7Bu!rcl(c6
-zwU<5ufWx#N!DF0-hHHfW`W6QAi}ConG7Z+OjQ1Myh(eVIZE{`~QR$OlN8j&2`F*tRw?Q;M)CTzSz2>
-d?VBWN6Nm7;1xhuEUj@CFbVZx3u<0Tss*!@ko3vfiG>)e2X?LL?-SY#Orb$%mQjw)pE?9T&(h{Y&QnN
-J?cG3tVUmOFv9)A_z6$VpJ=V$3A^DJ*!noM3+XT&TyV+;SN9}JGTV^
-EZ3UMI%XAOlAj)qT$6LB)WoSyg=Mt53)r)rFst({i&3OK*^GIy({-d(S-f&*)nH^rhxCtEtmX@aA_m7
-w0{=(Hvoq{Io&(NpIz@kg%Nh1`E-;CvT46u?dvE^?2m$^06GZaqm^cgK-Wz##IIa~~$^QmAo8FQMSz(
-}c|lZP;bClfG)wHT#rc_M-%8kTZZ58sid8KA7Bq7o4Wy!F^WfnUAO$
-*Ag&R=sbqIsH#Z@w)a&$^eS+!7n1h$FN{F8Rv4u51Y=|6+DSkk?lU$`er0N)+=Qa7}*#53iB1l`|R|+
-*Sf;s_ke?JjMvJkt^g&GNi2YZttwsao?!*zH_o-7m$F>Ij
-#!=(U#*V92wa*PZz{vPaLiB=|KuJd&G&!1JSDIhcy)qmn9%B1a+lGs@)JY+K
-%yz^x*>Ih1nop9xTf6qkYhMZ2UFv+fq0F=Z?R&q6gUI#ER7zgwYSo7l98l*^606LEUL6)L$kJh&U&u{ge^YHXd-i0L+Th362B78=cG|LT{B2O#Dqs#X96o
-y&j#B|aJk9v;69FYsoEknxOX)H}Kd!$dSOHgd)sgcYqc?2q!oBMal_er<%g2&2(;VXIfU*6i2(JY%Ki
-8q}L|x(ZMqWb$;2AWpqa)N(&l_#sL>`U+db))R*$KYA0GWco&y>e_<^XP>4)K2@4a@SQa}~?p%jP_U2Vls30Y#lS>KW4t0}XtnLE9GEa_xYEKkk9!(O(d3;kjQ?d>A_%ZR<3H
-f8Eng(najL{uD5SO221lX^m(;3?7LE(*Uy`ZrmZ*fq6EdA0>+hs0G8mj?I!dLfc6Tyas*o?8n_va5Xa
-^HX_q|2biFpYC5G(O%WE1WI9E3Pkl2mH4LaqI
-LG$4N597qw(zNU0H?oN3pjnq)IcesCLkCk{pTL=!YhSut#_@KSu4QTc!Brf(9UqEs(7_#jW>8}Q^+
-G}%dzq3^3pw9ikA{z}L_BK8Rw$;f8O~HMK{PuXCXOi(L|Kiz*%$}>-1n**2^>c4RSRVhx1XP)Z0MMEE
-l49>urzcYpYQD9bsV9Iq@#~hsyCxVMCT-E$2~$v_&Nv9jt^dAVJ&?Y#O0BO#o3KO^Q~})@QF6!2|6sD
-<{oz?b}ad^!yX7jiW3mUm&14$ccR@U0eeR1DOR=h_OvLP89y8Fv^~)QAfJGG<$;(mo>lpJ|BH?9<&(D
-92oVfEWs%3171<56fVfPGV**@`o`55T-VbdlpcQgk!9P__-IGpOm2cij!|)&9YLF<&4G7cxmxoiUfx8w23d_6Oa^Rkz+t28B0O!UgT(oiIHQ$(di5hRL9kf=7N
-GkFQ9|FEeWD*bC_s%7Fi%$nF1DN!pPKoC2hq}{^lBpmBUNg{(Kr1N^65b65u#Klb7smzIV<#FjC06il
-##V1=F3=if+((ew`W(i$IwQ{cpQ^tB$ac4ae;|N&)XnG)KnMZ{d+I69Xv~81ew$Runsp#+ssm7RZd9)
-0r*o^JpBq4leQiLL-Ma(*+riJX*er`K^1d_<)R%KD?4Du7&*cF&OfXCH;lHnuC49Aa;;PaoKoF*WW1~
-iD&4znxGc}5JJ&Vj5%`b%3KBADcVM&^6D@8ut!7l@myA^wVYC2(7BW9zQ5znfuGrrFtkm6H%iv)(P!M
->johEBtN>9^T@dtgxDzyA?nsC+!Ju0p>tZ(FyY8I8nXlQgMoyI1BZOs;d!UCYs8J{5LdsQ5t1cL1^2n
-+ZX%?`nqZ*WuYMztFNQeEQqeeBwM=8{>S{1uux5dY;7{<^>qyX4M&5zr0LPEmb_JG)wUc-sAQ{H#jdL
-G6?5=H_2LwfV(HeK{S|922Z&QWM70U$9SuWKu+xTnmO;SItccP)j#XcaM`qzvx+3UU`jzV-e6P4x(4;(E1(xi4DVoVyBfXN;r4=0|YvVqA
-aG?Hjh9q2(Y`pbuCl`kJmQKM~cn*iRLV83b9J^-zj`6@n}kO?L+dmJYttOga}cyP#!${g{4>eFK|^?(
-e&Z=Kn|4GB-kOO6{nv;{qce*S8NB!oUic|o%#*_Tms9ebP(r@hZ2=jwz1Q_6MG3Nn4M>21blDcq9nIW
-yOma#L=%u9_d5O(n{g7{Jx0GiJ1S`cNOq*DpgWbB~1?6DK&O5Y&M%8uuj@&GMocCG64oBm3idVB>TO2
-fbjMXi9qWdfToBIjFjWCxDX
-x=7a+2f4OqVAvB_8Iq|q+M-qD{+hiXAREw?5@PW+
-C6W7$-PZ!D`)SpO0$Bw1x!A^bOVQxys0lk_noBWy*tR(jk?6;ot5hMgTr9zD`za=U4RPXD(V2xu5zXLi!H3lPB`OR_fYCPO7(6s9599S19MM)SVRsa5q|z2YxChCFuDZ3e
-=ZB0}kIiUjN*9A(Jha0D&crsb6irc(+8v4_C87A-X8rvrg8;pfT1EkWiw8EkPP*!(>IaS#qn{o;oK3!
-{+q;ve1I^ay%&a?(VfIV8O`I4%ObZ$=p6mD^YB-F!r7+&9N!>L4EBtny5kCHZ|sxRH<<(8eoJpj`H_I=*t;fYH)wu0l;4|9(A_5?i
-~B5K9PxsiO6qoc#fiPmZS4fw7zHxD%YHfm^uTI;h*D3NXH<&QUyR27K_c4{neMUNbyM%Qqmx)~vPF@%?Ay#V@Y&Tz*|U^y&Y7dKTGS2
-3+1$S+M4Vn9e8uIf?he3srPQ4Q%>RRzjya#%zfDV@sh!|Lzd0b5>Lih9uvq2F2haRpxt-go8aRk+FbF
-7^NX_Hn%4}6k;r%`D$3xQSnkaf`Wbd3zOnj;W=PP8MP=+A&=cy0_C(2~k%1k_?=vxXu-g-nq!MSJmW9
-T7>2?)qnCfH%GGzpU<{>)V=%z_McpmdV;h&kE3^MS@;Y#3I_h_h#Z`|kIz-eA;|wRk9HgtH;L3Ggr>H
-A0S9r>o$5JalHM%VK(F>NoP-vv`ay^XV^7r~f+3uAYpi_ODN#OyR{4)vxU3*k-SCj}aW3Pvka1g|~gTd+GQE)yGiwF
-}DJW=*IzH?j2{
-bd)9e1~?rx8qB^wK`^A&Jp&Ivk(zCa6MKeOUTLCzSyCOy^!lWDnYWiJ}!91j5<(11J`hi$&Qe6mX)KM
-p7=t(Qt-#=IKxa_hbhY%{1mV7-xzZB_vL~O2m?jB5ygE5RcVk0IfK8ab^yqJ`scIz)T;0adKbjx-m=f
-5pju;#@6(I^AzJL4bP||rc&PqI^NI|qKnHPYsFe!V
-GqQIPaulBIPF6x4PUMvu+JqLqW6g0~bb=lY)ql)q|!ROqkDdveLrC5FSH%`@aI)_cEC-M#2Q5V-`#ts
-FpHByx?eXv(?qO!qah4ngWlHtWNm@@`0ayeAhhEAXd?G&nm*e8DSKbvG6`a&UolQ>19=g9kF@_fv6m(
-KNrUyx3116!6zMlY1bJIwqa+^AwQy!o&7ES;OFb;t_XX74Q|8mP)#NMs!(E;M`Y0#7!njrRt#AE@*~6
-mDuaJkAR8h_iw`^^$_{A#P+yKRmxsX-1S&Nu6O)q9t)IP;x1+
-$DFUDa58e}i<{mr%&ks8EZPgMYm3!7^%xSrEueC}#Eu5+zT%B8C*V&GxC-RaCTX@5h~KOHGCNGUE|rL!uky~a}w;(~y+d0wE#kAsVEg6mBhs6pBjjtb6!#C|TrL#D
-EB**E9D@3+a|kMmL*X}0YT5Wru5VnVc(IgO?W!O3)aPp(4FjNA9M--o1s_XlRUKkL#^XDn{7TpL{
-DgX)Ve3m_x-%R>R{=9q~kAT74sL*f6A_NMmG%e?%@wFMO)nP(Xb4s2&4x-(k9Q2k8!mrMnmZfC}2|MJ
-1m2E&yik`mF(ysAZM85opB<5-pOVU;UFz1zB2F%j-c%EQ{!agPNNnR2zw*&4
-%r-errf9_MjQ*)>ExIeI3$uU#FpP095#OLYY!a}RC7upwW$ZvwVKqb~ixllNNq{9|&|12$j`&cwj5mL8ME;5pvlIaN
-0mV2w?FH-!ap{?AXJChGk8V4w{QCnMU1nPQFOK+=Q
-;p|=kNJ20WCt@2U}Kh>24B&oQZEuCiC2w+4BIB8)jD1)h0+{;`?fi32kn*#XA?@zIgVvxla|%W_TVi0
-7i*QrB=*us`^&sIAx^ymm5C6PPq(lhc#m;S$_$D)s*4JjzWdHGY0czN3SrUigRm_o2UeT!G1^+rD%w#
-Zs@Y}A$cLO*P+KjEx!9UG>7VvnF#KU4*UokPyc3fc!TM+^!kXvJWnK7j0l%THKf0Yf4De~jJf6>QB1l
-*QZ~w@@G;QaP;OBdf1)Kt8QGv*kV;p9)pw94fpH819&tz0X(Q>hc#c+pIcPeZ!VdM;Ym@PRfu{kM6qu
-8`IEa6P$L)Ze(u?s!`p&&jIy4ggxuOSa^hx0fX1(GY$37TagN3Qf;bmmw<}RnvXj**-Yqj2W4{HV&c7
-ayJFwb!;mnrF+5+$;lmrhXs5cI{$9llO$cJ$@kTY-)fNaE6UBJ?F1o>-qil!>Vc;Twc;Er$jX$=$AK?
-T4*^L`KBtu5oQGRrwC+Dr3?(eOBxR3MM73K*CCF{;XqqbBFwyB`M|691Zch4rGyZZAU10m@6G9GmOrP
-gxp?p`LBZVc+FU2iSw%zp$vzvmEV&Yki#%W`2Z0p;3R&u!I9H@_huVGy{M*dpbPISlJTQzby7`tI(rr?!3jodmNWx*#*HR{w)uFq
-7#`&V^fz=_afBQJg8R}r<8*GUIhvYX)A3)CW^samWs<9$EQ@^DOas}9!cA2$B*Jzl;P73~qA+3JReR1
-bJqlTtR-)U-08h98p6a=X`;*m%7h;%UUG_P9;AeE}10b$tc*$h;i0t63N6KYhm`xi+POIV0>k{LU?06
-}ZcYieq*!|CfDM|MZ(DljF00JOAq6vqz6-KmGKl>6Lb0S^J@bZEn_2>IJm&`}~Fy_+lm@6};J!TS6J3
-F@YS2;Uo=Dh%&?w{@1SR+ZKaBoNU0Ia`#L)0~X))(#YGU)Y0S8x0EyN_*2g`8eg}fHbw3IVeT{tqRPoDLN)adk~h$U_lyR
-=j!fMtt_$&(%3)zG%{x*50a^A9!%`j*q)Z&1iAt%C(taQ}X8m_yd&TD~zzw&!2wgpG|PA&^RsXBG_Df
-|N1$sma4!7)dIzP9-Qzxn4jPm3KF~MP95KTaLD)ITpV@o%(-7Em@(o={u@5H>bg+A!)uAJuE&3eWNovY=Ux8yjitPC^L43bqfC0lLP(@a`o?w$SVP8GiAKBR;
-;=qkrJF?!7mTzbc~(JkuA9hy6Fyb*^p}Hv-MQ_pATyI`c_SXV(2!$p7s+^F>cz{t<}zq6ab8{|Ll<+0
-&PQ1Y*AILCh*|SG~&+KZdI}7UQ*BDg-hM^-g#(>s2;wGrGR=rrCt7C?XsCd)DC2yCswNm`sDzR#@9_t
-m53PesnqOoq{8+Mnlr`8=YMiEdVw&T(e@YpZe&L$-Wt*h&AUPEZ>6<ZuqVA>DMivlfGTv}
-*V5^g!}-nWl^&hj?Omkm~@f96ciWB
-3ciw1;7LVw&w0BQqSp@Z}dwpx?R2&8k87Gj2_NG>ul!vdQIDUxwNy<`PB#cyu}NGyMaoj%l=NG?-k4`
-3d&^oOLj38>I9EoNIq{DCeR5!V~(m>GRi4Vyzji_VE?0UDCSXlnpJFSL6-_*yu0&lNQX1^!6S4Ct7qU
-@m~M}5u3#$*9%<-qYc?408F5t&4ZTj)?C9v_QYgy;S;L^K`w8Dk$Tv)Inle6!^~d2EjP-2zXZMn5UPb
-W!NJVb9+F=AcWy{&W*;GLHSCF-f+RONcEQ~wl_LZ3c+B||eHH~2iS56M%Oz;g7t+}d;+{W?_=|#tlld
-Pv=>5njLICo&e0j(Hu%03fao?Pp=2$5*W%I9>+Hhn~P4T{*;$#Rt+YO_Pag%z?`?+Q86H$CRfwd{PUz
-LK|i1PBZ0r8-f@Shf_ZA@jX0x0aY#TBrLxorAvIMBi&XHm%^fnZnly`SJ|@(XrR6jCdkWJlDYR40DJ;
-Z_G_Hw?2745(Hxi@Yf~5P(-CP$jh`7HAEH71kwI3%x>PJ_no!&8pC83gA)Q^ZV3
-;6Z}PaEPAsg`ziq=UyUdD=HOZ-cl0Pkr&CscM=6xK?g+Ok7
-~PK4f@`9O#bOet?E&^n)|($AEL__g8i-0qH|~q|Y5R^)IqQ)N<)?jtp2mOKMgQuX57`)zL}Z%}ELeiP
-m?mRGV?S191nLW2A4bA5N!LJq4IkKFLhC&n2&>ckZD_R?0WgXHH6^p?E|27AessfmOQ*uVQs4P6lJY=
-Z^Ze175oZPOv^dMFd>vgyHUH$1ic0)2Fd4b?T(yywyF=x7by>hc|CIc`P4M;?rD5M`zZGt%30o9l9sL
-z*k#9=9aeyvpFKmbiv(Uyc()+T;81NMYpp$b<47jYD-+0bHzDrbu^cB6_BD{lvebLz-PLajq>;NCiMS
-MO9KQH0000805+CpNw*JonUM$p0QwaG01yBG0B~t=FKlmPVRUJ4ZgVbhdA(TQZ{xTTe%D{YIuDY!j@-
-ooeQ*&J!LGLrF1tCbQ|uLKAkY$R^CF8nl8WOl_Wt&MLsGw-&2C#1^@}BPW;p!jo8eHC$>dt)+)7m$cG
-w9m*g>#TsRy=En&qn6$gP<%SsBaAk{R1Wt+w}T4WiM`&wzs_}Zwlu_E*DQ543N>
-7UY?+g2#n>6E)UQ0OQOlaN
-;Y_Ra>FUGVn@=n3@u`N*#t7Yuj@;pOT}TaYqce6{*QNA0vbR!;+$t@FiT<`)e$3unV*Tvx)kk*GDy3v
-M%Xz*N8Qzl#tWTye^>%r^yj^DRFF*bW&G*aI>hdp3=*4mTkLY$M4co|4F#Ojg&qcvp%+^P8k6DF17vz
-Uvb|;uojm{BK4(Y~51JN{!ZmOK5$P&*V_|_RUO`Z#5HceR`Tl}zy6ARXIRluYK%xe)9q7)VaNmG^3V@
-K66E%xd$m?meZX$0@1pRRt=CoWb-ny>`QB|0KAn4G=cIUE1Q3s@eX=otDa3{yG>DRUv24%v12Ci&l
-1_TMh!}oEPWt~u3JwZ_$15_g7;vnBne((?aAbj`h^p{0kT(5A$*Ny*#$Mjo)R{O)sH<93No#Dz;zK-T
-2ur((+WSqvZYXuzO}@&AX+T6bRVAx!)>H*_9;LPoFGcm3oB;7rAVn*7s~hYYK#CYt2+9;^iI{TM>(AI
-bUK+s^u+s-=1PC*<2OB$XxV1V#R$@O|@G`5l*vO}N+HXep>$)*fLK7OP7iGV@U|V5(JCijxBG{SC29h
-t>j0OYFTHK1gD^6{Sm@zrdJazU`Yo(3jS*f-%CtJM-X?=9Xv~
--0Qctb9zSL)pRc229DcdLN&j(JXurn0>%s89@Oh_{OGMbf^b>e7Eg;%VmcBFm{}T1rW+_I
-2BLZ=)X)n2VZMn8ke8r^==LS5Km4w(KK72k><3;zY1mGtogn#lXowx$ck^ACFu@_C>PF3>KcUA)$P(x`4sP4k0kyL^g&*Pw#3s0_`vKp
-6JV8VSz8mhM+#)_RHbw0nZ_AgH?k~LV*x*Q6~jbKP=7*)p$;f^O8vPl1{CbpF6d{hNxX}LO#e50rX{8
-$h41<7HJpk^Jfri2(j)W~XbENP1xm5y`7tv{CdBEanD&-^4TNfNC8!1SUn`%T$In-ob#o`~`H5kL`j7
-DW-(W+-{|z|l{|lYAbSs^^b5ju)*}O4&PKRkpg~FvN`qZl6x(Ib?qhW+9XxqY?VCk|nRN$Pc-{#kHO+
-|iwt+r@-dydZCMVoLhE{1H38cRdEmU{C$_#EPdup)mS22O6&|%x)<2HUpYA7tC+;RitLou#8ei|t`0x_gUO}BV<0gH49i*rBlJ*wQTCN+qnRz~WeL(p
-6OVkFlb*vAEc(R&jZp&P63GvSp<0_BFQLP2Gx`NHUTicJ6RPoobqJrxq)l
-DGz2wANNRR?1hTBXA0&X50(Pqq`Bs6kRE!-&;uF#oU|B}Q3>KJUoscXdr^=Iw5@ZshbeUuT_bq}rzfn
-CG`*P^(4C$1CcVzWW#!qmna35~B81mA)+pLA$9r~x9HhPA^diK5Y@xRDhvhvXeZP{F#
-pn#3s(0+q#R12NrI>vkLs4>PsM