From 087915ee87db16082a177771b4762d6d7d47246a Mon Sep 17 00:00:00 2001 From: anamotaadyen Date: Fri, 4 Nov 2022 12:32:04 +0000 Subject: [PATCH 1/2] Removing venv from remote --- venv/.DS_Store | Bin 6148 -> 0 bytes venv/bin/activate | 76 - venv/bin/activate.csh | 37 - venv/bin/activate.fish | 75 - venv/bin/dotenv | 11 - venv/bin/easy_install | 11 - venv/bin/easy_install-3.7 | 11 - venv/bin/flask | 11 - venv/bin/normalizer | 11 - venv/bin/pip | 11 - venv/bin/pip3 | 11 - venv/bin/pip3.7 | 11 - venv/bin/python | 1 - venv/bin/python3 | 1 - venv/lib/.DS_Store | Bin 6148 -> 0 bytes venv/lib/python3.7/.DS_Store | Bin 6148 -> 0 bytes venv/lib/python3.7/site-packages/.DS_Store | Bin 6148 -> 0 bytes .../Adyen-6.0.0-py3.7.egg-info/PKG-INFO | 19 - .../Adyen-6.0.0-py3.7.egg-info/SOURCES.txt | 14 - .../dependency_links.txt | 1 - .../installed-files.txt | 18 - .../Adyen-6.0.0-py3.7.egg-info/top_level.txt | 1 - .../python3.7/site-packages/Adyen/__init__.py | 46 - .../Adyen/__pycache__/__init__.cpython-37.pyc | Bin 1430 -> 0 bytes .../Adyen/__pycache__/client.cpython-37.pyc | Bin 19713 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 2776 -> 0 bytes .../__pycache__/httpclient.cpython-37.pyc | Bin 9647 -> 0 bytes .../Adyen/__pycache__/services.cpython-37.pyc | Bin 13602 -> 0 bytes .../Adyen/__pycache__/settings.cpython-37.pyc | Bin 787 -> 0 bytes .../Adyen/__pycache__/util.cpython-37.pyc | Bin 2961 -> 0 bytes .../python3.7/site-packages/Adyen/client.py | 779 -- .../site-packages/Adyen/exceptions.py | 71 - .../site-packages/Adyen/httpclient.py | 351 - .../python3.7/site-packages/Adyen/services.py | 369 - .../python3.7/site-packages/Adyen/settings.py | 16 - .../lib/python3.7/site-packages/Adyen/util.py | 96 - .../Flask-2.0.3.dist-info/INSTALLER | 1 - .../Flask-2.0.3.dist-info/LICENSE.rst | 28 - .../Flask-2.0.3.dist-info/METADATA | 125 - .../Flask-2.0.3.dist-info/RECORD | 51 - .../site-packages/Flask-2.0.3.dist-info/WHEEL | 5 - .../Flask-2.0.3.dist-info/entry_points.txt | 2 - .../Flask-2.0.3.dist-info/top_level.txt | 1 - .../Jinja2-3.0.3.dist-info/INSTALLER | 1 - .../Jinja2-3.0.3.dist-info/LICENSE.rst | 28 - .../Jinja2-3.0.3.dist-info/METADATA | 113 - .../Jinja2-3.0.3.dist-info/RECORD | 58 - .../Jinja2-3.0.3.dist-info/WHEEL | 5 - .../Jinja2-3.0.3.dist-info/entry_points.txt | 3 - .../Jinja2-3.0.3.dist-info/top_level.txt | 1 - .../MarkupSafe-2.1.0.dist-info/INSTALLER | 1 - .../MarkupSafe-2.1.0.dist-info/LICENSE.rst | 28 - .../MarkupSafe-2.1.0.dist-info/METADATA | 101 - .../MarkupSafe-2.1.0.dist-info/RECORD | 14 - .../MarkupSafe-2.1.0.dist-info/WHEEL | 5 - .../MarkupSafe-2.1.0.dist-info/top_level.txt | 1 - .../Werkzeug-2.0.3.dist-info/INSTALLER | 1 - .../Werkzeug-2.0.3.dist-info/LICENSE.rst | 28 - .../Werkzeug-2.0.3.dist-info/METADATA | 129 - .../Werkzeug-2.0.3.dist-info/RECORD | 111 - .../Werkzeug-2.0.3.dist-info/WHEEL | 5 - .../Werkzeug-2.0.3.dist-info/top_level.txt | 1 - .../__pycache__/easy_install.cpython-37.pyc | Bin 333 -> 0 bytes .../typing_extensions.cpython-37.pyc | Bin 95330 -> 0 bytes .../__pycache__/zipp.cpython-37.pyc | Bin 10099 -> 0 bytes .../certifi-2021.10.8.dist-info/INSTALLER | 1 - .../certifi-2021.10.8.dist-info/LICENSE | 21 - .../certifi-2021.10.8.dist-info/METADATA | 83 - .../certifi-2021.10.8.dist-info/RECORD | 13 - .../certifi-2021.10.8.dist-info/WHEEL | 6 - .../certifi-2021.10.8.dist-info/top_level.txt | 1 - .../site-packages/certifi/__init__.py | 3 - .../site-packages/certifi/__main__.py | 12 - .../__pycache__/__init__.cpython-37.pyc | Bin 264 -> 0 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 441 -> 0 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 1133 -> 0 bytes .../site-packages/certifi/cacert.pem | 4362 --------- .../python3.7/site-packages/certifi/core.py | 60 - .../INSTALLER | 1 - .../LICENSE | 21 - .../METADATA | 269 - .../RECORD | 33 - .../charset_normalizer-2.0.12.dist-info/WHEEL | 5 - .../entry_points.txt | 3 - .../top_level.txt | 1 - .../charset_normalizer/__init__.py | 56 - .../__pycache__/__init__.cpython-37.pyc | Bin 1727 -> 0 bytes .../__pycache__/api.cpython-37.pyc | Bin 10950 -> 0 bytes .../__pycache__/cd.cpython-37.pyc | Bin 8799 -> 0 bytes .../__pycache__/constant.cpython-37.pyc | Bin 13821 -> 0 bytes .../__pycache__/legacy.cpython-37.pyc | Bin 3331 -> 0 bytes .../__pycache__/md.cpython-37.pyc | Bin 15045 -> 0 bytes .../__pycache__/models.cpython-37.pyc | Bin 13211 -> 0 bytes .../__pycache__/utils.cpython-37.pyc | Bin 8022 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 276 -> 0 bytes .../site-packages/charset_normalizer/api.py | 608 -- .../charset_normalizer/assets/__init__.py | 1244 --- .../__pycache__/__init__.cpython-37.pyc | Bin 7991 -> 0 bytes .../site-packages/charset_normalizer/cd.py | 340 - .../charset_normalizer/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-37.pyc | Bin 218 -> 0 bytes .../cli/__pycache__/normalizer.cpython-37.pyc | Bin 6074 -> 0 bytes .../charset_normalizer/cli/normalizer.py | 290 - .../charset_normalizer/constant.py | 503 - .../charset_normalizer/legacy.py | 95 - .../site-packages/charset_normalizer/md.py | 559 -- .../charset_normalizer/models.py | 392 - .../site-packages/charset_normalizer/py.typed | 0 .../site-packages/charset_normalizer/utils.py | 342 - .../charset_normalizer/version.py | 6 - .../click-8.0.4.dist-info/INSTALLER | 1 - .../click-8.0.4.dist-info/LICENSE.rst | 28 - .../click-8.0.4.dist-info/METADATA | 111 - .../click-8.0.4.dist-info/RECORD | 41 - .../site-packages/click-8.0.4.dist-info/WHEEL | 5 - .../click-8.0.4.dist-info/top_level.txt | 1 - .../python3.7/site-packages/click/__init__.py | 75 - .../click/__pycache__/__init__.cpython-37.pyc | Bin 2696 -> 0 bytes .../click/__pycache__/_compat.cpython-37.pyc | Bin 15757 -> 0 bytes .../__pycache__/_termui_impl.cpython-37.pyc | Bin 15619 -> 0 bytes .../__pycache__/_textwrap.cpython-37.pyc | Bin 1518 -> 0 bytes .../__pycache__/_unicodefun.cpython-37.pyc | Bin 2311 -> 0 bytes .../__pycache__/_winconsole.cpython-37.pyc | Bin 7737 -> 0 bytes .../click/__pycache__/core.cpython-37.pyc | Bin 87988 -> 0 bytes .../__pycache__/decorators.cpython-37.pyc | Bin 14374 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 10079 -> 0 bytes .../__pycache__/formatting.cpython-37.pyc | Bin 9308 -> 0 bytes .../click/__pycache__/globals.cpython-37.pyc | Bin 2403 -> 0 bytes .../click/__pycache__/parser.cpython-37.pyc | Bin 13480 -> 0 bytes .../shell_completion.cpython-37.pyc | Bin 16690 -> 0 bytes .../click/__pycache__/termui.cpython-37.pyc | Bin 26316 -> 0 bytes .../click/__pycache__/testing.cpython-37.pyc | Bin 14719 -> 0 bytes .../click/__pycache__/types.cpython-37.pyc | Bin 32982 -> 0 bytes .../click/__pycache__/utils.cpython-37.pyc | Bin 17764 -> 0 bytes .../python3.7/site-packages/click/_compat.py | 626 -- .../site-packages/click/_termui_impl.py | 717 -- .../site-packages/click/_textwrap.py | 49 - .../site-packages/click/_unicodefun.py | 100 - .../site-packages/click/_winconsole.py | 279 - .../lib/python3.7/site-packages/click/core.py | 2953 ------ .../site-packages/click/decorators.py | 436 - .../site-packages/click/exceptions.py | 287 - .../site-packages/click/formatting.py | 301 - .../python3.7/site-packages/click/globals.py | 68 - .../python3.7/site-packages/click/parser.py | 529 - .../python3.7/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 581 -- .../python3.7/site-packages/click/termui.py | 806 -- .../python3.7/site-packages/click/testing.py | 479 - .../python3.7/site-packages/click/types.py | 1049 -- .../python3.7/site-packages/click/utils.py | 588 -- .../site-packages/dotenv/__init__.py | 49 - .../__pycache__/__init__.cpython-37.pyc | Bin 1235 -> 0 bytes .../dotenv/__pycache__/cli.cpython-37.pyc | Bin 4823 -> 0 bytes .../dotenv/__pycache__/ipython.cpython-37.pyc | Bin 1480 -> 0 bytes .../dotenv/__pycache__/main.cpython-37.pyc | Bin 9431 -> 0 bytes .../dotenv/__pycache__/parser.cpython-37.pyc | Bin 5786 -> 0 bytes .../__pycache__/variables.cpython-37.pyc | Bin 3508 -> 0 bytes .../dotenv/__pycache__/version.cpython-37.pyc | Bin 218 -> 0 bytes .../lib/python3.7/site-packages/dotenv/cli.py | 164 - .../python3.7/site-packages/dotenv/ipython.py | 39 - .../python3.7/site-packages/dotenv/main.py | 364 - .../python3.7/site-packages/dotenv/parser.py | 182 - .../python3.7/site-packages/dotenv/py.typed | 1 - .../site-packages/dotenv/variables.py | 88 - .../python3.7/site-packages/dotenv/version.py | 1 - .../python3.7/site-packages/easy_install.py | 5 - .../python3.7/site-packages/flask/__init__.py | 46 - .../python3.7/site-packages/flask/__main__.py | 3 - .../flask/__pycache__/__init__.cpython-37.pyc | Bin 1887 -> 0 bytes .../flask/__pycache__/__main__.cpython-37.pyc | Bin 228 -> 0 bytes .../flask/__pycache__/app.cpython-37.pyc | Bin 62880 -> 0 bytes .../__pycache__/blueprints.cpython-37.pyc | Bin 21948 -> 0 bytes .../flask/__pycache__/cli.cpython-37.pyc | Bin 26861 -> 0 bytes .../flask/__pycache__/config.cpython-37.pyc | Bin 11610 -> 0 bytes .../flask/__pycache__/ctx.cpython-37.pyc | Bin 15489 -> 0 bytes .../__pycache__/debughelpers.cpython-37.pyc | Bin 6435 -> 0 bytes .../flask/__pycache__/globals.cpython-37.pyc | Bin 1828 -> 0 bytes .../flask/__pycache__/helpers.cpython-37.pyc | Bin 27033 -> 0 bytes .../flask/__pycache__/logging.cpython-37.pyc | Bin 2446 -> 0 bytes .../flask/__pycache__/scaffold.cpython-37.pyc | Bin 24830 -> 0 bytes .../flask/__pycache__/sessions.cpython-37.pyc | Bin 13590 -> 0 bytes .../flask/__pycache__/signals.cpython-37.pyc | Bin 2380 -> 0 bytes .../__pycache__/templating.cpython-37.pyc | Bin 5497 -> 0 bytes .../flask/__pycache__/testing.cpython-37.pyc | Bin 9164 -> 0 bytes .../flask/__pycache__/typing.cpython-37.pyc | Bin 1411 -> 0 bytes .../flask/__pycache__/views.cpython-37.pyc | Bin 5012 -> 0 bytes .../flask/__pycache__/wrappers.cpython-37.pyc | Bin 4991 -> 0 bytes venv/lib/python3.7/site-packages/flask/app.py | 2091 ---- .../site-packages/flask/blueprints.py | 609 -- venv/lib/python3.7/site-packages/flask/cli.py | 999 -- .../python3.7/site-packages/flask/config.py | 295 - venv/lib/python3.7/site-packages/flask/ctx.py | 489 - .../site-packages/flask/debughelpers.py | 172 - .../python3.7/site-packages/flask/globals.py | 59 - .../python3.7/site-packages/flask/helpers.py | 836 -- .../site-packages/flask/json/__init__.py | 363 - .../json/__pycache__/__init__.cpython-37.pyc | Bin 11562 -> 0 bytes .../flask/json/__pycache__/tag.cpython-37.pyc | Bin 11820 -> 0 bytes .../python3.7/site-packages/flask/json/tag.py | 312 - .../python3.7/site-packages/flask/logging.py | 74 - .../python3.7/site-packages/flask/py.typed | 0 .../python3.7/site-packages/flask/scaffold.py | 875 -- .../python3.7/site-packages/flask/sessions.py | 416 - .../python3.7/site-packages/flask/signals.py | 56 - .../site-packages/flask/templating.py | 165 - .../python3.7/site-packages/flask/testing.py | 298 - .../python3.7/site-packages/flask/typing.py | 49 - .../python3.7/site-packages/flask/views.py | 158 - .../python3.7/site-packages/flask/wrappers.py | 167 - .../idna-3.3.dist-info/INSTALLER | 1 - .../idna-3.3.dist-info/LICENSE.md | 29 - .../site-packages/idna-3.3.dist-info/METADATA | 236 - .../site-packages/idna-3.3.dist-info/RECORD | 23 - .../site-packages/idna-3.3.dist-info/WHEEL | 5 - .../idna-3.3.dist-info/top_level.txt | 1 - .../python3.7/site-packages/idna/__init__.py | 44 - .../idna/__pycache__/__init__.cpython-37.pyc | Bin 904 -> 0 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 3272 -> 0 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 752 -> 0 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 9796 -> 0 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 23124 -> 0 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 1974 -> 0 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 200 -> 0 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 185546 -> 0 bytes .../lib/python3.7/site-packages/idna/codec.py | 112 - .../python3.7/site-packages/idna/compat.py | 13 - venv/lib/python3.7/site-packages/idna/core.py | 397 - .../python3.7/site-packages/idna/idnadata.py | 2137 ----- .../python3.7/site-packages/idna/intranges.py | 54 - .../site-packages/idna/package_data.py | 2 - .../lib/python3.7/site-packages/idna/py.typed | 0 .../python3.7/site-packages/idna/uts46data.py | 8512 ----------------- .../INSTALLER | 1 - .../LICENSE | 13 - .../METADATA | 118 - .../RECORD | 23 - .../importlib_metadata-4.11.2.dist-info/WHEEL | 5 - .../top_level.txt | 1 - .../importlib_metadata/__init__.py | 1056 -- .../__pycache__/__init__.cpython-37.pyc | Bin 37138 -> 0 bytes .../__pycache__/_adapters.cpython-37.pyc | Bin 2407 -> 0 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 1564 -> 0 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 2030 -> 0 bytes .../__pycache__/_functools.cpython-37.pyc | Bin 3147 -> 0 bytes .../__pycache__/_itertools.cpython-37.pyc | Bin 2047 -> 0 bytes .../__pycache__/_meta.cpython-37.pyc | Bin 2380 -> 0 bytes .../__pycache__/_text.cpython-37.pyc | Bin 3102 -> 0 bytes .../importlib_metadata/_adapters.py | 68 - .../importlib_metadata/_collections.py | 30 - .../importlib_metadata/_compat.py | 71 - .../importlib_metadata/_functools.py | 104 - .../importlib_metadata/_itertools.py | 73 - .../site-packages/importlib_metadata/_meta.py | 48 - .../site-packages/importlib_metadata/_text.py | 99 - .../site-packages/importlib_metadata/py.typed | 0 .../itsdangerous-2.1.0.dist-info/INSTALLER | 1 - .../itsdangerous-2.1.0.dist-info/LICENSE.rst | 28 - .../itsdangerous-2.1.0.dist-info/METADATA | 97 - .../itsdangerous-2.1.0.dist-info/RECORD | 23 - .../itsdangerous-2.1.0.dist-info/WHEEL | 5 - .../top_level.txt | 1 - .../site-packages/itsdangerous/__init__.py | 19 - .../__pycache__/__init__.cpython-37.pyc | Bin 871 -> 0 bytes .../__pycache__/_json.cpython-37.pyc | Bin 911 -> 0 bytes .../__pycache__/encoding.cpython-37.pyc | Bin 1854 -> 0 bytes .../__pycache__/exc.cpython-37.pyc | Bin 3380 -> 0 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 9600 -> 0 bytes .../__pycache__/signer.cpython-37.pyc | Bin 8419 -> 0 bytes .../__pycache__/timed.cpython-37.pyc | Bin 6259 -> 0 bytes .../__pycache__/url_safe.cpython-37.pyc | Bin 2693 -> 0 bytes .../site-packages/itsdangerous/_json.py | 16 - .../site-packages/itsdangerous/encoding.py | 54 - .../site-packages/itsdangerous/exc.py | 107 - .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 295 - .../site-packages/itsdangerous/signer.py | 257 - .../site-packages/itsdangerous/timed.py | 227 - .../site-packages/itsdangerous/url_safe.py | 80 - .../site-packages/jinja2/__init__.py | 45 - .../__pycache__/__init__.cpython-37.pyc | Bin 1912 -> 0 bytes .../__pycache__/_identifier.cpython-37.pyc | Bin 1897 -> 0 bytes .../__pycache__/async_utils.cpython-37.pyc | Bin 2474 -> 0 bytes .../jinja2/__pycache__/bccache.cpython-37.pyc | Bin 13137 -> 0 bytes .../__pycache__/compiler.cpython-37.pyc | Bin 54391 -> 0 bytes .../__pycache__/constants.cpython-37.pyc | Bin 1554 -> 0 bytes .../jinja2/__pycache__/debug.cpython-37.pyc | Bin 5358 -> 0 bytes .../__pycache__/defaults.cpython-37.pyc | Bin 1341 -> 0 bytes .../__pycache__/environment.cpython-37.pyc | Bin 52486 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 5580 -> 0 bytes .../jinja2/__pycache__/ext.cpython-37.pyc | Bin 26280 -> 0 bytes .../jinja2/__pycache__/filters.cpython-37.pyc | Bin 49789 -> 0 bytes .../__pycache__/idtracking.cpython-37.pyc | Bin 11178 -> 0 bytes .../jinja2/__pycache__/lexer.cpython-37.pyc | Bin 20059 -> 0 bytes .../jinja2/__pycache__/loaders.cpython-37.pyc | Bin 20255 -> 0 bytes .../jinja2/__pycache__/meta.cpython-37.pyc | Bin 3806 -> 0 bytes .../__pycache__/nativetypes.cpython-37.pyc | Bin 4859 -> 0 bytes .../jinja2/__pycache__/nodes.cpython-37.pyc | Bin 41420 -> 0 bytes .../__pycache__/optimizer.cpython-37.pyc | Bin 1908 -> 0 bytes .../jinja2/__pycache__/parser.cpython-37.pyc | Bin 27537 -> 0 bytes .../jinja2/__pycache__/runtime.cpython-37.pyc | Bin 32979 -> 0 bytes .../jinja2/__pycache__/sandbox.cpython-37.pyc | Bin 11832 -> 0 bytes .../jinja2/__pycache__/tests.cpython-37.pyc | Bin 6529 -> 0 bytes .../jinja2/__pycache__/utils.cpython-37.pyc | Bin 27201 -> 0 bytes .../jinja2/__pycache__/visitor.cpython-37.pyc | Bin 3886 -> 0 bytes .../site-packages/jinja2/_identifier.py | 6 - .../site-packages/jinja2/async_utils.py | 75 - .../python3.7/site-packages/jinja2/bccache.py | 364 - .../site-packages/jinja2/compiler.py | 1957 ---- .../site-packages/jinja2/constants.py | 20 - .../python3.7/site-packages/jinja2/debug.py | 259 - .../site-packages/jinja2/defaults.py | 48 - .../site-packages/jinja2/environment.py | 1661 ---- .../site-packages/jinja2/exceptions.py | 166 - .../lib/python3.7/site-packages/jinja2/ext.py | 879 -- .../python3.7/site-packages/jinja2/filters.py | 1824 ---- .../site-packages/jinja2/idtracking.py | 318 - .../python3.7/site-packages/jinja2/lexer.py | 869 -- .../python3.7/site-packages/jinja2/loaders.py | 652 -- .../python3.7/site-packages/jinja2/meta.py | 111 - .../site-packages/jinja2/nativetypes.py | 124 - .../python3.7/site-packages/jinja2/nodes.py | 1204 --- .../site-packages/jinja2/optimizer.py | 47 - .../python3.7/site-packages/jinja2/parser.py | 1040 -- .../python3.7/site-packages/jinja2/py.typed | 0 .../python3.7/site-packages/jinja2/runtime.py | 1104 --- .../python3.7/site-packages/jinja2/sandbox.py | 428 - .../python3.7/site-packages/jinja2/tests.py | 255 - .../python3.7/site-packages/jinja2/utils.py | 854 -- .../python3.7/site-packages/jinja2/visitor.py | 92 - .../site-packages/markupsafe/__init__.py | 291 - .../__pycache__/__init__.cpython-37.pyc | Bin 10672 -> 0 bytes .../__pycache__/_native.cpython-37.pyc | Bin 2008 -> 0 bytes .../site-packages/markupsafe/_native.py | 63 - .../site-packages/markupsafe/_speedups.c | 320 - .../_speedups.cpython-37m-darwin.so | Bin 34984 -> 0 bytes .../site-packages/markupsafe/_speedups.pyi | 9 - .../site-packages/markupsafe/py.typed | 0 .../pip-22.2.2.dist-info/INSTALLER | 1 - .../pip-22.2.2.dist-info/LICENSE.txt | 20 - .../pip-22.2.2.dist-info/METADATA | 90 - .../site-packages/pip-22.2.2.dist-info/RECORD | 991 -- .../site-packages/pip-22.2.2.dist-info/WHEEL | 5 - .../pip-22.2.2.dist-info/entry_points.txt | 4 - .../pip-22.2.2.dist-info/top_level.txt | 1 - .../python3.7/site-packages/pip/__init__.py | 13 - .../python3.7/site-packages/pip/__main__.py | 31 - .../site-packages/pip/__pip-runner__.py | 36 - .../pip/__pycache__/__init__.cpython-37.pyc | Bin 636 -> 0 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 594 -> 0 bytes .../__pycache__/__pip-runner__.cpython-37.pyc | Bin 1396 -> 0 bytes .../site-packages/pip/_internal/__init__.py | 19 - .../__pycache__/__init__.cpython-37.pyc | Bin 757 -> 0 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 9037 -> 0 bytes .../__pycache__/cache.cpython-37.pyc | Bin 9172 -> 0 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 11168 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 23857 -> 0 bytes .../_internal/__pycache__/main.cpython-37.pyc | Bin 622 -> 0 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 3610 -> 0 bytes .../self_outdated_check.cpython-37.pyc | Bin 6433 -> 0 bytes .../__pycache__/wheel_builder.cpython-37.pyc | Bin 9087 -> 0 bytes .../site-packages/pip/_internal/build_env.py | 290 - .../site-packages/pip/_internal/cache.py | 289 - .../pip/_internal/cli/__init__.py | 4 - .../cli/__pycache__/__init__.cpython-37.pyc | Bin 281 -> 0 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 5271 -> 0 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 6264 -> 0 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 23711 -> 0 bytes .../command_context.cpython-37.pyc | Bin 1285 -> 0 bytes .../cli/__pycache__/main.cpython-37.pyc | Bin 1363 -> 0 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 2152 -> 0 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 9868 -> 0 bytes .../__pycache__/progress_bars.cpython-37.pyc | Bin 1882 -> 0 bytes .../__pycache__/req_command.cpython-37.pyc | Bin 12886 -> 0 bytes .../cli/__pycache__/spinners.cpython-37.pyc | Bin 4885 -> 0 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 360 -> 0 bytes .../pip/_internal/cli/autocompletion.py | 171 - .../pip/_internal/cli/base_command.py | 223 - .../pip/_internal/cli/cmdoptions.py | 1062 -- .../pip/_internal/cli/command_context.py | 27 - .../site-packages/pip/_internal/cli/main.py | 70 - .../pip/_internal/cli/main_parser.py | 87 - .../site-packages/pip/_internal/cli/parser.py | 294 - .../pip/_internal/cli/progress_bars.py | 68 - .../pip/_internal/cli/req_command.py | 502 - .../pip/_internal/cli/spinners.py | 159 - .../pip/_internal/cli/status_codes.py | 6 - .../pip/_internal/commands/__init__.py | 132 - .../__pycache__/__init__.cpython-37.pyc | Bin 3124 -> 0 bytes .../commands/__pycache__/cache.cpython-37.pyc | Bin 6269 -> 0 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 1578 -> 0 bytes .../__pycache__/completion.cpython-37.pyc | Bin 4143 -> 0 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 8745 -> 0 bytes .../commands/__pycache__/debug.cpython-37.pyc | Bin 6522 -> 0 bytes .../__pycache__/download.cpython-37.pyc | Bin 4052 -> 0 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 2634 -> 0 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 2106 -> 0 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 1302 -> 0 bytes .../commands/__pycache__/index.cpython-37.pyc | Bin 4433 -> 0 bytes .../__pycache__/inspect.cpython-37.pyc | Bin 3103 -> 0 bytes .../__pycache__/install.cpython-37.pyc | Bin 19135 -> 0 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 9992 -> 0 bytes .../__pycache__/search.cpython-37.pyc | Bin 5266 -> 0 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 6270 -> 0 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 3208 -> 0 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 4897 -> 0 bytes .../pip/_internal/commands/cache.py | 223 - .../pip/_internal/commands/check.py | 53 - .../pip/_internal/commands/completion.py | 126 - .../pip/_internal/commands/configuration.py | 276 - .../pip/_internal/commands/debug.py | 199 - .../pip/_internal/commands/download.py | 142 - .../pip/_internal/commands/freeze.py | 97 - .../pip/_internal/commands/hash.py | 59 - .../pip/_internal/commands/help.py | 41 - .../pip/_internal/commands/index.py | 138 - .../pip/_internal/commands/inspect.py | 97 - .../pip/_internal/commands/install.py | 827 -- .../pip/_internal/commands/list.py | 360 - .../pip/_internal/commands/search.py | 174 - .../pip/_internal/commands/show.py | 183 - .../pip/_internal/commands/uninstall.py | 106 - .../pip/_internal/commands/wheel.py | 178 - .../pip/_internal/configuration.py | 374 - .../pip/_internal/distributions/__init__.py | 21 - .../__pycache__/__init__.cpython-37.pyc | Bin 798 -> 0 bytes .../__pycache__/base.cpython-37.pyc | Bin 1890 -> 0 bytes .../__pycache__/installed.cpython-37.pyc | Bin 1268 -> 0 bytes .../__pycache__/sdist.cpython-37.pyc | Bin 4992 -> 0 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 1635 -> 0 bytes .../pip/_internal/distributions/base.py | 39 - .../pip/_internal/distributions/installed.py | 23 - .../pip/_internal/distributions/sdist.py | 150 - .../pip/_internal/distributions/wheel.py | 34 - .../site-packages/pip/_internal/exceptions.py | 658 -- .../pip/_internal/index/__init__.py | 2 - .../index/__pycache__/__init__.cpython-37.pyc | Bin 235 -> 0 bytes .../__pycache__/collector.cpython-37.pyc | Bin 17615 -> 0 bytes .../__pycache__/package_finder.cpython-37.pyc | Bin 28676 -> 0 bytes .../index/__pycache__/sources.cpython-37.pyc | Bin 7213 -> 0 bytes .../pip/_internal/index/collector.py | 621 -- .../pip/_internal/index/package_finder.py | 1025 -- .../pip/_internal/index/sources.py | 224 - .../pip/_internal/locations/__init__.py | 528 - .../__pycache__/__init__.cpython-37.pyc | Bin 12505 -> 0 bytes .../__pycache__/_distutils.cpython-37.pyc | Bin 4755 -> 0 bytes .../__pycache__/_sysconfig.cpython-37.pyc | Bin 6208 -> 0 bytes .../locations/__pycache__/base.cpython-37.pyc | Bin 2406 -> 0 bytes .../pip/_internal/locations/_distutils.py | 180 - .../pip/_internal/locations/_sysconfig.py | 218 - .../pip/_internal/locations/base.py | 81 - .../site-packages/pip/_internal/main.py | 12 - .../pip/_internal/metadata/__init__.py | 105 - .../__pycache__/__init__.cpython-37.pyc | Bin 3999 -> 0 bytes .../metadata/__pycache__/_json.cpython-37.pyc | Bin 2281 -> 0 bytes .../metadata/__pycache__/base.cpython-37.pyc | Bin 26153 -> 0 bytes .../__pycache__/pkg_resources.cpython-37.pyc | Bin 9754 -> 0 bytes .../pip/_internal/metadata/_json.py | 84 - .../pip/_internal/metadata/base.py | 670 -- .../_internal/metadata/importlib/__init__.py | 4 - .../__pycache__/__init__.cpython-37.pyc | Bin 326 -> 0 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 2127 -> 0 bytes .../__pycache__/_dists.cpython-37.pyc | Bin 8229 -> 0 bytes .../__pycache__/_envs.cpython-37.pyc | Bin 7346 -> 0 bytes .../_internal/metadata/importlib/_compat.py | 43 - .../_internal/metadata/importlib/_dists.py | 206 - .../pip/_internal/metadata/importlib/_envs.py | 180 - .../pip/_internal/metadata/pkg_resources.py | 253 - .../pip/_internal/models/__init__.py | 2 - .../__pycache__/__init__.cpython-37.pyc | Bin 269 -> 0 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 1451 -> 0 bytes .../__pycache__/direct_url.cpython-37.pyc | Bin 6978 -> 0 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 2698 -> 0 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 1231 -> 0 bytes .../installation_report.cpython-37.pyc | Bin 1743 -> 0 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 10568 -> 0 bytes .../models/__pycache__/scheme.cpython-37.pyc | Bin 1031 -> 0 bytes .../__pycache__/search_scope.cpython-37.pyc | Bin 3460 -> 0 bytes .../selection_prefs.cpython-37.pyc | Bin 1683 -> 0 bytes .../__pycache__/target_python.cpython-37.pyc | Bin 3393 -> 0 bytes .../models/__pycache__/wheel.cpython-37.pyc | Bin 4403 -> 0 bytes .../pip/_internal/models/candidate.py | 34 - .../pip/_internal/models/direct_url.py | 212 - .../pip/_internal/models/format_control.py | 80 - .../pip/_internal/models/index.py | 28 - .../_internal/models/installation_report.py | 53 - .../pip/_internal/models/link.py | 314 - .../pip/_internal/models/scheme.py | 31 - .../pip/_internal/models/search_scope.py | 129 - .../pip/_internal/models/selection_prefs.py | 51 - .../pip/_internal/models/target_python.py | 110 - .../pip/_internal/models/wheel.py | 92 - .../pip/_internal/network/__init__.py | 2 - .../__pycache__/__init__.cpython-37.pyc | Bin 257 -> 0 bytes .../network/__pycache__/auth.cpython-37.pyc | Bin 7447 -> 0 bytes .../network/__pycache__/cache.cpython-37.pyc | Bin 2801 -> 0 bytes .../__pycache__/download.cpython-37.pyc | Bin 5639 -> 0 bytes .../__pycache__/lazy_wheel.cpython-37.pyc | Bin 8259 -> 0 bytes .../__pycache__/session.cpython-37.pyc | Bin 12395 -> 0 bytes .../network/__pycache__/utils.cpython-37.pyc | Bin 1438 -> 0 bytes .../network/__pycache__/xmlrpc.cpython-37.pyc | Bin 2036 -> 0 bytes .../pip/_internal/network/auth.py | 323 - .../pip/_internal/network/cache.py | 69 - .../pip/_internal/network/download.py | 186 - .../pip/_internal/network/lazy_wheel.py | 210 - .../pip/_internal/network/session.py | 518 - .../pip/_internal/network/utils.py | 96 - .../pip/_internal/network/xmlrpc.py | 60 - .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 205 -> 0 bytes .../__pycache__/check.cpython-37.pyc | Bin 3987 -> 0 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 6067 -> 0 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 13687 -> 0 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-37.pyc | Bin 211 -> 0 bytes .../__pycache__/build_tracker.cpython-37.pyc | Bin 4101 -> 0 bytes .../build/__pycache__/metadata.cpython-37.pyc | Bin 1374 -> 0 bytes .../metadata_editable.cpython-37.pyc | Bin 1406 -> 0 bytes .../metadata_legacy.cpython-37.pyc | Bin 2270 -> 0 bytes .../build/__pycache__/wheel.cpython-37.pyc | Bin 1192 -> 0 bytes .../__pycache__/wheel_editable.cpython-37.pyc | Bin 1388 -> 0 bytes .../__pycache__/wheel_legacy.cpython-37.pyc | Bin 2665 -> 0 bytes .../operations/build/build_tracker.py | 124 - .../_internal/operations/build/metadata.py | 39 - .../operations/build/metadata_editable.py | 41 - .../operations/build/metadata_legacy.py | 74 - .../pip/_internal/operations/build/wheel.py | 37 - .../operations/build/wheel_editable.py | 46 - .../operations/build/wheel_legacy.py | 102 - .../pip/_internal/operations/check.py | 149 - .../pip/_internal/operations/freeze.py | 254 - .../_internal/operations/install/__init__.py | 2 - .../__pycache__/__init__.cpython-37.pyc | Bin 269 -> 0 bytes .../editable_legacy.cpython-37.pyc | Bin 1440 -> 0 bytes .../install/__pycache__/legacy.cpython-37.pyc | Bin 3183 -> 0 bytes .../install/__pycache__/wheel.cpython-37.pyc | Bin 20539 -> 0 bytes .../operations/install/editable_legacy.py | 47 - .../_internal/operations/install/legacy.py | 120 - .../pip/_internal/operations/install/wheel.py | 736 -- .../pip/_internal/operations/prepare.py | 614 -- .../site-packages/pip/_internal/pyproject.py | 175 - .../pip/_internal/req/__init__.py | 94 - .../req/__pycache__/__init__.cpython-37.pyc | Bin 2534 -> 0 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 12114 -> 0 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 13255 -> 0 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 22405 -> 0 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 3941 -> 0 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 18786 -> 0 bytes .../pip/_internal/req/constructors.py | 501 - .../pip/_internal/req/req_file.py | 540 -- .../pip/_internal/req/req_install.py | 879 -- .../pip/_internal/req/req_set.py | 82 - .../pip/_internal/req/req_uninstall.py | 640 -- .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 205 -> 0 bytes .../__pycache__/base.cpython-37.pyc | Bin 1044 -> 0 bytes .../pip/_internal/resolution/base.py | 20 - .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 212 -> 0 bytes .../__pycache__/resolver.cpython-37.pyc | Bin 14798 -> 0 bytes .../_internal/resolution/legacy/resolver.py | 600 -- .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 216 -> 0 bytes .../__pycache__/base.cpython-37.pyc | Bin 6796 -> 0 bytes .../__pycache__/candidates.cpython-37.pyc | Bin 18783 -> 0 bytes .../__pycache__/factory.cpython-37.pyc | Bin 18750 -> 0 bytes .../found_candidates.cpython-37.pyc | Bin 4861 -> 0 bytes .../__pycache__/provider.cpython-37.pyc | Bin 7551 -> 0 bytes .../__pycache__/reporter.cpython-37.pyc | Bin 3291 -> 0 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 7562 -> 0 bytes .../__pycache__/resolver.cpython-37.pyc | Bin 8135 -> 0 bytes .../_internal/resolution/resolvelib/base.py | 141 - .../resolution/resolvelib/candidates.py | 556 -- .../resolution/resolvelib/factory.py | 731 -- .../resolution/resolvelib/found_candidates.py | 155 - .../resolution/resolvelib/provider.py | 248 - .../resolution/resolvelib/reporter.py | 68 - .../resolution/resolvelib/requirements.py | 166 - .../resolution/resolvelib/resolver.py | 296 - .../pip/_internal/self_outdated_check.py | 239 - .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 200 -> 0 bytes .../utils/__pycache__/_log.cpython-37.pyc | Bin 1503 -> 0 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 1622 -> 0 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 1503 -> 0 bytes .../compatibility_tags.cpython-37.pyc | Bin 4007 -> 0 bytes .../utils/__pycache__/datetime.cpython-37.pyc | Bin 515 -> 0 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 3191 -> 0 bytes .../direct_url_helpers.cpython-37.pyc | Bin 2079 -> 0 bytes .../__pycache__/distutils_args.cpython-37.pyc | Bin 1107 -> 0 bytes .../utils/__pycache__/egg_link.cpython-37.pyc | Bin 2132 -> 0 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 1319 -> 0 bytes .../__pycache__/entrypoints.cpython-37.pyc | Bin 2626 -> 0 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 4416 -> 0 bytes .../__pycache__/filetypes.cpython-37.pyc | Bin 946 -> 0 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 1665 -> 0 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 5141 -> 0 bytes .../inject_securetransport.cpython-37.pyc | Bin 985 -> 0 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 9578 -> 0 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 21497 -> 0 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 2046 -> 0 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 2076 -> 0 bytes .../setuptools_build.cpython-37.pyc | Bin 4570 -> 0 bytes .../__pycache__/subprocess.cpython-37.pyc | Bin 5633 -> 0 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 7263 -> 0 bytes .../__pycache__/unpacking.cpython-37.pyc | Bin 6565 -> 0 bytes .../utils/__pycache__/urls.cpython-37.pyc | Bin 1592 -> 0 bytes .../__pycache__/virtualenv.cpython-37.pyc | Bin 3236 -> 0 bytes .../utils/__pycache__/wheel.cpython-37.pyc | Bin 4436 -> 0 bytes .../site-packages/pip/_internal/utils/_log.py | 38 - .../pip/_internal/utils/appdirs.py | 52 - .../pip/_internal/utils/compat.py | 63 - .../pip/_internal/utils/compatibility_tags.py | 165 - .../pip/_internal/utils/datetime.py | 11 - .../pip/_internal/utils/deprecation.py | 120 - .../pip/_internal/utils/direct_url_helpers.py | 87 - .../pip/_internal/utils/distutils_args.py | 43 - .../pip/_internal/utils/egg_link.py | 75 - .../pip/_internal/utils/encoding.py | 36 - .../pip/_internal/utils/entrypoints.py | 79 - .../pip/_internal/utils/filesystem.py | 153 - .../pip/_internal/utils/filetypes.py | 27 - .../pip/_internal/utils/glibc.py | 88 - .../pip/_internal/utils/hashes.py | 144 - .../_internal/utils/inject_securetransport.py | 35 - .../pip/_internal/utils/logging.py | 348 - .../site-packages/pip/_internal/utils/misc.py | 723 -- .../pip/_internal/utils/models.py | 39 - .../pip/_internal/utils/packaging.py | 57 - .../pip/_internal/utils/setuptools_build.py | 195 - .../pip/_internal/utils/subprocess.py | 260 - .../pip/_internal/utils/temp_dir.py | 246 - .../pip/_internal/utils/unpacking.py | 257 - .../site-packages/pip/_internal/utils/urls.py | 62 - .../pip/_internal/utils/virtualenv.py | 104 - .../pip/_internal/utils/wheel.py | 136 - .../pip/_internal/vcs/__init__.py | 15 - .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 523 -> 0 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 3326 -> 0 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 12531 -> 0 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 5044 -> 0 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 8469 -> 0 bytes .../__pycache__/versioncontrol.cpython-37.pyc | Bin 21070 -> 0 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 101 - .../site-packages/pip/_internal/vcs/git.py | 526 - .../pip/_internal/vcs/mercurial.py | 163 - .../pip/_internal/vcs/subversion.py | 324 - .../pip/_internal/vcs/versioncontrol.py | 705 -- .../pip/_internal/wheel_builder.py | 383 - .../site-packages/pip/_vendor/__init__.py | 120 - .../__pycache__/__init__.cpython-37.pyc | Bin 3124 -> 0 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 27471 -> 0 bytes .../typing_extensions.cpython-37.pyc | Bin 65756 -> 0 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 - .../__pycache__/__init__.cpython-37.pyc | Bin 651 -> 0 bytes .../__pycache__/_cmd.cpython-37.pyc | Bin 1561 -> 0 bytes .../__pycache__/adapter.cpython-37.pyc | Bin 3108 -> 0 bytes .../__pycache__/cache.cpython-37.pyc | Bin 2660 -> 0 bytes .../__pycache__/compat.cpython-37.pyc | Bin 765 -> 0 bytes .../__pycache__/controller.cpython-37.pyc | Bin 8550 -> 0 bytes .../__pycache__/filewrapper.cpython-37.pyc | Bin 2777 -> 0 bytes .../__pycache__/heuristics.cpython-37.pyc | Bin 4682 -> 0 bytes .../__pycache__/serialize.cpython-37.pyc | Bin 4390 -> 0 bytes .../__pycache__/wrapper.cpython-37.pyc | Bin 674 -> 0 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 - .../pip/_vendor/cachecontrol/adapter.py | 137 - .../pip/_vendor/cachecontrol/cache.py | 65 - .../_vendor/cachecontrol/caches/__init__.py | 9 - .../__pycache__/__init__.cpython-37.pyc | Bin 370 -> 0 bytes .../__pycache__/file_cache.cpython-37.pyc | Bin 4810 -> 0 bytes .../__pycache__/redis_cache.cpython-37.pyc | Bin 1602 -> 0 bytes .../_vendor/cachecontrol/caches/file_cache.py | 188 - .../cachecontrol/caches/redis_cache.py | 39 - .../pip/_vendor/cachecontrol/compat.py | 32 - .../pip/_vendor/cachecontrol/controller.py | 439 - .../pip/_vendor/cachecontrol/filewrapper.py | 111 - .../pip/_vendor/cachecontrol/heuristics.py | 139 - .../pip/_vendor/cachecontrol/serialize.py | 190 - .../pip/_vendor/cachecontrol/wrapper.py | 33 - .../pip/_vendor/certifi/__init__.py | 4 - .../pip/_vendor/certifi/__main__.py | 12 - .../__pycache__/__init__.cpython-37.pyc | Bin 313 -> 0 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 461 -> 0 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 1750 -> 0 bytes .../pip/_vendor/certifi/cacert.pem | 4685 --------- .../site-packages/pip/_vendor/certifi/core.py | 84 - .../pip/_vendor/chardet/__init__.py | 93 - .../__pycache__/__init__.cpython-37.pyc | Bin 2408 -> 0 bytes .../__pycache__/big5freq.cpython-37.pyc | Bin 27187 -> 0 bytes .../__pycache__/big5prober.cpython-37.pyc | Bin 1119 -> 0 bytes .../chardistribution.cpython-37.pyc | Bin 6921 -> 0 bytes .../charsetgroupprober.cpython-37.pyc | Bin 2229 -> 0 bytes .../__pycache__/charsetprober.cpython-37.pyc | Bin 3365 -> 0 bytes .../codingstatemachine.cpython-37.pyc | Bin 2880 -> 0 bytes .../__pycache__/cp949prober.cpython-37.pyc | Bin 1126 -> 0 bytes .../chardet/__pycache__/enums.cpython-37.pyc | Bin 2606 -> 0 bytes .../__pycache__/escprober.cpython-37.pyc | Bin 2587 -> 0 bytes .../chardet/__pycache__/escsm.cpython-37.pyc | Bin 7074 -> 0 bytes .../__pycache__/eucjpprober.cpython-37.pyc | Bin 2398 -> 0 bytes .../__pycache__/euckrfreq.cpython-37.pyc | Bin 12071 -> 0 bytes .../__pycache__/euckrprober.cpython-37.pyc | Bin 1127 -> 0 bytes .../__pycache__/euctwfreq.cpython-37.pyc | Bin 27191 -> 0 bytes .../__pycache__/euctwprober.cpython-37.pyc | Bin 1127 -> 0 bytes .../__pycache__/gb2312freq.cpython-37.pyc | Bin 19115 -> 0 bytes .../__pycache__/gb2312prober.cpython-37.pyc | Bin 1135 -> 0 bytes .../__pycache__/hebrewprober.cpython-37.pyc | Bin 2977 -> 0 bytes .../__pycache__/jisfreq.cpython-37.pyc | Bin 22143 -> 0 bytes .../__pycache__/johabfreq.cpython-37.pyc | Bin 37332 -> 0 bytes .../__pycache__/johabprober.cpython-37.pyc | Bin 1126 -> 0 bytes .../chardet/__pycache__/jpcntx.cpython-37.pyc | Bin 38003 -> 0 bytes .../langbulgarianmodel.cpython-37.pyc | Bin 21544 -> 0 bytes .../__pycache__/langgreekmodel.cpython-37.pyc | Bin 20232 -> 0 bytes .../langhebrewmodel.cpython-37.pyc | Bin 20298 -> 0 bytes .../langhungarianmodel.cpython-37.pyc | Bin 21489 -> 0 bytes .../langrussianmodel.cpython-37.pyc | Bin 26052 -> 0 bytes .../__pycache__/langthaimodel.cpython-37.pyc | Bin 20474 -> 0 bytes .../langturkishmodel.cpython-37.pyc | Bin 20314 -> 0 bytes .../__pycache__/latin1prober.cpython-37.pyc | Bin 2913 -> 0 bytes .../mbcharsetprober.cpython-37.pyc | Bin 2219 -> 0 bytes .../mbcsgroupprober.cpython-37.pyc | Bin 1180 -> 0 bytes .../chardet/__pycache__/mbcssm.cpython-37.pyc | Bin 17335 -> 0 bytes .../sbcharsetprober.cpython-37.pyc | Bin 3210 -> 0 bytes .../sbcsgroupprober.cpython-37.pyc | Bin 1715 -> 0 bytes .../__pycache__/sjisprober.cpython-37.pyc | Bin 2424 -> 0 bytes .../universaldetector.cpython-37.pyc | Bin 6477 -> 0 bytes .../__pycache__/utf1632prober.cpython-37.pyc | Bin 5900 -> 0 bytes .../__pycache__/utf8prober.cpython-37.pyc | Bin 1952 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 447 -> 0 bytes .../pip/_vendor/chardet/big5freq.py | 386 - .../pip/_vendor/chardet/big5prober.py | 47 - .../pip/_vendor/chardet/chardistribution.py | 259 - .../pip/_vendor/chardet/charsetgroupprober.py | 109 - .../pip/_vendor/chardet/charsetprober.py | 138 - .../pip/_vendor/chardet/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-37.pyc | Bin 204 -> 0 bytes .../cli/__pycache__/chardetect.cpython-37.pyc | Bin 2392 -> 0 bytes .../pip/_vendor/chardet/cli/chardetect.py | 86 - .../pip/_vendor/chardet/codingstatemachine.py | 88 - .../pip/_vendor/chardet/cp949prober.py | 49 - .../pip/_vendor/chardet/enums.py | 82 - .../pip/_vendor/chardet/escprober.py | 102 - .../pip/_vendor/chardet/escsm.py | 260 - .../pip/_vendor/chardet/eucjpprober.py | 95 - .../pip/_vendor/chardet/euckrfreq.py | 196 - .../pip/_vendor/chardet/euckrprober.py | 47 - .../pip/_vendor/chardet/euctwfreq.py | 388 - .../pip/_vendor/chardet/euctwprober.py | 47 - .../pip/_vendor/chardet/gb2312freq.py | 284 - .../pip/_vendor/chardet/gb2312prober.py | 47 - .../pip/_vendor/chardet/hebrewprober.py | 302 - .../pip/_vendor/chardet/jisfreq.py | 325 - .../pip/_vendor/chardet/johabfreq.py | 2382 ----- .../pip/_vendor/chardet/johabprober.py | 47 - .../pip/_vendor/chardet/jpcntx.py | 237 - .../pip/_vendor/chardet/langbulgarianmodel.py | 4649 --------- .../pip/_vendor/chardet/langgreekmodel.py | 4397 --------- .../pip/_vendor/chardet/langhebrewmodel.py | 4380 --------- .../pip/_vendor/chardet/langhungarianmodel.py | 4649 --------- .../pip/_vendor/chardet/langrussianmodel.py | 5725 ----------- .../pip/_vendor/chardet/langthaimodel.py | 4380 --------- .../pip/_vendor/chardet/langturkishmodel.py | 4380 --------- .../pip/_vendor/chardet/latin1prober.py | 145 - .../pip/_vendor/chardet/mbcharsetprober.py | 95 - .../pip/_vendor/chardet/mbcsgroupprober.py | 56 - .../pip/_vendor/chardet/mbcssm.py | 660 -- .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 209 -> 0 bytes .../__pycache__/languages.cpython-37.pyc | Bin 7775 -> 0 bytes .../pip/_vendor/chardet/metadata/languages.py | 351 - .../pip/_vendor/chardet/sbcharsetprober.py | 160 - .../pip/_vendor/chardet/sbcsgroupprober.py | 88 - .../pip/_vendor/chardet/sjisprober.py | 98 - .../pip/_vendor/chardet/universaldetector.py | 328 - .../pip/_vendor/chardet/utf1632prober.py | 223 - .../pip/_vendor/chardet/utf8prober.py | 80 - .../pip/_vendor/chardet/version.py | 9 - .../pip/_vendor/colorama/__init__.py | 6 - .../__pycache__/__init__.cpython-37.pyc | Bin 452 -> 0 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 3350 -> 0 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 7937 -> 0 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 1671 -> 0 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 3865 -> 0 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 4613 -> 0 bytes .../pip/_vendor/colorama/ansi.py | 102 - .../pip/_vendor/colorama/ansitowin32.py | 266 - .../pip/_vendor/colorama/initialise.py | 80 - .../pip/_vendor/colorama/win32.py | 152 - .../pip/_vendor/colorama/winterm.py | 169 - .../pip/_vendor/distlib/__init__.py | 23 - .../__pycache__/__init__.cpython-37.pyc | Bin 1050 -> 0 bytes .../distlib/__pycache__/compat.cpython-37.pyc | Bin 31616 -> 0 bytes .../__pycache__/database.cpython-37.pyc | Bin 43122 -> 0 bytes .../distlib/__pycache__/index.cpython-37.pyc | Bin 17127 -> 0 bytes .../__pycache__/locators.cpython-37.pyc | Bin 38570 -> 0 bytes .../__pycache__/manifest.cpython-37.pyc | Bin 10298 -> 0 bytes .../__pycache__/markers.cpython-37.pyc | Bin 5053 -> 0 bytes .../__pycache__/metadata.cpython-37.pyc | Bin 27621 -> 0 bytes .../__pycache__/resources.cpython-37.pyc | Bin 10882 -> 0 bytes .../__pycache__/scripts.cpython-37.pyc | Bin 11368 -> 0 bytes .../distlib/__pycache__/util.cpython-37.pyc | Bin 51400 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 20482 -> 0 bytes .../distlib/__pycache__/wheel.cpython-37.pyc | Bin 27445 -> 0 bytes .../pip/_vendor/distlib/compat.py | 1116 --- .../pip/_vendor/distlib/database.py | 1350 --- .../pip/_vendor/distlib/index.py | 508 - .../pip/_vendor/distlib/locators.py | 1300 --- .../pip/_vendor/distlib/manifest.py | 393 - .../pip/_vendor/distlib/markers.py | 152 - .../pip/_vendor/distlib/metadata.py | 1076 --- .../pip/_vendor/distlib/resources.py | 358 - .../pip/_vendor/distlib/scripts.py | 437 - .../site-packages/pip/_vendor/distlib/t32.exe | Bin 97792 -> 0 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 182784 -> 0 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 107520 -> 0 bytes .../site-packages/pip/_vendor/distlib/util.py | 1932 ---- .../pip/_vendor/distlib/version.py | 739 -- .../site-packages/pip/_vendor/distlib/w32.exe | Bin 91648 -> 0 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 168448 -> 0 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 101888 -> 0 bytes .../pip/_vendor/distlib/wheel.py | 1082 --- .../pip/_vendor/distro/__init__.py | 54 - .../pip/_vendor/distro/__main__.py | 4 - .../__pycache__/__init__.cpython-37.pyc | Bin 1008 -> 0 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 272 -> 0 bytes .../distro/__pycache__/distro.cpython-37.pyc | Bin 41403 -> 0 bytes .../pip/_vendor/distro/distro.py | 1374 --- .../pip/_vendor/idna/__init__.py | 44 - .../idna/__pycache__/__init__.cpython-37.pyc | Bin 924 -> 0 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 3283 -> 0 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 763 -> 0 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 9816 -> 0 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 23144 -> 0 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 1994 -> 0 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 220 -> 0 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 185557 -> 0 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 - .../site-packages/pip/_vendor/idna/compat.py | 13 - .../site-packages/pip/_vendor/idna/core.py | 397 - .../pip/_vendor/idna/idnadata.py | 2137 ----- .../pip/_vendor/idna/intranges.py | 54 - .../pip/_vendor/idna/package_data.py | 2 - .../pip/_vendor/idna/uts46data.py | 8512 ----------------- .../pip/_vendor/msgpack/__init__.py | 57 - .../__pycache__/__init__.cpython-37.pyc | Bin 1419 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 1875 -> 0 bytes .../msgpack/__pycache__/ext.cpython-37.pyc | Bin 6231 -> 0 bytes .../__pycache__/fallback.cpython-37.pyc | Bin 25654 -> 0 bytes .../pip/_vendor/msgpack/exceptions.py | 48 - .../site-packages/pip/_vendor/msgpack/ext.py | 193 - .../pip/_vendor/msgpack/fallback.py | 1010 -- .../pip/_vendor/packaging/__about__.py | 26 - .../pip/_vendor/packaging/__init__.py | 25 - .../__pycache__/__about__.cpython-37.pyc | Bin 623 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 479 -> 0 bytes .../__pycache__/_manylinux.cpython-37.pyc | Bin 7236 -> 0 bytes .../__pycache__/_musllinux.cpython-37.pyc | Bin 4579 -> 0 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 2827 -> 0 bytes .../__pycache__/markers.cpython-37.pyc | Bin 9450 -> 0 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 3959 -> 0 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 21578 -> 0 bytes .../packaging/__pycache__/tags.cpython-37.pyc | Bin 12157 -> 0 bytes .../__pycache__/utils.cpython-37.pyc | Bin 3600 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 13108 -> 0 bytes .../pip/_vendor/packaging/_manylinux.py | 301 - .../pip/_vendor/packaging/_musllinux.py | 136 - .../pip/_vendor/packaging/_structures.py | 61 - .../pip/_vendor/packaging/markers.py | 304 - .../pip/_vendor/packaging/requirements.py | 146 - .../pip/_vendor/packaging/specifiers.py | 802 -- .../pip/_vendor/packaging/tags.py | 487 - .../pip/_vendor/packaging/utils.py | 136 - .../pip/_vendor/packaging/version.py | 504 - .../pip/_vendor/pep517/__init__.py | 6 - .../__pycache__/__init__.cpython-37.pyc | Bin 322 -> 0 bytes .../pep517/__pycache__/build.cpython-37.pyc | Bin 3488 -> 0 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 4984 -> 0 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 2923 -> 0 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 1468 -> 0 bytes .../__pycache__/dirtools.cpython-37.pyc | Bin 1336 -> 0 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 4394 -> 0 bytes .../pep517/__pycache__/meta.cpython-37.pyc | Bin 2823 -> 0 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 12430 -> 0 bytes .../site-packages/pip/_vendor/pep517/build.py | 127 - .../site-packages/pip/_vendor/pep517/check.py | 207 - .../pip/_vendor/pep517/colorlog.py | 115 - .../pip/_vendor/pep517/compat.py | 51 - .../pip/_vendor/pep517/dirtools.py | 44 - .../pip/_vendor/pep517/envbuild.py | 171 - .../pip/_vendor/pep517/in_process/__init__.py | 17 - .../__pycache__/__init__.cpython-37.pyc | Bin 930 -> 0 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 10223 -> 0 bytes .../_vendor/pep517/in_process/_in_process.py | 363 - .../site-packages/pip/_vendor/pep517/meta.py | 92 - .../pip/_vendor/pep517/wrappers.py | 375 - .../pip/_vendor/pkg_resources/__init__.py | 3296 ------- .../__pycache__/__init__.cpython-37.pyc | Bin 99756 -> 0 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 651 -> 0 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 - .../pip/_vendor/platformdirs/__init__.py | 340 - .../pip/_vendor/platformdirs/__main__.py | 46 - .../__pycache__/__init__.cpython-37.pyc | Bin 11091 -> 0 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 1243 -> 0 bytes .../__pycache__/android.cpython-37.pyc | Bin 4465 -> 0 bytes .../__pycache__/api.cpython-37.pyc | Bin 5230 -> 0 bytes .../__pycache__/macos.cpython-37.pyc | Bin 3341 -> 0 bytes .../__pycache__/unix.cpython-37.pyc | Bin 7106 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 302 -> 0 bytes .../__pycache__/windows.cpython-37.pyc | Bin 6467 -> 0 bytes .../pip/_vendor/platformdirs/android.py | 120 - .../pip/_vendor/platformdirs/api.py | 156 - .../pip/_vendor/platformdirs/macos.py | 64 - .../pip/_vendor/platformdirs/unix.py | 181 - .../pip/_vendor/platformdirs/version.py | 4 - .../pip/_vendor/platformdirs/windows.py | 182 - .../pip/_vendor/pygments/__init__.py | 83 - .../pip/_vendor/pygments/__main__.py | 17 - .../__pycache__/__init__.cpython-37.pyc | Bin 3026 -> 0 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 597 -> 0 bytes .../__pycache__/cmdline.cpython-37.pyc | Bin 15127 -> 0 bytes .../__pycache__/console.cpython-37.pyc | Bin 1908 -> 0 bytes .../__pycache__/filter.cpython-37.pyc | Bin 2628 -> 0 bytes .../__pycache__/formatter.cpython-37.pyc | Bin 2997 -> 0 bytes .../pygments/__pycache__/lexer.cpython-37.pyc | Bin 24385 -> 0 bytes .../__pycache__/modeline.cpython-37.pyc | Bin 1185 -> 0 bytes .../__pycache__/plugin.cpython-37.pyc | Bin 2109 -> 0 bytes .../__pycache__/regexopt.cpython-37.pyc | Bin 2885 -> 0 bytes .../__pycache__/scanner.cpython-37.pyc | Bin 3536 -> 0 bytes .../__pycache__/sphinxext.cpython-37.pyc | Bin 4563 -> 0 bytes .../pygments/__pycache__/style.cpython-37.pyc | Bin 4473 -> 0 bytes .../pygments/__pycache__/token.cpython-37.pyc | Bin 4324 -> 0 bytes .../__pycache__/unistring.cpython-37.pyc | Bin 31247 -> 0 bytes .../pygments/__pycache__/util.cpython-37.pyc | Bin 9059 -> 0 bytes .../pip/_vendor/pygments/cmdline.py | 663 -- .../pip/_vendor/pygments/console.py | 70 - .../pip/_vendor/pygments/filter.py | 71 - .../pip/_vendor/pygments/filters/__init__.py | 937 -- .../__pycache__/__init__.cpython-37.pyc | Bin 23471 -> 0 bytes .../pip/_vendor/pygments/formatter.py | 94 - .../_vendor/pygments/formatters/__init__.py | 153 - .../__pycache__/__init__.cpython-37.pyc | Bin 4584 -> 0 bytes .../__pycache__/_mapping.cpython-37.pyc | Bin 5517 -> 0 bytes .../__pycache__/bbcode.cpython-37.pyc | Bin 3066 -> 0 bytes .../__pycache__/groff.cpython-37.pyc | Bin 4356 -> 0 bytes .../__pycache__/html.cpython-37.pyc | Bin 29102 -> 0 bytes .../formatters/__pycache__/img.cpython-37.pyc | Bin 17492 -> 0 bytes .../formatters/__pycache__/irc.cpython-37.pyc | Bin 4435 -> 0 bytes .../__pycache__/latex.cpython-37.pyc | Bin 13723 -> 0 bytes .../__pycache__/other.cpython-37.pyc | Bin 4766 -> 0 bytes .../__pycache__/pangomarkup.cpython-37.pyc | Bin 2089 -> 0 bytes .../formatters/__pycache__/rtf.cpython-37.pyc | Bin 4123 -> 0 bytes .../formatters/__pycache__/svg.cpython-37.pyc | Bin 6323 -> 0 bytes .../__pycache__/terminal.cpython-37.pyc | Bin 3887 -> 0 bytes .../__pycache__/terminal256.cpython-37.pyc | Bin 9203 -> 0 bytes .../_vendor/pygments/formatters/_mapping.py | 84 - .../pip/_vendor/pygments/formatters/bbcode.py | 108 - .../pip/_vendor/pygments/formatters/groff.py | 170 - .../pip/_vendor/pygments/formatters/html.py | 989 -- .../pip/_vendor/pygments/formatters/img.py | 641 -- .../pip/_vendor/pygments/formatters/irc.py | 179 - .../pip/_vendor/pygments/formatters/latex.py | 521 - .../pip/_vendor/pygments/formatters/other.py | 161 - .../pygments/formatters/pangomarkup.py | 83 - .../pip/_vendor/pygments/formatters/rtf.py | 146 - .../pip/_vendor/pygments/formatters/svg.py | 188 - .../_vendor/pygments/formatters/terminal.py | 127 - .../pygments/formatters/terminal256.py | 338 - .../pip/_vendor/pygments/lexer.py | 882 -- .../pip/_vendor/pygments/lexers/__init__.py | 345 - .../__pycache__/__init__.cpython-37.pyc | Bin 9291 -> 0 bytes .../__pycache__/_mapping.cpython-37.pyc | Bin 63854 -> 0 bytes .../lexers/__pycache__/python.cpython-37.pyc | Bin 30843 -> 0 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 596 -- .../pip/_vendor/pygments/lexers/python.py | 1191 --- .../pip/_vendor/pygments/modeline.py | 43 - .../pip/_vendor/pygments/plugin.py | 69 - .../pip/_vendor/pygments/regexopt.py | 91 - .../pip/_vendor/pygments/scanner.py | 104 - .../pip/_vendor/pygments/sphinxext.py | 155 - .../pip/_vendor/pygments/style.py | 197 - .../pip/_vendor/pygments/styles/__init__.py | 93 - .../__pycache__/__init__.cpython-37.pyc | Bin 3005 -> 0 bytes .../pip/_vendor/pygments/token.py | 212 - .../pip/_vendor/pygments/unistring.py | 153 - .../pip/_vendor/pygments/util.py | 308 - .../pip/_vendor/pyparsing/__init__.py | 331 - .../__pycache__/__init__.cpython-37.pyc | Bin 7725 -> 0 bytes .../__pycache__/actions.cpython-37.pyc | Bin 7140 -> 0 bytes .../__pycache__/common.cpython-37.pyc | Bin 9934 -> 0 bytes .../pyparsing/__pycache__/core.cpython-37.pyc | Bin 178870 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 9208 -> 0 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 34985 -> 0 bytes .../__pycache__/results.cpython-37.pyc | Bin 24606 -> 0 bytes .../__pycache__/testing.cpython-37.pyc | Bin 11893 -> 0 bytes .../__pycache__/unicode.cpython-37.pyc | Bin 11176 -> 0 bytes .../pyparsing/__pycache__/util.cpython-37.pyc | Bin 8567 -> 0 bytes .../pip/_vendor/pyparsing/actions.py | 207 - .../pip/_vendor/pyparsing/common.py | 424 - .../pip/_vendor/pyparsing/core.py | 5814 ----------- .../pip/_vendor/pyparsing/diagram/__init__.py | 642 -- .../__pycache__/__init__.cpython-37.pyc | Bin 16395 -> 0 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 - .../pip/_vendor/pyparsing/helpers.py | 1088 --- .../pip/_vendor/pyparsing/results.py | 760 -- .../pip/_vendor/pyparsing/testing.py | 331 - .../pip/_vendor/pyparsing/unicode.py | 352 - .../pip/_vendor/pyparsing/util.py | 235 - .../pip/_vendor/requests/__init__.py | 182 - .../__pycache__/__init__.cpython-37.pyc | Bin 4008 -> 0 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 564 -> 0 bytes .../_internal_utils.cpython-37.pyc | Bin 1577 -> 0 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 16879 -> 0 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 6696 -> 0 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 8374 -> 0 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 642 -> 0 bytes .../__pycache__/compat.cpython-37.pyc | Bin 1380 -> 0 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 18776 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 6396 -> 0 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 2836 -> 0 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 989 -> 0 bytes .../__pycache__/models.cpython-37.pyc | Bin 24552 -> 0 bytes .../__pycache__/packages.cpython-37.pyc | Bin 519 -> 0 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 19602 -> 0 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 4236 -> 0 bytes .../__pycache__/structures.cpython-37.pyc | Bin 4411 -> 0 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 24007 -> 0 bytes .../pip/_vendor/requests/__version__.py | 14 - .../pip/_vendor/requests/_internal_utils.py | 48 - .../pip/_vendor/requests/adapters.py | 584 -- .../site-packages/pip/_vendor/requests/api.py | 157 - .../pip/_vendor/requests/auth.py | 315 - .../pip/_vendor/requests/certs.py | 17 - .../pip/_vendor/requests/compat.py | 67 - .../pip/_vendor/requests/cookies.py | 561 -- .../pip/_vendor/requests/exceptions.py | 141 - .../pip/_vendor/requests/help.py | 131 - .../pip/_vendor/requests/hooks.py | 33 - .../pip/_vendor/requests/models.py | 1034 -- .../pip/_vendor/requests/packages.py | 16 - .../pip/_vendor/requests/sessions.py | 831 -- .../pip/_vendor/requests/status_codes.py | 128 - .../pip/_vendor/requests/structures.py | 99 - .../pip/_vendor/requests/utils.py | 1086 --- .../pip/_vendor/resolvelib/__init__.py | 26 - .../__pycache__/__init__.cpython-37.pyc | Bin 647 -> 0 bytes .../__pycache__/providers.cpython-37.pyc | Bin 6688 -> 0 bytes .../__pycache__/reporters.cpython-37.pyc | Bin 2597 -> 0 bytes .../__pycache__/resolvers.cpython-37.pyc | Bin 15316 -> 0 bytes .../__pycache__/structs.cpython-37.pyc | Bin 7280 -> 0 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 210 -> 0 bytes .../collections_abc.cpython-37.pyc | Bin 386 -> 0 bytes .../resolvelib/compat/collections_abc.py | 6 - .../pip/_vendor/resolvelib/providers.py | 133 - .../pip/_vendor/resolvelib/reporters.py | 43 - .../pip/_vendor/resolvelib/resolvers.py | 482 - .../pip/_vendor/resolvelib/structs.py | 165 - .../pip/_vendor/rich/__init__.py | 176 - .../pip/_vendor/rich/__main__.py | 282 - .../rich/__pycache__/__init__.cpython-37.pyc | Bin 5829 -> 0 bytes .../rich/__pycache__/__main__.cpython-37.pyc | Bin 7195 -> 0 bytes .../__pycache__/_cell_widths.cpython-37.pyc | Bin 9989 -> 0 bytes .../__pycache__/_emoji_codes.cpython-37.pyc | Bin 132652 -> 0 bytes .../__pycache__/_emoji_replace.cpython-37.pyc | Bin 1183 -> 0 bytes .../__pycache__/_export_format.cpython-37.pyc | Bin 2320 -> 0 bytes .../__pycache__/_extension.cpython-37.pyc | Bin 500 -> 0 bytes .../rich/__pycache__/_inspect.cpython-37.pyc | Bin 8622 -> 0 bytes .../__pycache__/_log_render.cpython-37.pyc | Bin 2537 -> 0 bytes .../rich/__pycache__/_loop.cpython-37.pyc | Bin 1301 -> 0 bytes .../rich/__pycache__/_palettes.cpython-37.pyc | Bin 6216 -> 0 bytes .../rich/__pycache__/_pick.cpython-37.pyc | Bin 659 -> 0 bytes .../rich/__pycache__/_ratio.cpython-37.pyc | Bin 5107 -> 0 bytes .../rich/__pycache__/_spinners.cpython-37.pyc | Bin 12357 -> 0 bytes .../rich/__pycache__/_stack.cpython-37.pyc | Bin 840 -> 0 bytes .../rich/__pycache__/_timer.cpython-37.pyc | Bin 695 -> 0 bytes .../__pycache__/_win32_console.cpython-37.pyc | Bin 19212 -> 0 bytes .../rich/__pycache__/_windows.cpython-37.pyc | Bin 1772 -> 0 bytes .../_windows_renderer.cpython-37.pyc | Bin 2072 -> 0 bytes .../rich/__pycache__/_wrap.cpython-37.pyc | Bin 1544 -> 0 bytes .../rich/__pycache__/abc.cpython-37.pyc | Bin 1301 -> 0 bytes .../rich/__pycache__/align.cpython-37.pyc | Bin 7904 -> 0 bytes .../rich/__pycache__/ansi.cpython-37.pyc | Bin 5547 -> 0 bytes .../rich/__pycache__/bar.cpython-37.pyc | Bin 2895 -> 0 bytes .../rich/__pycache__/box.cpython-37.pyc | Bin 8413 -> 0 bytes .../rich/__pycache__/cells.cpython-37.pyc | Bin 4190 -> 0 bytes .../rich/__pycache__/color.cpython-37.pyc | Bin 15106 -> 0 bytes .../__pycache__/color_triplet.cpython-37.pyc | Bin 1452 -> 0 bytes .../rich/__pycache__/columns.cpython-37.pyc | Bin 6094 -> 0 bytes .../rich/__pycache__/console.cpython-37.pyc | Bin 79506 -> 0 bytes .../rich/__pycache__/constrain.cpython-37.pyc | Bin 1648 -> 0 bytes .../__pycache__/containers.cpython-37.pyc | Bin 6427 -> 0 bytes .../rich/__pycache__/control.cpython-37.pyc | Bin 8044 -> 0 bytes .../__pycache__/default_styles.cpython-37.pyc | Bin 5292 -> 0 bytes .../rich/__pycache__/diagnose.cpython-37.pyc | Bin 1214 -> 0 bytes .../rich/__pycache__/emoji.cpython-37.pyc | Bin 3173 -> 0 bytes .../rich/__pycache__/errors.cpython-37.pyc | Bin 1778 -> 0 bytes .../__pycache__/file_proxy.cpython-37.pyc | Bin 2208 -> 0 bytes .../rich/__pycache__/filesize.cpython-37.pyc | Bin 2599 -> 0 bytes .../__pycache__/highlighter.cpython-37.pyc | Bin 8059 -> 0 bytes .../rich/__pycache__/json.cpython-37.pyc | Bin 4652 -> 0 bytes .../rich/__pycache__/jupyter.cpython-37.pyc | Bin 4063 -> 0 bytes .../rich/__pycache__/layout.cpython-37.pyc | Bin 14623 -> 0 bytes .../rich/__pycache__/live.cpython-37.pyc | Bin 10923 -> 0 bytes .../__pycache__/live_render.cpython-37.pyc | Bin 3361 -> 0 bytes .../rich/__pycache__/logging.cpython-37.pyc | Bin 9653 -> 0 bytes .../rich/__pycache__/markup.cpython-37.pyc | Bin 5895 -> 0 bytes .../rich/__pycache__/measure.cpython-37.pyc | Bin 4971 -> 0 bytes .../rich/__pycache__/padding.cpython-37.pyc | Bin 4359 -> 0 bytes .../rich/__pycache__/pager.cpython-37.pyc | Bin 1443 -> 0 bytes .../rich/__pycache__/palette.cpython-37.pyc | Bin 3687 -> 0 bytes .../rich/__pycache__/panel.cpython-37.pyc | Bin 6311 -> 0 bytes .../rich/__pycache__/pretty.cpython-37.pyc | Bin 27038 -> 0 bytes .../rich/__pycache__/progress.cpython-37.pyc | Bin 52847 -> 0 bytes .../__pycache__/progress_bar.cpython-37.pyc | Bin 6742 -> 0 bytes .../rich/__pycache__/prompt.cpython-37.pyc | Bin 11229 -> 0 bytes .../rich/__pycache__/protocol.cpython-37.pyc | Bin 1342 -> 0 bytes .../rich/__pycache__/region.cpython-37.pyc | Bin 530 -> 0 bytes .../rich/__pycache__/repr.cpython-37.pyc | Bin 4067 -> 0 bytes .../rich/__pycache__/rule.cpython-37.pyc | Bin 4216 -> 0 bytes .../rich/__pycache__/scope.cpython-37.pyc | Bin 2948 -> 0 bytes .../rich/__pycache__/screen.cpython-37.pyc | Bin 1809 -> 0 bytes .../rich/__pycache__/segment.cpython-37.pyc | Bin 20368 -> 0 bytes .../rich/__pycache__/spinner.cpython-37.pyc | Bin 4290 -> 0 bytes .../rich/__pycache__/status.cpython-37.pyc | Bin 4498 -> 0 bytes .../rich/__pycache__/style.cpython-37.pyc | Bin 20673 -> 0 bytes .../rich/__pycache__/styled.cpython-37.pyc | Bin 1673 -> 0 bytes .../rich/__pycache__/syntax.cpython-37.pyc | Bin 24846 -> 0 bytes .../rich/__pycache__/table.cpython-37.pyc | Bin 29110 -> 0 bytes .../__pycache__/terminal_theme.cpython-37.pyc | Bin 3155 -> 0 bytes .../rich/__pycache__/text.cpython-37.pyc | Bin 39708 -> 0 bytes .../rich/__pycache__/theme.cpython-37.pyc | Bin 4603 -> 0 bytes .../rich/__pycache__/themes.cpython-37.pyc | Bin 302 -> 0 bytes .../rich/__pycache__/traceback.cpython-37.pyc | Bin 19254 -> 0 bytes .../rich/__pycache__/tree.cpython-37.pyc | Bin 7207 -> 0 bytes .../pip/_vendor/rich/_cell_widths.py | 451 - .../pip/_vendor/rich/_emoji_codes.py | 3610 ------- .../pip/_vendor/rich/_emoji_replace.py | 32 - .../pip/_vendor/rich/_export_format.py | 78 - .../pip/_vendor/rich/_extension.py | 10 - .../pip/_vendor/rich/_inspect.py | 270 - .../pip/_vendor/rich/_log_render.py | 94 - .../site-packages/pip/_vendor/rich/_loop.py | 43 - .../pip/_vendor/rich/_palettes.py | 309 - .../site-packages/pip/_vendor/rich/_pick.py | 17 - .../site-packages/pip/_vendor/rich/_ratio.py | 160 - .../pip/_vendor/rich/_spinners.py | 482 - .../site-packages/pip/_vendor/rich/_stack.py | 16 - .../site-packages/pip/_vendor/rich/_timer.py | 19 - .../pip/_vendor/rich/_win32_console.py | 662 -- .../pip/_vendor/rich/_windows.py | 72 - .../pip/_vendor/rich/_windows_renderer.py | 56 - .../site-packages/pip/_vendor/rich/_wrap.py | 56 - .../site-packages/pip/_vendor/rich/abc.py | 33 - .../site-packages/pip/_vendor/rich/align.py | 311 - .../site-packages/pip/_vendor/rich/ansi.py | 237 - .../site-packages/pip/_vendor/rich/bar.py | 94 - .../site-packages/pip/_vendor/rich/box.py | 517 - .../site-packages/pip/_vendor/rich/cells.py | 154 - .../site-packages/pip/_vendor/rich/color.py | 615 -- .../pip/_vendor/rich/color_triplet.py | 38 - .../site-packages/pip/_vendor/rich/columns.py | 187 - .../site-packages/pip/_vendor/rich/console.py | 2572 ----- .../pip/_vendor/rich/constrain.py | 37 - .../pip/_vendor/rich/containers.py | 167 - .../site-packages/pip/_vendor/rich/control.py | 225 - .../pip/_vendor/rich/default_styles.py | 188 - .../pip/_vendor/rich/diagnose.py | 37 - .../site-packages/pip/_vendor/rich/emoji.py | 96 - .../site-packages/pip/_vendor/rich/errors.py | 34 - .../pip/_vendor/rich/file_proxy.py | 54 - .../pip/_vendor/rich/filesize.py | 89 - .../pip/_vendor/rich/highlighter.py | 232 - .../site-packages/pip/_vendor/rich/json.py | 140 - .../site-packages/pip/_vendor/rich/jupyter.py | 101 - .../site-packages/pip/_vendor/rich/layout.py | 445 - .../site-packages/pip/_vendor/rich/live.py | 373 - .../pip/_vendor/rich/live_render.py | 113 - .../site-packages/pip/_vendor/rich/logging.py | 280 - .../site-packages/pip/_vendor/rich/markup.py | 246 - .../site-packages/pip/_vendor/rich/measure.py | 151 - .../site-packages/pip/_vendor/rich/padding.py | 141 - .../site-packages/pip/_vendor/rich/pager.py | 34 - .../site-packages/pip/_vendor/rich/palette.py | 100 - .../site-packages/pip/_vendor/rich/panel.py | 251 - .../site-packages/pip/_vendor/rich/pretty.py | 1010 -- .../pip/_vendor/rich/progress.py | 1703 ---- .../pip/_vendor/rich/progress_bar.py | 224 - .../site-packages/pip/_vendor/rich/prompt.py | 376 - .../pip/_vendor/rich/protocol.py | 42 - .../site-packages/pip/_vendor/rich/region.py | 10 - .../site-packages/pip/_vendor/rich/repr.py | 152 - .../site-packages/pip/_vendor/rich/rule.py | 134 - .../site-packages/pip/_vendor/rich/scope.py | 86 - .../site-packages/pip/_vendor/rich/screen.py | 54 - .../site-packages/pip/_vendor/rich/segment.py | 739 -- .../site-packages/pip/_vendor/rich/spinner.py | 136 - .../site-packages/pip/_vendor/rich/status.py | 132 - .../site-packages/pip/_vendor/rich/style.py | 771 -- .../site-packages/pip/_vendor/rich/styled.py | 42 - .../site-packages/pip/_vendor/rich/syntax.py | 934 -- .../site-packages/pip/_vendor/rich/table.py | 996 -- .../pip/_vendor/rich/terminal_theme.py | 153 - .../site-packages/pip/_vendor/rich/text.py | 1286 --- .../site-packages/pip/_vendor/rich/theme.py | 112 - .../site-packages/pip/_vendor/rich/themes.py | 5 - .../pip/_vendor/rich/traceback.py | 679 -- .../site-packages/pip/_vendor/rich/tree.py | 251 - .../site-packages/pip/_vendor/six.py | 998 -- .../pip/_vendor/tenacity/__init__.py | 517 - .../__pycache__/__init__.cpython-37.pyc | Bin 16204 -> 0 bytes .../__pycache__/_asyncio.cpython-37.pyc | Bin 2581 -> 0 bytes .../__pycache__/_utils.cpython-37.pyc | Bin 1238 -> 0 bytes .../tenacity/__pycache__/after.cpython-37.pyc | Bin 1208 -> 0 bytes .../__pycache__/before.cpython-37.pyc | Bin 1105 -> 0 bytes .../__pycache__/before_sleep.cpython-37.pyc | Bin 1382 -> 0 bytes .../tenacity/__pycache__/nap.cpython-37.pyc | Bin 1185 -> 0 bytes .../tenacity/__pycache__/retry.cpython-37.pyc | Bin 9041 -> 0 bytes .../tenacity/__pycache__/stop.cpython-37.pyc | Bin 4298 -> 0 bytes .../__pycache__/tornadoweb.cpython-37.pyc | Bin 1741 -> 0 bytes .../tenacity/__pycache__/wait.cpython-37.pyc | Bin 8029 -> 0 bytes .../pip/_vendor/tenacity/_asyncio.py | 92 - .../pip/_vendor/tenacity/_utils.py | 68 - .../pip/_vendor/tenacity/after.py | 46 - .../pip/_vendor/tenacity/before.py | 41 - .../pip/_vendor/tenacity/before_sleep.py | 58 - .../site-packages/pip/_vendor/tenacity/nap.py | 43 - .../pip/_vendor/tenacity/retry.py | 213 - .../pip/_vendor/tenacity/stop.py | 96 - .../pip/_vendor/tenacity/tornadoweb.py | 59 - .../pip/_vendor/tenacity/wait.py | 191 - .../pip/_vendor/tomli/__init__.py | 11 - .../tomli/__pycache__/__init__.cpython-37.pyc | Bin 364 -> 0 bytes .../tomli/__pycache__/_parser.cpython-37.pyc | Bin 16733 -> 0 bytes .../tomli/__pycache__/_re.cpython-37.pyc | Bin 2787 -> 0 bytes .../tomli/__pycache__/_types.cpython-37.pyc | Bin 334 -> 0 bytes .../pip/_vendor/tomli/_parser.py | 691 -- .../site-packages/pip/_vendor/tomli/_re.py | 107 - .../site-packages/pip/_vendor/tomli/_types.py | 10 - .../pip/_vendor/typing_extensions.py | 2069 ---- .../pip/_vendor/urllib3/__init__.py | 85 - .../__pycache__/__init__.cpython-37.pyc | Bin 2190 -> 0 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 10719 -> 0 bytes .../__pycache__/_version.cpython-37.pyc | Bin 223 -> 0 bytes .../__pycache__/connection.cpython-37.pyc | Bin 13790 -> 0 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 25361 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 12061 -> 0 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 8151 -> 0 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 2769 -> 0 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 15054 -> 0 bytes .../__pycache__/request.cpython-37.pyc | Bin 5569 -> 0 bytes .../__pycache__/response.cpython-37.pyc | Bin 20506 -> 0 bytes .../pip/_vendor/urllib3/_collections.py | 337 - .../pip/_vendor/urllib3/_version.py | 2 - .../pip/_vendor/urllib3/connection.py | 567 -- .../pip/_vendor/urllib3/connectionpool.py | 1110 --- .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 208 -> 0 bytes .../_appengine_environ.cpython-37.pyc | Bin 1417 -> 0 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 8189 -> 0 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 3614 -> 0 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 15444 -> 0 bytes .../securetransport.cpython-37.pyc | Bin 21506 -> 0 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 5578 -> 0 bytes .../urllib3/contrib/_appengine_environ.py | 36 - .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 225 -> 0 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 10659 -> 0 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 9030 -> 0 bytes .../contrib/_securetransport/bindings.py | 519 - .../contrib/_securetransport/low_level.py | 397 - .../pip/_vendor/urllib3/contrib/appengine.py | 314 - .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 - .../pip/_vendor/urllib3/contrib/pyopenssl.py | 510 - .../urllib3/contrib/securetransport.py | 921 -- .../pip/_vendor/urllib3/contrib/socks.py | 216 - .../pip/_vendor/urllib3/exceptions.py | 323 - .../pip/_vendor/urllib3/fields.py | 274 - .../pip/_vendor/urllib3/filepost.py | 98 - .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 209 -> 0 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 27524 -> 0 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 219 -> 0 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 1309 -> 0 bytes .../urllib3/packages/backports/makefile.py | 51 - .../pip/_vendor/urllib3/packages/six.py | 1076 --- .../pip/_vendor/urllib3/poolmanager.py | 537 -- .../pip/_vendor/urllib3/request.py | 170 - .../pip/_vendor/urllib3/response.py | 818 -- .../pip/_vendor/urllib3/util/__init__.py | 49 - .../util/__pycache__/__init__.cpython-37.pyc | Bin 1118 -> 0 bytes .../__pycache__/connection.cpython-37.pyc | Bin 3424 -> 0 bytes .../util/__pycache__/proxy.cpython-37.pyc | Bin 1326 -> 0 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 1049 -> 0 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 3361 -> 0 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 2336 -> 0 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 16879 -> 0 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 11301 -> 0 bytes .../ssl_match_hostname.cpython-37.pyc | Bin 3256 -> 0 bytes .../__pycache__/ssltransport.cpython-37.pyc | Bin 7314 -> 0 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 8908 -> 0 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 10681 -> 0 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 3139 -> 0 bytes .../pip/_vendor/urllib3/util/connection.py | 149 - .../pip/_vendor/urllib3/util/proxy.py | 57 - .../pip/_vendor/urllib3/util/queue.py | 22 - .../pip/_vendor/urllib3/util/request.py | 137 - .../pip/_vendor/urllib3/util/response.py | 107 - .../pip/_vendor/urllib3/util/retry.py | 620 -- .../pip/_vendor/urllib3/util/ssl_.py | 495 - .../urllib3/util/ssl_match_hostname.py | 159 - .../pip/_vendor/urllib3/util/ssltransport.py | 221 - .../pip/_vendor/urllib3/util/timeout.py | 268 - .../pip/_vendor/urllib3/util/url.py | 435 - .../pip/_vendor/urllib3/util/wait.py | 152 - .../site-packages/pip/_vendor/vendor.txt | 23 - .../pip/_vendor/webencodings/__init__.py | 342 - .../__pycache__/__init__.cpython-37.pyc | Bin 9684 -> 0 bytes .../__pycache__/labels.cpython-37.pyc | Bin 4098 -> 0 bytes .../__pycache__/mklabels.cpython-37.pyc | Bin 1920 -> 0 bytes .../__pycache__/tests.cpython-37.pyc | Bin 5061 -> 0 bytes .../__pycache__/x_user_defined.cpython-37.pyc | Bin 2673 -> 0 bytes .../pip/_vendor/webencodings/labels.py | 231 - .../pip/_vendor/webencodings/mklabels.py | 59 - .../pip/_vendor/webencodings/tests.py | 153 - .../_vendor/webencodings/x_user_defined.py | 325 - venv/lib/python3.7/site-packages/pip/py.typed | 4 - .../site-packages/pkg_resources/__init__.py | 3171 ------ .../__pycache__/__init__.cpython-37.pyc | Bin 96877 -> 0 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 646 -> 0 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 209 -> 0 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 20697 -> 0 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 203052 -> 0 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 24410 -> 0 bytes .../pkg_resources/_vendor/appdirs.py | 608 -- .../_vendor/packaging/__about__.py | 21 - .../_vendor/packaging/__init__.py | 14 - .../__pycache__/__about__.cpython-37.pyc | Bin 745 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 583 -> 0 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 1035 -> 0 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 2887 -> 0 bytes .../__pycache__/markers.cpython-37.pyc | Bin 8895 -> 0 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 3900 -> 0 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 19813 -> 0 bytes .../__pycache__/utils.cpython-37.pyc | Bin 514 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 10580 -> 0 bytes .../_vendor/packaging/_compat.py | 30 - .../_vendor/packaging/_structures.py | 68 - .../_vendor/packaging/markers.py | 301 - .../_vendor/packaging/requirements.py | 127 - .../_vendor/packaging/specifiers.py | 774 -- .../pkg_resources/_vendor/packaging/utils.py | 14 - .../_vendor/packaging/version.py | 393 - .../pkg_resources/_vendor/pyparsing.py | 5742 ----------- .../pkg_resources/_vendor/six.py | 868 -- .../pkg_resources/extern/__init__.py | 73 - .../__pycache__/__init__.cpython-37.pyc | Bin 2428 -> 0 bytes .../site-packages/pkg_resources/py31compat.py | 23 - .../python_dotenv-0.19.2.dist-info/INSTALLER | 1 - .../python_dotenv-0.19.2.dist-info/LICENSE | 87 - .../python_dotenv-0.19.2.dist-info/METADATA | 578 -- .../python_dotenv-0.19.2.dist-info/RECORD | 23 - .../python_dotenv-0.19.2.dist-info/WHEEL | 6 - .../entry_points.txt | 4 - .../top_level.txt | 1 - .../requests-2.27.1.dist-info/INSTALLER | 1 - .../requests-2.27.1.dist-info/LICENSE | 175 - .../requests-2.27.1.dist-info/METADATA | 125 - .../requests-2.27.1.dist-info/RECORD | 42 - .../requests-2.27.1.dist-info/WHEEL | 6 - .../requests-2.27.1.dist-info/top_level.txt | 1 - .../site-packages/requests/__init__.py | 152 - .../__pycache__/__init__.cpython-37.pyc | Bin 3895 -> 0 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 544 -> 0 bytes .../_internal_utils.cpython-37.pyc | Bin 1297 -> 0 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 16941 -> 0 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 6676 -> 0 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 8341 -> 0 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 610 -> 0 bytes .../__pycache__/compat.cpython-37.pyc | Bin 1814 -> 0 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 18776 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 5918 -> 0 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 2851 -> 0 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 969 -> 0 bytes .../__pycache__/models.cpython-37.pyc | Bin 24542 -> 0 bytes .../__pycache__/packages.cpython-37.pyc | Bin 700 -> 0 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 19657 -> 0 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 4214 -> 0 bytes .../__pycache__/structures.cpython-37.pyc | Bin 4398 -> 0 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 24042 -> 0 bytes .../site-packages/requests/__version__.py | 14 - .../site-packages/requests/_internal_utils.py | 42 - .../site-packages/requests/adapters.py | 538 -- .../python3.7/site-packages/requests/api.py | 159 - .../python3.7/site-packages/requests/auth.py | 305 - .../python3.7/site-packages/requests/certs.py | 18 - .../site-packages/requests/compat.py | 81 - .../site-packages/requests/cookies.py | 549 -- .../site-packages/requests/exceptions.py | 133 - .../python3.7/site-packages/requests/help.py | 135 - .../python3.7/site-packages/requests/hooks.py | 34 - .../site-packages/requests/models.py | 973 -- .../site-packages/requests/packages.py | 26 - .../site-packages/requests/sessions.py | 771 -- .../site-packages/requests/status_codes.py | 123 - .../site-packages/requests/structures.py | 105 - .../python3.7/site-packages/requests/utils.py | 1060 -- .../setuptools-40.6.2.dist-info/INSTALLER | 1 - .../setuptools-40.6.2.dist-info/LICENSE | 19 - .../setuptools-40.6.2.dist-info/METADATA | 73 - .../setuptools-40.6.2.dist-info/RECORD | 188 - .../setuptools-40.6.2.dist-info/WHEEL | 6 - .../dependency_links.txt | 2 - .../entry_points.txt | 65 - .../setuptools-40.6.2.dist-info/top_level.txt | 3 - .../setuptools-40.6.2.dist-info/zip-safe | 1 - .../site-packages/setuptools/__init__.py | 195 - .../__pycache__/__init__.cpython-37.pyc | Bin 6533 -> 0 bytes .../_deprecation_warning.cpython-37.pyc | Bin 564 -> 0 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 5145 -> 0 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 6281 -> 0 bytes .../__pycache__/config.cpython-37.pyc | Bin 17013 -> 0 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 871 -> 0 bytes .../__pycache__/depends.cpython-37.pyc | Bin 5280 -> 0 bytes .../__pycache__/dist.cpython-37.pyc | Bin 38455 -> 0 bytes .../__pycache__/extension.cpython-37.pyc | Bin 1991 -> 0 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 1556 -> 0 bytes .../__pycache__/glob.cpython-37.pyc | Bin 3766 -> 0 bytes .../__pycache__/launch.cpython-37.pyc | Bin 870 -> 0 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 2449 -> 0 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 4650 -> 0 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 34447 -> 0 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 3628 -> 0 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 32482 -> 0 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 7219 -> 0 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 827 -> 0 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 1213 -> 0 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 1436 -> 0 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 2208 -> 0 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 15552 -> 0 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 1518 -> 0 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 6807 -> 0 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 1185 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 344 -> 0 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 7032 -> 0 bytes .../windows_support.cpython-37.pyc | Bin 1027 -> 0 bytes .../setuptools/_deprecation_warning.py | 7 - .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 206 -> 0 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 203049 -> 0 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 24407 -> 0 bytes .../setuptools/_vendor/packaging/__about__.py | 21 - .../setuptools/_vendor/packaging/__init__.py | 14 - .../__pycache__/__about__.cpython-37.pyc | Bin 742 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 580 -> 0 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 1032 -> 0 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 2884 -> 0 bytes .../__pycache__/markers.cpython-37.pyc | Bin 8889 -> 0 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 3891 -> 0 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 19810 -> 0 bytes .../__pycache__/utils.cpython-37.pyc | Bin 511 -> 0 bytes .../__pycache__/version.cpython-37.pyc | Bin 10577 -> 0 bytes .../setuptools/_vendor/packaging/_compat.py | 30 - .../_vendor/packaging/_structures.py | 68 - .../setuptools/_vendor/packaging/markers.py | 301 - .../_vendor/packaging/requirements.py | 127 - .../_vendor/packaging/specifiers.py | 774 -- .../setuptools/_vendor/packaging/utils.py | 14 - .../setuptools/_vendor/packaging/version.py | 393 - .../setuptools/_vendor/pyparsing.py | 5742 ----------- .../site-packages/setuptools/_vendor/six.py | 868 -- .../site-packages/setuptools/archive_util.py | 173 - .../site-packages/setuptools/build_meta.py | 182 - .../site-packages/setuptools/cli-32.exe | Bin 65536 -> 0 bytes .../site-packages/setuptools/cli-64.exe | Bin 74752 -> 0 bytes .../site-packages/setuptools/cli.exe | Bin 65536 -> 0 bytes .../setuptools/command/__init__.py | 18 - .../__pycache__/__init__.cpython-37.pyc | Bin 752 -> 0 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 2420 -> 0 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 14208 -> 0 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 1799 -> 0 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 990 -> 0 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 2469 -> 0 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 9723 -> 0 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 8599 -> 0 bytes .../__pycache__/develop.cpython-37.pyc | Bin 6440 -> 0 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 1395 -> 0 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 64851 -> 0 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 21672 -> 0 bytes .../__pycache__/install.cpython-37.pyc | Bin 4027 -> 0 bytes .../install_egg_info.cpython-37.pyc | Bin 2428 -> 0 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 4104 -> 0 bytes .../install_scripts.cpython-37.pyc | Bin 2307 -> 0 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 4640 -> 0 bytes .../__pycache__/register.cpython-37.pyc | Bin 797 -> 0 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 2546 -> 0 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 941 -> 0 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 6237 -> 0 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 4539 -> 0 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 8134 -> 0 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 5220 -> 0 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 6150 -> 0 bytes .../site-packages/setuptools/command/alias.py | 80 - .../setuptools/command/bdist_egg.py | 502 - .../setuptools/command/bdist_rpm.py | 43 - .../setuptools/command/bdist_wininst.py | 21 - .../setuptools/command/build_clib.py | 98 - .../setuptools/command/build_ext.py | 321 - .../setuptools/command/build_py.py | 270 - .../setuptools/command/develop.py | 218 - .../setuptools/command/dist_info.py | 36 - .../setuptools/command/easy_install.py | 2342 ----- .../setuptools/command/egg_info.py | 716 -- .../setuptools/command/install.py | 125 - .../setuptools/command/install_egg_info.py | 62 - .../setuptools/command/install_lib.py | 121 - .../setuptools/command/install_scripts.py | 65 - .../setuptools/command/launcher manifest.xml | 15 - .../setuptools/command/py36compat.py | 136 - .../setuptools/command/register.py | 18 - .../setuptools/command/rotate.py | 66 - .../setuptools/command/saveopts.py | 22 - .../site-packages/setuptools/command/sdist.py | 200 - .../setuptools/command/setopt.py | 149 - .../site-packages/setuptools/command/test.py | 270 - .../setuptools/command/upload.py | 196 - .../setuptools/command/upload_docs.py | 206 - .../site-packages/setuptools/config.py | 635 -- .../site-packages/setuptools/dep_util.py | 23 - .../site-packages/setuptools/depends.py | 186 - .../site-packages/setuptools/dist.py | 1147 --- .../site-packages/setuptools/extension.py | 57 - .../setuptools/extern/__init__.py | 73 - .../__pycache__/__init__.cpython-37.pyc | Bin 2429 -> 0 bytes .../site-packages/setuptools/glibc.py | 86 - .../site-packages/setuptools/glob.py | 174 - .../site-packages/setuptools/gui-32.exe | Bin 65536 -> 0 bytes .../site-packages/setuptools/gui-64.exe | Bin 75264 -> 0 bytes .../site-packages/setuptools/gui.exe | Bin 65536 -> 0 bytes .../site-packages/setuptools/launch.py | 35 - .../site-packages/setuptools/lib2to3_ex.py | 62 - .../site-packages/setuptools/monkey.py | 179 - .../site-packages/setuptools/msvc.py | 1301 --- .../site-packages/setuptools/namespaces.py | 107 - .../site-packages/setuptools/package_index.py | 1128 --- .../site-packages/setuptools/pep425tags.py | 319 - .../site-packages/setuptools/py27compat.py | 28 - .../site-packages/setuptools/py31compat.py | 32 - .../site-packages/setuptools/py33compat.py | 55 - .../site-packages/setuptools/py36compat.py | 82 - .../site-packages/setuptools/sandbox.py | 491 - .../setuptools/script (dev).tmpl | 6 - .../site-packages/setuptools/script.tmpl | 3 - .../site-packages/setuptools/site-patch.py | 74 - .../site-packages/setuptools/ssl_support.py | 260 - .../site-packages/setuptools/unicode_utils.py | 44 - .../site-packages/setuptools/version.py | 6 - .../site-packages/setuptools/wheel.py | 210 - .../setuptools/windows_support.py | 29 - .../INSTALLER | 1 - .../typing_extensions-4.1.1.dist-info/LICENSE | 254 - .../METADATA | 35 - .../typing_extensions-4.1.1.dist-info/RECORD | 7 - .../typing_extensions-4.1.1.dist-info/WHEEL | 4 - .../site-packages/typing_extensions.py | 2908 ------ .../urllib3-1.26.9.dist-info/INSTALLER | 1 - .../urllib3-1.26.9.dist-info/LICENSE.txt | 21 - .../urllib3-1.26.9.dist-info/METADATA | 1426 --- .../urllib3-1.26.9.dist-info/RECORD | 82 - .../urllib3-1.26.9.dist-info/WHEEL | 6 - .../urllib3-1.26.9.dist-info/top_level.txt | 1 - .../site-packages/urllib3/__init__.py | 85 - .../__pycache__/__init__.cpython-37.pyc | Bin 2170 -> 0 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 10699 -> 0 bytes .../__pycache__/_version.cpython-37.pyc | Bin 202 -> 0 bytes .../__pycache__/connection.cpython-37.pyc | Bin 13775 -> 0 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 25308 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 12041 -> 0 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 8131 -> 0 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 2749 -> 0 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 15034 -> 0 bytes .../__pycache__/request.cpython-37.pyc | Bin 5549 -> 0 bytes .../__pycache__/response.cpython-37.pyc | Bin 20591 -> 0 bytes .../site-packages/urllib3/_collections.py | 337 - .../site-packages/urllib3/_version.py | 2 - .../site-packages/urllib3/connection.py | 567 -- .../site-packages/urllib3/connectionpool.py | 1108 --- .../site-packages/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 188 -> 0 bytes .../_appengine_environ.cpython-37.pyc | Bin 1397 -> 0 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 8157 -> 0 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 3606 -> 0 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 15403 -> 0 bytes .../securetransport.cpython-37.pyc | Bin 21459 -> 0 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 5558 -> 0 bytes .../urllib3/contrib/_appengine_environ.py | 36 - .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 217 -> 0 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 10651 -> 0 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 9022 -> 0 bytes .../contrib/_securetransport/bindings.py | 519 - .../contrib/_securetransport/low_level.py | 397 - .../urllib3/contrib/appengine.py | 314 - .../site-packages/urllib3/contrib/ntlmpool.py | 130 - .../urllib3/contrib/pyopenssl.py | 511 - .../urllib3/contrib/securetransport.py | 922 -- .../site-packages/urllib3/contrib/socks.py | 216 - .../site-packages/urllib3/exceptions.py | 323 - .../python3.7/site-packages/urllib3/fields.py | 274 - .../site-packages/urllib3/filepost.py | 98 - .../urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 189 -> 0 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 27504 -> 0 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 211 -> 0 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 1301 -> 0 bytes .../urllib3/packages/backports/makefile.py | 51 - .../site-packages/urllib3/packages/six.py | 1077 --- .../site-packages/urllib3/poolmanager.py | 537 -- .../site-packages/urllib3/request.py | 170 - .../site-packages/urllib3/response.py | 824 -- .../site-packages/urllib3/util/__init__.py | 49 - .../util/__pycache__/__init__.cpython-37.pyc | Bin 1098 -> 0 bytes .../__pycache__/connection.cpython-37.pyc | Bin 3404 -> 0 bytes .../util/__pycache__/proxy.cpython-37.pyc | Bin 1306 -> 0 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 1029 -> 0 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 3494 -> 0 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 2316 -> 0 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 16859 -> 0 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 11269 -> 0 bytes .../ssl_match_hostname.cpython-37.pyc | Bin 3236 -> 0 bytes .../__pycache__/ssltransport.cpython-37.pyc | Bin 7294 -> 0 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 8888 -> 0 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 10624 -> 0 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 3119 -> 0 bytes .../site-packages/urllib3/util/connection.py | 149 - .../site-packages/urllib3/util/proxy.py | 57 - .../site-packages/urllib3/util/queue.py | 22 - .../site-packages/urllib3/util/request.py | 146 - .../site-packages/urllib3/util/response.py | 107 - .../site-packages/urllib3/util/retry.py | 620 -- .../site-packages/urllib3/util/ssl_.py | 495 - .../urllib3/util/ssl_match_hostname.py | 159 - .../urllib3/util/ssltransport.py | 221 - .../site-packages/urllib3/util/timeout.py | 268 - .../site-packages/urllib3/util/url.py | 432 - .../site-packages/urllib3/util/wait.py | 153 - .../site-packages/werkzeug/__init__.py | 6 - .../__pycache__/__init__.cpython-37.pyc | Bin 355 -> 0 bytes .../__pycache__/_internal.cpython-37.pyc | Bin 18310 -> 0 bytes .../__pycache__/_reloader.cpython-37.pyc | Bin 11941 -> 0 bytes .../__pycache__/datastructures.cpython-37.pyc | Bin 107770 -> 0 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 30725 -> 0 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 2068 -> 0 bytes .../__pycache__/formparser.cpython-37.pyc | Bin 13805 -> 0 bytes .../werkzeug/__pycache__/http.cpython-37.pyc | Bin 37888 -> 0 bytes .../werkzeug/__pycache__/local.cpython-37.pyc | Bin 22687 -> 0 bytes .../__pycache__/routing.cpython-37.pyc | Bin 72969 -> 0 bytes .../__pycache__/security.cpython-37.pyc | Bin 8101 -> 0 bytes .../__pycache__/serving.cpython-37.pyc | Bin 30490 -> 0 bytes .../werkzeug/__pycache__/test.cpython-37.pyc | Bin 39009 -> 0 bytes .../__pycache__/testapp.cpython-37.pyc | Bin 9612 -> 0 bytes .../werkzeug/__pycache__/urls.cpython-37.pyc | Bin 36466 -> 0 bytes .../__pycache__/user_agent.cpython-37.pyc | Bin 1818 -> 0 bytes .../__pycache__/useragents.cpython-37.pyc | Bin 6851 -> 0 bytes .../werkzeug/__pycache__/utils.cpython-37.pyc | Bin 32934 -> 0 bytes .../werkzeug/__pycache__/wsgi.cpython-37.pyc | Bin 30075 -> 0 bytes .../site-packages/werkzeug/_internal.py | 626 -- .../site-packages/werkzeug/_reloader.py | 430 - .../site-packages/werkzeug/datastructures.py | 3059 ------ .../site-packages/werkzeug/datastructures.pyi | 912 -- .../site-packages/werkzeug/debug/__init__.py | 500 - .../debug/__pycache__/__init__.cpython-37.pyc | Bin 12873 -> 0 bytes .../debug/__pycache__/console.cpython-37.pyc | Bin 7875 -> 0 bytes .../debug/__pycache__/repr.cpython-37.pyc | Bin 8812 -> 0 bytes .../debug/__pycache__/tbtools.cpython-37.pyc | Bin 17941 -> 0 bytes .../site-packages/werkzeug/debug/console.py | 214 - .../site-packages/werkzeug/debug/repr.py | 284 - .../werkzeug/debug/shared/FONT_LICENSE | 96 - .../werkzeug/debug/shared/ICON_LICENSE.md | 6 - .../werkzeug/debug/shared/console.png | Bin 507 -> 0 bytes .../werkzeug/debug/shared/debugger.js | 359 - .../werkzeug/debug/shared/less.png | Bin 191 -> 0 bytes .../werkzeug/debug/shared/more.png | Bin 200 -> 0 bytes .../werkzeug/debug/shared/source.png | Bin 818 -> 0 bytes .../werkzeug/debug/shared/style.css | 163 - .../werkzeug/debug/shared/ubuntu.ttf | Bin 70220 -> 0 bytes .../site-packages/werkzeug/debug/tbtools.py | 600 -- .../site-packages/werkzeug/exceptions.py | 944 -- .../site-packages/werkzeug/filesystem.py | 55 - .../site-packages/werkzeug/formparser.py | 495 - .../python3.7/site-packages/werkzeug/http.py | 1393 --- .../python3.7/site-packages/werkzeug/local.py | 690 -- .../werkzeug/middleware/__init__.py | 22 - .../__pycache__/__init__.cpython-37.pyc | Bin 713 -> 0 bytes .../__pycache__/dispatcher.cpython-37.pyc | Bin 2754 -> 0 bytes .../__pycache__/http_proxy.cpython-37.pyc | Bin 6819 -> 0 bytes .../__pycache__/lint.cpython-37.pyc | Bin 12692 -> 0 bytes .../__pycache__/profiler.cpython-37.pyc | Bin 4923 -> 0 bytes .../__pycache__/proxy_fix.cpython-37.pyc | Bin 6157 -> 0 bytes .../__pycache__/shared_data.cpython-37.pyc | Bin 9882 -> 0 bytes .../werkzeug/middleware/dispatcher.py | 78 - .../werkzeug/middleware/http_proxy.py | 230 - .../site-packages/werkzeug/middleware/lint.py | 420 - .../werkzeug/middleware/profiler.py | 139 - .../werkzeug/middleware/proxy_fix.py | 187 - .../werkzeug/middleware/shared_data.py | 320 - .../python3.7/site-packages/werkzeug/py.typed | 0 .../site-packages/werkzeug/routing.py | 2342 ----- .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 188 -> 0 bytes .../__pycache__/multipart.cpython-37.pyc | Bin 6536 -> 0 bytes .../sansio/__pycache__/request.cpython-37.pyc | Bin 17118 -> 0 bytes .../__pycache__/response.cpython-37.pyc | Bin 22895 -> 0 bytes .../sansio/__pycache__/utils.cpython-37.pyc | Bin 3848 -> 0 bytes .../werkzeug/sansio/multipart.py | 260 - .../site-packages/werkzeug/sansio/request.py | 548 -- .../site-packages/werkzeug/sansio/response.py | 704 -- .../site-packages/werkzeug/sansio/utils.py | 142 - .../site-packages/werkzeug/security.py | 247 - .../site-packages/werkzeug/serving.py | 1088 --- .../python3.7/site-packages/werkzeug/test.py | 1331 --- .../site-packages/werkzeug/testapp.py | 240 - .../python3.7/site-packages/werkzeug/urls.py | 1211 --- .../site-packages/werkzeug/user_agent.py | 47 - .../site-packages/werkzeug/useragents.py | 215 - .../python3.7/site-packages/werkzeug/utils.py | 1099 --- .../werkzeug/wrappers/__init__.py | 16 - .../__pycache__/__init__.cpython-37.pyc | Bin 911 -> 0 bytes .../__pycache__/accept.cpython-37.pyc | Bin 805 -> 0 bytes .../wrappers/__pycache__/auth.cpython-37.pyc | Bin 1353 -> 0 bytes .../__pycache__/base_request.cpython-37.pyc | Bin 1746 -> 0 bytes .../__pycache__/base_response.cpython-37.pyc | Bin 1757 -> 0 bytes .../common_descriptors.cpython-37.pyc | Bin 1430 -> 0 bytes .../wrappers/__pycache__/cors.cpython-37.pyc | Bin 1351 -> 0 bytes .../wrappers/__pycache__/etag.cpython-37.pyc | Bin 1338 -> 0 bytes .../wrappers/__pycache__/json.cpython-37.pyc | Bin 810 -> 0 bytes .../__pycache__/request.cpython-37.pyc | Bin 21164 -> 0 bytes .../__pycache__/response.cpython-37.pyc | Bin 29643 -> 0 bytes .../__pycache__/user_agent.cpython-37.pyc | Bin 818 -> 0 bytes .../site-packages/werkzeug/wrappers/accept.py | 14 - .../site-packages/werkzeug/wrappers/auth.py | 26 - .../werkzeug/wrappers/base_request.py | 36 - .../werkzeug/wrappers/base_response.py | 36 - .../werkzeug/wrappers/common_descriptors.py | 26 - .../site-packages/werkzeug/wrappers/cors.py | 26 - .../site-packages/werkzeug/wrappers/etag.py | 26 - .../site-packages/werkzeug/wrappers/json.py | 13 - .../werkzeug/wrappers/request.py | 660 -- .../werkzeug/wrappers/response.py | 891 -- .../werkzeug/wrappers/user_agent.py | 14 - .../python3.7/site-packages/werkzeug/wsgi.py | 982 -- .../zipp-3.7.0.dist-info/INSTALLER | 1 - .../zipp-3.7.0.dist-info/LICENSE | 19 - .../zipp-3.7.0.dist-info/METADATA | 58 - .../site-packages/zipp-3.7.0.dist-info/RECORD | 8 - .../site-packages/zipp-3.7.0.dist-info/WHEEL | 5 - .../zipp-3.7.0.dist-info/top_level.txt | 1 - venv/lib/python3.7/site-packages/zipp.py | 329 - venv/pyvenv.cfg | 3 - 1760 files changed, 325361 deletions(-) delete mode 100644 venv/.DS_Store delete mode 100644 venv/bin/activate delete mode 100644 venv/bin/activate.csh delete mode 100644 venv/bin/activate.fish delete mode 100755 venv/bin/dotenv delete mode 100755 venv/bin/easy_install delete mode 100755 venv/bin/easy_install-3.7 delete mode 100755 venv/bin/flask delete mode 100755 venv/bin/normalizer delete mode 100755 venv/bin/pip delete mode 100755 venv/bin/pip3 delete mode 100755 venv/bin/pip3.7 delete mode 120000 venv/bin/python delete mode 120000 venv/bin/python3 delete mode 100644 venv/lib/.DS_Store delete mode 100644 venv/lib/python3.7/.DS_Store delete mode 100644 venv/lib/python3.7/site-packages/.DS_Store delete mode 100644 venv/lib/python3.7/site-packages/Adyen-6.0.0-py3.7.egg-info/PKG-INFO delete mode 100644 venv/lib/python3.7/site-packages/Adyen-6.0.0-py3.7.egg-info/SOURCES.txt delete mode 100644 venv/lib/python3.7/site-packages/Adyen-6.0.0-py3.7.egg-info/dependency_links.txt delete mode 100644 venv/lib/python3.7/site-packages/Adyen-6.0.0-py3.7.egg-info/installed-files.txt delete mode 100644 venv/lib/python3.7/site-packages/Adyen-6.0.0-py3.7.egg-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/client.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/httpclient.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/services.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/settings.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/__pycache__/util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/Adyen/client.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/httpclient.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/services.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/settings.py delete mode 100644 venv/lib/python3.7/site-packages/Adyen/util.py delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/__pycache__/zipp.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/certifi/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/certifi/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/certifi/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/certifi/cacert.pem delete mode 100644 venv/lib/python3.7/site-packages/certifi/core.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/cd.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/constant.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/legacy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/md.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/api.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/cd.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/normalizer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/constant.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/legacy.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/md.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/models.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/py.typed delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/utils.py delete mode 100644 venv/lib/python3.7/site-packages/charset_normalizer/version.py delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/click-8.0.4.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/click/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_termui_impl.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_textwrap.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_winconsole.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/decorators.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/shell_completion.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/termui.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/testing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/click/_compat.py delete mode 100644 venv/lib/python3.7/site-packages/click/_termui_impl.py delete mode 100644 venv/lib/python3.7/site-packages/click/_textwrap.py delete mode 100644 venv/lib/python3.7/site-packages/click/_unicodefun.py delete mode 100644 venv/lib/python3.7/site-packages/click/_winconsole.py delete mode 100644 venv/lib/python3.7/site-packages/click/core.py delete mode 100644 venv/lib/python3.7/site-packages/click/decorators.py delete mode 100644 venv/lib/python3.7/site-packages/click/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/click/formatting.py delete mode 100644 venv/lib/python3.7/site-packages/click/globals.py delete mode 100644 venv/lib/python3.7/site-packages/click/parser.py delete mode 100644 venv/lib/python3.7/site-packages/click/py.typed delete mode 100644 venv/lib/python3.7/site-packages/click/shell_completion.py delete mode 100644 venv/lib/python3.7/site-packages/click/termui.py delete mode 100644 venv/lib/python3.7/site-packages/click/testing.py delete mode 100644 venv/lib/python3.7/site-packages/click/types.py delete mode 100644 venv/lib/python3.7/site-packages/click/utils.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/cli.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/ipython.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/main.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/variables.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/dotenv/cli.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/ipython.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/main.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/parser.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/py.typed delete mode 100644 venv/lib/python3.7/site-packages/dotenv/variables.py delete mode 100644 venv/lib/python3.7/site-packages/dotenv/version.py delete mode 100644 venv/lib/python3.7/site-packages/easy_install.py delete mode 100644 venv/lib/python3.7/site-packages/flask/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/flask/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/app.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/blueprints.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/config.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/ctx.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/debughelpers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/globals.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/logging.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/scaffold.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/signals.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/typing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/wrappers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/app.py delete mode 100644 venv/lib/python3.7/site-packages/flask/blueprints.py delete mode 100644 venv/lib/python3.7/site-packages/flask/cli.py delete mode 100644 venv/lib/python3.7/site-packages/flask/config.py delete mode 100644 venv/lib/python3.7/site-packages/flask/ctx.py delete mode 100644 venv/lib/python3.7/site-packages/flask/debughelpers.py delete mode 100644 venv/lib/python3.7/site-packages/flask/globals.py delete mode 100644 venv/lib/python3.7/site-packages/flask/helpers.py delete mode 100644 venv/lib/python3.7/site-packages/flask/json/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/flask/json/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/json/__pycache__/tag.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/flask/json/tag.py delete mode 100644 venv/lib/python3.7/site-packages/flask/logging.py delete mode 100644 venv/lib/python3.7/site-packages/flask/py.typed delete mode 100644 venv/lib/python3.7/site-packages/flask/scaffold.py delete mode 100644 venv/lib/python3.7/site-packages/flask/sessions.py delete mode 100644 venv/lib/python3.7/site-packages/flask/signals.py delete mode 100644 venv/lib/python3.7/site-packages/flask/templating.py delete mode 100644 venv/lib/python3.7/site-packages/flask/testing.py delete mode 100644 venv/lib/python3.7/site-packages/flask/typing.py delete mode 100644 venv/lib/python3.7/site-packages/flask/views.py delete mode 100644 venv/lib/python3.7/site-packages/flask/wrappers.py delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/LICENSE.md delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/idna-3.3.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/idna/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/codec.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/idnadata.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/intranges.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/package_data.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/__pycache__/uts46data.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/idna/codec.py delete mode 100644 venv/lib/python3.7/site-packages/idna/compat.py delete mode 100644 venv/lib/python3.7/site-packages/idna/core.py delete mode 100644 venv/lib/python3.7/site-packages/idna/idnadata.py delete mode 100644 venv/lib/python3.7/site-packages/idna/intranges.py delete mode 100644 venv/lib/python3.7/site-packages/idna/package_data.py delete mode 100644 venv/lib/python3.7/site-packages/idna/py.typed delete mode 100644 venv/lib/python3.7/site-packages/idna/uts46data.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata-4.11.2.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_adapters.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_collections.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_functools.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_itertools.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_meta.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/__pycache__/_text.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_adapters.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_collections.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_compat.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_functools.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_itertools.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_meta.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/_text.py delete mode 100644 venv/lib/python3.7/site-packages/importlib_metadata/py.typed delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/LICENSE.rst delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous-2.1.0.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/_json.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/encoding.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/exc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/serializer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/signer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/timed.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/url_safe.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/_json.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/encoding.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/exc.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/py.typed delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/serializer.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/signer.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/timed.py delete mode 100644 venv/lib/python3.7/site-packages/itsdangerous/url_safe.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/_identifier.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/async_utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/bccache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/compiler.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/constants.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/debug.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/defaults.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/environment.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/ext.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/filters.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/idtracking.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/lexer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/loaders.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/meta.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/nativetypes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/nodes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/optimizer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/runtime.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/sandbox.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/tests.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/visitor.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/jinja2/_identifier.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/async_utils.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/bccache.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/compiler.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/constants.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/debug.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/defaults.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/environment.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/ext.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/filters.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/idtracking.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/lexer.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/loaders.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/meta.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/nativetypes.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/nodes.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/optimizer.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/parser.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/py.typed delete mode 100644 venv/lib/python3.7/site-packages/jinja2/runtime.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/sandbox.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/tests.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/utils.py delete mode 100644 venv/lib/python3.7/site-packages/jinja2/visitor.py delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/_native.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/_native.py delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/_speedups.c delete mode 100755 venv/lib/python3.7/site-packages/markupsafe/_speedups.cpython-37m-darwin.so delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/_speedups.pyi delete mode 100644 venv/lib/python3.7/site-packages/markupsafe/py.typed delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/LICENSE.txt delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/pip-22.2.2.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/pip/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/__pip-runner__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__pip-runner__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/main.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/build_env.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/command_context.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/main.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/progress_bars.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/req_command.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/spinners.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/debug.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/index.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/check.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/completion.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/configuration.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/debug.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/download.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/help.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/index.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/inspect.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/install.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/list.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/search.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/show.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/configuration.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__pycache__/base.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/base.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/installed.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/sdist.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/distributions/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/__pycache__/collector.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/__pycache__/sources.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/collector.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/package_finder.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index/sources.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/__pycache__/base.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/_distutils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/_sysconfig.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations/base.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/main.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/__pycache__/base.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/_json.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/base.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/_compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/_dists.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/importlib/_envs.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/metadata/pkg_resources.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/scheme.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/target_python.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/candidate.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/direct_url.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/index.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/installation_report.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/link.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/scheme.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/search_scope.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/selection_prefs.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/target_python.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/auth.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/download.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/session.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/auth.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/download.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/lazy_wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/session.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/utils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/network/xmlrpc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/build_tracker.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/metadata.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/metadata_editable.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/metadata_legacy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/wheel_editable.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/build/wheel_legacy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/check.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/editable_legacy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/legacy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/install/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pyproject.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/__pycache__/base.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/base.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/legacy/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/legacy/resolver.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/base.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/candidates.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/factory.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/provider.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/reporter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/requirements.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolution/resolvelib/resolver.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/self_outdated_check.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/_log.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/urls.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/_log.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/compatibility_tags.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/datetime.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/direct_url_helpers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/distutils_args.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/egg_link.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/entrypoints.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/filetypes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/inject_securetransport.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/models.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/subprocess.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/unpacking.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/urls.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/virtualenv.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/versioncontrol.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_internal/wheel_builder.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/johabfreq.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/johabprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langrussianmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/metadata/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/metadata/languages.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf1632prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64-arm.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64-arm.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro/distro.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/ext.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_manylinux.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_musllinux.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/tags.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/version.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/build.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/dirtools.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/in_process/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/in_process/_in_process.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/meta.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/android.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/api.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/macos.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/unix.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/version.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/platformdirs/windows.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/cmdline.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/console.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/filter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/filters/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/_mapping.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/bbcode.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/groff.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/html.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/img.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/irc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/latex.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/other.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/rtf.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/svg.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/terminal.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/formatters/terminal256.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexer.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/_mapping.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/lexers/python.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/modeline.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/plugin.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/regexopt.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/scanner.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/sphinxext.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/style.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/styles/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/token.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/unistring.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pygments/util.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/actions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/common.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/core.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/diagram/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/helpers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/results.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/testing.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/unicode.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing/util.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/help.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/compat/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/providers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/reporters.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/resolvers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/resolvelib/structs.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__main__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/align.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/box.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/color.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/console.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/control.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/json.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/live.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/region.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/status.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/style.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/table.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/text.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_cell_widths.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_emoji_codes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_emoji_replace.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_export_format.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_extension.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_inspect.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_log_render.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_loop.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_palettes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_pick.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_ratio.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_spinners.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_stack.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_timer.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_win32_console.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_windows.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_windows_renderer.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/_wrap.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/abc.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/align.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/ansi.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/bar.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/box.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/cells.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/color.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/color_triplet.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/columns.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/console.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/constrain.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/containers.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/control.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/default_styles.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/diagnose.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/emoji.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/errors.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/file_proxy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/filesize.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/highlighter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/json.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/jupyter.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/layout.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/live.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/live_render.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/logging.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/markup.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/measure.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/padding.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/pager.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/palette.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/panel.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/pretty.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/progress.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/progress_bar.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/prompt.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/protocol.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/region.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/repr.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/rule.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/scope.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/screen.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/segment.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/spinner.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/status.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/style.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/styled.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/syntax.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/table.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/terminal_theme.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/text.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/theme.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/themes.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/traceback.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/rich/tree.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/six.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/_asyncio.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/_utils.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/after.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/before.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/before_sleep.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/nap.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/retry.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/stop.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/tornadoweb.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tenacity/wait.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/_parser.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/_re.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/tomli/_types.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/typing_extensions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_version.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/proxy.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssltransport.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/vendor.txt delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py delete mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py delete mode 100644 venv/lib/python3.7/site-packages/pip/py.typed delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/pkg_resources/py31compat.py delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/python_dotenv-0.19.2.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/requests-2.27.1.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/requests/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/__version__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/_internal_utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/adapters.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/api.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/auth.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/certs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/cookies.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/help.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/hooks.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/models.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/packages.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/sessions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/status_codes.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/structures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/requests/__version__.py delete mode 100644 venv/lib/python3.7/site-packages/requests/_internal_utils.py delete mode 100644 venv/lib/python3.7/site-packages/requests/adapters.py delete mode 100644 venv/lib/python3.7/site-packages/requests/api.py delete mode 100644 venv/lib/python3.7/site-packages/requests/auth.py delete mode 100644 venv/lib/python3.7/site-packages/requests/certs.py delete mode 100644 venv/lib/python3.7/site-packages/requests/compat.py delete mode 100644 venv/lib/python3.7/site-packages/requests/cookies.py delete mode 100644 venv/lib/python3.7/site-packages/requests/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/requests/help.py delete mode 100644 venv/lib/python3.7/site-packages/requests/hooks.py delete mode 100644 venv/lib/python3.7/site-packages/requests/models.py delete mode 100644 venv/lib/python3.7/site-packages/requests/packages.py delete mode 100644 venv/lib/python3.7/site-packages/requests/sessions.py delete mode 100644 venv/lib/python3.7/site-packages/requests/status_codes.py delete mode 100644 venv/lib/python3.7/site-packages/requests/structures.py delete mode 100644 venv/lib/python3.7/site-packages/requests/utils.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/dependency_links.txt delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/zip-safe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/six.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/archive_util.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/build_meta.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-32.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-64.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/cli.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/alias.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_clib.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_ext.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_py.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/develop.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/dist_info.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/easy_install.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/egg_info.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_lib.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/py36compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/register.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/rotate.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/saveopts.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/sdist.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/setopt.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/test.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/config.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/dep_util.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/depends.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/dist.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/extension.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/setuptools/glibc.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/glob.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-32.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-64.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/gui.exe delete mode 100644 venv/lib/python3.7/site-packages/setuptools/launch.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/monkey.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/msvc.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/namespaces.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/package_index.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/pep425tags.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/py27compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/py31compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/py33compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/py36compat.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/sandbox.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl delete mode 100644 venv/lib/python3.7/site-packages/setuptools/script.tmpl delete mode 100644 venv/lib/python3.7/site-packages/setuptools/site-patch.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/ssl_support.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/unicode_utils.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/version.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/wheel.py delete mode 100644 venv/lib/python3.7/site-packages/setuptools/windows_support.py delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions-4.1.1.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions-4.1.1.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions-4.1.1.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions-4.1.1.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions-4.1.1.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/typing_extensions.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/LICENSE.txt delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/urllib3-1.26.9.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/_collections.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/_version.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/connection.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/connectionpool.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/fields.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/filepost.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/poolmanager.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/_collections.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/_version.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/connection.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/connectionpool.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/_appengine_environ.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/appengine.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/__pycache__/socks.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_appengine_environ.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/bindings.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/_securetransport/low_level.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/appengine.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/ntlmpool.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/securetransport.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/contrib/socks.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/fields.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/filepost.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/__pycache__/six.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/backports/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/backports/makefile.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/packages/six.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/poolmanager.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/request.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/response.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/connection.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/proxy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/queue.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/retry.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssl_.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/ssltransport.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/timeout.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/url.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/__pycache__/wait.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/connection.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/proxy.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/queue.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/request.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/response.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/retry.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/ssl_.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/ssl_match_hostname.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/ssltransport.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/timeout.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/url.py delete mode 100644 venv/lib/python3.7/site-packages/urllib3/util/wait.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/_internal.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/_reloader.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/datastructures.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/exceptions.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/filesystem.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/formparser.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/http.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/local.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/routing.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/security.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/serving.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/test.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/testapp.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/urls.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/user_agent.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/useragents.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/wsgi.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/_internal.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/_reloader.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/datastructures.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/datastructures.pyi delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/console.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/repr.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/console.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/repr.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/FONT_LICENSE delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/ICON_LICENSE.md delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/console.png delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/debugger.js delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/less.png delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/more.png delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/source.png delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/style.css delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/ubuntu.ttf delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/tbtools.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/exceptions.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/filesystem.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/formparser.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/http.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/local.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/http_proxy.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/py.typed delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/routing.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/utils.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/multipart.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/request.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/response.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/sansio/utils.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/security.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/serving.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/test.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/testapp.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/urls.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/user_agent.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/useragents.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/utils.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/accept.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/cors.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/etag.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/json.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/response.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/cors.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py delete mode 100644 venv/lib/python3.7/site-packages/werkzeug/wsgi.py delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/INSTALLER delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/LICENSE delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/METADATA delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/RECORD delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/WHEEL delete mode 100644 venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/top_level.txt delete mode 100644 venv/lib/python3.7/site-packages/zipp.py delete mode 100644 venv/pyvenv.cfg diff --git a/venv/.DS_Store b/venv/.DS_Store deleted file mode 100644 index 04862746aa3994040f4352e4aecdbca694ca8d90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKJ5Iwu5S=BFh(ePR3M5k^q@diuM5dsi$_2nl2$39|CXtXR+)>bQ1xhMDM*u`a z!!;MfZcTpWBQr$qXkO zu93FmB#rUJGis`UD)8SG;5W5IG4<(WFY(^r9eCxnjLM+x^Xx ztGo9{W?QH;NT;mlNBQjSY9;XQQ|z-g>+t1SOO(g<okT-ah}lcPuB~DZ5#3 zo|V~pWm;7l(kYFp3uVVthq_19D{#ChaO6C-MN|N1Hd|%Iq4uhPDxeBX6yWbefW{aK zW)AJA1D(AB0Lz%RhH;Gtz(6n*%pAf4GcFbAQjJ_OjNBcJONT#{_{^b8Cu3Je9a-7P z4aL~iF(24)GND85RRLANSD@q`YkdCi&cFZrN&2J;r~(V6fGJ05qVwK|598PZjtE@XePV diff --git a/venv/bin/activate b/venv/bin/activate deleted file mode 100644 index a1dde1c..0000000 --- a/venv/bin/activate +++ /dev/null @@ -1,76 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r - fi - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - if [ ! "$1" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="/Users/anamo/Desktop/Demos/Hackathon/CheckoutCreate/venv" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/bin:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - if [ "x(venv) " != x ] ; then - PS1="(venv) ${PS1:-}" - else - if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" - else - PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" - fi - fi - export PS1 -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r -fi diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh deleted file mode 100644 index 4583c2f..0000000 --- a/venv/bin/activate.csh +++ /dev/null @@ -1,37 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi . -# Ported to Python 3.3 venv by Andrew Svetlov - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' - -# Unset irrelevant variables. -deactivate nondestructive - -setenv VIRTUAL_ENV "/Users/anamo/Desktop/Demos/Hackathon/CheckoutCreate/venv" - -set _OLD_VIRTUAL_PATH="$PATH" -setenv PATH "$VIRTUAL_ENV/bin:$PATH" - - -set _OLD_VIRTUAL_PROMPT="$prompt" - -if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then - if ("venv" != "") then - set env_name = "venv" - else - if (`basename "VIRTUAL_ENV"` == "__") then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` - else - set env_name = `basename "$VIRTUAL_ENV"` - endif - endif - set prompt = "[$env_name] $prompt" - unset env_name -endif - -alias pydoc python -m pydoc - -rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish deleted file mode 100644 index e5444cc..0000000 --- a/venv/bin/activate.fish +++ /dev/null @@ -1,75 +0,0 @@ -# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) -# you cannot run it directly - -function deactivate -d "Exit virtualenv and return to normal shell environment" - # reset old environment variables - if test -n "$_OLD_VIRTUAL_PATH" - set -gx PATH $_OLD_VIRTUAL_PATH - set -e _OLD_VIRTUAL_PATH - end - if test -n "$_OLD_VIRTUAL_PYTHONHOME" - set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME - set -e _OLD_VIRTUAL_PYTHONHOME - end - - if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - functions -e fish_prompt - set -e _OLD_FISH_PROMPT_OVERRIDE - functions -c _old_fish_prompt fish_prompt - functions -e _old_fish_prompt - end - - set -e VIRTUAL_ENV - if test "$argv[1]" != "nondestructive" - # Self destruct! - functions -e deactivate - end -end - -# unset irrelevant variables -deactivate nondestructive - -set -gx VIRTUAL_ENV "/Users/bradleyl/hackathon/checkoutCreate/venv" - -set -gx _OLD_VIRTUAL_PATH $PATH -set -gx PATH "$VIRTUAL_ENV/bin" $PATH - -# unset PYTHONHOME if set -if set -q PYTHONHOME - set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME - set -e PYTHONHOME -end - -if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # fish uses a function instead of an env var to generate the prompt. - - # save the current fish_prompt function as the function _old_fish_prompt - functions -c fish_prompt _old_fish_prompt - - # with the original prompt function renamed, we can override with our own. - function fish_prompt - # Save the return status of the last command - set -l old_status $status - - # Prompt override? - if test -n "(venv) " - printf "%s%s" "(venv) " (set_color normal) - else - # ...Otherwise, prepend env - set -l _checkbase (basename "$VIRTUAL_ENV") - if test $_checkbase = "__" - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) - else - printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) - end - end - - # Restore the return status of the previous command. - echo "exit $old_status" | . - _old_fish_prompt - end - - set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" -end diff --git a/venv/bin/dotenv b/venv/bin/dotenv deleted file mode 100755 index a8aa7b8..0000000 --- a/venv/bin/dotenv +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from dotenv.cli import cli - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(cli()) diff --git a/venv/bin/easy_install b/venv/bin/easy_install deleted file mode 100755 index 825b69b..0000000 --- a/venv/bin/easy_install +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from setuptools.command.easy_install import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/easy_install-3.7 b/venv/bin/easy_install-3.7 deleted file mode 100755 index 825b69b..0000000 --- a/venv/bin/easy_install-3.7 +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from setuptools.command.easy_install import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/flask b/venv/bin/flask deleted file mode 100755 index b3066d7..0000000 --- a/venv/bin/flask +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from flask.cli import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/normalizer b/venv/bin/normalizer deleted file mode 100755 index c2d8de2..0000000 --- a/venv/bin/normalizer +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from charset_normalizer.cli.normalizer import cli_detect - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(cli_detect()) diff --git a/venv/bin/pip b/venv/bin/pip deleted file mode 100755 index 6c56d7e..0000000 --- a/venv/bin/pip +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 deleted file mode 100755 index 6c56d7e..0000000 --- a/venv/bin/pip3 +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/pip3.7 b/venv/bin/pip3.7 deleted file mode 100755 index 6c56d7e..0000000 --- a/venv/bin/pip3.7 +++ /dev/null @@ -1,11 +0,0 @@ -#!/Users/anamo/Desktop/Demos/WebCheckoutComponent/adyen-python-online-payments/venv/bin/python3 - -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv/bin/python b/venv/bin/python deleted file mode 120000 index b8a0adb..0000000 --- a/venv/bin/python +++ /dev/null @@ -1 +0,0 @@ -python3 \ No newline at end of file diff --git a/venv/bin/python3 b/venv/bin/python3 deleted file mode 120000 index a4db6b9..0000000 --- a/venv/bin/python3 +++ /dev/null @@ -1 +0,0 @@ -/usr/local/adyen/python/bin/python3 \ No newline at end of file diff --git a/venv/lib/.DS_Store b/venv/lib/.DS_Store deleted file mode 100644 index f5bd06291edd1b112b7da23b729f7e1f7c0a6179..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&1xGl5FR;>qa_r4NNFwwL60@9^F!T`%hq*Xpc~plT3m0|#7owz#a_n*W7um; zAEwYl9w1MUOW&d|&{Jn5xoNNsJ(yC$42(YQ=o@MEt&uzcAey6S2cQZ75}mN*VY9$! zoP5qoE>b}hW)2N0?7=f=gyT6j2mVI|=-YXa!6oF-gFn9CFbfkM;^ zT6w*)Avffv{1Ei?ILJHsXxQuwPUz`a>m;1@JK@{7J8oCEUh6dP#A$b665^DruO$7-tQt9q=`umbl%0XiQPI-&2duxO4B zY)lD&SjMn1>{Bg4Im)5$u&{_DXu_r<+En363}MqTt{l&ISXi{_AYAbw+{(gLD8j6c z^D9FK;alXE6<`JKDzIiBt91V#EwBIYCh-$1zzW>iD-bOcuaYY?O-(g`9BWV0bz{tQ2EAUSh_yxNIZzcc$ diff --git a/venv/lib/python3.7/.DS_Store b/venv/lib/python3.7/.DS_Store deleted file mode 100644 index ceda568f74a5f05b0786e73d9bb75f0a1b092389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!EVz)5S?ue*-%x=0R-GuLYxSYv{j{wiwWVt6<2To6zteatvX&ScE}+_@)0=k zH;6mp6ZjY|bY^!Vs0tQb5TZNM%$wbvx6Z!EyIueggL&Ks=m3C3C-g31_=(Xt`5D{b zo))4obKHgkLKwp_MrTd|r@+6i0KL20P(lh7B=F<=JHdAODAVI8(-BtD7I7c_&NpM2 zH8P_`SupcMRAgyc^?F~##-?}SVoSEpvuD&g)H;jSc^ExOlf|fW z`GL->FwK*hA*6AFCC{Ixd8`)$J3o7!YXykm?A$28f4kf|H!F4vbqY8I zepdn79~3&F&sbYDTL%Vn1wiz$+Zg8bp+FqP=rh(9aRg0RDx#$dzG4VV$9~0iK4Wds z(n0X$L-3OY-%x~kI?k_5ISAjPi%tQjz-a|GZL>q?|HEJ3|4)-#%PHU#_^%WY-Y^&r za7lc&o>?57wF>i|bsAMf2m}&BvcxqlNg7pDy@XH>Trq+JAY&(?wQ9UkY&SwtBwvAl z;1@XZC;SU1c(c0|i4(-FLe)+*`^M{e>-bG}H%mlfkdHbuUW

M^re)HB7nPfqfjHikajmAiM^D0V4 zayF28GD;QK(>I*DQ}>&9=JRgvu;uP|7A<#v*loAm-u}U2QFm@XczE>OKZ`#k@)Ik9 zRS?UdvK@mL@EL)5<#TVE#4Oi`4SB;|;P9G93sOU!L#kMX1&BV^!7l&{38@Hbt4+D6XRDAC4OD;4bCCdp8$ z9<@=r19(Xq3#+Pp9$LjDJV9hFE6|f2{E5Pf63uo*bEHtX61C2TY0Bh)0 zhM4~>Fvm66H&|%I9hlHmpr#6Q#1NW}e%Ivn4Hg9pk$yokU-w zZLI=UfmH>n`m)LU|I@#p|5r)&$|_(LxKav;+Oc;$z$=-(b?xPNuXW+?;B1^%XjBw5 jW;<2^Z^d`v%5cx+0N6KJXhaXp{t-|z*v2YwsS5lCUM!FI1~X(v;mRwf)q5eURl&jGJvg`k?!6#i_Id$<_M7)*`e%cXzmTjNaPk7W z{sVv!<_IDk>PVNm(xaY3n9DrTkWJdOc0)8}i?*!Y6m98KUv_9m1~iae+La*gu;cjX@4vvYj0FAwN}L%t@g!-5Zl1$^VZ zM-TbodqR)+(cLjU20WoBfT#2n@Ckhact+0v&*?eqen&>(M~H=tyn2vKbRjCk<4l%? zGPTdLd8V@>uZLBhr3K@$$P8DB&>tQ2aq328G6C=5l;+C9Qf7x=jmP!ST30ik-h*&iX0Uni>gHy=+&jgjubK;YM$Fg9RKs$`%cU2;miuwc=vd3S8r#Q9; zZ~|RpL4C*a>(NsROWjtcQm~XlNnx=S{(owsT4=WcXuy9;d5PbZRz8k)5by`4x(Fdc z55blR1EM~pZ=R)Gs{smFEL#d&L|ZFcBU=s{%#10Q1y{Q`6Aw%W@dQ4ZIKdA*E+%&h xLr}*E2M9+9m_l`kfOT5~47~O~U#98{3{0czwi`mO&-~E&Gzh(6x8?lz`~!{hcH{s6 diff --git a/venv/lib/python3.7/site-packages/Adyen/__pycache__/client.cpython-37.pyc b/venv/lib/python3.7/site-packages/Adyen/__pycache__/client.cpython-37.pyc deleted file mode 100644 index 4ccb92bff1cb79f0ddbd6d2a87eeb9503cbf2acb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19713 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 STH-miYIg5-t*#6A?DsdO#Um~N diff --git a/venv/lib/python3.7/site-packages/Adyen/__pycache__/httpclient.cpython-37.pyc b/venv/lib/python3.7/site-packages/Adyen/__pycache__/httpclient.cpython-37.pyc deleted file mode 100644 index 5cd3e233afa9fa4fcf108bb492162dac6284d96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9647 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 bLI12(!06PlX;4uwXd1Q-s@O~bbkY9}v?Bh_ diff --git a/venv/lib/python3.7/site-packages/Adyen/__pycache__/services.cpython-37.pyc b/venv/lib/python3.7/site-packages/Adyen/__pycache__/services.cpython-37.pyc deleted file mode 100644 index d69f16fd114f37c0e6d4715acf6718d21bd92c28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13602 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 diff --git a/venv/lib/python3.7/site-packages/Adyen/__pycache__/util.cpython-37.pyc b/venv/lib/python3.7/site-packages/Adyen/__pycache__/util.cpython-37.pyc deleted file mode 100644 index 6e2b4ca3b368de47cb046cf3fee0eb34a668f105..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2961 zcmcguTW{P%6!!SGUhgHFOG_Ir3ZWDhnrvxHfhrA@mIoeK3V~L#iY%{Zl6B(Cc4js- zk@G?#Q6BgSNV^g*Nc;+Z#=P>xU&s^Zc(a>}h=izwtvPc%GoJDJ=6v7y(^}2d;QGb* zIQ+e;X@BCw_|n1o1d8Z^p&BKzmJp95x~C_GXAo@DV>7WltMHB3PD);>@Xgrq9OyUW zvR5u@*K>=y;#H_c?E}rL(h_x`uF*1ep{~;ktwKFT%{8rA`wLdpnueMRIwFhvlKD~6 z%eYhyjkY5ZWvOcP(k(alofV^Csj`aan+XnEksa;{5PmSrV32GyaquOIm}^znunOj#dH%;4eAbwoZg%n z8he(U9n9s{;KEQF5&)ypR!$^DpYhMB(sp0_qA%paL!NC%lr2yQ5YPzt&O+ANWT6ZR z#Dy2uCX_WOViC+ZBwo*<5k6d}gz7^bYJ-|X9hS1%hvdnw{^ZFaxdYW5*Z~*NPK6B8 zkSQZdr7CgOi-V8>%EopO|EBRNnEdc@>s!INXmxl%W405wxWIO?=|JJ@}5`Gb~#EnMp13mZ(d?$I5Vw)!%PmwP+PWg-lE%!jpRF%;ZH zjkv@lyH_??3R@4^(e3qo5p685#90Wbu)2Kw(kVbN6AC~aa7MchVe4&_j@-<10(i2Lj_ z&NHr@PLu{Bj3QMEZgl)Ed&V(RWeZ4qMwJB+B|@2-S(GXx33}YZZbL|}Ojt!I8xZO< z7}8CGP#G!vUfC=~il|aI5M6*AX6ptw-oLHvP9WIrTdLf-ed}n9O(OtbHf>eGkMl?A zq#T^h$1tX0J#Q)-5zFW7DJ&*c9biwRbi;=aflBG!F&jDwn`a`ZTT>Jh;{i*hXz z$dQQp_(5;Nlmc@XA#M;?2bh60F5x$!Z2~K%SQ!dJEB*lUf{F+L?~|Xj=b(tNA*IXc zl~%^jPVwxlXejz9_;?7=8m(_Qpqf(y)KgvBvh<_2PH2NpA2_-30A`%%r86iOdg;;` z(96nZwb0AjpbmODb)=WGZC-*%MqBlt)N&qPKTj-FY(R*+G)^L4U1+=AIMwIS1IPhQEy4~!;lG4XxBtRQ9Y4}m_h0JNgoP=5rc&Qmy6P*V&1+o*vXOg43;FJD(B7PAD_fY$1ffcPjj$4DKP zR}hwGJ-+%Cu7XRNz_@>b)#Sx7;~JyAxd2m)xc3rzm(ZY&b5tPyDw+i}ucKK+^9GtL zXplzyDw?;zH0@))j^wa@6p&xYqTuh~(09>b0zfj{LBBXdE}t91doV^UgE=dQ$lQjZ zlase?n84^uD3B}g#)QeZFaL)?@+DY^^6S`&nD85DPBTf(pOQKM zBy}Fc@PF34yU^2YDA)Jb`zYhS&oQw$0><$tNtN*@Qf65!M(1iJ%;Fg27#JyvgLsq* z3;05j9z`zU5mg9ku@@YdIq|*4mmmEError:\s*(.*?)= 3: - stringbuffer = BytesIO() - else: - stringbuffer = StringIO() - - curl.setopt(curl.WRITEDATA, stringbuffer) - - # Add User-Agent header to request so that the - # request can be identified as coming from the Adyen Python library. - headers['User-Agent'] = self.user_agent - - if username and password: - curl.setopt(curl.USERPWD, '%s:%s' % (username, password)) - elif xapikey: - headers["X-API-KEY"] = xapikey - - # Convert the header dict to formatted array as pycurl needs. - if sys.version_info[0] >= 3: - header_list = ["%s:%s" % (k, v) for k, v in headers.items()] - else: - header_list = ["%s:%s" % (k, v) for k, v in headers.iteritems()] - # Ensure proper content-type when adding headers - if json: - header_list.append("Content-Type:application/json") - - curl.setopt(pycurl.HTTPHEADER, header_list) - - # Return regular dict instead of JSON encoded dict for request: - raw_store = json - - # Set the request body. - raw_request = json_lib.dumps(json) if json else urlencode(data) - curl.setopt(curl.POSTFIELDS, raw_request) - - curl.setopt(curl.TIMEOUT, self.timeout) - curl.perform() - - # Grab the response content - result = stringbuffer.getvalue() - status_code = curl.getinfo(curl.RESPONSE_CODE) - - curl.close() - - # Return regular dict instead of JSON encoded dict for request: - raw_request = raw_store - - return result, raw_request, status_code, response_headers - - def _requests_post( - self, - url, - json=None, - data=None, - username="", - password="", - xapikey="", - headers=None - ): - """This function will POST to the url endpoint using requests. - Returning an AdyenResult object on 200 HTTP response. - Either json or data has to be provided. - If username and password are provided, basic auth will be used. - - - Args: - url (str): url to send the POST - json (dict, optional): Dict of the JSON to POST - data (dict, optional): Dict, presumed flat structure of key/value - of request to place - username (str, optionl): Username for basic auth. Must be included - as part of password. - password (str, optional): Password for basic auth. Must be included - as part of username. - xapikey (str, optional): Adyen API key. Will be used for auth - if username and password are absent. - headers (dict, optional): Key/Value pairs of headers to include - timeout (int, optional): Default 30. Timeout for the request. - - Returns: - str: Raw response received - str: Raw request placed - int: HTTP status code, eg 200,404,401 - dict: Key/Value pairs of the headers received. - """ - if headers is None: - headers = {} - - # Adding basic auth if username and password provided. - auth = None - if username and password: - auth = requests.auth.HTTPBasicAuth(username, password) - elif xapikey: - headers['x-api-key'] = xapikey - - # Add User-Agent header to request so that the request - # can be identified as coming from the Adyen Python library. - headers['User-Agent'] = self.user_agent - - request = requests.post( - url=url, - auth=auth, - data=data, - json=json, - headers=headers, - timeout=self.timeout - ) - - # Ensure either json or data is returned for raw request - # Updated: Only return regular dict, - # don't switch out formats if this is not important. - message = json - - return request.text, message, request.status_code, request.headers - - def _urllib_post( - self, - url, - json=None, - data=None, - username="", - password="", - xapikey="", - headers=None, - ): - - """This function will POST to the url endpoint using urllib2. returning - an AdyenResult object on 200 HTTP responce. Either json or data has to - be provided. If username and password are provided, basic auth will be - used. - - Args: - url (str): url to send the POST - json (dict, optional): Dict of the JSON to POST - data (dict, optional): Dict, presumed flat structure of - key/value of request to place as - www-form - username (str, optional): Username for basic auth. Must be - uncluded as part of password. - password (str, optional): Password for basic auth. Must be - included as part of username. - xapikey (str, optional): Adyen API key. Will be used for auth - if username and password are absent. - headers (dict, optional): Key/Value pairs of headers to include - - Returns: - str: Raw response received - str: Raw request placed - int: HTTP status code, eg 200,404,401 - dict: Key/Value pairs of the headers received. - """ - - if headers is None: - headers = {} - - # Store regular dict to return later: - raw_store = json - - raw_request = json_lib.dumps(json) if json else urlencode(data) - url_request = Request(url, data=raw_request.encode('utf8')) - if json: - url_request.add_header('Content-Type', 'application/json') - elif not data: - raise ValueError("Please provide either a json or a data field.") - - # Add User-Agent header to request so that the - # request can be identified as coming from the Adyen Python library. - headers['User-Agent'] = self.user_agent - - # Set regular dict to return as raw_request: - raw_request = raw_store - - # Adding basic auth is username and password provided. - if username and password: - if sys.version_info[0] >= 3: - basic_authstring = base64.encodebytes(('%s:%s' % - (username, password)) - .encode()).decode(). \ - replace('\n', '') - else: - basic_authstring = base64.encodestring('%s:%s' % (username, - password)). \ - replace('\n', '') - url_request.add_header("Authorization", - "Basic %s" % basic_authstring) - elif xapikey: - headers["X-API-KEY"] = xapikey - - # Adding the headers to the request. - for key, value in headers.items(): - url_request.add_header(key, str(value)) - - # URLlib raises all non 200 responses as en error. - try: - response = urlopen(url_request, timeout=self.timeout) - except HTTPError as e: - raw_response = e.read() - - return raw_response, raw_request, e.getcode(), e.headers - else: - raw_response = response.read() - response.close() - - # The dict(response.info()) is the headers of the response - # Raw response, raw request, status code and headers returned - return (raw_response, raw_request, - response.getcode(), dict(response.info())) - - def request( - self, - url, - json="", - data="", - username="", - password="", - headers=None, - ): - """This is overridden on module initialization. This function will make - an HTTP POST to a given url. Either json/data will be what is posted to - the end point. he HTTP request needs to be basicAuth when username and - password are provided. a headers dict maybe provided, - whatever the values are should be applied. - - Args: - url (str): url to send the POST - json (dict, optional): Dict of the JSON to POST - data (dict, optional): Dict, presumed flat structure of - key/value of request to place as - www-form - username (str, optional): Username for basic auth. Must be - included as part of password. - password (str, optional): Password for basic auth. Must be - included as part of username. - xapikey (str, optional): Adyen API key. Will be used for auth - if username and password are absent. - headers (dict, optional): Key/Value pairs of headers to include - Returns: - str: Raw request placed - str: Raw response received - int: HTTP status code, eg 200,404,401 - dict: Key/Value pairs of the headers received. - """ - raise NotImplementedError('request of HTTPClient should have been ' - 'overridden on initialization. ' - 'Otherwise, can be overridden to ' - 'supply your own post method') diff --git a/venv/lib/python3.7/site-packages/Adyen/services.py b/venv/lib/python3.7/site-packages/Adyen/services.py deleted file mode 100644 index e288106..0000000 --- a/venv/lib/python3.7/site-packages/Adyen/services.py +++ /dev/null @@ -1,369 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import datetime - -from Adyen import AdyenClient - - -class AdyenBase(object): - def __setattr__(self, attr, value): - client_attr = ["username", "password", "platform"] - if attr in client_attr: - if value: - self.client[attr] = value - else: - super(AdyenBase, self).__setattr__(attr, value) - - def __getattr__(self, attr): - client_attr = ["username", "password", "platform"] - if attr in client_attr: - return self.client[attr] - - -class AdyenServiceBase(AdyenBase): - def __init__(self, client=None): - if client: - self.client = client - else: - self.client = AdyenClient() - - -class AdyenRecurring(AdyenServiceBase): - """This represents the Adyen API Recurring Service. - - API calls currently implemented: listRecurringDetails and disable. Please - refer to the Recurring Manual for specifics around the API. - https://docs.adyen.com/online-payments/tokenization - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenRecurring, self).__init__(client=client) - self.service = "Recurring" - - def list_recurring_details(self, request, **kwargs): - - action = "listRecurringDetails" - - return self.client.call_api(request, self.service, - action, **kwargs) - - def disable(self, request, **kwargs): - - action = "disable" - - if 'recurringDetailReference' not in request: - raise ValueError("Include a 'recurringDetailReference'" - " to disable a specific recurring contract.") - else: - return self.client.call_api(request, self.service, - action, **kwargs) - - -class AdyenHPP(AdyenServiceBase): - """This represents the Adyen HPP Service. - - This currently only implements the directory_lookup request which will - return the list of payment methods available for given shopper. Please - refer to the HPP manual and the directory lookup section for the specifics. - https://docs.adyen.com/online-payments/classic-integrations/hosted-payment-pages/directory-lookup - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenHPP, self).__init__(client=client) - - def directory_lookup(self, request, **kwargs): - - action = "directory" - - try: - datetime.datetime.strptime(request['sessionValidity'], - '%Y-%m-%dT%H:%M:%SZ') - except ValueError: - raise ValueError( - "Incorrect date format, should be Y-m-dH:M:SZ," - " use datetime.strftime('%Y-%m-%dT%H:%M:%SZ')" - " to format a datetime object.") - - return self.client.call_hpp(request, action) - - def hpp_payment(self, request, skip_details=None, **kwargs): - - if skip_details: - action = "skipDetails" - else: - action = "select" - - if action == "skipDetails": - if "issuerId" not in request: - request['issuerId'] = "" - if type(request['sessionValidity']) is not str: - raise TypeError( - 'HPP: sessionValidity must be type of str,' - ' use datetime.strftime to convert and format.') - if all(k in request for k in ("shopperEmail", "shopperReference", - "recurringContract")): - recc = request['recurringContract'] - if recc != 'ONECLICK' and recc != 'RECURRING' \ - and recc != 'ONECLICK,RECURRING': - raise ValueError( - "HPP: recurringContract must be on of the following" - " values: 'ONECLICK', 'RECURRING'," - " 'ONECLICK,RECURRING'") - - result = self.client.hpp_payment(request, action) - return result - - -class AdyenPayment(AdyenServiceBase): - """This represents the Adyen API Payment Service. - - API calls currently implemented: - authorise - authorise3d - adjustAuthorisation - cancel - capture - refund - cancelOrRefund - Please refer to our API Explorer for specifics around these APIs. - https://docs.adyen.com/api-explorer/ - - The AdyenPayment class, is accessible as adyen.payment.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenPayment, self).__init__(client=client) - self.service = "Payment" - - def authorise(self, request, idempotency_key=None, **kwargs): - - action = "authorise" - - if 'shopperEmail' in request: - if request['shopperEmail'] == '': - raise ValueError( - 'shopperEmail must contain the shopper email' - ' when authorising recurring contracts.') - if 'shopperReference' in request: - if request['shopperReference'] == '': - raise ValueError( - 'shopperReference must contain the shopper' - ' name when authorising recurring contracts.') - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def authorise3d(self, request, idempotency_key=None, **kwargs): - action = "authorise3d" - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def adjustAuthorisation(self, request, **kwargs): - action = "adjustAuthorisation" - - return self.client.call_api(request, self.service, - action, **kwargs) - - def cancel(self, request, idempotency_key=None, **kwargs): - action = "cancel" - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def capture(self, request, idempotency_key=None, **kwargs): - - action = "capture" - - if request['modificationAmount']["value"] == "" or \ - request['modificationAmount']['value'] == "0": - raise ValueError( - "Set the 'modificationAmount' to the original transaction" - " amount, or less for a partial capture. " - "modificationAmount should be an object with the following" - " keys: {'currency':,'value':}") - if request['originalReference'] == "": - raise ValueError("Set the 'originalReference' to the psp " - "reference of the transaction to be modified") - - response = self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - return response - - def refund(self, request, idempotency_key=None, **kwargs): - - action = "refund" - - if request['modificationAmount']['value'] == "" or \ - request['modificationAmount']['value'] == "0": - raise ValueError( - "To refund this payment, provide the original value. " - "Set the value to less than the original amount, " - "to partially refund this payment.") - else: - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def cancel_or_refund(self, request, idempotency_key=None, **kwargs): - action = "cancelOrRefund" - - return self.client.call_api( - request, self.service, action, idempotency_key, **kwargs - ) - - -class AdyenThirdPartyPayout(AdyenServiceBase): - """This represents the Adyen Payouts Service. - https://docs.adyen.com/api-explorer/#/Payout/overview - - The AdyenThirdPartyPayout class is accessible as adyen.payout.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenThirdPartyPayout, self).__init__(client=client) - self.service = "Payout" - - def confirm(self, request=None, **kwargs): - action = "confirmThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def decline(self, request=None, **kwargs): - action = "declineThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def store_detail(self, request=None, **kwargs): - action = "storeDetail" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def submit(self, request=None, **kwargs): - action = "submitThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def store_detail_and_submit(self, request=None, **kwargs): - action = "storeDetailAndSubmitThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - -class AdyenCheckoutApi(AdyenServiceBase): - """This represents the Adyen Checkout API . - - API calls currently implemented: - paymentMethods - payments - payments/details - originKeys - - Please refer to the checkout documentation for specifics around the API. - https://docs.adyen.com/online-payments - - The AdyenPayment class, is accessible as adyen.payment.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenCheckoutApi, self).__init__(client=client) - self.service = "Checkout" - - def payment_methods(self, request, **kwargs): - action = "paymentMethods" - if 'merchantAccount' in request: - if request['merchantAccount'] == '': - raise ValueError( - 'merchantAccount must contain the merchant account' - ' when retrieving payment methods.') - - return self.client.call_checkout_api(request, action, **kwargs) - - def payments(self, request, idempotency_key=None, **kwargs): - action = "payments" - return self.client.call_checkout_api(request, action, idempotency_key, - **kwargs) - - def payments_details(self, request=None, idempotency_key=None, **kwargs): - action = "paymentsDetails" - return self.client.call_checkout_api(request, action, idempotency_key, - **kwargs) - - def payment_session(self, request=None, **kwargs): - action = "paymentSession" - return self.client.call_checkout_api(request, action, **kwargs) - - def payment_result(self, request=None, **kwargs): - action = "paymentsResult" - return self.client.call_checkout_api(request, action, **kwargs) - - def origin_keys(self, request=None, **kwargs): - action = "originKeys" - return self.client.call_checkout_api(request, action, **kwargs) - - def sessions(self, request=None, **kwargs): - action = "sessions" - return self.client.call_checkout_api(request, action, **kwargs) - # Orders endpoints - - # /paymentMethods/balance - def payment_methods_balance(self, request, **kwargs): - action = "paymentMethodsBalance" - return self.client.call_checkout_api(request, action, **kwargs) - - # /orders - def orders(self, request, **kwargs): - action = "orders" - return self.client.call_checkout_api(request, action, **kwargs) - - # /orders/cancel - def orders_cancel(self, request, **kwargs): - action = "ordersCancel" - return self.client.call_checkout_api(request, action, **kwargs) - - -class AdyenBinLookup(AdyenServiceBase): - """This represents the Adyen API Bin Lookup service. - - API call currently implemented: getCostEstimate. - Please refer to the Bin Lookup Manual for specifics around the API. - https://docs.adyen.com/api-explorer/#/BinLookup/ - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenBinLookup, self).__init__(client=client) - self.service = "BinLookup" - - def get_cost_estimate(self, request="", **kwargs): - - action = "getCostEstimate" - - return self.client.call_api(request, self.service, action, **kwargs) diff --git a/venv/lib/python3.7/site-packages/Adyen/settings.py b/venv/lib/python3.7/site-packages/Adyen/settings.py deleted file mode 100644 index 6291ba4..0000000 --- a/venv/lib/python3.7/site-packages/Adyen/settings.py +++ /dev/null @@ -1,16 +0,0 @@ -# Those constants are used from the library only -BASE_PAL_URL = "https://pal-{}.adyen.com/pal/servlet" -PAL_LIVE_ENDPOINT_URL_TEMPLATE = "https://{}-pal-live" \ - ".adyenpayments.com/pal/servlet" -BASE_HPP_URL = "https://{}.adyen.com/hpp" -ENDPOINT_CHECKOUT_TEST = "https://checkout-test.adyen.com" -ENDPOINT_CHECKOUT_LIVE_SUFFIX = "https://{}-checkout-live" \ - ".adyenpayments.com/checkout" -API_BIN_LOOKUP_VERSION = "v50" -API_CHECKOUT_VERSION = "v68" -API_CHECKOUT_UTILITY_VERSION = "v1" -API_RECURRING_VERSION = "v49" -API_PAYMENT_VERSION = "v64" -API_PAYOUT_VERSION = "v64" -LIB_VERSION = "6.0.0" -LIB_NAME = "adyen-python-api-library" diff --git a/venv/lib/python3.7/site-packages/Adyen/util.py b/venv/lib/python3.7/site-packages/Adyen/util.py deleted file mode 100644 index b9cb952..0000000 --- a/venv/lib/python3.7/site-packages/Adyen/util.py +++ /dev/null @@ -1,96 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from itertools import chain -from collections import OrderedDict -import base64 -import hmac -import hashlib -import binascii - - -def generate_hpp_sig(dict_object, hmac_key): - if 'issuerId' in dict_object: - if dict_object['issuerId'] == "": - del dict_object['issuerId'] - - if not isinstance(dict_object, dict): - raise ValueError("Must Provide dictionary object") - - def escape_val(val): - if isinstance(val, int): - return val - return val.replace('\\', '\\\\').replace(':', '\\:') - - hmac_key = binascii.a2b_hex(hmac_key) - - ordered_request = OrderedDict(sorted(dict_object.items(), - key=lambda t: t[0])) - - signing_string = ':'.join( - map(escape_val, chain(map(str, ordered_request.keys()), - map(str, ordered_request.values())))) - - hm = hmac.new(hmac_key, signing_string.encode('utf-8'), hashlib.sha256) - return base64.b64encode(hm.digest()) - - -def is_valid_hmac(dict_object, hmac_key): - if 'additionalData' in dict_object: - if dict_object['additionalData']['hmacSignature'] == "": - raise ValueError("Must Provide hmacSignature in additionalData") - else: - expected_sign = dict_object['additionalData']['hmacSignature'] - del dict_object['additionalData'] - merchant_sign = generate_hpp_sig(dict_object, hmac_key) - merchant_sign_str = merchant_sign.decode("utf-8") - return merchant_sign_str == expected_sign - - -def generate_notification_sig(dict_object, hmac_key): - if 'issuerId' in dict_object: - if dict_object['issuerId'] == "": - del dict_object['issuerId'] - - if not isinstance(dict_object, dict): - raise ValueError("Must Provide dictionary object") - - def escape_val(val): - if isinstance(val, int): - return val - return val.replace('\\', '\\\\') - - hmac_key = binascii.a2b_hex(hmac_key) - - request_dict = dict(dict_object) - request_dict['value'] = request_dict['amount']['value'] - request_dict['currency'] = request_dict['amount']['currency'] - - element_orders = [ - 'pspReference', - 'originalReference', - 'merchantAccountCode', - 'merchantReference', - 'value', - 'currency', - 'eventCode', - 'success', - ] - - signing_string = ':'.join( - map(escape_val, map(str, ( - request_dict.get(element, '') for element in element_orders)))) - - hm = hmac.new(hmac_key, signing_string.encode('utf-8'), hashlib.sha256) - return base64.b64encode(hm.digest()) - - -def is_valid_hmac_notification(dict_object, hmac_key): - if 'additionalData' in dict_object: - if dict_object['additionalData']['hmacSignature'] == "": - raise ValueError("Must Provide hmacSignature in additionalData") - else: - expected_sign = dict_object['additionalData']['hmacSignature'] - del dict_object['additionalData'] - merchant_sign = generate_notification_sig(dict_object, hmac_key) - merchant_sign_str = merchant_sign.decode("utf-8") - return merchant_sign_str == expected_sign diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/LICENSE.rst deleted file mode 100644 index 9d227a0..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2010 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/METADATA b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/METADATA deleted file mode 100644 index d617f5f..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/METADATA +++ /dev/null @@ -1,125 +0,0 @@ -Metadata-Version: 2.1 -Name: Flask -Version: 2.0.3 -Summary: A simple framework for building complex web applications. -Home-page: https://palletsprojects.com/p/flask -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://flask.palletsprojects.com/ -Project-URL: Changes, https://flask.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/flask/ -Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Framework :: Flask -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application -Classifier: Topic :: Software Development :: Libraries :: Application Frameworks -Requires-Python: >=3.6 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst -Requires-Dist: Werkzeug (>=2.0) -Requires-Dist: Jinja2 (>=3.0) -Requires-Dist: itsdangerous (>=2.0) -Requires-Dist: click (>=7.1.2) -Provides-Extra: async -Requires-Dist: asgiref (>=3.2) ; extra == 'async' -Provides-Extra: dotenv -Requires-Dist: python-dotenv ; extra == 'dotenv' - -Flask -===== - -Flask is a lightweight `WSGI`_ web application framework. It is designed -to make getting started quick and easy, with the ability to scale up to -complex applications. It began as a simple wrapper around `Werkzeug`_ -and `Jinja`_ and has become one of the most popular Python web -application frameworks. - -Flask offers suggestions, but doesn't enforce any dependencies or -project layout. It is up to the developer to choose the tools and -libraries they want to use. There are many extensions provided by the -community that make adding new functionality easy. - -.. _WSGI: https://wsgi.readthedocs.io/ -.. _Werkzeug: https://werkzeug.palletsprojects.com/ -.. _Jinja: https://jinja.palletsprojects.com/ - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - $ pip install -U Flask - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -A Simple Example ----------------- - -.. code-block:: python - - # save this as app.py - from flask import Flask - - app = Flask(__name__) - - @app.route("/") - def hello(): - return "Hello, World!" - -.. code-block:: text - - $ flask run - * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) - - -Contributing ------------- - -For guidance on setting up a development environment and how to make a -contribution to Flask, see the `contributing guidelines`_. - -.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst - - -Donate ------- - -The Pallets organization develops and supports Flask and the libraries -it uses. In order to grow the community of contributors and users, and -allow the maintainers to devote more time to the projects, `please -donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://flask.palletsprojects.com/ -- Changes: https://flask.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/Flask/ -- Source Code: https://github.com/pallets/flask/ -- Issue Tracker: https://github.com/pallets/flask/issues/ -- Website: https://palletsprojects.com/p/flask/ -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/RECORD b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/RECORD deleted file mode 100644 index 7ccce61..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/RECORD +++ /dev/null @@ -1,51 +0,0 @@ -../../../bin/flask,sha256=sR4yhMrSywRbEyuOk0H-s-iJmN0WEkOx-nXnh3QFpg8,289 -Flask-2.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -Flask-2.0.3.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 -Flask-2.0.3.dist-info/METADATA,sha256=jK50YtxZfODLQP_GF1sNH6dOXRCI5bBLrAc7pWQwuXw,3839 -Flask-2.0.3.dist-info/RECORD,, -Flask-2.0.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 -Flask-2.0.3.dist-info/entry_points.txt,sha256=s3MqQpduU25y4dq3ftBYD6bMVdVnbMpZP-sUNw0zw0k,41 -Flask-2.0.3.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 -flask/__init__.py,sha256=ubQS5Xt6LMjPSwGO3Jksi5yx8AyuU0vT_VdHjt0j97A,2251 -flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 -flask/__pycache__/__init__.cpython-37.pyc,, -flask/__pycache__/__main__.cpython-37.pyc,, -flask/__pycache__/app.cpython-37.pyc,, -flask/__pycache__/blueprints.cpython-37.pyc,, -flask/__pycache__/cli.cpython-37.pyc,, -flask/__pycache__/config.cpython-37.pyc,, -flask/__pycache__/ctx.cpython-37.pyc,, -flask/__pycache__/debughelpers.cpython-37.pyc,, -flask/__pycache__/globals.cpython-37.pyc,, -flask/__pycache__/helpers.cpython-37.pyc,, -flask/__pycache__/logging.cpython-37.pyc,, -flask/__pycache__/scaffold.cpython-37.pyc,, -flask/__pycache__/sessions.cpython-37.pyc,, -flask/__pycache__/signals.cpython-37.pyc,, -flask/__pycache__/templating.cpython-37.pyc,, -flask/__pycache__/testing.cpython-37.pyc,, -flask/__pycache__/typing.cpython-37.pyc,, -flask/__pycache__/views.cpython-37.pyc,, -flask/__pycache__/wrappers.cpython-37.pyc,, -flask/app.py,sha256=ectBbi9hGmVHAse5TNcFQZIDRkDAxYUAnLgfuKD0Xws,81975 -flask/blueprints.py,sha256=AkAVXZ_MMkjwjklzCAMdBNowTiM0wVQPynnUnXjTL2M,23781 -flask/cli.py,sha256=9v7FDIwWZ3QZsR6ka-qMYzMxSThfmQ4PEA4lkI38R6c,32287 -flask/config.py,sha256=70Uyjh1Jzb9MfTCT7NDhuZWAzyIEu-TIyk6-22MP3zQ,11285 -flask/ctx.py,sha256=Rmw5VOFQdbomLoCQPbU_0FbQkuB56CtpnQVU4yzXYB8,17589 -flask/debughelpers.py,sha256=W82-xrRmodjopBngI9roYH-q08EbQwN2HEGfDAi6SA0,6184 -flask/globals.py,sha256=cWd-R2hUH3VqPhnmQNww892tQS6Yjqg_wg8UvW1M7NM,1723 -flask/helpers.py,sha256=kstplLDtD0Isobilp87Lfmwq1tk2spnHjUf_O5-EhoE,30618 -flask/json/__init__.py,sha256=_YIqOsy8YOSyoLbplFtNcKvF5kwNKenmJ87Ub2Myc0k,12104 -flask/json/__pycache__/__init__.cpython-37.pyc,, -flask/json/__pycache__/tag.cpython-37.pyc,, -flask/json/tag.py,sha256=fys3HBLssWHuMAIJuTcf2K0bCtosePBKXIWASZEEjnU,8857 -flask/logging.py,sha256=1o_hirVGqdj7SBdETnhX7IAjklG89RXlrwz_2CjzQQE,2273 -flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -flask/scaffold.py,sha256=fM9mRy7QBh9fhJ0VTogVx900dDa5oxz8FOw6OK5F-TU,32796 -flask/sessions.py,sha256=46jK4JlcdeBiYbDWTZJn_6u8EqDV-ByRdhlKrbgFi5M,15714 -flask/signals.py,sha256=H7QwDciK-dtBxinjKpexpglP0E6k0MJILiFWTItfmqU,2136 -flask/templating.py,sha256=l96VD39JQ0nue4Bcj7wZ4-FWWs-ppLxvgBCpwDQ4KAk,5626 -flask/testing.py,sha256=T3mr2PLQEkfxoftSTxmGfTtb_FSX3PgfGT8DUGNPWuk,10840 -flask/typing.py,sha256=L5JMltVjj8fovGS1hrMpb13IPfsFDESCCnpRN5CPT4U,1844 -flask/views.py,sha256=nhq31TRB5Z-z2mjFGZACaaB2Et5XPCmWhWxJxOvLWww,5948 -flask/wrappers.py,sha256=VndbHPRBSUUOejmd2Y3ydkoCVUtsS2OJIdJEVIkBVD8,5604 diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/WHEEL deleted file mode 100644 index becc9a6..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/entry_points.txt deleted file mode 100644 index 137232d..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[console_scripts] -flask = flask.cli:main diff --git a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/top_level.txt deleted file mode 100644 index 7e10602..0000000 --- a/venv/lib/python3.7/site-packages/Flask-2.0.3.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -flask diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/LICENSE.rst deleted file mode 100644 index c37cae4..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2007 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/METADATA b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/METADATA deleted file mode 100644 index 3b9355a..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/METADATA +++ /dev/null @@ -1,113 +0,0 @@ -Metadata-Version: 2.1 -Name: Jinja2 -Version: 3.0.3 -Summary: A very fast and expressive template engine. -Home-page: https://palletsprojects.com/p/jinja/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://jinja.palletsprojects.com/ -Project-URL: Changes, https://jinja.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/jinja/ -Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Python: >=3.6 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst -Requires-Dist: MarkupSafe (>=2.0) -Provides-Extra: i18n -Requires-Dist: Babel (>=2.7) ; extra == 'i18n' - -Jinja -===== - -Jinja is a fast, expressive, extensible templating engine. Special -placeholders in the template allow writing code similar to Python -syntax. Then the template is passed data to render the final document. - -It includes: - -- Template inheritance and inclusion. -- Define and import macros within templates. -- HTML templates can use autoescaping to prevent XSS from untrusted - user input. -- A sandboxed environment can safely render untrusted templates. -- AsyncIO support for generating templates and calling async - functions. -- I18N support with Babel. -- Templates are compiled to optimized Python code just-in-time and - cached, or can be compiled ahead-of-time. -- Exceptions point to the correct line in templates to make debugging - easier. -- Extensible filters, tests, functions, and even syntax. - -Jinja's philosophy is that while application logic belongs in Python if -possible, it shouldn't make the template designer's job difficult by -restricting functionality too much. - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - $ pip install -U Jinja2 - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -In A Nutshell -------------- - -.. code-block:: jinja - - {% extends "base.html" %} - {% block title %}Members{% endblock %} - {% block content %} -

- {% endblock %} - - -Donate ------- - -The Pallets organization develops and supports Jinja and other popular -packages. In order to grow the community of contributors and users, and -allow the maintainers to devote more time to the projects, `please -donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://jinja.palletsprojects.com/ -- Changes: https://jinja.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/Jinja2/ -- Source Code: https://github.com/pallets/jinja/ -- Issue Tracker: https://github.com/pallets/jinja/issues/ -- Website: https://palletsprojects.com/p/jinja/ -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/RECORD b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/RECORD deleted file mode 100644 index 6e631ed..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/RECORD +++ /dev/null @@ -1,58 +0,0 @@ -Jinja2-3.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -Jinja2-3.0.3.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 -Jinja2-3.0.3.dist-info/METADATA,sha256=uvKoBSMLvh0qHK-6khEqSe1yOV4jxFzbPSREOp-3BXk,3539 -Jinja2-3.0.3.dist-info/RECORD,, -Jinja2-3.0.3.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 -Jinja2-3.0.3.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61 -Jinja2-3.0.3.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 -jinja2/__init__.py,sha256=V3JjnTV-nyIHN6rwj03N1M11fegjGvv-weiHMQwH1pk,2205 -jinja2/__pycache__/__init__.cpython-37.pyc,, -jinja2/__pycache__/_identifier.cpython-37.pyc,, -jinja2/__pycache__/async_utils.cpython-37.pyc,, -jinja2/__pycache__/bccache.cpython-37.pyc,, -jinja2/__pycache__/compiler.cpython-37.pyc,, -jinja2/__pycache__/constants.cpython-37.pyc,, -jinja2/__pycache__/debug.cpython-37.pyc,, -jinja2/__pycache__/defaults.cpython-37.pyc,, -jinja2/__pycache__/environment.cpython-37.pyc,, -jinja2/__pycache__/exceptions.cpython-37.pyc,, -jinja2/__pycache__/ext.cpython-37.pyc,, -jinja2/__pycache__/filters.cpython-37.pyc,, -jinja2/__pycache__/idtracking.cpython-37.pyc,, -jinja2/__pycache__/lexer.cpython-37.pyc,, -jinja2/__pycache__/loaders.cpython-37.pyc,, -jinja2/__pycache__/meta.cpython-37.pyc,, -jinja2/__pycache__/nativetypes.cpython-37.pyc,, -jinja2/__pycache__/nodes.cpython-37.pyc,, -jinja2/__pycache__/optimizer.cpython-37.pyc,, -jinja2/__pycache__/parser.cpython-37.pyc,, -jinja2/__pycache__/runtime.cpython-37.pyc,, -jinja2/__pycache__/sandbox.cpython-37.pyc,, -jinja2/__pycache__/tests.cpython-37.pyc,, -jinja2/__pycache__/utils.cpython-37.pyc,, -jinja2/__pycache__/visitor.cpython-37.pyc,, -jinja2/_identifier.py,sha256=EdgGJKi7O1yvr4yFlvqPNEqV6M1qHyQr8Gt8GmVTKVM,1775 -jinja2/async_utils.py,sha256=jBcJSmLoQa2PjJdNcOpwaUmBxFNE9rZNwMF7Ob3dP9I,1947 -jinja2/bccache.py,sha256=v5rKAlYxIvfJEa0uGzAC6yCYSS3KuXT5Eqi-n9qvNi8,12670 -jinja2/compiler.py,sha256=v7zKz-mgSYXmfXD9mRmi2BU0B6Z-1RGZmOXCrsPKzc0,72209 -jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 -jinja2/debug.py,sha256=r0JL0vfO7HPlyKZEdr6eVlg7HoIg2OQGmJ7SeUEyAeI,8494 -jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 -jinja2/environment.py,sha256=Vz20npBX5-SUH_eguQuxrSQDEsLFjho0qcHLdMhY3hA,60983 -jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 -jinja2/ext.py,sha256=44SjDjeYkkxQTpmC2BetOTxEFMgQ42p2dfSwXmPFcSo,32122 -jinja2/filters.py,sha256=jusKTZbd0ddZMaibZkxMUVKNsOsaYtOq_Il8Imtx4BE,52609 -jinja2/idtracking.py,sha256=WekexMql3u5n3vDxFsQ_i8HW0j24AtjWTjrPBLWrHww,10721 -jinja2/lexer.py,sha256=qNEQqDQw_zO5EaH6rFQsER7Qwn2du0o22prB-TR11HE,29930 -jinja2/loaders.py,sha256=1MjXJOU6p4VywFqtpDZhtvtT_vIlmHnZKMKHHw4SZzA,22754 -jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 -jinja2/nativetypes.py,sha256=KCJl71MogrDih_BHBu6xV5p7Cr_jggAgu-shKTg6L28,3969 -jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 -jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 -jinja2/parser.py,sha256=kHnU8v92GwMYkfr0MVakWv8UlSf_kJPx8LUsgQMof70,39767 -jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -jinja2/runtime.py,sha256=wVRlkEmAgNU67AIQDqLvI6UkNLkzDqpLA-z4Mi3vl3g,35054 -jinja2/sandbox.py,sha256=-8zxR6TO9kUkciAVFsIKu8Oq-C7PTeYEdZ5TtA55-gw,14600 -jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 -jinja2/utils.py,sha256=udQxWIKaq4QDCZiXN31ngKOaGGdaMA5fl0JMaM-F6fg,26971 -jinja2/visitor.py,sha256=ZmeLuTj66ic35-uFH-1m0EKXiw4ObDDb_WuE6h5vPFg,3572 diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/WHEEL deleted file mode 100644 index 5bad85f..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.0) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/entry_points.txt deleted file mode 100644 index 3619483..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[babel.extractors] -jinja2 = jinja2.ext:babel_extract [i18n] - diff --git a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/top_level.txt deleted file mode 100644 index 7f7afbf..0000000 --- a/venv/lib/python3.7/site-packages/Jinja2-3.0.3.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -jinja2 diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/LICENSE.rst deleted file mode 100644 index 9d227a0..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2010 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/METADATA b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/METADATA deleted file mode 100644 index 0c81a12..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/METADATA +++ /dev/null @@ -1,101 +0,0 @@ -Metadata-Version: 2.1 -Name: MarkupSafe -Version: 2.1.0 -Summary: Safely add untrusted strings to HTML/XML markup. -Home-page: https://palletsprojects.com/p/markupsafe/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://markupsafe.palletsprojects.com/ -Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/markupsafe/ -Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Python: >=3.7 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst - -MarkupSafe -========== - -MarkupSafe implements a text object that escapes characters so it is -safe to use in HTML and XML. Characters that have special meanings are -replaced so that they display as the actual characters. This mitigates -injection attacks, meaning untrusted user input can safely be displayed -on a page. - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - pip install -U MarkupSafe - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -Examples --------- - -.. code-block:: pycon - - >>> from markupsafe import Markup, escape - - >>> # escape replaces special characters and wraps in Markup - >>> escape("") - Markup('<script>alert(document.cookie);</script>') - - >>> # wrap in Markup to mark text "safe" and prevent escaping - >>> Markup("Hello") - Markup('hello') - - >>> escape(Markup("Hello")) - Markup('hello') - - >>> # Markup is a str subclass - >>> # methods and operators escape their arguments - >>> template = Markup("Hello {name}") - >>> template.format(name='"World"') - Markup('Hello "World"') - - -Donate ------- - -The Pallets organization develops and supports MarkupSafe and other -popular packages. In order to grow the community of contributors and -users, and allow the maintainers to devote more time to the projects, -`please donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://markupsafe.palletsprojects.com/ -- Changes: https://markupsafe.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/MarkupSafe/ -- Source Code: https://github.com/pallets/markupsafe/ -- Issue Tracker: https://github.com/pallets/markupsafe/issues/ -- Website: https://palletsprojects.com/p/markupsafe/ -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/RECORD b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/RECORD deleted file mode 100644 index 06384a7..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/RECORD +++ /dev/null @@ -1,14 +0,0 @@ -MarkupSafe-2.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -MarkupSafe-2.1.0.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 -MarkupSafe-2.1.0.dist-info/METADATA,sha256=585PQ3HNHmJeHpbdXckhscUSR9AaQnh5RWaaMtCB4_8,3242 -MarkupSafe-2.1.0.dist-info/RECORD,, -MarkupSafe-2.1.0.dist-info/WHEEL,sha256=MTGYRPpheMM24WbmS90Rp7e0ky6cZJ8CkS_x1qgwoGk,110 -MarkupSafe-2.1.0.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 -markupsafe/__init__.py,sha256=7p5vza0YNtAtfancH4eGnJLe9V4uEFATInoX7Ko7aig,9130 -markupsafe/__pycache__/__init__.cpython-37.pyc,, -markupsafe/__pycache__/_native.cpython-37.pyc,, -markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 -markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 -markupsafe/_speedups.cpython-37m-darwin.so,sha256=bsPzxjMESIuCzC-OuQDjL_P579nPHCp-GkcwUbKjrYo,34984 -markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 -markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/WHEEL b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/WHEEL deleted file mode 100644 index 8d824da..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.0) -Root-Is-Purelib: false -Tag: cp37-cp37m-macosx_10_9_x86_64 - diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/top_level.txt deleted file mode 100644 index 75bf729..0000000 --- a/venv/lib/python3.7/site-packages/MarkupSafe-2.1.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -markupsafe diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/LICENSE.rst deleted file mode 100644 index c37cae4..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2007 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/METADATA b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/METADATA deleted file mode 100644 index 551fa0b..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/METADATA +++ /dev/null @@ -1,129 +0,0 @@ -Metadata-Version: 2.1 -Name: Werkzeug -Version: 2.0.3 -Summary: The comprehensive WSGI web application library. -Home-page: https://palletsprojects.com/p/werkzeug/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://werkzeug.palletsprojects.com/ -Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/werkzeug/ -Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware -Classifier: Topic :: Software Development :: Libraries :: Application Frameworks -Requires-Python: >=3.6 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst -Requires-Dist: dataclasses ; python_version < "3.7" -Provides-Extra: watchdog -Requires-Dist: watchdog ; extra == 'watchdog' - -Werkzeug -======== - -*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff") - -Werkzeug is a comprehensive `WSGI`_ web application library. It began as -a simple collection of various utilities for WSGI applications and has -become one of the most advanced WSGI utility libraries. - -It includes: - -- An interactive debugger that allows inspecting stack traces and - source code in the browser with an interactive interpreter for any - frame in the stack. -- A full-featured request object with objects to interact with - headers, query args, form data, files, and cookies. -- A response object that can wrap other WSGI applications and handle - streaming data. -- A routing system for matching URLs to endpoints and generating URLs - for endpoints, with an extensible system for capturing variables - from URLs. -- HTTP utilities to handle entity tags, cache control, dates, user - agents, cookies, files, and more. -- A threaded WSGI server for use while developing applications - locally. -- A test client for simulating HTTP requests during testing without - requiring running a server. - -Werkzeug doesn't enforce any dependencies. It is up to the developer to -choose a template engine, database adapter, and even how to handle -requests. It can be used to build all sorts of end user applications -such as blogs, wikis, or bulletin boards. - -`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while -providing more structure and patterns for defining powerful -applications. - -.. _WSGI: https://wsgi.readthedocs.io/en/latest/ -.. _Flask: https://www.palletsprojects.com/p/flask/ - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - pip install -U Werkzeug - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -A Simple Example ----------------- - -.. code-block:: python - - from werkzeug.wrappers import Request, Response - - @Request.application - def application(request): - return Response('Hello, World!') - - if __name__ == '__main__': - from werkzeug.serving import run_simple - run_simple('localhost', 4000, application) - - -Donate ------- - -The Pallets organization develops and supports Werkzeug and other -popular packages. In order to grow the community of contributors and -users, and allow the maintainers to devote more time to the projects, -`please donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://werkzeug.palletsprojects.com/ -- Changes: https://werkzeug.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/Werkzeug/ -- Source Code: https://github.com/pallets/werkzeug/ -- Issue Tracker: https://github.com/pallets/werkzeug/issues/ -- Website: https://palletsprojects.com/p/werkzeug/ -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/RECORD b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/RECORD deleted file mode 100644 index 7d1ef41..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/RECORD +++ /dev/null @@ -1,111 +0,0 @@ -Werkzeug-2.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -Werkzeug-2.0.3.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 -Werkzeug-2.0.3.dist-info/METADATA,sha256=Rxzda7JFgpyr7oqR42Z57bNxRp-pjna_KYhcivqvXY4,4452 -Werkzeug-2.0.3.dist-info/RECORD,, -Werkzeug-2.0.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 -Werkzeug-2.0.3.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 -werkzeug/__init__.py,sha256=2frslFsD2EbmZUTfzZ5njDmic66S5f6XMdT24AOGYhk,188 -werkzeug/__pycache__/__init__.cpython-37.pyc,, -werkzeug/__pycache__/_internal.cpython-37.pyc,, -werkzeug/__pycache__/_reloader.cpython-37.pyc,, -werkzeug/__pycache__/datastructures.cpython-37.pyc,, -werkzeug/__pycache__/exceptions.cpython-37.pyc,, -werkzeug/__pycache__/filesystem.cpython-37.pyc,, -werkzeug/__pycache__/formparser.cpython-37.pyc,, -werkzeug/__pycache__/http.cpython-37.pyc,, -werkzeug/__pycache__/local.cpython-37.pyc,, -werkzeug/__pycache__/routing.cpython-37.pyc,, -werkzeug/__pycache__/security.cpython-37.pyc,, -werkzeug/__pycache__/serving.cpython-37.pyc,, -werkzeug/__pycache__/test.cpython-37.pyc,, -werkzeug/__pycache__/testapp.cpython-37.pyc,, -werkzeug/__pycache__/urls.cpython-37.pyc,, -werkzeug/__pycache__/user_agent.cpython-37.pyc,, -werkzeug/__pycache__/useragents.cpython-37.pyc,, -werkzeug/__pycache__/utils.cpython-37.pyc,, -werkzeug/__pycache__/wsgi.cpython-37.pyc,, -werkzeug/_internal.py,sha256=_0GZM3B6gE4eoRTp9K6T7spvY5qJQ9Od9GRIp4lZpzU,18572 -werkzeug/_reloader.py,sha256=B1hEfgsUOz2IginBQM5Zak_eaIF7gr3GS5-0x2OHvAE,13950 -werkzeug/datastructures.py,sha256=m79A8rHQEt5B7qVqyrjARXzHL66Katn8S92urGscTw4,97929 -werkzeug/datastructures.pyi,sha256=uFOqffFoaOEa-43IPlK9otu1X4lDOoqIgG4ULS0ObiE,34119 -werkzeug/debug/__init__.py,sha256=Vn0WQfD9w6DGg1j_2gWpSKKTaFlwxhbCBwi7QQMz1s8,17917 -werkzeug/debug/__pycache__/__init__.cpython-37.pyc,, -werkzeug/debug/__pycache__/console.cpython-37.pyc,, -werkzeug/debug/__pycache__/repr.cpython-37.pyc,, -werkzeug/debug/__pycache__/tbtools.cpython-37.pyc,, -werkzeug/debug/console.py,sha256=jJjid1dIlCNWbDHXTtjJW5XqNfPjSOKbtUmEX5weNdY,5976 -werkzeug/debug/repr.py,sha256=QCSHENKsChEZDCIApkVi_UNjhJ77v8BMXK1OfxO189M,9483 -werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673 -werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222 -werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 -werkzeug/debug/shared/debugger.js,sha256=tg42SZs1SVmYWZ-_Fj5ELK5-FLHnGNQrei0K2By8Bw8,10521 -werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 -werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 -werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818 -werkzeug/debug/shared/style.css,sha256=h1ZSUVaKNpfbfcYzRb513WAhPySGDQom1uih3uEDxPw,6704 -werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 -werkzeug/debug/tbtools.py,sha256=khUCWQcpbxzeOs5NlT-E9n99BI-ELH9K9RY5exc-X_o,19362 -werkzeug/exceptions.py,sha256=WLCqXBEHm5Xj2d2sfON9XIneeRS3MlNXKH85k1AQIJU,28776 -werkzeug/filesystem.py,sha256=JS2Dv2QF98WILxY4_thHl-WMcUcwluF_4igkDPaP1l4,1956 -werkzeug/formparser.py,sha256=X-p3Ek4ji8XrKrbmaWxr8StLSc6iuksbpIeweaabs4s,17400 -werkzeug/http.py,sha256=Xm3WhYKRQKh_J12514F8y8prILldXceOceeO8EiQEZI,45222 -werkzeug/local.py,sha256=5HbGdD0vVNJgXH3SXfkMjdxIpzy7iqkHJMGCNjljFNo,23664 -werkzeug/middleware/__init__.py,sha256=qfqgdT5npwG9ses3-FXQJf3aB95JYP1zchetH_T3PUw,500 -werkzeug/middleware/__pycache__/__init__.cpython-37.pyc,, -werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc,, -werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc,, -werkzeug/middleware/__pycache__/lint.cpython-37.pyc,, -werkzeug/middleware/__pycache__/profiler.cpython-37.pyc,, -werkzeug/middleware/__pycache__/proxy_fix.cpython-37.pyc,, -werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc,, -werkzeug/middleware/dispatcher.py,sha256=Fh_w-KyWnTSYF-Lfv5dimQ7THSS7afPAZMmvc4zF1gg,2580 -werkzeug/middleware/http_proxy.py,sha256=HE8VyhS7CR-E1O6_9b68huv8FLgGGR1DLYqkS3Xcp3Q,7558 -werkzeug/middleware/lint.py,sha256=sAg3GcOhICIkwYX5bJGG8n8iebX0Yipq_UH0HvrBvoU,13964 -werkzeug/middleware/profiler.py,sha256=QkXk7cqnaPnF8wQu-5SyPCIOT3_kdABUBorQOghVNOA,4899 -werkzeug/middleware/proxy_fix.py,sha256=l7LC_LDu0Yd4SvUxS5SFigAJMzcIOGm6LNKl9IXJBSU,6974 -werkzeug/middleware/shared_data.py,sha256=xydEqOhAGg0aQJEllPDVfz2-8jHwWvJpAxfPsfPCu7k,10960 -werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -werkzeug/routing.py,sha256=rATL0ZkbTBgvdgJp6WgihuwKyivCF8K4a8kQ4hFgY6A,84581 -werkzeug/sansio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -werkzeug/sansio/__pycache__/__init__.cpython-37.pyc,, -werkzeug/sansio/__pycache__/multipart.cpython-37.pyc,, -werkzeug/sansio/__pycache__/request.cpython-37.pyc,, -werkzeug/sansio/__pycache__/response.cpython-37.pyc,, -werkzeug/sansio/__pycache__/utils.cpython-37.pyc,, -werkzeug/sansio/multipart.py,sha256=BRjBk_mCPjSJzwNVvBgmrJGk3QxA9pYfsgzFki28bxc,8751 -werkzeug/sansio/request.py,sha256=kt7fizz15HPuYKYU1_3TTEkNSuXeeaM4aLcjW84qvv4,20247 -werkzeug/sansio/response.py,sha256=zvCq9HSBBZGBd5Gg412BY9RZIwnKsJl5Kzfd3Kl9sSo,26098 -werkzeug/sansio/utils.py,sha256=V5v-UUnX8pm4RehP9Tt_NiUSOJGJGUvKjlW0eOIQldM,4164 -werkzeug/security.py,sha256=gPDRuCjkjWrcqj99tBMq8_nHFZLFQjgoW5Ga5XIw9jo,8158 -werkzeug/serving.py,sha256=6aV-RKbZm4rUHveQGuh4SY0wFZTmXyR43yD_kCQm8Wo,38287 -werkzeug/test.py,sha256=eUORFaeIDXcmncLdYxgFqYiVdolZkYRY67QV1_ATk20,48235 -werkzeug/testapp.py,sha256=f48prWSGJhbSrvYb8e1fnAah4BkrLb0enHSdChgsjBY,9471 -werkzeug/urls.py,sha256=Du2lreBHvgBh5c2_bcx72g3hzV2ZabXYZsp-picUIJs,41023 -werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420 -werkzeug/useragents.py,sha256=G8tmv_6vxJaPrLQH3eODNgIYe0_V6KETROQlJI-WxDE,7264 -werkzeug/utils.py,sha256=D_dnCLUfodQ4k0GRSpnI6qDoVoaX7-Dza57bx7sabG0,37101 -werkzeug/wrappers/__init__.py,sha256=-s75nPbyXHzU_rwmLPDhoMuGbEUk0jZT_n0ZQAOFGf8,654 -werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/accept.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/auth.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/cors.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/etag.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/json.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/request.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/response.cpython-37.pyc,, -werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc,, -werkzeug/wrappers/accept.py,sha256=NzyLfKH3qC5cSbkEc5azw5-lp_kU8JIrtc8AdGQ0HBs,413 -werkzeug/wrappers/auth.py,sha256=ArJiEn8HHzy1B7wUGuN7s3AHpnClKlaDY0F7N7QZSLA,824 -werkzeug/wrappers/base_request.py,sha256=saz9RyNQkvI_XLPYVm29KijNHmD1YzgxDqa0qHTbgss,1174 -werkzeug/wrappers/base_response.py,sha256=q_-TaYywT5G4zA-DWDRDJhJSat2_4O7gOPob6ye4_9A,1186 -werkzeug/wrappers/common_descriptors.py,sha256=aeVFTsTb0HJn5O8zF6WwELEDDULdOLFkWaUrvD1Huds,866 -werkzeug/wrappers/cors.py,sha256=9Ho7aXd64sB2Msz71jRXAdAI8UyqIJgv-CJsnlfUSzM,814 -werkzeug/wrappers/etag.py,sha256=7SI34rtlXJHyJlqe8B0dFu4ouo6L0DJmYyqwWoY79oc,814 -werkzeug/wrappers/json.py,sha256=h_XfBZV5ZETkHYgONuoSyB9KXR9W90mgBh_mFUysp6c,394 -werkzeug/wrappers/request.py,sha256=I77nwHgCzynmgwJVNw7bo7MfTU_CusNBO0b4TjpIRdQ,24790 -werkzeug/wrappers/response.py,sha256=c24tBeq8G5RwPCU5iCJvJPaKyUEIrfMiWO4yGtTOwmI,35214 -werkzeug/wrappers/user_agent.py,sha256=IMUJCFohZSMsBTmqyJZtjG5y4sB1zxQBE690bixb6uY,419 -werkzeug/wsgi.py,sha256=L7s5-Rlt7BRVEZ1m81MaenGfMDP7yL3p1Kxt9Yssqzg,33727 diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/WHEEL deleted file mode 100644 index becc9a6..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/top_level.txt deleted file mode 100644 index 6fe8da8..0000000 --- a/venv/lib/python3.7/site-packages/Werkzeug-2.0.3.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -werkzeug diff --git a/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc deleted file mode 100644 index d7cea0bdd53277f20af761d3945d50dc025d396c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333 zcmYk0&q~BF5XO_XY7zGd1TEgmvQ3x$gMx?%9=v!^PkR|+6K!eI#H1~B4_%7R6iZ{hOwW>YPWH)OJ^ut*H=Erlh15>q7uZiwfYw;ZThGU|6r?px*&t zDgzi!Dk?d^>d^AK(X~>-CL2J)9TbWms_`A;6`5^k-|aIe+7vCVIccdO4@xj@Ea?_x z35%01E2rr(OJVjj&&s^avgJH=der2O=t566*vYKy8riBT`O7E&a}(Y5;i*)t5&R6h Ma65bucp=`yUlt->`Tzg` diff --git a/venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/typing_extensions.cpython-37.pyc deleted file mode 100644 index eddf8e6bf46de30db3b755e9a039f5472031b98b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95330 zcmeFa37A~Rb>G|D^z0CyKdd8Q&p!i6^` z{M*CLem>1V-jGUpDK9;rD!K1;DQ&+q!FRTlwcoi?&c6FfdHe1!^;dIq1uyMo-k;f? z^0KG;N(0paf2ulI8mf%7-{MehyXF7J)r_1>Gj8@%1#m^bd-=-uS) z@%DNX-p$@EvwKP#sP#9h8!n7^w|cjEx6fuTrm61^@6P8_rH$3m^QqER)vIRG-d*0C zpHG)I8Psn%)%TIKpYz`8?IYLK_3JG4ZcE+a-4mo1ynEf9_n*A`ytnc8=IS-oesAJ@ zhPU@u`{%Zlw$zJnPkH;j1J9?t1Eg&A4tj@P&Xu-Rx7l5~w58gAVY_$##dK+h-5uuc zTDyCIyPdqV-FrKEAAC7edY%1xh+hx$>pFhDzVv#lv)}6cO3>%;us(mM!TS|*6-&kX zQ)`}O{1mV~;!OhEB)Q%Yz_zQpi?MjrJ3<{rga3QH$H?;-c|!Q#Sbbvvf6>Z4N?jTM z4su*yy1riUro7kFbJu&1dquwAWH9am#*F_Id2T4(&=a1I0M8TNlhpNO0-oK~-Hh^6 z2G0!!&(mIsJf#FYW7V+$o*PIVFO74(v2-KXn@TrP>NDQEc;j8wq4U|&9#Z#~_Hvyl zO>n)rbTijmO1Bu4TMf$pLCUSATkE@c_n5bpcehs4bGMOtdv(Y5RCSMjdGCHXU%HjF zJ4$!hyI1pW*560UouxbLyS$WFp1*71&84@b)zinlt10Jdp1!sEy6q_-xs&^SrG579 zc6;|(QtmF@T|e$+gYmNYlS^e&r_z-D!(Qc7itnGR=hCVAX7J=5Ai2AGZFT2N=3<67 zZ=j|V-gau*ZcqB>?sZQCsP8tY@3uO(Se<`Jo%faQvp1)`ExfsfH}50$ZPgvs{WHv8 zYwvyb=6&|&X5P&C*OTW!=|KH9($bzwdxH8sZ!@KArWE0PXZ;7Plmk}ECM#u*JO@h$ z>o@Xd)!W3Io2s{{he)TVs@Fvjq~;FV+Xs1asC0=*QKw8%l5Y7QNHtdeHN|Cf^Sk6mK#p{sZMaTza@(uMT{q&%fSl zc}wJY2QWSBodKpZ)zsWO8M8-7IqSWNls8o$@s?lC^3Fal<*h)^CQFkGkCq;VzPu-T zdo_4ln5TEob-rs5i~&KP?*qY+(h+9Qd%ZF0K2kkW`W}0Jtv&xJ&mSv2#;6~mobUCn z1%_*@51-GTPnRCEd^cOZFO%L(TLCXGMbr6`Rs#D&MYH2226UH8`K2tqfewX+C zT#s3uAEeH_ubDy4nM~>3^*rC{(!0GM@ZLa8k4KQ@q5l1IReCKwf4p?u zzWYjj-pk&Hc%$O|nfDRzcIau@-rZ?6e1dmRlumG+E=@x{RKk~l^#{F=0;~GQ3+UH0 zsXyfHB$YQyC+d5=k9i-b+$!mx@IFcUC&{hxm?7ndUC!!^jpd0BDyem#-ybFSY-yJ3 z$`;ebRd2MtY&&S1-($=Ifv9fKw||zyDQQ^I7jlY2S~M zE2QQN)dlY_c{e_v0!!xW^BwPLg(&!W-n-EAy&JuYMs?@wcaY~Vdp}0mKStSg`mRCB z=e!>$<;O|cT5Zt#Kk;&3X|cK(P~v%m`zL|BU?YFJbef!g$*)iF?&rOq;@zKOgqr;N zg7=gB`pIgOl27yduXsPr@1M5czLhgz<*5CwQmZ~np1!Fdxc8t{LBJm*U1>L2L=;V)Ct|K-PIf@2el|@%C!<4c_1P3I_N4to~p2euc7rB~kzPRlhH&|9w{Kpq2V_ zR3$A%Bcg z|Dm_nN`2l+{YT!fQtGcJN_~Iz{XwbETdAVZL%yik2TC8{`ak61*st=|4{X1?_YWw ztc@S`e#iS)P{WVZ-`i2D+B)oigZF=T?fazuYw!0c_4g8W{b2P6kuUy@wfe)}?+2xh zk@w$ve?Z+o^oGed4DI?M8`T>a)eW`=eysGd`Y2q}4(|^? zlkxt@yW#m<>0_4Xb(ZG|%KmuinY#WD<+;xCtdQpurBBqKpym(r z|L?qi|CwC%llI>~_rpB>6rY>;{D|>LpZ3JN{D`i?=)72f8_NSle z^ZuiE-Shdz-u<;~SiTsL{?qp9&f|E6TX$!})4j%WQ0U*GKK;-{66 zX%D@{wJIk_+Hjz`T%UeOMYS4!@~55-9BTNDrBaB9iuhg3}4S%8C zH)H*jf2iJ49}d@esFFR^*dO#>yMMBJ#(JvIprrXm#cLOi_>ER$x-s7#@+rPDZ|}AH zeHu_(sJ5>PZpzaqtJ9~f7jsi|LfareFkh=Q-R;|#D!$j=F!l72!{tK{9zOJrhbG_N z?wd4_3zLn^e5!%<8z2l^ENK6)GF-BxwMyFO`pp96K8j>a=$%wf9lxixy)+%LV7jhr7mXD zsna{2Osxu0Gn4Isa=AI*Xf?}a5Hn{zm0fHsj%V9hZ@N_)P)d2avAA5yDc?_}{I^oq zw^}zZ`n6{nn43Y|n`avHjArxZPu;v&Tijc#H(QnY`Mq~8R!-D!z4g@1v=5ZtOP5yb&03@03{uK*%EaPwd!$@% z1mFs!$JKOGz@!WOkEBP_{@tWat8etD{u$t7ee`8+Rx`~_>Zeb`G=Da8KK&eh(n_By z_y=2=)s&YxpYd;8P0eMSZ|Tg{$|;rJ&2X3IJG+`)&78{mUy9!QgqQVl&r|kX_I?|O zR-Y6yq@?wmcXF#aum4oe|AgLM&23Aa>hnM06^=4;-hh>t^MAq{tY^F-;2Sn5H>_s4 zA6d0V#iTI7AEX-93$Oopo*gHtX?s4Ie)<8zcxa~qdgx(y^v)9G|nlP>GPQ8g*4kLl#! z$Cv*$T{KG)&<)%p0M0J@_tkk|z~xdaZ&(+&Ft;rklPkHYMx$8DEmZ2urR+@g%*tqT zpf&C*19ulI)2$^2cV%c#k*dIps#hG(JIZueL)z{yFI4Y^8I@Nr=6Xz z*4x?U(!zLOI}4_?2jg)o<*Ga_T zMczNa^LE~mk@kl2+a1n)jf6^Ye6N zdB$%nB+&U;Dr^dgQ|V0Fe~j<25h6GpjZiM5K%2NpHev>P;~LOs4e;Md2LBOVCUtp~ z%Xr%V9^H51lU4X0(hZYR>5lrcq+5NPxe4n#pJ{9oZ5j^HH`i5TyHIX|GPTP5C2D+c zqDBpv{#08&_-+chwdz1oM_Q>lR-@U}OR2Mut!fo|80wjU@-dbC{i~T5Q>Xg<{VixA zQ-1%8sSCN)jMU1lKBf5ENXfsDLaChbvdxBC(-7|gIWy`vQ}dgUuEoVFl#{7k9GkD6txY#( z{mSCW+O*3&K2dytNme~uSpf0(?HjaLMLZ+?Q0d0Sjg3w1DZUfp^32ga#i?WC#Kn1-0|)n!0Bg*UsB|>^Z8@XH)=Aq0f4@v_W6M3Xxl~iyMJZ*xG`lDn zc2H~?Mh|9-FFPsyAV~o}CuF}WZ-%mnZ3fpJy431$ITd)`+2YJneYzzEq}V!HX%&sx zEc(W_xz$c%et0b!6pNw{Do&-;7R19A!y033DHgrzOtIN&ERKyA_ud!f*caiG$}blE zN{t2g@Y(6=qM#YuU2hc6RF-#-$3@wytsd9vTdO}?nXeg^H(Dn_?!`v4X6;}pn3$c| zQ#^j$P%;GR*zx00m1k&UULJ+tOeFv!A8yDB;uAE4o<88^`~!rjMxlw10%!w z4U-}wlbKw(F{};-LX3RzM76loWHz3uwN3(exO|R{Pk30wt4`Cj-+Bqp0;(yP%{xA{WUU++FbK zo5F-(4fM4r^q#Wf2jVH~Wl%s2A)<5r>Y`sR|1zb8ICOPfHAv*1N4TR#MGVOR@t50TK$A^I;Q2GyD{REE`R=}Ec#56IQjI-G)pj-*$%bhISOHaXtsSIFd_&_zS! zFX|$eH&J|yGg{HV#K(A@g78Htl_wdD1I2)22+1D!&}{ij$Rn)=w8V%iEfpa}uwW=6 zlH;gcbd9NlU)_u3P@C0~&4Mcl-LH9GwJzFJDTb3Irbtm4?k2fP$F#C5lYTyO;HmP_ zhf0U{6%E;n_ZHuZgt{Jp$v28O-CMl1SbSsASZWpr(R#o=vD`s5FIl^hkm8{R8)dfK zbkqMe08c&i$l*sHp9-LT20`u^Am4gPfL$dIRGO`zqJ}>fS2=#Ab*i4%(A+7OBU__b z!U8o)(J);LB_buu6-(Ws-#{R3)v8Ta0#px;Y2jw{mksWk;)`SQ5v=&59;AbvF0+4t zpyXu(!FRv0kJv&yUnmu14?)_1Y$Es`d;t-(G{h9Ws-1UprSf&C%xggE*MPV@rqFI72{e^>MKRASBy>3j0UYB`69dJ@?-~1hm@t>!N*idqUYsQDCDPo z$$0@KZf9DH?cAv|-WtJ|f@}3!t6ctfDn{j{(kmMsRv9y*XB~A)9ehZcB{@n)lWvKX z1l9@J=`OTV8P*ZBQ*$|wG?}8X#$>d{XtjKqwMBAL$J0Ki(K6Wcli$>mxw2#3#b<&w z->)jqbqVflX301H5klLX_G^m}Hdf@Ey3M-6iKwS}%`GEpL%2}+O6|b~+2Zo2JZy?b zOrZb}d%u~_%BHA~q7^Dq-brkZmfHz_*mBEat8TfNH5DAcPG$V-R$&7WB|h!3#OZcjVQmL zeY0{%$jwfEEB(y3(#O!x^fi|l3%6>`L`fd{h&rF~Ey^{!1#n3;G@*NXo? z1&jE=6yOi0wCGS+p1e5tUf3okOj3(pR@S^sw2p zF8`&><#He8ubngQSu|(Vg%J$0tYglkrIc%qv>0r`VcmGW?pD)t*;AH^CS3Yb!RAET zC0=chpml#pg8V`ig{bG|c+hKoCO;)uA>*|2<#P3Oxm*ya;y%@B$f@b!^vZ^C+%1Qy z8t&$>JYI18`Lgbe*Af!BL3}}XALN4G$_>_Zb$&h^FpU}$_5I3ZOuSm~&-pY*xfDin znOtTtTPPIr!+Dr9Jq;C6L)=F=s6mWW;bZ(*9ux~*mes|!9D21@W+roL(BI`ODVz<3 z=GAzn@?YqE6F0po3TN#FiDE>;TnDq)=wO1J7#-1INDBh6l>x(qn)+nJOAw!!+uKvD z)Gr%FNmh=ziVheN?N!nBExQ z_bT90p;4c{;x(Hci3m>`epF7giVP(bI)1!dwqYxmj~_2eja@sj)I!o|@My|ks*>73 z-xrr6Y2w5jymnL=c~KWO&O|&ZEVbW|KqIwDJfKtK*%CxFsE$3+ur}lVoz4RN@k|%R z@QX~bZ4tTHl7U!k%H`Kl)QY6I)$L+HN;7VueS!y2@tlOG?i${}Gi)M5+Bwb7=uhNw zKOa-S$NX|naeKHN?2Nun+jd`bv4Lof@B}ZjR4uYl7AwL1yfY9$%b*Qrp0mDPvS6q+#Ugw?Tf=HJ z-c!01HSGZ)DxiI+yk$}_|I8hdOz()Ne~_ z9ZizLwsFY@QLyWlJ8T6(=5+c{OH9zD9zccgL%WV87Nz781Ki!R?4_WI#9Xu(wV7p& zSu~W<2Adk`HtraDK$Hm zg9p*pB1CLXbU?HuMUt@QG_SeEP@Q3Xd3w^iHLUfVYSjj9cV|n|XeK)Q>bS1nqN;Qg zsv*7Hte&3-l(S#y*A`*?pPv#02PA2;LJd-LUF9(7?m zH`lOZfiKlux%_sWP;OMV|Q8l$KY8=$I zSyR(u3dA<^mh$1qJ}fZhkOgI=BhbvyM`boY!3E4@Uk2sMjji;Bj0cXQCCFmjnZxqn zh89X=+pNr+{-CdUPb-gFrXL;?CY*QsE);Z+UM|xbpp>aqr)lUzzc7e}ou{qkvwJM( z(8UxM4%eN_wuV=;tqoW>yzlg4YXnslgvno2&eMxerabBzFH~-%gG``as4di{#lI~y zU@X|;!#t~)Xd4(E@*lzeA^XPjjoI3CM6Ab*rSKY_J5a7Okk~b^P)Wt?EP-8HJeM-=FNBB za%(JtO&WD}BsSB|R!&T}2W+3d(U@&O zwE4i)_(m;x&g7Ck)@*Ybi%#vX&B&aN`pQl{*fer4wHlTXeg!R!5w+uBTYEGftdot# zDV}M@Vslkq@Ea655QD)`qr`DQ)n%kt=%S6RhOFhns6TzD58pmw6EVCQ(fu% z`Ix0kER$*v2LqoJmK&PpeZCCujH*StD@|y9WDnJp@=p`n%r>{QGE(=gW^BzNtLYzQ+A39qF3;xnY{Q?mvfD!m%x?F2GER0%)Zx%_4I|?-tgBkX+c{a}_TpkR zuu>40|BhPiwqBh^(CnS*Q+wJ&u(YlEpQ7*t@s7t-?f)eeDby%ra~W(R2GEr`bLV!S zAs#GRXl>`zXw8nkR&VX+V}`-K`nt-(ZM$Zuaq%)P$aB~{1P08&bimhQ**OY;Wb5hQ zSGj_%gA3`oRBBFDq+?~9{i`8vuwq`dJKFuI=lLvn=yo4`nR@ttjSHxx?rdKZ*hdB<#-5QVgHZ|i9>ccup)Pp+ALY&86r_e> znS$8G>w7~Rk_<H0L4hE_WY`# zDsTg#!7yMXM?2L)X8qwWa5v2-`qQKRd@eWtcaX>Gyu$e}6AU;1Wfz*6Lrv5@|NH#U zsZcBV$94BkU4D{FFw6bVE1{RDqG|d^QTIEQ|J4cSg;zbz1gQi8Jq96U1KoSBE{M&9aJqoX|yR={B!y_Qw}dQ+sK%s^r6B6=9(&%knwI zCy*m$yzTbuo0qS>&+EzB$b~_pRLnZSO<7%*#{thyi2mm9Fh*w z$qlEs$hO+c%H{lA_UwI56>=eektLt|th?K)_lojOxzO+BE~cB4c&YRuA5G#hR9Gbi zd+W(3Q>V8CK0{a*{7?Q^uxWjOWn_%-dTdD5}ai240{ zdKm+@Gu6r|zdB=fjW~Ir$a9WZo8|Hmx?M%77+RP^QdzbfV$3K>i<)Z3y`mK?sifXR zs;{vW+bzDne1gq5<^QY_*=lY1ReY*!3)=UT+ZMZJ-5GBt>~C)^KeA+Qb9lH(0)m$} z2MQbU@c{&dYRmsidPg&+-H*he{it?M-X;D&P+IO(6=7l!?KW<0GJHjZ@jMt^Tk!jo zz1hwQy7o|_2Vp#U(uIQbB{f97RJNBVgpyj2W%{=nbj*O1MLzldO=$U5+;25(-?mBt}#s>^LpYC>#Dd1;g)4~5L zZ-6iN@#X)P?vvBYX4XMc52_h_0B~iGMn8PNjQ9NsrbJoxlL_l}iF)#=fj`btm9;ck zba<~C+S}JH@jzH_D($z)8g-UBN${B1v4tC_dYnu9n_8JpL+9d=0B@6WrxP+;HMuWB zU(G7wS18798V1&#Vm#XUQ)f)d=p?S-IPPvTEP97P)VN8Z<7@YST0g=+0jj?%QKD=p zhoC-^)Sb9~4-n%C%4(%vgs$Kb2k+_-!@s_jc@Yf?NRlD62aN8E&~E?XR^JP$7t%8s z6DJC-e2hf?!^+j_N2^kJ(X=Y#`AJ`0@W52m%c?oTEomIVty_d!FT&X2wK5^ogc!?) zQ;R5k-7{HybYflBKTHY!KhCHT4M&%zPj*0pH!KT7jV-)b+tkaI!fk({k!#G>;Q}IsnX{W- zV*gY&&Q8Nt91BYDmZnebb!p>!tbckqBE_vfw6+1VIJv@hI%k*SEu9;RG}j}-5`;|^=L2hFO@ z_d1)UW&3C@UvIBV^=W5C?mFS%U3dz+N3p3Lh?p2kNX?F)?MF7w zv0awW7-~*A&|;z#flxq!!~`ZHQ)AXscjaQ{w3Z^Y(|F&8evpmG!W=A(Y~In zvNwDM2oE#XiSy6kfOaM5Fts+5hAU|tWaKiY+gfz=*~rHh9{78yLPlFCLZnx3WuW`; z`DW6BAH+jb+VPLu8hHdI*U7t!HN2TIF0(!k-G$7=K^&6nA>@=;;N)xN>8mfc`cb^~#XjQAzwGs&%beY*npWZIDVuOF{`2th z1&l#6r|0l|%;7E0@2#>39(4Ke4$oPi541>;w|Q$o-*~8hjr>D;R^QYbk_8PM97xv(L!su`YK*%T?$F}%PnlKp~}Yo6({h^Q_sww70JjIv^~(FpbKhULxT!V)ht zddxmBy<@HKqa%%v+`$cN{U)vT@}qf?*aV%cd0^vnnv5a)_%_|+Ah6J!O^oY7Qa>85 zTCk6M6Ju&CLF^~fW99AuPh3`0pCouPHPt3(CwN&WPns@CEK?Fj2b}S95rgsZ7(#RF zcAL%zJNq$&+;zJ3BfM?cmyu_yNMN|{QC!K%h-76VO0f}Hzoeyl4W0M+NMaLPjcE5- z%n&!Nrb%$K%$OIo&woIdU(-b!@lM2ggu7toweyPtso74~toh8p-%&nwfIQ*4M&g6& z4$b2fj-K*a%CJ+BOK)LPZsL0rtWGAqBeR)nA-gHPvLkE|6Sb?TXapsg7x)-a`Wn*C zZ0Z~q;V`NxMB<$qMeehw^5=5(;ow(JzgBbp9RzH^lo{{EAV2XZN7y)op`9b%CFP{f z^__iCzYv-4JC|?uujVO36ZEOo{M>-bYYk#Wn|HtGhR*e`_L*7oM<^Q+iEtD7x#4qt zr=LQY){}z&`PJ;XzWPjyKo7V86!>OS@}=}D3^TC`)6GFIcVPtfI&J=}g;nZ4uT9AT zr4wN?5Ao;=(gvxeusQ%)7+CE$;xNc{=(GJ+b03?N8&%7Tsq(OTDGUW6q)vaj&zl^NDDT#wyoyRV*&3hH9nHo#%XIi zHSRF=|J9TJKVpbi-f+mRAhkMHS*#l7fV()4yLY&Qx^lQzmOx?QCKwiHH?toYqESq}*v9=&WVe$}K(1i#LhA566aWS5pT!DE%7acC@yjud z=%8ZeUJ~l}%jL^aFf-B()QwUr9i8&C$j}V7UkM z=3-A&k(JHk#++#TS*r$Y6l37OkD|@;!(^Z}9cV;$3wa!PkXWWeH+Uis5qKwh5!GLd z!HcR84cEebHJ|2x9J&qA|kVQmpdt$CJZeL!>WY^%jgkxu2GwD592rEokb>O_-% zPT#A9=`m{XGb-PC!9Kgu|d62-z&x+!~Q^RBRl%tEyNlN?8HhHqVd@H%C6)ukZ2ZH!;p8VIEYMB zI5mEiQ>JB6e>p=KiTD1G=<;b@KBLPaUD~=F(8V+^CU*ZN{j@c%KTzbEWNVlSH~Eqt z|CTPlq04V_36)3DWI$QDD50RN-L-!rth=MAa^6A4%$s)@OtHXLWY{CgiJhp;G?ObE6Wi7ks8(0*42ww&R|hc+LIH%TsXfJ6X6X2} z){|}v?2EL(sHrR(LItVy;xl?;y{Hx5G^vgqsOYC@SB(?+n0`L3%Qv{7h^sF{ zLyEy<=rYo^NaHe`*ANe`2}sQ)nnPsM{Fyof+Q9j;6O{hhLB0HOr1D+L}>& zYjb*Arh|Fus`gU;LZ&@3ZL}fp0N!Y*MVX`i@2MewuFEBiu|z&AYL)Rtug}q*TxK{w zvIFe?0?*K#4kz{IzF6&ujA{|#_qzL^rr?_;e zp*9%Pq97mxrJUU>5J(|VOc5SkiYZGcOgi@%KgA46>V#YHh+*f-iw}h{v!H6u z1j95D;oM7z@wQDB>`pZs5l^v>RBzi=MA}1%MI<%U1d-0d7@2@eNmxNm4_J#+sjK)F zldJJ*o@9hp`?Yv9hg&Ha%$zZt_pIjijUYgpByzcatOl%Ib02Jq$&2+rRzx1fCWE;h zI6JwTVR?Gs+~De6DZa{lR z_N3td#A@!`K>azSPoAF};+w_srIeURV{xzd`YsIHh~#DS=b(he9acIlt{@)>SlkV* z4LElz1xUrF!aO1m6Ekh_+z1d1tq#NT4zG@I-LSfW>qx-<4#4DR&TX{58sM!G)_E-N zt&MY|rwaPL+D}9`vA5jKusm-?-i9sSn5>PI4FtvRtpB6rx+n?8fp zA#(QBFuUl@=h)}e(vO=e0r_9 z2Uq)m>s!>b#p*GJ|9qNOr+B&*hItg%*U|F!)q*gA0P#ClH}ZQ&eTTyXQtpDqzLvCW z`QFL*&erQzM?Dv)-J|A=Kh?T!b@amPwLge(B!~r9@uKQ@!|EtZ#kS5ZA@NzSQC1c= z+>5Q-teG$3gET+Zt>remsva!xm52lfE-MmTLL49#WOL#*ivvlf+oB{vjcr|uiQhq5 zJ{EUDM3U7bHtqR-CA_`=Z+W3tKaXFok{!J0v@}?~qRqnLx{FKCI_5wNl>bF80l)75 zffBliy4rPPRAt)o8(XpR>O_lyb zO``+F+84=sxzT!aTpw9K#T&MP9=g_BpLKKu`5jS^%RZxULj(wBa$c&A?i8@VB7c{c z91nz-@$7^l%p?jWbx3Jr8J#gpm63659sn= zb$LOTU*&>OWK8Xcxo`Iw``#Xqt7wy$zf~7>?elt;cZSXWU(t`j*c!tBQxcraBQe?k zPrCdWmr?<9V+%f2+8}n7P-#v)u+Rd~tM`*BBwNO=sihm#s zXbsGn!ms(@YIbf2yP1q%=We*Q;Z(l)ARI=P91_&uM{1bDs;U^Ub64qY__haIo4kDM zYN_TzrPt{P5$88kzuP@9t`#0_KoDb_^VQWH&#p0b*q{^iJLaI!*B0g*xnU0Oa&z!h zVX-JfRd!}FjiRC?tkt;$TPrpTwE1gO{&Ga(NHo{7E92cmV&YCOjg`}Xf1AYGsQqet zo{uSiB!tpuYm`4IYH}!Qu7_hZl`o2#z-}Q@)DUg5Ls9dt4n<8VP}C5YGPJNlX`|6b z0p#xs6gB%~=hhms6jVR{J`^?k0!7UPiW)O`cjNa8R3RIj0RIh*&WpO(U>Q9!3KnZT zOh;l%%QuzJ#`9OWyF!(RFY&pevAv!fr|P(jYU8HMjefUUV|HMva9CZo#r%`SEyHiN3wd^i zQCIsj!7pTdl-D!n$ris`Kpp&Uy`x=W+vaiaT5kXICUvHppYQS31+89^NiVQtEJUG% zL6y**K0egpfR)f6e_LFy+ywu!#v~h;ZS(wpzk+&v$Wf3V0laQKvy3}U>FG4i&*`V( z+HvkeToVZiaLqBPhGfd|qLA!5Ze-Kv+_pqkHfN<2JDrZ zNBndGz>!W11;}je`duYNFt+=#K(pxF27SWb!h(!lP>*Wt zQ#tKDZDQ-fSy+tNy#nxOxRXJtWHVhiV|yWYF03%@KSPcTIaao>i!$SVllog{8$)uT z?dv3B6I;*yg&qi%F13Lnj{e^Pf+-mS4Z?bbz#0DeOxEYD2}A+eXuDbd~?{Xan- zx0HCgyHgjFfQ^od%6FG9z`mmL3)~cTx;@@#&1U5?hER|<$GE5;O(PDQG?!^!*Fyir zNkc@IHTDnouuPvy7hAc5mmk5~saR2jFmuZaj6|%Dx@|#-@Svbf1pBVVLC2;sEOFG+7#cEtO8dEIy2N4&kCCm(z^RU&!wHk1HsP&MPgQ1 z$5@{T`eD_hsYhH4G|Z8-B%Wb_k3oMQH$-nYH6da-4wQjduIXW7c@QO)fJewBgFbN= z^&gxxYsVHOh2%AY>>a{rJK+v%s31~HWDvEU5!M5Eto{g)bqk&^lhz)5Lec+hlEC{L zM!clFooIo1hZ7TZyhpRBz7Qv+GmAE(qu&J2=MT_*5u#*ysIfGXY6{mF7^~HB82urxSgq0 z=e_2=lT7D5#hdpOZ@kg@+l^y~+1KKH!Fg-HkXZ!^Ev)_TB4st5Xg>-%+OKJ1;lyZv zR+@GHKGM3MEF%XKqyz>BXBJ|Vbd@5DH2MY+*_zm(v z(a|ks{BKz8L)6YBPt-n~sGXe+8SY9n_P>RlM83|MbJ!dRstvX>jL2N~e7crC*T1~8 zRk$$VVH7<#cwq<&iP4K0Y#pw;N5O=50PnDyCcOV}a-v||obxteXTbsPFH85m`PJb| z2|Fm}lSUUKIGl*&WV1U;+byz;(=CyXya?T7A@5;mR^^}{LOw4r#*Dtaa;Hzt<8eK| z^7bB>TjZ!aEB#i^d2nYoMn~)5sukk$zGUqyZ|hZ1t8$8YZ>BxBX_>jbS2@ihacnui zt$0RpCe5RWC^HUyS8k76>Qb(to%qg2gvUWp#XG9%7b`{0BOS5P-BHXP0ihXt0s}%b zzceZ=m+J+rtJ%afE=7})#b}sGf-8Yd;5U=hF5t^rXGCyn)?Itk{Xw_m7yhJs5$*Rn!YQ3T>w&6^DTF`B&vu~|V1qxZpLy3k?M!`5p#Bj<5<3u7 z(Rpqc4cSj^Aq~l4&F8|?8c7$k@~f7JJj^np?>rj-I4ERxB1Gpi{#Ghp zx%*0J58hm&IQJ?}ae@>X1rj9s69v|vnV3cbZG0Nq06~-b&0i&n7@IQ6gLYZ#B z*M#O<=J~X`Qwu90eztawoGt2h3PK2xqEPhnF^E1x!O+k&)QZ)no?%TvH+~N$%|Iy? z91#n!$;w{Lo$ITKQe`pO&eqU~pJP|{CFjI$c7Ch<7xIe5hSIQKp2xUU=sIxrL9=b! zk8N9?xCVoB17QiW&sr@+Y3#LLG@Gr}fhdijNG|QPhgF;2?>DQiK`7k)Xa9Ow=dsmy zWzG$q8%EiQf7Lnc&sxLK)4zc3>G#O$i2oO>Bi`WlR7ai>vp*XKhK;LGY2qz>i8q~9 z+Ag4oQ*+dJM@PQIQ)urPG`j!7RkGm1(oMNfSj#r5)cT;c$nLRC>nm?!&zTj6yUpCO zd%)c_Se{`;C#Q_&52Ft4D{oyDdxJUowG5VvjPUokOHjG7-IGw_-Fu4fnYm?Ov2_bB zs<-le>mIoeo*TcrSjA$s*h(07YraN&q!2(1nr+xhAzp*UIJSkZ)N!jqQhat;VA4O7 zI1@DK8kV)l0_}9&Kf~K=w4a;|Dq3eJgNjcz49%xkZd`+*-F9WsYw}(S>3><_9QY~n zr}T!M(1v|PkParNWKC_eoH&cyj5Zi^65E6rtK%%D`=oenItAf><6TqywfpgUE#G<9 zExvTX{_AwPO_y7A`I;`b>he!?(Qpu<&Tp)6crNDgI{?AIR+qziypy}}QO6?on98Mo zY>L%VGkY&>Y@Del19_A-bTquQp`*Rd5PKvJTcKVkZA|>uP?xSsBsf!)jyy8eE?wPO zv2`b7`F@%Z4yiHqKSjcfhH;XcRR3mFmM+X48?cBxvdtz9n`@`?bZSg-hy_w)OoDwj zIY+VX*7qRqXaiTj*tYFhZbA-rJdL^26lWw>sL?HcBG*o>DR_*BPAE9PUunj)28*Ox z;r2d7mQM(LlS$;r{}vjcyIANyU*_4SA<;dUgrBYzU?*c zch5E&-tKeqm4Ead9d(}QEMSGqwsH<_O zd!!$VTHTqugD8<-4oq=b9W;uk5p7K1K{UvrXA<~*2GtVGp%4%5J~6|bURblg<~z=K5^GgOxcq)xjE8q^A(Cf3ktAiyNI#ehOgc>@n-Aq+b3?jDS9JX z&Y^F{zaHYdIl{$h9O2|JErF9rS9IXdAv?ZYT0LSWL}8-@aitjbrfW@%QV#$_9Qh)` zZEjq%AE?bQTypZV$;s)xHXW01>wcNzf8898nxtgH5NXPo#4x7vEpWxX_Z7vyubehpp60WAzqbHO`m>ggkg@4x?{LsNEllvPjsOuUY`1!Na# zzY?-BsiCOf#dnkJ6k6J`j5NLI%hC0+y)PRNWN*d+3pG+&eXYE0v+uJUcv@_Sb0ilG zSPQQh^7*YnQwoye&R>SJl+?g4c=eOg6tAW(u(|InNLu)8@YXL{3Bz-WgZzt>K&VkX zHhPut1(nbmRulpSa@FY`L>0&DgE#+2P>Nh1{|BWM)-B~fSScGXjJB>~Bi~9<%J{&_ zy+=75X0cg3;Bc(!?I}JM3i6^ElZ{sN+l2E<5XeKLKH>Ihh0z_|oF&0F!MAV&uezRh zEjGOjer?gk3T}pb^#6sox<~aOY5yu5ReTpLt8G3I%q<$O1M{^?(;#+ZVH~Y7!N&i7MO|sz$&cvHCK9LBE-shFYxpH4 zN|k4AFsE0kv5BWcWIi1@sk5v&YS=H+AKyd1(gqtaCcN_>jCeRV_tbM=7rbNSRoDV~ z|H;u)+5s6lZwc;3;=7DN|A1s;`|IN>-p}acgWM>Jnu~=fD+Pc z(sD0nF;&Up$%F39v*WE-a~HBs+6CMDD=$*`V|G}zW9?3|UbuitkXh%7nPd*dYl(B3 zfdRACxQQGm>&#SY90(Isxv69a3+R-t4|Zj941Y%eJlbF z@fmeC3``>HYqR)hATvF~DW+NjB0|c>VP$E)6`bM1M70xNn5A_)LR9RgW^EAB9If55 z&R?B}LpIhmDra|uK+kaSy5g6xAny)mIze%EOZBxoG5ame7}VWUyQ6Z(mg=;%S=?Q# zPtPxT)nF!@@@DsVM_S1<(yKG{jgA#}ElAXKn($6*uf zSk|~fJQ4G4EV~G!lNq$P2LmrbAnLFLD8{}4ThZdh7)KX~9jeH%R2<0+MR&A-hDXJ@ z082@U=HTHc4?K3bxOcB1?1?G@NsaylwD9~!3iF7OPxL@eai^+jLfwOXOob&lyJzFV z!@*r{EYZ{|N1(F_SYsE^(BLFzgXw$>0`9B8>e=cvw~C%WK2g-DML;%T9Z+zfZAP(5 zg;qDyuEvQ*7Q3k)z?O{pw72+>wOrhE)X^X@a4ae;77LYFqZZ16MU!t9DjxmbP<$~p zJ*vGJ7VebGOx@xb9YPj5*_~&`i2x20cQ@nAMn zNGBCx&552x>#KMREfq)kn30`n!#0K5Fm38|YQoZPJr9*&r)(YTW-qq0aBXLCaJsM5 z$}U9_)l4qi5|Q99)Fq}W!$-gtTU%Z4P#az+zM;>5x9%gr{oSONaw?{~QoZ!2S}i37 zq>5T0N3m(m@jtDU@J~(FUsJ1Lr0q`Y><_};$S0?u!vWBAr`8_v?CE%Cbl&0d&ZYq$ zWHlVoQI@I7JGeXs0l;;WfePq}sTPc!MbZbP$XLD@OVGHW27!Dq4-)GMQ<_+Fh{s%! zk8N!cUTU_ASuyW$O${TIyIb*MVr0dl_mdfVYETf!X^PD5RU>CCW%IRDBtaPc1ucN) z1Lv~DQ#Fp7rrj?9P@Uld-uX~Z?1Z&>cLo{b&T_5;+7n*q%qLkt@XV;D&HS*)7^|nl z!P2+zRNr>W0L(h(Ik4(Ga4f>9T<+6yF~ScrhZ3JdQ^c5~YL|%#+mI3kqnOMZD)y?0 z^xCT6J*RUuK1IQay@()OYFZf!VYWa&=n&7egUh_NM~FVijV!CB1sqAQZ0lkvB@T0$I1q|T&-CMdcFY*6*U2v=oC=L*HGbGLCL zcUmV)vlm5oZsnkX8PjR#kdHSp7#09p3Vo-tHymCcCLNFAq>*y@9)YIXv=zCsqgQ`O zY$5bnh_L$3@-grN6FHlK@sY@yf7sk#=ONS!V1DOxF!Fe2@`2FA$Po2K%5mLj&|c@y~ZM9Jq z(VtqopHGi7SQIH&bFzfp6>g;_%3*a?AlOBL)B$gRF&Z=+s$2vq4tRuTg41U42zZj( zw4@26l}`OHqLSdB4xg0;e#FL{ zTwauFu*K8)Q04C44tPq|9hC7c$&!L0SPGYdlBFzpAD}QlJRh+50V2cTn zMvGv4G!*4xOhg!7CHqwwL}>jDWk1J6o~pvL168HiT2dUjHKiFBAjPx_OAOonj46g% z`(iExUbO|=E-^|0kkk&vMK2zYT65gVD<-Eh7D)0^V~18&ap&(XPF5{ATlA)}_%rho zGC+dvJ&`EeGw~h5G(TW|xZZZmzHUEOy!YO?ZzXTXS%MrL%`tN~MMbxM>t?`&KMBP< z&0WLGM8n+0)2!csLk^~6V|UsP#v#6wAVuv9w<%1ju<_HP<1^U|wT(&Zu0^_x1v`4I zs~3W)HW6kR8$T97j%L}EAoikWW>+UB=W0g*y-Ro}isoXndL^LIKsIr#Z$}xbJp2oR z^X!eafJDicF3Q-Mh}MhpX>~Fqx?yfY1485aFweeWN|d6b+ofMXXA%!K;vnqZA>M|A zl4Ovu`gyB<+9lc&t|!)mtD=%wg=|wlS~SI8MQeJU9}(NiQDOnVm-1!y$)bcWq#1m| z^I>tPlLO@vhIQS3_Y0S_%^q61RzDUY_Ix#mMM~BVgX(iOg6PZp6vB_No?3Wu#+B*W z%Ht7;&TpxCva!U;CG>#do{0*O)%j|Lk?ok!(5V0$Ay>@yN+e2*Pnbz1r$a>?9KwnO z6s$24G|!d_bG~PdIiRk5S{LJ8)!)84$uH<))(6IDoz_pSe;B3OX#6e-rEAQ}8f~db z${0Z)iet=>CZF>`(@BTjyzcMu=4lO=x!B6phe= z9lB?7aPHazxIA8SM*U_sU_JX6N>iV>aBeYf#|SR_k9VkEF=+nu7gX**e_hLiFa>RVy8^Nh4AmYxOqv`8Q@ zBhO>!R2r70D)~1Mt!oqC zBleUyT<8}zde?YcNFySaw~gn+35Z*&o|#+FWq8AdJ) zG0cciC;FLr_gd*)lj5U-%Spis0kd*VPuQY<5$daNRKMA_gYKz|boh47{){8H)bw9@ z&et)%x_d(+&nLs)z#U;nca0$vnh?HZxhNp5+NZd|UOS65JUcYZJyrmsixgW3-`Fg& z0$@#zpUw8v1@>?B8?ju6QcElkgmP>eGmtLq!bQMV<&vHMthp;rI;!3)2yquOXf0b4 zd^jnK6P}YpFgvHGFJ!nFHea%MSM%+hB#Fj7@WFo{FFS!eI9=;$B^X^h&mD6=dfk_V zj-Qi;pq*2)!wg$2v`&~Mnkp)dL_Myb-B!H*?PUJ6AReYDr{o#NWqvb4{d%xZMv5zq z8t=NvbdnqPx@Gl_-6?y|Y33n(06TE$m$i~Je%cjRv>4xW_u>QWjqo?mwJ)c9UXJ@d z#sSMoQuu|AfHQDb`QRtZoQ!;TZ2@*Z5aI}!C-KA)vc@YjQ_Rpde)Y$AUdpr55D&C8 zpzn&7{IwHG1$|CEC5c-H9a$Do;zc4EA5<*sn&62Z!mS7U`F z@R;pdz#C56X&aI7H!-<#C|KXoX`58mB^J1CD>;k>Oo}n<5uz9~d>Rbgj1d!_&2J`OpGWKcZ3$bvcuVG4f$b z1D1A<81oo&`0n?)3{0(J#rMmsLvKK`GO)l>fZ`ycqvl|0<#;*Fhlmez8;H_CTm{@S zM^`g5)Qy5P#~GX{TwCnG>wxJ!7B#(_=}ofzftlc|V}5ZBIi$_jCo29c;e)e@c`15C zWVLwIKgAfh1x@re!6%E%5#0@822obN(T>t7DtBt>VmFF=X8y^>nbHgJmwjLo~HR zG&2VJE=qO_r{bE4{(Xoc#tR8bR!(DCzBz|2K3+&LZTfePZ?Z#>5U(BihRROK0xuygY|F@L-*63m^ zE+PKtVHe`>_XN5zFvL<|>!H_JxSY|Nq^U0M*QWf#+_;szi7k`D)?ZA+F*;8OMn;<` z_3N2%_-sL7?{d?fDL#sn%K7zb8QX-}z^4Ni=u4D{M~Jma9J@p2|E@d3Z4FerKZsFi z4Q5CULDklFpB<^Z7BN-8H`Q3D3KqA{5V+#RY)E;Z9;URpGU6Ew`BIb^!-tcAHwuwl!j$lUvjbt&LCn3%zTU4X;)( zTNlHPvK}1Qq zg9!e%8_MD-J}Y9rME;~gu=P*T2UzeWd}cUtN=%7)_aNlrYY^Q1?~aZh9x#TFe^L+C#KjH zdx~~0*q)+UweKmu(;0K_DLzocO@e#@!yS#K2v)Sf64S$3q?!?@G-m7#y0c({DS`=1 zuwA*v#X`c7a~K;7YJKL8+pwkw>fm=&sSqfUovjSZrdrp_69R4e89SfSkPTV|OKkL1AWCD`jwBnCM zc_!Hj4yaZX~J6nUeL9@!9ubf#UkziWwbX&Ki`4*?`+d?l3ye{xZcZe z;dUO~2wUt_5gTO1B3!0hXoBbDi7OEoWdzZg2M~Y>3#hGkC(uf`-Httnyc?KQ z(%1A?z6@A4skB`cuZC`ShD}&aGvulzS@L3;SoO92(P78n|}^T!Om__cah>_hZ5L40hKcE`bvqBfvdfoaBqc28nBWEN1%egfo`z5#Tc@~? zKt1yekW3}!z?c#!D1OhM0+$|e^jo+#>Hl4>;~Nv0Z=#TN!3l=~Lw^$kze0Am9rok8 z`=l*+4B5Cx+q-~Io zFO&PaAYbHBS&*wx#3$$6AJxl-fis=zv25zqL`THS<^h0wcUWd2?dx}MF<#q*n(nB? z(_xq@2?>=Octr$>==9j!`=?}n?d(`&T3~i5;>U>KF~vsif@hyBQi8gRl@pC;u?JGU`dhh1 zYmmg~h%?a2KFN3sM?#(EL!E?tH0fd zc{(h!kgojfYs4})0&A|X75UZ_=n{J16dn2hd z6fq%%h|07a+jSR)KS@lbH0|E!jVNsgl@&r8l@-(CSn7Nk z%m!-Qkj(b=)cCARYYzhEb1GO+N=f4@rFSn$Y1-LKv9+SJRAl4b*(q|$C3JW&*>e(n zzDt*{m@XSObgX(2bsT0K)@Vf|H2St_ML(Xvw_?mrXdGGAU%guNa*&34%qv%m{_rIs z4a*A^xSE*y)3-j~)=B#51Skn!DCo3slCB9}Xexv|0VWYDWZgM?2&i9FJ!bPW$mR|< zKd4fb&U*a?6;svaJ`#FQO#18Unfc$#?C>Y^*}XA<>o?Wix#bIJIuhXKNWyDl-?9P_#N^WY~{h4yr{0k3iN zmD+pI#?}m4xJr3_tX2rDX7rTz6y|HdM!)hslqQ>J$$#d5RB@-ni#cBF_xpC7AYqHw zWGNomQ*;^vF^h1{;p~^{C=&M%P)CB{?MM&mYC4y{3fy(z6O8OTeM%Swk6I&;gwBZ< za0x?aS2LsR^gS3y1H_S-6*g5B3#-|vEmSM8^D{8pfq|=}J-^YUNJ-VEGRFl#uBA#d z0fARcEQsA=*+Igt-7)(y-xP8d9e5UzWz9zR*HYzFxMP?$)knxer#tb$SmUPwsqp?|v zJH*HQ50Sijd6ftbwtj;%>_mgySwx=_D8WwLOWY^sg!RP-N&EYPhYyrlYM_QJIq4B$P0szve2JB%h*y)TMltcr;r2EU#1Ml`712}hI56|KN$a^zU_YiP4-#J11^C#}v2 zHfCmU&}AKVYgQx%+kzOaT^5&M*%Zg2?Hol|cn%e_sAbpMrq>ksgQ#io?ubljELJ(| zbOrWKabm+X{PuYrM~^t;_3Z3N(|1g_+wJ@k(MnH_XeWP>{zun}HxK<@v_! zER~GS?2A>9Fo4>w+IwGD(!L1NfH~T|d-nn3oAx#iAfV-6-ajsCLHK#DQ^@5)fR$)$<&Qu(}EL_}I+u_sp=IDLQnye6Dx~Hc(hx z^*XyLXbC)OYYC*DaR9^>cl4<;2N@08m@VbO{zP{s+ZXmU?mJ_I4V;;8RM#kOH8 zM=il#ujN-do??;}xhgT@3_ph_Fb~2q6yc`hwWzS}NdP4v)Cln+JA!pH)hN#Bf{Qyu z(-9jg(=7!AYT|WCK!@qhSUJnu{B8&=z^M^_h$*JYNg&nYUANw5)6zq)hkIp$hF`vy zg0{x;g-WhY%uXa^7m(mcgmT)&O2!Zh9-a`fM5^Iw_nx%gjrz`I=?oMX6w%S8$$U}w zPBvO{oP|&sWsM2GNkQSJW3-qlBs#kr&^TzGi_lVRA{8@~m6$rwrHeI1Nyk$aNbIje z)Q@Bpt@qlg3H`Z=jL)LK4tMlx`!esblSgSPxGEWt7`M3umheFZ?Bc6cK_)4qzO z9x|WU>mwHMbIN0aRE4{CPPCuD4rCJ7z$8#t=}+I$7;WK)bz8qLBW>&KbS$S%bY@$}()XQI=0Bl}&7pf}RKi(W6Uiw|UeKLsO)TVvnfqR+%#Z1E z2_s)gNB>p=of-M=&FPrq+;DEoCJcO0tq=hto6Ag-Df&}K>92W`ODNk_v;Jl$+tu@Y z_p^~C*)BIXP#R3cdKz-F9x|L$b#5T?=K!+XNOhx&_JkBTTFo|(2Qi;wIc}uAt$ZjJ z90HEq*(pqiAn7~&GXXqHH*txdgrZ6#4zHa0yY1cU))preI|atdL(P zf8oFIhV|eBw|i&-dD|^NvK>+QnU^@uoOy&#kE|gS-N!mku7m~B17|{>^?f#H%Y^?v z-s~C3M+R95Pg2Uo5u)R4Q8$M&7GB@KjfT?3^StF|k&(ND{G3r6H9K$~yyFt>b2P7) z7vcBuGM*xa$5w%Lvqki=zD`)Bgdjx3)>G|n>RhIOFGX`lfk2$gr6SUFgOccm7kIrE zb^|-Nmm21P8q=NjCsfq^t0!O!S6FdC&%%oJt;!Ga362B_+?44BMT#;mE;|{KS`BfZ zGV8O83!!g!U}I+r;yE}Wv&6%DvIB`i6>&_YL`|TLGJEZ5DJYz3hHV0;_FV#}A`X|J z;XN>mYMxd#ml(Qxc)qCG42LrK^zXjH`Z`tyy=^^t9XDF(h=V2uV~05b3$HBtSxi$5 z#Z|dOdy(KvEEqBrbWGF{n(*$b{5Kwc#zzLa#aF0Ik=QXI)6xx;4SGn=au zD>o-P@Nr6sR=N zwwj_fE>C1wYSx4n;sM_5Z8dl($oxzaYs^IUh%<3b7z_5+c359TipW@kXGqkqYlbSZ zsxc&~kA|4Bp6Q=BsF1;P>xax!71{v1A&W9dX!`{8wDmh{sQQ;9h!sMyt7a1+6j-o> z=B$fPGLXDnFKIda@kE_Fd(;`sBJFCfG2Jo(t3q7Q+r*4#=i`jgMU}1vhM9qX z4?7rTn=oM&zP9Q7>j{|FPUj9o!j1ud%`4S!Br5KZ zQj_DCSgzI_dS;}gml5N-OW2bTlfR{Eg`|by(2|j*Oiy}~8M(;BWTuDH%iEVYbmBYC zOZ-lvx16D8RBwXZ=A6F$1TecOv$mx7qO?!Z;C~sGiPMXIN8_upm3(azy2y*Ut zvB$IO-iX^}EA9C4DPFVI!#msVk`D7)Btm)xpSJp}&XH2Vh%k1(bIfTTh_=l+88TqV ziR>ze9X2`TfqI4mGXl9OfU#npFqrHmxa3X{Dm8d)+wgO?5jR@x^$Jl^&j8MiIwGP{ zY*nXE)@!Gig1CzK*JVn-s z*?T;QW?}q^*{VZOwAXuv?t8q+&LtKdoj}UO(bFjhz*WJQc6kNJqk))iV16reM)o|T zvP^8@l!YLaJEIykSd=Q8Hu%LiHSCtD-obH8(4=BC|}2OV7Q5{-HOx* z?=rv*D|RJ@YVSbfQ`~wh=Z&09wq|xGKOux+F0x${C^w z1{z6}w0J_2>4*fJIJz*2@amj-B4Gpw;6@^}oKZUs6A`Tdn?6r8@^L!>n(AbKkeCFm z>O5zvYhv{};a1E9H|(f*F5QM@i#vIvJ2SI` zBgwFpF^H@WK?0p%5YEU50)|>pTOMqD*(^`?CDt>s6#*1>9m!N%#{j8ws>XnLpL1Y! zj;ChUaIDAaiEk|KibJ>Tau66&MX(ivznTgU4UkoV`I`19Qu*I#<07O#ew?fz0!?)D z!r}1o{0#9)5#b;lJJ}zogV8R6nhw>4aqzN4qPHBcg?hNZi z6){HFNfuE_apR63HxG8_QE&|ScsEF6pp;;Mwup*5%hACgt3|1{<8^3uR3b~y(ur^= zluhla;_D3RObe@34W$8{yeKi@BOJNWL^Wj*x9r*p&irXDgF8{7XMCux97xr0Yqr&3 zcxq>3%vWd3)&_*%s);vOK|lm1%q}E}7K6;RcrJ=zJ0q>Id6g z*+bgD7Ox`BLu${a^#5w_>SN`cStM=MP3*!>fFNyvq#tn$t7roQHBcZx+W-O5rbz!OiWVpe z6gV_!3l!)F(Ebs?DbPRK{(f(EW@qn~N79sPqrM|TOXN16Zi$LyrH zmj5U&2b_+4_}^?>D8IW6w#lR5g2E=Cf*W9W*|2HRY}Pmc&}`NDPksZP8q{l8A zRoWiADD=9=F80_(%?kF|#rlmNyVzqFKP>EGh@Xpt7vaa7K@v#bcrpS3e^ykoVz%|E zsAToaAv;6xrGpTBm7&To#Qsp}O28loqW^s`FDAz-TuqM$>G2@JMv!~P9uLyvL3%t$ zPh_>M1bAF2dLpY2iO32X4=;k@mCgM&3ClI2+CJM1{Dh_dka9p~PT4we#3Q;X#n{Zb&U~cm6 zFEDw9NgMop=T*XwFW{%&`2->b*|0NoyVzHhwcwH6P0-mC?-&xL_s`fR=x7HWJ>X7J z;j|G)Oby&o5p;hu{&D7Dj1mO<{YAXzehCTmxW3G5IqKz@R2}guANl4pukpIWu8A*v zC4ij~iVwy%!UMFMraDi?8}JoO!~*SbhZ@9BO{n;(GB{*3$YhCDDtaB|e4TK}G-!t) z!eoeeJA#ZOOZ=mSK0Gp_7MljdgCv3X*;k`YTk;;Dj&s0V$ z2k?Jyb?Dk~C07{}&j{JdK@7}8h@DNdM)gf zb@0Rg>|4Rs2rj5*1)U7gehZ|Cz-VFDn*W10+Yr?nhVOj0Uc`a3TdTr=;T-}e^~N@i zv;h{%XlNQ*6m%ttxjIbwcAxeW^qyS3{=NlAd&fnPCITVYVSlR*L?xjR#N;Y>nRiA6{(e?+pA*ndsglH+c3iCp(#vk2-;2EsJ*>z_X--- zt>%8%RI=#rTUC#?RV^8!>sAv&t0>tM;$Dk~!67L_E8_&zI@6!f{o=0zFR)+QNJ$a* zeqcd%cN=6{K|pKmb(yp~fl(_17TRHaCIZGe-1}h{7$9+?nkETNNT2{KFuJYRS8vCF=9l8PZmegMfVF#WN{2^Lto&%q9lBG zj>)H){FKS2`hJ)2#%~cSG5n#wyJQ+mX86x#u5FJgVI50!ns-rKXh5$8YFF-j4JH>Z zv=&rQ0;uA+IJ>t_d~JEP4hhyZ}U3anc+qS0{mn%3G9N&^;Z#UM~Ps|XB zZREpUEX*Gi=AfSwMG?)aw)x7k8JL>TZeKI}-L7Ej@_aBib4b{x3mr@txe_`(2g3FD ztP9`1^f0#)*h28`w!26u;Kom&1tdzD-YS$211&xr-HvQ6^5R$wfhV!DR4SRgpPTZ&i2s<~gT43!{`AVr#Ist9gM%5E~81)Xdm7;X+jE5x_ z6+p2IVzmd@{%_O8!@DL{$s*hHVeEwWnVj5%Wk+v}uv0)Me2}QfcocNEk9d?oCWcvs z5RZ&cJa~6!#G~{M7U)?Vw9MBV4aNRIkF}(f5=C3t_m~Th$@Dp9@ldl=(x>_;{0s>% zk7GMbeWfI?^_fA9pz*A|LqmVlMRvoLaPw5HOwmTx(&m;|RwS>|XYPmq)tytD;j00y zAZZ~GSCu{@}l=XDkYb#QLXz*MSI@H_u9dCV>)byO~V z9hgmc)mp5U8Knfe^_GJ*Ld_3c1ya`?&>F0%2P!SYB|FGF7{BP}%mvqx$S^L^70_My zG2Y?FPD+!)*sSdq#zuE5tGGE((Fmzu$KZpxJ4O~(FF}v=QP2syp!}3fKV+um!Ch1S zR8e5-O`&cBzc+={M77e;e0(3K(EGe@zhI^yoLZ?V^g&vJ!(4B+z^}xJdJX>0oPM+l$K74n@uqu zsxWMxS$APa=2pMhtU(MtEk+vJJ4diOah5Ar02k^n)~bbBEbvkYY=eTbBbHbAQ(3B> z$Y1o!m(X{nVof{Nt0ngY*Y9wJ%lVUeRb9s$QtZj2WbiJOAh}vQIz@RB7uFElk%wg! zvA}hAxdxBUm5!oV`N`vtKmK^&E17UvuB=fD9UM!51s#DwY7x5`@_{9TKwX>i-U=H? zSV+D|2d$=F32YWf>{$k1hsh5%y9Te8oy(!{DY|9nqED5@%tcOxwq=QN3BP+J6BjEisk5X4F;!>Z0>Y8ZaxArIZRFAaW_+MnBj>r zX!)37zV~?$YEUf+36ojt2d~?y2t-zTz`55N~SR^pMA!y+w^bp2yx% zD*Y`@N#S-b7pm3}=g?s0A>A1^V;qShu9X|baV3w=ezCW zglnZ1&{`0m?N2-&BK$gApwEhj=(NX19$I14P$E2=$dSdSM-dgw!*A*y74JE`(_1d` z`47=@QR-3SJI4}eY8)b!am;Fdyz@u`QVC;%VQ~!>!+8(_SwWj6>4y?bi6H@Fd89A( z`>{OIek_jxF(g2!^NB3Zi!PMb=c}4P;0T$DM0Y}c@J}teIu@=~_AnB$iE9EsY%uaG z!g>)Go2w9l*e0MTm_%?BQ6nVLH7bOuO0xZ_Ia7zr?;~9Z@w6xyYVEp>JhDP!=i7)! zDG~NZDiKyeAJtJY7YVI1;o{nThDmU|VNRg`jF_Slf~`piU#y2aux1GP2T-5zFWCx; zSdBj6p?3JAbqcw1vHv{^og#D!C#h5TR=kmT3+~&gRd_3AGzxL(mbm=V%`4F8{4(CQ zv;cC=&YWg#~gcUDOLj@$n6mAyh#l?JK;|Hg3O)dp{N^04EMZvO>3Tz}GG0voda*4}0nq zzM_g4qNj2!*cvb#Q;)UzP_Z@E4XX-=Xd$K^7v?Ma(!-{OrmqLUsOMi5Le!e)URmS7+U3&5A&T zZ2SVM9*pxE8lKkWLcGY|Aw=M}LIhPzG&QZpuO+~ZQqA9iHnl>->7`o9o5A8-LQYF} zPS)k;dGD8)L_u*4wPY+P_&c-@H$u)liii|)`VL6MTeVX&DD>+&TP-UpF; zMflfEVD#K#38#`Kl-O)@b*Wl7DtFt0Wj!TllL%c@y+KJ;;i%kzh!Nr;OD@QP%L7B~SIgtz3w|8acJ;OmELc^OLT(o@)!N-U@9}5J9T#yu zsDXuuYt*XLkcZt&teM+CaL5l%5N1oLH5P{3?1XkK(z=ep_W%p$s1%VF@ASyS7Ubdf z&fQN2BQi97;^-58ye}XLrjPQXP)%M-LAWvE`%*~z;cW)|@HQ$0j`F2|V5XJ5V)UbY zDeU!)frdmBGK@uPf2-dgQN6C;qU-OVkZ2|t2OC+xKcb~WX1RX^Bcnq)^q@8{WxzOw zy%mE}n2Z_ePjY6%U;j20#RvAI_p6n13jt6vQUG)Y@ad(otJvo=Y&-21wAcp`K4?a$ z>IN1JjVtSEL6T(A0gN=)lUJ2_h>V^gyn7fHlvG#4PV=4bSM~;l;#+2fy|D9FpD1;iVW~5;T^U4 zqoa(Iw-cXd)xt~8)QM>j1bU++DcioCkS)8Yk+*Fu)&bMzwyRqO;348p5hQN-(u453 z4U5OXgf*RZnPZ0wBVPeQ-HfSi1}G?_R`W4@xbbQ6{n&6iBtO}r3fpTJ@IJl<>%(G zccQ=EQd=RD0_!BzD>@3(&+L+93k1ibY~f{;DV}oSL)C9>1Rlc5ynu9W&X1KhH;4Tj zqxnkMYUluSM~659bP|l{Hc&2EsME(Qbu_e2jAdD+6k=r4R`5%_JUQ#Z6>zXwqlOBg z^-xt9dD85>XqL=Z7fXz&L-(=BEKe@a9!GfUN6;{(mIAF2=%Apa<0y$C#&P)wFL5_i zFdVJUDmT=CUpw+PURb4t(D#v7!ZCa1=A;Qm8_~rFrq6QTj zx~PR}2wscAxQ{4>bnSu|!x#!tFqT8`D(FL*9=Fh%UxWiZC{#~bPbbyZoOorwE8Uc) zIQuoo67T3}k%C3+JfVC%X^itG{V>)>(bv4GmCUysqotK~)!$~~p|>&ho-e_zGx;1f zQbkc6u78)B6^tGQk0`2(A9aLkLPtYG{RS)t=Ml0=e&3)a4eo0_c0s!79GV$c0y3hb zvtvfsA=#sPL5=&c{uX5;+W&}eGUHJOb0V*1um27wo&BLj%yh9MCy18Z>#T!ojy#e| zM3NFz(5b2I`x3XR35t|rP*dTVYVGP`qwwe_j!jJEKUb?X77LF(dTb)lFE>IRmDA63 z1@9_?ASDIa*YTh8 z_;IC^jg-WdK4IcYJAPbgr;GKlqw7-D>qKCi&6$hjl$r(9NR=mnEn(LlJGBK!b z{06Fazs=-LCjY{O{uhF%&o0Gh?lRwrtLA^5H!iTGFd`(*;O`L!d7r{M~ zX_97fqhfhe5&Ug+y7>dEuKjI;O1R+NB5(=?{LrdotgVtr7Y=NaxNsm(3TGA0_5L8b zql`N^*{R~0iOZ{P=))(C8=R?77zqIS6CmT6_C zxEoihkd0SiLbHsrJRnd>4Y{gNevXEKVCk3{_9D->vBrVJ#_Dt2tVO(S*S2Pzhg@u~ ztdLcX2E9<7zB)~2Yk7TjeQs_7VRZlz)-Rv4HdP3~P@Aqa5!9gGY{2}VoL~)nI$L{G z;ggoZ{^B`4->fYmh=Df^XvdFQn6!iOu%VjkQKn-mFo@RZmeOdPWrdK@h!M8Px7kCK zkv!u1ES6TTLSH^$9X7IPKLg4bxF%w)#6oSUI+1K8#WqHXph_4xE|-*6%4=Yw;bKVIvJ+4?rK$AWhYJ^8OBQ ziS~_XzQo=^uQXQ>>jJF|$L@@@tyZUC!2OP`2miks0n#MhZ4|{8khYZ8BsnMc7#z8} z17KNN;ZPJi0zIcgB}{`GCcgzsf|U%iz1VcNypF`64Qy) zMj5PHuWsCPb`7=^v`LT=fssRV*kDkQ;rK%gHvID<1}~}OzjE+$WcH1!MLf|O#A1wX zL8-aaXzi`L82#qw@bw!-2J$dB_AS(^OBMX|%5H77QHPN({LnR6S(C|&Ol~j{BF%cV z$d&)&_zH=Cz3=td>(1-(1v)cyUQ6Fhyqpl?oCBxvscN|{`&HEeG@K!6)r4Y7ZL7qR z7vZA(aG2OXDYFi}`z2MRHvrigJuLfp+0@qRcDNKhc>i=tL0P5``UpV|DvNSx-e&RtUB*ER9>bGDcvdT3klNt))VF z$vYwR{>!ls@>$mIE(d4q%K(E=H^0GP;8=DXbxd4brLh%WSbHtwqzN;@Tt8;U~Ac02`lhX>tWoBSVQ3XbH?W?jdLEicb z9(c74uxJ#2X<>?0Ah5nzx7mLI}LnG@Fd9LRnIHGuPv3w)s^9C7%|w-OpHr^k0T(uZ zQ?Z0dVVo*nbCpiOxXP>PVPOe9q?ZZE5`{leYcUuBsRnl~zI<-Z40sHF$-upc#Zz>! zBf+Rd)JgQ2#51%;FJ$!?2?iui08>Y>9u|veBmG#`=9_SUDBFsvUhBB@&0hl}W5Hp3 zhJE7rCO*T;;40+9|2)IpkFT68z0vnZ{0-*~D7n80yD|6?i?!3d;GKY_@Yr6uplY4fV$ z!J;{+HL_8xZxc{tLvjzE$63Ef70!;NDRzp_%sf5uru(aS=Kd~{)^HhTCO|lix2H?< zW%mJ=&HavhiOCET?&(_@NZ)DW4HwloJd#bj=(MwVmsp3^M-h8mm|au&=YEpOzccw1 zlk-e2GP%s;ER&BSxs)wFT|*dAFh$_cxDvZmP;o_tae-G?nJhA?F}co!+Dk4)PvWc3 zUEx)eNuJ5QOzvay%S?U+$)({UgzD~6y#yY$xxBpYKEOxZfVtmdGR$Oz$v!3&_qlWu z=za%DYxqJ_9N|3&%jhcHgSnJOxD*t%vPBDpMWXN>KKm|{KVfo+$zddyQos+iHd{k} zX%`SI6^(Ys@UWGjmABhZ^dI0G9K`PZOeUE;%;a~N{0Ec2Wzu5uAd|mi@?T7T%;Z0r z(CpEjU{YXmgvnh@_Op(0UJdYS50chMvDm1tK{BsTe$b6$eEJykm6*&ksW8d&!K1wT zH757+=SO%o&Z`T&I>xKxOg_e+k1#ojpRGOT#F61yx|wk)ZgU@Ea++D=OrBzLhRKsm zewGQnE4tX9^tpe<lXR z=G8o}j`8X^6Os~_c9<>=9YhaZw3S6uSM(Z{?3hZC?saD2p|c$9x|9I8+)25ddhU5X z_y=Cm&*`Q3>6LZ&kN7hX90VjI{lqdPC`(l~xzGD;Y{Q^F7yKnh92}6xvnfSItQ7KS z>(BlbckEwwu8!+eJQ2&L;66H@Igp7BCh(1?6N9--EFI5{4koD1F&G<)4LPYqK9+Vy zW4Xb^-obe8V}o(zNv8AZB>wY$I+4Ns>A`p^mP({j*}L$cf6N!pkpiYu4zDv#E-QDP z2VSWJ|s9*rG1o`#?wjQ^x47qsFQn$P~yG)IhBvs`*JyX zhu4R5_wbtSAS9X5A$SbP4WNwSG)i~aI}eQR8y!NA#+f4*&kV~|TyhPjoxvpf6?hza Xo~_D`N;-x#f%juh;<4D_8P@Q>kjh30 diff --git a/venv/lib/python3.7/site-packages/__pycache__/zipp.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/zipp.cpython-37.pyc deleted file mode 100644 index 08d8a6bfac4d8693c857e085bcb79fe6b67547b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10099 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 import certifi - - >>> certifi.where() - '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' - -Or from the command line:: - - $ python -m certifi - /usr/local/lib/python3.7/site-packages/certifi/cacert.pem - -Enjoy! - -1024-bit Root Certificates -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Browsers and certificate authorities have concluded that 1024-bit keys are -unacceptably weak for certificates, particularly root certificates. For this -reason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its -bundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key) -certificate from the same CA. Because Mozilla removed these certificates from -its bundle, ``certifi`` removed them as well. - -In previous versions, ``certifi`` provided the ``certifi.old_where()`` function -to intentionally re-add the 1024-bit roots back into your bundle. This was not -recommended in production and therefore was removed at the end of 2018. - -.. _`Certifi`: https://certifiio.readthedocs.io/en/latest/ -.. _`Requests`: https://requests.readthedocs.io/en/master/ - -Addition/Removal of Certificates --------------------------------- - -Certifi does not support any addition/removal or other modification of the -CA trust store content. This project is intended to provide a reliable and -highly portable root of trust to python deployments. Look to upstream projects -for methods to use alternate trust. - - diff --git a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/RECORD b/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/RECORD deleted file mode 100644 index 386956f..0000000 --- a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/RECORD +++ /dev/null @@ -1,13 +0,0 @@ -certifi-2021.10.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -certifi-2021.10.8.dist-info/LICENSE,sha256=vp2C82ES-Hp_HXTs1Ih-FGe7roh4qEAEoAEXseR1o-I,1049 -certifi-2021.10.8.dist-info/METADATA,sha256=iB_zbT1uX_8_NC7iGv0YEB-9b3idhQwHrFTSq8R1kD8,2994 -certifi-2021.10.8.dist-info/RECORD,, -certifi-2021.10.8.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 -certifi-2021.10.8.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 -certifi/__init__.py,sha256=xWdRgntT3j1V95zkRipGOg_A1UfEju2FcpujhysZLRI,62 -certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 -certifi/__pycache__/__init__.cpython-37.pyc,, -certifi/__pycache__/__main__.cpython-37.pyc,, -certifi/__pycache__/core.cpython-37.pyc,, -certifi/cacert.pem,sha256=-og4Keu4zSpgL5shwfhd4kz0eUnVILzrGCi0zRy2kGw,265969 -certifi/core.py,sha256=V0uyxKOYdz6ulDSusclrLmjbPgOXsD0BnEf0SQ7OnoE,2303 diff --git a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/WHEEL b/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/WHEEL deleted file mode 100644 index 6d38aa0..0000000 --- a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/top_level.txt deleted file mode 100644 index 963eac5..0000000 --- a/venv/lib/python3.7/site-packages/certifi-2021.10.8.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -certifi diff --git a/venv/lib/python3.7/site-packages/certifi/__init__.py b/venv/lib/python3.7/site-packages/certifi/__init__.py deleted file mode 100644 index 8db1a0e..0000000 --- a/venv/lib/python3.7/site-packages/certifi/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .core import contents, where - -__version__ = "2021.10.08" diff --git a/venv/lib/python3.7/site-packages/certifi/__main__.py b/venv/lib/python3.7/site-packages/certifi/__main__.py deleted file mode 100644 index 8945b5d..0000000 --- a/venv/lib/python3.7/site-packages/certifi/__main__.py +++ /dev/null @@ -1,12 +0,0 @@ -import argparse - -from certifi import contents, where - -parser = argparse.ArgumentParser() -parser.add_argument("-c", "--contents", action="store_true") -args = parser.parse_args() - -if args.contents: - print(contents()) -else: - print(where()) diff --git a/venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/certifi/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 3c2b1ec5efa990dc7492e01f081ab0e8c072605b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264 zcmXwzu};G<5Qc3hm8zmj9eITe(HgAE{ir@aXz5)${NnUiJK*m?C%v` zd<1ZGjnp`5Xd7{ALTe3(7RAY)!=u9{APi^*(CP^NnDA}61+N0$^y%OoJqUC`y(!>a X85KA$`*E7@J1fr`4=J}#c~S8+%xb5l|Cj)T0Muq9%sRrnUtZ_RF?_aOLcOz@vYuS5Kb3 zd9q!VNjmf1^mSgZ+U*cnEFU&cUsgX{^AFz^7xt(}OB`^RfuU2B!5j@y?hQQ%1lTs- zz|a@|G~ga@aGwXS&iA)X>tlhZNM4IQfi_?RAt*vyd%rb@cOYth+H`OeA%j_2Xi;co z{N+SQu|_dlhjF~KL#0b85-sNSr%7|V>MmAQ1bWJohC_6(;`U@ cs+GZKdCBLQIEQwza@#T5M;Puyi~`s~KlzD%Qvd(} diff --git a/venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc b/venv/lib/python3.7/site-packages/certifi/__pycache__/core.cpython-37.pyc deleted file mode 100644 index ed72c3b84833ed1973a165091b404a966bbced40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1133 zcmZuv&2AGh5VpO$&1RF7{{tM*3ROrskUb#80R)t&5?mrE0oq)wt?f43Zq||Q6jHTZ z+H1uVAT>u`$yZLi0v8zXCT&$Q(KzFo9nUx4%;C>$;cb{qhJtV#7VjYTH`(sPS7CyjEaXo67{`EeZt87c$3$7c!CE3 zuUFq}qJnH79`OcbM4Ws;?bd;am{2C$&N}01^zB@ts6WhfJd%8pi&zOWQH74pP{diG zO`7Ma$z&1dl2wM>j#=tn>WsxGmMYGSj+rcsD2(nzzo8-2YZL2_Q!})6B~ng}_-dF7 zEW`t&3#uQ$VSs_XP~A7!v2aXMVmw36{24mNDMSIi*R!=b`h)1Ad^@mB+Fk9gt@r7> z)&3hB?g&H6!i|N$+uyLBHp10c#JQveE8K!Ixpvxj* zL&5gs#B`wvBa(el>?e7)m5iq@{J8Tp(U}pC#x7w;=wyyCVNwYo*#=*RLWvu$Pd9KB zhK&d}iE4svgH*FDV~zd^6H1944(bDqLKM;=x!vFvP diff --git a/venv/lib/python3.7/site-packages/certifi/cacert.pem b/venv/lib/python3.7/site-packages/certifi/cacert.pem deleted file mode 100644 index 6d0ccc0..0000000 --- a/venv/lib/python3.7/site-packages/certifi/cacert.pem +++ /dev/null @@ -1,4362 +0,0 @@ - -# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Label: "GlobalSign Root CA" -# Serial: 4835703278459707669005204 -# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a -# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c -# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Label: "GlobalSign Root CA - R2" -# Serial: 4835703278459682885658125 -# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 -# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe -# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Label: "Entrust.net Premium 2048 Secure Server CA" -# Serial: 946069240 -# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 -# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 -# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- - -# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Label: "Baltimore CyberTrust Root" -# Serial: 33554617 -# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 -# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 -# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Label: "Entrust Root Certification Authority" -# Serial: 1164660820 -# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 -# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 -# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -# Issuer: CN=AAA Certificate Services O=Comodo CA Limited -# Subject: CN=AAA Certificate Services O=Comodo CA Limited -# Label: "Comodo AAA Services root" -# Serial: 1 -# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 -# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 -# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited -# Label: "QuoVadis Root CA 2" -# Serial: 1289 -# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b -# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 -# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 3" -# Serial: 1478 -# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf -# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 -# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- - -# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 -# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 -# Label: "Security Communication Root CA" -# Serial: 0 -# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a -# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 -# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- - -# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Label: "XRamp Global CA Root" -# Serial: 107108908803651509692980124233745014957 -# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 -# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 -# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Label: "Go Daddy Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 -# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 -# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- - -# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Label: "Starfield Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 -# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a -# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root CA" -# Serial: 17154717934120587862167794914071425081 -# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 -# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 -# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root CA" -# Serial: 10944719598952040374951832963794454346 -# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e -# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 -# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert High Assurance EV Root CA" -# Serial: 3553400076410547919724730734378100087 -# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a -# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 -# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- - -# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Label: "DST Root CA X3" -# Serial: 91299735575339953335919266965803778155 -# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 -# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 -# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - -# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG -# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG -# Label: "SwissSign Gold CA - G2" -# Serial: 13492815561806991280 -# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 -# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 -# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Label: "SwissSign Silver CA - G2" -# Serial: 5700383053117599563 -# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 -# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb -# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=SecureTrust CA O=SecureTrust Corporation -# Subject: CN=SecureTrust CA O=SecureTrust Corporation -# Label: "SecureTrust CA" -# Serial: 17199774589125277788362757014266862032 -# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 -# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 -# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -# Issuer: CN=Secure Global CA O=SecureTrust Corporation -# Subject: CN=Secure Global CA O=SecureTrust Corporation -# Label: "Secure Global CA" -# Serial: 9751836167731051554232119481456978597 -# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de -# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b -# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO Certification Authority O=COMODO CA Limited -# Label: "COMODO Certification Authority" -# Serial: 104350513648249232941998508985834464573 -# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 -# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b -# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- - -# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Label: "Network Solutions Certificate Authority" -# Serial: 116697915152937497490437556386812487904 -# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e -# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce -# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Label: "COMODO ECC Certification Authority" -# Serial: 41578283867086692638256921589707938090 -# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 -# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 -# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -# Issuer: CN=Certigna O=Dhimyotis -# Subject: CN=Certigna O=Dhimyotis -# Label: "Certigna" -# Serial: 18364802974209362175 -# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff -# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 -# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc -# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc -# Label: "Cybertrust Global Root" -# Serial: 4835703278459682877484360 -# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 -# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 -# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority -# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority -# Label: "ePKI Root Certification Authority" -# Serial: 28956088682735189655030529057352760477 -# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 -# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 -# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -# Issuer: O=certSIGN OU=certSIGN ROOT CA -# Subject: O=certSIGN OU=certSIGN ROOT CA -# Label: "certSIGN ROOT CA" -# Serial: 35210227249154 -# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 -# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b -# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" -# Serial: 80544274841616 -# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 -# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 -# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Label: "Hongkong Post Root CA 1" -# Serial: 1000 -# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca -# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 -# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- - -# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Label: "SecureSign RootCA11" -# Serial: 1 -# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 -# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 -# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Label: "Microsec e-Szigno Root CA 2009" -# Serial: 14014712776195784473 -# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 -# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e -# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Label: "GlobalSign Root CA - R3" -# Serial: 4835703278459759426209954 -# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 -# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad -# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- - -# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" -# Serial: 6047274297262753887 -# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 -# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa -# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -# Issuer: CN=Izenpe.com O=IZENPE S.A. -# Subject: CN=Izenpe.com O=IZENPE S.A. -# Label: "Izenpe.com" -# Serial: 917563065490389241595536686991402621 -# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 -# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 -# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Label: "Go Daddy Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 -# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b -# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 -# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e -# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Services Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 -# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f -# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Commercial O=AffirmTrust -# Subject: CN=AffirmTrust Commercial O=AffirmTrust -# Label: "AffirmTrust Commercial" -# Serial: 8608355977964138876 -# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 -# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 -# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Networking O=AffirmTrust -# Subject: CN=AffirmTrust Networking O=AffirmTrust -# Label: "AffirmTrust Networking" -# Serial: 8957382827206547757 -# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f -# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f -# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium O=AffirmTrust -# Subject: CN=AffirmTrust Premium O=AffirmTrust -# Label: "AffirmTrust Premium" -# Serial: 7893706540734352110 -# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 -# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 -# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust -# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust -# Label: "AffirmTrust Premium ECC" -# Serial: 8401224907861490260 -# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d -# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb -# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA" -# Serial: 279744 -# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 -# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e -# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Label: "TWCA Root Certification Authority" -# Serial: 1 -# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 -# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 -# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Label: "Security Communication RootCA2" -# Serial: 0 -# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 -# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 -# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes -# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes -# Label: "EC-ACC" -# Serial: -23701579247955709139626555126524820479 -# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 -# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 -# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB -8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy -dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 -YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 -dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh -IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD -LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG -EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g -KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD -ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu -bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg -ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R -85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm -4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV -HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd -QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t -lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB -o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 -opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo -dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW -ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN -AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y -/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k -SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy -Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS -Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl -nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2011" -# Serial: 0 -# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 -# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d -# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - -# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Label: "Actalis Authentication Root CA" -# Serial: 6271844772424770508 -# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 -# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac -# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 2 Root CA" -# Serial: 2 -# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 -# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 -# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 3 Root CA" -# Serial: 2 -# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec -# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 -# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 3" -# Serial: 1 -# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef -# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 -# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 2009" -# Serial: 623603 -# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f -# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 -# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 EV 2009" -# Serial: 623604 -# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 -# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 -# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- - -# Issuer: CN=CA Disig Root R2 O=Disig a.s. -# Subject: CN=CA Disig Root R2 O=Disig a.s. -# Label: "CA Disig Root R2" -# Serial: 10572350602393338211 -# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 -# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 -# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- - -# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Label: "ACCVRAIZ1" -# Serial: 6828503384748696800 -# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 -# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 -# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- - -# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Label: "TWCA Global Root CA" -# Serial: 3262 -# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 -# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 -# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- - -# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera -# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera -# Label: "TeliaSonera Root CA v1" -# Serial: 199041966741090107964904287217786801558 -# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c -# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 -# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- - -# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Label: "E-Tugra Certification Authority" -# Serial: 7667447206703254355 -# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 -# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 -# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 2" -# Serial: 1 -# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a -# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 -# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot 2011 O=Atos -# Subject: CN=Atos TrustedRoot 2011 O=Atos -# Label: "Atos TrustedRoot 2011" -# Serial: 6643877497813316402 -# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 -# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 -# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 1 G3" -# Serial: 687049649626669250736271037606554624078720034195 -# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab -# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 -# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 2 G3" -# Serial: 390156079458959257446133169266079962026824725800 -# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 -# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 -# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 3 G3" -# Serial: 268090761170461462463995952157327242137089239581 -# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 -# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d -# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G2" -# Serial: 15385348160840213938643033620894905419 -# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d -# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f -# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G3" -# Serial: 15459312981008553731928384953135426796 -# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb -# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 -# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G2" -# Serial: 4293743540046975378534879503202253541 -# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 -# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 -# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G3" -# Serial: 7089244469030293291760083333884364146 -# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca -# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e -# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Trusted Root G4" -# Serial: 7451500558977370777930084869016614236 -# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 -# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 -# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- - -# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Label: "COMODO RSA Certification Authority" -# Serial: 101909084537582093308941363524873193117 -# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 -# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 -# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Label: "USERTrust RSA Certification Authority" -# Serial: 2645093764781058787591871645665788717 -# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 -# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e -# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Label: "USERTrust ECC Certification Authority" -# Serial: 123013823720199481456569720443997572134 -# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 -# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 -# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Label: "GlobalSign ECC Root CA - R4" -# Serial: 14367148294922964480859022125800977897474 -# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e -# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb -# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Label: "GlobalSign ECC Root CA - R5" -# Serial: 32785792099990507226680698011560947931244 -# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 -# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa -# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- - -# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden -# Label: "Staat der Nederlanden EV Root CA" -# Serial: 10000013 -# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba -# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb -# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Label: "IdenTrust Commercial Root CA 1" -# Serial: 13298821034946342390520003877796839426 -# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 -# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 -# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Label: "IdenTrust Public Sector Root CA 1" -# Serial: 13298821034946342390521976156843933698 -# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba -# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd -# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - G2" -# Serial: 1246989352 -# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 -# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 -# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - EC1" -# Serial: 51543124481930649114116133369 -# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc -# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 -# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- - -# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority -# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority -# Label: "CFCA EV ROOT" -# Serial: 407555286 -# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 -# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 -# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GB CA" -# Serial: 157768595616588414422159278966750757568 -# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d -# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed -# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- - -# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Label: "SZAFIR ROOT CA2" -# Serial: 357043034767186914217277344587386743377558296292 -# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 -# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de -# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA 2" -# Serial: 44979900017204383099463764357512596969 -# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 -# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 -# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce -# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 -# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef -# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 -# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- - -# Issuer: CN=ISRG Root X1 O=Internet Security Research Group -# Subject: CN=ISRG Root X1 O=Internet Security Research Group -# Label: "ISRG Root X1" -# Serial: 172886928669790476064670243504169061120 -# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e -# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 -# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- - -# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Label: "AC RAIZ FNMT-RCM" -# Serial: 485876308206448804701554682760554759 -# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d -# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 -# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 1 O=Amazon -# Subject: CN=Amazon Root CA 1 O=Amazon -# Label: "Amazon Root CA 1" -# Serial: 143266978916655856878034712317230054538369994 -# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 -# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 -# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 2 O=Amazon -# Subject: CN=Amazon Root CA 2 O=Amazon -# Label: "Amazon Root CA 2" -# Serial: 143266982885963551818349160658925006970653239 -# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 -# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a -# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 3 O=Amazon -# Subject: CN=Amazon Root CA 3 O=Amazon -# Label: "Amazon Root CA 3" -# Serial: 143266986699090766294700635381230934788665930 -# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 -# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e -# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 4 O=Amazon -# Subject: CN=Amazon Root CA 4 O=Amazon -# Label: "Amazon Root CA 4" -# Serial: 143266989758080763974105200630763877849284878 -# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd -# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be -# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- - -# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" -# Serial: 1 -# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 -# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca -# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- - -# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Label: "GDCA TrustAUTH R5 ROOT" -# Serial: 9009899650740120186 -# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 -# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 -# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- - -# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor RootCert CA-1" -# Serial: 15752444095811006489 -# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 -# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a -# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y -IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB -pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h -IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG -A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU -cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid -RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V -seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme -9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV -EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW -hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ -DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD -ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I -/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ -yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts -L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN -zl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- - -# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor RootCert CA-2" -# Serial: 2711694510199101698 -# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 -# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 -# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig -Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk -MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg -Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD -VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy -dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ -QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq -1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp -2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK -DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape -az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF -3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 -oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM -g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 -mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd -BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U -nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw -DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX -dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ -MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL -/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX -CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa -ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW -2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 -N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 -Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB -As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp -5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu -1uwJ ------END CERTIFICATE----- - -# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor ECA-1" -# Serial: 9548242946988625984 -# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c -# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd -# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y -IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig -RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb -3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA -BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 -3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou -owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ -wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF -ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf -BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv -civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 -AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 -soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI -WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi -tJ/X5g== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Label: "SSL.com Root Certification Authority RSA" -# Serial: 8875640296558310041 -# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 -# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb -# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com Root Certification Authority ECC" -# Serial: 8495723813297216424 -# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e -# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a -# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority RSA R2" -# Serial: 6248227494352943350 -# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 -# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a -# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority ECC" -# Serial: 3182246526754555285 -# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 -# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d -# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Label: "GlobalSign Root CA - R6" -# Serial: 1417766617973444989252670301619537 -# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae -# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 -# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GC CA" -# Serial: 44084345621038548146064804565436152554 -# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 -# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 -# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R1 O=Google Trust Services LLC -# Subject: CN=GTS Root R1 O=Google Trust Services LLC -# Label: "GTS Root R1" -# Serial: 146587175971765017618439757810265552097 -# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 -# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 -# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX -mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 -zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P -fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc -vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 -Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp -zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO -Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW -k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ -DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF -lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW -Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z -XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR -gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 -d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv -J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg -DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM -+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy -F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 -SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws -E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R2 O=Google Trust Services LLC -# Subject: CN=GTS Root R2 O=Google Trust Services LLC -# Label: "GTS Root R2" -# Serial: 146587176055767053814479386953112547951 -# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b -# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d -# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg -GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu -XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd -re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu -PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 -mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K -8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj -x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR -nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 -kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok -twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp -8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT -z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA -pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb -pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB -R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R -RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk -0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC -5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF -izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn -yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R3 O=Google Trust Services LLC -# Subject: CN=GTS Root R3 O=Google Trust Services LLC -# Label: "GTS Root R3" -# Serial: 146587176140553309517047991083707763997 -# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 -# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 -# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A -DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk -fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA -njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R4 O=Google Trust Services LLC -# Subject: CN=GTS Root R4 O=Google Trust Services LLC -# Label: "GTS Root R4" -# Serial: 146587176229350439916519468929765261721 -# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 -# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb -# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l -xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 -CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx -sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- - -# Issuer: CN=UCA Global G2 Root O=UniTrust -# Subject: CN=UCA Global G2 Root O=UniTrust -# Label: "UCA Global G2 Root" -# Serial: 124779693093741543919145257850076631279 -# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 -# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a -# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- - -# Issuer: CN=UCA Extended Validation Root O=UniTrust -# Subject: CN=UCA Extended Validation Root O=UniTrust -# Label: "UCA Extended Validation Root" -# Serial: 106100277556486529736699587978573607008 -# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 -# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a -# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- - -# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Label: "Certigna Root CA" -# Serial: 269714418870597844693661054334862075617 -# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 -# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 -# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- - -# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Label: "emSign Root CA - G1" -# Serial: 235931866688319308814040 -# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac -# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c -# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- - -# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI -# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI -# Label: "emSign ECC Root CA - G3" -# Serial: 287880440101571086945156 -# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 -# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 -# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG -EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo -bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ -TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s -b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 -WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS -fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB -zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB -CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD -+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- - -# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI -# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI -# Label: "emSign Root CA - C1" -# Serial: 825510296613316004955058 -# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 -# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 -# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG -A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg -SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v -dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ -BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ -HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH -3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH -GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c -xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 -aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq -TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 -/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 -kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG -YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT -+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo -WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- - -# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI -# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI -# Label: "emSign ECC Root CA - C3" -# Serial: 582948710642506000014504 -# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 -# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 -# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG -EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx -IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND -IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci -MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti -sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O -BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c -3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J -0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- - -# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Label: "Hongkong Post Root CA 3" -# Serial: 46170865288971385588281144162979347873371282084 -# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 -# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 -# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 ------BEGIN CERTIFICATE----- -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 -mpv0 ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - G4" -# Serial: 289383649854506086828220374796556676440 -# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 -# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 -# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 -MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ -2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E -T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j -5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM -C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T -DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX -wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A -2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm -nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl -N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj -c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS -5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS -Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr -hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ -B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI -AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw -H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ -b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk -2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol -IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk -5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY -n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- - -# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft ECC Root Certificate Authority 2017" -# Serial: 136839042543790627607696632466672567020 -# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 -# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 -# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- - -# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft RSA Root Certificate Authority 2017" -# Serial: 40975477897264996090493496164228220339 -# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 -# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 -# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- - -# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Label: "e-Szigno Root CA 2017" -# Serial: 411379200276854331539784714 -# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 -# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 -# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- - -# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Label: "certSIGN Root CA G2" -# Serial: 313609486401300475190 -# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 -# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 -# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- - -# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. -# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. -# Label: "Trustwave Global Certification Authority" -# Serial: 1846098327275375458322922162 -# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e -# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 -# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 ------BEGIN CERTIFICATE----- -MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw -CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x -ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 -c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx -OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI -SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn -swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu -7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 -1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW -80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP -JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l -RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw -hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 -coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc -BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n -twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud -DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W -0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe -uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q -lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB -aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE -sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT -MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe -qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh -VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 -h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 -EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK -yeC2nOnOcXHebD8WpHk= ------END CERTIFICATE----- - -# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. -# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. -# Label: "Trustwave Global ECC P256 Certification Authority" -# Serial: 4151900041497450638097112925 -# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 -# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf -# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 ------BEGIN CERTIFICATE----- -MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG -SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN -FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w -DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw -CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh -DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 ------END CERTIFICATE----- - -# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. -# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. -# Label: "Trustwave Global ECC P384 Certification Authority" -# Serial: 2704997926503831671788816187 -# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 -# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 -# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 ------BEGIN CERTIFICATE----- -MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB -BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ -j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF -1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G -A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 -AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC -MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu -Sw== ------END CERTIFICATE----- - -# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Label: "NAVER Global Root Certification Authority" -# Serial: 9013692873798656336226253319739695165984492813 -# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b -# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 -# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy ------END CERTIFICATE----- - -# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" -# Serial: 131542671362353147877283741781055151509 -# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb -# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a -# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw -CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw -FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S -Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 -MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL -DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS -QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH -sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK -Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu -SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC -MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy -v+c= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Label: "GlobalSign Root R46" -# Serial: 1552617688466950547958867513931858518042577 -# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef -# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 -# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA -MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD -VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy -MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt -c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ -OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG -vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud -316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo -0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE -y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF -zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE -+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN -I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs -x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa -ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC -4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 -7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti -2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk -pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF -FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt -rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk -ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 -u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP -4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 -N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 -vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Label: "GlobalSign Root E46" -# Serial: 1552617690338932563915843282459653771421763 -# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f -# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 -# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx -CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD -ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw -MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex -HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq -R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd -yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ -7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 -+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH -# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH -# Label: "GLOBALTRUST 2020" -# Serial: 109160994242082918454945253 -# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 -# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 -# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG -A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw -FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx -MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u -aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b -RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z -YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 -QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw -yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ -BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ -SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH -r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 -4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me -dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw -q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 -nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu -H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC -XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd -6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf -+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi -kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 -wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB -TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C -MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn -4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I -aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy -qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- - -# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Label: "ANF Secure Server Root CA" -# Serial: 996390341000653745 -# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 -# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 -# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV -BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk -YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV -BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN -MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF -UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD -VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v -dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj -cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q -yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH -2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX -H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL -zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR -p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz -W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ -SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn -LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 -n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B -u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj -o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC -AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L -9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej -rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK -pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 -vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq -OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ -/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 -2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI -+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 -MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo -tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= ------END CERTIFICATE----- - -# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum EC-384 CA" -# Serial: 160250656287871593594747141429395092468 -# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 -# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed -# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw -CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw -JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT -EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 -WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT -LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX -BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE -KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm -Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 -EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J -UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn -nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Root CA" -# Serial: 40870380103424195783807378461123655149 -# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 -# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 -# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Label: "TunTrust Root CA" -# Serial: 108534058042236574382096126452369648152337120275 -# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 -# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb -# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg -Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv -b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG -EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u -IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ -n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd -2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF -VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ -GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF -li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU -r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 -eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb -MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg -jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB -7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW -5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE -ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z -xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu -QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 -FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH -22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP -xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn -dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 -Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b -nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ -CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH -u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj -d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS RSA Root CA 2021" -# Serial: 76817823531813593706434026085292783742 -# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 -# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d -# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg -Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL -MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv -b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l -mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE -4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv -a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M -pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw -Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b -LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY -AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB -AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq -E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr -W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ -CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU -X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 -f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja -H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP -JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P -zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt -jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 -/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT -BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 -aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW -xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU -63ZTGI0RmLo= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS ECC Root CA 2021" -# Serial: 137515985548005187474074462014555733966 -# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 -# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 -# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw -CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh -cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v -dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG -A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg -Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 -KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y -STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD -AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw -SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN -nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------END CERTIFICATE----- diff --git a/venv/lib/python3.7/site-packages/certifi/core.py b/venv/lib/python3.7/site-packages/certifi/core.py deleted file mode 100644 index 5d2b8cd..0000000 --- a/venv/lib/python3.7/site-packages/certifi/core.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -certifi.py -~~~~~~~~~~ - -This module returns the installation location of cacert.pem or its contents. -""" -import os - -try: - from importlib.resources import path as get_path, read_text - - _CACERT_CTX = None - _CACERT_PATH = None - - def where(): - # This is slightly terrible, but we want to delay extracting the file - # in cases where we're inside of a zipimport situation until someone - # actually calls where(), but we don't want to re-extract the file - # on every call of where(), so we'll do it once then store it in a - # global variable. - global _CACERT_CTX - global _CACERT_PATH - if _CACERT_PATH is None: - # This is slightly janky, the importlib.resources API wants you to - # manage the cleanup of this file, so it doesn't actually return a - # path, it returns a context manager that will give you the path - # when you enter it and will do any cleanup when you leave it. In - # the common case of not needing a temporary file, it will just - # return the file system location and the __exit__() is a no-op. - # - # We also have to hold onto the actual context manager, because - # it will do the cleanup whenever it gets garbage collected, so - # we will also store that at the global level as well. - _CACERT_CTX = get_path("certifi", "cacert.pem") - _CACERT_PATH = str(_CACERT_CTX.__enter__()) - - return _CACERT_PATH - - -except ImportError: - # This fallback will work for Python versions prior to 3.7 that lack the - # importlib.resources module but relies on the existing `where` function - # so won't address issues with environments like PyOxidizer that don't set - # __file__ on modules. - def read_text(_module, _path, encoding="ascii"): - with open(where(), "r", encoding=encoding) as data: - return data.read() - - # If we don't have importlib.resources, then we will just do the old logic - # of assuming we're on the filesystem and munge the path directly. - def where(): - f = os.path.dirname(__file__) - - return os.path.join(f, "cacert.pem") - - -def contents(): - return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/LICENSE b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/LICENSE deleted file mode 100644 index ad82355..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 TAHRI Ahmed R. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/METADATA b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/METADATA deleted file mode 100644 index 1b04ed4..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/METADATA +++ /dev/null @@ -1,269 +0,0 @@ -Metadata-Version: 2.1 -Name: charset-normalizer -Version: 2.0.12 -Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. -Home-page: https://github.com/ousret/charset_normalizer -Author: Ahmed TAHRI @Ousret -Author-email: ahmed.tahri@cloudnursery.dev -License: MIT -Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues -Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest -Keywords: encoding,i18n,txt,text,charset,charset-detector,normalization,unicode,chardet -Platform: UNKNOWN -Classifier: License :: OSI Approved :: MIT License -Classifier: Intended Audience :: Developers -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Topic :: Text Processing :: Linguistic -Classifier: Topic :: Utilities -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Typing :: Typed -Requires-Python: >=3.5.0 -Description-Content-Type: text/markdown -License-File: LICENSE -Provides-Extra: unicode_backport -Requires-Dist: unicodedata2 ; extra == 'unicode_backport' - - -

Charset Detection, for Everyone 👋

- -

- The Real First Universal Charset Detector
- - - - - - - - Download Count Total - -

- -> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`, -> I'm trying to resolve the issue by taking a new approach. -> All IANA character set names for which the Python core library provides codecs are supported. - -

- >>>>> 👉 Try Me Online Now, Then Adopt Me 👈 <<<<< -

- -This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. - -| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | -| ------------- | :-------------: | :------------------: | :------------------: | -| `Fast` | ❌
| ✅
| ✅
| -| `Universal**` | ❌ | ✅ | ❌ | -| `Reliable` **without** distinguishable standards | ❌ | ✅ | ✅ | -| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | -| `Free & Open` | ✅ | ✅ | ✅ | -| `License` | LGPL-2.1 | MIT | MPL-1.1 -| `Native Python` | ✅ | ✅ | ❌ | -| `Detect spoken language` | ❌ | ✅ | N/A | -| `Supported Encoding` | 30 | :tada: [93](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 - -

-Reading Normalized TextCat Reading Text - -*\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*
-Did you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html) - -## ⭐ Your support - -*Fork, test-it, star-it, submit your ideas! We do listen.* - -## ⚡ Performance - -This package offer better performance than its counterpart Chardet. Here are some numbers. - -| Package | Accuracy | Mean per file (ms) | File per sec (est) | -| ------------- | :-------------: | :------------------: | :------------------: | -| [chardet](https://github.com/chardet/chardet) | 92 % | 220 ms | 5 file/sec | -| charset-normalizer | **98 %** | **40 ms** | 25 file/sec | - -| Package | 99th percentile | 95th percentile | 50th percentile | -| ------------- | :-------------: | :------------------: | :------------------: | -| [chardet](https://github.com/chardet/chardet) | 1115 ms | 300 ms | 27 ms | -| charset-normalizer | 460 ms | 240 ms | 18 ms | - -Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload. - -> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows. -> And yes, these results might change at any time. The dataset can be updated to include more files. -> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. - -[cchardet](https://github.com/PyYoshi/cChardet) is a non-native (cpp binding) and unmaintained faster alternative with -a better accuracy than chardet but lower than this package. If speed is the most important factor, you should try it. - -## ✨ Installation - -Using PyPi for latest stable -```sh -pip install charset-normalizer -U -``` - -If you want a more up-to-date `unicodedata` than the one available in your Python setup. -```sh -pip install charset-normalizer[unicode_backport] -U -``` - -## 🚀 Basic Usage - -### CLI -This package comes with a CLI. - -``` -usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] - file [file ...] - -The Real First Universal Charset Detector. Discover originating encoding used -on text file. Normalize text to unicode. - -positional arguments: - files File(s) to be analysed - -optional arguments: - -h, --help show this help message and exit - -v, --verbose Display complementary information about file if any. - Stdout will contain logs about the detection process. - -a, --with-alternative - Output complementary possibilities if any. Top-level - JSON WILL be a list. - -n, --normalize Permit to normalize input file. If not set, program - does not write anything. - -m, --minimal Only output the charset detected to STDOUT. Disabling - JSON output. - -r, --replace Replace file when trying to normalize it instead of - creating a new one. - -f, --force Replace file without asking if you are sure, use this - flag with caution. - -t THRESHOLD, --threshold THRESHOLD - Define a custom maximum amount of chaos allowed in - decoded content. 0. <= chaos <= 1. - --version Show version information and exit. -``` - -```bash -normalizer ./data/sample.1.fr.srt -``` - -:tada: Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. - -```json -{ - "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", - "encoding": "cp1252", - "encoding_aliases": [ - "1252", - "windows_1252" - ], - "alternative_encodings": [ - "cp1254", - "cp1256", - "cp1258", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - "mbcs" - ], - "language": "French", - "alphabets": [ - "Basic Latin", - "Latin-1 Supplement" - ], - "has_sig_or_bom": false, - "chaos": 0.149, - "coherence": 97.152, - "unicode_path": null, - "is_preferred": true -} -``` - -### Python -*Just print out normalized text* -```python -from charset_normalizer import from_path - -results = from_path('./my_subtitle.srt') - -print(str(results.best())) -``` - -*Normalize any text file* -```python -from charset_normalizer import normalize -try: - normalize('./my_subtitle.srt') # should write to disk my_subtitle-***.srt -except IOError as e: - print('Sadly, we are unable to perform charset normalization.', str(e)) -``` - -*Upgrade your code without effort* -```python -from charset_normalizer import detect -``` - -The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. - -See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) - -## 😇 Why - -When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a -reliable alternative using a completely different method. Also! I never back down on a good challenge! - -I **don't care** about the **originating charset** encoding, because **two different tables** can -produce **two identical rendered string.** -What I want is to get readable text, the best I can. - -In a way, **I'm brute forcing text decoding.** How cool is that ? 😎 - -Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. - -## 🍰 How - - - Discard all charset encoding table that could not fit the binary content. - - Measure chaos, or the mess once opened (by chunks) with a corresponding charset encoding. - - Extract matches with the lowest mess detected. - - Additionally, we measure coherence / probe for a language. - -**Wait a minute**, what is chaos/mess and coherence according to **YOU ?** - -*Chaos :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then -**I established** some ground rules about **what is obvious** when **it seems like** a mess. - I know that my interpretation of what is chaotic is very subjective, feel free to contribute in order to - improve or rewrite it. - -*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought -that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. - -## ⚡ Known limitations - - - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) - - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. - -## 👤 Contributing - -Contributions, issues and feature requests are very much welcome.
-Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. - -## 📝 License - -Copyright © 2019 [Ahmed TAHRI @Ousret](https://github.com/Ousret).
-This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. - -Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) - - diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/RECORD b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/RECORD deleted file mode 100644 index 6568ddf..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/RECORD +++ /dev/null @@ -1,33 +0,0 @@ -../../../bin/normalizer,sha256=cvQIDNDw9DOwJLsKITnYoAFW6rlHOLju_1jpmDfZL0s,325 -charset_normalizer-2.0.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -charset_normalizer-2.0.12.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 -charset_normalizer-2.0.12.dist-info/METADATA,sha256=eX-U3s7nb6wcvXZFyM1mdBf1yz4I0msVBgNvLEscAbo,11713 -charset_normalizer-2.0.12.dist-info/RECORD,, -charset_normalizer-2.0.12.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 -charset_normalizer-2.0.12.dist-info/entry_points.txt,sha256=5AJq_EPtGGUwJPgQLnBZfbVr-FYCIwT0xP7dIEZO3NI,77 -charset_normalizer-2.0.12.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 -charset_normalizer/__init__.py,sha256=x2A2OW29MBcqdxsvy6t1wzkUlH3ma0guxL6ZCfS8J94,1790 -charset_normalizer/__pycache__/__init__.cpython-37.pyc,, -charset_normalizer/__pycache__/api.cpython-37.pyc,, -charset_normalizer/__pycache__/cd.cpython-37.pyc,, -charset_normalizer/__pycache__/constant.cpython-37.pyc,, -charset_normalizer/__pycache__/legacy.cpython-37.pyc,, -charset_normalizer/__pycache__/md.cpython-37.pyc,, -charset_normalizer/__pycache__/models.cpython-37.pyc,, -charset_normalizer/__pycache__/utils.cpython-37.pyc,, -charset_normalizer/__pycache__/version.cpython-37.pyc,, -charset_normalizer/api.py,sha256=r__Wz85F5pYOkRwEY5imXY_pCZ2Nil1DkdaAJY7T5o0,20303 -charset_normalizer/assets/__init__.py,sha256=FPnfk8limZRb8ZIUQcTvPEcbuM1eqOdWGw0vbWGycDs,25485 -charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc,, -charset_normalizer/cd.py,sha256=a9Kzzd9tHl_W08ExbCFMmRJqdo2k7EBQ8Z_3y9DmYsg,11076 -charset_normalizer/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc,, -charset_normalizer/cli/__pycache__/normalizer.cpython-37.pyc,, -charset_normalizer/cli/normalizer.py,sha256=LkeFIRc1l28rOgXpEby695x0bcKQv4D8z9FmA3Z2c3A,9364 -charset_normalizer/constant.py,sha256=51u_RS10I1vYVpBao__xHqf--HHNrR6me1A1se5r5Y0,19449 -charset_normalizer/legacy.py,sha256=XKeZOts_HdYQU_Jb3C9ZfOjY2CiUL132k9_nXer8gig,3384 -charset_normalizer/md.py,sha256=WEwnu2MyIiMeEaorRduqcTxGjIBclWIG3i-9_UL6LLs,18191 -charset_normalizer/models.py,sha256=XrGpVxfonhcilIWC1WeiP3-ZORGEe_RG3sgrfPLl9qM,13303 -charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -charset_normalizer/utils.py,sha256=AWSL0z1B42IwdLfjX4ZMASA9cTUsTp0PweCdW98SI-4,9308 -charset_normalizer/version.py,sha256=uxO2cT0YIavQv4dQlNGmHPIOOwOa-exspxXi3IR7dck,80 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/WHEEL b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/WHEEL deleted file mode 100644 index becc9a6..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/entry_points.txt deleted file mode 100644 index a67f60b..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -normalizer = charset_normalizer.cli.normalizer:cli_detect - diff --git a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/top_level.txt deleted file mode 100644 index 66958f0..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer-2.0.12.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -charset_normalizer diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__init__.py b/venv/lib/python3.7/site-packages/charset_normalizer/__init__.py deleted file mode 100644 index 1aea851..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf_8 -*- -""" -Charset-Normalizer -~~~~~~~~~~~~~~ -The Real First Universal Charset Detector. -A library that helps you read text from an unknown charset encoding. -Motivated by chardet, This package is trying to resolve the issue by taking a new approach. -All IANA character set names for which the Python core library provides codecs are supported. - -Basic usage: - >>> from charset_normalizer import from_bytes - >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) - >>> best_guess = results.best() - >>> str(best_guess) - 'Bсеки човек има право на образование. Oбразованието!' - -Others methods and usages are available - see the full documentation -at . -:copyright: (c) 2021 by Ahmed TAHRI -:license: MIT, see LICENSE for more details. -""" -import logging - -from .api import from_bytes, from_fp, from_path, normalize -from .legacy import ( - CharsetDetector, - CharsetDoctor, - CharsetNormalizerMatch, - CharsetNormalizerMatches, - detect, -) -from .models import CharsetMatch, CharsetMatches -from .utils import set_logging_handler -from .version import VERSION, __version__ - -__all__ = ( - "from_fp", - "from_path", - "from_bytes", - "normalize", - "detect", - "CharsetMatch", - "CharsetMatches", - "CharsetNormalizerMatch", - "CharsetNormalizerMatches", - "CharsetDetector", - "CharsetDoctor", - "__version__", - "VERSION", - "set_logging_handler", -) - -# Attach a NullHandler to the top level logger by default -# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library - -logging.getLogger("charset_normalizer").addHandler(logging.NullHandler()) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 8a80967f966832a8fb23df62f1ebff24ee99429a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1727 zcmcIkOK;>v5VkXKPhPv(U4pcS;*^ZEv0*uYMoSjY3(nP7PWu-)Agb-j1CcA1TiX)rIX7n+`2A4(*#Em} z7=LQ!@~h+F6a3}(NCLw(0yCIlrfUYZpw4D^&8_jeTjve8!JBT=G*I4PE#7w9yyJGb z# zY6_oHMSYbB+u8sY4FwSsP$5weQkF`XBpC=w0#Niz1&1QxKw`+^qc}N^!LR%Sjr}Bu z;*o9bBq|ycMFSX4N_9ZhBRB{n2`TZ9$cO?Sm6+gdPzk;*6E>#kQY&OewVfhIT1_CP z$3W6lB*YI9AY-t-G1w^ICBC8pFnEXwrxFem0motFhvieBPgIy7zC_TgsPLI_6yR0F zN_`0gbuvrSL?B$-vNnl~e8?nX>{|e^zP?@sJdM(eud)mg*Jh>K8%`9Jmj)P5#*~DQ zZs=B5HZQ)-U+2H(XK?XdexCoV8OYD_-||z)|G4-jKSkL&ke#)_yYi7o8WC!tcQ>^sgV zQeif<{e(NanG{qx|1H|OZT0;morq`@sy?jxJ$U@?<_F&`L-nP|ekxyeu z`>?Zp@Tdgve0%HZVE<{^V_dfsHZ?+&w)F;=f-!hwBJI@+OV3Bu4@IjyAErg8JfuX0 zMdzx6dW~XXI)Rr1Sj=4t5oXVn!uyB@pGsW!mPGvEFlcTa{ z7E3rc9!o|e95XM(^fM~Zto6myz5VUoLDBU*y(Tcrp4XcfdIySzCb)DAfh*DwT}@^+ znbV}BiQb~3rAb?pMNJkonMYFG^{Z`hV~%=n7cI}jvU*<8n&K&HB#kOZ*M7B2x5?;; z_>&tRuDxnFMU&%XGkFcGXk-fORQYdBL#iNYaN0Rx44rpIR6WOhP*GSU2%c3bDY^q} zyD9UdAs(VlN&X6*7ZMZX;J(D%O_&qv<)(KIHXikll1y#k+EmmT(|GLQVs+ATCB1Kd z;K)ePwdppLw=}Bbc~KlG&$H7>(SCwKWsI)hN9R(buAA+dW%FTc(VR6GYxSjn01skc A-~a#s diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/api.cpython-37.pyc deleted file mode 100644 index 84e00b59c30b09605d1f5a98b61af5b2c290334a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10950 zcmb_iOKclSdhTvEn-5Vm^?urJ%a$zK5@ma4XJ)0V2HM$(YIua zj-*LWN=u2|;@&f3u+F zzb&}Z$AXbI6noGqYDMRicFHMfC1*$*0_L=lv4@=zZNwSXMx8Nj%o*3ld4JZPa3-}$ z{+_d^oM~;^nbBr=J8#cAr?u108SRX7Ry*scn(Ca>&N*}1999*M&Km>AqILmq^T&d= zU@jb8#QUOAI2MmZU^ruz%}e;dY$|49N=Tkd=8`#M4F5Q1j2NTO)7r9e)=YmT+!)}- zjS0Y24AsnkCEO(7ri^L8tr+LN0&d!v`Ek~mHBJNSiXmeKCl*7Z?4^}ZajSO zVEv=byLY0}=K6Z|*6RD!jk_N{yt{V$ZZu3i8z0=ff4|?C-u&q1?Yp2d@0h+H(*sru zw|8{ro52TqP}_-$CtIdpR-$p;ZB_k-S+lk+)94WzQ*Z-`)DTo9j|E{RX<=BLHFhl*J8S=uE!kRw%R6Z zm**FCzZO`IS@zXXonN%gC#Fp_ByHjhGA;Wr(onz)K@x<2{nJ08zkm4F=Dl(*%K7Hw zCh5bE(tcnz{3u`BX}Wt@xot+dV27C?$Tp$^Xt#XNCat-=Wj?LhO`lq$4Q84SbpOPx zZkap!6U%F|C}Tct*t+FL3NwQyb8A_$Cj4E+r-09GeEc8h1R)SYArJ#;TRM<@HAora zksPE$;Q$-uK>UFiX4t!dvYY8-1LY_iXOCK5r-(4≥Ez|`gbD-3*+J+FyMs_d9{suEgf&n9E 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 C${Lse diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/cd.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/cd.cpython-37.pyc deleted file mode 100644 index 351fbf538a252791a855e97d8601515b60906de2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8799 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 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/legacy.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/legacy.cpython-37.pyc deleted file mode 100644 index d4d2c01784a378e5a1dd1853ee81ff924e587f7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3331 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 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/models.cpython-37.pyc deleted file mode 100644 index 4c8cd7c24c9dd13231041033733f7938fd79942b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13211 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 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index 5d2d77085a3e0ea71717d8ed2c82c5f9e31e2246..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8022 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 PeBpQ@XW+jIS^a+j>+2`Q diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/__pycache__/version.cpython-37.pyc deleted file mode 100644 index b291425feab88f9385ffd10d16ea68c5f6f85f0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 276 zcmXv}Jx{|h5VaH2qM%Al%&Z+6Lm5~QAW(-crJ{l%i{-|rCaN1-wi}WB7bF<@OIi6B zOk65B>E7Mx-n);7(I_Ek@9|x}#Q5D8{}y9%kM7S96v>F983p+E?oe_DJIH^3za z_}TCmkF)sNNu{CDypZ`;hQd@lFCgEVeRy;r1MnKEn(K1SZPT}}(rfO^02A8_HsFyj jorfSQ<91S)EjZL1&P;979pCJX+H1J&KlKcOMU4Ie+s9AP diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/api.py b/venv/lib/python3.7/site-packages/charset_normalizer/api.py deleted file mode 100644 index bdc8ed9..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/api.py +++ /dev/null @@ -1,608 +0,0 @@ -import logging -from os.path import basename, splitext -from typing import BinaryIO, List, Optional, Set - -try: - from os import PathLike -except ImportError: # pragma: no cover - PathLike = str # type: ignore - -from .cd import ( - coherence_ratio, - encoding_languages, - mb_encoding_languages, - merge_coherence_ratios, -) -from .constant import IANA_SUPPORTED, TOO_BIG_SEQUENCE, TOO_SMALL_SEQUENCE, TRACE -from .md import mess_ratio -from .models import CharsetMatch, CharsetMatches -from .utils import ( - any_specified_encoding, - iana_name, - identify_sig_or_bom, - is_cp_similar, - is_multi_byte_encoding, - should_strip_sig_or_bom, -) - -# Will most likely be controversial -# logging.addLevelName(TRACE, "TRACE") -logger = logging.getLogger("charset_normalizer") -explain_handler = logging.StreamHandler() -explain_handler.setFormatter( - logging.Formatter("%(asctime)s | %(levelname)s | %(message)s") -) - - -def from_bytes( - sequences: bytes, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.2, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False, -) -> CharsetMatches: - """ - Given a raw bytes sequence, return the best possibles charset usable to render str objects. - If there is no results, it is a strong indicator that the source is binary/not text. - By default, the process will extract 5 blocs of 512o each to assess the mess and coherence of a given sequence. - And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. - - The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page - but never take it for granted. Can improve the performance. - - You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that - purpose. - - This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. - By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' - toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. - Custom logging format and handler can be set manually. - """ - - if not isinstance(sequences, (bytearray, bytes)): - raise TypeError( - "Expected object of type bytes or bytearray, got: {0}".format( - type(sequences) - ) - ) - - if explain: - previous_logger_level = logger.level # type: int - logger.addHandler(explain_handler) - logger.setLevel(TRACE) - - length = len(sequences) # type: int - - if length == 0: - logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") - if explain: - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level or logging.WARNING) - return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) - - if cp_isolation is not None: - logger.log( - TRACE, - "cp_isolation is set. use this flag for debugging purpose. " - "limited list of encoding allowed : %s.", - ", ".join(cp_isolation), - ) - cp_isolation = [iana_name(cp, False) for cp in cp_isolation] - else: - cp_isolation = [] - - if cp_exclusion is not None: - logger.log( - TRACE, - "cp_exclusion is set. use this flag for debugging purpose. " - "limited list of encoding excluded : %s.", - ", ".join(cp_exclusion), - ) - cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] - else: - cp_exclusion = [] - - if length <= (chunk_size * steps): - logger.log( - TRACE, - "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", - steps, - chunk_size, - length, - ) - steps = 1 - chunk_size = length - - if steps > 1 and length / steps < chunk_size: - chunk_size = int(length / steps) - - is_too_small_sequence = len(sequences) < TOO_SMALL_SEQUENCE # type: bool - is_too_large_sequence = len(sequences) >= TOO_BIG_SEQUENCE # type: bool - - if is_too_small_sequence: - logger.log( - TRACE, - "Trying to detect encoding from a tiny portion of ({}) byte(s).".format( - length - ), - ) - elif is_too_large_sequence: - logger.log( - TRACE, - "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format( - length - ), - ) - - prioritized_encodings = [] # type: List[str] - - specified_encoding = ( - any_specified_encoding(sequences) if preemptive_behaviour else None - ) # type: Optional[str] - - if specified_encoding is not None: - prioritized_encodings.append(specified_encoding) - logger.log( - TRACE, - "Detected declarative mark in sequence. Priority +1 given for %s.", - specified_encoding, - ) - - tested = set() # type: Set[str] - tested_but_hard_failure = [] # type: List[str] - tested_but_soft_failure = [] # type: List[str] - - fallback_ascii = None # type: Optional[CharsetMatch] - fallback_u8 = None # type: Optional[CharsetMatch] - fallback_specified = None # type: Optional[CharsetMatch] - - results = CharsetMatches() # type: CharsetMatches - - sig_encoding, sig_payload = identify_sig_or_bom(sequences) - - if sig_encoding is not None: - prioritized_encodings.append(sig_encoding) - logger.log( - TRACE, - "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", - len(sig_payload), - sig_encoding, - ) - - prioritized_encodings.append("ascii") - - if "utf_8" not in prioritized_encodings: - prioritized_encodings.append("utf_8") - - for encoding_iana in prioritized_encodings + IANA_SUPPORTED: - - if cp_isolation and encoding_iana not in cp_isolation: - continue - - if cp_exclusion and encoding_iana in cp_exclusion: - continue - - if encoding_iana in tested: - continue - - tested.add(encoding_iana) - - decoded_payload = None # type: Optional[str] - bom_or_sig_available = sig_encoding == encoding_iana # type: bool - strip_sig_or_bom = bom_or_sig_available and should_strip_sig_or_bom( - encoding_iana - ) # type: bool - - if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: - logger.log( - TRACE, - "Encoding %s wont be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", - encoding_iana, - ) - continue - - try: - is_multi_byte_decoder = is_multi_byte_encoding(encoding_iana) # type: bool - except (ModuleNotFoundError, ImportError): - logger.log( - TRACE, - "Encoding %s does not provide an IncrementalDecoder", - encoding_iana, - ) - continue - - try: - if is_too_large_sequence and is_multi_byte_decoder is False: - str( - sequences[: int(50e4)] - if strip_sig_or_bom is False - else sequences[len(sig_payload) : int(50e4)], - encoding=encoding_iana, - ) - else: - decoded_payload = str( - sequences - if strip_sig_or_bom is False - else sequences[len(sig_payload) :], - encoding=encoding_iana, - ) - except (UnicodeDecodeError, LookupError) as e: - if not isinstance(e, LookupError): - logger.log( - TRACE, - "Code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - - similar_soft_failure_test = False # type: bool - - for encoding_soft_failed in tested_but_soft_failure: - if is_cp_similar(encoding_iana, encoding_soft_failed): - similar_soft_failure_test = True - break - - if similar_soft_failure_test: - logger.log( - TRACE, - "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", - encoding_iana, - encoding_soft_failed, - ) - continue - - r_ = range( - 0 if not bom_or_sig_available else len(sig_payload), - length, - int(length / steps), - ) - - multi_byte_bonus = ( - is_multi_byte_decoder - and decoded_payload is not None - and len(decoded_payload) < length - ) # type: bool - - if multi_byte_bonus: - logger.log( - TRACE, - "Code page %s is a multi byte encoding table and it appear that at least one character " - "was encoded using n-bytes.", - encoding_iana, - ) - - max_chunk_gave_up = int(len(r_) / 4) # type: int - - max_chunk_gave_up = max(max_chunk_gave_up, 2) - early_stop_count = 0 # type: int - lazy_str_hard_failure = False - - md_chunks = [] # type: List[str] - md_ratios = [] - - for i in r_: - if i + chunk_size > length + 8: - continue - - cut_sequence = sequences[i : i + chunk_size] - - if bom_or_sig_available and strip_sig_or_bom is False: - cut_sequence = sig_payload + cut_sequence - - try: - chunk = cut_sequence.decode( - encoding_iana, - errors="ignore" if is_multi_byte_decoder else "strict", - ) # type: str - except UnicodeDecodeError as e: # Lazy str loading may have missed something there - logger.log( - TRACE, - "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - early_stop_count = max_chunk_gave_up - lazy_str_hard_failure = True - break - - # multi-byte bad cutting detector and adjustment - # not the cleanest way to perform that fix but clever enough for now. - if is_multi_byte_decoder and i > 0 and sequences[i] >= 0x80: - - chunk_partial_size_chk = min(chunk_size, 16) # type: int - - if ( - decoded_payload - and chunk[:chunk_partial_size_chk] not in decoded_payload - ): - for j in range(i, i - 4, -1): - cut_sequence = sequences[j : i + chunk_size] - - if bom_or_sig_available and strip_sig_or_bom is False: - cut_sequence = sig_payload + cut_sequence - - chunk = cut_sequence.decode(encoding_iana, errors="ignore") - - if chunk[:chunk_partial_size_chk] in decoded_payload: - break - - md_chunks.append(chunk) - - md_ratios.append(mess_ratio(chunk, threshold)) - - if md_ratios[-1] >= threshold: - early_stop_count += 1 - - if (early_stop_count >= max_chunk_gave_up) or ( - bom_or_sig_available and strip_sig_or_bom is False - ): - break - - # We might want to check the sequence again with the whole content - # Only if initial MD tests passes - if ( - not lazy_str_hard_failure - and is_too_large_sequence - and not is_multi_byte_decoder - ): - try: - sequences[int(50e3) :].decode(encoding_iana, errors="strict") - except UnicodeDecodeError as e: - logger.log( - TRACE, - "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - - mean_mess_ratio = ( - sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 - ) # type: float - if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: - tested_but_soft_failure.append(encoding_iana) - logger.log( - TRACE, - "%s was excluded because of initial chaos probing. Gave up %i time(s). " - "Computed mean chaos is %f %%.", - encoding_iana, - early_stop_count, - round(mean_mess_ratio * 100, ndigits=3), - ) - # Preparing those fallbacks in case we got nothing. - if ( - encoding_iana in ["ascii", "utf_8", specified_encoding] - and not lazy_str_hard_failure - ): - fallback_entry = CharsetMatch( - sequences, encoding_iana, threshold, False, [], decoded_payload - ) - if encoding_iana == specified_encoding: - fallback_specified = fallback_entry - elif encoding_iana == "ascii": - fallback_ascii = fallback_entry - else: - fallback_u8 = fallback_entry - continue - - logger.log( - TRACE, - "%s passed initial chaos probing. Mean measured chaos is %f %%", - encoding_iana, - round(mean_mess_ratio * 100, ndigits=3), - ) - - if not is_multi_byte_decoder: - target_languages = encoding_languages(encoding_iana) # type: List[str] - else: - target_languages = mb_encoding_languages(encoding_iana) - - if target_languages: - logger.log( - TRACE, - "{} should target any language(s) of {}".format( - encoding_iana, str(target_languages) - ), - ) - - cd_ratios = [] - - # We shall skip the CD when its about ASCII - # Most of the time its not relevant to run "language-detection" on it. - if encoding_iana != "ascii": - for chunk in md_chunks: - chunk_languages = coherence_ratio( - chunk, 0.1, ",".join(target_languages) if target_languages else None - ) - - cd_ratios.append(chunk_languages) - - cd_ratios_merged = merge_coherence_ratios(cd_ratios) - - if cd_ratios_merged: - logger.log( - TRACE, - "We detected language {} using {}".format( - cd_ratios_merged, encoding_iana - ), - ) - - results.append( - CharsetMatch( - sequences, - encoding_iana, - mean_mess_ratio, - bom_or_sig_available, - cd_ratios_merged, - decoded_payload, - ) - ) - - if ( - encoding_iana in [specified_encoding, "ascii", "utf_8"] - and mean_mess_ratio < 0.1 - ): - logger.debug( - "Encoding detection: %s is most likely the one.", encoding_iana - ) - if explain: - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - return CharsetMatches([results[encoding_iana]]) - - if encoding_iana == sig_encoding: - logger.debug( - "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " - "the beginning of the sequence.", - encoding_iana, - ) - if explain: - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - return CharsetMatches([results[encoding_iana]]) - - if len(results) == 0: - if fallback_u8 or fallback_ascii or fallback_specified: - logger.log( - TRACE, - "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", - ) - - if fallback_specified: - logger.debug( - "Encoding detection: %s will be used as a fallback match", - fallback_specified.encoding, - ) - results.append(fallback_specified) - elif ( - (fallback_u8 and fallback_ascii is None) - or ( - fallback_u8 - and fallback_ascii - and fallback_u8.fingerprint != fallback_ascii.fingerprint - ) - or (fallback_u8 is not None) - ): - logger.debug("Encoding detection: utf_8 will be used as a fallback match") - results.append(fallback_u8) - elif fallback_ascii: - logger.debug("Encoding detection: ascii will be used as a fallback match") - results.append(fallback_ascii) - - if results: - logger.debug( - "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", - results.best().encoding, # type: ignore - len(results) - 1, - ) - else: - logger.debug("Encoding detection: Unable to determine any suitable charset.") - - if explain: - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - - return results - - -def from_fp( - fp: BinaryIO, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False, -) -> CharsetMatches: - """ - Same thing than the function from_bytes but using a file pointer that is already ready. - Will not close the file pointer. - """ - return from_bytes( - fp.read(), - steps, - chunk_size, - threshold, - cp_isolation, - cp_exclusion, - preemptive_behaviour, - explain, - ) - - -def from_path( - path: PathLike, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False, -) -> CharsetMatches: - """ - Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. - Can raise IOError. - """ - with open(path, "rb") as fp: - return from_fp( - fp, - steps, - chunk_size, - threshold, - cp_isolation, - cp_exclusion, - preemptive_behaviour, - explain, - ) - - -def normalize( - path: PathLike, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, -) -> CharsetMatch: - """ - Take a (text-based) file path and try to create another file next to it, this time using UTF-8. - """ - results = from_path( - path, - steps, - chunk_size, - threshold, - cp_isolation, - cp_exclusion, - preemptive_behaviour, - ) - - filename = basename(path) - target_extensions = list(splitext(filename)) - - if len(results) == 0: - raise IOError( - 'Unable to normalize "{}", no encoding charset seems to fit.'.format( - filename - ) - ) - - result = results.best() - - target_extensions[0] += "-" + result.encoding # type: ignore - - with open( - "{}".format(str(path).replace(filename, "".join(target_extensions))), "wb" - ) as fp: - fp.write(result.output()) # type: ignore - - return result # type: ignore diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py b/venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py deleted file mode 100644 index b2e56ff..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/assets/__init__.py +++ /dev/null @@ -1,1244 +0,0 @@ -# -*- coding: utf_8 -*- -from collections import OrderedDict - -FREQUENCIES = OrderedDict( - [ - ( - "English", - [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "u", - "m", - "f", - "p", - "g", - "w", - "y", - "b", - "v", - "k", - "x", - "j", - "z", - "q", - ], - ), - ( - "German", - [ - "e", - "n", - "i", - "r", - "s", - "t", - "a", - "d", - "h", - "u", - "l", - "g", - "o", - "c", - "m", - "b", - "f", - "k", - "w", - "z", - "p", - "v", - "ü", - "ä", - "ö", - "j", - ], - ), - ( - "French", - [ - "e", - "a", - "s", - "n", - "i", - "t", - "r", - "l", - "u", - "o", - "d", - "c", - "p", - "m", - "é", - "v", - "g", - "f", - "b", - "h", - "q", - "à", - "x", - "è", - "y", - "j", - ], - ), - ( - "Dutch", - [ - "e", - "n", - "a", - "i", - "r", - "t", - "o", - "d", - "s", - "l", - "g", - "h", - "v", - "m", - "u", - "k", - "c", - "p", - "b", - "w", - "j", - "z", - "f", - "y", - "x", - "ë", - ], - ), - ( - "Italian", - [ - "e", - "i", - "a", - "o", - "n", - "l", - "t", - "r", - "s", - "c", - "d", - "u", - "p", - "m", - "g", - "v", - "f", - "b", - "z", - "h", - "q", - "è", - "à", - "k", - "y", - "ò", - ], - ), - ( - "Polish", - [ - "a", - "i", - "o", - "e", - "n", - "r", - "z", - "w", - "s", - "c", - "t", - "k", - "y", - "d", - "p", - "m", - "u", - "l", - "j", - "ł", - "g", - "b", - "h", - "ą", - "ę", - "ó", - ], - ), - ( - "Spanish", - [ - "e", - "a", - "o", - "n", - "s", - "r", - "i", - "l", - "d", - "t", - "c", - "u", - "m", - "p", - "b", - "g", - "v", - "f", - "y", - "ó", - "h", - "q", - "í", - "j", - "z", - "á", - ], - ), - ( - "Russian", - [ - "о", - "а", - "е", - "и", - "н", - "с", - "т", - "р", - "в", - "л", - "к", - "м", - "д", - "п", - "у", - "г", - "я", - "ы", - "з", - "б", - "й", - "ь", - "ч", - "х", - "ж", - "ц", - ], - ), - ( - "Japanese", - [ - "の", - "に", - "る", - "た", - "は", - "ー", - "と", - "し", - "を", - "で", - "て", - "が", - "い", - "ン", - "れ", - "な", - "年", - "ス", - "っ", - "ル", - "か", - "ら", - "あ", - "さ", - "も", - "り", - ], - ), - ( - "Portuguese", - [ - "a", - "e", - "o", - "s", - "i", - "r", - "d", - "n", - "t", - "m", - "u", - "c", - "l", - "p", - "g", - "v", - "b", - "f", - "h", - "ã", - "q", - "é", - "ç", - "á", - "z", - "í", - ], - ), - ( - "Swedish", - [ - "e", - "a", - "n", - "r", - "t", - "s", - "i", - "l", - "d", - "o", - "m", - "k", - "g", - "v", - "h", - "f", - "u", - "p", - "ä", - "c", - "b", - "ö", - "å", - "y", - "j", - "x", - ], - ), - ( - "Chinese", - [ - "的", - "一", - "是", - "不", - "了", - "在", - "人", - "有", - "我", - "他", - "这", - "个", - "们", - "中", - "来", - "上", - "大", - "为", - "和", - "国", - "地", - "到", - "以", - "说", - "时", - "要", - "就", - "出", - "会", - ], - ), - ( - "Ukrainian", - [ - "о", - "а", - "н", - "і", - "и", - "р", - "в", - "т", - "е", - "с", - "к", - "л", - "у", - "д", - "м", - "п", - "з", - "я", - "ь", - "б", - "г", - "й", - "ч", - "х", - "ц", - "ї", - ], - ), - ( - "Norwegian", - [ - "e", - "r", - "n", - "t", - "a", - "s", - "i", - "o", - "l", - "d", - "g", - "k", - "m", - "v", - "f", - "p", - "u", - "b", - "h", - "å", - "y", - "j", - "ø", - "c", - "æ", - "w", - ], - ), - ( - "Finnish", - [ - "a", - "i", - "n", - "t", - "e", - "s", - "l", - "o", - "u", - "k", - "ä", - "m", - "r", - "v", - "j", - "h", - "p", - "y", - "d", - "ö", - "g", - "c", - "b", - "f", - "w", - "z", - ], - ), - ( - "Vietnamese", - [ - "n", - "h", - "t", - "i", - "c", - "g", - "a", - "o", - "u", - "m", - "l", - "r", - "à", - "đ", - "s", - "e", - "v", - "p", - "b", - "y", - "ư", - "d", - "á", - "k", - "ộ", - "ế", - ], - ), - ( - "Czech", - [ - "o", - "e", - "a", - "n", - "t", - "s", - "i", - "l", - "v", - "r", - "k", - "d", - "u", - "m", - "p", - "í", - "c", - "h", - "z", - "á", - "y", - "j", - "b", - "ě", - "é", - "ř", - ], - ), - ( - "Hungarian", - [ - "e", - "a", - "t", - "l", - "s", - "n", - "k", - "r", - "i", - "o", - "z", - "á", - "é", - "g", - "m", - "b", - "y", - "v", - "d", - "h", - "u", - "p", - "j", - "ö", - "f", - "c", - ], - ), - ( - "Korean", - [ - "이", - "다", - "에", - "의", - "는", - "로", - "하", - "을", - "가", - "고", - "지", - "서", - "한", - "은", - "기", - "으", - "년", - "대", - "사", - "시", - "를", - "리", - "도", - "인", - "스", - "일", - ], - ), - ( - "Indonesian", - [ - "a", - "n", - "e", - "i", - "r", - "t", - "u", - "s", - "d", - "k", - "m", - "l", - "g", - "p", - "b", - "o", - "h", - "y", - "j", - "c", - "w", - "f", - "v", - "z", - "x", - "q", - ], - ), - ( - "Turkish", - [ - "a", - "e", - "i", - "n", - "r", - "l", - "ı", - "k", - "d", - "t", - "s", - "m", - "y", - "u", - "o", - "b", - "ü", - "ş", - "v", - "g", - "z", - "h", - "c", - "p", - "ç", - "ğ", - ], - ), - ( - "Romanian", - [ - "e", - "i", - "a", - "r", - "n", - "t", - "u", - "l", - "o", - "c", - "s", - "d", - "p", - "m", - "ă", - "f", - "v", - "î", - "g", - "b", - "ș", - "ț", - "z", - "h", - "â", - "j", - ], - ), - ( - "Farsi", - [ - "ا", - "ی", - "ر", - "د", - "ن", - "ه", - "و", - "م", - "ت", - "ب", - "س", - "ل", - "ک", - "ش", - "ز", - "ف", - "گ", - "ع", - "خ", - "ق", - "ج", - "آ", - "پ", - "ح", - "ط", - "ص", - ], - ), - ( - "Arabic", - [ - "ا", - "ل", - "ي", - "م", - "و", - "ن", - "ر", - "ت", - "ب", - "ة", - "ع", - "د", - "س", - "ف", - "ه", - "ك", - "ق", - "أ", - "ح", - "ج", - "ش", - "ط", - "ص", - "ى", - "خ", - "إ", - ], - ), - ( - "Danish", - [ - "e", - "r", - "n", - "t", - "a", - "i", - "s", - "d", - "l", - "o", - "g", - "m", - "k", - "f", - "v", - "u", - "b", - "h", - "p", - "å", - "y", - "ø", - "æ", - "c", - "j", - "w", - ], - ), - ( - "Serbian", - [ - "а", - "и", - "о", - "е", - "н", - "р", - "с", - "у", - "т", - "к", - "ј", - "в", - "д", - "м", - "п", - "л", - "г", - "з", - "б", - "a", - "i", - "e", - "o", - "n", - "ц", - "ш", - ], - ), - ( - "Lithuanian", - [ - "i", - "a", - "s", - "o", - "r", - "e", - "t", - "n", - "u", - "k", - "m", - "l", - "p", - "v", - "d", - "j", - "g", - "ė", - "b", - "y", - "ų", - "š", - "ž", - "c", - "ą", - "į", - ], - ), - ( - "Slovene", - [ - "e", - "a", - "i", - "o", - "n", - "r", - "s", - "l", - "t", - "j", - "v", - "k", - "d", - "p", - "m", - "u", - "z", - "b", - "g", - "h", - "č", - "c", - "š", - "ž", - "f", - "y", - ], - ), - ( - "Slovak", - [ - "o", - "a", - "e", - "n", - "i", - "r", - "v", - "t", - "s", - "l", - "k", - "d", - "m", - "p", - "u", - "c", - "h", - "j", - "b", - "z", - "á", - "y", - "ý", - "í", - "č", - "é", - ], - ), - ( - "Hebrew", - [ - "י", - "ו", - "ה", - "ל", - "ר", - "ב", - "ת", - "מ", - "א", - "ש", - "נ", - "ע", - "ם", - "ד", - "ק", - "ח", - "פ", - "ס", - "כ", - "ג", - "ט", - "צ", - "ן", - "ז", - "ך", - ], - ), - ( - "Bulgarian", - [ - "а", - "и", - "о", - "е", - "н", - "т", - "р", - "с", - "в", - "л", - "к", - "д", - "п", - "м", - "з", - "г", - "я", - "ъ", - "у", - "б", - "ч", - "ц", - "й", - "ж", - "щ", - "х", - ], - ), - ( - "Croatian", - [ - "a", - "i", - "o", - "e", - "n", - "r", - "j", - "s", - "t", - "u", - "k", - "l", - "v", - "d", - "m", - "p", - "g", - "z", - "b", - "c", - "č", - "h", - "š", - "ž", - "ć", - "f", - ], - ), - ( - "Hindi", - [ - "क", - "र", - "स", - "न", - "त", - "म", - "ह", - "प", - "य", - "ल", - "व", - "ज", - "द", - "ग", - "ब", - "श", - "ट", - "अ", - "ए", - "थ", - "भ", - "ड", - "च", - "ध", - "ष", - "इ", - ], - ), - ( - "Estonian", - [ - "a", - "i", - "e", - "s", - "t", - "l", - "u", - "n", - "o", - "k", - "r", - "d", - "m", - "v", - "g", - "p", - "j", - "h", - "ä", - "b", - "õ", - "ü", - "f", - "c", - "ö", - "y", - ], - ), - ( - "Simple English", - [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "m", - "u", - "f", - "p", - "g", - "w", - "b", - "y", - "v", - "k", - "j", - "x", - "z", - "q", - ], - ), - ( - "Thai", - [ - "า", - "น", - "ร", - "อ", - "ก", - "เ", - "ง", - "ม", - "ย", - "ล", - "ว", - "ด", - "ท", - "ส", - "ต", - "ะ", - "ป", - "บ", - "ค", - "ห", - "แ", - "จ", - "พ", - "ช", - "ข", - "ใ", - ], - ), - ( - "Greek", - [ - "α", - "τ", - "ο", - "ι", - "ε", - "ν", - "ρ", - "σ", - "κ", - "η", - "π", - "ς", - "υ", - "μ", - "λ", - "ί", - "ό", - "ά", - "γ", - "έ", - "δ", - "ή", - "ω", - "χ", - "θ", - "ύ", - ], - ), - ( - "Tamil", - [ - "க", - "த", - "ப", - "ட", - "ர", - "ம", - "ல", - "ன", - "வ", - "ற", - "ய", - "ள", - "ச", - "ந", - "இ", - "ண", - "அ", - "ஆ", - "ழ", - "ங", - "எ", - "உ", - "ஒ", - "ஸ", - ], - ), - ( - "Classical Chinese", - [ - "之", - "年", - "為", - "也", - "以", - "一", - "人", - "其", - "者", - "國", - "有", - "二", - "十", - "於", - "曰", - "三", - "不", - "大", - "而", - "子", - "中", - "五", - "四", - ], - ), - ( - "Kazakh", - [ - "а", - "ы", - "е", - "н", - "т", - "р", - "л", - "і", - "д", - "с", - "м", - "қ", - "к", - "о", - "б", - "и", - "у", - "ғ", - "ж", - "ң", - "з", - "ш", - "й", - "п", - "г", - "ө", - ], - ), - ] -) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index a20a0afcbc547f6d89bd927f38887a9a51fbdeb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7991 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 B8`1y( diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/cd.py b/venv/lib/python3.7/site-packages/charset_normalizer/cd.py deleted file mode 100644 index 8429a0e..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/cd.py +++ /dev/null @@ -1,340 +0,0 @@ -import importlib -from codecs import IncrementalDecoder -from collections import Counter, OrderedDict -from functools import lru_cache -from typing import Dict, List, Optional, Tuple - -from .assets import FREQUENCIES -from .constant import KO_NAMES, LANGUAGE_SUPPORTED_COUNT, TOO_SMALL_SEQUENCE, ZH_NAMES -from .md import is_suspiciously_successive_range -from .models import CoherenceMatches -from .utils import ( - is_accentuated, - is_latin, - is_multi_byte_encoding, - is_unicode_range_secondary, - unicode_range, -) - - -def encoding_unicode_range(iana_name: str) -> List[str]: - """ - Return associated unicode ranges in a single byte code page. - """ - if is_multi_byte_encoding(iana_name): - raise IOError("Function not supported on multi-byte code page") - - decoder = importlib.import_module("encodings.{}".format(iana_name)).IncrementalDecoder # type: ignore - - p = decoder(errors="ignore") # type: IncrementalDecoder - seen_ranges = {} # type: Dict[str, int] - character_count = 0 # type: int - - for i in range(0x40, 0xFF): - chunk = p.decode(bytes([i])) # type: str - - if chunk: - character_range = unicode_range(chunk) # type: Optional[str] - - if character_range is None: - continue - - if is_unicode_range_secondary(character_range) is False: - if character_range not in seen_ranges: - seen_ranges[character_range] = 0 - seen_ranges[character_range] += 1 - character_count += 1 - - return sorted( - [ - character_range - for character_range in seen_ranges - if seen_ranges[character_range] / character_count >= 0.15 - ] - ) - - -def unicode_range_languages(primary_range: str) -> List[str]: - """ - Return inferred languages used with a unicode range. - """ - languages = [] # type: List[str] - - for language, characters in FREQUENCIES.items(): - for character in characters: - if unicode_range(character) == primary_range: - languages.append(language) - break - - return languages - - -@lru_cache() -def encoding_languages(iana_name: str) -> List[str]: - """ - Single-byte encoding language association. Some code page are heavily linked to particular language(s). - This function does the correspondence. - """ - unicode_ranges = encoding_unicode_range(iana_name) # type: List[str] - primary_range = None # type: Optional[str] - - for specified_range in unicode_ranges: - if "Latin" not in specified_range: - primary_range = specified_range - break - - if primary_range is None: - return ["Latin Based"] - - return unicode_range_languages(primary_range) - - -@lru_cache() -def mb_encoding_languages(iana_name: str) -> List[str]: - """ - Multi-byte encoding language association. Some code page are heavily linked to particular language(s). - This function does the correspondence. - """ - if ( - iana_name.startswith("shift_") - or iana_name.startswith("iso2022_jp") - or iana_name.startswith("euc_j") - or iana_name == "cp932" - ): - return ["Japanese"] - if iana_name.startswith("gb") or iana_name in ZH_NAMES: - return ["Chinese", "Classical Chinese"] - if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: - return ["Korean"] - - return [] - - -@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) -def get_target_features(language: str) -> Tuple[bool, bool]: - """ - Determine main aspects from a supported language if it contains accents and if is pure Latin. - """ - target_have_accents = False # type: bool - target_pure_latin = True # type: bool - - for character in FREQUENCIES[language]: - if not target_have_accents and is_accentuated(character): - target_have_accents = True - if target_pure_latin and is_latin(character) is False: - target_pure_latin = False - - return target_have_accents, target_pure_latin - - -def alphabet_languages( - characters: List[str], ignore_non_latin: bool = False -) -> List[str]: - """ - Return associated languages associated to given characters. - """ - languages = [] # type: List[Tuple[str, float]] - - source_have_accents = any(is_accentuated(character) for character in characters) - - for language, language_characters in FREQUENCIES.items(): - - target_have_accents, target_pure_latin = get_target_features(language) - - if ignore_non_latin and target_pure_latin is False: - continue - - if target_have_accents is False and source_have_accents: - continue - - character_count = len(language_characters) # type: int - - character_match_count = len( - [c for c in language_characters if c in characters] - ) # type: int - - ratio = character_match_count / character_count # type: float - - if ratio >= 0.2: - languages.append((language, ratio)) - - languages = sorted(languages, key=lambda x: x[1], reverse=True) - - return [compatible_language[0] for compatible_language in languages] - - -def characters_popularity_compare( - language: str, ordered_characters: List[str] -) -> float: - """ - Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. - The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). - Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) - """ - if language not in FREQUENCIES: - raise ValueError("{} not available".format(language)) - - character_approved_count = 0 # type: int - - for character in ordered_characters: - if character not in FREQUENCIES[language]: - continue - - characters_before_source = FREQUENCIES[language][ - 0 : FREQUENCIES[language].index(character) - ] # type: List[str] - characters_after_source = FREQUENCIES[language][ - FREQUENCIES[language].index(character) : - ] # type: List[str] - - characters_before = ordered_characters[ - 0 : ordered_characters.index(character) - ] # type: List[str] - characters_after = ordered_characters[ - ordered_characters.index(character) : - ] # type: List[str] - - before_match_count = [ - e in characters_before for e in characters_before_source - ].count( - True - ) # type: int - after_match_count = [ - e in characters_after for e in characters_after_source - ].count( - True - ) # type: int - - if len(characters_before_source) == 0 and before_match_count <= 4: - character_approved_count += 1 - continue - - if len(characters_after_source) == 0 and after_match_count <= 4: - character_approved_count += 1 - continue - - if ( - before_match_count / len(characters_before_source) >= 0.4 - or after_match_count / len(characters_after_source) >= 0.4 - ): - character_approved_count += 1 - continue - - return character_approved_count / len(ordered_characters) - - -def alpha_unicode_split(decoded_sequence: str) -> List[str]: - """ - Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. - Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; - One containing the latin letters and the other hebrew. - """ - layers = OrderedDict() # type: Dict[str, str] - - for character in decoded_sequence: - if character.isalpha() is False: - continue - - character_range = unicode_range(character) # type: Optional[str] - - if character_range is None: - continue - - layer_target_range = None # type: Optional[str] - - for discovered_range in layers: - if ( - is_suspiciously_successive_range(discovered_range, character_range) - is False - ): - layer_target_range = discovered_range - break - - if layer_target_range is None: - layer_target_range = character_range - - if layer_target_range not in layers: - layers[layer_target_range] = character.lower() - continue - - layers[layer_target_range] += character.lower() - - return list(layers.values()) - - -def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: - """ - This function merge results previously given by the function coherence_ratio. - The return type is the same as coherence_ratio. - """ - per_language_ratios = OrderedDict() # type: Dict[str, List[float]] - for result in results: - for sub_result in result: - language, ratio = sub_result - if language not in per_language_ratios: - per_language_ratios[language] = [ratio] - continue - per_language_ratios[language].append(ratio) - - merge = [ - ( - language, - round( - sum(per_language_ratios[language]) / len(per_language_ratios[language]), - 4, - ), - ) - for language in per_language_ratios - ] - - return sorted(merge, key=lambda x: x[1], reverse=True) - - -@lru_cache(maxsize=2048) -def coherence_ratio( - decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None -) -> CoherenceMatches: - """ - Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. - A layer = Character extraction by alphabets/ranges. - """ - - results = [] # type: List[Tuple[str, float]] - ignore_non_latin = False # type: bool - - sufficient_match_count = 0 # type: int - - lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] - if "Latin Based" in lg_inclusion_list: - ignore_non_latin = True - lg_inclusion_list.remove("Latin Based") - - for layer in alpha_unicode_split(decoded_sequence): - sequence_frequencies = Counter(layer) # type: Counter - most_common = sequence_frequencies.most_common() - - character_count = sum(o for c, o in most_common) # type: int - - if character_count <= TOO_SMALL_SEQUENCE: - continue - - popular_character_ordered = [c for c, o in most_common] # type: List[str] - - for language in lg_inclusion_list or alphabet_languages( - popular_character_ordered, ignore_non_latin - ): - ratio = characters_popularity_compare( - language, popular_character_ordered - ) # type: float - - if ratio < threshold: - continue - elif ratio >= 0.8: - sufficient_match_count += 1 - - results.append((language, round(ratio, 4))) - - if sufficient_match_count >= 3: - break - - return sorted(results, key=lambda x: x[1], reverse=True) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py b/venv/lib/python3.7/site-packages/charset_normalizer/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 07f0a3b0a9a1a3e4c1f19c9286ed965ebb98657c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218 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 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py b/venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py deleted file mode 100644 index 5f912c9..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/cli/normalizer.py +++ /dev/null @@ -1,290 +0,0 @@ -import argparse -import sys -from json import dumps -from os.path import abspath -from platform import python_version -from typing import List - -from charset_normalizer import from_fp -from charset_normalizer.models import CliDetectionResult -from charset_normalizer.version import __version__ - - -def query_yes_no(question: str, default: str = "yes") -> bool: - """Ask a yes/no question via input() and return their answer. - - "question" is a string that is presented to the user. - "default" is the presumed answer if the user just hits . - It must be "yes" (the default), "no" or None (meaning - an answer is required of the user). - - The "answer" return value is True for "yes" or False for "no". - - Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input - """ - valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} - if default is None: - prompt = " [y/n] " - elif default == "yes": - prompt = " [Y/n] " - elif default == "no": - prompt = " [y/N] " - else: - raise ValueError("invalid default answer: '%s'" % default) - - while True: - sys.stdout.write(question + prompt) - choice = input().lower() - if default is not None and choice == "": - return valid[default] - elif choice in valid: - return valid[choice] - else: - sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") - - -def cli_detect(argv: List[str] = None) -> int: - """ - CLI assistant using ARGV and ArgumentParser - :param argv: - :return: 0 if everything is fine, anything else equal trouble - """ - parser = argparse.ArgumentParser( - description="The Real First Universal Charset Detector. " - "Discover originating encoding used on text file. " - "Normalize text to unicode." - ) - - parser.add_argument( - "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed" - ) - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - dest="verbose", - help="Display complementary information about file if any. " - "Stdout will contain logs about the detection process.", - ) - parser.add_argument( - "-a", - "--with-alternative", - action="store_true", - default=False, - dest="alternatives", - help="Output complementary possibilities if any. Top-level JSON WILL be a list.", - ) - parser.add_argument( - "-n", - "--normalize", - action="store_true", - default=False, - dest="normalize", - help="Permit to normalize input file. If not set, program does not write anything.", - ) - parser.add_argument( - "-m", - "--minimal", - action="store_true", - default=False, - dest="minimal", - help="Only output the charset detected to STDOUT. Disabling JSON output.", - ) - parser.add_argument( - "-r", - "--replace", - action="store_true", - default=False, - dest="replace", - help="Replace file when trying to normalize it instead of creating a new one.", - ) - parser.add_argument( - "-f", - "--force", - action="store_true", - default=False, - dest="force", - help="Replace file without asking if you are sure, use this flag with caution.", - ) - parser.add_argument( - "-t", - "--threshold", - action="store", - default=0.1, - type=float, - dest="threshold", - help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.", - ) - parser.add_argument( - "--version", - action="version", - version="Charset-Normalizer {} - Python {}".format( - __version__, python_version() - ), - help="Show version information and exit.", - ) - - args = parser.parse_args(argv) - - if args.replace is True and args.normalize is False: - print("Use --replace in addition of --normalize only.", file=sys.stderr) - return 1 - - if args.force is True and args.replace is False: - print("Use --force in addition of --replace only.", file=sys.stderr) - return 1 - - if args.threshold < 0.0 or args.threshold > 1.0: - print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr) - return 1 - - x_ = [] - - for my_file in args.files: - - matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose) - - best_guess = matches.best() - - if best_guess is None: - print( - 'Unable to identify originating encoding for "{}". {}'.format( - my_file.name, - "Maybe try increasing maximum amount of chaos." - if args.threshold < 1.0 - else "", - ), - file=sys.stderr, - ) - x_.append( - CliDetectionResult( - abspath(my_file.name), - None, - [], - [], - "Unknown", - [], - False, - 1.0, - 0.0, - None, - True, - ) - ) - else: - x_.append( - CliDetectionResult( - abspath(my_file.name), - best_guess.encoding, - best_guess.encoding_aliases, - [ - cp - for cp in best_guess.could_be_from_charset - if cp != best_guess.encoding - ], - best_guess.language, - best_guess.alphabets, - best_guess.bom, - best_guess.percent_chaos, - best_guess.percent_coherence, - None, - True, - ) - ) - - if len(matches) > 1 and args.alternatives: - for el in matches: - if el != best_guess: - x_.append( - CliDetectionResult( - abspath(my_file.name), - el.encoding, - el.encoding_aliases, - [ - cp - for cp in el.could_be_from_charset - if cp != el.encoding - ], - el.language, - el.alphabets, - el.bom, - el.percent_chaos, - el.percent_coherence, - None, - False, - ) - ) - - if args.normalize is True: - - if best_guess.encoding.startswith("utf") is True: - print( - '"{}" file does not need to be normalized, as it already came from unicode.'.format( - my_file.name - ), - file=sys.stderr, - ) - if my_file.closed is False: - my_file.close() - continue - - o_ = my_file.name.split(".") # type: List[str] - - if args.replace is False: - o_.insert(-1, best_guess.encoding) - if my_file.closed is False: - my_file.close() - elif ( - args.force is False - and query_yes_no( - 'Are you sure to normalize "{}" by replacing it ?'.format( - my_file.name - ), - "no", - ) - is False - ): - if my_file.closed is False: - my_file.close() - continue - - try: - x_[0].unicode_path = abspath("./{}".format(".".join(o_))) - - with open(x_[0].unicode_path, "w", encoding="utf-8") as fp: - fp.write(str(best_guess)) - except IOError as e: - print(str(e), file=sys.stderr) - if my_file.closed is False: - my_file.close() - return 2 - - if my_file.closed is False: - my_file.close() - - if args.minimal is False: - print( - dumps( - [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__, - ensure_ascii=True, - indent=4, - ) - ) - else: - for my_file in args.files: - print( - ", ".join( - [ - el.encoding or "undefined" - for el in x_ - if el.path == abspath(my_file.name) - ] - ) - ) - - return 0 - - -if __name__ == "__main__": - cli_detect() diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/constant.py b/venv/lib/python3.7/site-packages/charset_normalizer/constant.py deleted file mode 100644 index c32f5cf..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/constant.py +++ /dev/null @@ -1,503 +0,0 @@ -from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE -from collections import OrderedDict -from encodings.aliases import aliases -from re import IGNORECASE, compile as re_compile -from typing import Dict, List, Set, Union - -from .assets import FREQUENCIES - -# Contain for each eligible encoding a list of/item bytes SIG/BOM -ENCODING_MARKS = OrderedDict( - [ - ("utf_8", BOM_UTF8), - ( - "utf_7", - [ - b"\x2b\x2f\x76\x38", - b"\x2b\x2f\x76\x39", - b"\x2b\x2f\x76\x2b", - b"\x2b\x2f\x76\x2f", - b"\x2b\x2f\x76\x38\x2d", - ], - ), - ("gb18030", b"\x84\x31\x95\x33"), - ("utf_32", [BOM_UTF32_BE, BOM_UTF32_LE]), - ("utf_16", [BOM_UTF16_BE, BOM_UTF16_LE]), - ] -) # type: Dict[str, Union[bytes, List[bytes]]] - -TOO_SMALL_SEQUENCE = 32 # type: int -TOO_BIG_SEQUENCE = int(10e6) # type: int - -UTF8_MAXIMAL_ALLOCATION = 1112064 # type: int - -UNICODE_RANGES_COMBINED = { - "Control character": range(31 + 1), - "Basic Latin": range(32, 127 + 1), - "Latin-1 Supplement": range(128, 255 + 1), - "Latin Extended-A": range(256, 383 + 1), - "Latin Extended-B": range(384, 591 + 1), - "IPA Extensions": range(592, 687 + 1), - "Spacing Modifier Letters": range(688, 767 + 1), - "Combining Diacritical Marks": range(768, 879 + 1), - "Greek and Coptic": range(880, 1023 + 1), - "Cyrillic": range(1024, 1279 + 1), - "Cyrillic Supplement": range(1280, 1327 + 1), - "Armenian": range(1328, 1423 + 1), - "Hebrew": range(1424, 1535 + 1), - "Arabic": range(1536, 1791 + 1), - "Syriac": range(1792, 1871 + 1), - "Arabic Supplement": range(1872, 1919 + 1), - "Thaana": range(1920, 1983 + 1), - "NKo": range(1984, 2047 + 1), - "Samaritan": range(2048, 2111 + 1), - "Mandaic": range(2112, 2143 + 1), - "Syriac Supplement": range(2144, 2159 + 1), - "Arabic Extended-A": range(2208, 2303 + 1), - "Devanagari": range(2304, 2431 + 1), - "Bengali": range(2432, 2559 + 1), - "Gurmukhi": range(2560, 2687 + 1), - "Gujarati": range(2688, 2815 + 1), - "Oriya": range(2816, 2943 + 1), - "Tamil": range(2944, 3071 + 1), - "Telugu": range(3072, 3199 + 1), - "Kannada": range(3200, 3327 + 1), - "Malayalam": range(3328, 3455 + 1), - "Sinhala": range(3456, 3583 + 1), - "Thai": range(3584, 3711 + 1), - "Lao": range(3712, 3839 + 1), - "Tibetan": range(3840, 4095 + 1), - "Myanmar": range(4096, 4255 + 1), - "Georgian": range(4256, 4351 + 1), - "Hangul Jamo": range(4352, 4607 + 1), - "Ethiopic": range(4608, 4991 + 1), - "Ethiopic Supplement": range(4992, 5023 + 1), - "Cherokee": range(5024, 5119 + 1), - "Unified Canadian Aboriginal Syllabics": range(5120, 5759 + 1), - "Ogham": range(5760, 5791 + 1), - "Runic": range(5792, 5887 + 1), - "Tagalog": range(5888, 5919 + 1), - "Hanunoo": range(5920, 5951 + 1), - "Buhid": range(5952, 5983 + 1), - "Tagbanwa": range(5984, 6015 + 1), - "Khmer": range(6016, 6143 + 1), - "Mongolian": range(6144, 6319 + 1), - "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6399 + 1), - "Limbu": range(6400, 6479 + 1), - "Tai Le": range(6480, 6527 + 1), - "New Tai Lue": range(6528, 6623 + 1), - "Khmer Symbols": range(6624, 6655 + 1), - "Buginese": range(6656, 6687 + 1), - "Tai Tham": range(6688, 6831 + 1), - "Combining Diacritical Marks Extended": range(6832, 6911 + 1), - "Balinese": range(6912, 7039 + 1), - "Sundanese": range(7040, 7103 + 1), - "Batak": range(7104, 7167 + 1), - "Lepcha": range(7168, 7247 + 1), - "Ol Chiki": range(7248, 7295 + 1), - "Cyrillic Extended C": range(7296, 7311 + 1), - "Sundanese Supplement": range(7360, 7375 + 1), - "Vedic Extensions": range(7376, 7423 + 1), - "Phonetic Extensions": range(7424, 7551 + 1), - "Phonetic Extensions Supplement": range(7552, 7615 + 1), - "Combining Diacritical Marks Supplement": range(7616, 7679 + 1), - "Latin Extended Additional": range(7680, 7935 + 1), - "Greek Extended": range(7936, 8191 + 1), - "General Punctuation": range(8192, 8303 + 1), - "Superscripts and Subscripts": range(8304, 8351 + 1), - "Currency Symbols": range(8352, 8399 + 1), - "Combining Diacritical Marks for Symbols": range(8400, 8447 + 1), - "Letterlike Symbols": range(8448, 8527 + 1), - "Number Forms": range(8528, 8591 + 1), - "Arrows": range(8592, 8703 + 1), - "Mathematical Operators": range(8704, 8959 + 1), - "Miscellaneous Technical": range(8960, 9215 + 1), - "Control Pictures": range(9216, 9279 + 1), - "Optical Character Recognition": range(9280, 9311 + 1), - "Enclosed Alphanumerics": range(9312, 9471 + 1), - "Box Drawing": range(9472, 9599 + 1), - "Block Elements": range(9600, 9631 + 1), - "Geometric Shapes": range(9632, 9727 + 1), - "Miscellaneous Symbols": range(9728, 9983 + 1), - "Dingbats": range(9984, 10175 + 1), - "Miscellaneous Mathematical Symbols-A": range(10176, 10223 + 1), - "Supplemental Arrows-A": range(10224, 10239 + 1), - "Braille Patterns": range(10240, 10495 + 1), - "Supplemental Arrows-B": range(10496, 10623 + 1), - "Miscellaneous Mathematical Symbols-B": range(10624, 10751 + 1), - "Supplemental Mathematical Operators": range(10752, 11007 + 1), - "Miscellaneous Symbols and Arrows": range(11008, 11263 + 1), - "Glagolitic": range(11264, 11359 + 1), - "Latin Extended-C": range(11360, 11391 + 1), - "Coptic": range(11392, 11519 + 1), - "Georgian Supplement": range(11520, 11567 + 1), - "Tifinagh": range(11568, 11647 + 1), - "Ethiopic Extended": range(11648, 11743 + 1), - "Cyrillic Extended-A": range(11744, 11775 + 1), - "Supplemental Punctuation": range(11776, 11903 + 1), - "CJK Radicals Supplement": range(11904, 12031 + 1), - "Kangxi Radicals": range(12032, 12255 + 1), - "Ideographic Description Characters": range(12272, 12287 + 1), - "CJK Symbols and Punctuation": range(12288, 12351 + 1), - "Hiragana": range(12352, 12447 + 1), - "Katakana": range(12448, 12543 + 1), - "Bopomofo": range(12544, 12591 + 1), - "Hangul Compatibility Jamo": range(12592, 12687 + 1), - "Kanbun": range(12688, 12703 + 1), - "Bopomofo Extended": range(12704, 12735 + 1), - "CJK Strokes": range(12736, 12783 + 1), - "Katakana Phonetic Extensions": range(12784, 12799 + 1), - "Enclosed CJK Letters and Months": range(12800, 13055 + 1), - "CJK Compatibility": range(13056, 13311 + 1), - "CJK Unified Ideographs Extension A": range(13312, 19903 + 1), - "Yijing Hexagram Symbols": range(19904, 19967 + 1), - "CJK Unified Ideographs": range(19968, 40959 + 1), - "Yi Syllables": range(40960, 42127 + 1), - "Yi Radicals": range(42128, 42191 + 1), - "Lisu": range(42192, 42239 + 1), - "Vai": range(42240, 42559 + 1), - "Cyrillic Extended-B": range(42560, 42655 + 1), - "Bamum": range(42656, 42751 + 1), - "Modifier Tone Letters": range(42752, 42783 + 1), - "Latin Extended-D": range(42784, 43007 + 1), - "Syloti Nagri": range(43008, 43055 + 1), - "Common Indic Number Forms": range(43056, 43071 + 1), - "Phags-pa": range(43072, 43135 + 1), - "Saurashtra": range(43136, 43231 + 1), - "Devanagari Extended": range(43232, 43263 + 1), - "Kayah Li": range(43264, 43311 + 1), - "Rejang": range(43312, 43359 + 1), - "Hangul Jamo Extended-A": range(43360, 43391 + 1), - "Javanese": range(43392, 43487 + 1), - "Myanmar Extended-B": range(43488, 43519 + 1), - "Cham": range(43520, 43615 + 1), - "Myanmar Extended-A": range(43616, 43647 + 1), - "Tai Viet": range(43648, 43743 + 1), - "Meetei Mayek Extensions": range(43744, 43775 + 1), - "Ethiopic Extended-A": range(43776, 43823 + 1), - "Latin Extended-E": range(43824, 43887 + 1), - "Cherokee Supplement": range(43888, 43967 + 1), - "Meetei Mayek": range(43968, 44031 + 1), - "Hangul Syllables": range(44032, 55215 + 1), - "Hangul Jamo Extended-B": range(55216, 55295 + 1), - "High Surrogates": range(55296, 56191 + 1), - "High Private Use Surrogates": range(56192, 56319 + 1), - "Low Surrogates": range(56320, 57343 + 1), - "Private Use Area": range(57344, 63743 + 1), - "CJK Compatibility Ideographs": range(63744, 64255 + 1), - "Alphabetic Presentation Forms": range(64256, 64335 + 1), - "Arabic Presentation Forms-A": range(64336, 65023 + 1), - "Variation Selectors": range(65024, 65039 + 1), - "Vertical Forms": range(65040, 65055 + 1), - "Combining Half Marks": range(65056, 65071 + 1), - "CJK Compatibility Forms": range(65072, 65103 + 1), - "Small Form Variants": range(65104, 65135 + 1), - "Arabic Presentation Forms-B": range(65136, 65279 + 1), - "Halfwidth and Fullwidth Forms": range(65280, 65519 + 1), - "Specials": range(65520, 65535 + 1), - "Linear B Syllabary": range(65536, 65663 + 1), - "Linear B Ideograms": range(65664, 65791 + 1), - "Aegean Numbers": range(65792, 65855 + 1), - "Ancient Greek Numbers": range(65856, 65935 + 1), - "Ancient Symbols": range(65936, 65999 + 1), - "Phaistos Disc": range(66000, 66047 + 1), - "Lycian": range(66176, 66207 + 1), - "Carian": range(66208, 66271 + 1), - "Coptic Epact Numbers": range(66272, 66303 + 1), - "Old Italic": range(66304, 66351 + 1), - "Gothic": range(66352, 66383 + 1), - "Old Permic": range(66384, 66431 + 1), - "Ugaritic": range(66432, 66463 + 1), - "Old Persian": range(66464, 66527 + 1), - "Deseret": range(66560, 66639 + 1), - "Shavian": range(66640, 66687 + 1), - "Osmanya": range(66688, 66735 + 1), - "Osage": range(66736, 66815 + 1), - "Elbasan": range(66816, 66863 + 1), - "Caucasian Albanian": range(66864, 66927 + 1), - "Linear A": range(67072, 67455 + 1), - "Cypriot Syllabary": range(67584, 67647 + 1), - "Imperial Aramaic": range(67648, 67679 + 1), - "Palmyrene": range(67680, 67711 + 1), - "Nabataean": range(67712, 67759 + 1), - "Hatran": range(67808, 67839 + 1), - "Phoenician": range(67840, 67871 + 1), - "Lydian": range(67872, 67903 + 1), - "Meroitic Hieroglyphs": range(67968, 67999 + 1), - "Meroitic Cursive": range(68000, 68095 + 1), - "Kharoshthi": range(68096, 68191 + 1), - "Old South Arabian": range(68192, 68223 + 1), - "Old North Arabian": range(68224, 68255 + 1), - "Manichaean": range(68288, 68351 + 1), - "Avestan": range(68352, 68415 + 1), - "Inscriptional Parthian": range(68416, 68447 + 1), - "Inscriptional Pahlavi": range(68448, 68479 + 1), - "Psalter Pahlavi": range(68480, 68527 + 1), - "Old Turkic": range(68608, 68687 + 1), - "Old Hungarian": range(68736, 68863 + 1), - "Rumi Numeral Symbols": range(69216, 69247 + 1), - "Brahmi": range(69632, 69759 + 1), - "Kaithi": range(69760, 69839 + 1), - "Sora Sompeng": range(69840, 69887 + 1), - "Chakma": range(69888, 69967 + 1), - "Mahajani": range(69968, 70015 + 1), - "Sharada": range(70016, 70111 + 1), - "Sinhala Archaic Numbers": range(70112, 70143 + 1), - "Khojki": range(70144, 70223 + 1), - "Multani": range(70272, 70319 + 1), - "Khudawadi": range(70320, 70399 + 1), - "Grantha": range(70400, 70527 + 1), - "Newa": range(70656, 70783 + 1), - "Tirhuta": range(70784, 70879 + 1), - "Siddham": range(71040, 71167 + 1), - "Modi": range(71168, 71263 + 1), - "Mongolian Supplement": range(71264, 71295 + 1), - "Takri": range(71296, 71375 + 1), - "Ahom": range(71424, 71487 + 1), - "Warang Citi": range(71840, 71935 + 1), - "Zanabazar Square": range(72192, 72271 + 1), - "Soyombo": range(72272, 72367 + 1), - "Pau Cin Hau": range(72384, 72447 + 1), - "Bhaiksuki": range(72704, 72815 + 1), - "Marchen": range(72816, 72895 + 1), - "Masaram Gondi": range(72960, 73055 + 1), - "Cuneiform": range(73728, 74751 + 1), - "Cuneiform Numbers and Punctuation": range(74752, 74879 + 1), - "Early Dynastic Cuneiform": range(74880, 75087 + 1), - "Egyptian Hieroglyphs": range(77824, 78895 + 1), - "Anatolian Hieroglyphs": range(82944, 83583 + 1), - "Bamum Supplement": range(92160, 92735 + 1), - "Mro": range(92736, 92783 + 1), - "Bassa Vah": range(92880, 92927 + 1), - "Pahawh Hmong": range(92928, 93071 + 1), - "Miao": range(93952, 94111 + 1), - "Ideographic Symbols and Punctuation": range(94176, 94207 + 1), - "Tangut": range(94208, 100351 + 1), - "Tangut Components": range(100352, 101119 + 1), - "Kana Supplement": range(110592, 110847 + 1), - "Kana Extended-A": range(110848, 110895 + 1), - "Nushu": range(110960, 111359 + 1), - "Duployan": range(113664, 113823 + 1), - "Shorthand Format Controls": range(113824, 113839 + 1), - "Byzantine Musical Symbols": range(118784, 119039 + 1), - "Musical Symbols": range(119040, 119295 + 1), - "Ancient Greek Musical Notation": range(119296, 119375 + 1), - "Tai Xuan Jing Symbols": range(119552, 119647 + 1), - "Counting Rod Numerals": range(119648, 119679 + 1), - "Mathematical Alphanumeric Symbols": range(119808, 120831 + 1), - "Sutton SignWriting": range(120832, 121519 + 1), - "Glagolitic Supplement": range(122880, 122927 + 1), - "Mende Kikakui": range(124928, 125151 + 1), - "Adlam": range(125184, 125279 + 1), - "Arabic Mathematical Alphabetic Symbols": range(126464, 126719 + 1), - "Mahjong Tiles": range(126976, 127023 + 1), - "Domino Tiles": range(127024, 127135 + 1), - "Playing Cards": range(127136, 127231 + 1), - "Enclosed Alphanumeric Supplement": range(127232, 127487 + 1), - "Enclosed Ideographic Supplement": range(127488, 127743 + 1), - "Miscellaneous Symbols and Pictographs": range(127744, 128511 + 1), - "Emoticons range(Emoji)": range(128512, 128591 + 1), - "Ornamental Dingbats": range(128592, 128639 + 1), - "Transport and Map Symbols": range(128640, 128767 + 1), - "Alchemical Symbols": range(128768, 128895 + 1), - "Geometric Shapes Extended": range(128896, 129023 + 1), - "Supplemental Arrows-C": range(129024, 129279 + 1), - "Supplemental Symbols and Pictographs": range(129280, 129535 + 1), - "CJK Unified Ideographs Extension B": range(131072, 173791 + 1), - "CJK Unified Ideographs Extension C": range(173824, 177983 + 1), - "CJK Unified Ideographs Extension D": range(177984, 178207 + 1), - "CJK Unified Ideographs Extension E": range(178208, 183983 + 1), - "CJK Unified Ideographs Extension F": range(183984, 191471 + 1), - "CJK Compatibility Ideographs Supplement": range(194560, 195103 + 1), - "Tags": range(917504, 917631 + 1), - "Variation Selectors Supplement": range(917760, 917999 + 1), -} # type: Dict[str, range] - - -UNICODE_SECONDARY_RANGE_KEYWORD = [ - "Supplement", - "Extended", - "Extensions", - "Modifier", - "Marks", - "Punctuation", - "Symbols", - "Forms", - "Operators", - "Miscellaneous", - "Drawing", - "Block", - "Shapes", - "Supplemental", - "Tags", -] # type: List[str] - -RE_POSSIBLE_ENCODING_INDICATION = re_compile( - r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", - IGNORECASE, -) - -IANA_SUPPORTED = sorted( - filter( - lambda x: x.endswith("_codec") is False - and x not in {"rot_13", "tactis", "mbcs"}, - list(set(aliases.values())), - ) -) # type: List[str] - -IANA_SUPPORTED_COUNT = len(IANA_SUPPORTED) # type: int - -# pre-computed code page that are similar using the function cp_similarity. -IANA_SUPPORTED_SIMILAR = { - "cp037": ["cp1026", "cp1140", "cp273", "cp500"], - "cp1026": ["cp037", "cp1140", "cp273", "cp500"], - "cp1125": ["cp866"], - "cp1140": ["cp037", "cp1026", "cp273", "cp500"], - "cp1250": ["iso8859_2"], - "cp1251": ["kz1048", "ptcp154"], - "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], - "cp1253": ["iso8859_7"], - "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], - "cp1257": ["iso8859_13"], - "cp273": ["cp037", "cp1026", "cp1140", "cp500"], - "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], - "cp500": ["cp037", "cp1026", "cp1140", "cp273"], - "cp850": ["cp437", "cp857", "cp858", "cp865"], - "cp857": ["cp850", "cp858", "cp865"], - "cp858": ["cp437", "cp850", "cp857", "cp865"], - "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], - "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], - "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], - "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], - "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], - "cp866": ["cp1125"], - "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], - "iso8859_11": ["tis_620"], - "iso8859_13": ["cp1257"], - "iso8859_14": [ - "iso8859_10", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_15": [ - "cp1252", - "cp1254", - "iso8859_10", - "iso8859_14", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_16": [ - "iso8859_14", - "iso8859_15", - "iso8859_2", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], - "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], - "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], - "iso8859_7": ["cp1253"], - "iso8859_9": [ - "cp1252", - "cp1254", - "cp1258", - "iso8859_10", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_4", - "latin_1", - ], - "kz1048": ["cp1251", "ptcp154"], - "latin_1": [ - "cp1252", - "cp1254", - "cp1258", - "iso8859_10", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_4", - "iso8859_9", - ], - "mac_iceland": ["mac_roman", "mac_turkish"], - "mac_roman": ["mac_iceland", "mac_turkish"], - "mac_turkish": ["mac_iceland", "mac_roman"], - "ptcp154": ["cp1251", "kz1048"], - "tis_620": ["iso8859_11"], -} # type: Dict[str, List[str]] - - -CHARDET_CORRESPONDENCE = { - "iso2022_kr": "ISO-2022-KR", - "iso2022_jp": "ISO-2022-JP", - "euc_kr": "EUC-KR", - "tis_620": "TIS-620", - "utf_32": "UTF-32", - "euc_jp": "EUC-JP", - "koi8_r": "KOI8-R", - "iso8859_1": "ISO-8859-1", - "iso8859_2": "ISO-8859-2", - "iso8859_5": "ISO-8859-5", - "iso8859_6": "ISO-8859-6", - "iso8859_7": "ISO-8859-7", - "iso8859_8": "ISO-8859-8", - "utf_16": "UTF-16", - "cp855": "IBM855", - "mac_cyrillic": "MacCyrillic", - "gb2312": "GB2312", - "gb18030": "GB18030", - "cp932": "CP932", - "cp866": "IBM866", - "utf_8": "utf-8", - "utf_8_sig": "UTF-8-SIG", - "shift_jis": "SHIFT_JIS", - "big5": "Big5", - "cp1250": "windows-1250", - "cp1251": "windows-1251", - "cp1252": "Windows-1252", - "cp1253": "windows-1253", - "cp1255": "windows-1255", - "cp1256": "windows-1256", - "cp1254": "Windows-1254", - "cp949": "CP949", -} # type: Dict[str, str] - - -COMMON_SAFE_ASCII_CHARACTERS = { - "<", - ">", - "=", - ":", - "/", - "&", - ";", - "{", - "}", - "[", - "]", - ",", - "|", - '"', - "-", -} # type: Set[str] - - -KO_NAMES = {"johab", "cp949", "euc_kr"} # type: Set[str] -ZH_NAMES = {"big5", "cp950", "big5hkscs", "hz"} # type: Set[str] - -NOT_PRINTABLE_PATTERN = re_compile(r"[0-9\W\n\r\t]+") - -LANGUAGE_SUPPORTED_COUNT = len(FREQUENCIES) # type: int - -# Logging LEVEL bellow DEBUG -TRACE = 5 # type: int diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/legacy.py b/venv/lib/python3.7/site-packages/charset_normalizer/legacy.py deleted file mode 100644 index cdebe2b..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/legacy.py +++ /dev/null @@ -1,95 +0,0 @@ -import warnings -from typing import Dict, Optional, Union - -from .api import from_bytes, from_fp, from_path, normalize -from .constant import CHARDET_CORRESPONDENCE -from .models import CharsetMatch, CharsetMatches - - -def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]: - """ - chardet legacy method - Detect the encoding of the given byte string. It should be mostly backward-compatible. - Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) - This function is deprecated and should be used to migrate your project easily, consult the documentation for - further information. Not planned for removal. - - :param byte_str: The byte sequence to examine. - """ - if not isinstance(byte_str, (bytearray, bytes)): - raise TypeError( # pragma: nocover - "Expected object of type bytes or bytearray, got: " - "{0}".format(type(byte_str)) - ) - - if isinstance(byte_str, bytearray): - byte_str = bytes(byte_str) - - r = from_bytes(byte_str).best() - - encoding = r.encoding if r is not None else None - language = r.language if r is not None and r.language != "Unknown" else "" - confidence = 1.0 - r.chaos if r is not None else None - - # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process - # but chardet does return 'utf-8-sig' and it is a valid codec name. - if r is not None and encoding == "utf_8" and r.bom: - encoding += "_sig" - - return { - "encoding": encoding - if encoding not in CHARDET_CORRESPONDENCE - else CHARDET_CORRESPONDENCE[encoding], - "language": language, - "confidence": confidence, - } - - -class CharsetNormalizerMatch(CharsetMatch): - pass - - -class CharsetNormalizerMatches(CharsetMatches): - @staticmethod - def from_fp(*args, **kwargs): # type: ignore - warnings.warn( # pragma: nocover - "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " - "and scheduled to be removed in 3.0", - DeprecationWarning, - ) - return from_fp(*args, **kwargs) # pragma: nocover - - @staticmethod - def from_bytes(*args, **kwargs): # type: ignore - warnings.warn( # pragma: nocover - "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " - "and scheduled to be removed in 3.0", - DeprecationWarning, - ) - return from_bytes(*args, **kwargs) # pragma: nocover - - @staticmethod - def from_path(*args, **kwargs): # type: ignore - warnings.warn( # pragma: nocover - "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " - "and scheduled to be removed in 3.0", - DeprecationWarning, - ) - return from_path(*args, **kwargs) # pragma: nocover - - @staticmethod - def normalize(*args, **kwargs): # type: ignore - warnings.warn( # pragma: nocover - "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " - "and scheduled to be removed in 3.0", - DeprecationWarning, - ) - return normalize(*args, **kwargs) # pragma: nocover - - -class CharsetDetector(CharsetNormalizerMatches): - pass - - -class CharsetDoctor(CharsetNormalizerMatches): - pass diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/md.py b/venv/lib/python3.7/site-packages/charset_normalizer/md.py deleted file mode 100644 index f3d6505..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/md.py +++ /dev/null @@ -1,559 +0,0 @@ -from functools import lru_cache -from typing import List, Optional - -from .constant import COMMON_SAFE_ASCII_CHARACTERS, UNICODE_SECONDARY_RANGE_KEYWORD -from .utils import ( - is_accentuated, - is_ascii, - is_case_variable, - is_cjk, - is_emoticon, - is_hangul, - is_hiragana, - is_katakana, - is_latin, - is_punctuation, - is_separator, - is_symbol, - is_thai, - remove_accent, - unicode_range, -) - - -class MessDetectorPlugin: - """ - Base abstract class used for mess detection plugins. - All detectors MUST extend and implement given methods. - """ - - def eligible(self, character: str) -> bool: - """ - Determine if given character should be fed in. - """ - raise NotImplementedError # pragma: nocover - - def feed(self, character: str) -> None: - """ - The main routine to be executed upon character. - Insert the logic in witch the text would be considered chaotic. - """ - raise NotImplementedError # pragma: nocover - - def reset(self) -> None: # pragma: no cover - """ - Permit to reset the plugin to the initial state. - """ - raise NotImplementedError - - @property - def ratio(self) -> float: - """ - Compute the chaos ratio based on what your feed() has seen. - Must NOT be lower than 0.; No restriction gt 0. - """ - raise NotImplementedError # pragma: nocover - - -class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._punctuation_count = 0 # type: int - self._symbol_count = 0 # type: int - self._character_count = 0 # type: int - - self._last_printable_char = None # type: Optional[str] - self._frenzy_symbol_in_word = False # type: bool - - def eligible(self, character: str) -> bool: - return character.isprintable() - - def feed(self, character: str) -> None: - self._character_count += 1 - - if ( - character != self._last_printable_char - and character not in COMMON_SAFE_ASCII_CHARACTERS - ): - if is_punctuation(character): - self._punctuation_count += 1 - elif ( - character.isdigit() is False - and is_symbol(character) - and is_emoticon(character) is False - ): - self._symbol_count += 2 - - self._last_printable_char = character - - def reset(self) -> None: # pragma: no cover - self._punctuation_count = 0 - self._character_count = 0 - self._symbol_count = 0 - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - ratio_of_punctuation = ( - self._punctuation_count + self._symbol_count - ) / self._character_count # type: float - - return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 - - -class TooManyAccentuatedPlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._character_count = 0 # type: int - self._accentuated_count = 0 # type: int - - def eligible(self, character: str) -> bool: - return character.isalpha() - - def feed(self, character: str) -> None: - self._character_count += 1 - - if is_accentuated(character): - self._accentuated_count += 1 - - def reset(self) -> None: # pragma: no cover - self._character_count = 0 - self._accentuated_count = 0 - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - ratio_of_accentuation = ( - self._accentuated_count / self._character_count - ) # type: float - return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 - - -class UnprintablePlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._unprintable_count = 0 # type: int - self._character_count = 0 # type: int - - def eligible(self, character: str) -> bool: - return True - - def feed(self, character: str) -> None: - if ( - character.isspace() is False # includes \n \t \r \v - and character.isprintable() is False - and character != "\x1A" # Why? Its the ASCII substitute character. - ): - self._unprintable_count += 1 - self._character_count += 1 - - def reset(self) -> None: # pragma: no cover - self._unprintable_count = 0 - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - return (self._unprintable_count * 8) / self._character_count - - -class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._successive_count = 0 # type: int - self._character_count = 0 # type: int - - self._last_latin_character = None # type: Optional[str] - - def eligible(self, character: str) -> bool: - return character.isalpha() and is_latin(character) - - def feed(self, character: str) -> None: - self._character_count += 1 - if ( - self._last_latin_character is not None - and is_accentuated(character) - and is_accentuated(self._last_latin_character) - ): - if character.isupper() and self._last_latin_character.isupper(): - self._successive_count += 1 - # Worse if its the same char duplicated with different accent. - if remove_accent(character) == remove_accent(self._last_latin_character): - self._successive_count += 1 - self._last_latin_character = character - - def reset(self) -> None: # pragma: no cover - self._successive_count = 0 - self._character_count = 0 - self._last_latin_character = None - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - return (self._successive_count * 2) / self._character_count - - -class SuspiciousRange(MessDetectorPlugin): - def __init__(self) -> None: - self._suspicious_successive_range_count = 0 # type: int - self._character_count = 0 # type: int - self._last_printable_seen = None # type: Optional[str] - - def eligible(self, character: str) -> bool: - return character.isprintable() - - def feed(self, character: str) -> None: - self._character_count += 1 - - if ( - character.isspace() - or is_punctuation(character) - or character in COMMON_SAFE_ASCII_CHARACTERS - ): - self._last_printable_seen = None - return - - if self._last_printable_seen is None: - self._last_printable_seen = character - return - - unicode_range_a = unicode_range( - self._last_printable_seen - ) # type: Optional[str] - unicode_range_b = unicode_range(character) # type: Optional[str] - - if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): - self._suspicious_successive_range_count += 1 - - self._last_printable_seen = character - - def reset(self) -> None: # pragma: no cover - self._character_count = 0 - self._suspicious_successive_range_count = 0 - self._last_printable_seen = None - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - ratio_of_suspicious_range_usage = ( - self._suspicious_successive_range_count * 2 - ) / self._character_count # type: float - - if ratio_of_suspicious_range_usage < 0.1: - return 0.0 - - return ratio_of_suspicious_range_usage - - -class SuperWeirdWordPlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._word_count = 0 # type: int - self._bad_word_count = 0 # type: int - self._foreign_long_count = 0 # type: int - - self._is_current_word_bad = False # type: bool - self._foreign_long_watch = False # type: bool - - self._character_count = 0 # type: int - self._bad_character_count = 0 # type: int - - self._buffer = "" # type: str - self._buffer_accent_count = 0 # type: int - - def eligible(self, character: str) -> bool: - return True - - def feed(self, character: str) -> None: - if character.isalpha(): - self._buffer = "".join([self._buffer, character]) - if is_accentuated(character): - self._buffer_accent_count += 1 - if ( - self._foreign_long_watch is False - and (is_latin(character) is False or is_accentuated(character)) - and is_cjk(character) is False - and is_hangul(character) is False - and is_katakana(character) is False - and is_hiragana(character) is False - and is_thai(character) is False - ): - self._foreign_long_watch = True - return - if not self._buffer: - return - if ( - character.isspace() or is_punctuation(character) or is_separator(character) - ) and self._buffer: - self._word_count += 1 - buffer_length = len(self._buffer) # type: int - - self._character_count += buffer_length - - if buffer_length >= 4: - if self._buffer_accent_count / buffer_length > 0.34: - self._is_current_word_bad = True - # Word/Buffer ending with a upper case accentuated letter are so rare, - # that we will consider them all as suspicious. Same weight as foreign_long suspicious. - if is_accentuated(self._buffer[-1]) and self._buffer[-1].isupper(): - self._foreign_long_count += 1 - self._is_current_word_bad = True - if buffer_length >= 24 and self._foreign_long_watch: - self._foreign_long_count += 1 - self._is_current_word_bad = True - - if self._is_current_word_bad: - self._bad_word_count += 1 - self._bad_character_count += len(self._buffer) - self._is_current_word_bad = False - - self._foreign_long_watch = False - self._buffer = "" - self._buffer_accent_count = 0 - elif ( - character not in {"<", ">", "-", "=", "~", "|", "_"} - and character.isdigit() is False - and is_symbol(character) - ): - self._is_current_word_bad = True - self._buffer += character - - def reset(self) -> None: # pragma: no cover - self._buffer = "" - self._is_current_word_bad = False - self._foreign_long_watch = False - self._bad_word_count = 0 - self._word_count = 0 - self._character_count = 0 - self._bad_character_count = 0 - self._foreign_long_count = 0 - - @property - def ratio(self) -> float: - if self._word_count <= 10 and self._foreign_long_count == 0: - return 0.0 - - return self._bad_character_count / self._character_count - - -class CjkInvalidStopPlugin(MessDetectorPlugin): - """ - GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and - can be easily detected. Searching for the overuse of '丅' and '丄'. - """ - - def __init__(self) -> None: - self._wrong_stop_count = 0 # type: int - self._cjk_character_count = 0 # type: int - - def eligible(self, character: str) -> bool: - return True - - def feed(self, character: str) -> None: - if character in {"丅", "丄"}: - self._wrong_stop_count += 1 - return - if is_cjk(character): - self._cjk_character_count += 1 - - def reset(self) -> None: # pragma: no cover - self._wrong_stop_count = 0 - self._cjk_character_count = 0 - - @property - def ratio(self) -> float: - if self._cjk_character_count < 16: - return 0.0 - return self._wrong_stop_count / self._cjk_character_count - - -class ArchaicUpperLowerPlugin(MessDetectorPlugin): - def __init__(self) -> None: - self._buf = False # type: bool - - self._character_count_since_last_sep = 0 # type: int - - self._successive_upper_lower_count = 0 # type: int - self._successive_upper_lower_count_final = 0 # type: int - - self._character_count = 0 # type: int - - self._last_alpha_seen = None # type: Optional[str] - self._current_ascii_only = True # type: bool - - def eligible(self, character: str) -> bool: - return True - - def feed(self, character: str) -> None: - is_concerned = character.isalpha() and is_case_variable(character) - chunk_sep = is_concerned is False - - if chunk_sep and self._character_count_since_last_sep > 0: - if ( - self._character_count_since_last_sep <= 64 - and character.isdigit() is False - and self._current_ascii_only is False - ): - self._successive_upper_lower_count_final += ( - self._successive_upper_lower_count - ) - - self._successive_upper_lower_count = 0 - self._character_count_since_last_sep = 0 - self._last_alpha_seen = None - self._buf = False - self._character_count += 1 - self._current_ascii_only = True - - return - - if self._current_ascii_only is True and is_ascii(character) is False: - self._current_ascii_only = False - - if self._last_alpha_seen is not None: - if (character.isupper() and self._last_alpha_seen.islower()) or ( - character.islower() and self._last_alpha_seen.isupper() - ): - if self._buf is True: - self._successive_upper_lower_count += 2 - self._buf = False - else: - self._buf = True - else: - self._buf = False - - self._character_count += 1 - self._character_count_since_last_sep += 1 - self._last_alpha_seen = character - - def reset(self) -> None: # pragma: no cover - self._character_count = 0 - self._character_count_since_last_sep = 0 - self._successive_upper_lower_count = 0 - self._successive_upper_lower_count_final = 0 - self._last_alpha_seen = None - self._buf = False - self._current_ascii_only = True - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - return self._successive_upper_lower_count_final / self._character_count - - -def is_suspiciously_successive_range( - unicode_range_a: Optional[str], unicode_range_b: Optional[str] -) -> bool: - """ - Determine if two Unicode range seen next to each other can be considered as suspicious. - """ - if unicode_range_a is None or unicode_range_b is None: - return True - - if unicode_range_a == unicode_range_b: - return False - - if "Latin" in unicode_range_a and "Latin" in unicode_range_b: - return False - - if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b: - return False - - # Latin characters can be accompanied with a combining diacritical mark - # eg. Vietnamese. - if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and ( - "Combining" in unicode_range_a or "Combining" in unicode_range_b - ): - return False - - keywords_range_a, keywords_range_b = unicode_range_a.split( - " " - ), unicode_range_b.split(" ") - - for el in keywords_range_a: - if el in UNICODE_SECONDARY_RANGE_KEYWORD: - continue - if el in keywords_range_b: - return False - - # Japanese Exception - range_a_jp_chars, range_b_jp_chars = ( - unicode_range_a - in ( - "Hiragana", - "Katakana", - ), - unicode_range_b in ("Hiragana", "Katakana"), - ) - if (range_a_jp_chars or range_b_jp_chars) and ( - "CJK" in unicode_range_a or "CJK" in unicode_range_b - ): - return False - if range_a_jp_chars and range_b_jp_chars: - return False - - if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b: - if "CJK" in unicode_range_a or "CJK" in unicode_range_b: - return False - if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": - return False - - # Chinese/Japanese use dedicated range for punctuation and/or separators. - if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or ( - unicode_range_a in ["Katakana", "Hiragana"] - and unicode_range_b in ["Katakana", "Hiragana"] - ): - if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b: - return False - if "Forms" in unicode_range_a or "Forms" in unicode_range_b: - return False - - return True - - -@lru_cache(maxsize=2048) -def mess_ratio( - decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False -) -> float: - """ - Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. - """ - - detectors = [ - md_class() for md_class in MessDetectorPlugin.__subclasses__() - ] # type: List[MessDetectorPlugin] - - length = len(decoded_sequence) + 1 # type: int - - mean_mess_ratio = 0.0 # type: float - - if length < 512: - intermediary_mean_mess_ratio_calc = 32 # type: int - elif length <= 1024: - intermediary_mean_mess_ratio_calc = 64 - else: - intermediary_mean_mess_ratio_calc = 128 - - for character, index in zip(decoded_sequence + "\n", range(length)): - for detector in detectors: - if detector.eligible(character): - detector.feed(character) - - if ( - index > 0 and index % intermediary_mean_mess_ratio_calc == 0 - ) or index == length - 1: - mean_mess_ratio = sum(dt.ratio for dt in detectors) - - if mean_mess_ratio >= maximum_threshold: - break - - if debug: - for dt in detectors: # pragma: nocover - print(dt.__class__, dt.ratio) - - return round(mean_mess_ratio, 3) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/models.py b/venv/lib/python3.7/site-packages/charset_normalizer/models.py deleted file mode 100644 index c38da31..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/models.py +++ /dev/null @@ -1,392 +0,0 @@ -import warnings -from collections import Counter -from encodings.aliases import aliases -from hashlib import sha256 -from json import dumps -from re import sub -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union - -from .constant import NOT_PRINTABLE_PATTERN, TOO_BIG_SEQUENCE -from .md import mess_ratio -from .utils import iana_name, is_multi_byte_encoding, unicode_range - - -class CharsetMatch: - def __init__( - self, - payload: bytes, - guessed_encoding: str, - mean_mess_ratio: float, - has_sig_or_bom: bool, - languages: "CoherenceMatches", - decoded_payload: Optional[str] = None, - ): - self._payload = payload # type: bytes - - self._encoding = guessed_encoding # type: str - self._mean_mess_ratio = mean_mess_ratio # type: float - self._languages = languages # type: CoherenceMatches - self._has_sig_or_bom = has_sig_or_bom # type: bool - self._unicode_ranges = None # type: Optional[List[str]] - - self._leaves = [] # type: List[CharsetMatch] - self._mean_coherence_ratio = 0.0 # type: float - - self._output_payload = None # type: Optional[bytes] - self._output_encoding = None # type: Optional[str] - - self._string = decoded_payload # type: Optional[str] - - def __eq__(self, other: object) -> bool: - if not isinstance(other, CharsetMatch): - raise TypeError( - "__eq__ cannot be invoked on {} and {}.".format( - str(other.__class__), str(self.__class__) - ) - ) - return self.encoding == other.encoding and self.fingerprint == other.fingerprint - - def __lt__(self, other: object) -> bool: - """ - Implemented to make sorted available upon CharsetMatches items. - """ - if not isinstance(other, CharsetMatch): - raise ValueError - - chaos_difference = abs(self.chaos - other.chaos) # type: float - coherence_difference = abs(self.coherence - other.coherence) # type: float - - # Bellow 1% difference --> Use Coherence - if chaos_difference < 0.01 and coherence_difference > 0.02: - # When having a tough decision, use the result that decoded as many multi-byte as possible. - if chaos_difference == 0.0 and self.coherence == other.coherence: - return self.multi_byte_usage > other.multi_byte_usage - return self.coherence > other.coherence - - return self.chaos < other.chaos - - @property - def multi_byte_usage(self) -> float: - return 1.0 - len(str(self)) / len(self.raw) - - @property - def chaos_secondary_pass(self) -> float: - """ - Check once again chaos in decoded text, except this time, with full content. - Use with caution, this can be very slow. - Notice: Will be removed in 3.0 - """ - warnings.warn( - "chaos_secondary_pass is deprecated and will be removed in 3.0", - DeprecationWarning, - ) - return mess_ratio(str(self), 1.0) - - @property - def coherence_non_latin(self) -> float: - """ - Coherence ratio on the first non-latin language detected if ANY. - Notice: Will be removed in 3.0 - """ - warnings.warn( - "coherence_non_latin is deprecated and will be removed in 3.0", - DeprecationWarning, - ) - return 0.0 - - @property - def w_counter(self) -> Counter: - """ - Word counter instance on decoded text. - Notice: Will be removed in 3.0 - """ - warnings.warn( - "w_counter is deprecated and will be removed in 3.0", DeprecationWarning - ) - - string_printable_only = sub(NOT_PRINTABLE_PATTERN, " ", str(self).lower()) - - return Counter(string_printable_only.split()) - - def __str__(self) -> str: - # Lazy Str Loading - if self._string is None: - self._string = str(self._payload, self._encoding, "strict") - return self._string - - def __repr__(self) -> str: - return "".format(self.encoding, self.fingerprint) - - def add_submatch(self, other: "CharsetMatch") -> None: - if not isinstance(other, CharsetMatch) or other == self: - raise ValueError( - "Unable to add instance <{}> as a submatch of a CharsetMatch".format( - other.__class__ - ) - ) - - other._string = None # Unload RAM usage; dirty trick. - self._leaves.append(other) - - @property - def encoding(self) -> str: - return self._encoding - - @property - def encoding_aliases(self) -> List[str]: - """ - Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. - """ - also_known_as = [] # type: List[str] - for u, p in aliases.items(): - if self.encoding == u: - also_known_as.append(p) - elif self.encoding == p: - also_known_as.append(u) - return also_known_as - - @property - def bom(self) -> bool: - return self._has_sig_or_bom - - @property - def byte_order_mark(self) -> bool: - return self._has_sig_or_bom - - @property - def languages(self) -> List[str]: - """ - Return the complete list of possible languages found in decoded sequence. - Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. - """ - return [e[0] for e in self._languages] - - @property - def language(self) -> str: - """ - Most probable language found in decoded sequence. If none were detected or inferred, the property will return - "Unknown". - """ - if not self._languages: - # Trying to infer the language based on the given encoding - # Its either English or we should not pronounce ourselves in certain cases. - if "ascii" in self.could_be_from_charset: - return "English" - - # doing it there to avoid circular import - from charset_normalizer.cd import encoding_languages, mb_encoding_languages - - languages = ( - mb_encoding_languages(self.encoding) - if is_multi_byte_encoding(self.encoding) - else encoding_languages(self.encoding) - ) - - if len(languages) == 0 or "Latin Based" in languages: - return "Unknown" - - return languages[0] - - return self._languages[0][0] - - @property - def chaos(self) -> float: - return self._mean_mess_ratio - - @property - def coherence(self) -> float: - if not self._languages: - return 0.0 - return self._languages[0][1] - - @property - def percent_chaos(self) -> float: - return round(self.chaos * 100, ndigits=3) - - @property - def percent_coherence(self) -> float: - return round(self.coherence * 100, ndigits=3) - - @property - def raw(self) -> bytes: - """ - Original untouched bytes. - """ - return self._payload - - @property - def submatch(self) -> List["CharsetMatch"]: - return self._leaves - - @property - def has_submatch(self) -> bool: - return len(self._leaves) > 0 - - @property - def alphabets(self) -> List[str]: - if self._unicode_ranges is not None: - return self._unicode_ranges - # list detected ranges - detected_ranges = [ - unicode_range(char) for char in str(self) - ] # type: List[Optional[str]] - # filter and sort - self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) - return self._unicode_ranges - - @property - def could_be_from_charset(self) -> List[str]: - """ - The complete list of encoding that output the exact SAME str result and therefore could be the originating - encoding. - This list does include the encoding available in property 'encoding'. - """ - return [self._encoding] + [m.encoding for m in self._leaves] - - def first(self) -> "CharsetMatch": - """ - Kept for BC reasons. Will be removed in 3.0. - """ - return self - - def best(self) -> "CharsetMatch": - """ - Kept for BC reasons. Will be removed in 3.0. - """ - return self - - def output(self, encoding: str = "utf_8") -> bytes: - """ - Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. - Any errors will be simply ignored by the encoder NOT replaced. - """ - if self._output_encoding is None or self._output_encoding != encoding: - self._output_encoding = encoding - self._output_payload = str(self).encode(encoding, "replace") - - return self._output_payload # type: ignore - - @property - def fingerprint(self) -> str: - """ - Retrieve the unique SHA256 computed using the transformed (re-encoded) payload. Not the original one. - """ - return sha256(self.output()).hexdigest() - - -class CharsetMatches: - """ - Container with every CharsetMatch items ordered by default from most probable to the less one. - Act like a list(iterable) but does not implements all related methods. - """ - - def __init__(self, results: List[CharsetMatch] = None): - self._results = sorted(results) if results else [] # type: List[CharsetMatch] - - def __iter__(self) -> Iterator[CharsetMatch]: - yield from self._results - - def __getitem__(self, item: Union[int, str]) -> CharsetMatch: - """ - Retrieve a single item either by its position or encoding name (alias may be used here). - Raise KeyError upon invalid index or encoding not present in results. - """ - if isinstance(item, int): - return self._results[item] - if isinstance(item, str): - item = iana_name(item, False) - for result in self._results: - if item in result.could_be_from_charset: - return result - raise KeyError - - def __len__(self) -> int: - return len(self._results) - - def __bool__(self) -> bool: - return len(self._results) > 0 - - def append(self, item: CharsetMatch) -> None: - """ - Insert a single match. Will be inserted accordingly to preserve sort. - Can be inserted as a submatch. - """ - if not isinstance(item, CharsetMatch): - raise ValueError( - "Cannot append instance '{}' to CharsetMatches".format( - str(item.__class__) - ) - ) - # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) - if len(item.raw) <= TOO_BIG_SEQUENCE: - for match in self._results: - if match.fingerprint == item.fingerprint and match.chaos == item.chaos: - match.add_submatch(item) - return - self._results.append(item) - self._results = sorted(self._results) - - def best(self) -> Optional["CharsetMatch"]: - """ - Simply return the first match. Strict equivalent to matches[0]. - """ - if not self._results: - return None - return self._results[0] - - def first(self) -> Optional["CharsetMatch"]: - """ - Redundant method, call the method best(). Kept for BC reasons. - """ - return self.best() - - -CoherenceMatch = Tuple[str, float] -CoherenceMatches = List[CoherenceMatch] - - -class CliDetectionResult: - def __init__( - self, - path: str, - encoding: Optional[str], - encoding_aliases: List[str], - alternative_encodings: List[str], - language: str, - alphabets: List[str], - has_sig_or_bom: bool, - chaos: float, - coherence: float, - unicode_path: Optional[str], - is_preferred: bool, - ): - self.path = path # type: str - self.unicode_path = unicode_path # type: Optional[str] - self.encoding = encoding # type: Optional[str] - self.encoding_aliases = encoding_aliases # type: List[str] - self.alternative_encodings = alternative_encodings # type: List[str] - self.language = language # type: str - self.alphabets = alphabets # type: List[str] - self.has_sig_or_bom = has_sig_or_bom # type: bool - self.chaos = chaos # type: float - self.coherence = coherence # type: float - self.is_preferred = is_preferred # type: bool - - @property - def __dict__(self) -> Dict[str, Any]: # type: ignore - return { - "path": self.path, - "encoding": self.encoding, - "encoding_aliases": self.encoding_aliases, - "alternative_encodings": self.alternative_encodings, - "language": self.language, - "alphabets": self.alphabets, - "has_sig_or_bom": self.has_sig_or_bom, - "chaos": self.chaos, - "coherence": self.coherence, - "unicode_path": self.unicode_path, - "is_preferred": self.is_preferred, - } - - def to_json(self) -> str: - return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/py.typed b/venv/lib/python3.7/site-packages/charset_normalizer/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/utils.py b/venv/lib/python3.7/site-packages/charset_normalizer/utils.py deleted file mode 100644 index dcb14df..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/utils.py +++ /dev/null @@ -1,342 +0,0 @@ -try: - import unicodedata2 as unicodedata -except ImportError: - import unicodedata # type: ignore[no-redef] - -import importlib -import logging -from codecs import IncrementalDecoder -from encodings.aliases import aliases -from functools import lru_cache -from re import findall -from typing import List, Optional, Set, Tuple, Union - -from _multibytecodec import MultibyteIncrementalDecoder # type: ignore - -from .constant import ( - ENCODING_MARKS, - IANA_SUPPORTED_SIMILAR, - RE_POSSIBLE_ENCODING_INDICATION, - UNICODE_RANGES_COMBINED, - UNICODE_SECONDARY_RANGE_KEYWORD, - UTF8_MAXIMAL_ALLOCATION, -) - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_accentuated(character: str) -> bool: - try: - description = unicodedata.name(character) # type: str - except ValueError: - return False - return ( - "WITH GRAVE" in description - or "WITH ACUTE" in description - or "WITH CEDILLA" in description - or "WITH DIAERESIS" in description - or "WITH CIRCUMFLEX" in description - or "WITH TILDE" in description - ) - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def remove_accent(character: str) -> str: - decomposed = unicodedata.decomposition(character) # type: str - if not decomposed: - return character - - codes = decomposed.split(" ") # type: List[str] - - return chr(int(codes[0], 16)) - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def unicode_range(character: str) -> Optional[str]: - """ - Retrieve the Unicode range official name from a single character. - """ - character_ord = ord(character) # type: int - - for range_name, ord_range in UNICODE_RANGES_COMBINED.items(): - if character_ord in ord_range: - return range_name - - return None - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_latin(character: str) -> bool: - try: - description = unicodedata.name(character) # type: str - except ValueError: - return False - return "LATIN" in description - - -def is_ascii(character: str) -> bool: - try: - character.encode("ascii") - except UnicodeEncodeError: - return False - return True - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_punctuation(character: str) -> bool: - character_category = unicodedata.category(character) # type: str - - if "P" in character_category: - return True - - character_range = unicode_range(character) # type: Optional[str] - - if character_range is None: - return False - - return "Punctuation" in character_range - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_symbol(character: str) -> bool: - character_category = unicodedata.category(character) # type: str - - if "S" in character_category or "N" in character_category: - return True - - character_range = unicode_range(character) # type: Optional[str] - - if character_range is None: - return False - - return "Forms" in character_range - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_emoticon(character: str) -> bool: - character_range = unicode_range(character) # type: Optional[str] - - if character_range is None: - return False - - return "Emoticons" in character_range - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_separator(character: str) -> bool: - if character.isspace() or character in {"|", "+", ",", ";", "<", ">"}: - return True - - character_category = unicodedata.category(character) # type: str - - return "Z" in character_category - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_case_variable(character: str) -> bool: - return character.islower() != character.isupper() - - -def is_private_use_only(character: str) -> bool: - character_category = unicodedata.category(character) # type: str - - return character_category == "Co" - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_cjk(character: str) -> bool: - try: - character_name = unicodedata.name(character) - except ValueError: - return False - - return "CJK" in character_name - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_hiragana(character: str) -> bool: - try: - character_name = unicodedata.name(character) - except ValueError: - return False - - return "HIRAGANA" in character_name - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_katakana(character: str) -> bool: - try: - character_name = unicodedata.name(character) - except ValueError: - return False - - return "KATAKANA" in character_name - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_hangul(character: str) -> bool: - try: - character_name = unicodedata.name(character) - except ValueError: - return False - - return "HANGUL" in character_name - - -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_thai(character: str) -> bool: - try: - character_name = unicodedata.name(character) - except ValueError: - return False - - return "THAI" in character_name - - -@lru_cache(maxsize=len(UNICODE_RANGES_COMBINED)) -def is_unicode_range_secondary(range_name: str) -> bool: - return any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) - - -def any_specified_encoding(sequence: bytes, search_zone: int = 4096) -> Optional[str]: - """ - Extract using ASCII-only decoder any specified encoding in the first n-bytes. - """ - if not isinstance(sequence, bytes): - raise TypeError - - seq_len = len(sequence) # type: int - - results = findall( - RE_POSSIBLE_ENCODING_INDICATION, - sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"), - ) # type: List[str] - - if len(results) == 0: - return None - - for specified_encoding in results: - specified_encoding = specified_encoding.lower().replace("-", "_") - - for encoding_alias, encoding_iana in aliases.items(): - if encoding_alias == specified_encoding: - return encoding_iana - if encoding_iana == specified_encoding: - return encoding_iana - - return None - - -@lru_cache(maxsize=128) -def is_multi_byte_encoding(name: str) -> bool: - """ - Verify is a specific encoding is a multi byte one based on it IANA name - """ - return name in { - "utf_8", - "utf_8_sig", - "utf_16", - "utf_16_be", - "utf_16_le", - "utf_32", - "utf_32_le", - "utf_32_be", - "utf_7", - } or issubclass( - importlib.import_module("encodings.{}".format(name)).IncrementalDecoder, # type: ignore - MultibyteIncrementalDecoder, - ) - - -def identify_sig_or_bom(sequence: bytes) -> Tuple[Optional[str], bytes]: - """ - Identify and extract SIG/BOM in given sequence. - """ - - for iana_encoding in ENCODING_MARKS: - marks = ENCODING_MARKS[iana_encoding] # type: Union[bytes, List[bytes]] - - if isinstance(marks, bytes): - marks = [marks] - - for mark in marks: - if sequence.startswith(mark): - return iana_encoding, mark - - return None, b"" - - -def should_strip_sig_or_bom(iana_encoding: str) -> bool: - return iana_encoding not in {"utf_16", "utf_32"} - - -def iana_name(cp_name: str, strict: bool = True) -> str: - cp_name = cp_name.lower().replace("-", "_") - - for encoding_alias, encoding_iana in aliases.items(): - if cp_name in [encoding_alias, encoding_iana]: - return encoding_iana - - if strict: - raise ValueError("Unable to retrieve IANA for '{}'".format(cp_name)) - - return cp_name - - -def range_scan(decoded_sequence: str) -> List[str]: - ranges = set() # type: Set[str] - - for character in decoded_sequence: - character_range = unicode_range(character) # type: Optional[str] - - if character_range is None: - continue - - ranges.add(character_range) - - return list(ranges) - - -def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: - - if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): - return 0.0 - - decoder_a = importlib.import_module("encodings.{}".format(iana_name_a)).IncrementalDecoder # type: ignore - decoder_b = importlib.import_module("encodings.{}".format(iana_name_b)).IncrementalDecoder # type: ignore - - id_a = decoder_a(errors="ignore") # type: IncrementalDecoder - id_b = decoder_b(errors="ignore") # type: IncrementalDecoder - - character_match_count = 0 # type: int - - for i in range(255): - to_be_decoded = bytes([i]) # type: bytes - if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): - character_match_count += 1 - - return character_match_count / 254 - - -def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: - """ - Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using - the function cp_similarity. - """ - return ( - iana_name_a in IANA_SUPPORTED_SIMILAR - and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] - ) - - -def set_logging_handler( - name: str = "charset_normalizer", - level: int = logging.INFO, - format_string: str = "%(asctime)s | %(levelname)s | %(message)s", -) -> None: - - logger = logging.getLogger(name) - logger.setLevel(level) - - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter(format_string)) - logger.addHandler(handler) diff --git a/venv/lib/python3.7/site-packages/charset_normalizer/version.py b/venv/lib/python3.7/site-packages/charset_normalizer/version.py deleted file mode 100644 index 77cfff2..0000000 --- a/venv/lib/python3.7/site-packages/charset_normalizer/version.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -Expose version -""" - -__version__ = "2.0.12" -VERSION = __version__.split(".") diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/LICENSE.rst deleted file mode 100644 index d12a849..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2014 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/METADATA b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/METADATA deleted file mode 100644 index 74471c7..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/METADATA +++ /dev/null @@ -1,111 +0,0 @@ -Metadata-Version: 2.1 -Name: click -Version: 8.0.4 -Summary: Composable command line interface toolkit -Home-page: https://palletsprojects.com/p/click/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://click.palletsprojects.com/ -Project-URL: Changes, https://click.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/click/ -Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Requires-Python: >=3.6 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst -Requires-Dist: colorama ; platform_system == "Windows" -Requires-Dist: importlib-metadata ; python_version < "3.8" - -\$ click\_ -========== - -Click is a Python package for creating beautiful command line interfaces -in a composable way with as little code as necessary. It's the "Command -Line Interface Creation Kit". It's highly configurable but comes with -sensible defaults out of the box. - -It aims to make the process of writing command line tools quick and fun -while also preventing any frustration caused by the inability to -implement an intended CLI API. - -Click in three points: - -- Arbitrary nesting of commands -- Automatic help page generation -- Supports lazy loading of subcommands at runtime - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - $ pip install -U click - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -A Simple Example ----------------- - -.. code-block:: python - - import click - - @click.command() - @click.option("--count", default=1, help="Number of greetings.") - @click.option("--name", prompt="Your name", help="The person to greet.") - def hello(count, name): - """Simple program that greets NAME for a total of COUNT times.""" - for _ in range(count): - click.echo(f"Hello, {name}!") - - if __name__ == '__main__': - hello() - -.. code-block:: text - - $ python hello.py --count=3 - Your name: Click - Hello, Click! - Hello, Click! - Hello, Click! - - -Donate ------- - -The Pallets organization develops and supports Click and other popular -packages. In order to grow the community of contributors and users, and -allow the maintainers to devote more time to the projects, `please -donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://click.palletsprojects.com/ -- Changes: https://click.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/click/ -- Source Code: https://github.com/pallets/click -- Issue Tracker: https://github.com/pallets/click/issues -- Website: https://palletsprojects.com/p/click -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/RECORD b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/RECORD deleted file mode 100644 index 2fdd4c4..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/RECORD +++ /dev/null @@ -1,41 +0,0 @@ -click-8.0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -click-8.0.4.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 -click-8.0.4.dist-info/METADATA,sha256=zcuHOwCuWGOxyQO9MNOlHVHnEqfFAUi2lHHEpCMtLJw,3247 -click-8.0.4.dist-info/RECORD,, -click-8.0.4.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 -click-8.0.4.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 -click/__init__.py,sha256=bOKrvMqmR9rN07vN_ycyrdF-EcTCl-EmuAjq-Fp4yPM,3243 -click/__pycache__/__init__.cpython-37.pyc,, -click/__pycache__/_compat.cpython-37.pyc,, -click/__pycache__/_termui_impl.cpython-37.pyc,, -click/__pycache__/_textwrap.cpython-37.pyc,, -click/__pycache__/_unicodefun.cpython-37.pyc,, -click/__pycache__/_winconsole.cpython-37.pyc,, -click/__pycache__/core.cpython-37.pyc,, -click/__pycache__/decorators.cpython-37.pyc,, -click/__pycache__/exceptions.cpython-37.pyc,, -click/__pycache__/formatting.cpython-37.pyc,, -click/__pycache__/globals.cpython-37.pyc,, -click/__pycache__/parser.cpython-37.pyc,, -click/__pycache__/shell_completion.cpython-37.pyc,, -click/__pycache__/termui.cpython-37.pyc,, -click/__pycache__/testing.cpython-37.pyc,, -click/__pycache__/types.cpython-37.pyc,, -click/__pycache__/utils.cpython-37.pyc,, -click/_compat.py,sha256=JIHLYs7Jzz4KT9t-ds4o4jBzLjnwCiJQKqur-5iwCKI,18810 -click/_termui_impl.py,sha256=qK6Cfy4mRFxvxE8dya8RBhLpSC8HjF-lvBc6aNrPdwg,23451 -click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 -click/_unicodefun.py,sha256=JKSh1oSwG_zbjAu4TBCa9tQde2P9FiYcf4MBfy5NdT8,3201 -click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 -click/core.py,sha256=MYYmvqVa_dh4x4f-mr7VyNi6197ucYbJ0fsWW5EnCrA,111432 -click/decorators.py,sha256=5ZngOD72Flo8VLN29iarI0A5u_F-dxmqtUqx4KN8hOg,14879 -click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167 -click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 -click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 -click/parser.py,sha256=cAEt1uQR8gq3-S9ysqbVU-fdAZNvilxw4ReJ_T1OQMk,19044 -click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -click/shell_completion.py,sha256=HHH0wMwlDW4WQhs8rRcS9M8MAo9gltGBN6V2PEbsTp0,18003 -click/termui.py,sha256=mZ12uc3-loFaV__vr8buxn9uIjAhy7QwVuZOQ8jDdjc,28873 -click/testing.py,sha256=ptpMYgRY7dVfE3UDgkgwayu9ePw98sQI3D7zZXiCpj4,16063 -click/types.py,sha256=rj2g3biAXKkNKV8vlwbIKSUlixhXybH84N84fwCYqUU,35092 -click/utils.py,sha256=M8tuplcFFHROha3vQ60ZRSakSB_ng6w9e8Uc1AugPZ0,18934 diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/WHEEL b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/WHEEL deleted file mode 100644 index becc9a6..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/top_level.txt deleted file mode 100644 index dca9a90..0000000 --- a/venv/lib/python3.7/site-packages/click-8.0.4.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -click diff --git a/venv/lib/python3.7/site-packages/click/__init__.py b/venv/lib/python3.7/site-packages/click/__init__.py deleted file mode 100644 index 35176c7..0000000 --- a/venv/lib/python3.7/site-packages/click/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -Click is a simple Python module inspired by the stdlib optparse to make -writing command line scripts fun. Unlike other modules, it's based -around a simple API that does not come with too much magic and is -composable. -""" -from .core import Argument as Argument -from .core import BaseCommand as BaseCommand -from .core import Command as Command -from .core import CommandCollection as CommandCollection -from .core import Context as Context -from .core import Group as Group -from .core import MultiCommand as MultiCommand -from .core import Option as Option -from .core import Parameter as Parameter -from .decorators import argument as argument -from .decorators import command as command -from .decorators import confirmation_option as confirmation_option -from .decorators import group as group -from .decorators import help_option as help_option -from .decorators import make_pass_decorator as make_pass_decorator -from .decorators import option as option -from .decorators import pass_context as pass_context -from .decorators import pass_obj as pass_obj -from .decorators import password_option as password_option -from .decorators import version_option as version_option -from .exceptions import Abort as Abort -from .exceptions import BadArgumentUsage as BadArgumentUsage -from .exceptions import BadOptionUsage as BadOptionUsage -from .exceptions import BadParameter as BadParameter -from .exceptions import ClickException as ClickException -from .exceptions import FileError as FileError -from .exceptions import MissingParameter as MissingParameter -from .exceptions import NoSuchOption as NoSuchOption -from .exceptions import UsageError as UsageError -from .formatting import HelpFormatter as HelpFormatter -from .formatting import wrap_text as wrap_text -from .globals import get_current_context as get_current_context -from .parser import OptionParser as OptionParser -from .termui import clear as clear -from .termui import confirm as confirm -from .termui import echo_via_pager as echo_via_pager -from .termui import edit as edit -from .termui import get_terminal_size as get_terminal_size -from .termui import getchar as getchar -from .termui import launch as launch -from .termui import pause as pause -from .termui import progressbar as progressbar -from .termui import prompt as prompt -from .termui import secho as secho -from .termui import style as style -from .termui import unstyle as unstyle -from .types import BOOL as BOOL -from .types import Choice as Choice -from .types import DateTime as DateTime -from .types import File as File -from .types import FLOAT as FLOAT -from .types import FloatRange as FloatRange -from .types import INT as INT -from .types import IntRange as IntRange -from .types import ParamType as ParamType -from .types import Path as Path -from .types import STRING as STRING -from .types import Tuple as Tuple -from .types import UNPROCESSED as UNPROCESSED -from .types import UUID as UUID -from .utils import echo as echo -from .utils import format_filename as format_filename -from .utils import get_app_dir as get_app_dir -from .utils import get_binary_stream as get_binary_stream -from .utils import get_os_args as get_os_args -from .utils import get_text_stream as get_text_stream -from .utils import open_file as open_file - -__version__ = "8.0.4" diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 0570f87d81f928dba724c03bec05e0c540e84b13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2696 zcmd7USytOf6b4`eo^9qKj6s1A!eldsd9ck85~dU2<@SS)EETpIO{YqRkQMYMdI5cU zM}F<6-aS+c*ErMk0SvqxsW{IKV%(*cORc z5r|kVR;$zEwnA$QxeeV0ZR{vI3Q=|p9fKGI@z7*F6d%+p}V1*-Hq;n9(E797kb&f=sxIU_o4ft zpWTlhfC2V^^Tr*7LG~N;5Dc*g(Zevz9zu`62zwYk3Zv{1^cak>N6~NLEqe?-4&&^% zXbm*>xbx1PfC;vSo`gyEJLkPS1yk$^=Yu;9)9gv-qdNmL?Dyzdm}O6)=U|Tg0X+}% z>}m7@EU-VKbC6@tp!1Mt&!QJ$kv)fAf+hAmdKs443+NSCVdv1Ru*%M(*I*(>NR*kZ4uw_%&ThTef4_9yf%?6TL|OLB9J2SEBlj4N+56}dIAI^4Kf`Bs0euRm>>~OLd|{W+U*RkJ z5Pb$`=p#6{j;|v#CqL@xl4G0qnyoZLQ??s8Lc4kjtG=hXzE#7P?Ww?)!qUo5T38jD z3N6PjYkm+0hEzfeea$uQMfy?Nq3u;P(|29Nvoy!{@MKfkL8!F5nwQgVJ;%Nmnvb){ z=h@Y~W{1;CD;r8!X+!!o9Qkq~g{xCs(g-!n7fSQ|kR}(}qa9XpSzNbfR&nu)ZECcl ztvn@uEnS1g=vc(YLb1y8 z?3t=?g4h0DDy<$EO6is`eQAU~O&)(4nB`+Q>GNeKx$T#K#j`rekG`~C=j(V7QvG-3 zLfMyegIz_#YF6r285Mzj9oW~ny=G4qdw#yn4&FXT-%ZiHmDI8Ah$AWaLc7jwrEpjL zJS2PJU*ik+QnobD-5k;W84GaiQ-vCZOg%~?(4TLww<1E_tVxM4r~Z1^*~VnJisItO zOh*`0D6Bk}o9;!JRbPLw4J>Dc&x#7mraSMZNpUgP_6$c?_7A%C1a_KLo+R!VHP5VK zXDl#kijHOi=~tvss@ymOn{L3{MA0&IstTVRo~Y(E87*F3p5d{0sp{J%9ZVh?p}4VK za+C^3BahE63pa@LvEv)zH^bxCqV4p8I+Lf~OIKsV-8=<6{K^RF8spbD-%c-1Xrh}M zzMT=7+l#Ajm!+fY>!U+#MsIIV`Tz5!cHVKh^*dbO!wpO$s3b-Z=$1`o_H*=(^>bx?Ydseio7*;1ZwR z5gDb3QN$?{6iJE{1$_m8^vjz-$qe=4*MW#^r|6*Qr0AmPrs$#QrRbyR$Ec@8bFV5n zK)r7$1}TOphABoUMk&T9-eN$yQ6>6}ljGE@Vc<4#{IcOF`HougfOnvrzy`!=OVw;S zi4FOlVv6De#Wcl7iW!PoiaCmTiUo=sMINIb3-J|Ja*;ZgD3&Q!C{`)fC_YiFQ*2Od zQfyIdQ|wUeV$@@`(8kN%qmF%w1BwDgk)lL#h*8hzdh^pl|05#L=>Ww)zvOT6ZKm>N zX;_YUa`IKfyvNPwdwH`e%zM8UmT-@RBL5(~hde$l@&P|mR&wikWrt!RpaB)3@+Lie g^15z&cBt#Q;HjS6X*_rKXcMU4FrqEl|HE(VzdRJnssI20 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc deleted file mode 100644 index 8832ec30a61b820fd8772d1996cce6785f1af5ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15757 zcmc(GTWlOxnqJ+yyVz_tDT<;gnzq`qESnySk}QwM_Gm0q6lu%0D33&2cH5p(vro0u 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 V9`{%?WltWV$}h_GfRhqk{|jTFbD#hK diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/_termui_impl.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/_termui_impl.cpython-37.pyc deleted file mode 100644 index 9de6aae63eb847fe4e6665a8fac0505ec2222cc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15619 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 AlK=n! diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/_winconsole.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/_winconsole.cpython-37.pyc deleted file mode 100644 index 5b40d3d535d07b0f55e4b59033f2a035ceb1051a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7737 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 OW$1GJ&>G86=>H9N%>Y9H diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/core.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/core.cpython-37.pyc deleted file mode 100644 index ed7e69e8dbbdfc3bf910cb64f69a67b2b1f5bc72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87988 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 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc deleted file mode 100644 index 918426db46541bd223d6683af7af008efc91b955..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10079 zcmb_iON<*wdhQp=CWkYkMsLfO+Ok*jc(okEG1eQ!>$P`Q_Bz3i70Y%IA{(lQ-80jp z=EK!ZSwqbr2MO3iR@Yos2BaJo$R(#e?lGt2kV8&sL{|L=bkf4aQfFmQck|D^ZNuNcO^vrt?PGVkF|+NNOyMqtK9M?cMug|Zdf zeY@kBth14?bSlU@K_#yCYn__ptFha!cj~4QT6+!kmuRiUOZ{f2DXlK@%bjIuT|ti% zxLe`L3r2Wy+qz)jY3;4B9Mqp!K_ggt2)d0p$x)egWkd zf{Q3$l<_a3{9^DD$}fd4V!W47z7$+W`LdKR1?FvI&HI{E+*~uW+D@3J;r$d@caZ15 z20;x}oIttD#%_`Zp;D-F!rtzXuWbwm`D^uCzViEF8mcubYm8Xv?nZ+&tEw;^t3i*W z@#2%4wt+i&9mxT<=5AeGO_58@hgNbmFrQk171)nZ^E2b2`3#diFfd_fb7Fhz-gGPr zuiG4l_gNY1mn(-RMlv6opW{;Fyae4 zVY1$fqu$;1@P02GrO|MZv`72j)Zf_&2jTsZdUus` zOmN46(VcRJomGmvARS zNwaBA&XpI~F2=;B$pq)cfO!!E?$LpE8H7Mt(k)N z9-4dhf$`LN2Izi_{R-^I7GOA+{?<*UhU$j*AYc9=$SRvsi^Gg~i=n&Y>xkZFc+j6*dMBaA1{h`678Ti@qEZJ z-tnMOhN|s(pYBG9m+p@uz+k-J@NoHCLzSZEVBgywD~P_*kPr=a+70P(Lm<@4x#5Pu zgA75u zaC?j;m&WnO=@6o-7sSS7*bhDEj4>*yA7qrTDZQJjhIGvqX3lKPPNRj5T3&n>w6ePvwg3HP{_lIc7 z<)dj<&B>|Rp3hLu5;-hmF=d_%xWNJb9!Xj51LF{Ke+a4HBOcV%Uof|4J(Zegd0pxR z7O^MDDF?q(P>bP z7_8HL6H(JJ=*+<&du0yIv;{;I6nYn}iHF1>AexTpSPhsFu6Y*E2I?-Embr?1a$=4Z z3YY{^Hr2~`SzTfB3KOah^*ts6g;$v)>}t+@jX96W8WZ8Z=Rl7ZV;gtkB5`Yuv_Oi3SrsoRmnT@1nBV@68x;7@}x2ceznjET-ZAVJg4Id;MDG>YbxWHFIGy$xXF^U}I3m9zqfhUkgL%IM(AP}%i2fN9NwU!fJJ(4Kp_HTlzOjm z4u!3G9UqE%yE4vnHtZE8YdP??+ul8x%^1KBf-tyo!+W#+MhTPUMUBX_F@{@vVJ|%% zVMPhR^pj5)*s7mfp%;hSDXDo~Ov2|^C}7RCVXidYju<7{_C~`biMHafqz`0@;;`J1 zy;9IIdYa^CY`_SFoo$UrEuZht5nquR(}KmMMUCKHKNfwMM)yL}{EmF_4%I@>PeQ$E zi&5 zuX`Yh)cRf=CET6xs11+k_r-Xaf|Ut1+@U$RPNgI2Oma`DpY3NRT2`TO zXy#ItRcYkjHc(@;CauwNm3pW(08M3ca{i-%Y&$o996oRQPS#2tL>)btvGd{l8H%Ej`@Ri|olOiIJ47;^olU zgG~(8fTySmKB+3^>e((TqgqlK)p?Z>>e5osgaWCH0%>4hSF+YGBEZmK=T;Fm@t?qa z_{5KBbwVI}^piameld=e$XITz66bxjGwz3j)Z2n)0W5zBNgfPS5&e-G-iv_9T31Aa zd&9dL%3yi+R5VJD1@O0y0`M+%$|592g8)Wt8p2+OJ1$yhxGj0%JJDUo;n1geBM7(s zaZGh0+GhZW!zwt|^nE=lb=+|SvHK3dbWlJkK=5qP8Rjmb z=4hCM^8ugUA)pT%q+jYE5YdU^xucla7Def>2X-*N6*>L1faP{DjEgSTkm zqvqdG1M43(S5V`k=08zWmzoxG4Z!jeT9zK8&q3uk@Lk|VG-YguuJ7hIrYBo9vD#kd z7F;taJ1QcvXaw2m*%WKWzWgUqG?ujx~R$lot(vx2X{I%+c2;NiABZTK%E9| zBDL;vLWU9<7QaBdmkx)?P7(9_8iWcgo?(8$XEMHg&h95WojQ^(Lcz*M+)ckbv(t4{ zg82M5xRbY#%=CZ*J+Nw3;V-yIp&95;KtDLvs_o|50#B=DO)lrFzEwbDyR0#$kt}Lq ziqr<~guV=z#7JHvtEkh$Fx-B!p)DF0%&7G(``y+-C3|!Fy&3vIXKKpP%mcv-$!4*z zXGC#2teK-)9%K3db6KRzi>UiOCn{P8rp78(KRN&0T8j``1!@tBap_3Kc$FUz&q-7y z!;rI>(zj{HKSIyH;w<={+i)CeNB&+nSDlrsitQyGId!CH<&<<}LpxG*oWy~uAWDS1 zE{SUnq08MVhK~_Tf;&}%JEg!1vSl38mhaI5 zUbcKQ_cjc{5XV4s;o~)Yb_O!VW{YFP&G`q;s)@v{XdC#7x#}vml;oQ#o|nLNNxmV? zvrq{((|O`dkAjvvHL+z~Y@VB~z`WO@D{&zIe94lPPCKGMj4V z{1(34#OMBlpCs40u7i&%)|EIC%wxQVJ82;)aU?xrJ8NN<@8=$n@Z02HX8HpATWtDw zXSd>w|2xBpk6z-oVr!vuk)iH{5=Bdn$gcH)O9UzOVQ6pR{sEpdpCJ-Gr2NHdyi*+Jh|mU zw;&Y=O(7x#7R_8XiLvxHrtmF?8*idH*QG73OQAze=ur3yJiATpr!eE5QIA$cn^r{* ztj)>tcyM>X$fyJ|fcT;}r|wf`4HHZw2|}L5WlQ6zJDt;?;-keW2=j`QJX&IKWRR;* z1i)RZ$ur;8DLLjuMz4{~%!^OT*#>U;r^3`uz<~|)Ax_*S-~)T$`x_G3BMnJFP1Fa) zTwhiT5gnN?^%@vvW+{A%3bFRFiVMsyunhIq5|<*vkEKk`&la(urhqa3f8iM(K$037 z0&t{o$yKZ?@hhqI9`55Hpz=OX1}8s$f9{x3pDV^h-i1FD6eo^4Usm&2^zUJsm_x zIlwR9!xH2yi+`_h0bK_4w+We5z zQK6jON~~L4vaIsi0Oum=7aUU*BpvdsKK;{+9M8*WIRZt zzD8Q%Ia$FRIj76b+;{XJ5#A;3lGl&`o&ZiwLKHl1q|SNsbggx+b*=S!>t^dp>tw5r G+xZ_7$qpa@ diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc deleted file mode 100644 index 0fdbeda97ac452aa972e1efdc952e3ccb72f7a4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9308 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 Yv1jeKrsm}NBH@al(~IlXzY*{JFPBLrMgRZ+ diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc deleted file mode 100644 index f2a9912f74a20d255c80aa6e4355ad349b598e77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2403 zcmah~-EP}96c%OKaU3U2(qv8AU2wpL%|mMs8@2+*u)m<$f)!rTW?1WCuxXLDl+dC; z(oP(tyJ&m6H|T)&vU`j@hHiJ&SJ=&V4rQfj7hnWLk>b(ecRrr;@tfu4ng{Lo(wE_j z1<(5nCq*m6;465{pU`oS6X|scynX49OWhLj1UU$F)2)=d6<*?jTo_loRahxK_PUF( zUgKAIg)i{xQ=c#L+LQ8Q(p_@jw?rM@%Y0$mbF1}Ym2bbXvWzR;CGbM{3i!FiSDysk z6_~9(C48M46}^f2HllKGz5%wI{4Mx*m6Lm3V#uP3(>q%!<}jB-56R2d#95%bzrF zwhX|!k>U>{VOpV#!^74{ssW&ErnBtwNZ4LD(HcPZ!aSZO#Ng=l(q}@N8hqL;tX*cZv6q5btFD z)H9!1$ePFGlsxi(@_4|5hvZjs-+SOC{(YDOlV$b@Hn{6ZH`GRg&V!_m0y+=1N$GwR z8yd2N4g{ST!6`G8(IYmaR@Epp7KXyS;Ug!Cs=Egfn#rYxBqMM8_hC3t0YthAu< zI0f2cn|qUxCJD3gRKNxfS$jB1!gfDp#uP`;r(A?eGplsr4~=ZB5*i!lDAn8BTP-z+onL?^iGYKOMWbRsok?PZUjm4aSX3e?TS2UfN=pu{jv^^F!YWL^G(lnt;MgKhGb0^IvodR|U zk#R0~yG=iBew6!fr%bak&1NrxEC7cxTmK zkH?|y^|BhA=$!Yg!qQYE90cVu7`+ijR>xE;3greE6k2r!#_*4e0)}S|mBvMZTjxty%0bW_?jnivf>1;E(d|!%l8r!C_J;FhKC2m&Ad~|8zM0n(%s_Wg7X-gf z6%eA2unL@sRO%27Qpc9dcVw(M@IqtVLT7(|KR|xsrJ}Dw2V;C)c+8uiOG-`!&el`Bp$3f_l3Go+m4$iI$3S7eE#al#*HXhZI$rNsZ~J q@t_@?3)7?e`B?FZ6klL*84SHj>VAc|z7&v+ARt$Rt*zDaO8H-$h;p+4 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc deleted file mode 100644 index 94cb6a428012a56df94117d2297727318e64165c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13480 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 b{0Ie#lZB`mKU&;-XuNpn@DX$D)sp#tG;l9W diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/termui.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/termui.cpython-37.pyc deleted file mode 100644 index 0e0e612dc42afa6d0d87cb53de1a37b438eccada..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26316 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 SPdx(hU6`9YZO+V1t^O~JIw~Fj diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc deleted file mode 100644 index 1197284203eadd22800ca6589619b6b6d0de492f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32982 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 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index 8ce3155b878f63913682d02bad925aabf2e66d7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17764 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 diff --git a/venv/lib/python3.7/site-packages/click/_compat.py b/venv/lib/python3.7/site-packages/click/_compat.py deleted file mode 100644 index 766d286..0000000 --- a/venv/lib/python3.7/site-packages/click/_compat.py +++ /dev/null @@ -1,626 +0,0 @@ -import codecs -import io -import os -import re -import sys -import typing as t -from weakref import WeakKeyDictionary - -CYGWIN = sys.platform.startswith("cygwin") -MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version) -# Determine local App Engine environment, per Google's own suggestion -APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get( - "SERVER_SOFTWARE", "" -) -WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2 -auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None -_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") - - -def get_filesystem_encoding() -> str: - return sys.getfilesystemencoding() or sys.getdefaultencoding() - - -def _make_text_stream( - stream: t.BinaryIO, - encoding: t.Optional[str], - errors: t.Optional[str], - force_readable: bool = False, - force_writable: bool = False, -) -> t.TextIO: - if encoding is None: - encoding = get_best_encoding(stream) - if errors is None: - errors = "replace" - return _NonClosingTextIOWrapper( - stream, - encoding, - errors, - line_buffering=True, - force_readable=force_readable, - force_writable=force_writable, - ) - - -def is_ascii_encoding(encoding: str) -> bool: - """Checks if a given encoding is ascii.""" - try: - return codecs.lookup(encoding).name == "ascii" - except LookupError: - return False - - -def get_best_encoding(stream: t.IO) -> str: - """Returns the default stream encoding if not found.""" - rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() - if is_ascii_encoding(rv): - return "utf-8" - return rv - - -class _NonClosingTextIOWrapper(io.TextIOWrapper): - def __init__( - self, - stream: t.BinaryIO, - encoding: t.Optional[str], - errors: t.Optional[str], - force_readable: bool = False, - force_writable: bool = False, - **extra: t.Any, - ) -> None: - self._stream = stream = t.cast( - t.BinaryIO, _FixupStream(stream, force_readable, force_writable) - ) - super().__init__(stream, encoding, errors, **extra) - - def __del__(self) -> None: - try: - self.detach() - except Exception: - pass - - def isatty(self) -> bool: - # https://bitbucket.org/pypy/pypy/issue/1803 - return self._stream.isatty() - - -class _FixupStream: - """The new io interface needs more from streams than streams - traditionally implement. As such, this fix-up code is necessary in - some circumstances. - - The forcing of readable and writable flags are there because some tools - put badly patched objects on sys (one such offender are certain version - of jupyter notebook). - """ - - def __init__( - self, - stream: t.BinaryIO, - force_readable: bool = False, - force_writable: bool = False, - ): - self._stream = stream - self._force_readable = force_readable - self._force_writable = force_writable - - def __getattr__(self, name: str) -> t.Any: - return getattr(self._stream, name) - - def read1(self, size: int) -> bytes: - f = getattr(self._stream, "read1", None) - - if f is not None: - return t.cast(bytes, f(size)) - - return self._stream.read(size) - - def readable(self) -> bool: - if self._force_readable: - return True - x = getattr(self._stream, "readable", None) - if x is not None: - return t.cast(bool, x()) - try: - self._stream.read(0) - except Exception: - return False - return True - - def writable(self) -> bool: - if self._force_writable: - return True - x = getattr(self._stream, "writable", None) - if x is not None: - return t.cast(bool, x()) - try: - self._stream.write("") # type: ignore - except Exception: - try: - self._stream.write(b"") - except Exception: - return False - return True - - def seekable(self) -> bool: - x = getattr(self._stream, "seekable", None) - if x is not None: - return t.cast(bool, x()) - try: - self._stream.seek(self._stream.tell()) - except Exception: - return False - return True - - -def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: - try: - return isinstance(stream.read(0), bytes) - except Exception: - return default - # This happens in some cases where the stream was already - # closed. In this case, we assume the default. - - -def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: - try: - stream.write(b"") - except Exception: - try: - stream.write("") - return False - except Exception: - pass - return default - return True - - -def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: - # We need to figure out if the given stream is already binary. - # This can happen because the official docs recommend detaching - # the streams to get binary streams. Some code might do this, so - # we need to deal with this case explicitly. - if _is_binary_reader(stream, False): - return t.cast(t.BinaryIO, stream) - - buf = getattr(stream, "buffer", None) - - # Same situation here; this time we assume that the buffer is - # actually binary in case it's closed. - if buf is not None and _is_binary_reader(buf, True): - return t.cast(t.BinaryIO, buf) - - return None - - -def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]: - # We need to figure out if the given stream is already binary. - # This can happen because the official docs recommend detaching - # the streams to get binary streams. Some code might do this, so - # we need to deal with this case explicitly. - if _is_binary_writer(stream, False): - return t.cast(t.BinaryIO, stream) - - buf = getattr(stream, "buffer", None) - - # Same situation here; this time we assume that the buffer is - # actually binary in case it's closed. - if buf is not None and _is_binary_writer(buf, True): - return t.cast(t.BinaryIO, buf) - - return None - - -def _stream_is_misconfigured(stream: t.TextIO) -> bool: - """A stream is misconfigured if its encoding is ASCII.""" - # If the stream does not have an encoding set, we assume it's set - # to ASCII. This appears to happen in certain unittest - # environments. It's not quite clear what the correct behavior is - # but this at least will force Click to recover somehow. - return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") - - -def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: - """A stream attribute is compatible if it is equal to the - desired value or the desired value is unset and the attribute - has a value. - """ - stream_value = getattr(stream, attr, None) - return stream_value == value or (value is None and stream_value is not None) - - -def _is_compatible_text_stream( - stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] -) -> bool: - """Check if a stream's encoding and errors attributes are - compatible with the desired values. - """ - return _is_compat_stream_attr( - stream, "encoding", encoding - ) and _is_compat_stream_attr(stream, "errors", errors) - - -def _force_correct_text_stream( - text_stream: t.IO, - encoding: t.Optional[str], - errors: t.Optional[str], - is_binary: t.Callable[[t.IO, bool], bool], - find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]], - force_readable: bool = False, - force_writable: bool = False, -) -> t.TextIO: - if is_binary(text_stream, False): - binary_reader = t.cast(t.BinaryIO, text_stream) - else: - text_stream = t.cast(t.TextIO, text_stream) - # If the stream looks compatible, and won't default to a - # misconfigured ascii encoding, return it as-is. - if _is_compatible_text_stream(text_stream, encoding, errors) and not ( - encoding is None and _stream_is_misconfigured(text_stream) - ): - return text_stream - - # Otherwise, get the underlying binary reader. - possible_binary_reader = find_binary(text_stream) - - # If that's not possible, silently use the original reader - # and get mojibake instead of exceptions. - if possible_binary_reader is None: - return text_stream - - binary_reader = possible_binary_reader - - # Default errors to replace instead of strict in order to get - # something that works. - if errors is None: - errors = "replace" - - # Wrap the binary stream in a text stream with the correct - # encoding parameters. - return _make_text_stream( - binary_reader, - encoding, - errors, - force_readable=force_readable, - force_writable=force_writable, - ) - - -def _force_correct_text_reader( - text_reader: t.IO, - encoding: t.Optional[str], - errors: t.Optional[str], - force_readable: bool = False, -) -> t.TextIO: - return _force_correct_text_stream( - text_reader, - encoding, - errors, - _is_binary_reader, - _find_binary_reader, - force_readable=force_readable, - ) - - -def _force_correct_text_writer( - text_writer: t.IO, - encoding: t.Optional[str], - errors: t.Optional[str], - force_writable: bool = False, -) -> t.TextIO: - return _force_correct_text_stream( - text_writer, - encoding, - errors, - _is_binary_writer, - _find_binary_writer, - force_writable=force_writable, - ) - - -def get_binary_stdin() -> t.BinaryIO: - reader = _find_binary_reader(sys.stdin) - if reader is None: - raise RuntimeError("Was not able to determine binary stream for sys.stdin.") - return reader - - -def get_binary_stdout() -> t.BinaryIO: - writer = _find_binary_writer(sys.stdout) - if writer is None: - raise RuntimeError("Was not able to determine binary stream for sys.stdout.") - return writer - - -def get_binary_stderr() -> t.BinaryIO: - writer = _find_binary_writer(sys.stderr) - if writer is None: - raise RuntimeError("Was not able to determine binary stream for sys.stderr.") - return writer - - -def get_text_stdin( - encoding: t.Optional[str] = None, errors: t.Optional[str] = None -) -> t.TextIO: - rv = _get_windows_console_stream(sys.stdin, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) - - -def get_text_stdout( - encoding: t.Optional[str] = None, errors: t.Optional[str] = None -) -> t.TextIO: - rv = _get_windows_console_stream(sys.stdout, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) - - -def get_text_stderr( - encoding: t.Optional[str] = None, errors: t.Optional[str] = None -) -> t.TextIO: - rv = _get_windows_console_stream(sys.stderr, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) - - -def _wrap_io_open( - file: t.Union[str, os.PathLike, int], - mode: str, - encoding: t.Optional[str], - errors: t.Optional[str], -) -> t.IO: - """Handles not passing ``encoding`` and ``errors`` in binary mode.""" - if "b" in mode: - return open(file, mode) - - return open(file, mode, encoding=encoding, errors=errors) - - -def open_stream( - filename: str, - mode: str = "r", - encoding: t.Optional[str] = None, - errors: t.Optional[str] = "strict", - atomic: bool = False, -) -> t.Tuple[t.IO, bool]: - binary = "b" in mode - - # Standard streams first. These are simple because they ignore the - # atomic flag. Use fsdecode to handle Path("-"). - if os.fsdecode(filename) == "-": - if any(m in mode for m in ["w", "a", "x"]): - if binary: - return get_binary_stdout(), False - return get_text_stdout(encoding=encoding, errors=errors), False - if binary: - return get_binary_stdin(), False - return get_text_stdin(encoding=encoding, errors=errors), False - - # Non-atomic writes directly go out through the regular open functions. - if not atomic: - return _wrap_io_open(filename, mode, encoding, errors), True - - # Some usability stuff for atomic writes - if "a" in mode: - raise ValueError( - "Appending to an existing file is not supported, because that" - " would involve an expensive `copy`-operation to a temporary" - " file. Open the file in normal `w`-mode and copy explicitly" - " if that's what you're after." - ) - if "x" in mode: - raise ValueError("Use the `overwrite`-parameter instead.") - if "w" not in mode: - raise ValueError("Atomic writes only make sense with `w`-mode.") - - # Atomic writes are more complicated. They work by opening a file - # as a proxy in the same folder and then using the fdopen - # functionality to wrap it in a Python file. Then we wrap it in an - # atomic file that moves the file over on close. - import errno - import random - - try: - perm: t.Optional[int] = os.stat(filename).st_mode - except OSError: - perm = None - - flags = os.O_RDWR | os.O_CREAT | os.O_EXCL - - if binary: - flags |= getattr(os, "O_BINARY", 0) - - while True: - tmp_filename = os.path.join( - os.path.dirname(filename), - f".__atomic-write{random.randrange(1 << 32):08x}", - ) - try: - fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) - break - except OSError as e: - if e.errno == errno.EEXIST or ( - os.name == "nt" - and e.errno == errno.EACCES - and os.path.isdir(e.filename) - and os.access(e.filename, os.W_OK) - ): - continue - raise - - if perm is not None: - os.chmod(tmp_filename, perm) # in case perm includes bits in umask - - f = _wrap_io_open(fd, mode, encoding, errors) - af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) - return t.cast(t.IO, af), True - - -class _AtomicFile: - def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None: - self._f = f - self._tmp_filename = tmp_filename - self._real_filename = real_filename - self.closed = False - - @property - def name(self) -> str: - return self._real_filename - - def close(self, delete: bool = False) -> None: - if self.closed: - return - self._f.close() - os.replace(self._tmp_filename, self._real_filename) - self.closed = True - - def __getattr__(self, name: str) -> t.Any: - return getattr(self._f, name) - - def __enter__(self) -> "_AtomicFile": - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - self.close(delete=exc_type is not None) - - def __repr__(self) -> str: - return repr(self._f) - - -def strip_ansi(value: str) -> str: - return _ansi_re.sub("", value) - - -def _is_jupyter_kernel_output(stream: t.IO) -> bool: - while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): - stream = stream._stream - - return stream.__class__.__module__.startswith("ipykernel.") - - -def should_strip_ansi( - stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None -) -> bool: - if color is None: - if stream is None: - stream = sys.stdin - return not isatty(stream) and not _is_jupyter_kernel_output(stream) - return not color - - -# On Windows, wrap the output streams with colorama to support ANSI -# color codes. -# NOTE: double check is needed so mypy does not analyze this on Linux -if sys.platform.startswith("win") and WIN: - from ._winconsole import _get_windows_console_stream - - def _get_argv_encoding() -> str: - import locale - - return locale.getpreferredencoding() - - _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() - - def auto_wrap_for_ansi( - stream: t.TextIO, color: t.Optional[bool] = None - ) -> t.TextIO: - """Support ANSI color and style codes on Windows by wrapping a - stream with colorama. - """ - try: - cached = _ansi_stream_wrappers.get(stream) - except Exception: - cached = None - - if cached is not None: - return cached - - import colorama - - strip = should_strip_ansi(stream, color) - ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) - rv = t.cast(t.TextIO, ansi_wrapper.stream) - _write = rv.write - - def _safe_write(s): - try: - return _write(s) - except BaseException: - ansi_wrapper.reset_all() - raise - - rv.write = _safe_write - - try: - _ansi_stream_wrappers[stream] = rv - except Exception: - pass - - return rv - -else: - - def _get_argv_encoding() -> str: - return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding() - - def _get_windows_console_stream( - f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] - ) -> t.Optional[t.TextIO]: - return None - - -def term_len(x: str) -> int: - return len(strip_ansi(x)) - - -def isatty(stream: t.IO) -> bool: - try: - return stream.isatty() - except Exception: - return False - - -def _make_cached_stream_func( - src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] -) -> t.Callable[[], t.TextIO]: - cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() - - def func() -> t.TextIO: - stream = src_func() - try: - rv = cache.get(stream) - except Exception: - rv = None - if rv is not None: - return rv - rv = wrapper_func() - try: - cache[stream] = rv - except Exception: - pass - return rv - - return func - - -_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) -_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) -_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) - - -binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { - "stdin": get_binary_stdin, - "stdout": get_binary_stdout, - "stderr": get_binary_stderr, -} - -text_streams: t.Mapping[ - str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] -] = { - "stdin": get_text_stdin, - "stdout": get_text_stdout, - "stderr": get_text_stderr, -} diff --git a/venv/lib/python3.7/site-packages/click/_termui_impl.py b/venv/lib/python3.7/site-packages/click/_termui_impl.py deleted file mode 100644 index 4b979bc..0000000 --- a/venv/lib/python3.7/site-packages/click/_termui_impl.py +++ /dev/null @@ -1,717 +0,0 @@ -""" -This module contains implementations for the termui module. To keep the -import time of Click down, some infrequently used functionality is -placed in this module and only imported as needed. -""" -import contextlib -import math -import os -import sys -import time -import typing as t -from gettext import gettext as _ - -from ._compat import _default_text_stdout -from ._compat import CYGWIN -from ._compat import get_best_encoding -from ._compat import isatty -from ._compat import open_stream -from ._compat import strip_ansi -from ._compat import term_len -from ._compat import WIN -from .exceptions import ClickException -from .utils import echo - -V = t.TypeVar("V") - -if os.name == "nt": - BEFORE_BAR = "\r" - AFTER_BAR = "\n" -else: - BEFORE_BAR = "\r\033[?25l" - AFTER_BAR = "\033[?25h\n" - - -class ProgressBar(t.Generic[V]): - def __init__( - self, - iterable: t.Optional[t.Iterable[V]], - length: t.Optional[int] = None, - fill_char: str = "#", - empty_char: str = " ", - bar_template: str = "%(bar)s", - info_sep: str = " ", - show_eta: bool = True, - show_percent: t.Optional[bool] = None, - show_pos: bool = False, - item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, - label: t.Optional[str] = None, - file: t.Optional[t.TextIO] = None, - color: t.Optional[bool] = None, - update_min_steps: int = 1, - width: int = 30, - ) -> None: - self.fill_char = fill_char - self.empty_char = empty_char - self.bar_template = bar_template - self.info_sep = info_sep - self.show_eta = show_eta - self.show_percent = show_percent - self.show_pos = show_pos - self.item_show_func = item_show_func - self.label = label or "" - if file is None: - file = _default_text_stdout() - self.file = file - self.color = color - self.update_min_steps = update_min_steps - self._completed_intervals = 0 - self.width = width - self.autowidth = width == 0 - - if length is None: - from operator import length_hint - - length = length_hint(iterable, -1) - - if length == -1: - length = None - if iterable is None: - if length is None: - raise TypeError("iterable or length is required") - iterable = t.cast(t.Iterable[V], range(length)) - self.iter = iter(iterable) - self.length = length - self.pos = 0 - self.avg: t.List[float] = [] - self.start = self.last_eta = time.time() - self.eta_known = False - self.finished = False - self.max_width: t.Optional[int] = None - self.entered = False - self.current_item: t.Optional[V] = None - self.is_hidden = not isatty(self.file) - self._last_line: t.Optional[str] = None - - def __enter__(self) -> "ProgressBar": - self.entered = True - self.render_progress() - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - self.render_finish() - - def __iter__(self) -> t.Iterator[V]: - if not self.entered: - raise RuntimeError("You need to use progress bars in a with block.") - self.render_progress() - return self.generator() - - def __next__(self) -> V: - # Iteration is defined in terms of a generator function, - # returned by iter(self); use that to define next(). This works - # because `self.iter` is an iterable consumed by that generator, - # so it is re-entry safe. Calling `next(self.generator())` - # twice works and does "what you want". - return next(iter(self)) - - def render_finish(self) -> None: - if self.is_hidden: - return - self.file.write(AFTER_BAR) - self.file.flush() - - @property - def pct(self) -> float: - if self.finished: - return 1.0 - return min(self.pos / (float(self.length or 1) or 1), 1.0) - - @property - def time_per_iteration(self) -> float: - if not self.avg: - return 0.0 - return sum(self.avg) / float(len(self.avg)) - - @property - def eta(self) -> float: - if self.length is not None and not self.finished: - return self.time_per_iteration * (self.length - self.pos) - return 0.0 - - def format_eta(self) -> str: - if self.eta_known: - t = int(self.eta) - seconds = t % 60 - t //= 60 - minutes = t % 60 - t //= 60 - hours = t % 24 - t //= 24 - if t > 0: - return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" - else: - return f"{hours:02}:{minutes:02}:{seconds:02}" - return "" - - def format_pos(self) -> str: - pos = str(self.pos) - if self.length is not None: - pos += f"/{self.length}" - return pos - - def format_pct(self) -> str: - return f"{int(self.pct * 100): 4}%"[1:] - - def format_bar(self) -> str: - if self.length is not None: - bar_length = int(self.pct * self.width) - bar = self.fill_char * bar_length - bar += self.empty_char * (self.width - bar_length) - elif self.finished: - bar = self.fill_char * self.width - else: - chars = list(self.empty_char * (self.width or 1)) - if self.time_per_iteration != 0: - chars[ - int( - (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) - * self.width - ) - ] = self.fill_char - bar = "".join(chars) - return bar - - def format_progress_line(self) -> str: - show_percent = self.show_percent - - info_bits = [] - if self.length is not None and show_percent is None: - show_percent = not self.show_pos - - if self.show_pos: - info_bits.append(self.format_pos()) - if show_percent: - info_bits.append(self.format_pct()) - if self.show_eta and self.eta_known and not self.finished: - info_bits.append(self.format_eta()) - if self.item_show_func is not None: - item_info = self.item_show_func(self.current_item) - if item_info is not None: - info_bits.append(item_info) - - return ( - self.bar_template - % { - "label": self.label, - "bar": self.format_bar(), - "info": self.info_sep.join(info_bits), - } - ).rstrip() - - def render_progress(self) -> None: - import shutil - - if self.is_hidden: - # Only output the label as it changes if the output is not a - # TTY. Use file=stderr if you expect to be piping stdout. - if self._last_line != self.label: - self._last_line = self.label - echo(self.label, file=self.file, color=self.color) - - return - - buf = [] - # Update width in case the terminal has been resized - if self.autowidth: - old_width = self.width - self.width = 0 - clutter_length = term_len(self.format_progress_line()) - new_width = max(0, shutil.get_terminal_size().columns - clutter_length) - if new_width < old_width: - buf.append(BEFORE_BAR) - buf.append(" " * self.max_width) # type: ignore - self.max_width = new_width - self.width = new_width - - clear_width = self.width - if self.max_width is not None: - clear_width = self.max_width - - buf.append(BEFORE_BAR) - line = self.format_progress_line() - line_len = term_len(line) - if self.max_width is None or self.max_width < line_len: - self.max_width = line_len - - buf.append(line) - buf.append(" " * (clear_width - line_len)) - line = "".join(buf) - # Render the line only if it changed. - - if line != self._last_line: - self._last_line = line - echo(line, file=self.file, color=self.color, nl=False) - self.file.flush() - - def make_step(self, n_steps: int) -> None: - self.pos += n_steps - if self.length is not None and self.pos >= self.length: - self.finished = True - - if (time.time() - self.last_eta) < 1.0: - return - - self.last_eta = time.time() - - # self.avg is a rolling list of length <= 7 of steps where steps are - # defined as time elapsed divided by the total progress through - # self.length. - if self.pos: - step = (time.time() - self.start) / self.pos - else: - step = time.time() - self.start - - self.avg = self.avg[-6:] + [step] - - self.eta_known = self.length is not None - - def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: - """Update the progress bar by advancing a specified number of - steps, and optionally set the ``current_item`` for this new - position. - - :param n_steps: Number of steps to advance. - :param current_item: Optional item to set as ``current_item`` - for the updated position. - - .. versionchanged:: 8.0 - Added the ``current_item`` optional parameter. - - .. versionchanged:: 8.0 - Only render when the number of steps meets the - ``update_min_steps`` threshold. - """ - if current_item is not None: - self.current_item = current_item - - self._completed_intervals += n_steps - - if self._completed_intervals >= self.update_min_steps: - self.make_step(self._completed_intervals) - self.render_progress() - self._completed_intervals = 0 - - def finish(self) -> None: - self.eta_known = False - self.current_item = None - self.finished = True - - def generator(self) -> t.Iterator[V]: - """Return a generator which yields the items added to the bar - during construction, and updates the progress bar *after* the - yielded block returns. - """ - # WARNING: the iterator interface for `ProgressBar` relies on - # this and only works because this is a simple generator which - # doesn't create or manage additional state. If this function - # changes, the impact should be evaluated both against - # `iter(bar)` and `next(bar)`. `next()` in particular may call - # `self.generator()` repeatedly, and this must remain safe in - # order for that interface to work. - if not self.entered: - raise RuntimeError("You need to use progress bars in a with block.") - - if self.is_hidden: - yield from self.iter - else: - for rv in self.iter: - self.current_item = rv - - # This allows show_item_func to be updated before the - # item is processed. Only trigger at the beginning of - # the update interval. - if self._completed_intervals == 0: - self.render_progress() - - yield rv - self.update(1) - - self.finish() - self.render_progress() - - -def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: - """Decide what method to use for paging through text.""" - stdout = _default_text_stdout() - if not isatty(sys.stdin) or not isatty(stdout): - return _nullpager(stdout, generator, color) - pager_cmd = (os.environ.get("PAGER", None) or "").strip() - if pager_cmd: - if WIN: - return _tempfilepager(generator, pager_cmd, color) - return _pipepager(generator, pager_cmd, color) - if os.environ.get("TERM") in ("dumb", "emacs"): - return _nullpager(stdout, generator, color) - if WIN or sys.platform.startswith("os2"): - return _tempfilepager(generator, "more <", color) - if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: - return _pipepager(generator, "less", color) - - import tempfile - - fd, filename = tempfile.mkstemp() - os.close(fd) - try: - if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: - return _pipepager(generator, "more", color) - return _nullpager(stdout, generator, color) - finally: - os.unlink(filename) - - -def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: - """Page through text by feeding it to another program. Invoking a - pager through this might support colors. - """ - import subprocess - - env = dict(os.environ) - - # If we're piping to less we might support colors under the - # condition that - cmd_detail = cmd.rsplit("/", 1)[-1].split() - if color is None and cmd_detail[0] == "less": - less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" - if not less_flags: - env["LESS"] = "-R" - color = True - elif "r" in less_flags or "R" in less_flags: - color = True - - c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) - stdin = t.cast(t.BinaryIO, c.stdin) - encoding = get_best_encoding(stdin) - try: - for text in generator: - if not color: - text = strip_ansi(text) - - stdin.write(text.encode(encoding, "replace")) - except (OSError, KeyboardInterrupt): - pass - else: - stdin.close() - - # Less doesn't respect ^C, but catches it for its own UI purposes (aborting - # search or other commands inside less). - # - # That means when the user hits ^C, the parent process (click) terminates, - # but less is still alive, paging the output and messing up the terminal. - # - # If the user wants to make the pager exit on ^C, they should set - # `LESS='-K'`. It's not our decision to make. - while True: - try: - c.wait() - except KeyboardInterrupt: - pass - else: - break - - -def _tempfilepager( - generator: t.Iterable[str], cmd: str, color: t.Optional[bool] -) -> None: - """Page through text by invoking a program on a temporary file.""" - import tempfile - - fd, filename = tempfile.mkstemp() - # TODO: This never terminates if the passed generator never terminates. - text = "".join(generator) - if not color: - text = strip_ansi(text) - encoding = get_best_encoding(sys.stdout) - with open_stream(filename, "wb")[0] as f: - f.write(text.encode(encoding)) - try: - os.system(f'{cmd} "{filename}"') - finally: - os.close(fd) - os.unlink(filename) - - -def _nullpager( - stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] -) -> None: - """Simply print unformatted text. This is the ultimate fallback.""" - for text in generator: - if not color: - text = strip_ansi(text) - stream.write(text) - - -class Editor: - def __init__( - self, - editor: t.Optional[str] = None, - env: t.Optional[t.Mapping[str, str]] = None, - require_save: bool = True, - extension: str = ".txt", - ) -> None: - self.editor = editor - self.env = env - self.require_save = require_save - self.extension = extension - - def get_editor(self) -> str: - if self.editor is not None: - return self.editor - for key in "VISUAL", "EDITOR": - rv = os.environ.get(key) - if rv: - return rv - if WIN: - return "notepad" - for editor in "sensible-editor", "vim", "nano": - if os.system(f"which {editor} >/dev/null 2>&1") == 0: - return editor - return "vi" - - def edit_file(self, filename: str) -> None: - import subprocess - - editor = self.get_editor() - environ: t.Optional[t.Dict[str, str]] = None - - if self.env: - environ = os.environ.copy() - environ.update(self.env) - - try: - c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) - exit_code = c.wait() - if exit_code != 0: - raise ClickException( - _("{editor}: Editing failed").format(editor=editor) - ) - except OSError as e: - raise ClickException( - _("{editor}: Editing failed: {e}").format(editor=editor, e=e) - ) from e - - def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: - import tempfile - - if not text: - data = b"" - elif isinstance(text, (bytes, bytearray)): - data = text - else: - if text and not text.endswith("\n"): - text += "\n" - - if WIN: - data = text.replace("\n", "\r\n").encode("utf-8-sig") - else: - data = text.encode("utf-8") - - fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) - f: t.BinaryIO - - try: - with os.fdopen(fd, "wb") as f: - f.write(data) - - # If the filesystem resolution is 1 second, like Mac OS - # 10.12 Extended, or 2 seconds, like FAT32, and the editor - # closes very fast, require_save can fail. Set the modified - # time to be 2 seconds in the past to work around this. - os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) - # Depending on the resolution, the exact value might not be - # recorded, so get the new recorded value. - timestamp = os.path.getmtime(name) - - self.edit_file(name) - - if self.require_save and os.path.getmtime(name) == timestamp: - return None - - with open(name, "rb") as f: - rv = f.read() - - if isinstance(text, (bytes, bytearray)): - return rv - - return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore - finally: - os.unlink(name) - - -def open_url(url: str, wait: bool = False, locate: bool = False) -> int: - import subprocess - - def _unquote_file(url: str) -> str: - from urllib.parse import unquote - - if url.startswith("file://"): - url = unquote(url[7:]) - - return url - - if sys.platform == "darwin": - args = ["open"] - if wait: - args.append("-W") - if locate: - args.append("-R") - args.append(_unquote_file(url)) - null = open("/dev/null", "w") - try: - return subprocess.Popen(args, stderr=null).wait() - finally: - null.close() - elif WIN: - if locate: - url = _unquote_file(url.replace('"', "")) - args = f'explorer /select,"{url}"' - else: - url = url.replace('"', "") - wait_str = "/WAIT" if wait else "" - args = f'start {wait_str} "" "{url}"' - return os.system(args) - elif CYGWIN: - if locate: - url = os.path.dirname(_unquote_file(url).replace('"', "")) - args = f'cygstart "{url}"' - else: - url = url.replace('"', "") - wait_str = "-w" if wait else "" - args = f'cygstart {wait_str} "{url}"' - return os.system(args) - - try: - if locate: - url = os.path.dirname(_unquote_file(url)) or "." - else: - url = _unquote_file(url) - c = subprocess.Popen(["xdg-open", url]) - if wait: - return c.wait() - return 0 - except OSError: - if url.startswith(("http://", "https://")) and not locate and not wait: - import webbrowser - - webbrowser.open(url) - return 0 - return 1 - - -def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: - if ch == "\x03": - raise KeyboardInterrupt() - - if ch == "\x04" and not WIN: # Unix-like, Ctrl+D - raise EOFError() - - if ch == "\x1a" and WIN: # Windows, Ctrl+Z - raise EOFError() - - return None - - -if WIN: - import msvcrt - - @contextlib.contextmanager - def raw_terminal() -> t.Iterator[int]: - yield -1 - - def getchar(echo: bool) -> str: - # The function `getch` will return a bytes object corresponding to - # the pressed character. Since Windows 10 build 1803, it will also - # return \x00 when called a second time after pressing a regular key. - # - # `getwch` does not share this probably-bugged behavior. Moreover, it - # returns a Unicode object by default, which is what we want. - # - # Either of these functions will return \x00 or \xe0 to indicate - # a special key, and you need to call the same function again to get - # the "rest" of the code. The fun part is that \u00e0 is - # "latin small letter a with grave", so if you type that on a French - # keyboard, you _also_ get a \xe0. - # E.g., consider the Up arrow. This returns \xe0 and then \x48. The - # resulting Unicode string reads as "a with grave" + "capital H". - # This is indistinguishable from when the user actually types - # "a with grave" and then "capital H". - # - # When \xe0 is returned, we assume it's part of a special-key sequence - # and call `getwch` again, but that means that when the user types - # the \u00e0 character, `getchar` doesn't return until a second - # character is typed. - # The alternative is returning immediately, but that would mess up - # cross-platform handling of arrow keys and others that start with - # \xe0. Another option is using `getch`, but then we can't reliably - # read non-ASCII characters, because return values of `getch` are - # limited to the current 8-bit codepage. - # - # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` - # is doing the right thing in more situations than with `getch`. - func: t.Callable[[], str] - - if echo: - func = msvcrt.getwche # type: ignore - else: - func = msvcrt.getwch # type: ignore - - rv = func() - - if rv in ("\x00", "\xe0"): - # \x00 and \xe0 are control characters that indicate special key, - # see above. - rv += func() - - _translate_ch_to_exc(rv) - return rv - -else: - import tty - import termios - - @contextlib.contextmanager - def raw_terminal() -> t.Iterator[int]: - f: t.Optional[t.TextIO] - fd: int - - if not isatty(sys.stdin): - f = open("/dev/tty") - fd = f.fileno() - else: - fd = sys.stdin.fileno() - f = None - - try: - old_settings = termios.tcgetattr(fd) - - try: - tty.setraw(fd) - yield fd - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - sys.stdout.flush() - - if f is not None: - f.close() - except termios.error: - pass - - def getchar(echo: bool) -> str: - with raw_terminal() as fd: - ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") - - if echo and isatty(sys.stdout): - sys.stdout.write(ch) - - _translate_ch_to_exc(ch) - return ch diff --git a/venv/lib/python3.7/site-packages/click/_textwrap.py b/venv/lib/python3.7/site-packages/click/_textwrap.py deleted file mode 100644 index b47dcbd..0000000 --- a/venv/lib/python3.7/site-packages/click/_textwrap.py +++ /dev/null @@ -1,49 +0,0 @@ -import textwrap -import typing as t -from contextlib import contextmanager - - -class TextWrapper(textwrap.TextWrapper): - def _handle_long_word( - self, - reversed_chunks: t.List[str], - cur_line: t.List[str], - cur_len: int, - width: int, - ) -> None: - space_left = max(width - cur_len, 1) - - if self.break_long_words: - last = reversed_chunks[-1] - cut = last[:space_left] - res = last[space_left:] - cur_line.append(cut) - reversed_chunks[-1] = res - elif not cur_line: - cur_line.append(reversed_chunks.pop()) - - @contextmanager - def extra_indent(self, indent: str) -> t.Iterator[None]: - old_initial_indent = self.initial_indent - old_subsequent_indent = self.subsequent_indent - self.initial_indent += indent - self.subsequent_indent += indent - - try: - yield - finally: - self.initial_indent = old_initial_indent - self.subsequent_indent = old_subsequent_indent - - def indent_only(self, text: str) -> str: - rv = [] - - for idx, line in enumerate(text.splitlines()): - indent = self.initial_indent - - if idx > 0: - indent = self.subsequent_indent - - rv.append(f"{indent}{line}") - - return "\n".join(rv) diff --git a/venv/lib/python3.7/site-packages/click/_unicodefun.py b/venv/lib/python3.7/site-packages/click/_unicodefun.py deleted file mode 100644 index 9cb30c3..0000000 --- a/venv/lib/python3.7/site-packages/click/_unicodefun.py +++ /dev/null @@ -1,100 +0,0 @@ -import codecs -import os -from gettext import gettext as _ - - -def _verify_python_env() -> None: - """Ensures that the environment is good for Unicode.""" - try: - from locale import getpreferredencoding - - fs_enc = codecs.lookup(getpreferredencoding()).name - except Exception: - fs_enc = "ascii" - - if fs_enc != "ascii": - return - - extra = [ - _( - "Click will abort further execution because Python was" - " configured to use ASCII as encoding for the environment." - " Consult https://click.palletsprojects.com/unicode-support/" - " for mitigation steps." - ) - ] - - if os.name == "posix": - import subprocess - - try: - rv = subprocess.Popen( - ["locale", "-a"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - encoding="ascii", - errors="replace", - ).communicate()[0] - except OSError: - rv = "" - - good_locales = set() - has_c_utf8 = False - - for line in rv.splitlines(): - locale = line.strip() - - if locale.lower().endswith((".utf-8", ".utf8")): - good_locales.add(locale) - - if locale.lower() in ("c.utf8", "c.utf-8"): - has_c_utf8 = True - - if not good_locales: - extra.append( - _( - "Additional information: on this system no suitable" - " UTF-8 locales were discovered. This most likely" - " requires resolving by reconfiguring the locale" - " system." - ) - ) - elif has_c_utf8: - extra.append( - _( - "This system supports the C.UTF-8 locale which is" - " recommended. You might be able to resolve your" - " issue by exporting the following environment" - " variables:" - ) - ) - extra.append(" export LC_ALL=C.UTF-8\n export LANG=C.UTF-8") - else: - extra.append( - _( - "This system lists some UTF-8 supporting locales" - " that you can pick from. The following suitable" - " locales were discovered: {locales}" - ).format(locales=", ".join(sorted(good_locales))) - ) - - bad_locale = None - - for env_locale in os.environ.get("LC_ALL"), os.environ.get("LANG"): - if env_locale and env_locale.lower().endswith((".utf-8", ".utf8")): - bad_locale = env_locale - - if env_locale is not None: - break - - if bad_locale is not None: - extra.append( - _( - "Click discovered that you exported a UTF-8 locale" - " but the locale system could not pick up from it" - " because it does not exist. The exported locale is" - " {locale!r} but it is not supported." - ).format(locale=bad_locale) - ) - - raise RuntimeError("\n\n".join(extra)) diff --git a/venv/lib/python3.7/site-packages/click/_winconsole.py b/venv/lib/python3.7/site-packages/click/_winconsole.py deleted file mode 100644 index 6b20df3..0000000 --- a/venv/lib/python3.7/site-packages/click/_winconsole.py +++ /dev/null @@ -1,279 +0,0 @@ -# This module is based on the excellent work by Adam Bartoš who -# provided a lot of what went into the implementation here in -# the discussion to issue1602 in the Python bug tracker. -# -# There are some general differences in regards to how this works -# compared to the original patches as we do not need to patch -# the entire interpreter but just work in our little world of -# echo and prompt. -import io -import sys -import time -import typing as t -from ctypes import byref -from ctypes import c_char -from ctypes import c_char_p -from ctypes import c_int -from ctypes import c_ssize_t -from ctypes import c_ulong -from ctypes import c_void_p -from ctypes import POINTER -from ctypes import py_object -from ctypes import Structure -from ctypes.wintypes import DWORD -from ctypes.wintypes import HANDLE -from ctypes.wintypes import LPCWSTR -from ctypes.wintypes import LPWSTR - -from ._compat import _NonClosingTextIOWrapper - -assert sys.platform == "win32" -import msvcrt # noqa: E402 -from ctypes import windll # noqa: E402 -from ctypes import WINFUNCTYPE # noqa: E402 - -c_ssize_p = POINTER(c_ssize_t) - -kernel32 = windll.kernel32 -GetStdHandle = kernel32.GetStdHandle -ReadConsoleW = kernel32.ReadConsoleW -WriteConsoleW = kernel32.WriteConsoleW -GetConsoleMode = kernel32.GetConsoleMode -GetLastError = kernel32.GetLastError -GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) -CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( - ("CommandLineToArgvW", windll.shell32) -) -LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) - -STDIN_HANDLE = GetStdHandle(-10) -STDOUT_HANDLE = GetStdHandle(-11) -STDERR_HANDLE = GetStdHandle(-12) - -PyBUF_SIMPLE = 0 -PyBUF_WRITABLE = 1 - -ERROR_SUCCESS = 0 -ERROR_NOT_ENOUGH_MEMORY = 8 -ERROR_OPERATION_ABORTED = 995 - -STDIN_FILENO = 0 -STDOUT_FILENO = 1 -STDERR_FILENO = 2 - -EOF = b"\x1a" -MAX_BYTES_WRITTEN = 32767 - -try: - from ctypes import pythonapi -except ImportError: - # On PyPy we cannot get buffers so our ability to operate here is - # severely limited. - get_buffer = None -else: - - class Py_buffer(Structure): - _fields_ = [ - ("buf", c_void_p), - ("obj", py_object), - ("len", c_ssize_t), - ("itemsize", c_ssize_t), - ("readonly", c_int), - ("ndim", c_int), - ("format", c_char_p), - ("shape", c_ssize_p), - ("strides", c_ssize_p), - ("suboffsets", c_ssize_p), - ("internal", c_void_p), - ] - - PyObject_GetBuffer = pythonapi.PyObject_GetBuffer - PyBuffer_Release = pythonapi.PyBuffer_Release - - def get_buffer(obj, writable=False): - buf = Py_buffer() - flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE - PyObject_GetBuffer(py_object(obj), byref(buf), flags) - - try: - buffer_type = c_char * buf.len - return buffer_type.from_address(buf.buf) - finally: - PyBuffer_Release(byref(buf)) - - -class _WindowsConsoleRawIOBase(io.RawIOBase): - def __init__(self, handle): - self.handle = handle - - def isatty(self): - super().isatty() - return True - - -class _WindowsConsoleReader(_WindowsConsoleRawIOBase): - def readable(self): - return True - - def readinto(self, b): - bytes_to_be_read = len(b) - if not bytes_to_be_read: - return 0 - elif bytes_to_be_read % 2: - raise ValueError( - "cannot read odd number of bytes from UTF-16-LE encoded console" - ) - - buffer = get_buffer(b, writable=True) - code_units_to_be_read = bytes_to_be_read // 2 - code_units_read = c_ulong() - - rv = ReadConsoleW( - HANDLE(self.handle), - buffer, - code_units_to_be_read, - byref(code_units_read), - None, - ) - if GetLastError() == ERROR_OPERATION_ABORTED: - # wait for KeyboardInterrupt - time.sleep(0.1) - if not rv: - raise OSError(f"Windows error: {GetLastError()}") - - if buffer[0] == EOF: - return 0 - return 2 * code_units_read.value - - -class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): - def writable(self): - return True - - @staticmethod - def _get_error_message(errno): - if errno == ERROR_SUCCESS: - return "ERROR_SUCCESS" - elif errno == ERROR_NOT_ENOUGH_MEMORY: - return "ERROR_NOT_ENOUGH_MEMORY" - return f"Windows error {errno}" - - def write(self, b): - bytes_to_be_written = len(b) - buf = get_buffer(b) - code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 - code_units_written = c_ulong() - - WriteConsoleW( - HANDLE(self.handle), - buf, - code_units_to_be_written, - byref(code_units_written), - None, - ) - bytes_written = 2 * code_units_written.value - - if bytes_written == 0 and bytes_to_be_written > 0: - raise OSError(self._get_error_message(GetLastError())) - return bytes_written - - -class ConsoleStream: - def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: - self._text_stream = text_stream - self.buffer = byte_stream - - @property - def name(self) -> str: - return self.buffer.name - - def write(self, x: t.AnyStr) -> int: - if isinstance(x, str): - return self._text_stream.write(x) - try: - self.flush() - except Exception: - pass - return self.buffer.write(x) - - def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: - for line in lines: - self.write(line) - - def __getattr__(self, name: str) -> t.Any: - return getattr(self._text_stream, name) - - def isatty(self) -> bool: - return self.buffer.isatty() - - def __repr__(self): - return f"" - - -def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: - text_stream = _NonClosingTextIOWrapper( - io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), - "utf-16-le", - "strict", - line_buffering=True, - ) - return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) - - -def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: - text_stream = _NonClosingTextIOWrapper( - io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), - "utf-16-le", - "strict", - line_buffering=True, - ) - return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) - - -def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: - text_stream = _NonClosingTextIOWrapper( - io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), - "utf-16-le", - "strict", - line_buffering=True, - ) - return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) - - -_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { - 0: _get_text_stdin, - 1: _get_text_stdout, - 2: _get_text_stderr, -} - - -def _is_console(f: t.TextIO) -> bool: - if not hasattr(f, "fileno"): - return False - - try: - fileno = f.fileno() - except (OSError, io.UnsupportedOperation): - return False - - handle = msvcrt.get_osfhandle(fileno) - return bool(GetConsoleMode(handle, byref(DWORD()))) - - -def _get_windows_console_stream( - f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] -) -> t.Optional[t.TextIO]: - if ( - get_buffer is not None - and encoding in {"utf-16-le", None} - and errors in {"strict", None} - and _is_console(f) - ): - func = _stream_factories.get(f.fileno()) - if func is not None: - b = getattr(f, "buffer", None) - - if b is None: - return None - - return func(b) diff --git a/venv/lib/python3.7/site-packages/click/core.py b/venv/lib/python3.7/site-packages/click/core.py deleted file mode 100644 index 6d8cace..0000000 --- a/venv/lib/python3.7/site-packages/click/core.py +++ /dev/null @@ -1,2953 +0,0 @@ -import enum -import errno -import inspect -import os -import sys -import typing as t -from collections import abc -from contextlib import contextmanager -from contextlib import ExitStack -from functools import partial -from functools import update_wrapper -from gettext import gettext as _ -from gettext import ngettext -from itertools import repeat - -from . import types -from ._unicodefun import _verify_python_env -from .exceptions import Abort -from .exceptions import BadParameter -from .exceptions import ClickException -from .exceptions import Exit -from .exceptions import MissingParameter -from .exceptions import UsageError -from .formatting import HelpFormatter -from .formatting import join_options -from .globals import pop_context -from .globals import push_context -from .parser import _flag_needs_value -from .parser import OptionParser -from .parser import split_opt -from .termui import confirm -from .termui import prompt -from .termui import style -from .utils import _detect_program_name -from .utils import _expand_args -from .utils import echo -from .utils import make_default_short_help -from .utils import make_str -from .utils import PacifyFlushWrapper - -if t.TYPE_CHECKING: - import typing_extensions as te - from .shell_completion import CompletionItem - -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) -V = t.TypeVar("V") - - -def _complete_visible_commands( - ctx: "Context", incomplete: str -) -> t.Iterator[t.Tuple[str, "Command"]]: - """List all the subcommands of a group that start with the - incomplete value and aren't hidden. - - :param ctx: Invocation context for the group. - :param incomplete: Value being completed. May be empty. - """ - multi = t.cast(MultiCommand, ctx.command) - - for name in multi.list_commands(ctx): - if name.startswith(incomplete): - command = multi.get_command(ctx, name) - - if command is not None and not command.hidden: - yield name, command - - -def _check_multicommand( - base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False -) -> None: - if not base_command.chain or not isinstance(cmd, MultiCommand): - return - if register: - hint = ( - "It is not possible to add multi commands as children to" - " another multi command that is in chain mode." - ) - else: - hint = ( - "Found a multi command as subcommand to a multi command" - " that is in chain mode. This is not supported." - ) - raise RuntimeError( - f"{hint}. Command {base_command.name!r} is set to chain and" - f" {cmd_name!r} was added as a subcommand but it in itself is a" - f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" - f" within a chained {type(base_command).__name__} named" - f" {base_command.name!r})." - ) - - -def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: - return list(zip(*repeat(iter(iterable), batch_size))) - - -@contextmanager -def augment_usage_errors( - ctx: "Context", param: t.Optional["Parameter"] = None -) -> t.Iterator[None]: - """Context manager that attaches extra information to exceptions.""" - try: - yield - except BadParameter as e: - if e.ctx is None: - e.ctx = ctx - if param is not None and e.param is None: - e.param = param - raise - except UsageError as e: - if e.ctx is None: - e.ctx = ctx - raise - - -def iter_params_for_processing( - invocation_order: t.Sequence["Parameter"], - declaration_order: t.Sequence["Parameter"], -) -> t.List["Parameter"]: - """Given a sequence of parameters in the order as should be considered - for processing and an iterable of parameters that exist, this returns - a list in the correct order as they should be processed. - """ - - def sort_key(item: "Parameter") -> t.Tuple[bool, float]: - try: - idx: float = invocation_order.index(item) - except ValueError: - idx = float("inf") - - return not item.is_eager, idx - - return sorted(declaration_order, key=sort_key) - - -class ParameterSource(enum.Enum): - """This is an :class:`~enum.Enum` that indicates the source of a - parameter's value. - - Use :meth:`click.Context.get_parameter_source` to get the - source for a parameter by name. - - .. versionchanged:: 8.0 - Use :class:`~enum.Enum` and drop the ``validate`` method. - - .. versionchanged:: 8.0 - Added the ``PROMPT`` value. - """ - - COMMANDLINE = enum.auto() - """The value was provided by the command line args.""" - ENVIRONMENT = enum.auto() - """The value was provided with an environment variable.""" - DEFAULT = enum.auto() - """Used the default specified by the parameter.""" - DEFAULT_MAP = enum.auto() - """Used a default provided by :attr:`Context.default_map`.""" - PROMPT = enum.auto() - """Used a prompt to confirm a default or provide a value.""" - - -class Context: - """The context is a special internal object that holds state relevant - for the script execution at every single level. It's normally invisible - to commands unless they opt-in to getting access to it. - - The context is useful as it can pass internal objects around and can - control special execution features such as reading data from - environment variables. - - A context can be used as context manager in which case it will call - :meth:`close` on teardown. - - :param command: the command class for this context. - :param parent: the parent context. - :param info_name: the info name for this invocation. Generally this - is the most descriptive name for the script or - command. For the toplevel script it is usually - the name of the script, for commands below it it's - the name of the script. - :param obj: an arbitrary object of user data. - :param auto_envvar_prefix: the prefix to use for automatic environment - variables. If this is `None` then reading - from environment variables is disabled. This - does not affect manually set environment - variables which are always read. - :param default_map: a dictionary (like object) with default values - for parameters. - :param terminal_width: the width of the terminal. The default is - inherit from parent context. If no context - defines the terminal width then auto - detection will be applied. - :param max_content_width: the maximum width for content rendered by - Click (this currently only affects help - pages). This defaults to 80 characters if - not overridden. In other words: even if the - terminal is larger than that, Click will not - format things wider than 80 characters by - default. In addition to that, formatters might - add some safety mapping on the right. - :param resilient_parsing: if this flag is enabled then Click will - parse without any interactivity or callback - invocation. Default values will also be - ignored. This is useful for implementing - things such as completion support. - :param allow_extra_args: if this is set to `True` then extra arguments - at the end will not raise an error and will be - kept on the context. The default is to inherit - from the command. - :param allow_interspersed_args: if this is set to `False` then options - and arguments cannot be mixed. The - default is to inherit from the command. - :param ignore_unknown_options: instructs click to ignore options it does - not know and keeps them for later - processing. - :param help_option_names: optionally a list of strings that define how - the default help parameter is named. The - default is ``['--help']``. - :param token_normalize_func: an optional function that is used to - normalize tokens (options, choices, - etc.). This for instance can be used to - implement case insensitive behavior. - :param color: controls if the terminal supports ANSI colors or not. The - default is autodetection. This is only needed if ANSI - codes are used in texts that Click prints which is by - default not the case. This for instance would affect - help output. - :param show_default: Show defaults for all options. If not set, - defaults to the value from a parent context. Overrides an - option's ``show_default`` argument. - - .. versionchanged:: 8.0 - The ``show_default`` parameter defaults to the value from the - parent context. - - .. versionchanged:: 7.1 - Added the ``show_default`` parameter. - - .. versionchanged:: 4.0 - Added the ``color``, ``ignore_unknown_options``, and - ``max_content_width`` parameters. - - .. versionchanged:: 3.0 - Added the ``allow_extra_args`` and ``allow_interspersed_args`` - parameters. - - .. versionchanged:: 2.0 - Added the ``resilient_parsing``, ``help_option_names``, and - ``token_normalize_func`` parameters. - """ - - #: The formatter class to create with :meth:`make_formatter`. - #: - #: .. versionadded:: 8.0 - formatter_class: t.Type["HelpFormatter"] = HelpFormatter - - def __init__( - self, - command: "Command", - parent: t.Optional["Context"] = None, - info_name: t.Optional[str] = None, - obj: t.Optional[t.Any] = None, - auto_envvar_prefix: t.Optional[str] = None, - default_map: t.Optional[t.Dict[str, t.Any]] = None, - terminal_width: t.Optional[int] = None, - max_content_width: t.Optional[int] = None, - resilient_parsing: bool = False, - allow_extra_args: t.Optional[bool] = None, - allow_interspersed_args: t.Optional[bool] = None, - ignore_unknown_options: t.Optional[bool] = None, - help_option_names: t.Optional[t.List[str]] = None, - token_normalize_func: t.Optional[t.Callable[[str], str]] = None, - color: t.Optional[bool] = None, - show_default: t.Optional[bool] = None, - ) -> None: - #: the parent context or `None` if none exists. - self.parent = parent - #: the :class:`Command` for this context. - self.command = command - #: the descriptive information name - self.info_name = info_name - #: Map of parameter names to their parsed values. Parameters - #: with ``expose_value=False`` are not stored. - self.params: t.Dict[str, t.Any] = {} - #: the leftover arguments. - self.args: t.List[str] = [] - #: protected arguments. These are arguments that are prepended - #: to `args` when certain parsing scenarios are encountered but - #: must be never propagated to another arguments. This is used - #: to implement nested parsing. - self.protected_args: t.List[str] = [] - - if obj is None and parent is not None: - obj = parent.obj - - #: the user object stored. - self.obj: t.Any = obj - self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) - - #: A dictionary (-like object) with defaults for parameters. - if ( - default_map is None - and info_name is not None - and parent is not None - and parent.default_map is not None - ): - default_map = parent.default_map.get(info_name) - - self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map - - #: This flag indicates if a subcommand is going to be executed. A - #: group callback can use this information to figure out if it's - #: being executed directly or because the execution flow passes - #: onwards to a subcommand. By default it's None, but it can be - #: the name of the subcommand to execute. - #: - #: If chaining is enabled this will be set to ``'*'`` in case - #: any commands are executed. It is however not possible to - #: figure out which ones. If you require this knowledge you - #: should use a :func:`result_callback`. - self.invoked_subcommand: t.Optional[str] = None - - if terminal_width is None and parent is not None: - terminal_width = parent.terminal_width - - #: The width of the terminal (None is autodetection). - self.terminal_width: t.Optional[int] = terminal_width - - if max_content_width is None and parent is not None: - max_content_width = parent.max_content_width - - #: The maximum width of formatted content (None implies a sensible - #: default which is 80 for most things). - self.max_content_width: t.Optional[int] = max_content_width - - if allow_extra_args is None: - allow_extra_args = command.allow_extra_args - - #: Indicates if the context allows extra args or if it should - #: fail on parsing. - #: - #: .. versionadded:: 3.0 - self.allow_extra_args = allow_extra_args - - if allow_interspersed_args is None: - allow_interspersed_args = command.allow_interspersed_args - - #: Indicates if the context allows mixing of arguments and - #: options or not. - #: - #: .. versionadded:: 3.0 - self.allow_interspersed_args: bool = allow_interspersed_args - - if ignore_unknown_options is None: - ignore_unknown_options = command.ignore_unknown_options - - #: Instructs click to ignore options that a command does not - #: understand and will store it on the context for later - #: processing. This is primarily useful for situations where you - #: want to call into external programs. Generally this pattern is - #: strongly discouraged because it's not possibly to losslessly - #: forward all arguments. - #: - #: .. versionadded:: 4.0 - self.ignore_unknown_options: bool = ignore_unknown_options - - if help_option_names is None: - if parent is not None: - help_option_names = parent.help_option_names - else: - help_option_names = ["--help"] - - #: The names for the help options. - self.help_option_names: t.List[str] = help_option_names - - if token_normalize_func is None and parent is not None: - token_normalize_func = parent.token_normalize_func - - #: An optional normalization function for tokens. This is - #: options, choices, commands etc. - self.token_normalize_func: t.Optional[ - t.Callable[[str], str] - ] = token_normalize_func - - #: Indicates if resilient parsing is enabled. In that case Click - #: will do its best to not cause any failures and default values - #: will be ignored. Useful for completion. - self.resilient_parsing: bool = resilient_parsing - - # If there is no envvar prefix yet, but the parent has one and - # the command on this level has a name, we can expand the envvar - # prefix automatically. - if auto_envvar_prefix is None: - if ( - parent is not None - and parent.auto_envvar_prefix is not None - and self.info_name is not None - ): - auto_envvar_prefix = ( - f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" - ) - else: - auto_envvar_prefix = auto_envvar_prefix.upper() - - if auto_envvar_prefix is not None: - auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") - - self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix - - if color is None and parent is not None: - color = parent.color - - #: Controls if styling output is wanted or not. - self.color: t.Optional[bool] = color - - if show_default is None and parent is not None: - show_default = parent.show_default - - #: Show option default values when formatting help text. - self.show_default: t.Optional[bool] = show_default - - self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] - self._depth = 0 - self._parameter_source: t.Dict[str, ParameterSource] = {} - self._exit_stack = ExitStack() - - def to_info_dict(self) -> t.Dict[str, t.Any]: - """Gather information that could be useful for a tool generating - user-facing documentation. This traverses the entire CLI - structure. - - .. code-block:: python - - with Context(cli) as ctx: - info = ctx.to_info_dict() - - .. versionadded:: 8.0 - """ - return { - "command": self.command.to_info_dict(self), - "info_name": self.info_name, - "allow_extra_args": self.allow_extra_args, - "allow_interspersed_args": self.allow_interspersed_args, - "ignore_unknown_options": self.ignore_unknown_options, - "auto_envvar_prefix": self.auto_envvar_prefix, - } - - def __enter__(self) -> "Context": - self._depth += 1 - push_context(self) - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - self._depth -= 1 - if self._depth == 0: - self.close() - pop_context() - - @contextmanager - def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: - """This helper method can be used with the context object to promote - it to the current thread local (see :func:`get_current_context`). - The default behavior of this is to invoke the cleanup functions which - can be disabled by setting `cleanup` to `False`. The cleanup - functions are typically used for things such as closing file handles. - - If the cleanup is intended the context object can also be directly - used as a context manager. - - Example usage:: - - with ctx.scope(): - assert get_current_context() is ctx - - This is equivalent:: - - with ctx: - assert get_current_context() is ctx - - .. versionadded:: 5.0 - - :param cleanup: controls if the cleanup functions should be run or - not. The default is to run these functions. In - some situations the context only wants to be - temporarily pushed in which case this can be disabled. - Nested pushes automatically defer the cleanup. - """ - if not cleanup: - self._depth += 1 - try: - with self as rv: - yield rv - finally: - if not cleanup: - self._depth -= 1 - - @property - def meta(self) -> t.Dict[str, t.Any]: - """This is a dictionary which is shared with all the contexts - that are nested. It exists so that click utilities can store some - state here if they need to. It is however the responsibility of - that code to manage this dictionary well. - - The keys are supposed to be unique dotted strings. For instance - module paths are a good choice for it. What is stored in there is - irrelevant for the operation of click. However what is important is - that code that places data here adheres to the general semantics of - the system. - - Example usage:: - - LANG_KEY = f'{__name__}.lang' - - def set_language(value): - ctx = get_current_context() - ctx.meta[LANG_KEY] = value - - def get_language(): - return get_current_context().meta.get(LANG_KEY, 'en_US') - - .. versionadded:: 5.0 - """ - return self._meta - - def make_formatter(self) -> HelpFormatter: - """Creates the :class:`~click.HelpFormatter` for the help and - usage output. - - To quickly customize the formatter class used without overriding - this method, set the :attr:`formatter_class` attribute. - - .. versionchanged:: 8.0 - Added the :attr:`formatter_class` attribute. - """ - return self.formatter_class( - width=self.terminal_width, max_width=self.max_content_width - ) - - def with_resource(self, context_manager: t.ContextManager[V]) -> V: - """Register a resource as if it were used in a ``with`` - statement. The resource will be cleaned up when the context is - popped. - - Uses :meth:`contextlib.ExitStack.enter_context`. It calls the - resource's ``__enter__()`` method and returns the result. When - the context is popped, it closes the stack, which calls the - resource's ``__exit__()`` method. - - To register a cleanup function for something that isn't a - context manager, use :meth:`call_on_close`. Or use something - from :mod:`contextlib` to turn it into a context manager first. - - .. code-block:: python - - @click.group() - @click.option("--name") - @click.pass_context - def cli(ctx): - ctx.obj = ctx.with_resource(connect_db(name)) - - :param context_manager: The context manager to enter. - :return: Whatever ``context_manager.__enter__()`` returns. - - .. versionadded:: 8.0 - """ - return self._exit_stack.enter_context(context_manager) - - def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: - """Register a function to be called when the context tears down. - - This can be used to close resources opened during the script - execution. Resources that support Python's context manager - protocol which would be used in a ``with`` statement should be - registered with :meth:`with_resource` instead. - - :param f: The function to execute on teardown. - """ - return self._exit_stack.callback(f) - - def close(self) -> None: - """Invoke all close callbacks registered with - :meth:`call_on_close`, and exit all context managers entered - with :meth:`with_resource`. - """ - self._exit_stack.close() - # In case the context is reused, create a new exit stack. - self._exit_stack = ExitStack() - - @property - def command_path(self) -> str: - """The computed command path. This is used for the ``usage`` - information on the help page. It's automatically created by - combining the info names of the chain of contexts to the root. - """ - rv = "" - if self.info_name is not None: - rv = self.info_name - if self.parent is not None: - parent_command_path = [self.parent.command_path] - - if isinstance(self.parent.command, Command): - for param in self.parent.command.get_params(self): - parent_command_path.extend(param.get_usage_pieces(self)) - - rv = f"{' '.join(parent_command_path)} {rv}" - return rv.lstrip() - - def find_root(self) -> "Context": - """Finds the outermost context.""" - node = self - while node.parent is not None: - node = node.parent - return node - - def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: - """Finds the closest object of a given type.""" - node: t.Optional["Context"] = self - - while node is not None: - if isinstance(node.obj, object_type): - return node.obj - - node = node.parent - - return None - - def ensure_object(self, object_type: t.Type[V]) -> V: - """Like :meth:`find_object` but sets the innermost object to a - new instance of `object_type` if it does not exist. - """ - rv = self.find_object(object_type) - if rv is None: - self.obj = rv = object_type() - return rv - - @t.overload - def lookup_default( - self, name: str, call: "te.Literal[True]" = True - ) -> t.Optional[t.Any]: - ... - - @t.overload - def lookup_default( - self, name: str, call: "te.Literal[False]" = ... - ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: - ... - - def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: - """Get the default for a parameter from :attr:`default_map`. - - :param name: Name of the parameter. - :param call: If the default is a callable, call it. Disable to - return the callable instead. - - .. versionchanged:: 8.0 - Added the ``call`` parameter. - """ - if self.default_map is not None: - value = self.default_map.get(name) - - if call and callable(value): - return value() - - return value - - return None - - def fail(self, message: str) -> "te.NoReturn": - """Aborts the execution of the program with a specific error - message. - - :param message: the error message to fail with. - """ - raise UsageError(message, self) - - def abort(self) -> "te.NoReturn": - """Aborts the script.""" - raise Abort() - - def exit(self, code: int = 0) -> "te.NoReturn": - """Exits the application with a given exit code.""" - raise Exit(code) - - def get_usage(self) -> str: - """Helper method to get formatted usage string for the current - context and command. - """ - return self.command.get_usage(self) - - def get_help(self) -> str: - """Helper method to get formatted help page for the current - context and command. - """ - return self.command.get_help(self) - - def _make_sub_context(self, command: "Command") -> "Context": - """Create a new context of the same type as this context, but - for a new command. - - :meta private: - """ - return type(self)(command, info_name=command.name, parent=self) - - def invoke( - __self, # noqa: B902 - __callback: t.Union["Command", t.Callable[..., t.Any]], - *args: t.Any, - **kwargs: t.Any, - ) -> t.Any: - """Invokes a command callback in exactly the way it expects. There - are two ways to invoke this method: - - 1. the first argument can be a callback and all other arguments and - keyword arguments are forwarded directly to the function. - 2. the first argument is a click command object. In that case all - arguments are forwarded as well but proper click parameters - (options and click arguments) must be keyword arguments and Click - will fill in defaults. - - Note that before Click 3.2 keyword arguments were not properly filled - in against the intention of this code and no context was created. For - more information about this change and why it was done in a bugfix - release see :ref:`upgrade-to-3.2`. - - .. versionchanged:: 8.0 - All ``kwargs`` are tracked in :attr:`params` so they will be - passed if :meth:`forward` is called at multiple levels. - """ - if isinstance(__callback, Command): - other_cmd = __callback - - if other_cmd.callback is None: - raise TypeError( - "The given command does not have a callback that can be invoked." - ) - else: - __callback = other_cmd.callback - - ctx = __self._make_sub_context(other_cmd) - - for param in other_cmd.params: - if param.name not in kwargs and param.expose_value: - kwargs[param.name] = param.type_cast_value( # type: ignore - ctx, param.get_default(ctx) - ) - - # Track all kwargs as params, so that forward() will pass - # them on in subsequent calls. - ctx.params.update(kwargs) - else: - ctx = __self - - with augment_usage_errors(__self): - with ctx: - return __callback(*args, **kwargs) - - def forward( - __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 - ) -> t.Any: - """Similar to :meth:`invoke` but fills in default keyword - arguments from the current context if the other command expects - it. This cannot invoke callbacks directly, only other commands. - - .. versionchanged:: 8.0 - All ``kwargs`` are tracked in :attr:`params` so they will be - passed if ``forward`` is called at multiple levels. - """ - # Can only forward to other commands, not direct callbacks. - if not isinstance(__cmd, Command): - raise TypeError("Callback is not a command.") - - for param in __self.params: - if param not in kwargs: - kwargs[param] = __self.params[param] - - return __self.invoke(__cmd, *args, **kwargs) - - def set_parameter_source(self, name: str, source: ParameterSource) -> None: - """Set the source of a parameter. This indicates the location - from which the value of the parameter was obtained. - - :param name: The name of the parameter. - :param source: A member of :class:`~click.core.ParameterSource`. - """ - self._parameter_source[name] = source - - def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: - """Get the source of a parameter. This indicates the location - from which the value of the parameter was obtained. - - This can be useful for determining when a user specified a value - on the command line that is the same as the default value. It - will be :attr:`~click.core.ParameterSource.DEFAULT` only if the - value was actually taken from the default. - - :param name: The name of the parameter. - :rtype: ParameterSource - - .. versionchanged:: 8.0 - Returns ``None`` if the parameter was not provided from any - source. - """ - return self._parameter_source.get(name) - - -class BaseCommand: - """The base command implements the minimal API contract of commands. - Most code will never use this as it does not implement a lot of useful - functionality but it can act as the direct subclass of alternative - parsing methods that do not depend on the Click parser. - - For instance, this can be used to bridge Click and other systems like - argparse or docopt. - - Because base commands do not implement a lot of the API that other - parts of Click take for granted, they are not supported for all - operations. For instance, they cannot be used with the decorators - usually and they have no built-in callback system. - - .. versionchanged:: 2.0 - Added the `context_settings` parameter. - - :param name: the name of the command to use unless a group overrides it. - :param context_settings: an optional dictionary with defaults that are - passed to the context object. - """ - - #: The context class to create with :meth:`make_context`. - #: - #: .. versionadded:: 8.0 - context_class: t.Type[Context] = Context - #: the default for the :attr:`Context.allow_extra_args` flag. - allow_extra_args = False - #: the default for the :attr:`Context.allow_interspersed_args` flag. - allow_interspersed_args = True - #: the default for the :attr:`Context.ignore_unknown_options` flag. - ignore_unknown_options = False - - def __init__( - self, - name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, - ) -> None: - #: the name the command thinks it has. Upon registering a command - #: on a :class:`Group` the group will default the command name - #: with this information. You should instead use the - #: :class:`Context`\'s :attr:`~Context.info_name` attribute. - self.name = name - - if context_settings is None: - context_settings = {} - - #: an optional dictionary with defaults passed to the context. - self.context_settings: t.Dict[str, t.Any] = context_settings - - def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: - """Gather information that could be useful for a tool generating - user-facing documentation. This traverses the entire structure - below this command. - - Use :meth:`click.Context.to_info_dict` to traverse the entire - CLI structure. - - :param ctx: A :class:`Context` representing this command. - - .. versionadded:: 8.0 - """ - return {"name": self.name} - - def __repr__(self) -> str: - return f"<{self.__class__.__name__} {self.name}>" - - def get_usage(self, ctx: Context) -> str: - raise NotImplementedError("Base commands cannot get usage") - - def get_help(self, ctx: Context) -> str: - raise NotImplementedError("Base commands cannot get help") - - def make_context( - self, - info_name: t.Optional[str], - args: t.List[str], - parent: t.Optional[Context] = None, - **extra: t.Any, - ) -> Context: - """This function when given an info name and arguments will kick - off the parsing and create a new :class:`Context`. It does not - invoke the actual command callback though. - - To quickly customize the context class used without overriding - this method, set the :attr:`context_class` attribute. - - :param info_name: the info name for this invocation. Generally this - is the most descriptive name for the script or - command. For the toplevel script it's usually - the name of the script, for commands below it it's - the name of the command. - :param args: the arguments to parse as list of strings. - :param parent: the parent context if available. - :param extra: extra keyword arguments forwarded to the context - constructor. - - .. versionchanged:: 8.0 - Added the :attr:`context_class` attribute. - """ - for key, value in self.context_settings.items(): - if key not in extra: - extra[key] = value - - ctx = self.context_class( - self, info_name=info_name, parent=parent, **extra # type: ignore - ) - - with ctx.scope(cleanup=False): - self.parse_args(ctx, args) - return ctx - - def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: - """Given a context and a list of arguments this creates the parser - and parses the arguments, then modifies the context as necessary. - This is automatically invoked by :meth:`make_context`. - """ - raise NotImplementedError("Base commands do not know how to parse arguments.") - - def invoke(self, ctx: Context) -> t.Any: - """Given a context, this invokes the command. The default - implementation is raising a not implemented error. - """ - raise NotImplementedError("Base commands are not invokable by default") - - def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: - """Return a list of completions for the incomplete value. Looks - at the names of chained multi-commands. - - Any command could be part of a chained multi-command, so sibling - commands are valid at any point during command completion. Other - command classes will return more completions. - - :param ctx: Invocation context for this command. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - results: t.List["CompletionItem"] = [] - - while ctx.parent is not None: - ctx = ctx.parent - - if isinstance(ctx.command, MultiCommand) and ctx.command.chain: - results.extend( - CompletionItem(name, help=command.get_short_help_str()) - for name, command in _complete_visible_commands(ctx, incomplete) - if name not in ctx.protected_args - ) - - return results - - @t.overload - def main( - self, - args: t.Optional[t.Sequence[str]] = None, - prog_name: t.Optional[str] = None, - complete_var: t.Optional[str] = None, - standalone_mode: "te.Literal[True]" = True, - **extra: t.Any, - ) -> "te.NoReturn": - ... - - @t.overload - def main( - self, - args: t.Optional[t.Sequence[str]] = None, - prog_name: t.Optional[str] = None, - complete_var: t.Optional[str] = None, - standalone_mode: bool = ..., - **extra: t.Any, - ) -> t.Any: - ... - - def main( - self, - args: t.Optional[t.Sequence[str]] = None, - prog_name: t.Optional[str] = None, - complete_var: t.Optional[str] = None, - standalone_mode: bool = True, - windows_expand_args: bool = True, - **extra: t.Any, - ) -> t.Any: - """This is the way to invoke a script with all the bells and - whistles as a command line application. This will always terminate - the application after a call. If this is not wanted, ``SystemExit`` - needs to be caught. - - This method is also available by directly calling the instance of - a :class:`Command`. - - :param args: the arguments that should be used for parsing. If not - provided, ``sys.argv[1:]`` is used. - :param prog_name: the program name that should be used. By default - the program name is constructed by taking the file - name from ``sys.argv[0]``. - :param complete_var: the environment variable that controls the - bash completion support. The default is - ``"__COMPLETE"`` with prog_name in - uppercase. - :param standalone_mode: the default behavior is to invoke the script - in standalone mode. Click will then - handle exceptions and convert them into - error messages and the function will never - return but shut down the interpreter. If - this is set to `False` they will be - propagated to the caller and the return - value of this function is the return value - of :meth:`invoke`. - :param windows_expand_args: Expand glob patterns, user dir, and - env vars in command line args on Windows. - :param extra: extra keyword arguments are forwarded to the context - constructor. See :class:`Context` for more information. - - .. versionchanged:: 8.0.1 - Added the ``windows_expand_args`` parameter to allow - disabling command line arg expansion on Windows. - - .. versionchanged:: 8.0 - When taking arguments from ``sys.argv`` on Windows, glob - patterns, user dir, and env vars are expanded. - - .. versionchanged:: 3.0 - Added the ``standalone_mode`` parameter. - """ - # Verify that the environment is configured correctly, or reject - # further execution to avoid a broken script. - _verify_python_env() - - if args is None: - args = sys.argv[1:] - - if os.name == "nt" and windows_expand_args: - args = _expand_args(args) - else: - args = list(args) - - if prog_name is None: - prog_name = _detect_program_name() - - # Process shell completion requests and exit early. - self._main_shell_completion(extra, prog_name, complete_var) - - try: - try: - with self.make_context(prog_name, args, **extra) as ctx: - rv = self.invoke(ctx) - if not standalone_mode: - return rv - # it's not safe to `ctx.exit(rv)` here! - # note that `rv` may actually contain data like "1" which - # has obvious effects - # more subtle case: `rv=[None, None]` can come out of - # chained commands which all returned `None` -- so it's not - # even always obvious that `rv` indicates success/failure - # by its truthiness/falsiness - ctx.exit() - except (EOFError, KeyboardInterrupt): - echo(file=sys.stderr) - raise Abort() from None - except ClickException as e: - if not standalone_mode: - raise - e.show() - sys.exit(e.exit_code) - except OSError as e: - if e.errno == errno.EPIPE: - sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) - sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) - sys.exit(1) - else: - raise - except Exit as e: - if standalone_mode: - sys.exit(e.exit_code) - else: - # in non-standalone mode, return the exit code - # note that this is only reached if `self.invoke` above raises - # an Exit explicitly -- thus bypassing the check there which - # would return its result - # the results of non-standalone execution may therefore be - # somewhat ambiguous: if there are codepaths which lead to - # `ctx.exit(1)` and to `return 1`, the caller won't be able to - # tell the difference between the two - return e.exit_code - except Abort: - if not standalone_mode: - raise - echo(_("Aborted!"), file=sys.stderr) - sys.exit(1) - - def _main_shell_completion( - self, - ctx_args: t.Dict[str, t.Any], - prog_name: str, - complete_var: t.Optional[str] = None, - ) -> None: - """Check if the shell is asking for tab completion, process - that, then exit early. Called from :meth:`main` before the - program is invoked. - - :param prog_name: Name of the executable in the shell. - :param complete_var: Name of the environment variable that holds - the completion instruction. Defaults to - ``_{PROG_NAME}_COMPLETE``. - """ - if complete_var is None: - complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() - - instruction = os.environ.get(complete_var) - - if not instruction: - return - - from .shell_completion import shell_complete - - rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) - sys.exit(rv) - - def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: - """Alias for :meth:`main`.""" - return self.main(*args, **kwargs) - - -class Command(BaseCommand): - """Commands are the basic building block of command line interfaces in - Click. A basic command handles command line parsing and might dispatch - more parsing to commands nested below it. - - .. versionchanged:: 2.0 - Added the `context_settings` parameter. - .. versionchanged:: 8.0 - Added repr showing the command name - .. versionchanged:: 7.1 - Added the `no_args_is_help` parameter. - - :param name: the name of the command to use unless a group overrides it. - :param context_settings: an optional dictionary with defaults that are - passed to the context object. - :param callback: the callback to invoke. This is optional. - :param params: the parameters to register with this command. This can - be either :class:`Option` or :class:`Argument` objects. - :param help: the help string to use for this command. - :param epilog: like the help string but it's printed at the end of the - help page after everything else. - :param short_help: the short help to use for this command. This is - shown on the command listing of the parent command. - :param add_help_option: by default each command registers a ``--help`` - option. This can be disabled by this parameter. - :param no_args_is_help: this controls what happens if no arguments are - provided. This option is disabled by default. - If enabled this will add ``--help`` as argument - if no arguments are passed - :param hidden: hide this command from help outputs. - - :param deprecated: issues a message indicating that - the command is deprecated. - """ - - def __init__( - self, - name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, - callback: t.Optional[t.Callable[..., t.Any]] = None, - params: t.Optional[t.List["Parameter"]] = None, - help: t.Optional[str] = None, - epilog: t.Optional[str] = None, - short_help: t.Optional[str] = None, - options_metavar: t.Optional[str] = "[OPTIONS]", - add_help_option: bool = True, - no_args_is_help: bool = False, - hidden: bool = False, - deprecated: bool = False, - ) -> None: - super().__init__(name, context_settings) - #: the callback to execute when the command fires. This might be - #: `None` in which case nothing happens. - self.callback = callback - #: the list of parameters for this command in the order they - #: should show up in the help page and execute. Eager parameters - #: will automatically be handled before non eager ones. - self.params: t.List["Parameter"] = params or [] - - # if a form feed (page break) is found in the help text, truncate help - # text to the content preceding the first form feed - if help and "\f" in help: - help = help.split("\f", 1)[0] - - self.help = help - self.epilog = epilog - self.options_metavar = options_metavar - self.short_help = short_help - self.add_help_option = add_help_option - self.no_args_is_help = no_args_is_help - self.hidden = hidden - self.deprecated = deprecated - - def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict(ctx) - info_dict.update( - params=[param.to_info_dict() for param in self.get_params(ctx)], - help=self.help, - epilog=self.epilog, - short_help=self.short_help, - hidden=self.hidden, - deprecated=self.deprecated, - ) - return info_dict - - def get_usage(self, ctx: Context) -> str: - """Formats the usage line into a string and returns it. - - Calls :meth:`format_usage` internally. - """ - formatter = ctx.make_formatter() - self.format_usage(ctx, formatter) - return formatter.getvalue().rstrip("\n") - - def get_params(self, ctx: Context) -> t.List["Parameter"]: - rv = self.params - help_option = self.get_help_option(ctx) - - if help_option is not None: - rv = [*rv, help_option] - - return rv - - def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: - """Writes the usage line into the formatter. - - This is a low-level method called by :meth:`get_usage`. - """ - pieces = self.collect_usage_pieces(ctx) - formatter.write_usage(ctx.command_path, " ".join(pieces)) - - def collect_usage_pieces(self, ctx: Context) -> t.List[str]: - """Returns all the pieces that go into the usage line and returns - it as a list of strings. - """ - rv = [self.options_metavar] if self.options_metavar else [] - - for param in self.get_params(ctx): - rv.extend(param.get_usage_pieces(ctx)) - - return rv - - def get_help_option_names(self, ctx: Context) -> t.List[str]: - """Returns the names for the help option.""" - all_names = set(ctx.help_option_names) - for param in self.params: - all_names.difference_update(param.opts) - all_names.difference_update(param.secondary_opts) - return list(all_names) - - def get_help_option(self, ctx: Context) -> t.Optional["Option"]: - """Returns the help option object.""" - help_options = self.get_help_option_names(ctx) - - if not help_options or not self.add_help_option: - return None - - def show_help(ctx: Context, param: "Parameter", value: str) -> None: - if value and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - return Option( - help_options, - is_flag=True, - is_eager=True, - expose_value=False, - callback=show_help, - help=_("Show this message and exit."), - ) - - def make_parser(self, ctx: Context) -> OptionParser: - """Creates the underlying option parser for this command.""" - parser = OptionParser(ctx) - for param in self.get_params(ctx): - param.add_to_parser(parser, ctx) - return parser - - def get_help(self, ctx: Context) -> str: - """Formats the help into a string and returns it. - - Calls :meth:`format_help` internally. - """ - formatter = ctx.make_formatter() - self.format_help(ctx, formatter) - return formatter.getvalue().rstrip("\n") - - def get_short_help_str(self, limit: int = 45) -> str: - """Gets short help for the command or makes it by shortening the - long help string. - """ - text = self.short_help or "" - - if not text and self.help: - text = make_default_short_help(self.help, limit) - - if self.deprecated: - text = _("(Deprecated) {text}").format(text=text) - - return text.strip() - - def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: - """Writes the help into the formatter if it exists. - - This is a low-level method called by :meth:`get_help`. - - This calls the following methods: - - - :meth:`format_usage` - - :meth:`format_help_text` - - :meth:`format_options` - - :meth:`format_epilog` - """ - self.format_usage(ctx, formatter) - self.format_help_text(ctx, formatter) - self.format_options(ctx, formatter) - self.format_epilog(ctx, formatter) - - def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: - """Writes the help text to the formatter if it exists.""" - text = self.help or "" - - if self.deprecated: - text = _("(Deprecated) {text}").format(text=text) - - if text: - formatter.write_paragraph() - - with formatter.indentation(): - formatter.write_text(text) - - def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: - """Writes all the options into the formatter if they exist.""" - opts = [] - for param in self.get_params(ctx): - rv = param.get_help_record(ctx) - if rv is not None: - opts.append(rv) - - if opts: - with formatter.section(_("Options")): - formatter.write_dl(opts) - - def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: - """Writes the epilog into the formatter if it exists.""" - if self.epilog: - formatter.write_paragraph() - with formatter.indentation(): - formatter.write_text(self.epilog) - - def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: - if not args and self.no_args_is_help and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - parser = self.make_parser(ctx) - opts, args, param_order = parser.parse_args(args=args) - - for param in iter_params_for_processing(param_order, self.get_params(ctx)): - value, args = param.handle_parse_result(ctx, opts, args) - - if args and not ctx.allow_extra_args and not ctx.resilient_parsing: - ctx.fail( - ngettext( - "Got unexpected extra argument ({args})", - "Got unexpected extra arguments ({args})", - len(args), - ).format(args=" ".join(map(str, args))) - ) - - ctx.args = args - return args - - def invoke(self, ctx: Context) -> t.Any: - """Given a context, this invokes the attached callback (if it exists) - in the right way. - """ - if self.deprecated: - message = _( - "DeprecationWarning: The command {name!r} is deprecated." - ).format(name=self.name) - echo(style(message, fg="red"), err=True) - - if self.callback is not None: - return ctx.invoke(self.callback, **ctx.params) - - def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: - """Return a list of completions for the incomplete value. Looks - at the names of options and chained multi-commands. - - :param ctx: Invocation context for this command. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - results: t.List["CompletionItem"] = [] - - if incomplete and not incomplete[0].isalnum(): - for param in self.get_params(ctx): - if ( - not isinstance(param, Option) - or param.hidden - or ( - not param.multiple - and ctx.get_parameter_source(param.name) # type: ignore - is ParameterSource.COMMANDLINE - ) - ): - continue - - results.extend( - CompletionItem(name, help=param.help) - for name in [*param.opts, *param.secondary_opts] - if name.startswith(incomplete) - ) - - results.extend(super().shell_complete(ctx, incomplete)) - return results - - -class MultiCommand(Command): - """A multi command is the basic implementation of a command that - dispatches to subcommands. The most common version is the - :class:`Group`. - - :param invoke_without_command: this controls how the multi command itself - is invoked. By default it's only invoked - if a subcommand is provided. - :param no_args_is_help: this controls what happens if no arguments are - provided. This option is enabled by default if - `invoke_without_command` is disabled or disabled - if it's enabled. If enabled this will add - ``--help`` as argument if no arguments are - passed. - :param subcommand_metavar: the string that is used in the documentation - to indicate the subcommand place. - :param chain: if this is set to `True` chaining of multiple subcommands - is enabled. This restricts the form of commands in that - they cannot have optional arguments but it allows - multiple commands to be chained together. - :param result_callback: The result callback to attach to this multi - command. This can be set or changed later with the - :meth:`result_callback` decorator. - """ - - allow_extra_args = True - allow_interspersed_args = False - - def __init__( - self, - name: t.Optional[str] = None, - invoke_without_command: bool = False, - no_args_is_help: t.Optional[bool] = None, - subcommand_metavar: t.Optional[str] = None, - chain: bool = False, - result_callback: t.Optional[t.Callable[..., t.Any]] = None, - **attrs: t.Any, - ) -> None: - super().__init__(name, **attrs) - - if no_args_is_help is None: - no_args_is_help = not invoke_without_command - - self.no_args_is_help = no_args_is_help - self.invoke_without_command = invoke_without_command - - if subcommand_metavar is None: - if chain: - subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." - else: - subcommand_metavar = "COMMAND [ARGS]..." - - self.subcommand_metavar = subcommand_metavar - self.chain = chain - # The result callback that is stored. This can be set or - # overridden with the :func:`result_callback` decorator. - self._result_callback = result_callback - - if self.chain: - for param in self.params: - if isinstance(param, Argument) and not param.required: - raise RuntimeError( - "Multi commands in chain mode cannot have" - " optional arguments." - ) - - def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict(ctx) - commands = {} - - for name in self.list_commands(ctx): - command = self.get_command(ctx, name) - - if command is None: - continue - - sub_ctx = ctx._make_sub_context(command) - - with sub_ctx.scope(cleanup=False): - commands[name] = command.to_info_dict(sub_ctx) - - info_dict.update(commands=commands, chain=self.chain) - return info_dict - - def collect_usage_pieces(self, ctx: Context) -> t.List[str]: - rv = super().collect_usage_pieces(ctx) - rv.append(self.subcommand_metavar) - return rv - - def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: - super().format_options(ctx, formatter) - self.format_commands(ctx, formatter) - - def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: - """Adds a result callback to the command. By default if a - result callback is already registered this will chain them but - this can be disabled with the `replace` parameter. The result - callback is invoked with the return value of the subcommand - (or the list of return values from all subcommands if chaining - is enabled) as well as the parameters as they would be passed - to the main callback. - - Example:: - - @click.group() - @click.option('-i', '--input', default=23) - def cli(input): - return 42 - - @cli.result_callback() - def process_result(result, input): - return result + input - - :param replace: if set to `True` an already existing result - callback will be removed. - - .. versionchanged:: 8.0 - Renamed from ``resultcallback``. - - .. versionadded:: 3.0 - """ - - def decorator(f: F) -> F: - old_callback = self._result_callback - - if old_callback is None or replace: - self._result_callback = f - return f - - def function(__value, *args, **kwargs): # type: ignore - inner = old_callback(__value, *args, **kwargs) # type: ignore - return f(inner, *args, **kwargs) - - self._result_callback = rv = update_wrapper(t.cast(F, function), f) - return rv - - return decorator - - def resultcallback(self, replace: bool = False) -> t.Callable[[F], F]: - import warnings - - warnings.warn( - "'resultcallback' has been renamed to 'result_callback'." - " The old name will be removed in Click 8.1.", - DeprecationWarning, - stacklevel=2, - ) - return self.result_callback(replace=replace) - - def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: - """Extra format methods for multi methods that adds all the commands - after the options. - """ - commands = [] - for subcommand in self.list_commands(ctx): - cmd = self.get_command(ctx, subcommand) - # What is this, the tool lied about a command. Ignore it - if cmd is None: - continue - if cmd.hidden: - continue - - commands.append((subcommand, cmd)) - - # allow for 3 times the default spacing - if len(commands): - limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) - - rows = [] - for subcommand, cmd in commands: - help = cmd.get_short_help_str(limit) - rows.append((subcommand, help)) - - if rows: - with formatter.section(_("Commands")): - formatter.write_dl(rows) - - def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: - if not args and self.no_args_is_help and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - rest = super().parse_args(ctx, args) - - if self.chain: - ctx.protected_args = rest - ctx.args = [] - elif rest: - ctx.protected_args, ctx.args = rest[:1], rest[1:] - - return ctx.args - - def invoke(self, ctx: Context) -> t.Any: - def _process_result(value: t.Any) -> t.Any: - if self._result_callback is not None: - value = ctx.invoke(self._result_callback, value, **ctx.params) - return value - - if not ctx.protected_args: - if self.invoke_without_command: - # No subcommand was invoked, so the result callback is - # invoked with None for regular groups, or an empty list - # for chained groups. - with ctx: - super().invoke(ctx) - return _process_result([] if self.chain else None) - ctx.fail(_("Missing command.")) - - # Fetch args back out - args = [*ctx.protected_args, *ctx.args] - ctx.args = [] - ctx.protected_args = [] - - # If we're not in chain mode, we only allow the invocation of a - # single command but we also inform the current context about the - # name of the command to invoke. - if not self.chain: - # Make sure the context is entered so we do not clean up - # resources until the result processor has worked. - with ctx: - cmd_name, cmd, args = self.resolve_command(ctx, args) - assert cmd is not None - ctx.invoked_subcommand = cmd_name - super().invoke(ctx) - sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) - with sub_ctx: - return _process_result(sub_ctx.command.invoke(sub_ctx)) - - # In chain mode we create the contexts step by step, but after the - # base command has been invoked. Because at that point we do not - # know the subcommands yet, the invoked subcommand attribute is - # set to ``*`` to inform the command that subcommands are executed - # but nothing else. - with ctx: - ctx.invoked_subcommand = "*" if args else None - super().invoke(ctx) - - # Otherwise we make every single context and invoke them in a - # chain. In that case the return value to the result processor - # is the list of all invoked subcommand's results. - contexts = [] - while args: - cmd_name, cmd, args = self.resolve_command(ctx, args) - assert cmd is not None - sub_ctx = cmd.make_context( - cmd_name, - args, - parent=ctx, - allow_extra_args=True, - allow_interspersed_args=False, - ) - contexts.append(sub_ctx) - args, sub_ctx.args = sub_ctx.args, [] - - rv = [] - for sub_ctx in contexts: - with sub_ctx: - rv.append(sub_ctx.command.invoke(sub_ctx)) - return _process_result(rv) - - def resolve_command( - self, ctx: Context, args: t.List[str] - ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: - cmd_name = make_str(args[0]) - original_cmd_name = cmd_name - - # Get the command - cmd = self.get_command(ctx, cmd_name) - - # If we can't find the command but there is a normalization - # function available, we try with that one. - if cmd is None and ctx.token_normalize_func is not None: - cmd_name = ctx.token_normalize_func(cmd_name) - cmd = self.get_command(ctx, cmd_name) - - # If we don't find the command we want to show an error message - # to the user that it was not provided. However, there is - # something else we should do: if the first argument looks like - # an option we want to kick off parsing again for arguments to - # resolve things like --help which now should go to the main - # place. - if cmd is None and not ctx.resilient_parsing: - if split_opt(cmd_name)[0]: - self.parse_args(ctx, ctx.args) - ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) - return cmd_name if cmd else None, cmd, args[1:] - - def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: - """Given a context and a command name, this returns a - :class:`Command` object if it exists or returns `None`. - """ - raise NotImplementedError - - def list_commands(self, ctx: Context) -> t.List[str]: - """Returns a list of subcommand names in the order they should - appear. - """ - return [] - - def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: - """Return a list of completions for the incomplete value. Looks - at the names of options, subcommands, and chained - multi-commands. - - :param ctx: Invocation context for this command. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - results = [ - CompletionItem(name, help=command.get_short_help_str()) - for name, command in _complete_visible_commands(ctx, incomplete) - ] - results.extend(super().shell_complete(ctx, incomplete)) - return results - - -class Group(MultiCommand): - """A group allows a command to have subcommands attached. This is - the most common way to implement nesting in Click. - - :param name: The name of the group command. - :param commands: A dict mapping names to :class:`Command` objects. - Can also be a list of :class:`Command`, which will use - :attr:`Command.name` to create the dict. - :param attrs: Other command arguments described in - :class:`MultiCommand`, :class:`Command`, and - :class:`BaseCommand`. - - .. versionchanged:: 8.0 - The ``commmands`` argument can be a list of command objects. - """ - - #: If set, this is used by the group's :meth:`command` decorator - #: as the default :class:`Command` class. This is useful to make all - #: subcommands use a custom command class. - #: - #: .. versionadded:: 8.0 - command_class: t.Optional[t.Type[Command]] = None - - #: If set, this is used by the group's :meth:`group` decorator - #: as the default :class:`Group` class. This is useful to make all - #: subgroups use a custom group class. - #: - #: If set to the special value :class:`type` (literally - #: ``group_class = type``), this group's class will be used as the - #: default class. This makes a custom group class continue to make - #: custom groups. - #: - #: .. versionadded:: 8.0 - group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None - # Literal[type] isn't valid, so use Type[type] - - def __init__( - self, - name: t.Optional[str] = None, - commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, - **attrs: t.Any, - ) -> None: - super().__init__(name, **attrs) - - if commands is None: - commands = {} - elif isinstance(commands, abc.Sequence): - commands = {c.name: c for c in commands if c.name is not None} - - #: The registered subcommands by their exported names. - self.commands: t.Dict[str, Command] = commands - - def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: - """Registers another :class:`Command` with this group. If the name - is not provided, the name of the command is used. - """ - name = name or cmd.name - if name is None: - raise TypeError("Command has no name.") - _check_multicommand(self, name, cmd, register=True) - self.commands[name] = cmd - - def command( - self, *args: t.Any, **kwargs: t.Any - ) -> t.Callable[[t.Callable[..., t.Any]], Command]: - """A shortcut decorator for declaring and attaching a command to - the group. This takes the same arguments as :func:`command` and - immediately registers the created command with this group by - calling :meth:`add_command`. - - To customize the command class used, set the - :attr:`command_class` attribute. - - .. versionchanged:: 8.0 - Added the :attr:`command_class` attribute. - """ - from .decorators import command - - if self.command_class is not None and "cls" not in kwargs: - kwargs["cls"] = self.command_class - - def decorator(f: t.Callable[..., t.Any]) -> Command: - cmd = command(*args, **kwargs)(f) - self.add_command(cmd) - return cmd - - return decorator - - def group( - self, *args: t.Any, **kwargs: t.Any - ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: - """A shortcut decorator for declaring and attaching a group to - the group. This takes the same arguments as :func:`group` and - immediately registers the created group with this group by - calling :meth:`add_command`. - - To customize the group class used, set the :attr:`group_class` - attribute. - - .. versionchanged:: 8.0 - Added the :attr:`group_class` attribute. - """ - from .decorators import group - - if self.group_class is not None and "cls" not in kwargs: - if self.group_class is type: - kwargs["cls"] = type(self) - else: - kwargs["cls"] = self.group_class - - def decorator(f: t.Callable[..., t.Any]) -> "Group": - cmd = group(*args, **kwargs)(f) - self.add_command(cmd) - return cmd - - return decorator - - def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: - return self.commands.get(cmd_name) - - def list_commands(self, ctx: Context) -> t.List[str]: - return sorted(self.commands) - - -class CommandCollection(MultiCommand): - """A command collection is a multi command that merges multiple multi - commands together into one. This is a straightforward implementation - that accepts a list of different multi commands as sources and - provides all the commands for each of them. - """ - - def __init__( - self, - name: t.Optional[str] = None, - sources: t.Optional[t.List[MultiCommand]] = None, - **attrs: t.Any, - ) -> None: - super().__init__(name, **attrs) - #: The list of registered multi commands. - self.sources: t.List[MultiCommand] = sources or [] - - def add_source(self, multi_cmd: MultiCommand) -> None: - """Adds a new multi command to the chain dispatcher.""" - self.sources.append(multi_cmd) - - def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: - for source in self.sources: - rv = source.get_command(ctx, cmd_name) - - if rv is not None: - if self.chain: - _check_multicommand(self, cmd_name, rv) - - return rv - - return None - - def list_commands(self, ctx: Context) -> t.List[str]: - rv: t.Set[str] = set() - - for source in self.sources: - rv.update(source.list_commands(ctx)) - - return sorted(rv) - - -def _check_iter(value: t.Any) -> t.Iterator[t.Any]: - """Check if the value is iterable but not a string. Raises a type - error, or return an iterator over the value. - """ - if isinstance(value, str): - raise TypeError - - return iter(value) - - -class Parameter: - r"""A parameter to a command comes in two versions: they are either - :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently - not supported by design as some of the internals for parsing are - intentionally not finalized. - - Some settings are supported by both options and arguments. - - :param param_decls: the parameter declarations for this option or - argument. This is a list of flags or argument - names. - :param type: the type that should be used. Either a :class:`ParamType` - or a Python type. The later is converted into the former - automatically if supported. - :param required: controls if this is optional or not. - :param default: the default value if omitted. This can also be a callable, - in which case it's invoked when the default is needed - without any arguments. - :param callback: A function to further process or validate the value - after type conversion. It is called as ``f(ctx, param, value)`` - and must return the value. It is called for all sources, - including prompts. - :param nargs: the number of arguments to match. If not ``1`` the return - value is a tuple instead of single value. The default for - nargs is ``1`` (except if the type is a tuple, then it's - the arity of the tuple). If ``nargs=-1``, all remaining - parameters are collected. - :param metavar: how the value is represented in the help page. - :param expose_value: if this is `True` then the value is passed onwards - to the command callback and stored on the context, - otherwise it's skipped. - :param is_eager: eager values are processed before non eager ones. This - should not be set for arguments or it will inverse the - order of processing. - :param envvar: a string or list of strings that are environment variables - that should be checked. - :param shell_complete: A function that returns custom shell - completions. Used instead of the param's type completion if - given. Takes ``ctx, param, incomplete`` and must return a list - of :class:`~click.shell_completion.CompletionItem` or a list of - strings. - - .. versionchanged:: 8.0 - ``process_value`` validates required parameters and bounded - ``nargs``, and invokes the parameter callback before returning - the value. This allows the callback to validate prompts. - ``full_process_value`` is removed. - - .. versionchanged:: 8.0 - ``autocompletion`` is renamed to ``shell_complete`` and has new - semantics described above. The old name is deprecated and will - be removed in 8.1, until then it will be wrapped to match the - new requirements. - - .. versionchanged:: 8.0 - For ``multiple=True, nargs>1``, the default must be a list of - tuples. - - .. versionchanged:: 8.0 - Setting a default is no longer required for ``nargs>1``, it will - default to ``None``. ``multiple=True`` or ``nargs=-1`` will - default to ``()``. - - .. versionchanged:: 7.1 - Empty environment variables are ignored rather than taking the - empty string value. This makes it possible for scripts to clear - variables if they can't unset them. - - .. versionchanged:: 2.0 - Changed signature for parameter callback to also be passed the - parameter. The old callback format will still work, but it will - raise a warning to give you a chance to migrate the code easier. - """ - - param_type_name = "parameter" - - def __init__( - self, - param_decls: t.Optional[t.Sequence[str]] = None, - type: t.Optional[t.Union[types.ParamType, t.Any]] = None, - required: bool = False, - default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, - callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, - nargs: t.Optional[int] = None, - multiple: bool = False, - metavar: t.Optional[str] = None, - expose_value: bool = True, - is_eager: bool = False, - envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, - shell_complete: t.Optional[ - t.Callable[ - [Context, "Parameter", str], - t.Union[t.List["CompletionItem"], t.List[str]], - ] - ] = None, - autocompletion: t.Optional[ - t.Callable[ - [Context, t.List[str], str], t.List[t.Union[t.Tuple[str, str], str]] - ] - ] = None, - ) -> None: - self.name, self.opts, self.secondary_opts = self._parse_decls( - param_decls or (), expose_value - ) - self.type = types.convert_type(type, default) - - # Default nargs to what the type tells us if we have that - # information available. - if nargs is None: - if self.type.is_composite: - nargs = self.type.arity - else: - nargs = 1 - - self.required = required - self.callback = callback - self.nargs = nargs - self.multiple = multiple - self.expose_value = expose_value - self.default = default - self.is_eager = is_eager - self.metavar = metavar - self.envvar = envvar - - if autocompletion is not None: - import warnings - - warnings.warn( - "'autocompletion' is renamed to 'shell_complete'. The old name is" - " deprecated and will be removed in Click 8.1. See the docs about" - " 'Parameter' for information about new behavior.", - DeprecationWarning, - stacklevel=2, - ) - - def shell_complete( - ctx: Context, param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - from click.shell_completion import CompletionItem - - out = [] - - for c in autocompletion(ctx, [], incomplete): # type: ignore - if isinstance(c, tuple): - c = CompletionItem(c[0], help=c[1]) - elif isinstance(c, str): - c = CompletionItem(c) - - if c.value.startswith(incomplete): - out.append(c) - - return out - - self._custom_shell_complete = shell_complete - - if __debug__: - if self.type.is_composite and nargs != self.type.arity: - raise ValueError( - f"'nargs' must be {self.type.arity} (or None) for" - f" type {self.type!r}, but it was {nargs}." - ) - - # Skip no default or callable default. - check_default = default if not callable(default) else None - - if check_default is not None: - if multiple: - try: - # Only check the first value against nargs. - check_default = next(_check_iter(check_default), None) - except TypeError: - raise ValueError( - "'default' must be a list when 'multiple' is true." - ) from None - - # Can be None for multiple with empty default. - if nargs != 1 and check_default is not None: - try: - _check_iter(check_default) - except TypeError: - if multiple: - message = ( - "'default' must be a list of lists when 'multiple' is" - " true and 'nargs' != 1." - ) - else: - message = "'default' must be a list when 'nargs' != 1." - - raise ValueError(message) from None - - if nargs > 1 and len(check_default) != nargs: - subject = "item length" if multiple else "length" - raise ValueError( - f"'default' {subject} must match nargs={nargs}." - ) - - def to_info_dict(self) -> t.Dict[str, t.Any]: - """Gather information that could be useful for a tool generating - user-facing documentation. - - Use :meth:`click.Context.to_info_dict` to traverse the entire - CLI structure. - - .. versionadded:: 8.0 - """ - return { - "name": self.name, - "param_type_name": self.param_type_name, - "opts": self.opts, - "secondary_opts": self.secondary_opts, - "type": self.type.to_info_dict(), - "required": self.required, - "nargs": self.nargs, - "multiple": self.multiple, - "default": self.default, - "envvar": self.envvar, - } - - def __repr__(self) -> str: - return f"<{self.__class__.__name__} {self.name}>" - - def _parse_decls( - self, decls: t.Sequence[str], expose_value: bool - ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: - raise NotImplementedError() - - @property - def human_readable_name(self) -> str: - """Returns the human readable name of this parameter. This is the - same as the name for options, but the metavar for arguments. - """ - return self.name # type: ignore - - def make_metavar(self) -> str: - if self.metavar is not None: - return self.metavar - - metavar = self.type.get_metavar(self) - - if metavar is None: - metavar = self.type.name.upper() - - if self.nargs != 1: - metavar += "..." - - return metavar - - @t.overload - def get_default( - self, ctx: Context, call: "te.Literal[True]" = True - ) -> t.Optional[t.Any]: - ... - - @t.overload - def get_default( - self, ctx: Context, call: bool = ... - ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: - ... - - def get_default( - self, ctx: Context, call: bool = True - ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: - """Get the default for the parameter. Tries - :meth:`Context.lookup_default` first, then the local default. - - :param ctx: Current context. - :param call: If the default is a callable, call it. Disable to - return the callable instead. - - .. versionchanged:: 8.0.2 - Type casting is no longer performed when getting a default. - - .. versionchanged:: 8.0.1 - Type casting can fail in resilient parsing mode. Invalid - defaults will not prevent showing help text. - - .. versionchanged:: 8.0 - Looks at ``ctx.default_map`` first. - - .. versionchanged:: 8.0 - Added the ``call`` parameter. - """ - value = ctx.lookup_default(self.name, call=False) # type: ignore - - if value is None: - value = self.default - - if call and callable(value): - value = value() - - return value - - def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: - raise NotImplementedError() - - def consume_value( - self, ctx: Context, opts: t.Mapping[str, t.Any] - ) -> t.Tuple[t.Any, ParameterSource]: - value = opts.get(self.name) # type: ignore - source = ParameterSource.COMMANDLINE - - if value is None: - value = self.value_from_envvar(ctx) - source = ParameterSource.ENVIRONMENT - - if value is None: - value = ctx.lookup_default(self.name) # type: ignore - source = ParameterSource.DEFAULT_MAP - - if value is None: - value = self.get_default(ctx) - source = ParameterSource.DEFAULT - - return value, source - - def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: - """Convert and validate a value against the option's - :attr:`type`, :attr:`multiple`, and :attr:`nargs`. - """ - if value is None: - return () if self.multiple or self.nargs == -1 else None - - def check_iter(value: t.Any) -> t.Iterator: - try: - return _check_iter(value) - except TypeError: - # This should only happen when passing in args manually, - # the parser should construct an iterable when parsing - # the command line. - raise BadParameter( - _("Value must be an iterable."), ctx=ctx, param=self - ) from None - - if self.nargs == 1 or self.type.is_composite: - convert: t.Callable[[t.Any], t.Any] = partial( - self.type, param=self, ctx=ctx - ) - elif self.nargs == -1: - - def convert(value: t.Any) -> t.Tuple: - return tuple(self.type(x, self, ctx) for x in check_iter(value)) - - else: # nargs > 1 - - def convert(value: t.Any) -> t.Tuple: - value = tuple(check_iter(value)) - - if len(value) != self.nargs: - raise BadParameter( - ngettext( - "Takes {nargs} values but 1 was given.", - "Takes {nargs} values but {len} were given.", - len(value), - ).format(nargs=self.nargs, len=len(value)), - ctx=ctx, - param=self, - ) - - return tuple(self.type(x, self, ctx) for x in value) - - if self.multiple: - return tuple(convert(x) for x in check_iter(value)) - - return convert(value) - - def value_is_missing(self, value: t.Any) -> bool: - if value is None: - return True - - if (self.nargs != 1 or self.multiple) and value == (): - return True - - return False - - def process_value(self, ctx: Context, value: t.Any) -> t.Any: - value = self.type_cast_value(ctx, value) - - if self.required and self.value_is_missing(value): - raise MissingParameter(ctx=ctx, param=self) - - if self.callback is not None: - value = self.callback(ctx, self, value) - - return value - - def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: - if self.envvar is None: - return None - - if isinstance(self.envvar, str): - rv = os.environ.get(self.envvar) - - if rv: - return rv - else: - for envvar in self.envvar: - rv = os.environ.get(envvar) - - if rv: - return rv - - return None - - def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: - rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) - - if rv is not None and self.nargs != 1: - rv = self.type.split_envvar_value(rv) - - return rv - - def handle_parse_result( - self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] - ) -> t.Tuple[t.Any, t.List[str]]: - with augment_usage_errors(ctx, param=self): - value, source = self.consume_value(ctx, opts) - ctx.set_parameter_source(self.name, source) # type: ignore - - try: - value = self.process_value(ctx, value) - except Exception: - if not ctx.resilient_parsing: - raise - - value = None - - if self.expose_value: - ctx.params[self.name] = value # type: ignore - - return value, args - - def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: - pass - - def get_usage_pieces(self, ctx: Context) -> t.List[str]: - return [] - - def get_error_hint(self, ctx: Context) -> str: - """Get a stringified version of the param for use in error messages to - indicate which param caused the error. - """ - hint_list = self.opts or [self.human_readable_name] - return " / ".join(f"'{x}'" for x in hint_list) - - def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: - """Return a list of completions for the incomplete value. If a - ``shell_complete`` function was given during init, it is used. - Otherwise, the :attr:`type` - :meth:`~click.types.ParamType.shell_complete` function is used. - - :param ctx: Invocation context for this command. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - if self._custom_shell_complete is not None: - results = self._custom_shell_complete(ctx, self, incomplete) - - if results and isinstance(results[0], str): - from click.shell_completion import CompletionItem - - results = [CompletionItem(c) for c in results] - - return t.cast(t.List["CompletionItem"], results) - - return self.type.shell_complete(ctx, self, incomplete) - - -class Option(Parameter): - """Options are usually optional values on the command line and - have some extra features that arguments don't have. - - All other parameters are passed onwards to the parameter constructor. - - :param show_default: controls if the default value should be shown on the - help page. Normally, defaults are not shown. If this - value is a string, it shows the string instead of the - value. This is particularly useful for dynamic options. - :param show_envvar: controls if an environment variable should be shown on - the help page. Normally, environment variables - are not shown. - :param prompt: if set to `True` or a non empty string then the user will be - prompted for input. If set to `True` the prompt will be the - option name capitalized. - :param confirmation_prompt: Prompt a second time to confirm the - value if it was prompted for. Can be set to a string instead of - ``True`` to customize the message. - :param prompt_required: If set to ``False``, the user will be - prompted for input only when the option was specified as a flag - without a value. - :param hide_input: if this is `True` then the input on the prompt will be - hidden from the user. This is useful for password - input. - :param is_flag: forces this option to act as a flag. The default is - auto detection. - :param flag_value: which value should be used for this flag if it's - enabled. This is set to a boolean automatically if - the option string contains a slash to mark two options. - :param multiple: if this is set to `True` then the argument is accepted - multiple times and recorded. This is similar to ``nargs`` - in how it works but supports arbitrary number of - arguments. - :param count: this flag makes an option increment an integer. - :param allow_from_autoenv: if this is enabled then the value of this - parameter will be pulled from an environment - variable in case a prefix is defined on the - context. - :param help: the help string. - :param hidden: hide this option from help outputs. - - .. versionchanged:: 8.0.1 - ``type`` is detected from ``flag_value`` if given. - """ - - param_type_name = "option" - - def __init__( - self, - param_decls: t.Optional[t.Sequence[str]] = None, - show_default: t.Union[bool, str] = False, - prompt: t.Union[bool, str] = False, - confirmation_prompt: t.Union[bool, str] = False, - prompt_required: bool = True, - hide_input: bool = False, - is_flag: t.Optional[bool] = None, - flag_value: t.Optional[t.Any] = None, - multiple: bool = False, - count: bool = False, - allow_from_autoenv: bool = True, - type: t.Optional[t.Union[types.ParamType, t.Any]] = None, - help: t.Optional[str] = None, - hidden: bool = False, - show_choices: bool = True, - show_envvar: bool = False, - **attrs: t.Any, - ) -> None: - default_is_missing = "default" not in attrs - super().__init__(param_decls, type=type, multiple=multiple, **attrs) - - if prompt is True: - if self.name is None: - raise TypeError("'name' is required with 'prompt=True'.") - - prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() - elif prompt is False: - prompt_text = None - else: - prompt_text = prompt - - self.prompt = prompt_text - self.confirmation_prompt = confirmation_prompt - self.prompt_required = prompt_required - self.hide_input = hide_input - self.hidden = hidden - - # If prompt is enabled but not required, then the option can be - # used as a flag to indicate using prompt or flag_value. - self._flag_needs_value = self.prompt is not None and not self.prompt_required - - if is_flag is None: - if flag_value is not None: - # Implicitly a flag because flag_value was set. - is_flag = True - elif self._flag_needs_value: - # Not a flag, but when used as a flag it shows a prompt. - is_flag = False - else: - # Implicitly a flag because flag options were given. - is_flag = bool(self.secondary_opts) - elif is_flag is False and not self._flag_needs_value: - # Not a flag, and prompt is not enabled, can be used as a - # flag if flag_value is set. - self._flag_needs_value = flag_value is not None - - if is_flag and default_is_missing: - self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False - - if flag_value is None: - flag_value = not self.default - - if is_flag and type is None: - # Re-guess the type from the flag value instead of the - # default. - self.type = types.convert_type(None, flag_value) - - self.is_flag: bool = is_flag - self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType) - self.flag_value: t.Any = flag_value - - # Counting - self.count = count - if count: - if type is None: - self.type = types.IntRange(min=0) - if default_is_missing: - self.default = 0 - - self.allow_from_autoenv = allow_from_autoenv - self.help = help - self.show_default = show_default - self.show_choices = show_choices - self.show_envvar = show_envvar - - if __debug__: - if self.nargs == -1: - raise TypeError("nargs=-1 is not supported for options.") - - if self.prompt and self.is_flag and not self.is_bool_flag: - raise TypeError("'prompt' is not valid for non-boolean flag.") - - if not self.is_bool_flag and self.secondary_opts: - raise TypeError("Secondary flag is not valid for non-boolean flag.") - - if self.is_bool_flag and self.hide_input and self.prompt is not None: - raise TypeError( - "'prompt' with 'hide_input' is not valid for boolean flag." - ) - - if self.count: - if self.multiple: - raise TypeError("'count' is not valid with 'multiple'.") - - if self.is_flag: - raise TypeError("'count' is not valid with 'is_flag'.") - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict.update( - help=self.help, - prompt=self.prompt, - is_flag=self.is_flag, - flag_value=self.flag_value, - count=self.count, - hidden=self.hidden, - ) - return info_dict - - def _parse_decls( - self, decls: t.Sequence[str], expose_value: bool - ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: - opts = [] - secondary_opts = [] - name = None - possible_names = [] - - for decl in decls: - if decl.isidentifier(): - if name is not None: - raise TypeError(f"Name '{name}' defined twice") - name = decl - else: - split_char = ";" if decl[:1] == "/" else "/" - if split_char in decl: - first, second = decl.split(split_char, 1) - first = first.rstrip() - if first: - possible_names.append(split_opt(first)) - opts.append(first) - second = second.lstrip() - if second: - secondary_opts.append(second.lstrip()) - if first == second: - raise ValueError( - f"Boolean option {decl!r} cannot use the" - " same flag for true/false." - ) - else: - possible_names.append(split_opt(decl)) - opts.append(decl) - - if name is None and possible_names: - possible_names.sort(key=lambda x: -len(x[0])) # group long options first - name = possible_names[0][1].replace("-", "_").lower() - if not name.isidentifier(): - name = None - - if name is None: - if not expose_value: - return None, opts, secondary_opts - raise TypeError("Could not determine name for option") - - if not opts and not secondary_opts: - raise TypeError( - f"No options defined but a name was passed ({name})." - " Did you mean to declare an argument instead? Did" - f" you mean to pass '--{name}'?" - ) - - return name, opts, secondary_opts - - def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: - if self.multiple: - action = "append" - elif self.count: - action = "count" - else: - action = "store" - - if self.is_flag: - action = f"{action}_const" - - if self.is_bool_flag and self.secondary_opts: - parser.add_option( - obj=self, opts=self.opts, dest=self.name, action=action, const=True - ) - parser.add_option( - obj=self, - opts=self.secondary_opts, - dest=self.name, - action=action, - const=False, - ) - else: - parser.add_option( - obj=self, - opts=self.opts, - dest=self.name, - action=action, - const=self.flag_value, - ) - else: - parser.add_option( - obj=self, - opts=self.opts, - dest=self.name, - action=action, - nargs=self.nargs, - ) - - def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: - if self.hidden: - return None - - any_prefix_is_slash = False - - def _write_opts(opts: t.Sequence[str]) -> str: - nonlocal any_prefix_is_slash - - rv, any_slashes = join_options(opts) - - if any_slashes: - any_prefix_is_slash = True - - if not self.is_flag and not self.count: - rv += f" {self.make_metavar()}" - - return rv - - rv = [_write_opts(self.opts)] - - if self.secondary_opts: - rv.append(_write_opts(self.secondary_opts)) - - help = self.help or "" - extra = [] - - if self.show_envvar: - envvar = self.envvar - - if envvar is None: - if ( - self.allow_from_autoenv - and ctx.auto_envvar_prefix is not None - and self.name is not None - ): - envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" - - if envvar is not None: - var_str = ( - envvar - if isinstance(envvar, str) - else ", ".join(str(d) for d in envvar) - ) - extra.append(_("env var: {var}").format(var=var_str)) - - # Temporarily enable resilient parsing to avoid type casting - # failing for the default. Might be possible to extend this to - # help formatting in general. - resilient = ctx.resilient_parsing - ctx.resilient_parsing = True - - try: - default_value = self.get_default(ctx, call=False) - finally: - ctx.resilient_parsing = resilient - - show_default_is_str = isinstance(self.show_default, str) - - if show_default_is_str or ( - default_value is not None and (self.show_default or ctx.show_default) - ): - if show_default_is_str: - default_string = f"({self.show_default})" - elif isinstance(default_value, (list, tuple)): - default_string = ", ".join(str(d) for d in default_value) - elif inspect.isfunction(default_value): - default_string = _("(dynamic)") - elif self.is_bool_flag and self.secondary_opts: - # For boolean flags that have distinct True/False opts, - # use the opt without prefix instead of the value. - default_string = split_opt( - (self.opts if self.default else self.secondary_opts)[0] - )[1] - else: - default_string = str(default_value) - - if default_string: - extra.append(_("default: {default}").format(default=default_string)) - - if ( - isinstance(self.type, types._NumberRangeBase) - # skip count with default range type - and not (self.count and self.type.min == 0 and self.type.max is None) - ): - range_str = self.type._describe_range() - - if range_str: - extra.append(range_str) - - if self.required: - extra.append(_("required")) - - if extra: - extra_str = "; ".join(extra) - help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" - - return ("; " if any_prefix_is_slash else " / ").join(rv), help - - @t.overload - def get_default( - self, ctx: Context, call: "te.Literal[True]" = True - ) -> t.Optional[t.Any]: - ... - - @t.overload - def get_default( - self, ctx: Context, call: bool = ... - ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: - ... - - def get_default( - self, ctx: Context, call: bool = True - ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: - # If we're a non boolean flag our default is more complex because - # we need to look at all flags in the same group to figure out - # if we're the default one in which case we return the flag - # value as default. - if self.is_flag and not self.is_bool_flag: - for param in ctx.command.params: - if param.name == self.name and param.default: - return param.flag_value # type: ignore - - return None - - return super().get_default(ctx, call=call) - - def prompt_for_value(self, ctx: Context) -> t.Any: - """This is an alternative flow that can be activated in the full - value processing if a value does not exist. It will prompt the - user until a valid value exists and then returns the processed - value as result. - """ - assert self.prompt is not None - - # Calculate the default before prompting anything to be stable. - default = self.get_default(ctx) - - # If this is a prompt for a flag we need to handle this - # differently. - if self.is_bool_flag: - return confirm(self.prompt, default) - - return prompt( - self.prompt, - default=default, - type=self.type, - hide_input=self.hide_input, - show_choices=self.show_choices, - confirmation_prompt=self.confirmation_prompt, - value_proc=lambda x: self.process_value(ctx, x), - ) - - def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: - rv = super().resolve_envvar_value(ctx) - - if rv is not None: - return rv - - if ( - self.allow_from_autoenv - and ctx.auto_envvar_prefix is not None - and self.name is not None - ): - envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" - rv = os.environ.get(envvar) - - return rv - - def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: - rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) - - if rv is None: - return None - - value_depth = (self.nargs != 1) + bool(self.multiple) - - if value_depth > 0: - rv = self.type.split_envvar_value(rv) - - if self.multiple and self.nargs != 1: - rv = batch(rv, self.nargs) - - return rv - - def consume_value( - self, ctx: Context, opts: t.Mapping[str, "Parameter"] - ) -> t.Tuple[t.Any, ParameterSource]: - value, source = super().consume_value(ctx, opts) - - # The parser will emit a sentinel value if the option can be - # given as a flag without a value. This is different from None - # to distinguish from the flag not being given at all. - if value is _flag_needs_value: - if self.prompt is not None and not ctx.resilient_parsing: - value = self.prompt_for_value(ctx) - source = ParameterSource.PROMPT - else: - value = self.flag_value - source = ParameterSource.COMMANDLINE - - elif ( - self.multiple - and value is not None - and any(v is _flag_needs_value for v in value) - ): - value = [self.flag_value if v is _flag_needs_value else v for v in value] - source = ParameterSource.COMMANDLINE - - # The value wasn't set, or used the param's default, prompt if - # prompting is enabled. - elif ( - source in {None, ParameterSource.DEFAULT} - and self.prompt is not None - and (self.required or self.prompt_required) - and not ctx.resilient_parsing - ): - value = self.prompt_for_value(ctx) - source = ParameterSource.PROMPT - - return value, source - - -class Argument(Parameter): - """Arguments are positional parameters to a command. They generally - provide fewer features than options but can have infinite ``nargs`` - and are required by default. - - All parameters are passed onwards to the parameter constructor. - """ - - param_type_name = "argument" - - def __init__( - self, - param_decls: t.Sequence[str], - required: t.Optional[bool] = None, - **attrs: t.Any, - ) -> None: - if required is None: - if attrs.get("default") is not None: - required = False - else: - required = attrs.get("nargs", 1) > 0 - - if "multiple" in attrs: - raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") - - super().__init__(param_decls, required=required, **attrs) - - if __debug__: - if self.default is not None and self.nargs == -1: - raise TypeError("'default' is not supported for nargs=-1.") - - @property - def human_readable_name(self) -> str: - if self.metavar is not None: - return self.metavar - return self.name.upper() # type: ignore - - def make_metavar(self) -> str: - if self.metavar is not None: - return self.metavar - var = self.type.get_metavar(self) - if not var: - var = self.name.upper() # type: ignore - if not self.required: - var = f"[{var}]" - if self.nargs != 1: - var += "..." - return var - - def _parse_decls( - self, decls: t.Sequence[str], expose_value: bool - ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: - if not decls: - if not expose_value: - return None, [], [] - raise TypeError("Could not determine name for argument") - if len(decls) == 1: - name = arg = decls[0] - name = name.replace("-", "_").lower() - else: - raise TypeError( - "Arguments take exactly one parameter declaration, got" - f" {len(decls)}." - ) - return name, [arg], [] - - def get_usage_pieces(self, ctx: Context) -> t.List[str]: - return [self.make_metavar()] - - def get_error_hint(self, ctx: Context) -> str: - return f"'{self.make_metavar()}'" - - def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: - parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/venv/lib/python3.7/site-packages/click/decorators.py b/venv/lib/python3.7/site-packages/click/decorators.py deleted file mode 100644 index 7930a16..0000000 --- a/venv/lib/python3.7/site-packages/click/decorators.py +++ /dev/null @@ -1,436 +0,0 @@ -import inspect -import types -import typing as t -from functools import update_wrapper -from gettext import gettext as _ - -from .core import Argument -from .core import Command -from .core import Context -from .core import Group -from .core import Option -from .core import Parameter -from .globals import get_current_context -from .utils import echo - -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) -FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command]) - - -def pass_context(f: F) -> F: - """Marks a callback as wanting to receive the current context - object as first argument. - """ - - def new_func(*args, **kwargs): # type: ignore - return f(get_current_context(), *args, **kwargs) - - return update_wrapper(t.cast(F, new_func), f) - - -def pass_obj(f: F) -> F: - """Similar to :func:`pass_context`, but only pass the object on the - context onwards (:attr:`Context.obj`). This is useful if that object - represents the state of a nested system. - """ - - def new_func(*args, **kwargs): # type: ignore - return f(get_current_context().obj, *args, **kwargs) - - return update_wrapper(t.cast(F, new_func), f) - - -def make_pass_decorator( - object_type: t.Type, ensure: bool = False -) -> "t.Callable[[F], F]": - """Given an object type this creates a decorator that will work - similar to :func:`pass_obj` but instead of passing the object of the - current context, it will find the innermost context of type - :func:`object_type`. - - This generates a decorator that works roughly like this:: - - from functools import update_wrapper - - def decorator(f): - @pass_context - def new_func(ctx, *args, **kwargs): - obj = ctx.find_object(object_type) - return ctx.invoke(f, obj, *args, **kwargs) - return update_wrapper(new_func, f) - return decorator - - :param object_type: the type of the object to pass. - :param ensure: if set to `True`, a new object will be created and - remembered on the context if it's not there yet. - """ - - def decorator(f: F) -> F: - def new_func(*args, **kwargs): # type: ignore - ctx = get_current_context() - - if ensure: - obj = ctx.ensure_object(object_type) - else: - obj = ctx.find_object(object_type) - - if obj is None: - raise RuntimeError( - "Managed to invoke callback without a context" - f" object of type {object_type.__name__!r}" - " existing." - ) - - return ctx.invoke(f, obj, *args, **kwargs) - - return update_wrapper(t.cast(F, new_func), f) - - return decorator - - -def pass_meta_key( - key: str, *, doc_description: t.Optional[str] = None -) -> "t.Callable[[F], F]": - """Create a decorator that passes a key from - :attr:`click.Context.meta` as the first argument to the decorated - function. - - :param key: Key in ``Context.meta`` to pass. - :param doc_description: Description of the object being passed, - inserted into the decorator's docstring. Defaults to "the 'key' - key from Context.meta". - - .. versionadded:: 8.0 - """ - - def decorator(f: F) -> F: - def new_func(*args, **kwargs): # type: ignore - ctx = get_current_context() - obj = ctx.meta[key] - return ctx.invoke(f, obj, *args, **kwargs) - - return update_wrapper(t.cast(F, new_func), f) - - if doc_description is None: - doc_description = f"the {key!r} key from :attr:`click.Context.meta`" - - decorator.__doc__ = ( - f"Decorator that passes {doc_description} as the first argument" - " to the decorated function." - ) - return decorator - - -def _make_command( - f: F, - name: t.Optional[str], - attrs: t.MutableMapping[str, t.Any], - cls: t.Type[Command], -) -> Command: - if isinstance(f, Command): - raise TypeError("Attempted to convert a callback into a command twice.") - - try: - params = f.__click_params__ # type: ignore - params.reverse() - del f.__click_params__ # type: ignore - except AttributeError: - params = [] - - help = attrs.get("help") - - if help is None: - help = inspect.getdoc(f) - else: - help = inspect.cleandoc(help) - - attrs["help"] = help - return cls( - name=name or f.__name__.lower().replace("_", "-"), - callback=f, - params=params, - **attrs, - ) - - -def command( - name: t.Optional[str] = None, - cls: t.Optional[t.Type[Command]] = None, - **attrs: t.Any, -) -> t.Callable[[F], Command]: - r"""Creates a new :class:`Command` and uses the decorated function as - callback. This will also automatically attach all decorated - :func:`option`\s and :func:`argument`\s as parameters to the command. - - The name of the command defaults to the name of the function with - underscores replaced by dashes. If you want to change that, you can - pass the intended name as the first argument. - - All keyword arguments are forwarded to the underlying command class. - - Once decorated the function turns into a :class:`Command` instance - that can be invoked as a command line utility or be attached to a - command :class:`Group`. - - :param name: the name of the command. This defaults to the function - name with underscores replaced by dashes. - :param cls: the command class to instantiate. This defaults to - :class:`Command`. - """ - if cls is None: - cls = Command - - def decorator(f: t.Callable[..., t.Any]) -> Command: - cmd = _make_command(f, name, attrs, cls) # type: ignore - cmd.__doc__ = f.__doc__ - return cmd - - return decorator - - -def group(name: t.Optional[str] = None, **attrs: t.Any) -> t.Callable[[F], Group]: - """Creates a new :class:`Group` with a function as callback. This - works otherwise the same as :func:`command` just that the `cls` - parameter is set to :class:`Group`. - """ - attrs.setdefault("cls", Group) - return t.cast(Group, command(name, **attrs)) - - -def _param_memo(f: FC, param: Parameter) -> None: - if isinstance(f, Command): - f.params.append(param) - else: - if not hasattr(f, "__click_params__"): - f.__click_params__ = [] # type: ignore - - f.__click_params__.append(param) # type: ignore - - -def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: - """Attaches an argument to the command. All positional arguments are - passed as parameter declarations to :class:`Argument`; all keyword - arguments are forwarded unchanged (except ``cls``). - This is equivalent to creating an :class:`Argument` instance manually - and attaching it to the :attr:`Command.params` list. - - :param cls: the argument class to instantiate. This defaults to - :class:`Argument`. - """ - - def decorator(f: FC) -> FC: - ArgumentClass = attrs.pop("cls", Argument) - _param_memo(f, ArgumentClass(param_decls, **attrs)) - return f - - return decorator - - -def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: - """Attaches an option to the command. All positional arguments are - passed as parameter declarations to :class:`Option`; all keyword - arguments are forwarded unchanged (except ``cls``). - This is equivalent to creating an :class:`Option` instance manually - and attaching it to the :attr:`Command.params` list. - - :param cls: the option class to instantiate. This defaults to - :class:`Option`. - """ - - def decorator(f: FC) -> FC: - # Issue 926, copy attrs, so pre-defined options can re-use the same cls= - option_attrs = attrs.copy() - - if "help" in option_attrs: - option_attrs["help"] = inspect.cleandoc(option_attrs["help"]) - OptionClass = option_attrs.pop("cls", Option) - _param_memo(f, OptionClass(param_decls, **option_attrs)) - return f - - return decorator - - -def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: - """Add a ``--yes`` option which shows a prompt before continuing if - not passed. If the prompt is declined, the program will exit. - - :param param_decls: One or more option names. Defaults to the single - value ``"--yes"``. - :param kwargs: Extra arguments are passed to :func:`option`. - """ - - def callback(ctx: Context, param: Parameter, value: bool) -> None: - if not value: - ctx.abort() - - if not param_decls: - param_decls = ("--yes",) - - kwargs.setdefault("is_flag", True) - kwargs.setdefault("callback", callback) - kwargs.setdefault("expose_value", False) - kwargs.setdefault("prompt", "Do you want to continue?") - kwargs.setdefault("help", "Confirm the action without prompting.") - return option(*param_decls, **kwargs) - - -def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: - """Add a ``--password`` option which prompts for a password, hiding - input and asking to enter the value again for confirmation. - - :param param_decls: One or more option names. Defaults to the single - value ``"--password"``. - :param kwargs: Extra arguments are passed to :func:`option`. - """ - if not param_decls: - param_decls = ("--password",) - - kwargs.setdefault("prompt", True) - kwargs.setdefault("confirmation_prompt", True) - kwargs.setdefault("hide_input", True) - return option(*param_decls, **kwargs) - - -def version_option( - version: t.Optional[str] = None, - *param_decls: str, - package_name: t.Optional[str] = None, - prog_name: t.Optional[str] = None, - message: t.Optional[str] = None, - **kwargs: t.Any, -) -> t.Callable[[FC], FC]: - """Add a ``--version`` option which immediately prints the version - number and exits the program. - - If ``version`` is not provided, Click will try to detect it using - :func:`importlib.metadata.version` to get the version for the - ``package_name``. On Python < 3.8, the ``importlib_metadata`` - backport must be installed. - - If ``package_name`` is not provided, Click will try to detect it by - inspecting the stack frames. This will be used to detect the - version, so it must match the name of the installed package. - - :param version: The version number to show. If not provided, Click - will try to detect it. - :param param_decls: One or more option names. Defaults to the single - value ``"--version"``. - :param package_name: The package name to detect the version from. If - not provided, Click will try to detect it. - :param prog_name: The name of the CLI to show in the message. If not - provided, it will be detected from the command. - :param message: The message to show. The values ``%(prog)s``, - ``%(package)s``, and ``%(version)s`` are available. Defaults to - ``"%(prog)s, version %(version)s"``. - :param kwargs: Extra arguments are passed to :func:`option`. - :raise RuntimeError: ``version`` could not be detected. - - .. versionchanged:: 8.0 - Add the ``package_name`` parameter, and the ``%(package)s`` - value for messages. - - .. versionchanged:: 8.0 - Use :mod:`importlib.metadata` instead of ``pkg_resources``. The - version is detected based on the package name, not the entry - point name. The Python package name must match the installed - package name, or be passed with ``package_name=``. - """ - if message is None: - message = _("%(prog)s, version %(version)s") - - if version is None and package_name is None: - frame = inspect.currentframe() - f_back = frame.f_back if frame is not None else None - f_globals = f_back.f_globals if f_back is not None else None - # break reference cycle - # https://docs.python.org/3/library/inspect.html#the-interpreter-stack - del frame - - if f_globals is not None: - package_name = f_globals.get("__name__") - - if package_name == "__main__": - package_name = f_globals.get("__package__") - - if package_name: - package_name = package_name.partition(".")[0] - - def callback(ctx: Context, param: Parameter, value: bool) -> None: - if not value or ctx.resilient_parsing: - return - - nonlocal prog_name - nonlocal version - - if prog_name is None: - prog_name = ctx.find_root().info_name - - if version is None and package_name is not None: - metadata: t.Optional[types.ModuleType] - - try: - from importlib import metadata # type: ignore - except ImportError: - # Python < 3.8 - import importlib_metadata as metadata # type: ignore - - try: - version = metadata.version(package_name) # type: ignore - except metadata.PackageNotFoundError: # type: ignore - raise RuntimeError( - f"{package_name!r} is not installed. Try passing" - " 'package_name' instead." - ) from None - - if version is None: - raise RuntimeError( - f"Could not determine the version for {package_name!r} automatically." - ) - - echo( - t.cast(str, message) - % {"prog": prog_name, "package": package_name, "version": version}, - color=ctx.color, - ) - ctx.exit() - - if not param_decls: - param_decls = ("--version",) - - kwargs.setdefault("is_flag", True) - kwargs.setdefault("expose_value", False) - kwargs.setdefault("is_eager", True) - kwargs.setdefault("help", _("Show the version and exit.")) - kwargs["callback"] = callback - return option(*param_decls, **kwargs) - - -def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: - """Add a ``--help`` option which immediately prints the help page - and exits the program. - - This is usually unnecessary, as the ``--help`` option is added to - each command automatically unless ``add_help_option=False`` is - passed. - - :param param_decls: One or more option names. Defaults to the single - value ``"--help"``. - :param kwargs: Extra arguments are passed to :func:`option`. - """ - - def callback(ctx: Context, param: Parameter, value: bool) -> None: - if not value or ctx.resilient_parsing: - return - - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - if not param_decls: - param_decls = ("--help",) - - kwargs.setdefault("is_flag", True) - kwargs.setdefault("expose_value", False) - kwargs.setdefault("is_eager", True) - kwargs.setdefault("help", _("Show this message and exit.")) - kwargs["callback"] = callback - return option(*param_decls, **kwargs) diff --git a/venv/lib/python3.7/site-packages/click/exceptions.py b/venv/lib/python3.7/site-packages/click/exceptions.py deleted file mode 100644 index 9e20b3e..0000000 --- a/venv/lib/python3.7/site-packages/click/exceptions.py +++ /dev/null @@ -1,287 +0,0 @@ -import os -import typing as t -from gettext import gettext as _ -from gettext import ngettext - -from ._compat import get_text_stderr -from .utils import echo - -if t.TYPE_CHECKING: - from .core import Context - from .core import Parameter - - -def _join_param_hints( - param_hint: t.Optional[t.Union[t.Sequence[str], str]] -) -> t.Optional[str]: - if param_hint is not None and not isinstance(param_hint, str): - return " / ".join(repr(x) for x in param_hint) - - return param_hint - - -class ClickException(Exception): - """An exception that Click can handle and show to the user.""" - - #: The exit code for this exception. - exit_code = 1 - - def __init__(self, message: str) -> None: - super().__init__(message) - self.message = message - - def format_message(self) -> str: - return self.message - - def __str__(self) -> str: - return self.message - - def show(self, file: t.Optional[t.IO] = None) -> None: - if file is None: - file = get_text_stderr() - - echo(_("Error: {message}").format(message=self.format_message()), file=file) - - -class UsageError(ClickException): - """An internal exception that signals a usage error. This typically - aborts any further handling. - - :param message: the error message to display. - :param ctx: optionally the context that caused this error. Click will - fill in the context automatically in some situations. - """ - - exit_code = 2 - - def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: - super().__init__(message) - self.ctx = ctx - self.cmd = self.ctx.command if self.ctx else None - - def show(self, file: t.Optional[t.IO] = None) -> None: - if file is None: - file = get_text_stderr() - color = None - hint = "" - if ( - self.ctx is not None - and self.ctx.command.get_help_option(self.ctx) is not None - ): - hint = _("Try '{command} {option}' for help.").format( - command=self.ctx.command_path, option=self.ctx.help_option_names[0] - ) - hint = f"{hint}\n" - if self.ctx is not None: - color = self.ctx.color - echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) - echo( - _("Error: {message}").format(message=self.format_message()), - file=file, - color=color, - ) - - -class BadParameter(UsageError): - """An exception that formats out a standardized error message for a - bad parameter. This is useful when thrown from a callback or type as - Click will attach contextual information to it (for instance, which - parameter it is). - - .. versionadded:: 2.0 - - :param param: the parameter object that caused this error. This can - be left out, and Click will attach this info itself - if possible. - :param param_hint: a string that shows up as parameter name. This - can be used as alternative to `param` in cases - where custom validation should happen. If it is - a string it's used as such, if it's a list then - each item is quoted and separated. - """ - - def __init__( - self, - message: str, - ctx: t.Optional["Context"] = None, - param: t.Optional["Parameter"] = None, - param_hint: t.Optional[str] = None, - ) -> None: - super().__init__(message, ctx) - self.param = param - self.param_hint = param_hint - - def format_message(self) -> str: - if self.param_hint is not None: - param_hint = self.param_hint - elif self.param is not None: - param_hint = self.param.get_error_hint(self.ctx) # type: ignore - else: - return _("Invalid value: {message}").format(message=self.message) - - return _("Invalid value for {param_hint}: {message}").format( - param_hint=_join_param_hints(param_hint), message=self.message - ) - - -class MissingParameter(BadParameter): - """Raised if click required an option or argument but it was not - provided when invoking the script. - - .. versionadded:: 4.0 - - :param param_type: a string that indicates the type of the parameter. - The default is to inherit the parameter type from - the given `param`. Valid values are ``'parameter'``, - ``'option'`` or ``'argument'``. - """ - - def __init__( - self, - message: t.Optional[str] = None, - ctx: t.Optional["Context"] = None, - param: t.Optional["Parameter"] = None, - param_hint: t.Optional[str] = None, - param_type: t.Optional[str] = None, - ) -> None: - super().__init__(message or "", ctx, param, param_hint) - self.param_type = param_type - - def format_message(self) -> str: - if self.param_hint is not None: - param_hint: t.Optional[str] = self.param_hint - elif self.param is not None: - param_hint = self.param.get_error_hint(self.ctx) # type: ignore - else: - param_hint = None - - param_hint = _join_param_hints(param_hint) - param_hint = f" {param_hint}" if param_hint else "" - - param_type = self.param_type - if param_type is None and self.param is not None: - param_type = self.param.param_type_name - - msg = self.message - if self.param is not None: - msg_extra = self.param.type.get_missing_message(self.param) - if msg_extra: - if msg: - msg += f". {msg_extra}" - else: - msg = msg_extra - - msg = f" {msg}" if msg else "" - - # Translate param_type for known types. - if param_type == "argument": - missing = _("Missing argument") - elif param_type == "option": - missing = _("Missing option") - elif param_type == "parameter": - missing = _("Missing parameter") - else: - missing = _("Missing {param_type}").format(param_type=param_type) - - return f"{missing}{param_hint}.{msg}" - - def __str__(self) -> str: - if not self.message: - param_name = self.param.name if self.param else None - return _("Missing parameter: {param_name}").format(param_name=param_name) - else: - return self.message - - -class NoSuchOption(UsageError): - """Raised if click attempted to handle an option that does not - exist. - - .. versionadded:: 4.0 - """ - - def __init__( - self, - option_name: str, - message: t.Optional[str] = None, - possibilities: t.Optional[t.Sequence[str]] = None, - ctx: t.Optional["Context"] = None, - ) -> None: - if message is None: - message = _("No such option: {name}").format(name=option_name) - - super().__init__(message, ctx) - self.option_name = option_name - self.possibilities = possibilities - - def format_message(self) -> str: - if not self.possibilities: - return self.message - - possibility_str = ", ".join(sorted(self.possibilities)) - suggest = ngettext( - "Did you mean {possibility}?", - "(Possible options: {possibilities})", - len(self.possibilities), - ).format(possibility=possibility_str, possibilities=possibility_str) - return f"{self.message} {suggest}" - - -class BadOptionUsage(UsageError): - """Raised if an option is generally supplied but the use of the option - was incorrect. This is for instance raised if the number of arguments - for an option is not correct. - - .. versionadded:: 4.0 - - :param option_name: the name of the option being used incorrectly. - """ - - def __init__( - self, option_name: str, message: str, ctx: t.Optional["Context"] = None - ) -> None: - super().__init__(message, ctx) - self.option_name = option_name - - -class BadArgumentUsage(UsageError): - """Raised if an argument is generally supplied but the use of the argument - was incorrect. This is for instance raised if the number of values - for an argument is not correct. - - .. versionadded:: 6.0 - """ - - -class FileError(ClickException): - """Raised if a file cannot be opened.""" - - def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: - if hint is None: - hint = _("unknown error") - - super().__init__(hint) - self.ui_filename = os.fsdecode(filename) - self.filename = filename - - def format_message(self) -> str: - return _("Could not open file {filename!r}: {message}").format( - filename=self.ui_filename, message=self.message - ) - - -class Abort(RuntimeError): - """An internal signalling exception that signals Click to abort.""" - - -class Exit(RuntimeError): - """An exception that indicates that the application should exit with some - status code. - - :param code: the status code to exit with. - """ - - __slots__ = ("exit_code",) - - def __init__(self, code: int = 0) -> None: - self.exit_code = code diff --git a/venv/lib/python3.7/site-packages/click/formatting.py b/venv/lib/python3.7/site-packages/click/formatting.py deleted file mode 100644 index ddd2a2f..0000000 --- a/venv/lib/python3.7/site-packages/click/formatting.py +++ /dev/null @@ -1,301 +0,0 @@ -import typing as t -from contextlib import contextmanager -from gettext import gettext as _ - -from ._compat import term_len -from .parser import split_opt - -# Can force a width. This is used by the test system -FORCED_WIDTH: t.Optional[int] = None - - -def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: - widths: t.Dict[int, int] = {} - - for row in rows: - for idx, col in enumerate(row): - widths[idx] = max(widths.get(idx, 0), term_len(col)) - - return tuple(y for x, y in sorted(widths.items())) - - -def iter_rows( - rows: t.Iterable[t.Tuple[str, str]], col_count: int -) -> t.Iterator[t.Tuple[str, ...]]: - for row in rows: - yield row + ("",) * (col_count - len(row)) - - -def wrap_text( - text: str, - width: int = 78, - initial_indent: str = "", - subsequent_indent: str = "", - preserve_paragraphs: bool = False, -) -> str: - """A helper function that intelligently wraps text. By default, it - assumes that it operates on a single paragraph of text but if the - `preserve_paragraphs` parameter is provided it will intelligently - handle paragraphs (defined by two empty lines). - - If paragraphs are handled, a paragraph can be prefixed with an empty - line containing the ``\\b`` character (``\\x08``) to indicate that - no rewrapping should happen in that block. - - :param text: the text that should be rewrapped. - :param width: the maximum width for the text. - :param initial_indent: the initial indent that should be placed on the - first line as a string. - :param subsequent_indent: the indent string that should be placed on - each consecutive line. - :param preserve_paragraphs: if this flag is set then the wrapping will - intelligently handle paragraphs. - """ - from ._textwrap import TextWrapper - - text = text.expandtabs() - wrapper = TextWrapper( - width, - initial_indent=initial_indent, - subsequent_indent=subsequent_indent, - replace_whitespace=False, - ) - if not preserve_paragraphs: - return wrapper.fill(text) - - p: t.List[t.Tuple[int, bool, str]] = [] - buf: t.List[str] = [] - indent = None - - def _flush_par() -> None: - if not buf: - return - if buf[0].strip() == "\b": - p.append((indent or 0, True, "\n".join(buf[1:]))) - else: - p.append((indent or 0, False, " ".join(buf))) - del buf[:] - - for line in text.splitlines(): - if not line: - _flush_par() - indent = None - else: - if indent is None: - orig_len = term_len(line) - line = line.lstrip() - indent = orig_len - term_len(line) - buf.append(line) - _flush_par() - - rv = [] - for indent, raw, text in p: - with wrapper.extra_indent(" " * indent): - if raw: - rv.append(wrapper.indent_only(text)) - else: - rv.append(wrapper.fill(text)) - - return "\n\n".join(rv) - - -class HelpFormatter: - """This class helps with formatting text-based help pages. It's - usually just needed for very special internal cases, but it's also - exposed so that developers can write their own fancy outputs. - - At present, it always writes into memory. - - :param indent_increment: the additional increment for each level. - :param width: the width for the text. This defaults to the terminal - width clamped to a maximum of 78. - """ - - def __init__( - self, - indent_increment: int = 2, - width: t.Optional[int] = None, - max_width: t.Optional[int] = None, - ) -> None: - import shutil - - self.indent_increment = indent_increment - if max_width is None: - max_width = 80 - if width is None: - width = FORCED_WIDTH - if width is None: - width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) - self.width = width - self.current_indent = 0 - self.buffer: t.List[str] = [] - - def write(self, string: str) -> None: - """Writes a unicode string into the internal buffer.""" - self.buffer.append(string) - - def indent(self) -> None: - """Increases the indentation.""" - self.current_indent += self.indent_increment - - def dedent(self) -> None: - """Decreases the indentation.""" - self.current_indent -= self.indent_increment - - def write_usage( - self, prog: str, args: str = "", prefix: t.Optional[str] = None - ) -> None: - """Writes a usage line into the buffer. - - :param prog: the program name. - :param args: whitespace separated list of arguments. - :param prefix: The prefix for the first line. Defaults to - ``"Usage: "``. - """ - if prefix is None: - prefix = f"{_('Usage:')} " - - usage_prefix = f"{prefix:>{self.current_indent}}{prog} " - text_width = self.width - self.current_indent - - if text_width >= (term_len(usage_prefix) + 20): - # The arguments will fit to the right of the prefix. - indent = " " * term_len(usage_prefix) - self.write( - wrap_text( - args, - text_width, - initial_indent=usage_prefix, - subsequent_indent=indent, - ) - ) - else: - # The prefix is too long, put the arguments on the next line. - self.write(usage_prefix) - self.write("\n") - indent = " " * (max(self.current_indent, term_len(prefix)) + 4) - self.write( - wrap_text( - args, text_width, initial_indent=indent, subsequent_indent=indent - ) - ) - - self.write("\n") - - def write_heading(self, heading: str) -> None: - """Writes a heading into the buffer.""" - self.write(f"{'':>{self.current_indent}}{heading}:\n") - - def write_paragraph(self) -> None: - """Writes a paragraph into the buffer.""" - if self.buffer: - self.write("\n") - - def write_text(self, text: str) -> None: - """Writes re-indented text into the buffer. This rewraps and - preserves paragraphs. - """ - indent = " " * self.current_indent - self.write( - wrap_text( - text, - self.width, - initial_indent=indent, - subsequent_indent=indent, - preserve_paragraphs=True, - ) - ) - self.write("\n") - - def write_dl( - self, - rows: t.Sequence[t.Tuple[str, str]], - col_max: int = 30, - col_spacing: int = 2, - ) -> None: - """Writes a definition list into the buffer. This is how options - and commands are usually formatted. - - :param rows: a list of two item tuples for the terms and values. - :param col_max: the maximum width of the first column. - :param col_spacing: the number of spaces between the first and - second column. - """ - rows = list(rows) - widths = measure_table(rows) - if len(widths) != 2: - raise TypeError("Expected two columns for definition list") - - first_col = min(widths[0], col_max) + col_spacing - - for first, second in iter_rows(rows, len(widths)): - self.write(f"{'':>{self.current_indent}}{first}") - if not second: - self.write("\n") - continue - if term_len(first) <= first_col - col_spacing: - self.write(" " * (first_col - term_len(first))) - else: - self.write("\n") - self.write(" " * (first_col + self.current_indent)) - - text_width = max(self.width - first_col - 2, 10) - wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) - lines = wrapped_text.splitlines() - - if lines: - self.write(f"{lines[0]}\n") - - for line in lines[1:]: - self.write(f"{'':>{first_col + self.current_indent}}{line}\n") - else: - self.write("\n") - - @contextmanager - def section(self, name: str) -> t.Iterator[None]: - """Helpful context manager that writes a paragraph, a heading, - and the indents. - - :param name: the section name that is written as heading. - """ - self.write_paragraph() - self.write_heading(name) - self.indent() - try: - yield - finally: - self.dedent() - - @contextmanager - def indentation(self) -> t.Iterator[None]: - """A context manager that increases the indentation.""" - self.indent() - try: - yield - finally: - self.dedent() - - def getvalue(self) -> str: - """Returns the buffer contents.""" - return "".join(self.buffer) - - -def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: - """Given a list of option strings this joins them in the most appropriate - way and returns them in the form ``(formatted_string, - any_prefix_is_slash)`` where the second item in the tuple is a flag that - indicates if any of the option prefixes was a slash. - """ - rv = [] - any_prefix_is_slash = False - - for opt in options: - prefix = split_opt(opt)[0] - - if prefix == "/": - any_prefix_is_slash = True - - rv.append((len(prefix), opt)) - - rv.sort(key=lambda x: x[0]) - return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/venv/lib/python3.7/site-packages/click/globals.py b/venv/lib/python3.7/site-packages/click/globals.py deleted file mode 100644 index 480058f..0000000 --- a/venv/lib/python3.7/site-packages/click/globals.py +++ /dev/null @@ -1,68 +0,0 @@ -import typing as t -from threading import local - -if t.TYPE_CHECKING: - import typing_extensions as te - from .core import Context - -_local = local() - - -@t.overload -def get_current_context(silent: "te.Literal[False]" = False) -> "Context": - ... - - -@t.overload -def get_current_context(silent: bool = ...) -> t.Optional["Context"]: - ... - - -def get_current_context(silent: bool = False) -> t.Optional["Context"]: - """Returns the current click context. This can be used as a way to - access the current context object from anywhere. This is a more implicit - alternative to the :func:`pass_context` decorator. This function is - primarily useful for helpers such as :func:`echo` which might be - interested in changing its behavior based on the current context. - - To push the current context, :meth:`Context.scope` can be used. - - .. versionadded:: 5.0 - - :param silent: if set to `True` the return value is `None` if no context - is available. The default behavior is to raise a - :exc:`RuntimeError`. - """ - try: - return t.cast("Context", _local.stack[-1]) - except (AttributeError, IndexError) as e: - if not silent: - raise RuntimeError("There is no active click context.") from e - - return None - - -def push_context(ctx: "Context") -> None: - """Pushes a new context to the current stack.""" - _local.__dict__.setdefault("stack", []).append(ctx) - - -def pop_context() -> None: - """Removes the top level from the stack.""" - _local.stack.pop() - - -def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: - """Internal helper to get the default value of the color flag. If a - value is passed it's returned unchanged, otherwise it's looked up from - the current context. - """ - if color is not None: - return color - - ctx = get_current_context(silent=True) - - if ctx is not None: - return ctx.color - - return None diff --git a/venv/lib/python3.7/site-packages/click/parser.py b/venv/lib/python3.7/site-packages/click/parser.py deleted file mode 100644 index 2d5a2ed..0000000 --- a/venv/lib/python3.7/site-packages/click/parser.py +++ /dev/null @@ -1,529 +0,0 @@ -""" -This module started out as largely a copy paste from the stdlib's -optparse module with the features removed that we do not need from -optparse because we implement them in Click on a higher level (for -instance type handling, help formatting and a lot more). - -The plan is to remove more and more from here over time. - -The reason this is a different module and not optparse from the stdlib -is that there are differences in 2.x and 3.x about the error messages -generated and optparse in the stdlib uses gettext for no good reason -and might cause us issues. - -Click uses parts of optparse written by Gregory P. Ward and maintained -by the Python Software Foundation. This is limited to code in parser.py. - -Copyright 2001-2006 Gregory P. Ward. All rights reserved. -Copyright 2002-2006 Python Software Foundation. All rights reserved. -""" -# This code uses parts of optparse written by Gregory P. Ward and -# maintained by the Python Software Foundation. -# Copyright 2001-2006 Gregory P. Ward -# Copyright 2002-2006 Python Software Foundation -import typing as t -from collections import deque -from gettext import gettext as _ -from gettext import ngettext - -from .exceptions import BadArgumentUsage -from .exceptions import BadOptionUsage -from .exceptions import NoSuchOption -from .exceptions import UsageError - -if t.TYPE_CHECKING: - import typing_extensions as te - from .core import Argument as CoreArgument - from .core import Context - from .core import Option as CoreOption - from .core import Parameter as CoreParameter - -V = t.TypeVar("V") - -# Sentinel value that indicates an option was passed as a flag without a -# value but is not a flag option. Option.consume_value uses this to -# prompt or use the flag_value. -_flag_needs_value = object() - - -def _unpack_args( - args: t.Sequence[str], nargs_spec: t.Sequence[int] -) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: - """Given an iterable of arguments and an iterable of nargs specifications, - it returns a tuple with all the unpacked arguments at the first index - and all remaining arguments as the second. - - The nargs specification is the number of arguments that should be consumed - or `-1` to indicate that this position should eat up all the remainders. - - Missing items are filled with `None`. - """ - args = deque(args) - nargs_spec = deque(nargs_spec) - rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] - spos: t.Optional[int] = None - - def _fetch(c: "te.Deque[V]") -> t.Optional[V]: - try: - if spos is None: - return c.popleft() - else: - return c.pop() - except IndexError: - return None - - while nargs_spec: - nargs = _fetch(nargs_spec) - - if nargs is None: - continue - - if nargs == 1: - rv.append(_fetch(args)) - elif nargs > 1: - x = [_fetch(args) for _ in range(nargs)] - - # If we're reversed, we're pulling in the arguments in reverse, - # so we need to turn them around. - if spos is not None: - x.reverse() - - rv.append(tuple(x)) - elif nargs < 0: - if spos is not None: - raise TypeError("Cannot have two nargs < 0") - - spos = len(rv) - rv.append(None) - - # spos is the position of the wildcard (star). If it's not `None`, - # we fill it with the remainder. - if spos is not None: - rv[spos] = tuple(args) - args = [] - rv[spos + 1 :] = reversed(rv[spos + 1 :]) - - return tuple(rv), list(args) - - -def split_opt(opt: str) -> t.Tuple[str, str]: - first = opt[:1] - if first.isalnum(): - return "", opt - if opt[1:2] == first: - return opt[:2], opt[2:] - return first, opt[1:] - - -def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: - if ctx is None or ctx.token_normalize_func is None: - return opt - prefix, opt = split_opt(opt) - return f"{prefix}{ctx.token_normalize_func(opt)}" - - -def split_arg_string(string: str) -> t.List[str]: - """Split an argument string as with :func:`shlex.split`, but don't - fail if the string is incomplete. Ignores a missing closing quote or - incomplete escape sequence and uses the partial token as-is. - - .. code-block:: python - - split_arg_string("example 'my file") - ["example", "my file"] - - split_arg_string("example my\\") - ["example", "my"] - - :param string: String to split. - """ - import shlex - - lex = shlex.shlex(string, posix=True) - lex.whitespace_split = True - lex.commenters = "" - out = [] - - try: - for token in lex: - out.append(token) - except ValueError: - # Raised when end-of-string is reached in an invalid state. Use - # the partial token as-is. The quote or escape character is in - # lex.state, not lex.token. - out.append(lex.token) - - return out - - -class Option: - def __init__( - self, - obj: "CoreOption", - opts: t.Sequence[str], - dest: t.Optional[str], - action: t.Optional[str] = None, - nargs: int = 1, - const: t.Optional[t.Any] = None, - ): - self._short_opts = [] - self._long_opts = [] - self.prefixes = set() - - for opt in opts: - prefix, value = split_opt(opt) - if not prefix: - raise ValueError(f"Invalid start character for option ({opt})") - self.prefixes.add(prefix[0]) - if len(prefix) == 1 and len(value) == 1: - self._short_opts.append(opt) - else: - self._long_opts.append(opt) - self.prefixes.add(prefix) - - if action is None: - action = "store" - - self.dest = dest - self.action = action - self.nargs = nargs - self.const = const - self.obj = obj - - @property - def takes_value(self) -> bool: - return self.action in ("store", "append") - - def process(self, value: str, state: "ParsingState") -> None: - if self.action == "store": - state.opts[self.dest] = value # type: ignore - elif self.action == "store_const": - state.opts[self.dest] = self.const # type: ignore - elif self.action == "append": - state.opts.setdefault(self.dest, []).append(value) # type: ignore - elif self.action == "append_const": - state.opts.setdefault(self.dest, []).append(self.const) # type: ignore - elif self.action == "count": - state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore - else: - raise ValueError(f"unknown action '{self.action}'") - state.order.append(self.obj) - - -class Argument: - def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): - self.dest = dest - self.nargs = nargs - self.obj = obj - - def process( - self, - value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], - state: "ParsingState", - ) -> None: - if self.nargs > 1: - assert value is not None - holes = sum(1 for x in value if x is None) - if holes == len(value): - value = None - elif holes != 0: - raise BadArgumentUsage( - _("Argument {name!r} takes {nargs} values.").format( - name=self.dest, nargs=self.nargs - ) - ) - - if self.nargs == -1 and self.obj.envvar is not None and value == (): - # Replace empty tuple with None so that a value from the - # environment may be tried. - value = None - - state.opts[self.dest] = value # type: ignore - state.order.append(self.obj) - - -class ParsingState: - def __init__(self, rargs: t.List[str]) -> None: - self.opts: t.Dict[str, t.Any] = {} - self.largs: t.List[str] = [] - self.rargs = rargs - self.order: t.List["CoreParameter"] = [] - - -class OptionParser: - """The option parser is an internal class that is ultimately used to - parse options and arguments. It's modelled after optparse and brings - a similar but vastly simplified API. It should generally not be used - directly as the high level Click classes wrap it for you. - - It's not nearly as extensible as optparse or argparse as it does not - implement features that are implemented on a higher level (such as - types or defaults). - - :param ctx: optionally the :class:`~click.Context` where this parser - should go with. - """ - - def __init__(self, ctx: t.Optional["Context"] = None) -> None: - #: The :class:`~click.Context` for this parser. This might be - #: `None` for some advanced use cases. - self.ctx = ctx - #: This controls how the parser deals with interspersed arguments. - #: If this is set to `False`, the parser will stop on the first - #: non-option. Click uses this to implement nested subcommands - #: safely. - self.allow_interspersed_args = True - #: This tells the parser how to deal with unknown options. By - #: default it will error out (which is sensible), but there is a - #: second mode where it will ignore it and continue processing - #: after shifting all the unknown options into the resulting args. - self.ignore_unknown_options = False - - if ctx is not None: - self.allow_interspersed_args = ctx.allow_interspersed_args - self.ignore_unknown_options = ctx.ignore_unknown_options - - self._short_opt: t.Dict[str, Option] = {} - self._long_opt: t.Dict[str, Option] = {} - self._opt_prefixes = {"-", "--"} - self._args: t.List[Argument] = [] - - def add_option( - self, - obj: "CoreOption", - opts: t.Sequence[str], - dest: t.Optional[str], - action: t.Optional[str] = None, - nargs: int = 1, - const: t.Optional[t.Any] = None, - ) -> None: - """Adds a new option named `dest` to the parser. The destination - is not inferred (unlike with optparse) and needs to be explicitly - provided. Action can be any of ``store``, ``store_const``, - ``append``, ``append_const`` or ``count``. - - The `obj` can be used to identify the option in the order list - that is returned from the parser. - """ - opts = [normalize_opt(opt, self.ctx) for opt in opts] - option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) - self._opt_prefixes.update(option.prefixes) - for opt in option._short_opts: - self._short_opt[opt] = option - for opt in option._long_opts: - self._long_opt[opt] = option - - def add_argument( - self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 - ) -> None: - """Adds a positional argument named `dest` to the parser. - - The `obj` can be used to identify the option in the order list - that is returned from the parser. - """ - self._args.append(Argument(obj, dest=dest, nargs=nargs)) - - def parse_args( - self, args: t.List[str] - ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: - """Parses positional arguments and returns ``(values, args, order)`` - for the parsed options and arguments as well as the leftover - arguments if there are any. The order is a list of objects as they - appear on the command line. If arguments appear multiple times they - will be memorized multiple times as well. - """ - state = ParsingState(args) - try: - self._process_args_for_options(state) - self._process_args_for_args(state) - except UsageError: - if self.ctx is None or not self.ctx.resilient_parsing: - raise - return state.opts, state.largs, state.order - - def _process_args_for_args(self, state: ParsingState) -> None: - pargs, args = _unpack_args( - state.largs + state.rargs, [x.nargs for x in self._args] - ) - - for idx, arg in enumerate(self._args): - arg.process(pargs[idx], state) - - state.largs = args - state.rargs = [] - - def _process_args_for_options(self, state: ParsingState) -> None: - while state.rargs: - arg = state.rargs.pop(0) - arglen = len(arg) - # Double dashes always handled explicitly regardless of what - # prefixes are valid. - if arg == "--": - return - elif arg[:1] in self._opt_prefixes and arglen > 1: - self._process_opts(arg, state) - elif self.allow_interspersed_args: - state.largs.append(arg) - else: - state.rargs.insert(0, arg) - return - - # Say this is the original argument list: - # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] - # ^ - # (we are about to process arg(i)). - # - # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of - # [arg0, ..., arg(i-1)] (any options and their arguments will have - # been removed from largs). - # - # The while loop will usually consume 1 or more arguments per pass. - # If it consumes 1 (eg. arg is an option that takes no arguments), - # then after _process_arg() is done the situation is: - # - # largs = subset of [arg0, ..., arg(i)] - # rargs = [arg(i+1), ..., arg(N-1)] - # - # If allow_interspersed_args is false, largs will always be - # *empty* -- still a subset of [arg0, ..., arg(i-1)], but - # not a very interesting subset! - - def _match_long_opt( - self, opt: str, explicit_value: t.Optional[str], state: ParsingState - ) -> None: - if opt not in self._long_opt: - from difflib import get_close_matches - - possibilities = get_close_matches(opt, self._long_opt) - raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) - - option = self._long_opt[opt] - if option.takes_value: - # At this point it's safe to modify rargs by injecting the - # explicit value, because no exception is raised in this - # branch. This means that the inserted value will be fully - # consumed. - if explicit_value is not None: - state.rargs.insert(0, explicit_value) - - value = self._get_value_from_state(opt, option, state) - - elif explicit_value is not None: - raise BadOptionUsage( - opt, _("Option {name!r} does not take a value.").format(name=opt) - ) - - else: - value = None - - option.process(value, state) - - def _match_short_opt(self, arg: str, state: ParsingState) -> None: - stop = False - i = 1 - prefix = arg[0] - unknown_options = [] - - for ch in arg[1:]: - opt = normalize_opt(f"{prefix}{ch}", self.ctx) - option = self._short_opt.get(opt) - i += 1 - - if not option: - if self.ignore_unknown_options: - unknown_options.append(ch) - continue - raise NoSuchOption(opt, ctx=self.ctx) - if option.takes_value: - # Any characters left in arg? Pretend they're the - # next arg, and stop consuming characters of arg. - if i < len(arg): - state.rargs.insert(0, arg[i:]) - stop = True - - value = self._get_value_from_state(opt, option, state) - - else: - value = None - - option.process(value, state) - - if stop: - break - - # If we got any unknown options we re-combinate the string of the - # remaining options and re-attach the prefix, then report that - # to the state as new larg. This way there is basic combinatorics - # that can be achieved while still ignoring unknown arguments. - if self.ignore_unknown_options and unknown_options: - state.largs.append(f"{prefix}{''.join(unknown_options)}") - - def _get_value_from_state( - self, option_name: str, option: Option, state: ParsingState - ) -> t.Any: - nargs = option.nargs - - if len(state.rargs) < nargs: - if option.obj._flag_needs_value: - # Option allows omitting the value. - value = _flag_needs_value - else: - raise BadOptionUsage( - option_name, - ngettext( - "Option {name!r} requires an argument.", - "Option {name!r} requires {nargs} arguments.", - nargs, - ).format(name=option_name, nargs=nargs), - ) - elif nargs == 1: - next_rarg = state.rargs[0] - - if ( - option.obj._flag_needs_value - and isinstance(next_rarg, str) - and next_rarg[:1] in self._opt_prefixes - and len(next_rarg) > 1 - ): - # The next arg looks like the start of an option, don't - # use it as the value if omitting the value is allowed. - value = _flag_needs_value - else: - value = state.rargs.pop(0) - else: - value = tuple(state.rargs[:nargs]) - del state.rargs[:nargs] - - return value - - def _process_opts(self, arg: str, state: ParsingState) -> None: - explicit_value = None - # Long option handling happens in two parts. The first part is - # supporting explicitly attached values. In any case, we will try - # to long match the option first. - if "=" in arg: - long_opt, explicit_value = arg.split("=", 1) - else: - long_opt = arg - norm_long_opt = normalize_opt(long_opt, self.ctx) - - # At this point we will match the (assumed) long option through - # the long option matching code. Note that this allows options - # like "-foo" to be matched as long options. - try: - self._match_long_opt(norm_long_opt, explicit_value, state) - except NoSuchOption: - # At this point the long option matching failed, and we need - # to try with short options. However there is a special rule - # which says, that if we have a two character options prefix - # (applies to "--foo" for instance), we do not dispatch to the - # short option code and will instead raise the no option - # error. - if arg[:2] not in self._opt_prefixes: - self._match_short_opt(arg, state) - return - - if not self.ignore_unknown_options: - raise - - state.largs.append(arg) diff --git a/venv/lib/python3.7/site-packages/click/py.typed b/venv/lib/python3.7/site-packages/click/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.7/site-packages/click/shell_completion.py b/venv/lib/python3.7/site-packages/click/shell_completion.py deleted file mode 100644 index 1e9df6f..0000000 --- a/venv/lib/python3.7/site-packages/click/shell_completion.py +++ /dev/null @@ -1,581 +0,0 @@ -import os -import re -import typing as t -from gettext import gettext as _ - -from .core import Argument -from .core import BaseCommand -from .core import Context -from .core import MultiCommand -from .core import Option -from .core import Parameter -from .core import ParameterSource -from .parser import split_arg_string -from .utils import echo - - -def shell_complete( - cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], - prog_name: str, - complete_var: str, - instruction: str, -) -> int: - """Perform shell completion for the given CLI program. - - :param cli: Command being called. - :param ctx_args: Extra arguments to pass to - ``cli.make_context``. - :param prog_name: Name of the executable in the shell. - :param complete_var: Name of the environment variable that holds - the completion instruction. - :param instruction: Value of ``complete_var`` with the completion - instruction and shell, in the form ``instruction_shell``. - :return: Status code to exit with. - """ - shell, _, instruction = instruction.partition("_") - comp_cls = get_completion_class(shell) - - if comp_cls is None: - return 1 - - comp = comp_cls(cli, ctx_args, prog_name, complete_var) - - if instruction == "source": - echo(comp.source()) - return 0 - - if instruction == "complete": - echo(comp.complete()) - return 0 - - return 1 - - -class CompletionItem: - """Represents a completion value and metadata about the value. The - default metadata is ``type`` to indicate special shell handling, - and ``help`` if a shell supports showing a help string next to the - value. - - Arbitrary parameters can be passed when creating the object, and - accessed using ``item.attr``. If an attribute wasn't passed, - accessing it returns ``None``. - - :param value: The completion suggestion. - :param type: Tells the shell script to provide special completion - support for the type. Click uses ``"dir"`` and ``"file"``. - :param help: String shown next to the value if supported. - :param kwargs: Arbitrary metadata. The built-in implementations - don't use this, but custom type completions paired with custom - shell support could use it. - """ - - __slots__ = ("value", "type", "help", "_info") - - def __init__( - self, - value: t.Any, - type: str = "plain", - help: t.Optional[str] = None, - **kwargs: t.Any, - ) -> None: - self.value = value - self.type = type - self.help = help - self._info = kwargs - - def __getattr__(self, name: str) -> t.Any: - return self._info.get(name) - - -# Only Bash >= 4.4 has the nosort option. -_SOURCE_BASH = """\ -%(complete_func)s() { - local IFS=$'\\n' - local response - - response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ -%(complete_var)s=bash_complete $1) - - for completion in $response; do - IFS=',' read type value <<< "$completion" - - if [[ $type == 'dir' ]]; then - COMPREPLY=() - compopt -o dirnames - elif [[ $type == 'file' ]]; then - COMPREPLY=() - compopt -o default - elif [[ $type == 'plain' ]]; then - COMPREPLY+=($value) - fi - done - - return 0 -} - -%(complete_func)s_setup() { - complete -o nosort -F %(complete_func)s %(prog_name)s -} - -%(complete_func)s_setup; -""" - -_SOURCE_ZSH = """\ -#compdef %(prog_name)s - -%(complete_func)s() { - local -a completions - local -a completions_with_descriptions - local -a response - (( ! $+commands[%(prog_name)s] )) && return 1 - - response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ -%(complete_var)s=zsh_complete %(prog_name)s)}") - - for type key descr in ${response}; do - if [[ "$type" == "plain" ]]; then - if [[ "$descr" == "_" ]]; then - completions+=("$key") - else - completions_with_descriptions+=("$key":"$descr") - fi - elif [[ "$type" == "dir" ]]; then - _path_files -/ - elif [[ "$type" == "file" ]]; then - _path_files -f - fi - done - - if [ -n "$completions_with_descriptions" ]; then - _describe -V unsorted completions_with_descriptions -U - fi - - if [ -n "$completions" ]; then - compadd -U -V unsorted -a completions - fi -} - -compdef %(complete_func)s %(prog_name)s; -""" - -_SOURCE_FISH = """\ -function %(complete_func)s; - set -l response; - - for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ -COMP_CWORD=(commandline -t) %(prog_name)s); - set response $response $value; - end; - - for completion in $response; - set -l metadata (string split "," $completion); - - if test $metadata[1] = "dir"; - __fish_complete_directories $metadata[2]; - else if test $metadata[1] = "file"; - __fish_complete_path $metadata[2]; - else if test $metadata[1] = "plain"; - echo $metadata[2]; - end; - end; -end; - -complete --no-files --command %(prog_name)s --arguments \ -"(%(complete_func)s)"; -""" - - -class ShellComplete: - """Base class for providing shell completion support. A subclass for - a given shell will override attributes and methods to implement the - completion instructions (``source`` and ``complete``). - - :param cli: Command being called. - :param prog_name: Name of the executable in the shell. - :param complete_var: Name of the environment variable that holds - the completion instruction. - - .. versionadded:: 8.0 - """ - - name: t.ClassVar[str] - """Name to register the shell as with :func:`add_completion_class`. - This is used in completion instructions (``{name}_source`` and - ``{name}_complete``). - """ - - source_template: t.ClassVar[str] - """Completion script template formatted by :meth:`source`. This must - be provided by subclasses. - """ - - def __init__( - self, - cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], - prog_name: str, - complete_var: str, - ) -> None: - self.cli = cli - self.ctx_args = ctx_args - self.prog_name = prog_name - self.complete_var = complete_var - - @property - def func_name(self) -> str: - """The name of the shell function defined by the completion - script. - """ - safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII) - return f"_{safe_name}_completion" - - def source_vars(self) -> t.Dict[str, t.Any]: - """Vars for formatting :attr:`source_template`. - - By default this provides ``complete_func``, ``complete_var``, - and ``prog_name``. - """ - return { - "complete_func": self.func_name, - "complete_var": self.complete_var, - "prog_name": self.prog_name, - } - - def source(self) -> str: - """Produce the shell script that defines the completion - function. By default this ``%``-style formats - :attr:`source_template` with the dict returned by - :meth:`source_vars`. - """ - return self.source_template % self.source_vars() - - def get_completion_args(self) -> t.Tuple[t.List[str], str]: - """Use the env vars defined by the shell script to return a - tuple of ``args, incomplete``. This must be implemented by - subclasses. - """ - raise NotImplementedError - - def get_completions( - self, args: t.List[str], incomplete: str - ) -> t.List[CompletionItem]: - """Determine the context and last complete command or parameter - from the complete args. Call that object's ``shell_complete`` - method to get the completions for the incomplete value. - - :param args: List of complete args before the incomplete value. - :param incomplete: Value being completed. May be empty. - """ - ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) - obj, incomplete = _resolve_incomplete(ctx, args, incomplete) - return obj.shell_complete(ctx, incomplete) - - def format_completion(self, item: CompletionItem) -> str: - """Format a completion item into the form recognized by the - shell script. This must be implemented by subclasses. - - :param item: Completion item to format. - """ - raise NotImplementedError - - def complete(self) -> str: - """Produce the completion data to send back to the shell. - - By default this calls :meth:`get_completion_args`, gets the - completions, then calls :meth:`format_completion` for each - completion. - """ - args, incomplete = self.get_completion_args() - completions = self.get_completions(args, incomplete) - out = [self.format_completion(item) for item in completions] - return "\n".join(out) - - -class BashComplete(ShellComplete): - """Shell completion for Bash.""" - - name = "bash" - source_template = _SOURCE_BASH - - def _check_version(self) -> None: - import subprocess - - output = subprocess.run( - ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE - ) - match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) - - if match is not None: - major, minor = match.groups() - - if major < "4" or major == "4" and minor < "4": - raise RuntimeError( - _( - "Shell completion is not supported for Bash" - " versions older than 4.4." - ) - ) - else: - raise RuntimeError( - _("Couldn't detect Bash version, shell completion is not supported.") - ) - - def source(self) -> str: - self._check_version() - return super().source() - - def get_completion_args(self) -> t.Tuple[t.List[str], str]: - cwords = split_arg_string(os.environ["COMP_WORDS"]) - cword = int(os.environ["COMP_CWORD"]) - args = cwords[1:cword] - - try: - incomplete = cwords[cword] - except IndexError: - incomplete = "" - - return args, incomplete - - def format_completion(self, item: CompletionItem) -> str: - return f"{item.type},{item.value}" - - -class ZshComplete(ShellComplete): - """Shell completion for Zsh.""" - - name = "zsh" - source_template = _SOURCE_ZSH - - def get_completion_args(self) -> t.Tuple[t.List[str], str]: - cwords = split_arg_string(os.environ["COMP_WORDS"]) - cword = int(os.environ["COMP_CWORD"]) - args = cwords[1:cword] - - try: - incomplete = cwords[cword] - except IndexError: - incomplete = "" - - return args, incomplete - - def format_completion(self, item: CompletionItem) -> str: - return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" - - -class FishComplete(ShellComplete): - """Shell completion for Fish.""" - - name = "fish" - source_template = _SOURCE_FISH - - def get_completion_args(self) -> t.Tuple[t.List[str], str]: - cwords = split_arg_string(os.environ["COMP_WORDS"]) - incomplete = os.environ["COMP_CWORD"] - args = cwords[1:] - - # Fish stores the partial word in both COMP_WORDS and - # COMP_CWORD, remove it from complete args. - if incomplete and args and args[-1] == incomplete: - args.pop() - - return args, incomplete - - def format_completion(self, item: CompletionItem) -> str: - if item.help: - return f"{item.type},{item.value}\t{item.help}" - - return f"{item.type},{item.value}" - - -_available_shells: t.Dict[str, t.Type[ShellComplete]] = { - "bash": BashComplete, - "fish": FishComplete, - "zsh": ZshComplete, -} - - -def add_completion_class( - cls: t.Type[ShellComplete], name: t.Optional[str] = None -) -> None: - """Register a :class:`ShellComplete` subclass under the given name. - The name will be provided by the completion instruction environment - variable during completion. - - :param cls: The completion class that will handle completion for the - shell. - :param name: Name to register the class under. Defaults to the - class's ``name`` attribute. - """ - if name is None: - name = cls.name - - _available_shells[name] = cls - - -def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: - """Look up a registered :class:`ShellComplete` subclass by the name - provided by the completion instruction environment variable. If the - name isn't registered, returns ``None``. - - :param shell: Name the class is registered under. - """ - return _available_shells.get(shell) - - -def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: - """Determine if the given parameter is an argument that can still - accept values. - - :param ctx: Invocation context for the command represented by the - parsed complete args. - :param param: Argument object being checked. - """ - if not isinstance(param, Argument): - return False - - assert param.name is not None - value = ctx.params[param.name] - return ( - param.nargs == -1 - or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE - or ( - param.nargs > 1 - and isinstance(value, (tuple, list)) - and len(value) < param.nargs - ) - ) - - -def _start_of_option(value: str) -> bool: - """Check if the value looks like the start of an option.""" - if not value: - return False - - c = value[0] - # Allow "/" since that starts a path. - return not c.isalnum() and c != "/" - - -def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: - """Determine if the given parameter is an option that needs a value. - - :param args: List of complete args before the incomplete value. - :param param: Option object being checked. - """ - if not isinstance(param, Option): - return False - - if param.is_flag: - return False - - last_option = None - - for index, arg in enumerate(reversed(args)): - if index + 1 > param.nargs: - break - - if _start_of_option(arg): - last_option = arg - - return last_option is not None and last_option in param.opts - - -def _resolve_context( - cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] -) -> Context: - """Produce the context hierarchy starting with the command and - traversing the complete arguments. This only follows the commands, - it doesn't trigger input prompts or callbacks. - - :param cli: Command being called. - :param prog_name: Name of the executable in the shell. - :param args: List of complete args before the incomplete value. - """ - ctx_args["resilient_parsing"] = True - ctx = cli.make_context(prog_name, args.copy(), **ctx_args) - args = ctx.protected_args + ctx.args - - while args: - command = ctx.command - - if isinstance(command, MultiCommand): - if not command.chain: - name, cmd, args = command.resolve_command(ctx, args) - - if cmd is None: - return ctx - - ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) - args = ctx.protected_args + ctx.args - else: - while args: - name, cmd, args = command.resolve_command(ctx, args) - - if cmd is None: - return ctx - - sub_ctx = cmd.make_context( - name, - args, - parent=ctx, - allow_extra_args=True, - allow_interspersed_args=False, - resilient_parsing=True, - ) - args = sub_ctx.args - - ctx = sub_ctx - args = [*sub_ctx.protected_args, *sub_ctx.args] - else: - break - - return ctx - - -def _resolve_incomplete( - ctx: Context, args: t.List[str], incomplete: str -) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: - """Find the Click object that will handle the completion of the - incomplete value. Return the object and the incomplete value. - - :param ctx: Invocation context for the command represented by - the parsed complete args. - :param args: List of complete args before the incomplete value. - :param incomplete: Value being completed. May be empty. - """ - # Different shells treat an "=" between a long option name and - # value differently. Might keep the value joined, return the "=" - # as a separate item, or return the split name and value. Always - # split and discard the "=" to make completion easier. - if incomplete == "=": - incomplete = "" - elif "=" in incomplete and _start_of_option(incomplete): - name, _, incomplete = incomplete.partition("=") - args.append(name) - - # The "--" marker tells Click to stop treating values as options - # even if they start with the option character. If it hasn't been - # given and the incomplete arg looks like an option, the current - # command will provide option name completions. - if "--" not in args and _start_of_option(incomplete): - return ctx.command, incomplete - - params = ctx.command.get_params(ctx) - - # If the last complete arg is an option name with an incomplete - # value, the option will provide value completions. - for param in params: - if _is_incomplete_option(args, param): - return param, incomplete - - # It's not an option name or value. The first argument without a - # parsed value will provide value completions. - for param in params: - if _is_incomplete_argument(ctx, param): - return param, incomplete - - # There were no unparsed arguments, the command may be a group that - # will provide command name completions. - return ctx.command, incomplete diff --git a/venv/lib/python3.7/site-packages/click/termui.py b/venv/lib/python3.7/site-packages/click/termui.py deleted file mode 100644 index 07b5257..0000000 --- a/venv/lib/python3.7/site-packages/click/termui.py +++ /dev/null @@ -1,806 +0,0 @@ -import inspect -import io -import itertools -import os -import sys -import typing as t -from gettext import gettext as _ - -from ._compat import isatty -from ._compat import strip_ansi -from ._compat import WIN -from .exceptions import Abort -from .exceptions import UsageError -from .globals import resolve_color_default -from .types import Choice -from .types import convert_type -from .types import ParamType -from .utils import echo -from .utils import LazyFile - -if t.TYPE_CHECKING: - from ._termui_impl import ProgressBar - -V = t.TypeVar("V") - -# The prompt functions to use. The doc tools currently override these -# functions to customize how they work. -visible_prompt_func: t.Callable[[str], str] = input - -_ansi_colors = { - "black": 30, - "red": 31, - "green": 32, - "yellow": 33, - "blue": 34, - "magenta": 35, - "cyan": 36, - "white": 37, - "reset": 39, - "bright_black": 90, - "bright_red": 91, - "bright_green": 92, - "bright_yellow": 93, - "bright_blue": 94, - "bright_magenta": 95, - "bright_cyan": 96, - "bright_white": 97, -} -_ansi_reset_all = "\033[0m" - - -def hidden_prompt_func(prompt: str) -> str: - import getpass - - return getpass.getpass(prompt) - - -def _build_prompt( - text: str, - suffix: str, - show_default: bool = False, - default: t.Optional[t.Any] = None, - show_choices: bool = True, - type: t.Optional[ParamType] = None, -) -> str: - prompt = text - if type is not None and show_choices and isinstance(type, Choice): - prompt += f" ({', '.join(map(str, type.choices))})" - if default is not None and show_default: - prompt = f"{prompt} [{_format_default(default)}]" - return f"{prompt}{suffix}" - - -def _format_default(default: t.Any) -> t.Any: - if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): - return default.name # type: ignore - - return default - - -def prompt( - text: str, - default: t.Optional[t.Any] = None, - hide_input: bool = False, - confirmation_prompt: t.Union[bool, str] = False, - type: t.Optional[t.Union[ParamType, t.Any]] = None, - value_proc: t.Optional[t.Callable[[str], t.Any]] = None, - prompt_suffix: str = ": ", - show_default: bool = True, - err: bool = False, - show_choices: bool = True, -) -> t.Any: - """Prompts a user for input. This is a convenience function that can - be used to prompt a user for input later. - - If the user aborts the input by sending an interrupt signal, this - function will catch it and raise a :exc:`Abort` exception. - - :param text: the text to show for the prompt. - :param default: the default value to use if no input happens. If this - is not given it will prompt until it's aborted. - :param hide_input: if this is set to true then the input value will - be hidden. - :param confirmation_prompt: Prompt a second time to confirm the - value. Can be set to a string instead of ``True`` to customize - the message. - :param type: the type to use to check the value against. - :param value_proc: if this parameter is provided it's a function that - is invoked instead of the type conversion to - convert a value. - :param prompt_suffix: a suffix that should be added to the prompt. - :param show_default: shows or hides the default value in the prompt. - :param err: if set to true the file defaults to ``stderr`` instead of - ``stdout``, the same as with echo. - :param show_choices: Show or hide choices if the passed type is a Choice. - For example if type is a Choice of either day or week, - show_choices is true and text is "Group by" then the - prompt will be "Group by (day, week): ". - - .. versionadded:: 8.0 - ``confirmation_prompt`` can be a custom string. - - .. versionadded:: 7.0 - Added the ``show_choices`` parameter. - - .. versionadded:: 6.0 - Added unicode support for cmd.exe on Windows. - - .. versionadded:: 4.0 - Added the `err` parameter. - - """ - - def prompt_func(text: str) -> str: - f = hidden_prompt_func if hide_input else visible_prompt_func - try: - # Write the prompt separately so that we get nice - # coloring through colorama on Windows - echo(text.rstrip(" "), nl=False, err=err) - # Echo a space to stdout to work around an issue where - # readline causes backspace to clear the whole line. - return f(" ") - except (KeyboardInterrupt, EOFError): - # getpass doesn't print a newline if the user aborts input with ^C. - # Allegedly this behavior is inherited from getpass(3). - # A doc bug has been filed at https://bugs.python.org/issue24711 - if hide_input: - echo(None, err=err) - raise Abort() from None - - if value_proc is None: - value_proc = convert_type(type, default) - - prompt = _build_prompt( - text, prompt_suffix, show_default, default, show_choices, type - ) - - if confirmation_prompt: - if confirmation_prompt is True: - confirmation_prompt = _("Repeat for confirmation") - - confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) - - while True: - while True: - value = prompt_func(prompt) - if value: - break - elif default is not None: - value = default - break - try: - result = value_proc(value) - except UsageError as e: - if hide_input: - echo(_("Error: The value you entered was invalid."), err=err) - else: - echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 - continue - if not confirmation_prompt: - return result - while True: - value2 = prompt_func(confirmation_prompt) - if value2: - break - if value == value2: - return result - echo(_("Error: The two entered values do not match."), err=err) - - -def confirm( - text: str, - default: t.Optional[bool] = False, - abort: bool = False, - prompt_suffix: str = ": ", - show_default: bool = True, - err: bool = False, -) -> bool: - """Prompts for confirmation (yes/no question). - - If the user aborts the input by sending a interrupt signal this - function will catch it and raise a :exc:`Abort` exception. - - :param text: the question to ask. - :param default: The default value to use when no input is given. If - ``None``, repeat until input is given. - :param abort: if this is set to `True` a negative answer aborts the - exception by raising :exc:`Abort`. - :param prompt_suffix: a suffix that should be added to the prompt. - :param show_default: shows or hides the default value in the prompt. - :param err: if set to true the file defaults to ``stderr`` instead of - ``stdout``, the same as with echo. - - .. versionchanged:: 8.0 - Repeat until input is given if ``default`` is ``None``. - - .. versionadded:: 4.0 - Added the ``err`` parameter. - """ - prompt = _build_prompt( - text, - prompt_suffix, - show_default, - "y/n" if default is None else ("Y/n" if default else "y/N"), - ) - - while True: - try: - # Write the prompt separately so that we get nice - # coloring through colorama on Windows - echo(prompt.rstrip(" "), nl=False, err=err) - # Echo a space to stdout to work around an issue where - # readline causes backspace to clear the whole line. - value = visible_prompt_func(" ").lower().strip() - except (KeyboardInterrupt, EOFError): - raise Abort() from None - if value in ("y", "yes"): - rv = True - elif value in ("n", "no"): - rv = False - elif default is not None and value == "": - rv = default - else: - echo(_("Error: invalid input"), err=err) - continue - break - if abort and not rv: - raise Abort() - return rv - - -def get_terminal_size() -> os.terminal_size: - """Returns the current size of the terminal as tuple in the form - ``(width, height)`` in columns and rows. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Use - :func:`shutil.get_terminal_size` instead. - """ - import shutil - import warnings - - warnings.warn( - "'click.get_terminal_size()' is deprecated and will be removed" - " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", - DeprecationWarning, - stacklevel=2, - ) - return shutil.get_terminal_size() - - -def echo_via_pager( - text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], - color: t.Optional[bool] = None, -) -> None: - """This function takes a text and shows it via an environment specific - pager on stdout. - - .. versionchanged:: 3.0 - Added the `color` flag. - - :param text_or_generator: the text to page, or alternatively, a - generator emitting the text to page. - :param color: controls if the pager supports ANSI colors or not. The - default is autodetection. - """ - color = resolve_color_default(color) - - if inspect.isgeneratorfunction(text_or_generator): - i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() - elif isinstance(text_or_generator, str): - i = [text_or_generator] - else: - i = iter(t.cast(t.Iterable[str], text_or_generator)) - - # convert every element of i to a text type if necessary - text_generator = (el if isinstance(el, str) else str(el) for el in i) - - from ._termui_impl import pager - - return pager(itertools.chain(text_generator, "\n"), color) - - -def progressbar( - iterable: t.Optional[t.Iterable[V]] = None, - length: t.Optional[int] = None, - label: t.Optional[str] = None, - show_eta: bool = True, - show_percent: t.Optional[bool] = None, - show_pos: bool = False, - item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, - fill_char: str = "#", - empty_char: str = "-", - bar_template: str = "%(label)s [%(bar)s] %(info)s", - info_sep: str = " ", - width: int = 36, - file: t.Optional[t.TextIO] = None, - color: t.Optional[bool] = None, - update_min_steps: int = 1, -) -> "ProgressBar[V]": - """This function creates an iterable context manager that can be used - to iterate over something while showing a progress bar. It will - either iterate over the `iterable` or `length` items (that are counted - up). While iteration happens, this function will print a rendered - progress bar to the given `file` (defaults to stdout) and will attempt - to calculate remaining time and more. By default, this progress bar - will not be rendered if the file is not a terminal. - - The context manager creates the progress bar. When the context - manager is entered the progress bar is already created. With every - iteration over the progress bar, the iterable passed to the bar is - advanced and the bar is updated. When the context manager exits, - a newline is printed and the progress bar is finalized on screen. - - Note: The progress bar is currently designed for use cases where the - total progress can be expected to take at least several seconds. - Because of this, the ProgressBar class object won't display - progress that is considered too fast, and progress where the time - between steps is less than a second. - - No printing must happen or the progress bar will be unintentionally - destroyed. - - Example usage:: - - with progressbar(items) as bar: - for item in bar: - do_something_with(item) - - Alternatively, if no iterable is specified, one can manually update the - progress bar through the `update()` method instead of directly - iterating over the progress bar. The update method accepts the number - of steps to increment the bar with:: - - with progressbar(length=chunks.total_bytes) as bar: - for chunk in chunks: - process_chunk(chunk) - bar.update(chunks.bytes) - - The ``update()`` method also takes an optional value specifying the - ``current_item`` at the new position. This is useful when used - together with ``item_show_func`` to customize the output for each - manual step:: - - with click.progressbar( - length=total_size, - label='Unzipping archive', - item_show_func=lambda a: a.filename - ) as bar: - for archive in zip_file: - archive.extract() - bar.update(archive.size, archive) - - :param iterable: an iterable to iterate over. If not provided the length - is required. - :param length: the number of items to iterate over. By default the - progressbar will attempt to ask the iterator about its - length, which might or might not work. If an iterable is - also provided this parameter can be used to override the - length. If an iterable is not provided the progress bar - will iterate over a range of that length. - :param label: the label to show next to the progress bar. - :param show_eta: enables or disables the estimated time display. This is - automatically disabled if the length cannot be - determined. - :param show_percent: enables or disables the percentage display. The - default is `True` if the iterable has a length or - `False` if not. - :param show_pos: enables or disables the absolute position display. The - default is `False`. - :param item_show_func: A function called with the current item which - can return a string to show next to the progress bar. If the - function returns ``None`` nothing is shown. The current item can - be ``None``, such as when entering and exiting the bar. - :param fill_char: the character to use to show the filled part of the - progress bar. - :param empty_char: the character to use to show the non-filled part of - the progress bar. - :param bar_template: the format string to use as template for the bar. - The parameters in it are ``label`` for the label, - ``bar`` for the progress bar and ``info`` for the - info section. - :param info_sep: the separator between multiple info items (eta etc.) - :param width: the width of the progress bar in characters, 0 means full - terminal width - :param file: The file to write to. If this is not a terminal then - only the label is printed. - :param color: controls if the terminal supports ANSI colors or not. The - default is autodetection. This is only needed if ANSI - codes are included anywhere in the progress bar output - which is not the case by default. - :param update_min_steps: Render only when this many updates have - completed. This allows tuning for very fast iterators. - - .. versionchanged:: 8.0 - Output is shown even if execution time is less than 0.5 seconds. - - .. versionchanged:: 8.0 - ``item_show_func`` shows the current item, not the previous one. - - .. versionchanged:: 8.0 - Labels are echoed if the output is not a TTY. Reverts a change - in 7.0 that removed all output. - - .. versionadded:: 8.0 - Added the ``update_min_steps`` parameter. - - .. versionchanged:: 4.0 - Added the ``color`` parameter. Added the ``update`` method to - the object. - - .. versionadded:: 2.0 - """ - from ._termui_impl import ProgressBar - - color = resolve_color_default(color) - return ProgressBar( - iterable=iterable, - length=length, - show_eta=show_eta, - show_percent=show_percent, - show_pos=show_pos, - item_show_func=item_show_func, - fill_char=fill_char, - empty_char=empty_char, - bar_template=bar_template, - info_sep=info_sep, - file=file, - label=label, - width=width, - color=color, - update_min_steps=update_min_steps, - ) - - -def clear() -> None: - """Clears the terminal screen. This will have the effect of clearing - the whole visible space of the terminal and moving the cursor to the - top left. This does not do anything if not connected to a terminal. - - .. versionadded:: 2.0 - """ - if not isatty(sys.stdout): - return - if WIN: - os.system("cls") - else: - sys.stdout.write("\033[2J\033[1;1H") - - -def _interpret_color( - color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 -) -> str: - if isinstance(color, int): - return f"{38 + offset};5;{color:d}" - - if isinstance(color, (tuple, list)): - r, g, b = color - return f"{38 + offset};2;{r:d};{g:d};{b:d}" - - return str(_ansi_colors[color] + offset) - - -def style( - text: t.Any, - fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, - bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, - bold: t.Optional[bool] = None, - dim: t.Optional[bool] = None, - underline: t.Optional[bool] = None, - overline: t.Optional[bool] = None, - italic: t.Optional[bool] = None, - blink: t.Optional[bool] = None, - reverse: t.Optional[bool] = None, - strikethrough: t.Optional[bool] = None, - reset: bool = True, -) -> str: - """Styles a text with ANSI styles and returns the new string. By - default the styling is self contained which means that at the end - of the string a reset code is issued. This can be prevented by - passing ``reset=False``. - - Examples:: - - click.echo(click.style('Hello World!', fg='green')) - click.echo(click.style('ATTENTION!', blink=True)) - click.echo(click.style('Some things', reverse=True, fg='cyan')) - click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) - - Supported color names: - - * ``black`` (might be a gray) - * ``red`` - * ``green`` - * ``yellow`` (might be an orange) - * ``blue`` - * ``magenta`` - * ``cyan`` - * ``white`` (might be light gray) - * ``bright_black`` - * ``bright_red`` - * ``bright_green`` - * ``bright_yellow`` - * ``bright_blue`` - * ``bright_magenta`` - * ``bright_cyan`` - * ``bright_white`` - * ``reset`` (reset the color code only) - - If the terminal supports it, color may also be specified as: - - - An integer in the interval [0, 255]. The terminal must support - 8-bit/256-color mode. - - An RGB tuple of three integers in [0, 255]. The terminal must - support 24-bit/true-color mode. - - See https://en.wikipedia.org/wiki/ANSI_color and - https://gist.github.com/XVilka/8346728 for more information. - - :param text: the string to style with ansi codes. - :param fg: if provided this will become the foreground color. - :param bg: if provided this will become the background color. - :param bold: if provided this will enable or disable bold mode. - :param dim: if provided this will enable or disable dim mode. This is - badly supported. - :param underline: if provided this will enable or disable underline. - :param overline: if provided this will enable or disable overline. - :param italic: if provided this will enable or disable italic. - :param blink: if provided this will enable or disable blinking. - :param reverse: if provided this will enable or disable inverse - rendering (foreground becomes background and the - other way round). - :param strikethrough: if provided this will enable or disable - striking through text. - :param reset: by default a reset-all code is added at the end of the - string which means that styles do not carry over. This - can be disabled to compose styles. - - .. versionchanged:: 8.0 - A non-string ``message`` is converted to a string. - - .. versionchanged:: 8.0 - Added support for 256 and RGB color codes. - - .. versionchanged:: 8.0 - Added the ``strikethrough``, ``italic``, and ``overline`` - parameters. - - .. versionchanged:: 7.0 - Added support for bright colors. - - .. versionadded:: 2.0 - """ - if not isinstance(text, str): - text = str(text) - - bits = [] - - if fg: - try: - bits.append(f"\033[{_interpret_color(fg)}m") - except KeyError: - raise TypeError(f"Unknown color {fg!r}") from None - - if bg: - try: - bits.append(f"\033[{_interpret_color(bg, 10)}m") - except KeyError: - raise TypeError(f"Unknown color {bg!r}") from None - - if bold is not None: - bits.append(f"\033[{1 if bold else 22}m") - if dim is not None: - bits.append(f"\033[{2 if dim else 22}m") - if underline is not None: - bits.append(f"\033[{4 if underline else 24}m") - if overline is not None: - bits.append(f"\033[{53 if overline else 55}m") - if italic is not None: - bits.append(f"\033[{3 if italic else 23}m") - if blink is not None: - bits.append(f"\033[{5 if blink else 25}m") - if reverse is not None: - bits.append(f"\033[{7 if reverse else 27}m") - if strikethrough is not None: - bits.append(f"\033[{9 if strikethrough else 29}m") - bits.append(text) - if reset: - bits.append(_ansi_reset_all) - return "".join(bits) - - -def unstyle(text: str) -> str: - """Removes ANSI styling information from a string. Usually it's not - necessary to use this function as Click's echo function will - automatically remove styling if necessary. - - .. versionadded:: 2.0 - - :param text: the text to remove style information from. - """ - return strip_ansi(text) - - -def secho( - message: t.Optional[t.Any] = None, - file: t.Optional[t.IO[t.AnyStr]] = None, - nl: bool = True, - err: bool = False, - color: t.Optional[bool] = None, - **styles: t.Any, -) -> None: - """This function combines :func:`echo` and :func:`style` into one - call. As such the following two calls are the same:: - - click.secho('Hello World!', fg='green') - click.echo(click.style('Hello World!', fg='green')) - - All keyword arguments are forwarded to the underlying functions - depending on which one they go with. - - Non-string types will be converted to :class:`str`. However, - :class:`bytes` are passed directly to :meth:`echo` without applying - style. If you want to style bytes that represent text, call - :meth:`bytes.decode` first. - - .. versionchanged:: 8.0 - A non-string ``message`` is converted to a string. Bytes are - passed through without style applied. - - .. versionadded:: 2.0 - """ - if message is not None and not isinstance(message, (bytes, bytearray)): - message = style(message, **styles) - - return echo(message, file=file, nl=nl, err=err, color=color) - - -def edit( - text: t.Optional[t.AnyStr] = None, - editor: t.Optional[str] = None, - env: t.Optional[t.Mapping[str, str]] = None, - require_save: bool = True, - extension: str = ".txt", - filename: t.Optional[str] = None, -) -> t.Optional[t.AnyStr]: - r"""Edits the given text in the defined editor. If an editor is given - (should be the full path to the executable but the regular operating - system search path is used for finding the executable) it overrides - the detected editor. Optionally, some environment variables can be - used. If the editor is closed without changes, `None` is returned. In - case a file is edited directly the return value is always `None` and - `require_save` and `extension` are ignored. - - If the editor cannot be opened a :exc:`UsageError` is raised. - - Note for Windows: to simplify cross-platform usage, the newlines are - automatically converted from POSIX to Windows and vice versa. As such, - the message here will have ``\n`` as newline markers. - - :param text: the text to edit. - :param editor: optionally the editor to use. Defaults to automatic - detection. - :param env: environment variables to forward to the editor. - :param require_save: if this is true, then not saving in the editor - will make the return value become `None`. - :param extension: the extension to tell the editor about. This defaults - to `.txt` but changing this might change syntax - highlighting. - :param filename: if provided it will edit this file instead of the - provided text contents. It will not use a temporary - file as an indirection in that case. - """ - from ._termui_impl import Editor - - ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) - - if filename is None: - return ed.edit(text) - - ed.edit_file(filename) - return None - - -def launch(url: str, wait: bool = False, locate: bool = False) -> int: - """This function launches the given URL (or filename) in the default - viewer application for this file type. If this is an executable, it - might launch the executable in a new session. The return value is - the exit code of the launched application. Usually, ``0`` indicates - success. - - Examples:: - - click.launch('https://click.palletsprojects.com/') - click.launch('/my/downloaded/file', locate=True) - - .. versionadded:: 2.0 - - :param url: URL or filename of the thing to launch. - :param wait: Wait for the program to exit before returning. This - only works if the launched program blocks. In particular, - ``xdg-open`` on Linux does not block. - :param locate: if this is set to `True` then instead of launching the - application associated with the URL it will attempt to - launch a file manager with the file located. This - might have weird effects if the URL does not point to - the filesystem. - """ - from ._termui_impl import open_url - - return open_url(url, wait=wait, locate=locate) - - -# If this is provided, getchar() calls into this instead. This is used -# for unittesting purposes. -_getchar: t.Optional[t.Callable[[bool], str]] = None - - -def getchar(echo: bool = False) -> str: - """Fetches a single character from the terminal and returns it. This - will always return a unicode character and under certain rare - circumstances this might return more than one character. The - situations which more than one character is returned is when for - whatever reason multiple characters end up in the terminal buffer or - standard input was not actually a terminal. - - Note that this will always read from the terminal, even if something - is piped into the standard input. - - Note for Windows: in rare cases when typing non-ASCII characters, this - function might wait for a second character and then return both at once. - This is because certain Unicode characters look like special-key markers. - - .. versionadded:: 2.0 - - :param echo: if set to `True`, the character read will also show up on - the terminal. The default is to not show it. - """ - global _getchar - - if _getchar is None: - from ._termui_impl import getchar as f - - _getchar = f - - return _getchar(echo) - - -def raw_terminal() -> t.ContextManager[int]: - from ._termui_impl import raw_terminal as f - - return f() - - -def pause(info: t.Optional[str] = None, err: bool = False) -> None: - """This command stops execution and waits for the user to press any - key to continue. This is similar to the Windows batch "pause" - command. If the program is not run through a terminal, this command - will instead do nothing. - - .. versionadded:: 2.0 - - .. versionadded:: 4.0 - Added the `err` parameter. - - :param info: The message to print before pausing. Defaults to - ``"Press any key to continue..."``. - :param err: if set to message goes to ``stderr`` instead of - ``stdout``, the same as with echo. - """ - if not isatty(sys.stdin) or not isatty(sys.stdout): - return - - if info is None: - info = _("Press any key to continue...") - - try: - if info: - echo(info, nl=False, err=err) - try: - getchar() - except (KeyboardInterrupt, EOFError): - pass - finally: - if info: - echo(err=err) diff --git a/venv/lib/python3.7/site-packages/click/testing.py b/venv/lib/python3.7/site-packages/click/testing.py deleted file mode 100644 index e395c2e..0000000 --- a/venv/lib/python3.7/site-packages/click/testing.py +++ /dev/null @@ -1,479 +0,0 @@ -import contextlib -import io -import os -import shlex -import shutil -import sys -import tempfile -import typing as t -from types import TracebackType - -from . import formatting -from . import termui -from . import utils -from ._compat import _find_binary_reader - -if t.TYPE_CHECKING: - from .core import BaseCommand - - -class EchoingStdin: - def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: - self._input = input - self._output = output - self._paused = False - - def __getattr__(self, x: str) -> t.Any: - return getattr(self._input, x) - - def _echo(self, rv: bytes) -> bytes: - if not self._paused: - self._output.write(rv) - - return rv - - def read(self, n: int = -1) -> bytes: - return self._echo(self._input.read(n)) - - def read1(self, n: int = -1) -> bytes: - return self._echo(self._input.read1(n)) # type: ignore - - def readline(self, n: int = -1) -> bytes: - return self._echo(self._input.readline(n)) - - def readlines(self) -> t.List[bytes]: - return [self._echo(x) for x in self._input.readlines()] - - def __iter__(self) -> t.Iterator[bytes]: - return iter(self._echo(x) for x in self._input) - - def __repr__(self) -> str: - return repr(self._input) - - -@contextlib.contextmanager -def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: - if stream is None: - yield - else: - stream._paused = True - yield - stream._paused = False - - -class _NamedTextIOWrapper(io.TextIOWrapper): - def __init__( - self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any - ) -> None: - super().__init__(buffer, **kwargs) - self._name = name - self._mode = mode - - @property - def name(self) -> str: - return self._name - - @property - def mode(self) -> str: - return self._mode - - -def make_input_stream( - input: t.Optional[t.Union[str, bytes, t.IO]], charset: str -) -> t.BinaryIO: - # Is already an input stream. - if hasattr(input, "read"): - rv = _find_binary_reader(t.cast(t.IO, input)) - - if rv is not None: - return rv - - raise TypeError("Could not find binary reader for input stream.") - - if input is None: - input = b"" - elif isinstance(input, str): - input = input.encode(charset) - - return io.BytesIO(t.cast(bytes, input)) - - -class Result: - """Holds the captured result of an invoked CLI script.""" - - def __init__( - self, - runner: "CliRunner", - stdout_bytes: bytes, - stderr_bytes: t.Optional[bytes], - return_value: t.Any, - exit_code: int, - exception: t.Optional[BaseException], - exc_info: t.Optional[ - t.Tuple[t.Type[BaseException], BaseException, TracebackType] - ] = None, - ): - #: The runner that created the result - self.runner = runner - #: The standard output as bytes. - self.stdout_bytes = stdout_bytes - #: The standard error as bytes, or None if not available - self.stderr_bytes = stderr_bytes - #: The value returned from the invoked command. - #: - #: .. versionadded:: 8.0 - self.return_value = return_value - #: The exit code as integer. - self.exit_code = exit_code - #: The exception that happened if one did. - self.exception = exception - #: The traceback - self.exc_info = exc_info - - @property - def output(self) -> str: - """The (standard) output as unicode string.""" - return self.stdout - - @property - def stdout(self) -> str: - """The standard output as unicode string.""" - return self.stdout_bytes.decode(self.runner.charset, "replace").replace( - "\r\n", "\n" - ) - - @property - def stderr(self) -> str: - """The standard error as unicode string.""" - if self.stderr_bytes is None: - raise ValueError("stderr not separately captured") - return self.stderr_bytes.decode(self.runner.charset, "replace").replace( - "\r\n", "\n" - ) - - def __repr__(self) -> str: - exc_str = repr(self.exception) if self.exception else "okay" - return f"<{type(self).__name__} {exc_str}>" - - -class CliRunner: - """The CLI runner provides functionality to invoke a Click command line - script for unittesting purposes in a isolated environment. This only - works in single-threaded systems without any concurrency as it changes the - global interpreter state. - - :param charset: the character set for the input and output data. - :param env: a dictionary with environment variables for overriding. - :param echo_stdin: if this is set to `True`, then reading from stdin writes - to stdout. This is useful for showing examples in - some circumstances. Note that regular prompts - will automatically echo the input. - :param mix_stderr: if this is set to `False`, then stdout and stderr are - preserved as independent streams. This is useful for - Unix-philosophy apps that have predictable stdout and - noisy stderr, such that each may be measured - independently - """ - - def __init__( - self, - charset: str = "utf-8", - env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, - echo_stdin: bool = False, - mix_stderr: bool = True, - ) -> None: - self.charset = charset - self.env = env or {} - self.echo_stdin = echo_stdin - self.mix_stderr = mix_stderr - - def get_default_prog_name(self, cli: "BaseCommand") -> str: - """Given a command object it will return the default program name - for it. The default is the `name` attribute or ``"root"`` if not - set. - """ - return cli.name or "root" - - def make_env( - self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None - ) -> t.Mapping[str, t.Optional[str]]: - """Returns the environment overrides for invoking a script.""" - rv = dict(self.env) - if overrides: - rv.update(overrides) - return rv - - @contextlib.contextmanager - def isolation( - self, - input: t.Optional[t.Union[str, bytes, t.IO]] = None, - env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, - color: bool = False, - ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: - """A context manager that sets up the isolation for invoking of a - command line tool. This sets up stdin with the given input data - and `os.environ` with the overrides from the given dictionary. - This also rebinds some internals in Click to be mocked (like the - prompt functionality). - - This is automatically done in the :meth:`invoke` method. - - :param input: the input stream to put into sys.stdin. - :param env: the environment overrides as dictionary. - :param color: whether the output should contain color codes. The - application can still override this explicitly. - - .. versionchanged:: 8.0 - ``stderr`` is opened with ``errors="backslashreplace"`` - instead of the default ``"strict"``. - - .. versionchanged:: 4.0 - Added the ``color`` parameter. - """ - bytes_input = make_input_stream(input, self.charset) - echo_input = None - - old_stdin = sys.stdin - old_stdout = sys.stdout - old_stderr = sys.stderr - old_forced_width = formatting.FORCED_WIDTH - formatting.FORCED_WIDTH = 80 - - env = self.make_env(env) - - bytes_output = io.BytesIO() - - if self.echo_stdin: - bytes_input = echo_input = t.cast( - t.BinaryIO, EchoingStdin(bytes_input, bytes_output) - ) - - sys.stdin = text_input = _NamedTextIOWrapper( - bytes_input, encoding=self.charset, name="", mode="r" - ) - - if self.echo_stdin: - # Force unbuffered reads, otherwise TextIOWrapper reads a - # large chunk which is echoed early. - text_input._CHUNK_SIZE = 1 # type: ignore - - sys.stdout = _NamedTextIOWrapper( - bytes_output, encoding=self.charset, name="", mode="w" - ) - - bytes_error = None - if self.mix_stderr: - sys.stderr = sys.stdout - else: - bytes_error = io.BytesIO() - sys.stderr = _NamedTextIOWrapper( - bytes_error, - encoding=self.charset, - name="", - mode="w", - errors="backslashreplace", - ) - - @_pause_echo(echo_input) # type: ignore - def visible_input(prompt: t.Optional[str] = None) -> str: - sys.stdout.write(prompt or "") - val = text_input.readline().rstrip("\r\n") - sys.stdout.write(f"{val}\n") - sys.stdout.flush() - return val - - @_pause_echo(echo_input) # type: ignore - def hidden_input(prompt: t.Optional[str] = None) -> str: - sys.stdout.write(f"{prompt or ''}\n") - sys.stdout.flush() - return text_input.readline().rstrip("\r\n") - - @_pause_echo(echo_input) # type: ignore - def _getchar(echo: bool) -> str: - char = sys.stdin.read(1) - - if echo: - sys.stdout.write(char) - - sys.stdout.flush() - return char - - default_color = color - - def should_strip_ansi( - stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None - ) -> bool: - if color is None: - return not default_color - return not color - - old_visible_prompt_func = termui.visible_prompt_func - old_hidden_prompt_func = termui.hidden_prompt_func - old__getchar_func = termui._getchar - old_should_strip_ansi = utils.should_strip_ansi # type: ignore - termui.visible_prompt_func = visible_input - termui.hidden_prompt_func = hidden_input - termui._getchar = _getchar - utils.should_strip_ansi = should_strip_ansi # type: ignore - - old_env = {} - try: - for key, value in env.items(): - old_env[key] = os.environ.get(key) - if value is None: - try: - del os.environ[key] - except Exception: - pass - else: - os.environ[key] = value - yield (bytes_output, bytes_error) - finally: - for key, value in old_env.items(): - if value is None: - try: - del os.environ[key] - except Exception: - pass - else: - os.environ[key] = value - sys.stdout = old_stdout - sys.stderr = old_stderr - sys.stdin = old_stdin - termui.visible_prompt_func = old_visible_prompt_func - termui.hidden_prompt_func = old_hidden_prompt_func - termui._getchar = old__getchar_func - utils.should_strip_ansi = old_should_strip_ansi # type: ignore - formatting.FORCED_WIDTH = old_forced_width - - def invoke( - self, - cli: "BaseCommand", - args: t.Optional[t.Union[str, t.Sequence[str]]] = None, - input: t.Optional[t.Union[str, bytes, t.IO]] = None, - env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, - catch_exceptions: bool = True, - color: bool = False, - **extra: t.Any, - ) -> Result: - """Invokes a command in an isolated environment. The arguments are - forwarded directly to the command line script, the `extra` keyword - arguments are passed to the :meth:`~clickpkg.Command.main` function of - the command. - - This returns a :class:`Result` object. - - :param cli: the command to invoke - :param args: the arguments to invoke. It may be given as an iterable - or a string. When given as string it will be interpreted - as a Unix shell command. More details at - :func:`shlex.split`. - :param input: the input data for `sys.stdin`. - :param env: the environment overrides. - :param catch_exceptions: Whether to catch any other exceptions than - ``SystemExit``. - :param extra: the keyword arguments to pass to :meth:`main`. - :param color: whether the output should contain color codes. The - application can still override this explicitly. - - .. versionchanged:: 8.0 - The result object has the ``return_value`` attribute with - the value returned from the invoked command. - - .. versionchanged:: 4.0 - Added the ``color`` parameter. - - .. versionchanged:: 3.0 - Added the ``catch_exceptions`` parameter. - - .. versionchanged:: 3.0 - The result object has the ``exc_info`` attribute with the - traceback if available. - """ - exc_info = None - with self.isolation(input=input, env=env, color=color) as outstreams: - return_value = None - exception: t.Optional[BaseException] = None - exit_code = 0 - - if isinstance(args, str): - args = shlex.split(args) - - try: - prog_name = extra.pop("prog_name") - except KeyError: - prog_name = self.get_default_prog_name(cli) - - try: - return_value = cli.main(args=args or (), prog_name=prog_name, **extra) - except SystemExit as e: - exc_info = sys.exc_info() - e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) - - if e_code is None: - e_code = 0 - - if e_code != 0: - exception = e - - if not isinstance(e_code, int): - sys.stdout.write(str(e_code)) - sys.stdout.write("\n") - e_code = 1 - - exit_code = e_code - - except Exception as e: - if not catch_exceptions: - raise - exception = e - exit_code = 1 - exc_info = sys.exc_info() - finally: - sys.stdout.flush() - stdout = outstreams[0].getvalue() - if self.mix_stderr: - stderr = None - else: - stderr = outstreams[1].getvalue() # type: ignore - - return Result( - runner=self, - stdout_bytes=stdout, - stderr_bytes=stderr, - return_value=return_value, - exit_code=exit_code, - exception=exception, - exc_info=exc_info, # type: ignore - ) - - @contextlib.contextmanager - def isolated_filesystem( - self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None - ) -> t.Iterator[str]: - """A context manager that creates a temporary directory and - changes the current working directory to it. This isolates tests - that affect the contents of the CWD to prevent them from - interfering with each other. - - :param temp_dir: Create the temporary directory under this - directory. If given, the created directory is not removed - when exiting. - - .. versionchanged:: 8.0 - Added the ``temp_dir`` parameter. - """ - cwd = os.getcwd() - dt = tempfile.mkdtemp(dir=temp_dir) # type: ignore[type-var] - os.chdir(dt) - - try: - yield t.cast(str, dt) - finally: - os.chdir(cwd) - - if temp_dir is None: - try: - shutil.rmtree(dt) - except OSError: # noqa: B014 - pass diff --git a/venv/lib/python3.7/site-packages/click/types.py b/venv/lib/python3.7/site-packages/click/types.py deleted file mode 100644 index 550c6ff..0000000 --- a/venv/lib/python3.7/site-packages/click/types.py +++ /dev/null @@ -1,1049 +0,0 @@ -import os -import stat -import typing as t -from datetime import datetime -from gettext import gettext as _ -from gettext import ngettext - -from ._compat import _get_argv_encoding -from ._compat import get_filesystem_encoding -from ._compat import open_stream -from .exceptions import BadParameter -from .utils import LazyFile -from .utils import safecall - -if t.TYPE_CHECKING: - import typing_extensions as te - from .core import Context - from .core import Parameter - from .shell_completion import CompletionItem - - -class ParamType: - """Represents the type of a parameter. Validates and converts values - from the command line or Python into the correct type. - - To implement a custom type, subclass and implement at least the - following: - - - The :attr:`name` class attribute must be set. - - Calling an instance of the type with ``None`` must return - ``None``. This is already implemented by default. - - :meth:`convert` must convert string values to the correct type. - - :meth:`convert` must accept values that are already the correct - type. - - It must be able to convert a value if the ``ctx`` and ``param`` - arguments are ``None``. This can occur when converting prompt - input. - """ - - is_composite: t.ClassVar[bool] = False - arity: t.ClassVar[int] = 1 - - #: the descriptive name of this type - name: str - - #: if a list of this type is expected and the value is pulled from a - #: string environment variable, this is what splits it up. `None` - #: means any whitespace. For all parameters the general rule is that - #: whitespace splits them up. The exception are paths and files which - #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on - #: Windows). - envvar_list_splitter: t.ClassVar[t.Optional[str]] = None - - def to_info_dict(self) -> t.Dict[str, t.Any]: - """Gather information that could be useful for a tool generating - user-facing documentation. - - Use :meth:`click.Context.to_info_dict` to traverse the entire - CLI structure. - - .. versionadded:: 8.0 - """ - # The class name without the "ParamType" suffix. - param_type = type(self).__name__.partition("ParamType")[0] - param_type = param_type.partition("ParameterType")[0] - return {"param_type": param_type, "name": self.name} - - def __call__( - self, - value: t.Any, - param: t.Optional["Parameter"] = None, - ctx: t.Optional["Context"] = None, - ) -> t.Any: - if value is not None: - return self.convert(value, param, ctx) - - def get_metavar(self, param: "Parameter") -> t.Optional[str]: - """Returns the metavar default for this param if it provides one.""" - - def get_missing_message(self, param: "Parameter") -> t.Optional[str]: - """Optionally might return extra information about a missing - parameter. - - .. versionadded:: 2.0 - """ - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - """Convert the value to the correct type. This is not called if - the value is ``None`` (the missing value). - - This must accept string values from the command line, as well as - values that are already the correct type. It may also convert - other compatible types. - - The ``param`` and ``ctx`` arguments may be ``None`` in certain - situations, such as when converting prompt input. - - If the value cannot be converted, call :meth:`fail` with a - descriptive message. - - :param value: The value to convert. - :param param: The parameter that is using this type to convert - its value. May be ``None``. - :param ctx: The current context that arrived at this value. May - be ``None``. - """ - return value - - def split_envvar_value(self, rv: str) -> t.Sequence[str]: - """Given a value from an environment variable this splits it up - into small chunks depending on the defined envvar list splitter. - - If the splitter is set to `None`, which means that whitespace splits, - then leading and trailing whitespace is ignored. Otherwise, leading - and trailing splitters usually lead to empty items being included. - """ - return (rv or "").split(self.envvar_list_splitter) - - def fail( - self, - message: str, - param: t.Optional["Parameter"] = None, - ctx: t.Optional["Context"] = None, - ) -> "t.NoReturn": - """Helper method to fail with an invalid value message.""" - raise BadParameter(message, ctx=ctx, param=param) - - def shell_complete( - self, ctx: "Context", param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - """Return a list of - :class:`~click.shell_completion.CompletionItem` objects for the - incomplete value. Most types do not provide completions, but - some do, and this allows custom types to provide custom - completions as well. - - :param ctx: Invocation context for this command. - :param param: The parameter that is requesting completion. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - return [] - - -class CompositeParamType(ParamType): - is_composite = True - - @property - def arity(self) -> int: # type: ignore - raise NotImplementedError() - - -class FuncParamType(ParamType): - def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: - self.name = func.__name__ - self.func = func - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict["func"] = self.func - return info_dict - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - try: - return self.func(value) - except ValueError: - try: - value = str(value) - except UnicodeError: - value = value.decode("utf-8", "replace") - - self.fail(value, param, ctx) - - -class UnprocessedParamType(ParamType): - name = "text" - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - return value - - def __repr__(self) -> str: - return "UNPROCESSED" - - -class StringParamType(ParamType): - name = "text" - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - if isinstance(value, bytes): - enc = _get_argv_encoding() - try: - value = value.decode(enc) - except UnicodeError: - fs_enc = get_filesystem_encoding() - if fs_enc != enc: - try: - value = value.decode(fs_enc) - except UnicodeError: - value = value.decode("utf-8", "replace") - else: - value = value.decode("utf-8", "replace") - return value - return str(value) - - def __repr__(self) -> str: - return "STRING" - - -class Choice(ParamType): - """The choice type allows a value to be checked against a fixed set - of supported values. All of these values have to be strings. - - You should only pass a list or tuple of choices. Other iterables - (like generators) may lead to surprising results. - - The resulting value will always be one of the originally passed choices - regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` - being specified. - - See :ref:`choice-opts` for an example. - - :param case_sensitive: Set to false to make choices case - insensitive. Defaults to true. - """ - - name = "choice" - - def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: - self.choices = choices - self.case_sensitive = case_sensitive - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict["choices"] = self.choices - info_dict["case_sensitive"] = self.case_sensitive - return info_dict - - def get_metavar(self, param: "Parameter") -> str: - choices_str = "|".join(self.choices) - - # Use curly braces to indicate a required argument. - if param.required and param.param_type_name == "argument": - return f"{{{choices_str}}}" - - # Use square braces to indicate an option or optional argument. - return f"[{choices_str}]" - - def get_missing_message(self, param: "Parameter") -> str: - return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - # Match through normalization and case sensitivity - # first do token_normalize_func, then lowercase - # preserve original `value` to produce an accurate message in - # `self.fail` - normed_value = value - normed_choices = {choice: choice for choice in self.choices} - - if ctx is not None and ctx.token_normalize_func is not None: - normed_value = ctx.token_normalize_func(value) - normed_choices = { - ctx.token_normalize_func(normed_choice): original - for normed_choice, original in normed_choices.items() - } - - if not self.case_sensitive: - normed_value = normed_value.casefold() - normed_choices = { - normed_choice.casefold(): original - for normed_choice, original in normed_choices.items() - } - - if normed_value in normed_choices: - return normed_choices[normed_value] - - choices_str = ", ".join(map(repr, self.choices)) - self.fail( - ngettext( - "{value!r} is not {choice}.", - "{value!r} is not one of {choices}.", - len(self.choices), - ).format(value=value, choice=choices_str, choices=choices_str), - param, - ctx, - ) - - def __repr__(self) -> str: - return f"Choice({list(self.choices)})" - - def shell_complete( - self, ctx: "Context", param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - """Complete choices that start with the incomplete value. - - :param ctx: Invocation context for this command. - :param param: The parameter that is requesting completion. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - str_choices = map(str, self.choices) - - if self.case_sensitive: - matched = (c for c in str_choices if c.startswith(incomplete)) - else: - incomplete = incomplete.lower() - matched = (c for c in str_choices if c.lower().startswith(incomplete)) - - return [CompletionItem(c) for c in matched] - - -class DateTime(ParamType): - """The DateTime type converts date strings into `datetime` objects. - - The format strings which are checked are configurable, but default to some - common (non-timezone aware) ISO 8601 formats. - - When specifying *DateTime* formats, you should only pass a list or a tuple. - Other iterables, like generators, may lead to surprising results. - - The format strings are processed using ``datetime.strptime``, and this - consequently defines the format strings which are allowed. - - Parsing is tried using each format, in order, and the first format which - parses successfully is used. - - :param formats: A list or tuple of date format strings, in the order in - which they should be tried. Defaults to - ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, - ``'%Y-%m-%d %H:%M:%S'``. - """ - - name = "datetime" - - def __init__(self, formats: t.Optional[t.Sequence[str]] = None): - self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict["formats"] = self.formats - return info_dict - - def get_metavar(self, param: "Parameter") -> str: - return f"[{'|'.join(self.formats)}]" - - def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: - try: - return datetime.strptime(value, format) - except ValueError: - return None - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - if isinstance(value, datetime): - return value - - for format in self.formats: - converted = self._try_to_convert_date(value, format) - - if converted is not None: - return converted - - formats_str = ", ".join(map(repr, self.formats)) - self.fail( - ngettext( - "{value!r} does not match the format {format}.", - "{value!r} does not match the formats {formats}.", - len(self.formats), - ).format(value=value, format=formats_str, formats=formats_str), - param, - ctx, - ) - - def __repr__(self) -> str: - return "DateTime" - - -class _NumberParamTypeBase(ParamType): - _number_class: t.ClassVar[t.Type] - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - try: - return self._number_class(value) - except ValueError: - self.fail( - _("{value!r} is not a valid {number_type}.").format( - value=value, number_type=self.name - ), - param, - ctx, - ) - - -class _NumberRangeBase(_NumberParamTypeBase): - def __init__( - self, - min: t.Optional[float] = None, - max: t.Optional[float] = None, - min_open: bool = False, - max_open: bool = False, - clamp: bool = False, - ) -> None: - self.min = min - self.max = max - self.min_open = min_open - self.max_open = max_open - self.clamp = clamp - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict.update( - min=self.min, - max=self.max, - min_open=self.min_open, - max_open=self.max_open, - clamp=self.clamp, - ) - return info_dict - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - import operator - - rv = super().convert(value, param, ctx) - lt_min: bool = self.min is not None and ( - operator.le if self.min_open else operator.lt - )(rv, self.min) - gt_max: bool = self.max is not None and ( - operator.ge if self.max_open else operator.gt - )(rv, self.max) - - if self.clamp: - if lt_min: - return self._clamp(self.min, 1, self.min_open) # type: ignore - - if gt_max: - return self._clamp(self.max, -1, self.max_open) # type: ignore - - if lt_min or gt_max: - self.fail( - _("{value} is not in the range {range}.").format( - value=rv, range=self._describe_range() - ), - param, - ctx, - ) - - return rv - - def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: - """Find the valid value to clamp to bound in the given - direction. - - :param bound: The boundary value. - :param dir: 1 or -1 indicating the direction to move. - :param open: If true, the range does not include the bound. - """ - raise NotImplementedError - - def _describe_range(self) -> str: - """Describe the range for use in help text.""" - if self.min is None: - op = "<" if self.max_open else "<=" - return f"x{op}{self.max}" - - if self.max is None: - op = ">" if self.min_open else ">=" - return f"x{op}{self.min}" - - lop = "<" if self.min_open else "<=" - rop = "<" if self.max_open else "<=" - return f"{self.min}{lop}x{rop}{self.max}" - - def __repr__(self) -> str: - clamp = " clamped" if self.clamp else "" - return f"<{type(self).__name__} {self._describe_range()}{clamp}>" - - -class IntParamType(_NumberParamTypeBase): - name = "integer" - _number_class = int - - def __repr__(self) -> str: - return "INT" - - -class IntRange(_NumberRangeBase, IntParamType): - """Restrict an :data:`click.INT` value to a range of accepted - values. See :ref:`ranges`. - - If ``min`` or ``max`` are not passed, any value is accepted in that - direction. If ``min_open`` or ``max_open`` are enabled, the - corresponding boundary is not included in the range. - - If ``clamp`` is enabled, a value outside the range is clamped to the - boundary instead of failing. - - .. versionchanged:: 8.0 - Added the ``min_open`` and ``max_open`` parameters. - """ - - name = "integer range" - - def _clamp( # type: ignore - self, bound: int, dir: "te.Literal[1, -1]", open: bool - ) -> int: - if not open: - return bound - - return bound + dir - - -class FloatParamType(_NumberParamTypeBase): - name = "float" - _number_class = float - - def __repr__(self) -> str: - return "FLOAT" - - -class FloatRange(_NumberRangeBase, FloatParamType): - """Restrict a :data:`click.FLOAT` value to a range of accepted - values. See :ref:`ranges`. - - If ``min`` or ``max`` are not passed, any value is accepted in that - direction. If ``min_open`` or ``max_open`` are enabled, the - corresponding boundary is not included in the range. - - If ``clamp`` is enabled, a value outside the range is clamped to the - boundary instead of failing. This is not supported if either - boundary is marked ``open``. - - .. versionchanged:: 8.0 - Added the ``min_open`` and ``max_open`` parameters. - """ - - name = "float range" - - def __init__( - self, - min: t.Optional[float] = None, - max: t.Optional[float] = None, - min_open: bool = False, - max_open: bool = False, - clamp: bool = False, - ) -> None: - super().__init__( - min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp - ) - - if (min_open or max_open) and clamp: - raise TypeError("Clamping is not supported for open bounds.") - - def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: - if not open: - return bound - - # Could use Python 3.9's math.nextafter here, but clamping an - # open float range doesn't seem to be particularly useful. It's - # left up to the user to write a callback to do it if needed. - raise RuntimeError("Clamping is not supported for open bounds.") - - -class BoolParamType(ParamType): - name = "boolean" - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - if value in {False, True}: - return bool(value) - - norm = value.strip().lower() - - if norm in {"1", "true", "t", "yes", "y", "on"}: - return True - - if norm in {"0", "false", "f", "no", "n", "off"}: - return False - - self.fail( - _("{value!r} is not a valid boolean.").format(value=value), param, ctx - ) - - def __repr__(self) -> str: - return "BOOL" - - -class UUIDParameterType(ParamType): - name = "uuid" - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - import uuid - - if isinstance(value, uuid.UUID): - return value - - value = value.strip() - - try: - return uuid.UUID(value) - except ValueError: - self.fail( - _("{value!r} is not a valid UUID.").format(value=value), param, ctx - ) - - def __repr__(self) -> str: - return "UUID" - - -class File(ParamType): - """Declares a parameter to be a file for reading or writing. The file - is automatically closed once the context tears down (after the command - finished working). - - Files can be opened for reading or writing. The special value ``-`` - indicates stdin or stdout depending on the mode. - - By default, the file is opened for reading text data, but it can also be - opened in binary mode or for writing. The encoding parameter can be used - to force a specific encoding. - - The `lazy` flag controls if the file should be opened immediately or upon - first IO. The default is to be non-lazy for standard input and output - streams as well as files opened for reading, `lazy` otherwise. When opening a - file lazily for reading, it is still opened temporarily for validation, but - will not be held open until first IO. lazy is mainly useful when opening - for writing to avoid creating the file until it is needed. - - Starting with Click 2.0, files can also be opened atomically in which - case all writes go into a separate file in the same folder and upon - completion the file will be moved over to the original location. This - is useful if a file regularly read by other users is modified. - - See :ref:`file-args` for more information. - """ - - name = "filename" - envvar_list_splitter = os.path.pathsep - - def __init__( - self, - mode: str = "r", - encoding: t.Optional[str] = None, - errors: t.Optional[str] = "strict", - lazy: t.Optional[bool] = None, - atomic: bool = False, - ) -> None: - self.mode = mode - self.encoding = encoding - self.errors = errors - self.lazy = lazy - self.atomic = atomic - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict.update(mode=self.mode, encoding=self.encoding) - return info_dict - - def resolve_lazy_flag(self, value: t.Any) -> bool: - if self.lazy is not None: - return self.lazy - if value == "-": - return False - elif "w" in self.mode: - return True - return False - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - try: - if hasattr(value, "read") or hasattr(value, "write"): - return value - - lazy = self.resolve_lazy_flag(value) - - if lazy: - f: t.IO = t.cast( - t.IO, - LazyFile( - value, self.mode, self.encoding, self.errors, atomic=self.atomic - ), - ) - - if ctx is not None: - ctx.call_on_close(f.close_intelligently) # type: ignore - - return f - - f, should_close = open_stream( - value, self.mode, self.encoding, self.errors, atomic=self.atomic - ) - - # If a context is provided, we automatically close the file - # at the end of the context execution (or flush out). If a - # context does not exist, it's the caller's responsibility to - # properly close the file. This for instance happens when the - # type is used with prompts. - if ctx is not None: - if should_close: - ctx.call_on_close(safecall(f.close)) - else: - ctx.call_on_close(safecall(f.flush)) - - return f - except OSError as e: # noqa: B014 - self.fail(f"{os.fsdecode(value)!r}: {e.strerror}", param, ctx) - - def shell_complete( - self, ctx: "Context", param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - """Return a special completion marker that tells the completion - system to use the shell to provide file path completions. - - :param ctx: Invocation context for this command. - :param param: The parameter that is requesting completion. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - return [CompletionItem(incomplete, type="file")] - - -class Path(ParamType): - """The ``Path`` type is similar to the :class:`File` type, but - returns the filename instead of an open file. Various checks can be - enabled to validate the type of file and permissions. - - :param exists: The file or directory needs to exist for the value to - be valid. If this is not set to ``True``, and the file does not - exist, then all further checks are silently skipped. - :param file_okay: Allow a file as a value. - :param dir_okay: Allow a directory as a value. - :param writable: The file or directory must be writable. - :param readable: The file or directory must be readable. - :param resolve_path: Make the value absolute and resolve any - symlinks. A ``~`` is not expanded, as this is supposed to be - done by the shell only. - :param allow_dash: Allow a single dash as a value, which indicates - a standard stream (but does not open it). Use - :func:`~click.open_file` to handle opening this value. - :param path_type: Convert the incoming path value to this type. If - ``None``, keep Python's default, which is ``str``. Useful to - convert to :class:`pathlib.Path`. - - .. versionchanged:: 8.0 - Allow passing ``type=pathlib.Path``. - - .. versionchanged:: 6.0 - Added the ``allow_dash`` parameter. - """ - - envvar_list_splitter = os.path.pathsep - - def __init__( - self, - exists: bool = False, - file_okay: bool = True, - dir_okay: bool = True, - writable: bool = False, - readable: bool = True, - resolve_path: bool = False, - allow_dash: bool = False, - path_type: t.Optional[t.Type] = None, - ): - self.exists = exists - self.file_okay = file_okay - self.dir_okay = dir_okay - self.writable = writable - self.readable = readable - self.resolve_path = resolve_path - self.allow_dash = allow_dash - self.type = path_type - - if self.file_okay and not self.dir_okay: - self.name = _("file") - elif self.dir_okay and not self.file_okay: - self.name = _("directory") - else: - self.name = _("path") - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict.update( - exists=self.exists, - file_okay=self.file_okay, - dir_okay=self.dir_okay, - writable=self.writable, - readable=self.readable, - allow_dash=self.allow_dash, - ) - return info_dict - - def coerce_path_result(self, rv: t.Any) -> t.Any: - if self.type is not None and not isinstance(rv, self.type): - if self.type is str: - rv = os.fsdecode(rv) - elif self.type is bytes: - rv = os.fsencode(rv) - else: - rv = self.type(rv) - - return rv - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - rv = value - - is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") - - if not is_dash: - if self.resolve_path: - # os.path.realpath doesn't resolve symlinks on Windows - # until Python 3.8. Use pathlib for now. - import pathlib - - rv = os.fsdecode(pathlib.Path(rv).resolve()) - - try: - st = os.stat(rv) - except OSError: - if not self.exists: - return self.coerce_path_result(rv) - self.fail( - _("{name} {filename!r} does not exist.").format( - name=self.name.title(), filename=os.fsdecode(value) - ), - param, - ctx, - ) - - if not self.file_okay and stat.S_ISREG(st.st_mode): - self.fail( - _("{name} {filename!r} is a file.").format( - name=self.name.title(), filename=os.fsdecode(value) - ), - param, - ctx, - ) - if not self.dir_okay and stat.S_ISDIR(st.st_mode): - self.fail( - _("{name} {filename!r} is a directory.").format( - name=self.name.title(), filename=os.fsdecode(value) - ), - param, - ctx, - ) - if self.writable and not os.access(rv, os.W_OK): - self.fail( - _("{name} {filename!r} is not writable.").format( - name=self.name.title(), filename=os.fsdecode(value) - ), - param, - ctx, - ) - if self.readable and not os.access(rv, os.R_OK): - self.fail( - _("{name} {filename!r} is not readable.").format( - name=self.name.title(), filename=os.fsdecode(value) - ), - param, - ctx, - ) - - return self.coerce_path_result(rv) - - def shell_complete( - self, ctx: "Context", param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - """Return a special completion marker that tells the completion - system to use the shell to provide path completions for only - directories or any paths. - - :param ctx: Invocation context for this command. - :param param: The parameter that is requesting completion. - :param incomplete: Value being completed. May be empty. - - .. versionadded:: 8.0 - """ - from click.shell_completion import CompletionItem - - type = "dir" if self.dir_okay and not self.file_okay else "file" - return [CompletionItem(incomplete, type=type)] - - -class Tuple(CompositeParamType): - """The default behavior of Click is to apply a type on a value directly. - This works well in most cases, except for when `nargs` is set to a fixed - count and different types should be used for different items. In this - case the :class:`Tuple` type can be used. This type can only be used - if `nargs` is set to a fixed number. - - For more information see :ref:`tuple-type`. - - This can be selected by using a Python tuple literal as a type. - - :param types: a list of types that should be used for the tuple items. - """ - - def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None: - self.types = [convert_type(ty) for ty in types] - - def to_info_dict(self) -> t.Dict[str, t.Any]: - info_dict = super().to_info_dict() - info_dict["types"] = [t.to_info_dict() for t in self.types] - return info_dict - - @property - def name(self) -> str: # type: ignore - return f"<{' '.join(ty.name for ty in self.types)}>" - - @property - def arity(self) -> int: # type: ignore - return len(self.types) - - def convert( - self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] - ) -> t.Any: - len_type = len(self.types) - len_value = len(value) - - if len_value != len_type: - self.fail( - ngettext( - "{len_type} values are required, but {len_value} was given.", - "{len_type} values are required, but {len_value} were given.", - len_value, - ).format(len_type=len_type, len_value=len_value), - param=param, - ctx=ctx, - ) - - return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) - - -def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: - """Find the most appropriate :class:`ParamType` for the given Python - type. If the type isn't provided, it can be inferred from a default - value. - """ - guessed_type = False - - if ty is None and default is not None: - if isinstance(default, (tuple, list)): - # If the default is empty, ty will remain None and will - # return STRING. - if default: - item = default[0] - - # A tuple of tuples needs to detect the inner types. - # Can't call convert recursively because that would - # incorrectly unwind the tuple to a single type. - if isinstance(item, (tuple, list)): - ty = tuple(map(type, item)) - else: - ty = type(item) - else: - ty = type(default) - - guessed_type = True - - if isinstance(ty, tuple): - return Tuple(ty) - - if isinstance(ty, ParamType): - return ty - - if ty is str or ty is None: - return STRING - - if ty is int: - return INT - - if ty is float: - return FLOAT - - if ty is bool: - return BOOL - - if guessed_type: - return STRING - - if __debug__: - try: - if issubclass(ty, ParamType): - raise AssertionError( - f"Attempted to use an uninstantiated parameter type ({ty})." - ) - except TypeError: - # ty is an instance (correct), so issubclass fails. - pass - - return FuncParamType(ty) - - -#: A dummy parameter type that just does nothing. From a user's -#: perspective this appears to just be the same as `STRING` but -#: internally no string conversion takes place if the input was bytes. -#: This is usually useful when working with file paths as they can -#: appear in bytes and unicode. -#: -#: For path related uses the :class:`Path` type is a better choice but -#: there are situations where an unprocessed type is useful which is why -#: it is is provided. -#: -#: .. versionadded:: 4.0 -UNPROCESSED = UnprocessedParamType() - -#: A unicode string parameter type which is the implicit default. This -#: can also be selected by using ``str`` as type. -STRING = StringParamType() - -#: An integer parameter. This can also be selected by using ``int`` as -#: type. -INT = IntParamType() - -#: A floating point value parameter. This can also be selected by using -#: ``float`` as type. -FLOAT = FloatParamType() - -#: A boolean parameter. This is the default for boolean flags. This can -#: also be selected by using ``bool`` as a type. -BOOL = BoolParamType() - -#: A UUID parameter. -UUID = UUIDParameterType() diff --git a/venv/lib/python3.7/site-packages/click/utils.py b/venv/lib/python3.7/site-packages/click/utils.py deleted file mode 100644 index 8dd3a00..0000000 --- a/venv/lib/python3.7/site-packages/click/utils.py +++ /dev/null @@ -1,588 +0,0 @@ -import os -import sys -import typing as t -from functools import update_wrapper -from types import ModuleType - -from ._compat import _default_text_stderr -from ._compat import _default_text_stdout -from ._compat import _find_binary_writer -from ._compat import auto_wrap_for_ansi -from ._compat import binary_streams -from ._compat import get_filesystem_encoding -from ._compat import open_stream -from ._compat import should_strip_ansi -from ._compat import strip_ansi -from ._compat import text_streams -from ._compat import WIN -from .globals import resolve_color_default - -if t.TYPE_CHECKING: - import typing_extensions as te - -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) - - -def _posixify(name: str) -> str: - return "-".join(name.split()).lower() - - -def safecall(func: F) -> F: - """Wraps a function so that it swallows exceptions.""" - - def wrapper(*args, **kwargs): # type: ignore - try: - return func(*args, **kwargs) - except Exception: - pass - - return update_wrapper(t.cast(F, wrapper), func) - - -def make_str(value: t.Any) -> str: - """Converts a value into a valid string.""" - if isinstance(value, bytes): - try: - return value.decode(get_filesystem_encoding()) - except UnicodeError: - return value.decode("utf-8", "replace") - return str(value) - - -def make_default_short_help(help: str, max_length: int = 45) -> str: - """Returns a condensed version of help string.""" - # Consider only the first paragraph. - paragraph_end = help.find("\n\n") - - if paragraph_end != -1: - help = help[:paragraph_end] - - # Collapse newlines, tabs, and spaces. - words = help.split() - - if not words: - return "" - - # The first paragraph started with a "no rewrap" marker, ignore it. - if words[0] == "\b": - words = words[1:] - - total_length = 0 - last_index = len(words) - 1 - - for i, word in enumerate(words): - total_length += len(word) + (i > 0) - - if total_length > max_length: # too long, truncate - break - - if word[-1] == ".": # sentence end, truncate without "..." - return " ".join(words[: i + 1]) - - if total_length == max_length and i != last_index: - break # not at sentence end, truncate with "..." - else: - return " ".join(words) # no truncation needed - - # Account for the length of the suffix. - total_length += len("...") - - # remove words until the length is short enough - while i > 0: - total_length -= len(words[i]) + (i > 0) - - if total_length <= max_length: - break - - i -= 1 - - return " ".join(words[:i]) + "..." - - -class LazyFile: - """A lazy file works like a regular file but it does not fully open - the file but it does perform some basic checks early to see if the - filename parameter does make sense. This is useful for safely opening - files for writing. - """ - - def __init__( - self, - filename: str, - mode: str = "r", - encoding: t.Optional[str] = None, - errors: t.Optional[str] = "strict", - atomic: bool = False, - ): - self.name = filename - self.mode = mode - self.encoding = encoding - self.errors = errors - self.atomic = atomic - self._f: t.Optional[t.IO] - - if filename == "-": - self._f, self.should_close = open_stream(filename, mode, encoding, errors) - else: - if "r" in mode: - # Open and close the file in case we're opening it for - # reading so that we can catch at least some errors in - # some cases early. - open(filename, mode).close() - self._f = None - self.should_close = True - - def __getattr__(self, name: str) -> t.Any: - return getattr(self.open(), name) - - def __repr__(self) -> str: - if self._f is not None: - return repr(self._f) - return f"" - - def open(self) -> t.IO: - """Opens the file if it's not yet open. This call might fail with - a :exc:`FileError`. Not handling this error will produce an error - that Click shows. - """ - if self._f is not None: - return self._f - try: - rv, self.should_close = open_stream( - self.name, self.mode, self.encoding, self.errors, atomic=self.atomic - ) - except OSError as e: # noqa: E402 - from .exceptions import FileError - - raise FileError(self.name, hint=e.strerror) from e - self._f = rv - return rv - - def close(self) -> None: - """Closes the underlying file, no matter what.""" - if self._f is not None: - self._f.close() - - def close_intelligently(self) -> None: - """This function only closes the file if it was opened by the lazy - file wrapper. For instance this will never close stdin. - """ - if self.should_close: - self.close() - - def __enter__(self) -> "LazyFile": - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - self.close_intelligently() - - def __iter__(self) -> t.Iterator[t.AnyStr]: - self.open() - return iter(self._f) # type: ignore - - -class KeepOpenFile: - def __init__(self, file: t.IO) -> None: - self._file = file - - def __getattr__(self, name: str) -> t.Any: - return getattr(self._file, name) - - def __enter__(self) -> "KeepOpenFile": - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - pass - - def __repr__(self) -> str: - return repr(self._file) - - def __iter__(self) -> t.Iterator[t.AnyStr]: - return iter(self._file) - - -def echo( - message: t.Optional[t.Any] = None, - file: t.Optional[t.IO[t.Any]] = None, - nl: bool = True, - err: bool = False, - color: t.Optional[bool] = None, -) -> None: - """Print a message and newline to stdout or a file. This should be - used instead of :func:`print` because it provides better support - for different data, files, and environments. - - Compared to :func:`print`, this does the following: - - - Ensures that the output encoding is not misconfigured on Linux. - - Supports Unicode in the Windows console. - - Supports writing to binary outputs, and supports writing bytes - to text outputs. - - Supports colors and styles on Windows. - - Removes ANSI color and style codes if the output does not look - like an interactive terminal. - - Always flushes the output. - - :param message: The string or bytes to output. Other objects are - converted to strings. - :param file: The file to write to. Defaults to ``stdout``. - :param err: Write to ``stderr`` instead of ``stdout``. - :param nl: Print a newline after the message. Enabled by default. - :param color: Force showing or hiding colors and other styles. By - default Click will remove color if the output does not look like - an interactive terminal. - - .. versionchanged:: 6.0 - Support Unicode output on the Windows console. Click does not - modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` - will still not support Unicode. - - .. versionchanged:: 4.0 - Added the ``color`` parameter. - - .. versionadded:: 3.0 - Added the ``err`` parameter. - - .. versionchanged:: 2.0 - Support colors on Windows if colorama is installed. - """ - if file is None: - if err: - file = _default_text_stderr() - else: - file = _default_text_stdout() - - # Convert non bytes/text into the native string type. - if message is not None and not isinstance(message, (str, bytes, bytearray)): - out: t.Optional[t.Union[str, bytes]] = str(message) - else: - out = message - - if nl: - out = out or "" - if isinstance(out, str): - out += "\n" - else: - out += b"\n" - - if not out: - file.flush() - return - - # If there is a message and the value looks like bytes, we manually - # need to find the binary stream and write the message in there. - # This is done separately so that most stream types will work as you - # would expect. Eg: you can write to StringIO for other cases. - if isinstance(out, (bytes, bytearray)): - binary_file = _find_binary_writer(file) - - if binary_file is not None: - file.flush() - binary_file.write(out) - binary_file.flush() - return - - # ANSI style code support. For no message or bytes, nothing happens. - # When outputting to a file instead of a terminal, strip codes. - else: - color = resolve_color_default(color) - - if should_strip_ansi(file, color): - out = strip_ansi(out) - elif WIN: - if auto_wrap_for_ansi is not None: - file = auto_wrap_for_ansi(file) # type: ignore - elif not color: - out = strip_ansi(out) - - file.write(out) # type: ignore - file.flush() - - -def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: - """Returns a system stream for byte processing. - - :param name: the name of the stream to open. Valid names are ``'stdin'``, - ``'stdout'`` and ``'stderr'`` - """ - opener = binary_streams.get(name) - if opener is None: - raise TypeError(f"Unknown standard stream '{name}'") - return opener() - - -def get_text_stream( - name: "te.Literal['stdin', 'stdout', 'stderr']", - encoding: t.Optional[str] = None, - errors: t.Optional[str] = "strict", -) -> t.TextIO: - """Returns a system stream for text processing. This usually returns - a wrapped stream around a binary stream returned from - :func:`get_binary_stream` but it also can take shortcuts for already - correctly configured streams. - - :param name: the name of the stream to open. Valid names are ``'stdin'``, - ``'stdout'`` and ``'stderr'`` - :param encoding: overrides the detected default encoding. - :param errors: overrides the default error mode. - """ - opener = text_streams.get(name) - if opener is None: - raise TypeError(f"Unknown standard stream '{name}'") - return opener(encoding, errors) - - -def open_file( - filename: str, - mode: str = "r", - encoding: t.Optional[str] = None, - errors: t.Optional[str] = "strict", - lazy: bool = False, - atomic: bool = False, -) -> t.IO: - """Open a file, with extra behavior to handle ``'-'`` to indicate - a standard stream, lazy open on write, and atomic write. Similar to - the behavior of the :class:`~click.File` param type. - - If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is - wrapped so that using it in a context manager will not close it. - This makes it possible to use the function without accidentally - closing a standard stream: - - .. code-block:: python - - with open_file(filename) as f: - ... - - :param filename: The name of the file to open, or ``'-'`` for - ``stdin``/``stdout``. - :param mode: The mode in which to open the file. - :param encoding: The encoding to decode or encode a file opened in - text mode. - :param errors: The error handling mode. - :param lazy: Wait to open the file until it is accessed. For read - mode, the file is temporarily opened to raise access errors - early, then closed until it is read again. - :param atomic: Write to a temporary file and replace the given file - on close. - - .. versionadded:: 3.0 - """ - if lazy: - return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic)) - - f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) - - if not should_close: - f = t.cast(t.IO, KeepOpenFile(f)) - - return f - - -def get_os_args() -> t.Sequence[str]: - """Returns the argument part of ``sys.argv``, removing the first - value which is the name of the script. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Access ``sys.argv[1:]`` directly - instead. - """ - import warnings - - warnings.warn( - "'get_os_args' is deprecated and will be removed in Click 8.1." - " Access 'sys.argv[1:]' directly instead.", - DeprecationWarning, - stacklevel=2, - ) - return sys.argv[1:] - - -def format_filename( - filename: t.Union[str, bytes, os.PathLike], shorten: bool = False -) -> str: - """Formats a filename for user display. The main purpose of this - function is to ensure that the filename can be displayed at all. This - will decode the filename to unicode if necessary in a way that it will - not fail. Optionally, it can shorten the filename to not include the - full path to the filename. - - :param filename: formats a filename for UI display. This will also convert - the filename into unicode without failing. - :param shorten: this optionally shortens the filename to strip of the - path that leads up to it. - """ - if shorten: - filename = os.path.basename(filename) - - return os.fsdecode(filename) - - -def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: - r"""Returns the config folder for the application. The default behavior - is to return whatever is most appropriate for the operating system. - - To give you an idea, for an app called ``"Foo Bar"``, something like - the following folders could be returned: - - Mac OS X: - ``~/Library/Application Support/Foo Bar`` - Mac OS X (POSIX): - ``~/.foo-bar`` - Unix: - ``~/.config/foo-bar`` - Unix (POSIX): - ``~/.foo-bar`` - Windows (roaming): - ``C:\Users\\AppData\Roaming\Foo Bar`` - Windows (not roaming): - ``C:\Users\\AppData\Local\Foo Bar`` - - .. versionadded:: 2.0 - - :param app_name: the application name. This should be properly capitalized - and can contain whitespace. - :param roaming: controls if the folder should be roaming or not on Windows. - Has no affect otherwise. - :param force_posix: if this is set to `True` then on any POSIX system the - folder will be stored in the home folder with a leading - dot instead of the XDG config home or darwin's - application support folder. - """ - if WIN: - key = "APPDATA" if roaming else "LOCALAPPDATA" - folder = os.environ.get(key) - if folder is None: - folder = os.path.expanduser("~") - return os.path.join(folder, app_name) - if force_posix: - return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) - if sys.platform == "darwin": - return os.path.join( - os.path.expanduser("~/Library/Application Support"), app_name - ) - return os.path.join( - os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), - _posixify(app_name), - ) - - -class PacifyFlushWrapper: - """This wrapper is used to catch and suppress BrokenPipeErrors resulting - from ``.flush()`` being called on broken pipe during the shutdown/final-GC - of the Python interpreter. Notably ``.flush()`` is always called on - ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any - other cleanup code, and the case where the underlying file is not a broken - pipe, all calls and attributes are proxied. - """ - - def __init__(self, wrapped: t.IO) -> None: - self.wrapped = wrapped - - def flush(self) -> None: - try: - self.wrapped.flush() - except OSError as e: - import errno - - if e.errno != errno.EPIPE: - raise - - def __getattr__(self, attr: str) -> t.Any: - return getattr(self.wrapped, attr) - - -def _detect_program_name( - path: t.Optional[str] = None, _main: ModuleType = sys.modules["__main__"] -) -> str: - """Determine the command used to run the program, for use in help - text. If a file or entry point was executed, the file name is - returned. If ``python -m`` was used to execute a module or package, - ``python -m name`` is returned. - - This doesn't try to be too precise, the goal is to give a concise - name for help text. Files are only shown as their name without the - path. ``python`` is only shown for modules, and the full path to - ``sys.executable`` is not shown. - - :param path: The Python file being executed. Python puts this in - ``sys.argv[0]``, which is used by default. - :param _main: The ``__main__`` module. This should only be passed - during internal testing. - - .. versionadded:: 8.0 - Based on command args detection in the Werkzeug reloader. - - :meta private: - """ - if not path: - path = sys.argv[0] - - # The value of __package__ indicates how Python was called. It may - # not exist if a setuptools script is installed as an egg. It may be - # set incorrectly for entry points created with pip on Windows. - if getattr(_main, "__package__", None) is None or ( - os.name == "nt" - and _main.__package__ == "" - and not os.path.exists(path) - and os.path.exists(f"{path}.exe") - ): - # Executed a file, like "python app.py". - return os.path.basename(path) - - # Executed a module, like "python -m example". - # Rewritten by Python from "-m script" to "/path/to/script.py". - # Need to look at main module to determine how it was executed. - py_module = t.cast(str, _main.__package__) - name = os.path.splitext(os.path.basename(path))[0] - - # A submodule like "example.cli". - if name != "__main__": - py_module = f"{py_module}.{name}" - - return f"python -m {py_module.lstrip('.')}" - - -def _expand_args( - args: t.Iterable[str], - *, - user: bool = True, - env: bool = True, - glob_recursive: bool = True, -) -> t.List[str]: - """Simulate Unix shell expansion with Python functions. - - See :func:`glob.glob`, :func:`os.path.expanduser`, and - :func:`os.path.expandvars`. - - This intended for use on Windows, where the shell does not do any - expansion. It may not exactly match what a Unix shell would do. - - :param args: List of command line arguments to expand. - :param user: Expand user home directory. - :param env: Expand environment variables. - :param glob_recursive: ``**`` matches directories recursively. - - .. versionadded:: 8.0 - - :meta private: - """ - from glob import glob - - out = [] - - for arg in args: - if user: - arg = os.path.expanduser(arg) - - if env: - arg = os.path.expandvars(arg) - - matches = glob(arg, recursive=glob_recursive) - - if not matches: - out.append(arg) - else: - out.extend(matches) - - return out diff --git a/venv/lib/python3.7/site-packages/dotenv/__init__.py b/venv/lib/python3.7/site-packages/dotenv/__init__.py deleted file mode 100644 index 3512d10..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/__init__.py +++ /dev/null @@ -1,49 +0,0 @@ -from typing import Any, Optional - -from .main import (dotenv_values, find_dotenv, get_key, load_dotenv, set_key, - unset_key) - - -def load_ipython_extension(ipython: Any) -> None: - from .ipython import load_ipython_extension - load_ipython_extension(ipython) - - -def get_cli_string( - path: Optional[str] = None, - action: Optional[str] = None, - key: Optional[str] = None, - value: Optional[str] = None, - quote: Optional[str] = None, -): - """Returns a string suitable for running as a shell script. - - Useful for converting a arguments passed to a fabric task - to be passed to a `local` or `run` command. - """ - command = ['dotenv'] - if quote: - command.append('-q %s' % quote) - if path: - command.append('-f %s' % path) - if action: - command.append(action) - if key: - command.append(key) - if value: - if ' ' in value: - command.append('"%s"' % value) - else: - command.append(value) - - return ' '.join(command).strip() - - -__all__ = ['get_cli_string', - 'load_dotenv', - 'dotenv_values', - 'get_key', - 'set_key', - 'unset_key', - 'find_dotenv', - 'load_ipython_extension'] diff --git a/venv/lib/python3.7/site-packages/dotenv/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/dotenv/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 5c46150bc808e58984f272c7dd72baa8a9c42b4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1235 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 NJEVtZ-|SHD=r2@rg*gBK diff --git a/venv/lib/python3.7/site-packages/dotenv/__pycache__/main.cpython-37.pyc b/venv/lib/python3.7/site-packages/dotenv/__pycache__/main.cpython-37.pyc deleted file mode 100644 index 1e90a4da9bf33d36268f55aa3a730b7364a5ae73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9431 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 diff --git a/venv/lib/python3.7/site-packages/dotenv/__pycache__/parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/dotenv/__pycache__/parser.cpython-37.pyc deleted file mode 100644 index 39f226c0b1f84daa4fdc96fa51f7761d1ee81ab7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5786 zcmaJ_OLH5?5#E{I1r`s2AVocG$rMSM1Z9!(BXOd#9+50NN^DxOB-;f+MwXZ%2@)^O zE@TOTs#2D6R4PBfsUnZLrIP=UQ+~l-bMjx%DPQ*j3lNgM>l%+(&D#uuq1!&ojO}lJ2owCz(%WgAOPBqizbki$) z%}hDd%$BplQt#`W&TCKSPFl+T!B&oPpS$HLJ*865M7aQ*)?#;Bc`szS2r7fo8Q?7N zEN~9^2yh;F4tNUqC~yJz81OXkao{5G3E&yvlfbjUr+|+DzX3c4{3h^G;L|##j;Z51 zwa1RPW|tR1FQ`S(iTb8w(2@5=C#<(yej`fX_CqXeMcy6#u&Y}&9l5-wWJjqWH1*bY zl+%wx<5#yD{&oOl#4YXhuAhh;HA8=Rp#dYgIf-|v!-K5b`y4G%X z>R=#!Z{yaDFFw9ml7`IDSztHcK+AK8&(z^(7!Uij7j5H!#C*V=pJr zjjhoL8)FP+uqyJZ)q1NQR;w351$0YGq(pCK$j;hu9#+GwAcpcon3gjuG}EVxN@c$w z-*7ezE%=cDydhzTPcDhbt~G*5R@@-;P51%chz(fw3JDiHRg#h04tJm&=7g;rs|hDU zA({2XF1UeM#4d^FwStl6O{_F$36LPiL}CXz{1t`<((pttKjK4&L+5^l2XZ}@28pr{ z;p|$W=!<9KL$C*KXheo0wD+CR?TZ6Bn2|%prC3gp-O#OA_fyy?N^ikd{YC?-YU%ID ze8B-T&oO3#`LwSd`G|KPjV>@Ndd1`dgXvP1G~Yt(tX89Jwc2c}ZiD*yYV~2)ZwzMa zdMh-iiHlsV;RiueBO)m?j}fy#!#0Acd7H=)AKWA3GN%C6(E{Ss6SIyKMZ4(mcnw3z zLuPUfEg+!|y^B2qD!)n22)8iHm^3Q{N(5ea;ss3n28}Jq6NczRC)pUdMhm_N7@h<_ zc943=lVQN@$u5#;;>YDQ=7{oC20rWQ3{zQ^1C>QebW|R1BAJ8EC-k%`f}YX^+Feic z88cWntBzp2$oHFzQeSFcXIY=ie zPDG>#)>`Cs25}~Gn!ec^ni6SgOrWei()%Z9K?=YUS^V{;V`hIgDv*e8(0i1B`tX8X zFbZrx6MF;Z9P=*b;;^ttJu(nP7&hyXUgHS0;|H+($Kmg>W{}zvK8ABOvLJd0zrp~e z?p=8xP{s`yu+4i|$TrNZ{M6Y91yz#M23Aj=J)Apqb`lavQz2cS&)&7sb9U{&$dfcC zcU>hoP)g`M))7UnQpy}5zSy&wLynv*ES`V8h_c%QHnsW#F&ZmOia7-Gfx<>BD2mqF zT{!kD5iDVz>;-Hx`>1$u395UJTg3jL@`-s&)HpPxUlRKh8gx2Z?|n^-NdQaqas#Gl zJSn+IYY78aK>QQ~Pi1KL5j^`aC$knh3L*A;lCs!$`>f?Yr69S{J3=0CY5rzQ&9}Ga z?0xUd1hhkW)e4}HF7@%f0z5|16BoDG$`+Yl!E)7 zri0@;@Y4LC1fFlT!}%@fTa_}A+oYm-QUJ-_;}Bu%mWoo_rrqrXLuvdPoSI7nCUlz} z9qH4RNVb-kg*-fQW@LV&Ri&B9I8H`k-XXx5#@TGQ8|HnYsTPPG;uq9gCGa5uQh=d+ zYdiv%35*!y-VBYc0o+6j3ILv%a|<^9Qbn*6@7-h+gEfS`e*Xr;B{N2muR9-lg*f{`PI{{TH5G2y?fp`k1 zR&r08V-%>-x6ywGv&bL^q9UHkR-P$4rr6O@Yo5U#FU8_Zv0QRu3n7z;W~%{;eAG1$ zyZB^MRVwzUs@>Lz#2v{#B8Mt&a}3?dOJ?{pi(c(umJNw=p(h-)g3Jp;c`3;OBymzV zUyazJtA)54nCE;=RR$~uMId{vz0pfmg7b@OtC3Z5*^;B_5sUm~Vy3Wn~YA;T+DHDP2S^Aczd86uzVX-!ZK-s8ngT@IQ;zP7bLD~ zd#g%kaODqYM*qC@aEUxxhY@7${OutDyx;08}kPbK>za)CA%HazxpT+U6^0A^Nw>jCugeo%{hQ5^ZC8c?%w+B*2Yakm6E9txKDtJ9&?Mp0|Ivmd_~}M z0u+BtmB1efd`;jUfg=R25MXOLg`3r{WH~t4SOEzZ6oVsmY+AitwL7!h(><=P zUE!riin8R9Jmi^3-bemYz4F9g$P?#O_w|<1bLke?ldQpc#qq%`!S;5u@1V8J{_kGjk(%=0)Djk9Os#J0rUddJL6Fw`W?}Qe%JN~awr|y+a{v-9TR;q_{NF01ieGT z;g6sN*$t`j-@ke56RDHXF~LV#szevc_@5;6`7}Q;!KZUQE%GEY{%45>aeg}KUV-P{ zEBC&(4eVUK@!9n}naTJ5@#Ve6wfnD!Ym#f%-fDZxu|n=A$Ca`d4m7SL9stl5jh8_O*y?@*@NID18rsS)mskz#nMm2$Cr5v!F-wuO2rAFAh| zlpa)o3>$g&TMFIwX~Ryyr&ZVqDj0+n7Y>A#Be`(DqrwwD^dKB1a1x}*L??o9w9=mF zLl1ZuoU<@WD5SVz)(a3ktL#hd>P2nC+fk zXjZstb^i0$ix8QyU#MB4Yn^BvB`a?%)lqV;;`n7)bb~sz5Ddatd=iRQC#0&jU>wpj zR*p0Sl9EGS(L;U&ZKSGWy3=x+mpaK)X*zM-1d{6E+UvmC%^ufOA=s}$u^~ffAL%q) z;f5(7-3S*3Ca4BrL1Fvs3?Tz`AU{l!a-yz){1+g?adG?x?%t4S&11C?AhHB}I-4=n zL4%EvvVpsnJUeS!ZY_;%s2dK|B~%@=jJk}~Hdg2f^%7RU!RiI95Ie)CxmJI|E)we( z2>M$X@&_m-P7UaY5BbO)a)sYhDDBgd^bkI+ND4b7PIF zJ)~*9hCN9(Q8l>Rq+IJt%u~j14!1f`F*xzTcgtCfhMKb#1Ln55m8n-jqAGLsmn9){@(Mje4}YybT>B zwjf6xHNsZT1YTI^Bb#z6@b7|G+{$+h7+K^Ee zUImeNoe^E?(Hg6_c4Ms$I>c}e6tnLi*ou^eA46}6YNiOf%gWuan6(6bPiN;JQvec+kB}I z6vH!_hk->V^3r2f!d2ge(>a|O7mh@w@ir({dm9fX9O%g!{Px7&nkTB1?dIi&2q_-4608XTzgH!Hb6{py}n7lhlrNXK^1^zFEA%yG;oH4(Z$i_p8&g+ Bqc#8l diff --git a/venv/lib/python3.7/site-packages/dotenv/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/dotenv/__pycache__/version.cpython-37.pyc deleted file mode 100644 index 4951bc35c141969f464b3aef343e5f936a24f464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218 zcmZ?b<>g`kf*2$1Byk}97{q}AMj*ohh>JOZL<&O`LkeRsgCx8mFYt%sLgr>mA5!-a`RJ4b5iX None: - '''This script is used to set, get or unset values from a .env file.''' - ctx.obj = {} - ctx.obj['QUOTE'] = quote - ctx.obj['EXPORT'] = export - ctx.obj['FILE'] = file - - -@cli.command() -@click.pass_context -def list(ctx: click.Context) -> None: - '''Display all the stored key/value.''' - file = ctx.obj['FILE'] - if not os.path.isfile(file): - raise click.BadParameter( - 'Path "%s" does not exist.' % (file), - ctx=ctx - ) - dotenv_as_dict = dotenv_values(file) - for k, v in dotenv_as_dict.items(): - click.echo('%s=%s' % (k, v)) - - -@cli.command() -@click.pass_context -@click.argument('key', required=True) -@click.argument('value', required=True) -def set(ctx: click.Context, key: Any, value: Any) -> None: - '''Store the given key/value.''' - file = ctx.obj['FILE'] - quote = ctx.obj['QUOTE'] - export = ctx.obj['EXPORT'] - success, key, value = set_key(file, key, value, quote, export) - if success: - click.echo('%s=%s' % (key, value)) - else: - exit(1) - - -@cli.command() -@click.pass_context -@click.argument('key', required=True) -def get(ctx: click.Context, key: Any) -> None: - '''Retrieve the value for the given key.''' - file = ctx.obj['FILE'] - if not os.path.isfile(file): - raise click.BadParameter( - 'Path "%s" does not exist.' % (file), - ctx=ctx - ) - stored_value = get_key(file, key) - if stored_value: - click.echo(stored_value) - else: - exit(1) - - -@cli.command() -@click.pass_context -@click.argument('key', required=True) -def unset(ctx: click.Context, key: Any) -> None: - '''Removes the given key.''' - file = ctx.obj['FILE'] - quote = ctx.obj['QUOTE'] - success, key = unset_key(file, key, quote) - if success: - click.echo("Successfully removed %s" % key) - else: - exit(1) - - -@cli.command(context_settings={'ignore_unknown_options': True}) -@click.pass_context -@click.option( - "--override/--no-override", - default=True, - help="Override variables from the environment file with those from the .env file.", -) -@click.argument('commandline', nargs=-1, type=click.UNPROCESSED) -def run(ctx: click.Context, override: bool, commandline: List[str]) -> None: - """Run command with environment variables present.""" - file = ctx.obj['FILE'] - if not os.path.isfile(file): - raise click.BadParameter( - 'Invalid value for \'-f\' "%s" does not exist.' % (file), - ctx=ctx - ) - dotenv_as_dict = { - k: v - for (k, v) in dotenv_values(file).items() - if v is not None and (override or k not in os.environ) - } - - if not commandline: - click.echo('No command given.') - exit(1) - ret = run_command(commandline, dotenv_as_dict) - exit(ret) - - -def run_command(command: List[str], env: Dict[str, str]) -> int: - """Run command in sub process. - - Runs the command in a sub process with the variables from `env` - added in the current environment variables. - - Parameters - ---------- - command: List[str] - The command and it's parameters - env: Dict - The additional environment variables - - Returns - ------- - int - The return code of the command - - """ - # copy the current environment variables and add the vales from - # `env` - cmd_env = os.environ.copy() - cmd_env.update(env) - - p = Popen(command, - universal_newlines=True, - bufsize=0, - shell=False, - env=cmd_env) - _, _ = p.communicate() - - return p.returncode - - -if __name__ == "__main__": - cli() diff --git a/venv/lib/python3.7/site-packages/dotenv/ipython.py b/venv/lib/python3.7/site-packages/dotenv/ipython.py deleted file mode 100644 index 7df727c..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/ipython.py +++ /dev/null @@ -1,39 +0,0 @@ -from IPython.core.magic import Magics, line_magic, magics_class # type: ignore -from IPython.core.magic_arguments import (argument, magic_arguments, # type: ignore - parse_argstring) # type: ignore - -from .main import find_dotenv, load_dotenv - - -@magics_class -class IPythonDotEnv(Magics): - - @magic_arguments() - @argument( - '-o', '--override', action='store_true', - help="Indicate to override existing variables" - ) - @argument( - '-v', '--verbose', action='store_true', - help="Indicate function calls to be verbose" - ) - @argument('dotenv_path', nargs='?', type=str, default='.env', - help='Search in increasingly higher folders for the `dotenv_path`') - @line_magic - def dotenv(self, line): - args = parse_argstring(self.dotenv, line) - # Locate the .env file - dotenv_path = args.dotenv_path - try: - dotenv_path = find_dotenv(dotenv_path, True, True) - except IOError: - print("cannot find .env file") - return - - # Load the .env file - load_dotenv(dotenv_path, verbose=args.verbose, override=args.override) - - -def load_ipython_extension(ipython): - """Register the %dotenv magic.""" - ipython.register_magics(IPythonDotEnv) diff --git a/venv/lib/python3.7/site-packages/dotenv/main.py b/venv/lib/python3.7/site-packages/dotenv/main.py deleted file mode 100644 index d867f02..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/main.py +++ /dev/null @@ -1,364 +0,0 @@ -import io -import logging -import os -import shutil -import sys -import tempfile -from collections import OrderedDict -from contextlib import contextmanager -from typing import (IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple, - Union) - -from .parser import Binding, parse_stream -from .variables import parse_variables - -logger = logging.getLogger(__name__) - -if sys.version_info >= (3, 6): - _PathLike = os.PathLike -else: - _PathLike = str - - -def with_warn_for_invalid_lines(mappings: Iterator[Binding]) -> Iterator[Binding]: - for mapping in mappings: - if mapping.error: - logger.warning( - "Python-dotenv could not parse statement starting at line %s", - mapping.original.line, - ) - yield mapping - - -class DotEnv(): - def __init__( - self, - dotenv_path: Optional[Union[str, _PathLike]], - stream: Optional[IO[str]] = None, - verbose: bool = False, - encoding: Union[None, str] = None, - interpolate: bool = True, - override: bool = True, - ) -> None: - self.dotenv_path = dotenv_path # type: Optional[Union[str, _PathLike]] - self.stream = stream # type: Optional[IO[str]] - self._dict = None # type: Optional[Dict[str, Optional[str]]] - self.verbose = verbose # type: bool - self.encoding = encoding # type: Union[None, str] - self.interpolate = interpolate # type: bool - self.override = override # type: bool - - @contextmanager - def _get_stream(self) -> Iterator[IO[str]]: - if self.dotenv_path and os.path.isfile(self.dotenv_path): - with io.open(self.dotenv_path, encoding=self.encoding) as stream: - yield stream - elif self.stream is not None: - yield self.stream - else: - if self.verbose: - logger.info( - "Python-dotenv could not find configuration file %s.", - self.dotenv_path or '.env', - ) - yield io.StringIO('') - - def dict(self) -> Dict[str, Optional[str]]: - """Return dotenv as dict""" - if self._dict: - return self._dict - - raw_values = self.parse() - - if self.interpolate: - self._dict = OrderedDict(resolve_variables(raw_values, override=self.override)) - else: - self._dict = OrderedDict(raw_values) - - return self._dict - - def parse(self) -> Iterator[Tuple[str, Optional[str]]]: - with self._get_stream() as stream: - for mapping in with_warn_for_invalid_lines(parse_stream(stream)): - if mapping.key is not None: - yield mapping.key, mapping.value - - def set_as_environment_variables(self) -> bool: - """ - Load the current dotenv as system environment variable. - """ - for k, v in self.dict().items(): - if k in os.environ and not self.override: - continue - if v is not None: - os.environ[k] = v - - return True - - def get(self, key: str) -> Optional[str]: - """ - """ - data = self.dict() - - if key in data: - return data[key] - - if self.verbose: - logger.warning("Key %s not found in %s.", key, self.dotenv_path) - - return None - - -def get_key(dotenv_path: Union[str, _PathLike], key_to_get: str) -> Optional[str]: - """ - Gets the value of a given key from the given .env - - If the .env path given doesn't exist, fails - """ - return DotEnv(dotenv_path, verbose=True).get(key_to_get) - - -@contextmanager -def rewrite(path: Union[str, _PathLike]) -> Iterator[Tuple[IO[str], IO[str]]]: - try: - if not os.path.isfile(path): - with io.open(path, "w+") as source: - source.write("") - with tempfile.NamedTemporaryFile(mode="w+", delete=False) as dest: - with io.open(path) as source: - yield (source, dest) # type: ignore - except BaseException: - if os.path.isfile(dest.name): - os.unlink(dest.name) - raise - else: - shutil.move(dest.name, path) - - -def set_key( - dotenv_path: Union[str, _PathLike], - key_to_set: str, - value_to_set: str, - quote_mode: str = "always", - export: bool = False, -) -> Tuple[Optional[bool], str, str]: - """ - Adds or Updates a key/value to the given .env - - If the .env path given doesn't exist, fails instead of risking creating - an orphan .env somewhere in the filesystem - """ - if quote_mode not in ("always", "auto", "never"): - raise ValueError("Unknown quote_mode: {}".format(quote_mode)) - - quote = ( - quote_mode == "always" - or (quote_mode == "auto" and not value_to_set.isalnum()) - ) - - if quote: - value_out = "'{}'".format(value_to_set.replace("'", "\\'")) - else: - value_out = value_to_set - if export: - line_out = 'export {}={}\n'.format(key_to_set, value_out) - else: - line_out = "{}={}\n".format(key_to_set, value_out) - - with rewrite(dotenv_path) as (source, dest): - replaced = False - missing_newline = False - for mapping in with_warn_for_invalid_lines(parse_stream(source)): - if mapping.key == key_to_set: - dest.write(line_out) - replaced = True - else: - dest.write(mapping.original.string) - missing_newline = not mapping.original.string.endswith("\n") - if not replaced: - if missing_newline: - dest.write("\n") - dest.write(line_out) - - return True, key_to_set, value_to_set - - -def unset_key( - dotenv_path: Union[str, _PathLike], - key_to_unset: str, - quote_mode: str = "always", -) -> Tuple[Optional[bool], str]: - """ - Removes a given key from the given .env - - If the .env path given doesn't exist, fails - If the given key doesn't exist in the .env, fails - """ - if not os.path.exists(dotenv_path): - logger.warning("Can't delete from %s - it doesn't exist.", dotenv_path) - return None, key_to_unset - - removed = False - with rewrite(dotenv_path) as (source, dest): - for mapping in with_warn_for_invalid_lines(parse_stream(source)): - if mapping.key == key_to_unset: - removed = True - else: - dest.write(mapping.original.string) - - if not removed: - logger.warning("Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path) - return None, key_to_unset - - return removed, key_to_unset - - -def resolve_variables( - values: Iterable[Tuple[str, Optional[str]]], - override: bool, -) -> Mapping[str, Optional[str]]: - new_values = {} # type: Dict[str, Optional[str]] - - for (name, value) in values: - if value is None: - result = None - else: - atoms = parse_variables(value) - env = {} # type: Dict[str, Optional[str]] - if override: - env.update(os.environ) # type: ignore - env.update(new_values) - else: - env.update(new_values) - env.update(os.environ) # type: ignore - result = "".join(atom.resolve(env) for atom in atoms) - - new_values[name] = result - - return new_values - - -def _walk_to_root(path: str) -> Iterator[str]: - """ - Yield directories starting from the given directory up to the root - """ - if not os.path.exists(path): - raise IOError('Starting path not found') - - if os.path.isfile(path): - path = os.path.dirname(path) - - last_dir = None - current_dir = os.path.abspath(path) - while last_dir != current_dir: - yield current_dir - parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir)) - last_dir, current_dir = current_dir, parent_dir - - -def find_dotenv( - filename: str = '.env', - raise_error_if_not_found: bool = False, - usecwd: bool = False, -) -> str: - """ - Search in increasingly higher folders for the given file - - Returns path to the file if found, or an empty string otherwise - """ - - def _is_interactive(): - """ Decide whether this is running in a REPL or IPython notebook """ - main = __import__('__main__', None, None, fromlist=['__file__']) - return not hasattr(main, '__file__') - - if usecwd or _is_interactive() or getattr(sys, 'frozen', False): - # Should work without __file__, e.g. in REPL or IPython notebook. - path = os.getcwd() - else: - # will work for .py files - frame = sys._getframe() - current_file = __file__ - - while frame.f_code.co_filename == current_file: - assert frame.f_back is not None - frame = frame.f_back - frame_filename = frame.f_code.co_filename - path = os.path.dirname(os.path.abspath(frame_filename)) - - for dirname in _walk_to_root(path): - check_path = os.path.join(dirname, filename) - if os.path.isfile(check_path): - return check_path - - if raise_error_if_not_found: - raise IOError('File not found') - - return '' - - -def load_dotenv( - dotenv_path: Union[str, _PathLike, None] = None, - stream: Optional[IO[str]] = None, - verbose: bool = False, - override: bool = False, - interpolate: bool = True, - encoding: Optional[str] = "utf-8", -) -> bool: - """Parse a .env file and then load all the variables found as environment variables. - - - *dotenv_path*: absolute or relative path to .env file. - - *stream*: Text stream (such as `io.StringIO`) with .env content, used if - `dotenv_path` is `None`. - - *verbose*: whether to output a warning the .env file is missing. Defaults to - `False`. - - *override*: whether to override the system environment variables with the variables - in `.env` file. Defaults to `False`. - - *encoding*: encoding to be used to read the file. - - If both `dotenv_path` and `stream`, `find_dotenv()` is used to find the .env file. - """ - if dotenv_path is None and stream is None: - dotenv_path = find_dotenv() - - dotenv = DotEnv( - dotenv_path=dotenv_path, - stream=stream, - verbose=verbose, - interpolate=interpolate, - override=override, - encoding=encoding, - ) - return dotenv.set_as_environment_variables() - - -def dotenv_values( - dotenv_path: Union[str, _PathLike, None] = None, - stream: Optional[IO[str]] = None, - verbose: bool = False, - interpolate: bool = True, - encoding: Optional[str] = "utf-8", -) -> Dict[str, Optional[str]]: - """ - Parse a .env file and return its content as a dict. - - - *dotenv_path*: absolute or relative path to .env file. - - *stream*: `StringIO` object with .env content, used if `dotenv_path` is `None`. - - *verbose*: whether to output a warning the .env file is missing. Defaults to - `False`. - in `.env` file. Defaults to `False`. - - *encoding*: encoding to be used to read the file. - - If both `dotenv_path` and `stream`, `find_dotenv()` is used to find the .env file. - """ - if dotenv_path is None and stream is None: - dotenv_path = find_dotenv() - - return DotEnv( - dotenv_path=dotenv_path, - stream=stream, - verbose=verbose, - interpolate=interpolate, - override=True, - encoding=encoding, - ).dict() diff --git a/venv/lib/python3.7/site-packages/dotenv/parser.py b/venv/lib/python3.7/site-packages/dotenv/parser.py deleted file mode 100644 index 398bd49..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/parser.py +++ /dev/null @@ -1,182 +0,0 @@ -import codecs -import re -from typing import (IO, Iterator, Match, NamedTuple, Optional, # noqa:F401 - Pattern, Sequence, Tuple) - - -def make_regex(string: str, extra_flags: int = 0) -> Pattern[str]: - return re.compile(string, re.UNICODE | extra_flags) - - -_newline = make_regex(r"(\r\n|\n|\r)") -_multiline_whitespace = make_regex(r"\s*", extra_flags=re.MULTILINE) -_whitespace = make_regex(r"[^\S\r\n]*") -_export = make_regex(r"(?:export[^\S\r\n]+)?") -_single_quoted_key = make_regex(r"'([^']+)'") -_unquoted_key = make_regex(r"([^=\#\s]+)") -_equal_sign = make_regex(r"(=[^\S\r\n]*)") -_single_quoted_value = make_regex(r"'((?:\\'|[^'])*)'") -_double_quoted_value = make_regex(r'"((?:\\"|[^"])*)"') -_unquoted_value = make_regex(r"([^\r\n]*)") -_comment = make_regex(r"(?:[^\S\r\n]*#[^\r\n]*)?") -_end_of_line = make_regex(r"[^\S\r\n]*(?:\r\n|\n|\r|$)") -_rest_of_line = make_regex(r"[^\r\n]*(?:\r|\n|\r\n)?") -_double_quote_escapes = make_regex(r"\\[\\'\"abfnrtv]") -_single_quote_escapes = make_regex(r"\\[\\']") - - -Original = NamedTuple( - "Original", - [ - ("string", str), - ("line", int), - ], -) - -Binding = NamedTuple( - "Binding", - [ - ("key", Optional[str]), - ("value", Optional[str]), - ("original", Original), - ("error", bool), - ], -) - - -class Position: - def __init__(self, chars: int, line: int) -> None: - self.chars = chars - self.line = line - - @classmethod - def start(cls) -> "Position": - return cls(chars=0, line=1) - - def set(self, other: "Position") -> None: - self.chars = other.chars - self.line = other.line - - def advance(self, string: str) -> None: - self.chars += len(string) - self.line += len(re.findall(_newline, string)) - - -class Error(Exception): - pass - - -class Reader: - def __init__(self, stream: IO[str]) -> None: - self.string = stream.read() - self.position = Position.start() - self.mark = Position.start() - - def has_next(self) -> bool: - return self.position.chars < len(self.string) - - def set_mark(self) -> None: - self.mark.set(self.position) - - def get_marked(self) -> Original: - return Original( - string=self.string[self.mark.chars:self.position.chars], - line=self.mark.line, - ) - - def peek(self, count: int) -> str: - return self.string[self.position.chars:self.position.chars + count] - - def read(self, count: int) -> str: - result = self.string[self.position.chars:self.position.chars + count] - if len(result) < count: - raise Error("read: End of string") - self.position.advance(result) - return result - - def read_regex(self, regex: Pattern[str]) -> Sequence[str]: - match = regex.match(self.string, self.position.chars) - if match is None: - raise Error("read_regex: Pattern not found") - self.position.advance(self.string[match.start():match.end()]) - return match.groups() - - -def decode_escapes(regex: Pattern[str], string: str) -> str: - def decode_match(match: Match[str]) -> str: - return codecs.decode(match.group(0), 'unicode-escape') # type: ignore - - return regex.sub(decode_match, string) - - -def parse_key(reader: Reader) -> Optional[str]: - char = reader.peek(1) - if char == "#": - return None - elif char == "'": - (key,) = reader.read_regex(_single_quoted_key) - else: - (key,) = reader.read_regex(_unquoted_key) - return key - - -def parse_unquoted_value(reader: Reader) -> str: - (part,) = reader.read_regex(_unquoted_value) - return re.sub(r"\s+#.*", "", part).rstrip() - - -def parse_value(reader: Reader) -> str: - char = reader.peek(1) - if char == u"'": - (value,) = reader.read_regex(_single_quoted_value) - return decode_escapes(_single_quote_escapes, value) - elif char == u'"': - (value,) = reader.read_regex(_double_quoted_value) - return decode_escapes(_double_quote_escapes, value) - elif char in (u"", u"\n", u"\r"): - return u"" - else: - return parse_unquoted_value(reader) - - -def parse_binding(reader: Reader) -> Binding: - reader.set_mark() - try: - reader.read_regex(_multiline_whitespace) - if not reader.has_next(): - return Binding( - key=None, - value=None, - original=reader.get_marked(), - error=False, - ) - reader.read_regex(_export) - key = parse_key(reader) - reader.read_regex(_whitespace) - if reader.peek(1) == "=": - reader.read_regex(_equal_sign) - value = parse_value(reader) # type: Optional[str] - else: - value = None - reader.read_regex(_comment) - reader.read_regex(_end_of_line) - return Binding( - key=key, - value=value, - original=reader.get_marked(), - error=False, - ) - except Error: - reader.read_regex(_rest_of_line) - return Binding( - key=None, - value=None, - original=reader.get_marked(), - error=True, - ) - - -def parse_stream(stream: IO[str]) -> Iterator[Binding]: - reader = Reader(stream) - while reader.has_next(): - yield parse_binding(reader) diff --git a/venv/lib/python3.7/site-packages/dotenv/py.typed b/venv/lib/python3.7/site-packages/dotenv/py.typed deleted file mode 100644 index 7632ecf..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/py.typed +++ /dev/null @@ -1 +0,0 @@ -# Marker file for PEP 561 diff --git a/venv/lib/python3.7/site-packages/dotenv/variables.py b/venv/lib/python3.7/site-packages/dotenv/variables.py deleted file mode 100644 index d77b700..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/variables.py +++ /dev/null @@ -1,88 +0,0 @@ -import re -from abc import ABCMeta -from typing import Iterator, Mapping, Optional, Pattern - -_posix_variable = re.compile( - r""" - \$\{ - (?P[^\}:]*) - (?::- - (?P[^\}]*) - )? - \} - """, - re.VERBOSE, -) # type: Pattern[str] - - -class Atom(): - __metaclass__ = ABCMeta - - def __ne__(self, other: object) -> bool: - result = self.__eq__(other) - if result is NotImplemented: - return NotImplemented - return not result - - def resolve(self, env: Mapping[str, Optional[str]]) -> str: - raise NotImplementedError - - -class Literal(Atom): - def __init__(self, value: str) -> None: - self.value = value - - def __repr__(self) -> str: - return "Literal(value={})".format(self.value) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, self.__class__): - return NotImplemented - return self.value == other.value - - def __hash__(self) -> int: - return hash((self.__class__, self.value)) - - def resolve(self, env: Mapping[str, Optional[str]]) -> str: - return self.value - - -class Variable(Atom): - def __init__(self, name: str, default: Optional[str]) -> None: - self.name = name - self.default = default - - def __repr__(self) -> str: - return "Variable(name={}, default={})".format(self.name, self.default) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, self.__class__): - return NotImplemented - return (self.name, self.default) == (other.name, other.default) - - def __hash__(self) -> int: - return hash((self.__class__, self.name, self.default)) - - def resolve(self, env: Mapping[str, Optional[str]]) -> str: - default = self.default if self.default is not None else "" - result = env.get(self.name, default) - return result if result is not None else "" - - -def parse_variables(value: str) -> Iterator[Atom]: - cursor = 0 - - for match in _posix_variable.finditer(value): - (start, end) = match.span() - name = match.groupdict()["name"] - default = match.groupdict()["default"] - - if start > cursor: - yield Literal(value=value[cursor:start]) - - yield Variable(name=name, default=default) - cursor = end - - length = len(value) - if cursor < length: - yield Literal(value=value[cursor:length]) diff --git a/venv/lib/python3.7/site-packages/dotenv/version.py b/venv/lib/python3.7/site-packages/dotenv/version.py deleted file mode 100644 index aa070c2..0000000 --- a/venv/lib/python3.7/site-packages/dotenv/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.19.2" diff --git a/venv/lib/python3.7/site-packages/easy_install.py b/venv/lib/python3.7/site-packages/easy_install.py deleted file mode 100644 index d87e984..0000000 --- a/venv/lib/python3.7/site-packages/easy_install.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Run the EasyInstall command""" - -if __name__ == '__main__': - from setuptools.command.easy_install import main - main() diff --git a/venv/lib/python3.7/site-packages/flask/__init__.py b/venv/lib/python3.7/site-packages/flask/__init__.py deleted file mode 100644 index feb5334..0000000 --- a/venv/lib/python3.7/site-packages/flask/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -from markupsafe import escape -from markupsafe import Markup -from werkzeug.exceptions import abort as abort -from werkzeug.utils import redirect as redirect - -from . import json as json -from .app import Flask as Flask -from .app import Request as Request -from .app import Response as Response -from .blueprints import Blueprint as Blueprint -from .config import Config as Config -from .ctx import after_this_request as after_this_request -from .ctx import copy_current_request_context as copy_current_request_context -from .ctx import has_app_context as has_app_context -from .ctx import has_request_context as has_request_context -from .globals import _app_ctx_stack as _app_ctx_stack -from .globals import _request_ctx_stack as _request_ctx_stack -from .globals import current_app as current_app -from .globals import g as g -from .globals import request as request -from .globals import session as session -from .helpers import flash as flash -from .helpers import get_flashed_messages as get_flashed_messages -from .helpers import get_template_attribute as get_template_attribute -from .helpers import make_response as make_response -from .helpers import safe_join as safe_join -from .helpers import send_file as send_file -from .helpers import send_from_directory as send_from_directory -from .helpers import stream_with_context as stream_with_context -from .helpers import url_for as url_for -from .json import jsonify as jsonify -from .signals import appcontext_popped as appcontext_popped -from .signals import appcontext_pushed as appcontext_pushed -from .signals import appcontext_tearing_down as appcontext_tearing_down -from .signals import before_render_template as before_render_template -from .signals import got_request_exception as got_request_exception -from .signals import message_flashed as message_flashed -from .signals import request_finished as request_finished -from .signals import request_started as request_started -from .signals import request_tearing_down as request_tearing_down -from .signals import signals_available as signals_available -from .signals import template_rendered as template_rendered -from .templating import render_template as render_template -from .templating import render_template_string as render_template_string - -__version__ = "2.0.3" diff --git a/venv/lib/python3.7/site-packages/flask/__main__.py b/venv/lib/python3.7/site-packages/flask/__main__.py deleted file mode 100644 index 4e28416..0000000 --- a/venv/lib/python3.7/site-packages/flask/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .cli import main - -main() diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index d4645d0f8dfdd580cb25877f8cf0c84977e0fdb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1887 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 aS^pFYzLvumM)4W`53fw~`DAMBgZ~SIG$%g* diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc deleted file mode 100644 index 4cd58a030c163f9bb4df8d583cbc5836fd0ff40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26861 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/config.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/config.cpython-37.pyc deleted file mode 100644 index 4f0b5a85223b2ae9cfc70db528ecd6dcf9ffa0f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11610 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 C#|kk3 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/debughelpers.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/debughelpers.cpython-37.pyc deleted file mode 100644 index 85ee0087025d6dbd80b809db9cf758445ad278f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6435 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/globals.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/globals.cpython-37.pyc deleted file mode 100644 index 9a04b2c05a4dfe431d76acec368f3e97cb4c851d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1828 zcmcIlOK;;g5EkW^?D&y~<2-gzu!jP5v9%99^b+)Cq`O7iAlPKFs4fC6j%~%1sFG9? zFVaiXztJDi-_U;|^j4t2{)L`8l$`7a-CI%091dqjoNpeYzv^^a4vt?dpNGHK9p_KG zxf@kvzQC#fLh{1l4kyC#39hbiDVJb^P6e z4xk48TjKBWZP@2KM-J{Qu+96oE=mvhE=v3N(m^3TFW{SV9@9E`dHfKR>=_h)29a8fGpSlpf;28wY>KGqLS9+N>{3REz#>hRoC=6X z?0wA4I|5{BDlnAd`2QhD1QTKA)Qp8duOhQ3q6#ymFev)Ab2+_$(4aNdGDcgr8qsr! z8*vFO8_E-^!O$$FHgW$(U7n7L5zb&8%7;VD=NW+Y+IpBvOdXA-0`z#F#ZhS6#|{@~ z1?L2(rbvu)L4G1P_^mBHH88HJ+>)P(soszq=hnqOB`3pLz8$O^CJ4=SplwIy6(iHU z{X9!d6vMGnQsw;zW}s9M>v`Uo1J>E7p_^9|7K7SAzrQ(Z6PLgJ@e2(~kEe=p0V^?H z;MvS9WHJsH5H7L$69vq`_!5%Kv52PQbY<0_j6NOf$iT;`ePIrIJhPw1cwT-GqjZI+ zg_O%IwWxx!4)38)?ICeUop|`DZRG!Jdb&YTo4eE$0jf40oNwN1*4a>96c1h1!=<#d zX()1`w(J}CpzV<*=nqi-5cDoeLY&30wY7CEYWf(NqNdIb-kERL^v1cUuIs6G(CQ6J z)yHjKL5D-~PE5^U7A4$<@&qj(LfNxN;f3zx8|(JBc6npnFsf-)4PD+%%BDUibJf6g z_&BfI3n!W9#N^H5Mv+ozWrOj%SD==!Ae)bby%Uw~T4nzz^3M4Wr^mtM+41DtZ%&@7 zfmIX$D%hOG$+@@or%Q+4l|oF|W(6A6v2WOzi{dMrOjU$o|Dnp<>?4==f`BE7EH5b? z1nR)*4=s6Q$(za*Tv0ynD3&}E@R_ZO{s@Wdc%<#Nan=b^`*>BaTJakAcy;WAU{`bwKbR diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc deleted file mode 100644 index 9c92d070e573fb3911416786d823e9898be39639..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27033 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

OQn7NOgM{a=Y1KdN( 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc deleted file mode 100644 index 014dbb20bcec38d1b55478faf32f85d00a129961..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13590 zcmbtb&2!wybsu0b9~^#D6eaD-Yj}4PiMDoVXI+(qUVq3m<)yu%WRV-&vz5$%1CRuX z8O$~?q&T6Hl(l8&;v90w#k*BfRdVpfhg?#rN~LnhCHWI@^~twXC8y0Lzu#*BGeeH# zbp;Z7fbK^3>-YU$H@`hQTPxuDr1;JD-q#C-U-KoqN_hAd?&!ZzxCPe;3Jv{hG)#Ff zHj4N)1FKVNlnk~NgL0?bD9f`IR65m0Rh~{=2p;s-q(phdSORwqRYGGk~X0cxtQ6MM1W@$fwJZO7g554uj=SA1W2 z|IvFp&c3&cW_QO^z7zNZPqF8Q69jus`}jM4JN}J<(NS6Qqo&`(!}6|kaNxP$+j+1( z_EqU#;6%r(W>R_Nec1P+IH^AJqF&gIyfz`sE(;Ie!X14Fg;!`8ZUIy>8b#0YO0M~_ z;TB!%BkQTrD0}6j3hGL3`C}814y$_0&Z*W3~?P)lZZyeRU+?tTBU-yOWY`MBqF z-N<(AJty+pwu^P3)lp~msUIKOk?w6fajg8ke(XhcEUc_Npr+gAf_d?mz;57B0L zo`Jbs^SOyhi-Wg!5Bc}C=26e3?S)~mYN|!N zs;exxNL^gv(=v*ixHT;1z1`L6q}ptDosQRR0$yrdj?aqOw2*!516Dn{`4ea}s*PP+}-d+rDj0**j3i_Zy7#3fY?%QTGz z%QBYAR>>+UwzhHS7u620=qD&f8QC=(7VZ*+8w^Z#{@DCkVc#Gle>B^udQ(zgNo&E( zAI*T37j(U})jlrD7t`(xzL)#ek=_d>PeiH5-@kcP1;;2VU2O00jXCh=r%u zDM9P448JWKVke)b4H>%8FcdX=E4JHCw;RR~p1_C3I4|h8IoHe-lve_|J z5!!AXrJ1dhbh8Pi2sPGeHZ#5P`)B~Fevh4o z@_Gxe_i+#L^ZCgT4#z7h4wY0~Z{O($v4)n=@#1gJ0aOIz(30|(;Z-DahExu&ZnNSN zu za@J0aI4R!ko+&a?QjB7yNHD>d;ZZ zudG-%EycDr?))P4zJ+^&Z*f%etRwgrZt-I%WViH@MgIb-vx2*ddkS|A_cZRA#_R`W zw+w1mlIiV!5Twd<@b?>{MEg{macCcST~9$u?XKU3-tv@!cJ08z(E8f`{!r683Z24O zl#p}c_yHZYx^4eZ)M?BTPFHveRpz*FgZoxr586 zmE2%D_UhZ=BXMU|i;3l^gD5E^(VOw~8h}+~j1f~#hDl0IBBh1LRMbpkusA})y0mYvPG;XP za>OsO_yZJFMp%nhMtpH$utYN@rFP&sa4>pdFR7qlbyC(!TiAO9uA$1RW6%cfsEVR$ zS>{URrlD9n#>aU?^FL@AbuBy#ZiU$>yYQCjR)|YsH7XvQ3KtHAOJ~A@Gg0)WrM>1( z<9!D2vqy8@^o@elG8VBK^La1EB35Go?^DvwNW^L^=I@L|EJQfjsEk6a#udCT%eYrD z?h54UntL7fD^fotH8P;(7V(5upO89i^J=jYtlP=B30-OszW`-P7!_jUIT)ZK7x z$laUCLMn4xT{v?4PTO<7S}qjGj@qgBvwHh1?8EY(cw{BN(+j)~yl=YQp>iRWs8wDs zzzF0$5uH>&4jDTi>-5lXAKKvR$UgPd@xbdJ+#)~IuhQO;43JMFJPckZTq3pPg$goYoDy zw_^BAT1T}Ho$i5`yL3Zo4)=}_xBxeddeCzdrv$TmL0`v3sfX?Zs}$`NM}moc6?XKz;)1NVQnE`Z*P@2>0Af4rfT*s0)Q@62 z>hDQkDhxfnjKq;0*JW*d=)`u1!QlG3_GRhM%16*jg6`Xl$L?frGTZ99jKi+HdT^KZ z$6Nc8v7%8I*{#-g*oBX2O9-r8WO!l$QK7MwBDLcjd(AHFNlsgGCsZeGh?BFUfbTG< z1in+=B~J@@uqq@|$~8bnuNSJ^qdpDQajuxDSMmLaeIE|8$OK&J)Chrh_F;8AH)Y;T zB-T?hjA+bOia7xb-nfQWJNgn1fI5&biF1K>4c(YMps!Dxkj52b0-3L5$TzSG4*riA z2_kb;qFjwu00aDiP6%JJfIwp2x=^B?A_=Z<%95>7e!v9w*EP*_XKj zGzDjM`-g{Kcc{`dzcUufh@Y?P4x*lJ1bI{fe-=p5nTVhU?NbH&B*-E(jO9336o+t2 zI+Q8GbJlGis<4YJkgFYuU1%K0GnvLd=sU{6imB#gNm{vr=vwh;s*7kzjOjV;LxF|- z2V`&zEp^*@pi?<2C-lIRaYhjFV5_lG=9g6{hVeYlrcQa+Bj zm?E;kCxc!(iav-;{KF)`34M%s&-c18cbS96wxe**4n=k3V~s6Ii&7+>Xa-+^bU?o+ zT#Td>Aktz^)`9bxkE6qX?al#JU>Tb_ZgxeoG=_-o=vE?!dB zpO8t&Err_P^@~cNeyKYd4$N?w;ffeR7*0Ff$SD+#jHiq(jlq9zFvTaagJU1~$nfP1 zb&(6f1ys@*QwrvD)RC!>`vVEUOcZVk+$GfJbCE+b#{C^ooliFrT6ha zhHqr>FX4M03Fc7>{StjNwkw0oOy?@MexdVNYLeL)!7uzpBqonUoCiPA@sO4j<`7eH z$nXdDX4-57NAE+;!nThZ0^LWFlQ8#M4M1{W+lc2@YiDz3XY0XsbK}8-?{953x9{HH zY_)PMfeEjqs=GNdQihdDTsV(}z-Zrp%&}6MfRziKbF45fCNcyo|B_2yyA$d}=%?o)^{MvcEgcK2W@6W`x|CV^jU=ycqq8WB#J> ziAfkU2ngZotaBeE9wnz6QWZi6!e&H=qE*GfB0z?*88uBWBJu^oedodbyIb2JG1NGW z6iA$@W11~-#ZUc6JK|I?`*2X0PDK(EeBgR9JZq{+PMrdm=UT}nkN#xyQOX@74EKP# zO@9o*y$#SYed;?QgUSp6a-WyDYzVA2lmtizq9XmyN$9&UKyRsjx0?YKga>|ms2-E6 z6A`eTOpm~N?^9!4Rlq%p5|$YCfvcSZKxSi`0JCWHrb`z4F5U%@7n4AaeXD+}Zr^p` zsdr(+w{YTUGbUWY15nP(gp)kah>;6c*?Dq-x1>11zfIY z6!6zy0QjfI8nR4f&0pArijW$KlX8HBncqvQNZOESQDX5)F>jEJDutdCAFf(Dr%MHr znCc`k{oW;WHliCeCjS||Bj!5_wVG8mX3SdAGHQlpt(eG67)utO&8le`mQk)Q88x$J zOfY+whRu}@EoJUoF`cS~_(q|(Bv0lID(0etbo!Vub49`dL&q{D=TNkT+jQiTYu7A- z8IR3%EKfONxiJ) z-re1O_+b0JA5SFF2p+Fpz+?8^Z^vA6WrUeC`2RP@WNGl`j?Ntn-H-_%d`4{k%_MAI z!lF(*W&VDSyBwR65Bcmk+}YfC{}DVAIxNF{F?sZo0nlAP1JV{paG=4ZKx^i+Uam0G zw3@ioK=YWwxWs<{t`P>txU~b-*p~fum`J?8=RD?Sd&-jINYsX6XsIFg@cniW4&#e_ zS2DE-If7rzoH^>rvFq5PbC9wc_xg6=_3do!Zcak;MefY{eg;I3a%Y4!aH}7OR#H^| z7VgYGK>A#)L?yM9mv_K&mCcQvbMpv0^s({Gd`@Lhyatu+%C4P*b2Np!64@c>O!I@{ zfMx7R3;($1>j2i~X68k2EXSpgG0mY}P%N|eK|8T;__uV4}=2QzQs`EY{UH0ys07zYyre=%#ys4PmtyMn%ThF7KZry zKjN3NL6GkfXgxHUh5$MpVkTF`puqmi42 zUcjTxdyh7E-feE)-FUb8X!8f}Z|=~Jr)~fSiDC9G%$E=41gFlK-uJqgzF>?^82S;; zt{__z9s9i=oy@T%+T1q7?h+!0(J*~dQtK;U$)`lEe>i z#w0pWl_r%X0Voj+d<5nfv-}{OvVA0YbF}pOk?batz*+i{A&B=F{@b1henZyNiQ9Q6 z9EBSR!(?`eTeR9>@Q@})(uhCXWMWEYc)08>Zhz!J;6t{# zE&?JM_7srJZKNRjUCd0SDoU5xL&kPGhla)+4vA#IooTovI{?Tjoq{=0eN}*%hh86Gin6oGz(Y=EBUv)Iw!teWAKgStu`5En~U1w1{%PY{(aF zbk47Qw?07C=x#j^0(vDL+QVtqs#|PKd9}v0htnml<;@+{hVzy@+!u zRjHpr{SBaQVnz9-a*Pl;|uj&aC-RG3k66 zH-Tun#3nNfa^Wj^-+rk8HY5rcn{{ZL4GS8GqDak zPCMO%(elT`Jb9o*=OoWg@<<26&Zx%oaxrt`ChnqZ{2ZCUSTc!tFX1jTclmRRNdzA2 zo5KMU9MDkyiENo9v#yU*IB`?^raT7|IYG?xQQ2ANWLC~Ss-`{~gER~pxpB#}Dv3qS zt_}c?I%GjIE1$&?iZLgS3^c-BvVX9`xQOFJs9{jEIX|Ebk^KtAGBPWsF^6NO%&}O; z;O&#Ib(%JR%;!*Y7Ixh)L%ItMs=2_{*)ex>6)ZsKs%YE5+kOj6OD66sT66m`%h90v`W0VEVF@0V;pUP({{#^c60&<5FuvSvm>BPihE{P|v5k-4RHH$ct@`gkQ ztL3C3;fWU|)hxTB$dc-e#el`1qgY+kI)A9-hx(oVECgHprzoCAZ({MXJNkc|bD#c6DZiadI1&Slk|(1e*E_0{Mi+35%gYp~#Do8IY&G ziZ}99`VZMu%KAdlg3QmDGsvsfj2UAYb>`T=-@ZV{3PZ0jDNVIC;T33=G!460Qu{UsP62w6@5K1 z@Qs;K10-rdz)P-W=eFt;dt}l3ZT`heq-bJ*3~WUsr7wx}MwKhC$IgM8V&m-Yj~{L} zH{RXc`2N=Rcaud8P7`5+hr<;(V3C*zGsJ{k})YpSWoU z?8#%8`VUwH5nfIbZ+!xkpZk|V5_m)eN%$QpJ`9QMEMxVRNAM@YB>a+yj)>k85#9Jn z0K2Z}!LA3p=m%2x-xC?!kfbZSzxKqzZ(efXs2Hf&QGKBLjv4?paMTc}p`#9gI&{<# zP)Cj$0X1^e7^tzMj)6KB-V1Vi=P&SroS%C3;GADdz2d3-=4pz|c65Mv3{$@kiv(u{ zNqiB>K!z_nGI#)vi{R%#grf7dlSEE!SNR}(Zu{&hU&p@%Y3dv*eHD1??hoh{!XUfYN_;ernt!E zI-f3hy5we27SnVg(`8wiCrWZ7r&qGLn&#PTx?1D$2a}JcIy3SNJYVt)si*Ut>m~5; z&3dw0+o-1dU`L}{#M_LvU`^^nd}G)47()*kvoT|rrKobG2aLU{c;1`@+9>N8+k3t; zSqU~2dh5K{Sq_kg#_-Tt?RjpW!hSopp?M9gZD_nC5PccS&dW%Kx5Co}Zm*ppg0Nu* zhLC5s`3E8fek|jVBz>3zm_x{}81f2vqh$PJEHFF+7aM-;5%O$KXL(jErJ|XpRl%=# zmh)LIAJNpoPdS}KM$i;M*7Q0v3u+dUYCtWf&BzKP)f^HLj<}&b&&z8~wJbzdT+nh( zo7m7m5+1g?NBh+mhLR0UoBihET{E zIt0Q%SG@rQe)643|9tcOg)2u$tqZEF)v8nwj=cn!SuvMr5E<;?#xS(U| z2p0^sI)=ptpA~C`fl~Ky+fB=&kf}-f4Z*H5o(!6e6wH*#eIqZyeXg>6&Gt@Wk?B^! zc)>MOGL_jCbVW8VRWjV$?u5$)&h;CNI6hP33wxc=e>c1z+>b_H=t1|v)6E#o=g>#b z6ogPJDK_uSBD9r_wdb%{{(afqzE6Heh5&e!O$As+{6IR=HY%tt0rlX=w0g*x$kU=^Y!H^$M)I zs3hGcX3Z3nacX9&D;`QpGxdaRLhE!=Lg0px3JY=ce1U@bPb#fCN5*cKbs zVq;ru;F9wd>i@d1hz)3S*sv`&b_bh%`5howjg8%7Ic#i;4QsIZuk5hBkLxemCs?=o ZJxmeb_Xd8?JA_&|3{M_Lo!Gnm`v-|Pc>n+a diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc deleted file mode 100644 index 435074f2aae462e26b95d213de7fcee12f5c932e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5497 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc deleted file mode 100644 index 1d50c03ed38de79a80b8e91c478579abb0af5e76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9164 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/typing.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/typing.cpython-37.pyc deleted file mode 100644 index fec89998d58060aebd75e47e55908d74fd29bb0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1411 zcmZWo&2Aev5MF9m(n^*r*_P$XNmDmzoTxuqpe@i#(biHNJ4oOdwwxlo1k`dQZ%yrP zNv<9B9r_4;fWA*py!Mn==&8fiPYrhk4radZo8fRs_3QPjgWn(SkKwmv$NAd^%g;yW zCtT_;;yB#lL^zZH`K2Jg#;73NsYg9x8CMjiC0at?<3&-P`qU>5Dl5E%wu);FYG~`@ zLdW9k7UhJKvDZVa0qupd1r6A^?IVMAd1YM0>N}|Zh*zP**LdxBm+oSG&-Ov@qxUf{O$aa9 zZ2G{)6P!sNeKL=7^$zZD6?+!Tkxx4g=FOE4SIS!x$@Pyc!^>#%DbdgF#E%#8ey)CE zBb?LINnugBn(7wXAst*kU{f z%R@ZV8zxO@;JrSTNeD_Ma;Y%w zrQ&%cu&Mv!M{PQ-rz&EObkz}ZuiQtljS4>|faS&cYc$H*&AOX)ATtj>v zh-eg~GfRKd`z}zChObhaFaZ^e1yfhS{K588yq52$3C{%lVE+=TkH&XPq-KAvM+(Fv j>!e-q(BH$g?^(>U>%@1Pg(_*H*CK7Qi=Op2$pi8)XPK0u diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc deleted file mode 100644 index 5932c90cf6de8e6dceebb1c2d63fcc56f26570d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5012 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 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/wrappers.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/wrappers.cpython-37.pyc deleted file mode 100644 index 2f0b3cde6f440f4445499cb7fef262dcc6d730be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4991 zcmai1Ta(*J6_#ZAI-Z*+w^<-1AP`)&v9k*lsi|+AS8d?P6JOFGS!d^0HbE9%+AbG2W?bD35A zdeG=M)N|Ee3Yz_wYWP=x^xSBaJoK(o2mk@ybc5 zU&ecrE#rNe*YI9t`ZKM)@-<}AdTl*vyyvi8{_%{*5^vSh$J#EBr%@R5uXQZNH*-IZ zLi{heGa+~=ZD%^g>s33R`ku6h{)|tBhxw@^C$xTd=5v?$5~{R*${*H~#&<8@}tOvRPJkhO}(#gYOMN7 zXEj!TX`bl)RyN4=lmT?+naDpq^h-|;XZezHH$g3hI5PYku&q9<%QP!z7rpGENhns zJQ#8jTXMo17OudN?gZ<3$fgk#YdIma4n2NkIbu8uV1l^QP%C#pDYlL#j-CoDkBIv^&K~53g(vzP3v7JwBp%Nk%g3CNfO0e zDj~KUDMi68JyyokR$B(d3v@(5BoqGNMcJI;NV`#KH6b|$G-0w~t_W%(bgZUODa~8 zMlR~`GUJdsav=!;$tqJvNFwSK3M@#zO)7&;NqNd8-fY)XdlqCau`7!JAjCA}E{|hJ zcnDcVSy@V*k7O()0OZC6L05$pQ|{2QfZ>5NhjSfbJv<9Ep(dte7QE1z@}1MO!T2NS z5;#uGQlwH2kmwyjhyzC;8z&7xit!XS8L2DK`~`nV>V>FJ@HMVs(3%xvO$zVP zYtA`Ffo*SL&l$(4iPjiyAmJt_RC^eUfA2vjXU;^T$8U55WV0hjAgjpp0I-SRsl!;WIUZ@e;BmRPobk<0$2tUjBCH+8INRE? z-tFA&yi*XMNW2b(2vQ}UDF_pjPJB`IjnjkJSd{9%Q88+|X)Ic=={`QE{30svW2@A@ z)Q`2VbX}8%xF?PMlDG$hn26H!sT|)!DO2(*LG=@?I>zb~{4Y<9_c={kpS-@ycu^bJbV7!3v&{F<{WLqEz+r%E#;spHd)mvYzAdX=QYlz`3j_tR$dC1HnxHhC4g|@`wJ5Zy z)K-#HQITezKj2%6(l{fc@n(L)%a^w|lbUUlpV@ZOux;cC6fJme+V;mY$Irf0ZJR}| zZ41iC$&%umE=}`?E|c0*Rna&;jA=U|;7(<+7@L-8lle>7Jt-kWC8Y=9Tr_F2zMWS> zNevYl>?!9-2}P{fz-I+XDl8K731U)g(j?hakj~F&MCnFlD)Mj&p75)aZ+Nn#FF3!qdbaTHpJbK;xfz=-XwL>RFfKiH1i93M-$ip9S8LVL}pBe#K~#Oa($0dSD^)hMrzpzH8SPB zN#26N1IjnKM$+OrI`Ft1dka2DD}hB_@)xo@k%5o;PXQg(1a#3qArXbuCEW%Uyyjck$3TUkr;^n;yk``J!^`&>JcHm9WAXPoDfetKCmms&7u0ZvbW{C@Y7N(CT*TIDoTLu=x?Tz9P-2Mx}~I zrL?%QoB8ZTG22VxyI3o3(eOPQzK%O3@-QmTn-Wj zQc}Al6aW$e{SkLeg?()e0EnNVD`aY4Nh(OBa5X_?d9qO`x#&n^m3Wf%;!EDADYO*d zz&1sy-^|ac61bLThU(alhK?Vntz= (3, 8): - iscoroutinefunction = inspect.iscoroutinefunction -else: - - def iscoroutinefunction(func: t.Any) -> bool: - while inspect.ismethod(func): - func = func.__func__ - - while isinstance(func, functools.partial): - func = func.func - - return inspect.iscoroutinefunction(func) - - -def _make_timedelta(value: t.Optional[timedelta]) -> t.Optional[timedelta]: - if value is None or isinstance(value, timedelta): - return value - - return timedelta(seconds=value) - - -class Flask(Scaffold): - """The flask object implements a WSGI application and acts as the central - object. It is passed the name of the module or package of the - application. Once it is created it will act as a central registry for - the view functions, the URL rules, template configuration and much more. - - The name of the package is used to resolve resources from inside the - package or the folder the module is contained in depending on if the - package parameter resolves to an actual python package (a folder with - an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). - - For more information about resource loading, see :func:`open_resource`. - - Usually you create a :class:`Flask` instance in your main module or - in the :file:`__init__.py` file of your package like this:: - - from flask import Flask - app = Flask(__name__) - - .. admonition:: About the First Parameter - - The idea of the first parameter is to give Flask an idea of what - belongs to your application. This name is used to find resources - on the filesystem, can be used by extensions to improve debugging - information and a lot more. - - So it's important what you provide there. If you are using a single - module, `__name__` is always the correct value. If you however are - using a package, it's usually recommended to hardcode the name of - your package there. - - For example if your application is defined in :file:`yourapplication/app.py` - you should create it with one of the two versions below:: - - app = Flask('yourapplication') - app = Flask(__name__.split('.')[0]) - - Why is that? The application will work even with `__name__`, thanks - to how resources are looked up. However it will make debugging more - painful. Certain extensions can make assumptions based on the - import name of your application. For example the Flask-SQLAlchemy - extension will look for the code in your application that triggered - an SQL query in debug mode. If the import name is not properly set - up, that debugging information is lost. (For example it would only - pick up SQL queries in `yourapplication.app` and not - `yourapplication.views.frontend`) - - .. versionadded:: 0.7 - The `static_url_path`, `static_folder`, and `template_folder` - parameters were added. - - .. versionadded:: 0.8 - The `instance_path` and `instance_relative_config` parameters were - added. - - .. versionadded:: 0.11 - The `root_path` parameter was added. - - .. versionadded:: 1.0 - The ``host_matching`` and ``static_host`` parameters were added. - - .. versionadded:: 1.0 - The ``subdomain_matching`` parameter was added. Subdomain - matching needs to be enabled manually now. Setting - :data:`SERVER_NAME` does not implicitly enable it. - - :param import_name: the name of the application package - :param static_url_path: can be used to specify a different path for the - static files on the web. Defaults to the name - of the `static_folder` folder. - :param static_folder: The folder with static files that is served at - ``static_url_path``. Relative to the application ``root_path`` - or an absolute path. Defaults to ``'static'``. - :param static_host: the host to use when adding the static route. - Defaults to None. Required when using ``host_matching=True`` - with a ``static_folder`` configured. - :param host_matching: set ``url_map.host_matching`` attribute. - Defaults to False. - :param subdomain_matching: consider the subdomain relative to - :data:`SERVER_NAME` when matching routes. Defaults to False. - :param template_folder: the folder that contains the templates that should - be used by the application. Defaults to - ``'templates'`` folder in the root path of the - application. - :param instance_path: An alternative instance path for the application. - By default the folder ``'instance'`` next to the - package or module is assumed to be the instance - path. - :param instance_relative_config: if set to ``True`` relative filenames - for loading the config are assumed to - be relative to the instance path instead - of the application root. - :param root_path: The path to the root of the application files. - This should only be set manually when it can't be detected - automatically, such as for namespace packages. - """ - - #: The class that is used for request objects. See :class:`~flask.Request` - #: for more information. - request_class = Request - - #: The class that is used for response objects. See - #: :class:`~flask.Response` for more information. - response_class = Response - - #: The class that is used for the Jinja environment. - #: - #: .. versionadded:: 0.11 - jinja_environment = Environment - - #: The class that is used for the :data:`~flask.g` instance. - #: - #: Example use cases for a custom class: - #: - #: 1. Store arbitrary attributes on flask.g. - #: 2. Add a property for lazy per-request database connectors. - #: 3. Return None instead of AttributeError on unexpected attributes. - #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. - #: - #: In Flask 0.9 this property was called `request_globals_class` but it - #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the - #: flask.g object is now application context scoped. - #: - #: .. versionadded:: 0.10 - app_ctx_globals_class = _AppCtxGlobals - - #: The class that is used for the ``config`` attribute of this app. - #: Defaults to :class:`~flask.Config`. - #: - #: Example use cases for a custom class: - #: - #: 1. Default values for certain config options. - #: 2. Access to config values through attributes in addition to keys. - #: - #: .. versionadded:: 0.11 - config_class = Config - - #: The testing flag. Set this to ``True`` to enable the test mode of - #: Flask extensions (and in the future probably also Flask itself). - #: For example this might activate test helpers that have an - #: additional runtime cost which should not be enabled by default. - #: - #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the - #: default it's implicitly enabled. - #: - #: This attribute can also be configured from the config with the - #: ``TESTING`` configuration key. Defaults to ``False``. - testing = ConfigAttribute("TESTING") - - #: If a secret key is set, cryptographic components can use this to - #: sign cookies and other things. Set this to a complex random value - #: when you want to use the secure cookie for instance. - #: - #: This attribute can also be configured from the config with the - #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. - secret_key = ConfigAttribute("SECRET_KEY") - - #: The secure cookie uses this for the name of the session cookie. - #: - #: This attribute can also be configured from the config with the - #: ``SESSION_COOKIE_NAME`` configuration key. Defaults to ``'session'`` - session_cookie_name = ConfigAttribute("SESSION_COOKIE_NAME") - - #: A :class:`~datetime.timedelta` which is used to set the expiration - #: date of a permanent session. The default is 31 days which makes a - #: permanent session survive for roughly one month. - #: - #: This attribute can also be configured from the config with the - #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to - #: ``timedelta(days=31)`` - permanent_session_lifetime = ConfigAttribute( - "PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta - ) - - #: A :class:`~datetime.timedelta` or number of seconds which is used - #: as the default ``max_age`` for :func:`send_file`. The default is - #: ``None``, which tells the browser to use conditional requests - #: instead of a timed cache. - #: - #: Configured with the :data:`SEND_FILE_MAX_AGE_DEFAULT` - #: configuration key. - #: - #: .. versionchanged:: 2.0 - #: Defaults to ``None`` instead of 12 hours. - send_file_max_age_default = ConfigAttribute( - "SEND_FILE_MAX_AGE_DEFAULT", get_converter=_make_timedelta - ) - - #: Enable this if you want to use the X-Sendfile feature. Keep in - #: mind that the server has to support this. This only affects files - #: sent with the :func:`send_file` method. - #: - #: .. versionadded:: 0.2 - #: - #: This attribute can also be configured from the config with the - #: ``USE_X_SENDFILE`` configuration key. Defaults to ``False``. - use_x_sendfile = ConfigAttribute("USE_X_SENDFILE") - - #: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`. - #: - #: .. versionadded:: 0.10 - json_encoder = json.JSONEncoder - - #: The JSON decoder class to use. Defaults to :class:`~flask.json.JSONDecoder`. - #: - #: .. versionadded:: 0.10 - json_decoder = json.JSONDecoder - - #: Options that are passed to the Jinja environment in - #: :meth:`create_jinja_environment`. Changing these options after - #: the environment is created (accessing :attr:`jinja_env`) will - #: have no effect. - #: - #: .. versionchanged:: 1.1.0 - #: This is a ``dict`` instead of an ``ImmutableDict`` to allow - #: easier configuration. - #: - jinja_options: dict = {} - - #: Default configuration parameters. - default_config = ImmutableDict( - { - "ENV": None, - "DEBUG": None, - "TESTING": False, - "PROPAGATE_EXCEPTIONS": None, - "PRESERVE_CONTEXT_ON_EXCEPTION": None, - "SECRET_KEY": None, - "PERMANENT_SESSION_LIFETIME": timedelta(days=31), - "USE_X_SENDFILE": False, - "SERVER_NAME": None, - "APPLICATION_ROOT": "/", - "SESSION_COOKIE_NAME": "session", - "SESSION_COOKIE_DOMAIN": None, - "SESSION_COOKIE_PATH": None, - "SESSION_COOKIE_HTTPONLY": True, - "SESSION_COOKIE_SECURE": False, - "SESSION_COOKIE_SAMESITE": None, - "SESSION_REFRESH_EACH_REQUEST": True, - "MAX_CONTENT_LENGTH": None, - "SEND_FILE_MAX_AGE_DEFAULT": None, - "TRAP_BAD_REQUEST_ERRORS": None, - "TRAP_HTTP_EXCEPTIONS": False, - "EXPLAIN_TEMPLATE_LOADING": False, - "PREFERRED_URL_SCHEME": "http", - "JSON_AS_ASCII": True, - "JSON_SORT_KEYS": True, - "JSONIFY_PRETTYPRINT_REGULAR": False, - "JSONIFY_MIMETYPE": "application/json", - "TEMPLATES_AUTO_RELOAD": None, - "MAX_COOKIE_SIZE": 4093, - } - ) - - #: The rule object to use for URL rules created. This is used by - #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. - #: - #: .. versionadded:: 0.7 - url_rule_class = Rule - - #: The map object to use for storing the URL rules and routing - #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. - #: - #: .. versionadded:: 1.1.0 - url_map_class = Map - - #: The :meth:`test_client` method creates an instance of this test - #: client class. Defaults to :class:`~flask.testing.FlaskClient`. - #: - #: .. versionadded:: 0.7 - test_client_class: t.Optional[t.Type["FlaskClient"]] = None - - #: The :class:`~click.testing.CliRunner` subclass, by default - #: :class:`~flask.testing.FlaskCliRunner` that is used by - #: :meth:`test_cli_runner`. Its ``__init__`` method should take a - #: Flask app object as the first argument. - #: - #: .. versionadded:: 1.0 - test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None - - #: the session interface to use. By default an instance of - #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. - #: - #: .. versionadded:: 0.8 - session_interface = SecureCookieSessionInterface() - - def __init__( - self, - import_name: str, - static_url_path: t.Optional[str] = None, - static_folder: t.Optional[t.Union[str, os.PathLike]] = "static", - static_host: t.Optional[str] = None, - host_matching: bool = False, - subdomain_matching: bool = False, - template_folder: t.Optional[str] = "templates", - instance_path: t.Optional[str] = None, - instance_relative_config: bool = False, - root_path: t.Optional[str] = None, - ): - super().__init__( - import_name=import_name, - static_folder=static_folder, - static_url_path=static_url_path, - template_folder=template_folder, - root_path=root_path, - ) - - if instance_path is None: - instance_path = self.auto_find_instance_path() - elif not os.path.isabs(instance_path): - raise ValueError( - "If an instance path is provided it must be absolute." - " A relative path was given instead." - ) - - #: Holds the path to the instance folder. - #: - #: .. versionadded:: 0.8 - self.instance_path = instance_path - - #: The configuration dictionary as :class:`Config`. This behaves - #: exactly like a regular dictionary but supports additional methods - #: to load a config from files. - self.config = self.make_config(instance_relative_config) - - #: A list of functions that are called when :meth:`url_for` raises a - #: :exc:`~werkzeug.routing.BuildError`. Each function registered here - #: is called with `error`, `endpoint` and `values`. If a function - #: returns ``None`` or raises a :exc:`BuildError` the next function is - #: tried. - #: - #: .. versionadded:: 0.9 - self.url_build_error_handlers: t.List[ - t.Callable[[Exception, str, dict], str] - ] = [] - - #: A list of functions that will be called at the beginning of the - #: first request to this instance. To register a function, use the - #: :meth:`before_first_request` decorator. - #: - #: .. versionadded:: 0.8 - self.before_first_request_funcs: t.List[BeforeFirstRequestCallable] = [] - - #: A list of functions that are called when the application context - #: is destroyed. Since the application context is also torn down - #: if the request ends this is the place to store code that disconnects - #: from databases. - #: - #: .. versionadded:: 0.9 - self.teardown_appcontext_funcs: t.List[TeardownCallable] = [] - - #: A list of shell context processor functions that should be run - #: when a shell context is created. - #: - #: .. versionadded:: 0.11 - self.shell_context_processors: t.List[t.Callable[[], t.Dict[str, t.Any]]] = [] - - #: Maps registered blueprint names to blueprint objects. The - #: dict retains the order the blueprints were registered in. - #: Blueprints can be registered multiple times, this dict does - #: not track how often they were attached. - #: - #: .. versionadded:: 0.7 - self.blueprints: t.Dict[str, "Blueprint"] = {} - - #: a place where extensions can store application specific state. For - #: example this is where an extension could store database engines and - #: similar things. - #: - #: The key must match the name of the extension module. For example in - #: case of a "Flask-Foo" extension in `flask_foo`, the key would be - #: ``'foo'``. - #: - #: .. versionadded:: 0.7 - self.extensions: dict = {} - - #: The :class:`~werkzeug.routing.Map` for this instance. You can use - #: this to change the routing converters after the class was created - #: but before any routes are connected. Example:: - #: - #: from werkzeug.routing import BaseConverter - #: - #: class ListConverter(BaseConverter): - #: def to_python(self, value): - #: return value.split(',') - #: def to_url(self, values): - #: return ','.join(super(ListConverter, self).to_url(value) - #: for value in values) - #: - #: app = Flask(__name__) - #: app.url_map.converters['list'] = ListConverter - self.url_map = self.url_map_class() - - self.url_map.host_matching = host_matching - self.subdomain_matching = subdomain_matching - - # tracks internally if the application already handled at least one - # request. - self._got_first_request = False - self._before_request_lock = Lock() - - # Add a static route using the provided static_url_path, static_host, - # and static_folder if there is a configured static_folder. - # Note we do this without checking if static_folder exists. - # For one, it might be created while the server is running (e.g. during - # development). Also, Google App Engine stores static files somewhere - if self.has_static_folder: - assert ( - bool(static_host) == host_matching - ), "Invalid static_host/host_matching combination" - # Use a weakref to avoid creating a reference cycle between the app - # and the view function (see #3761). - self_ref = weakref.ref(self) - self.add_url_rule( - f"{self.static_url_path}/", - endpoint="static", - host=static_host, - view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 - ) - - # Set the name of the Click group in case someone wants to add - # the app's commands to another CLI tool. - self.cli.name = self.name - - def _is_setup_finished(self) -> bool: - return self.debug and self._got_first_request - - @locked_cached_property - def name(self) -> str: # type: ignore - """The name of the application. This is usually the import name - with the difference that it's guessed from the run file if the - import name is main. This name is used as a display name when - Flask needs the name of the application. It can be set and overridden - to change the value. - - .. versionadded:: 0.8 - """ - if self.import_name == "__main__": - fn = getattr(sys.modules["__main__"], "__file__", None) - if fn is None: - return "__main__" - return os.path.splitext(os.path.basename(fn))[0] - return self.import_name - - @property - def propagate_exceptions(self) -> bool: - """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration - value in case it's set, otherwise a sensible default is returned. - - .. versionadded:: 0.7 - """ - rv = self.config["PROPAGATE_EXCEPTIONS"] - if rv is not None: - return rv - return self.testing or self.debug - - @property - def preserve_context_on_exception(self) -> bool: - """Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION`` - configuration value in case it's set, otherwise a sensible default - is returned. - - .. versionadded:: 0.7 - """ - rv = self.config["PRESERVE_CONTEXT_ON_EXCEPTION"] - if rv is not None: - return rv - return self.debug - - @locked_cached_property - def logger(self) -> logging.Logger: - """A standard Python :class:`~logging.Logger` for the app, with - the same name as :attr:`name`. - - In debug mode, the logger's :attr:`~logging.Logger.level` will - be set to :data:`~logging.DEBUG`. - - If there are no handlers configured, a default handler will be - added. See :doc:`/logging` for more information. - - .. versionchanged:: 1.1.0 - The logger takes the same name as :attr:`name` rather than - hard-coding ``"flask.app"``. - - .. versionchanged:: 1.0.0 - Behavior was simplified. The logger is always named - ``"flask.app"``. The level is only set during configuration, - it doesn't check ``app.debug`` each time. Only one format is - used, not different ones depending on ``app.debug``. No - handlers are removed, and a handler is only added if no - handlers are already configured. - - .. versionadded:: 0.3 - """ - return create_logger(self) - - @locked_cached_property - def jinja_env(self) -> Environment: - """The Jinja environment used to load templates. - - The environment is created the first time this property is - accessed. Changing :attr:`jinja_options` after that will have no - effect. - """ - return self.create_jinja_environment() - - @property - def got_first_request(self) -> bool: - """This attribute is set to ``True`` if the application started - handling the first request. - - .. versionadded:: 0.8 - """ - return self._got_first_request - - def make_config(self, instance_relative: bool = False) -> Config: - """Used to create the config attribute by the Flask constructor. - The `instance_relative` parameter is passed in from the constructor - of Flask (there named `instance_relative_config`) and indicates if - the config should be relative to the instance path or the root path - of the application. - - .. versionadded:: 0.8 - """ - root_path = self.root_path - if instance_relative: - root_path = self.instance_path - defaults = dict(self.default_config) - defaults["ENV"] = get_env() - defaults["DEBUG"] = get_debug_flag() - return self.config_class(root_path, defaults) - - def auto_find_instance_path(self) -> str: - """Tries to locate the instance path if it was not provided to the - constructor of the application class. It will basically calculate - the path to a folder named ``instance`` next to your main file or - the package. - - .. versionadded:: 0.8 - """ - prefix, package_path = find_package(self.import_name) - if prefix is None: - return os.path.join(package_path, "instance") - return os.path.join(prefix, "var", f"{self.name}-instance") - - def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: - """Opens a resource from the application's instance folder - (:attr:`instance_path`). Otherwise works like - :meth:`open_resource`. Instance resources can also be opened for - writing. - - :param resource: the name of the resource. To access resources within - subfolders use forward slashes as separator. - :param mode: resource file opening mode, default is 'rb'. - """ - return open(os.path.join(self.instance_path, resource), mode) - - @property - def templates_auto_reload(self) -> bool: - """Reload templates when they are changed. Used by - :meth:`create_jinja_environment`. - - This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If - not set, it will be enabled in debug mode. - - .. versionadded:: 1.0 - This property was added but the underlying config and behavior - already existed. - """ - rv = self.config["TEMPLATES_AUTO_RELOAD"] - return rv if rv is not None else self.debug - - @templates_auto_reload.setter - def templates_auto_reload(self, value: bool) -> None: - self.config["TEMPLATES_AUTO_RELOAD"] = value - - def create_jinja_environment(self) -> Environment: - """Create the Jinja environment based on :attr:`jinja_options` - and the various Jinja-related methods of the app. Changing - :attr:`jinja_options` after this will have no effect. Also adds - Flask-related globals and filters to the environment. - - .. versionchanged:: 0.11 - ``Environment.auto_reload`` set in accordance with - ``TEMPLATES_AUTO_RELOAD`` configuration option. - - .. versionadded:: 0.5 - """ - options = dict(self.jinja_options) - - if "autoescape" not in options: - options["autoescape"] = self.select_jinja_autoescape - - if "auto_reload" not in options: - options["auto_reload"] = self.templates_auto_reload - - rv = self.jinja_environment(self, **options) - rv.globals.update( - url_for=url_for, - get_flashed_messages=get_flashed_messages, - config=self.config, - # request, session and g are normally added with the - # context processor for efficiency reasons but for imported - # templates we also want the proxies in there. - request=request, - session=session, - g=g, - ) - rv.policies["json.dumps_function"] = json.dumps - return rv - - def create_global_jinja_loader(self) -> DispatchingJinjaLoader: - """Creates the loader for the Jinja2 environment. Can be used to - override just the loader and keeping the rest unchanged. It's - discouraged to override this function. Instead one should override - the :meth:`jinja_loader` function instead. - - The global loader dispatches between the loaders of the application - and the individual blueprints. - - .. versionadded:: 0.7 - """ - return DispatchingJinjaLoader(self) - - def select_jinja_autoescape(self, filename: str) -> bool: - """Returns ``True`` if autoescaping should be active for the given - template name. If no template name is given, returns `True`. - - .. versionadded:: 0.5 - """ - if filename is None: - return True - return filename.endswith((".html", ".htm", ".xml", ".xhtml")) - - def update_template_context(self, context: dict) -> None: - """Update the template context with some commonly used variables. - This injects request, session, config and g into the template - context as well as everything template context processors want - to inject. Note that the as of Flask 0.6, the original values - in the context will not be overridden if a context processor - decides to return a value with the same key. - - :param context: the context as a dictionary that is updated in place - to add extra variables. - """ - names: t.Iterable[t.Optional[str]] = (None,) - - # A template may be rendered outside a request context. - if request: - names = chain(names, reversed(request.blueprints)) - - # The values passed to render_template take precedence. Keep a - # copy to re-apply after all context functions. - orig_ctx = context.copy() - - for name in names: - if name in self.template_context_processors: - for func in self.template_context_processors[name]: - context.update(func()) - - context.update(orig_ctx) - - def make_shell_context(self) -> dict: - """Returns the shell context for an interactive shell for this - application. This runs all the registered shell context - processors. - - .. versionadded:: 0.11 - """ - rv = {"app": self, "g": g} - for processor in self.shell_context_processors: - rv.update(processor()) - return rv - - #: What environment the app is running in. Flask and extensions may - #: enable behaviors based on the environment, such as enabling debug - #: mode. This maps to the :data:`ENV` config key. This is set by the - #: :envvar:`FLASK_ENV` environment variable and may not behave as - #: expected if set in code. - #: - #: **Do not enable development when deploying in production.** - #: - #: Default: ``'production'`` - env = ConfigAttribute("ENV") - - @property - def debug(self) -> bool: - """Whether debug mode is enabled. When using ``flask run`` to start - the development server, an interactive debugger will be shown for - unhandled exceptions, and the server will be reloaded when code - changes. This maps to the :data:`DEBUG` config key. This is - enabled when :attr:`env` is ``'development'`` and is overridden - by the ``FLASK_DEBUG`` environment variable. It may not behave as - expected if set in code. - - **Do not enable debug mode when deploying in production.** - - Default: ``True`` if :attr:`env` is ``'development'``, or - ``False`` otherwise. - """ - return self.config["DEBUG"] - - @debug.setter - def debug(self, value: bool) -> None: - self.config["DEBUG"] = value - self.jinja_env.auto_reload = self.templates_auto_reload - - def run( - self, - host: t.Optional[str] = None, - port: t.Optional[int] = None, - debug: t.Optional[bool] = None, - load_dotenv: bool = True, - **options: t.Any, - ) -> None: - """Runs the application on a local development server. - - Do not use ``run()`` in a production setting. It is not intended to - meet security and performance requirements for a production server. - Instead, see :doc:`/deploying/index` for WSGI server recommendations. - - If the :attr:`debug` flag is set the server will automatically reload - for code changes and show a debugger in case an exception happened. - - If you want to run the application in debug mode, but disable the - code execution on the interactive debugger, you can pass - ``use_evalex=False`` as parameter. This will keep the debugger's - traceback screen active, but disable code execution. - - It is not recommended to use this function for development with - automatic reloading as this is badly supported. Instead you should - be using the :command:`flask` command line script's ``run`` support. - - .. admonition:: Keep in Mind - - Flask will suppress any server error with a generic error page - unless it is in debug mode. As such to enable just the - interactive debugger without the code reloading, you have to - invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. - Setting ``use_debugger`` to ``True`` without being in debug mode - won't catch any exceptions because there won't be any to - catch. - - :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to - have the server available externally as well. Defaults to - ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable - if present. - :param port: the port of the webserver. Defaults to ``5000`` or the - port defined in the ``SERVER_NAME`` config variable if present. - :param debug: if given, enable or disable debug mode. See - :attr:`debug`. - :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` - files to set environment variables. Will also change the working - directory to the directory containing the first file found. - :param options: the options to be forwarded to the underlying Werkzeug - server. See :func:`werkzeug.serving.run_simple` for more - information. - - .. versionchanged:: 1.0 - If installed, python-dotenv will be used to load environment - variables from :file:`.env` and :file:`.flaskenv` files. - - If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG` - environment variables will override :attr:`env` and - :attr:`debug`. - - Threaded mode is enabled by default. - - .. versionchanged:: 0.10 - The default port is now picked from the ``SERVER_NAME`` - variable. - """ - # Change this into a no-op if the server is invoked from the - # command line. Have a look at cli.py for more information. - if os.environ.get("FLASK_RUN_FROM_CLI") == "true": - from .debughelpers import explain_ignored_app_run - - explain_ignored_app_run() - return - - if get_load_dotenv(load_dotenv): - cli.load_dotenv() - - # if set, let env vars override previous values - if "FLASK_ENV" in os.environ: - self.env = get_env() - self.debug = get_debug_flag() - elif "FLASK_DEBUG" in os.environ: - self.debug = get_debug_flag() - - # debug passed to method overrides all other sources - if debug is not None: - self.debug = bool(debug) - - server_name = self.config.get("SERVER_NAME") - sn_host = sn_port = None - - if server_name: - sn_host, _, sn_port = server_name.partition(":") - - if not host: - if sn_host: - host = sn_host - else: - host = "127.0.0.1" - - if port or port == 0: - port = int(port) - elif sn_port: - port = int(sn_port) - else: - port = 5000 - - options.setdefault("use_reloader", self.debug) - options.setdefault("use_debugger", self.debug) - options.setdefault("threaded", True) - - cli.show_server_banner(self.env, self.debug, self.name, False) - - from werkzeug.serving import run_simple - - try: - run_simple(t.cast(str, host), port, self, **options) - finally: - # reset the first request information if the development server - # reset normally. This makes it possible to restart the server - # without reloader and that stuff from an interactive shell. - self._got_first_request = False - - def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient": - """Creates a test client for this application. For information - about unit testing head over to :doc:`/testing`. - - Note that if you are testing for assertions or exceptions in your - application code, you must set ``app.testing = True`` in order for the - exceptions to propagate to the test client. Otherwise, the exception - will be handled by the application (not visible to the test client) and - the only indication of an AssertionError or other exception will be a - 500 status code response to the test client. See the :attr:`testing` - attribute. For example:: - - app.testing = True - client = app.test_client() - - The test client can be used in a ``with`` block to defer the closing down - of the context until the end of the ``with`` block. This is useful if - you want to access the context locals for testing:: - - with app.test_client() as c: - rv = c.get('/?vodka=42') - assert request.args['vodka'] == '42' - - Additionally, you may pass optional keyword arguments that will then - be passed to the application's :attr:`test_client_class` constructor. - For example:: - - from flask.testing import FlaskClient - - class CustomClient(FlaskClient): - def __init__(self, *args, **kwargs): - self._authentication = kwargs.pop("authentication") - super(CustomClient,self).__init__( *args, **kwargs) - - app.test_client_class = CustomClient - client = app.test_client(authentication='Basic ....') - - See :class:`~flask.testing.FlaskClient` for more information. - - .. versionchanged:: 0.4 - added support for ``with`` block usage for the client. - - .. versionadded:: 0.7 - The `use_cookies` parameter was added as well as the ability - to override the client to be used by setting the - :attr:`test_client_class` attribute. - - .. versionchanged:: 0.11 - Added `**kwargs` to support passing additional keyword arguments to - the constructor of :attr:`test_client_class`. - """ - cls = self.test_client_class - if cls is None: - from .testing import FlaskClient as cls # type: ignore - return cls( # type: ignore - self, self.response_class, use_cookies=use_cookies, **kwargs - ) - - def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner": - """Create a CLI runner for testing CLI commands. - See :ref:`testing-cli`. - - Returns an instance of :attr:`test_cli_runner_class`, by default - :class:`~flask.testing.FlaskCliRunner`. The Flask app object is - passed as the first argument. - - .. versionadded:: 1.0 - """ - cls = self.test_cli_runner_class - - if cls is None: - from .testing import FlaskCliRunner as cls # type: ignore - - return cls(self, **kwargs) # type: ignore - - @setupmethod - def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None: - """Register a :class:`~flask.Blueprint` on the application. Keyword - arguments passed to this method will override the defaults set on the - blueprint. - - Calls the blueprint's :meth:`~flask.Blueprint.register` method after - recording the blueprint in the application's :attr:`blueprints`. - - :param blueprint: The blueprint to register. - :param url_prefix: Blueprint routes will be prefixed with this. - :param subdomain: Blueprint routes will match on this subdomain. - :param url_defaults: Blueprint routes will use these default values for - view arguments. - :param options: Additional keyword arguments are passed to - :class:`~flask.blueprints.BlueprintSetupState`. They can be - accessed in :meth:`~flask.Blueprint.record` callbacks. - - .. versionchanged:: 2.0.1 - The ``name`` option can be used to change the (pre-dotted) - name the blueprint is registered with. This allows the same - blueprint to be registered multiple times with unique names - for ``url_for``. - - .. versionadded:: 0.7 - """ - blueprint.register(self, options) - - def iter_blueprints(self) -> t.ValuesView["Blueprint"]: - """Iterates over all blueprints by the order they were registered. - - .. versionadded:: 0.11 - """ - return self.blueprints.values() - - @setupmethod - def add_url_rule( - self, - rule: str, - endpoint: t.Optional[str] = None, - view_func: t.Optional[t.Callable] = None, - provide_automatic_options: t.Optional[bool] = None, - **options: t.Any, - ) -> None: - if endpoint is None: - endpoint = _endpoint_from_view_func(view_func) # type: ignore - options["endpoint"] = endpoint - methods = options.pop("methods", None) - - # if the methods are not given and the view_func object knows its - # methods we can use that instead. If neither exists, we go with - # a tuple of only ``GET`` as default. - if methods is None: - methods = getattr(view_func, "methods", None) or ("GET",) - if isinstance(methods, str): - raise TypeError( - "Allowed methods must be a list of strings, for" - ' example: @app.route(..., methods=["POST"])' - ) - methods = {item.upper() for item in methods} - - # Methods that should always be added - required_methods = set(getattr(view_func, "required_methods", ())) - - # starting with Flask 0.8 the view_func object can disable and - # force-enable the automatic options handling. - if provide_automatic_options is None: - provide_automatic_options = getattr( - view_func, "provide_automatic_options", None - ) - - if provide_automatic_options is None: - if "OPTIONS" not in methods: - provide_automatic_options = True - required_methods.add("OPTIONS") - else: - provide_automatic_options = False - - # Add the required methods now. - methods |= required_methods - - rule = self.url_rule_class(rule, methods=methods, **options) - rule.provide_automatic_options = provide_automatic_options # type: ignore - - self.url_map.add(rule) - if view_func is not None: - old_func = self.view_functions.get(endpoint) - if old_func is not None and old_func != view_func: - raise AssertionError( - "View function mapping is overwriting an existing" - f" endpoint function: {endpoint}" - ) - self.view_functions[endpoint] = view_func - - @setupmethod - def template_filter( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: - """A decorator that is used to register custom template filter. - You can specify a name for the filter, otherwise the function - name will be used. Example:: - - @app.template_filter() - def reverse(s): - return s[::-1] - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - - def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable: - self.add_template_filter(f, name=name) - return f - - return decorator - - @setupmethod - def add_template_filter( - self, f: TemplateFilterCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template filter. Works exactly like the - :meth:`template_filter` decorator. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - self.jinja_env.filters[name or f.__name__] = f - - @setupmethod - def template_test( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: - """A decorator that is used to register custom template test. - You can specify a name for the test, otherwise the function - name will be used. Example:: - - @app.template_test() - def is_prime(n): - if n == 2: - return True - for i in range(2, int(math.ceil(math.sqrt(n))) + 1): - if n % i == 0: - return False - return True - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - - def decorator(f: TemplateTestCallable) -> TemplateTestCallable: - self.add_template_test(f, name=name) - return f - - return decorator - - @setupmethod - def add_template_test( - self, f: TemplateTestCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template test. Works exactly like the - :meth:`template_test` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - self.jinja_env.tests[name or f.__name__] = f - - @setupmethod - def template_global( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: - """A decorator that is used to register a custom template global function. - You can specify a name for the global function, otherwise the function - name will be used. Example:: - - @app.template_global() - def double(n): - return 2 * n - - .. versionadded:: 0.10 - - :param name: the optional name of the global function, otherwise the - function name will be used. - """ - - def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable: - self.add_template_global(f, name=name) - return f - - return decorator - - @setupmethod - def add_template_global( - self, f: TemplateGlobalCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template global function. Works exactly like the - :meth:`template_global` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the global function, otherwise the - function name will be used. - """ - self.jinja_env.globals[name or f.__name__] = f - - @setupmethod - def before_first_request( - self, f: BeforeFirstRequestCallable - ) -> BeforeFirstRequestCallable: - """Registers a function to be run before the first request to this - instance of the application. - - The function will be called without any arguments and its return - value is ignored. - - .. versionadded:: 0.8 - """ - self.before_first_request_funcs.append(f) - return f - - @setupmethod - def teardown_appcontext(self, f: TeardownCallable) -> TeardownCallable: - """Registers a function to be called when the application context - ends. These functions are typically also called when the request - context is popped. - - Example:: - - ctx = app.app_context() - ctx.push() - ... - ctx.pop() - - When ``ctx.pop()`` is executed in the above example, the teardown - functions are called just before the app context moves from the - stack of active contexts. This becomes relevant if you are using - such constructs in tests. - - Since a request context typically also manages an application - context it would also be called when you pop a request context. - - When a teardown function was called because of an unhandled exception - it will be passed an error object. If an :meth:`errorhandler` is - registered, it will handle the exception and the teardown will not - receive it. - - The return values of teardown functions are ignored. - - .. versionadded:: 0.9 - """ - self.teardown_appcontext_funcs.append(f) - return f - - @setupmethod - def shell_context_processor(self, f: t.Callable) -> t.Callable: - """Registers a shell context processor function. - - .. versionadded:: 0.11 - """ - self.shell_context_processors.append(f) - return f - - def _find_error_handler( - self, e: Exception - ) -> t.Optional["ErrorHandlerCallable[Exception]"]: - """Return a registered error handler for an exception in this order: - blueprint handler for a specific code, app handler for a specific code, - blueprint handler for an exception class, app handler for an exception - class, or ``None`` if a suitable handler is not found. - """ - exc_class, code = self._get_exc_class_and_code(type(e)) - names = (*request.blueprints, None) - - for c in (code, None) if code is not None else (None,): - for name in names: - handler_map = self.error_handler_spec[name][c] - - if not handler_map: - continue - - for cls in exc_class.__mro__: - handler = handler_map.get(cls) - - if handler is not None: - return handler - return None - - def handle_http_exception( - self, e: HTTPException - ) -> t.Union[HTTPException, ResponseReturnValue]: - """Handles an HTTP exception. By default this will invoke the - registered error handlers and fall back to returning the - exception as response. - - .. versionchanged:: 1.0.3 - ``RoutingException``, used internally for actions such as - slash redirects during routing, is not passed to error - handlers. - - .. versionchanged:: 1.0 - Exceptions are looked up by code *and* by MRO, so - ``HTTPException`` subclasses can be handled with a catch-all - handler for the base ``HTTPException``. - - .. versionadded:: 0.3 - """ - # Proxy exceptions don't have error codes. We want to always return - # those unchanged as errors - if e.code is None: - return e - - # RoutingExceptions are used internally to trigger routing - # actions, such as slash redirects raising RequestRedirect. They - # are not raised or handled in user code. - if isinstance(e, RoutingException): - return e - - handler = self._find_error_handler(e) - if handler is None: - return e - return self.ensure_sync(handler)(e) - - def trap_http_exception(self, e: Exception) -> bool: - """Checks if an HTTP exception should be trapped or not. By default - this will return ``False`` for all exceptions except for a bad request - key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It - also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. - - This is called for all HTTP exceptions raised by a view function. - If it returns ``True`` for any exception the error handler for this - exception is not called and it shows up as regular exception in the - traceback. This is helpful for debugging implicitly raised HTTP - exceptions. - - .. versionchanged:: 1.0 - Bad request errors are not trapped by default in debug mode. - - .. versionadded:: 0.8 - """ - if self.config["TRAP_HTTP_EXCEPTIONS"]: - return True - - trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] - - # if unset, trap key errors in debug mode - if ( - trap_bad_request is None - and self.debug - and isinstance(e, BadRequestKeyError) - ): - return True - - if trap_bad_request: - return isinstance(e, BadRequest) - - return False - - def handle_user_exception( - self, e: Exception - ) -> t.Union[HTTPException, ResponseReturnValue]: - """This method is called whenever an exception occurs that - should be handled. A special case is :class:`~werkzeug - .exceptions.HTTPException` which is forwarded to the - :meth:`handle_http_exception` method. This function will either - return a response value or reraise the exception with the same - traceback. - - .. versionchanged:: 1.0 - Key errors raised from request data like ``form`` show the - bad key in debug mode rather than a generic bad request - message. - - .. versionadded:: 0.7 - """ - if isinstance(e, BadRequestKeyError) and ( - self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] - ): - e.show_exception = True - - if isinstance(e, HTTPException) and not self.trap_http_exception(e): - return self.handle_http_exception(e) - - handler = self._find_error_handler(e) - - if handler is None: - raise - - return self.ensure_sync(handler)(e) - - def handle_exception(self, e: Exception) -> Response: - """Handle an exception that did not have an error handler - associated with it, or that was raised from an error handler. - This always causes a 500 ``InternalServerError``. - - Always sends the :data:`got_request_exception` signal. - - If :attr:`propagate_exceptions` is ``True``, such as in debug - mode, the error will be re-raised so that the debugger can - display it. Otherwise, the original exception is logged, and - an :exc:`~werkzeug.exceptions.InternalServerError` is returned. - - If an error handler is registered for ``InternalServerError`` or - ``500``, it will be used. For consistency, the handler will - always receive the ``InternalServerError``. The original - unhandled exception is available as ``e.original_exception``. - - .. versionchanged:: 1.1.0 - Always passes the ``InternalServerError`` instance to the - handler, setting ``original_exception`` to the unhandled - error. - - .. versionchanged:: 1.1.0 - ``after_request`` functions and other finalization is done - even for the default 500 response when there is no handler. - - .. versionadded:: 0.3 - """ - exc_info = sys.exc_info() - got_request_exception.send(self, exception=e) - - if self.propagate_exceptions: - # Re-raise if called with an active exception, otherwise - # raise the passed in exception. - if exc_info[1] is e: - raise - - raise e - - self.log_exception(exc_info) - server_error: t.Union[InternalServerError, ResponseReturnValue] - server_error = InternalServerError(original_exception=e) - handler = self._find_error_handler(server_error) - - if handler is not None: - server_error = self.ensure_sync(handler)(server_error) - - return self.finalize_request(server_error, from_error_handler=True) - - def log_exception( - self, - exc_info: t.Union[ - t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None] - ], - ) -> None: - """Logs an exception. This is called by :meth:`handle_exception` - if debugging is disabled and right before the handler is called. - The default implementation logs the exception as error on the - :attr:`logger`. - - .. versionadded:: 0.8 - """ - self.logger.error( - f"Exception on {request.path} [{request.method}]", exc_info=exc_info - ) - - def raise_routing_exception(self, request: Request) -> "te.NoReturn": - """Exceptions that are recording during routing are reraised with - this method. During debug we are not reraising redirect requests - for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising - a different error instead to help debug situations. - - :internal: - """ - if ( - not self.debug - or not isinstance(request.routing_exception, RequestRedirect) - or request.method in ("GET", "HEAD", "OPTIONS") - ): - raise request.routing_exception # type: ignore - - from .debughelpers import FormDataRoutingRedirect - - raise FormDataRoutingRedirect(request) - - def dispatch_request(self) -> ResponseReturnValue: - """Does the request dispatching. Matches the URL and returns the - return value of the view or error handler. This does not have to - be a response object. In order to convert the return value to a - proper response object, call :func:`make_response`. - - .. versionchanged:: 0.7 - This no longer does the exception handling, this code was - moved to the new :meth:`full_dispatch_request`. - """ - req = _request_ctx_stack.top.request - if req.routing_exception is not None: - self.raise_routing_exception(req) - rule = req.url_rule - # if we provide automatic options for this URL and the - # request came with the OPTIONS method, reply automatically - if ( - getattr(rule, "provide_automatic_options", False) - and req.method == "OPTIONS" - ): - return self.make_default_options_response() - # otherwise dispatch to the handler for that endpoint - return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) - - def full_dispatch_request(self) -> Response: - """Dispatches the request and on top of that performs request - pre and postprocessing as well as HTTP exception catching and - error handling. - - .. versionadded:: 0.7 - """ - self.try_trigger_before_first_request_functions() - try: - request_started.send(self) - rv = self.preprocess_request() - if rv is None: - rv = self.dispatch_request() - except Exception as e: - rv = self.handle_user_exception(e) - return self.finalize_request(rv) - - def finalize_request( - self, - rv: t.Union[ResponseReturnValue, HTTPException], - from_error_handler: bool = False, - ) -> Response: - """Given the return value from a view function this finalizes - the request by converting it into a response and invoking the - postprocessing functions. This is invoked for both normal - request dispatching as well as error handlers. - - Because this means that it might be called as a result of a - failure a special safe mode is available which can be enabled - with the `from_error_handler` flag. If enabled, failures in - response processing will be logged and otherwise ignored. - - :internal: - """ - response = self.make_response(rv) - try: - response = self.process_response(response) - request_finished.send(self, response=response) - except Exception: - if not from_error_handler: - raise - self.logger.exception( - "Request finalizing failed with an error while handling an error" - ) - return response - - def try_trigger_before_first_request_functions(self) -> None: - """Called before each request and will ensure that it triggers - the :attr:`before_first_request_funcs` and only exactly once per - application instance (which means process usually). - - :internal: - """ - if self._got_first_request: - return - with self._before_request_lock: - if self._got_first_request: - return - for func in self.before_first_request_funcs: - self.ensure_sync(func)() - self._got_first_request = True - - def make_default_options_response(self) -> Response: - """This method is called to create the default ``OPTIONS`` response. - This can be changed through subclassing to change the default - behavior of ``OPTIONS`` responses. - - .. versionadded:: 0.7 - """ - adapter = _request_ctx_stack.top.url_adapter - methods = adapter.allowed_methods() - rv = self.response_class() - rv.allow.update(methods) - return rv - - def should_ignore_error(self, error: t.Optional[BaseException]) -> bool: - """This is called to figure out if an error should be ignored - or not as far as the teardown system is concerned. If this - function returns ``True`` then the teardown handlers will not be - passed the error. - - .. versionadded:: 0.10 - """ - return False - - def ensure_sync(self, func: t.Callable) -> t.Callable: - """Ensure that the function is synchronous for WSGI workers. - Plain ``def`` functions are returned as-is. ``async def`` - functions are wrapped to run and wait for the response. - - Override this method to change how the app runs async views. - - .. versionadded:: 2.0 - """ - if iscoroutinefunction(func): - return self.async_to_sync(func) - - return func - - def async_to_sync( - self, func: t.Callable[..., t.Coroutine] - ) -> t.Callable[..., t.Any]: - """Return a sync function that will run the coroutine function. - - .. code-block:: python - - result = app.async_to_sync(func)(*args, **kwargs) - - Override this method to change how the app converts async code - to be synchronously callable. - - .. versionadded:: 2.0 - """ - try: - from asgiref.sync import async_to_sync as asgiref_async_to_sync - except ImportError: - raise RuntimeError( - "Install Flask with the 'async' extra in order to use async views." - ) from None - - # Check that Werkzeug isn't using its fallback ContextVar class. - if ContextVar.__module__ == "werkzeug.local": - raise RuntimeError( - "Async cannot be used with this combination of Python " - "and Greenlet versions." - ) - - return asgiref_async_to_sync(func) - - def make_response(self, rv: ResponseReturnValue) -> Response: - """Convert the return value from a view function to an instance of - :attr:`response_class`. - - :param rv: the return value from the view function. The view function - must return a response. Returning ``None``, or the view ending - without returning, is not allowed. The following types are allowed - for ``view_rv``: - - ``str`` - A response object is created with the string encoded to UTF-8 - as the body. - - ``bytes`` - A response object is created with the bytes as the body. - - ``dict`` - A dictionary that will be jsonify'd before being returned. - - ``tuple`` - Either ``(body, status, headers)``, ``(body, status)``, or - ``(body, headers)``, where ``body`` is any of the other types - allowed here, ``status`` is a string or an integer, and - ``headers`` is a dictionary or a list of ``(key, value)`` - tuples. If ``body`` is a :attr:`response_class` instance, - ``status`` overwrites the exiting value and ``headers`` are - extended. - - :attr:`response_class` - The object is returned unchanged. - - other :class:`~werkzeug.wrappers.Response` class - The object is coerced to :attr:`response_class`. - - :func:`callable` - The function is called as a WSGI application. The result is - used to create a response object. - - .. versionchanged:: 0.9 - Previously a tuple was interpreted as the arguments for the - response object. - """ - - status = headers = None - - # unpack tuple returns - if isinstance(rv, tuple): - len_rv = len(rv) - - # a 3-tuple is unpacked directly - if len_rv == 3: - rv, status, headers = rv - # decide if a 2-tuple has status or headers - elif len_rv == 2: - if isinstance(rv[1], (Headers, dict, tuple, list)): - rv, headers = rv - else: - rv, status = rv - # other sized tuples are not allowed - else: - raise TypeError( - "The view function did not return a valid response tuple." - " The tuple must have the form (body, status, headers)," - " (body, status), or (body, headers)." - ) - - # the body must not be None - if rv is None: - raise TypeError( - f"The view function for {request.endpoint!r} did not" - " return a valid response. The function either returned" - " None or ended without a return statement." - ) - - # make sure the body is an instance of the response class - if not isinstance(rv, self.response_class): - if isinstance(rv, (str, bytes, bytearray)): - # let the response class set the status and headers instead of - # waiting to do it manually, so that the class can handle any - # special logic - rv = self.response_class(rv, status=status, headers=headers) - status = headers = None - elif isinstance(rv, dict): - rv = jsonify(rv) - elif isinstance(rv, BaseResponse) or callable(rv): - # evaluate a WSGI callable, or coerce a different response - # class to the correct type - try: - rv = self.response_class.force_type(rv, request.environ) # type: ignore # noqa: B950 - except TypeError as e: - raise TypeError( - f"{e}\nThe view function did not return a valid" - " response. The return type must be a string," - " dict, tuple, Response instance, or WSGI" - f" callable, but it was a {type(rv).__name__}." - ).with_traceback(sys.exc_info()[2]) from None - else: - raise TypeError( - "The view function did not return a valid" - " response. The return type must be a string," - " dict, tuple, Response instance, or WSGI" - f" callable, but it was a {type(rv).__name__}." - ) - - rv = t.cast(Response, rv) - # prefer the status if it was provided - if status is not None: - if isinstance(status, (str, bytes, bytearray)): - rv.status = status # type: ignore - else: - rv.status_code = status - - # extend existing headers with provided headers - if headers: - rv.headers.update(headers) - - return rv - - def create_url_adapter( - self, request: t.Optional[Request] - ) -> t.Optional[MapAdapter]: - """Creates a URL adapter for the given request. The URL adapter - is created at a point where the request context is not yet set - up so the request is passed explicitly. - - .. versionadded:: 0.6 - - .. versionchanged:: 0.9 - This can now also be called without a request object when the - URL adapter is created for the application context. - - .. versionchanged:: 1.0 - :data:`SERVER_NAME` no longer implicitly enables subdomain - matching. Use :attr:`subdomain_matching` instead. - """ - if request is not None: - # If subdomain matching is disabled (the default), use the - # default subdomain in all cases. This should be the default - # in Werkzeug but it currently does not have that feature. - if not self.subdomain_matching: - subdomain = self.url_map.default_subdomain or None - else: - subdomain = None - - return self.url_map.bind_to_environ( - request.environ, - server_name=self.config["SERVER_NAME"], - subdomain=subdomain, - ) - # We need at the very least the server name to be set for this - # to work. - if self.config["SERVER_NAME"] is not None: - return self.url_map.bind( - self.config["SERVER_NAME"], - script_name=self.config["APPLICATION_ROOT"], - url_scheme=self.config["PREFERRED_URL_SCHEME"], - ) - - return None - - def inject_url_defaults(self, endpoint: str, values: dict) -> None: - """Injects the URL defaults for the given endpoint directly into - the values dictionary passed. This is used internally and - automatically called on URL building. - - .. versionadded:: 0.7 - """ - names: t.Iterable[t.Optional[str]] = (None,) - - # url_for may be called outside a request context, parse the - # passed endpoint instead of using request.blueprints. - if "." in endpoint: - names = chain( - names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) - ) - - for name in names: - if name in self.url_default_functions: - for func in self.url_default_functions[name]: - func(endpoint, values) - - def handle_url_build_error( - self, error: Exception, endpoint: str, values: dict - ) -> str: - """Handle :class:`~werkzeug.routing.BuildError` on - :meth:`url_for`. - """ - for handler in self.url_build_error_handlers: - try: - rv = handler(error, endpoint, values) - except BuildError as e: - # make error available outside except block - error = e - else: - if rv is not None: - return rv - - # Re-raise if called with an active exception, otherwise raise - # the passed in exception. - if error is sys.exc_info()[1]: - raise - - raise error - - def preprocess_request(self) -> t.Optional[ResponseReturnValue]: - """Called before the request is dispatched. Calls - :attr:`url_value_preprocessors` registered with the app and the - current blueprint (if any). Then calls :attr:`before_request_funcs` - registered with the app and the blueprint. - - If any :meth:`before_request` handler returns a non-None value, the - value is handled as if it was the return value from the view, and - further request handling is stopped. - """ - names = (None, *reversed(request.blueprints)) - - for name in names: - if name in self.url_value_preprocessors: - for url_func in self.url_value_preprocessors[name]: - url_func(request.endpoint, request.view_args) - - for name in names: - if name in self.before_request_funcs: - for before_func in self.before_request_funcs[name]: - rv = self.ensure_sync(before_func)() - - if rv is not None: - return rv - - return None - - def process_response(self, response: Response) -> Response: - """Can be overridden in order to modify the response object - before it's sent to the WSGI server. By default this will - call all the :meth:`after_request` decorated functions. - - .. versionchanged:: 0.5 - As of Flask 0.5 the functions registered for after request - execution are called in reverse order of registration. - - :param response: a :attr:`response_class` object. - :return: a new response object or the same, has to be an - instance of :attr:`response_class`. - """ - ctx = _request_ctx_stack.top - - for func in ctx._after_request_functions: - response = self.ensure_sync(func)(response) - - for name in chain(request.blueprints, (None,)): - if name in self.after_request_funcs: - for func in reversed(self.after_request_funcs[name]): - response = self.ensure_sync(func)(response) - - if not self.session_interface.is_null_session(ctx.session): - self.session_interface.save_session(self, ctx.session, response) - - return response - - def do_teardown_request( - self, exc: t.Optional[BaseException] = _sentinel # type: ignore - ) -> None: - """Called after the request is dispatched and the response is - returned, right before the request context is popped. - - This calls all functions decorated with - :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` - if a blueprint handled the request. Finally, the - :data:`request_tearing_down` signal is sent. - - This is called by - :meth:`RequestContext.pop() `, - which may be delayed during testing to maintain access to - resources. - - :param exc: An unhandled exception raised while dispatching the - request. Detected from the current exception information if - not passed. Passed to each teardown function. - - .. versionchanged:: 0.9 - Added the ``exc`` argument. - """ - if exc is _sentinel: - exc = sys.exc_info()[1] - - for name in chain(request.blueprints, (None,)): - if name in self.teardown_request_funcs: - for func in reversed(self.teardown_request_funcs[name]): - self.ensure_sync(func)(exc) - - request_tearing_down.send(self, exc=exc) - - def do_teardown_appcontext( - self, exc: t.Optional[BaseException] = _sentinel # type: ignore - ) -> None: - """Called right before the application context is popped. - - When handling a request, the application context is popped - after the request context. See :meth:`do_teardown_request`. - - This calls all functions decorated with - :meth:`teardown_appcontext`. Then the - :data:`appcontext_tearing_down` signal is sent. - - This is called by - :meth:`AppContext.pop() `. - - .. versionadded:: 0.9 - """ - if exc is _sentinel: - exc = sys.exc_info()[1] - - for func in reversed(self.teardown_appcontext_funcs): - self.ensure_sync(func)(exc) - - appcontext_tearing_down.send(self, exc=exc) - - def app_context(self) -> AppContext: - """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` - block to push the context, which will make :data:`current_app` - point at this application. - - An application context is automatically pushed by - :meth:`RequestContext.push() ` - when handling a request, and when running a CLI command. Use - this to manually create a context outside of these situations. - - :: - - with app.app_context(): - init_db() - - See :doc:`/appcontext`. - - .. versionadded:: 0.9 - """ - return AppContext(self) - - def request_context(self, environ: dict) -> RequestContext: - """Create a :class:`~flask.ctx.RequestContext` representing a - WSGI environment. Use a ``with`` block to push the context, - which will make :data:`request` point at this request. - - See :doc:`/reqcontext`. - - Typically you should not call this from your own code. A request - context is automatically pushed by the :meth:`wsgi_app` when - handling a request. Use :meth:`test_request_context` to create - an environment and context instead of this method. - - :param environ: a WSGI environment - """ - return RequestContext(self, environ) - - def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: - """Create a :class:`~flask.ctx.RequestContext` for a WSGI - environment created from the given values. This is mostly useful - during testing, where you may want to run a function that uses - request data without dispatching a full request. - - See :doc:`/reqcontext`. - - Use a ``with`` block to push the context, which will make - :data:`request` point at the request for the created - environment. :: - - with test_request_context(...): - generate_report() - - When using the shell, it may be easier to push and pop the - context manually to avoid indentation. :: - - ctx = app.test_request_context(...) - ctx.push() - ... - ctx.pop() - - Takes the same arguments as Werkzeug's - :class:`~werkzeug.test.EnvironBuilder`, with some defaults from - the application. See the linked Werkzeug docs for most of the - available arguments. Flask-specific behavior is listed here. - - :param path: URL path being requested. - :param base_url: Base URL where the app is being served, which - ``path`` is relative to. If not given, built from - :data:`PREFERRED_URL_SCHEME`, ``subdomain``, - :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. - :param subdomain: Subdomain name to append to - :data:`SERVER_NAME`. - :param url_scheme: Scheme to use instead of - :data:`PREFERRED_URL_SCHEME`. - :param data: The request body, either as a string or a dict of - form keys and values. - :param json: If given, this is serialized as JSON and passed as - ``data``. Also defaults ``content_type`` to - ``application/json``. - :param args: other positional arguments passed to - :class:`~werkzeug.test.EnvironBuilder`. - :param kwargs: other keyword arguments passed to - :class:`~werkzeug.test.EnvironBuilder`. - """ - from .testing import EnvironBuilder - - builder = EnvironBuilder(self, *args, **kwargs) - - try: - return self.request_context(builder.get_environ()) - finally: - builder.close() - - def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any: - """The actual WSGI application. This is not implemented in - :meth:`__call__` so that middlewares can be applied without - losing a reference to the app object. Instead of doing this:: - - app = MyMiddleware(app) - - It's a better idea to do this instead:: - - app.wsgi_app = MyMiddleware(app.wsgi_app) - - Then you still have the original application object around and - can continue to call methods on it. - - .. versionchanged:: 0.7 - Teardown events for the request and app contexts are called - even if an unhandled error occurs. Other events may not be - called depending on when an error occurs during dispatch. - See :ref:`callbacks-and-errors`. - - :param environ: A WSGI environment. - :param start_response: A callable accepting a status code, - a list of headers, and an optional exception context to - start the response. - """ - ctx = self.request_context(environ) - error: t.Optional[BaseException] = None - try: - try: - ctx.push() - response = self.full_dispatch_request() - except Exception as e: - error = e - response = self.handle_exception(e) - except: # noqa: B001 - error = sys.exc_info()[1] - raise - return response(environ, start_response) - finally: - if self.should_ignore_error(error): - error = None - ctx.auto_pop(error) - - def __call__(self, environ: dict, start_response: t.Callable) -> t.Any: - """The WSGI server calls the Flask application object as the - WSGI application. This calls :meth:`wsgi_app`, which can be - wrapped to apply middleware. - """ - return self.wsgi_app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/flask/blueprints.py b/venv/lib/python3.7/site-packages/flask/blueprints.py deleted file mode 100644 index 5c23a73..0000000 --- a/venv/lib/python3.7/site-packages/flask/blueprints.py +++ /dev/null @@ -1,609 +0,0 @@ -import os -import typing as t -from collections import defaultdict -from functools import update_wrapper - -from .scaffold import _endpoint_from_view_func -from .scaffold import _sentinel -from .scaffold import Scaffold -from .typing import AfterRequestCallable -from .typing import BeforeFirstRequestCallable -from .typing import BeforeRequestCallable -from .typing import TeardownCallable -from .typing import TemplateContextProcessorCallable -from .typing import TemplateFilterCallable -from .typing import TemplateGlobalCallable -from .typing import TemplateTestCallable -from .typing import URLDefaultCallable -from .typing import URLValuePreprocessorCallable - -if t.TYPE_CHECKING: - from .app import Flask - from .typing import ErrorHandlerCallable - -DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] - - -class BlueprintSetupState: - """Temporary holder object for registering a blueprint with the - application. An instance of this class is created by the - :meth:`~flask.Blueprint.make_setup_state` method and later passed - to all register callback functions. - """ - - def __init__( - self, - blueprint: "Blueprint", - app: "Flask", - options: t.Any, - first_registration: bool, - ) -> None: - #: a reference to the current application - self.app = app - - #: a reference to the blueprint that created this setup state. - self.blueprint = blueprint - - #: a dictionary with all options that were passed to the - #: :meth:`~flask.Flask.register_blueprint` method. - self.options = options - - #: as blueprints can be registered multiple times with the - #: application and not everything wants to be registered - #: multiple times on it, this attribute can be used to figure - #: out if the blueprint was registered in the past already. - self.first_registration = first_registration - - subdomain = self.options.get("subdomain") - if subdomain is None: - subdomain = self.blueprint.subdomain - - #: The subdomain that the blueprint should be active for, ``None`` - #: otherwise. - self.subdomain = subdomain - - url_prefix = self.options.get("url_prefix") - if url_prefix is None: - url_prefix = self.blueprint.url_prefix - #: The prefix that should be used for all URLs defined on the - #: blueprint. - self.url_prefix = url_prefix - - self.name = self.options.get("name", blueprint.name) - self.name_prefix = self.options.get("name_prefix", "") - - #: A dictionary with URL defaults that is added to each and every - #: URL that was defined with the blueprint. - self.url_defaults = dict(self.blueprint.url_values_defaults) - self.url_defaults.update(self.options.get("url_defaults", ())) - - def add_url_rule( - self, - rule: str, - endpoint: t.Optional[str] = None, - view_func: t.Optional[t.Callable] = None, - **options: t.Any, - ) -> None: - """A helper method to register a rule (and optionally a view function) - to the application. The endpoint is automatically prefixed with the - blueprint's name. - """ - if self.url_prefix is not None: - if rule: - rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) - else: - rule = self.url_prefix - options.setdefault("subdomain", self.subdomain) - if endpoint is None: - endpoint = _endpoint_from_view_func(view_func) # type: ignore - defaults = self.url_defaults - if "defaults" in options: - defaults = dict(defaults, **options.pop("defaults")) - - self.app.add_url_rule( - rule, - f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), - view_func, - defaults=defaults, - **options, - ) - - -class Blueprint(Scaffold): - """Represents a blueprint, a collection of routes and other - app-related functions that can be registered on a real application - later. - - A blueprint is an object that allows defining application functions - without requiring an application object ahead of time. It uses the - same decorators as :class:`~flask.Flask`, but defers the need for an - application by recording them for later registration. - - Decorating a function with a blueprint creates a deferred function - that is called with :class:`~flask.blueprints.BlueprintSetupState` - when the blueprint is registered on an application. - - See :doc:`/blueprints` for more information. - - :param name: The name of the blueprint. Will be prepended to each - endpoint name. - :param import_name: The name of the blueprint package, usually - ``__name__``. This helps locate the ``root_path`` for the - blueprint. - :param static_folder: A folder with static files that should be - served by the blueprint's static route. The path is relative to - the blueprint's root path. Blueprint static files are disabled - by default. - :param static_url_path: The url to serve static files from. - Defaults to ``static_folder``. If the blueprint does not have - a ``url_prefix``, the app's static route will take precedence, - and the blueprint's static files won't be accessible. - :param template_folder: A folder with templates that should be added - to the app's template search path. The path is relative to the - blueprint's root path. Blueprint templates are disabled by - default. Blueprint templates have a lower precedence than those - in the app's templates folder. - :param url_prefix: A path to prepend to all of the blueprint's URLs, - to make them distinct from the rest of the app's routes. - :param subdomain: A subdomain that blueprint routes will match on by - default. - :param url_defaults: A dict of default values that blueprint routes - will receive by default. - :param root_path: By default, the blueprint will automatically set - this based on ``import_name``. In certain situations this - automatic detection can fail, so the path can be specified - manually instead. - - .. versionchanged:: 1.1.0 - Blueprints have a ``cli`` group to register nested CLI commands. - The ``cli_group`` parameter controls the name of the group under - the ``flask`` command. - - .. versionadded:: 0.7 - """ - - warn_on_modifications = False - _got_registered_once = False - - #: Blueprint local JSON encoder class to use. Set to ``None`` to use - #: the app's :class:`~flask.Flask.json_encoder`. - json_encoder = None - #: Blueprint local JSON decoder class to use. Set to ``None`` to use - #: the app's :class:`~flask.Flask.json_decoder`. - json_decoder = None - - def __init__( - self, - name: str, - import_name: str, - static_folder: t.Optional[t.Union[str, os.PathLike]] = None, - static_url_path: t.Optional[str] = None, - template_folder: t.Optional[str] = None, - url_prefix: t.Optional[str] = None, - subdomain: t.Optional[str] = None, - url_defaults: t.Optional[dict] = None, - root_path: t.Optional[str] = None, - cli_group: t.Optional[str] = _sentinel, # type: ignore - ): - super().__init__( - import_name=import_name, - static_folder=static_folder, - static_url_path=static_url_path, - template_folder=template_folder, - root_path=root_path, - ) - - if "." in name: - raise ValueError("'name' may not contain a dot '.' character.") - - self.name = name - self.url_prefix = url_prefix - self.subdomain = subdomain - self.deferred_functions: t.List[DeferredSetupFunction] = [] - - if url_defaults is None: - url_defaults = {} - - self.url_values_defaults = url_defaults - self.cli_group = cli_group - self._blueprints: t.List[t.Tuple["Blueprint", dict]] = [] - - def _is_setup_finished(self) -> bool: - return self.warn_on_modifications and self._got_registered_once - - def record(self, func: t.Callable) -> None: - """Registers a function that is called when the blueprint is - registered on the application. This function is called with the - state as argument as returned by the :meth:`make_setup_state` - method. - """ - if self._got_registered_once and self.warn_on_modifications: - from warnings import warn - - warn( - Warning( - "The blueprint was already registered once but is" - " getting modified now. These changes will not show" - " up." - ) - ) - self.deferred_functions.append(func) - - def record_once(self, func: t.Callable) -> None: - """Works like :meth:`record` but wraps the function in another - function that will ensure the function is only called once. If the - blueprint is registered a second time on the application, the - function passed is not called. - """ - - def wrapper(state: BlueprintSetupState) -> None: - if state.first_registration: - func(state) - - return self.record(update_wrapper(wrapper, func)) - - def make_setup_state( - self, app: "Flask", options: dict, first_registration: bool = False - ) -> BlueprintSetupState: - """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` - object that is later passed to the register callback functions. - Subclasses can override this to return a subclass of the setup state. - """ - return BlueprintSetupState(self, app, options, first_registration) - - def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None: - """Register a :class:`~flask.Blueprint` on this blueprint. Keyword - arguments passed to this method will override the defaults set - on the blueprint. - - .. versionchanged:: 2.0.1 - The ``name`` option can be used to change the (pre-dotted) - name the blueprint is registered with. This allows the same - blueprint to be registered multiple times with unique names - for ``url_for``. - - .. versionadded:: 2.0 - """ - if blueprint is self: - raise ValueError("Cannot register a blueprint on itself") - self._blueprints.append((blueprint, options)) - - def register(self, app: "Flask", options: dict) -> None: - """Called by :meth:`Flask.register_blueprint` to register all - views and callbacks registered on the blueprint with the - application. Creates a :class:`.BlueprintSetupState` and calls - each :meth:`record` callback with it. - - :param app: The application this blueprint is being registered - with. - :param options: Keyword arguments forwarded from - :meth:`~Flask.register_blueprint`. - - .. versionchanged:: 2.0.1 - Nested blueprints are registered with their dotted name. - This allows different blueprints with the same name to be - nested at different locations. - - .. versionchanged:: 2.0.1 - The ``name`` option can be used to change the (pre-dotted) - name the blueprint is registered with. This allows the same - blueprint to be registered multiple times with unique names - for ``url_for``. - - .. versionchanged:: 2.0.1 - Registering the same blueprint with the same name multiple - times is deprecated and will become an error in Flask 2.1. - """ - name_prefix = options.get("name_prefix", "") - self_name = options.get("name", self.name) - name = f"{name_prefix}.{self_name}".lstrip(".") - - if name in app.blueprints: - existing_at = f" '{name}'" if self_name != name else "" - - if app.blueprints[name] is not self: - raise ValueError( - f"The name '{self_name}' is already registered for" - f" a different blueprint{existing_at}. Use 'name='" - " to provide a unique name." - ) - else: - import warnings - - warnings.warn( - f"The name '{self_name}' is already registered for" - f" this blueprint{existing_at}. Use 'name=' to" - " provide a unique name. This will become an error" - " in Flask 2.1.", - stacklevel=4, - ) - - first_bp_registration = not any(bp is self for bp in app.blueprints.values()) - first_name_registration = name not in app.blueprints - - app.blueprints[name] = self - self._got_registered_once = True - state = self.make_setup_state(app, options, first_bp_registration) - - if self.has_static_folder: - state.add_url_rule( - f"{self.static_url_path}/", - view_func=self.send_static_file, - endpoint="static", - ) - - # Merge blueprint data into parent. - if first_bp_registration or first_name_registration: - - def extend(bp_dict, parent_dict): - for key, values in bp_dict.items(): - key = name if key is None else f"{name}.{key}" - parent_dict[key].extend(values) - - for key, value in self.error_handler_spec.items(): - key = name if key is None else f"{name}.{key}" - value = defaultdict( - dict, - { - code: { - exc_class: func for exc_class, func in code_values.items() - } - for code, code_values in value.items() - }, - ) - app.error_handler_spec[key] = value - - for endpoint, func in self.view_functions.items(): - app.view_functions[endpoint] = func - - extend(self.before_request_funcs, app.before_request_funcs) - extend(self.after_request_funcs, app.after_request_funcs) - extend( - self.teardown_request_funcs, - app.teardown_request_funcs, - ) - extend(self.url_default_functions, app.url_default_functions) - extend(self.url_value_preprocessors, app.url_value_preprocessors) - extend(self.template_context_processors, app.template_context_processors) - - for deferred in self.deferred_functions: - deferred(state) - - cli_resolved_group = options.get("cli_group", self.cli_group) - - if self.cli.commands: - if cli_resolved_group is None: - app.cli.commands.update(self.cli.commands) - elif cli_resolved_group is _sentinel: - self.cli.name = name - app.cli.add_command(self.cli) - else: - self.cli.name = cli_resolved_group - app.cli.add_command(self.cli) - - for blueprint, bp_options in self._blueprints: - bp_options = bp_options.copy() - bp_url_prefix = bp_options.get("url_prefix") - - if bp_url_prefix is None: - bp_url_prefix = blueprint.url_prefix - - if state.url_prefix is not None and bp_url_prefix is not None: - bp_options["url_prefix"] = ( - state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") - ) - elif bp_url_prefix is not None: - bp_options["url_prefix"] = bp_url_prefix - elif state.url_prefix is not None: - bp_options["url_prefix"] = state.url_prefix - - bp_options["name_prefix"] = name - blueprint.register(app, bp_options) - - def add_url_rule( - self, - rule: str, - endpoint: t.Optional[str] = None, - view_func: t.Optional[t.Callable] = None, - provide_automatic_options: t.Optional[bool] = None, - **options: t.Any, - ) -> None: - """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for - the :func:`url_for` function is prefixed with the name of the blueprint. - """ - if endpoint and "." in endpoint: - raise ValueError("'endpoint' may not contain a dot '.' character.") - - if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: - raise ValueError("'view_func' name may not contain a dot '.' character.") - - self.record( - lambda s: s.add_url_rule( - rule, - endpoint, - view_func, - provide_automatic_options=provide_automatic_options, - **options, - ) - ) - - def app_template_filter( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: - """Register a custom template filter, available application wide. Like - :meth:`Flask.template_filter` but for a blueprint. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - - def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable: - self.add_app_template_filter(f, name=name) - return f - - return decorator - - def add_app_template_filter( - self, f: TemplateFilterCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template filter, available application wide. Like - :meth:`Flask.add_template_filter` but for a blueprint. Works exactly - like the :meth:`app_template_filter` decorator. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - - def register_template(state: BlueprintSetupState) -> None: - state.app.jinja_env.filters[name or f.__name__] = f - - self.record_once(register_template) - - def app_template_test( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: - """Register a custom template test, available application wide. Like - :meth:`Flask.template_test` but for a blueprint. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - - def decorator(f: TemplateTestCallable) -> TemplateTestCallable: - self.add_app_template_test(f, name=name) - return f - - return decorator - - def add_app_template_test( - self, f: TemplateTestCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template test, available application wide. Like - :meth:`Flask.add_template_test` but for a blueprint. Works exactly - like the :meth:`app_template_test` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - - def register_template(state: BlueprintSetupState) -> None: - state.app.jinja_env.tests[name or f.__name__] = f - - self.record_once(register_template) - - def app_template_global( - self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: - """Register a custom template global, available application wide. Like - :meth:`Flask.template_global` but for a blueprint. - - .. versionadded:: 0.10 - - :param name: the optional name of the global, otherwise the - function name will be used. - """ - - def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable: - self.add_app_template_global(f, name=name) - return f - - return decorator - - def add_app_template_global( - self, f: TemplateGlobalCallable, name: t.Optional[str] = None - ) -> None: - """Register a custom template global, available application wide. Like - :meth:`Flask.add_template_global` but for a blueprint. Works exactly - like the :meth:`app_template_global` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the global, otherwise the - function name will be used. - """ - - def register_template(state: BlueprintSetupState) -> None: - state.app.jinja_env.globals[name or f.__name__] = f - - self.record_once(register_template) - - def before_app_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable: - """Like :meth:`Flask.before_request`. Such a function is executed - before each request, even if outside of a blueprint. - """ - self.record_once( - lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) - ) - return f - - def before_app_first_request( - self, f: BeforeFirstRequestCallable - ) -> BeforeFirstRequestCallable: - """Like :meth:`Flask.before_first_request`. Such a function is - executed before the first request to the application. - """ - self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) - return f - - def after_app_request(self, f: AfterRequestCallable) -> AfterRequestCallable: - """Like :meth:`Flask.after_request` but for a blueprint. Such a function - is executed after each request, even if outside of the blueprint. - """ - self.record_once( - lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) - ) - return f - - def teardown_app_request(self, f: TeardownCallable) -> TeardownCallable: - """Like :meth:`Flask.teardown_request` but for a blueprint. Such a - function is executed when tearing down each request, even if outside of - the blueprint. - """ - self.record_once( - lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) - ) - return f - - def app_context_processor( - self, f: TemplateContextProcessorCallable - ) -> TemplateContextProcessorCallable: - """Like :meth:`Flask.context_processor` but for a blueprint. Such a - function is executed each request, even if outside of the blueprint. - """ - self.record_once( - lambda s: s.app.template_context_processors.setdefault(None, []).append(f) - ) - return f - - def app_errorhandler(self, code: t.Union[t.Type[Exception], int]) -> t.Callable: - """Like :meth:`Flask.errorhandler` but for a blueprint. This - handler is used for all requests, even if outside of the blueprint. - """ - - def decorator( - f: "ErrorHandlerCallable[Exception]", - ) -> "ErrorHandlerCallable[Exception]": - self.record_once(lambda s: s.app.errorhandler(code)(f)) - return f - - return decorator - - def app_url_value_preprocessor( - self, f: URLValuePreprocessorCallable - ) -> URLValuePreprocessorCallable: - """Same as :meth:`url_value_preprocessor` but application wide.""" - self.record_once( - lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) - ) - return f - - def app_url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable: - """Same as :meth:`url_defaults` but application wide.""" - self.record_once( - lambda s: s.app.url_default_functions.setdefault(None, []).append(f) - ) - return f diff --git a/venv/lib/python3.7/site-packages/flask/cli.py b/venv/lib/python3.7/site-packages/flask/cli.py deleted file mode 100644 index 8e21532..0000000 --- a/venv/lib/python3.7/site-packages/flask/cli.py +++ /dev/null @@ -1,999 +0,0 @@ -import ast -import inspect -import os -import platform -import re -import sys -import traceback -import warnings -from functools import update_wrapper -from operator import attrgetter -from threading import Lock -from threading import Thread - -import click -from werkzeug.utils import import_string - -from .globals import current_app -from .helpers import get_debug_flag -from .helpers import get_env -from .helpers import get_load_dotenv - -try: - import dotenv -except ImportError: - dotenv = None - -try: - import ssl -except ImportError: - ssl = None # type: ignore - - -class NoAppException(click.UsageError): - """Raised if an application cannot be found or loaded.""" - - -def find_best_app(script_info, module): - """Given a module instance this tries to find the best possible - application in the module or raises an exception. - """ - from . import Flask - - # Search for the most common names first. - for attr_name in ("app", "application"): - app = getattr(module, attr_name, None) - - if isinstance(app, Flask): - return app - - # Otherwise find the only object that is a Flask instance. - matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] - - if len(matches) == 1: - return matches[0] - elif len(matches) > 1: - raise NoAppException( - "Detected multiple Flask applications in module" - f" {module.__name__!r}. Use 'FLASK_APP={module.__name__}:name'" - f" to specify the correct one." - ) - - # Search for app factory functions. - for attr_name in ("create_app", "make_app"): - app_factory = getattr(module, attr_name, None) - - if inspect.isfunction(app_factory): - try: - app = call_factory(script_info, app_factory) - - if isinstance(app, Flask): - return app - except TypeError as e: - if not _called_with_wrong_args(app_factory): - raise - - raise NoAppException( - f"Detected factory {attr_name!r} in module {module.__name__!r}," - " but could not call it without arguments. Use" - f" \"FLASK_APP='{module.__name__}:{attr_name}(args)'\"" - " to specify arguments." - ) from e - - raise NoAppException( - "Failed to find Flask application or factory in module" - f" {module.__name__!r}. Use 'FLASK_APP={module.__name__}:name'" - " to specify one." - ) - - -def call_factory(script_info, app_factory, args=None, kwargs=None): - """Takes an app factory, a ``script_info` object and optionally a tuple - of arguments. Checks for the existence of a script_info argument and calls - the app_factory depending on that and the arguments provided. - """ - sig = inspect.signature(app_factory) - args = [] if args is None else args - kwargs = {} if kwargs is None else kwargs - - if "script_info" in sig.parameters: - warnings.warn( - "The 'script_info' argument is deprecated and will not be" - " passed to the app factory function in Flask 2.1.", - DeprecationWarning, - ) - kwargs["script_info"] = script_info - - if not args and len(sig.parameters) == 1: - first_parameter = next(iter(sig.parameters.values())) - - if ( - first_parameter.default is inspect.Parameter.empty - # **kwargs is reported as an empty default, ignore it - and first_parameter.kind is not inspect.Parameter.VAR_KEYWORD - ): - warnings.warn( - "Script info is deprecated and will not be passed as the" - " single argument to the app factory function in Flask" - " 2.1.", - DeprecationWarning, - ) - args.append(script_info) - - return app_factory(*args, **kwargs) - - -def _called_with_wrong_args(f): - """Check whether calling a function raised a ``TypeError`` because - the call failed or because something in the factory raised the - error. - - :param f: The function that was called. - :return: ``True`` if the call failed. - """ - tb = sys.exc_info()[2] - - try: - while tb is not None: - if tb.tb_frame.f_code is f.__code__: - # In the function, it was called successfully. - return False - - tb = tb.tb_next - - # Didn't reach the function. - return True - finally: - # Delete tb to break a circular reference. - # https://docs.python.org/2/library/sys.html#sys.exc_info - del tb - - -def find_app_by_string(script_info, module, app_name): - """Check if the given string is a variable name or a function. Call - a function to get the app instance, or return the variable directly. - """ - from . import Flask - - # Parse app_name as a single expression to determine if it's a valid - # attribute name or function call. - try: - expr = ast.parse(app_name.strip(), mode="eval").body - except SyntaxError: - raise NoAppException( - f"Failed to parse {app_name!r} as an attribute name or function call." - ) from None - - if isinstance(expr, ast.Name): - name = expr.id - args = kwargs = None - elif isinstance(expr, ast.Call): - # Ensure the function name is an attribute name only. - if not isinstance(expr.func, ast.Name): - raise NoAppException( - f"Function reference must be a simple name: {app_name!r}." - ) - - name = expr.func.id - - # Parse the positional and keyword arguments as literals. - try: - args = [ast.literal_eval(arg) for arg in expr.args] - kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.keywords} - except ValueError: - # literal_eval gives cryptic error messages, show a generic - # message with the full expression instead. - raise NoAppException( - f"Failed to parse arguments as literal values: {app_name!r}." - ) from None - else: - raise NoAppException( - f"Failed to parse {app_name!r} as an attribute name or function call." - ) - - try: - attr = getattr(module, name) - except AttributeError as e: - raise NoAppException( - f"Failed to find attribute {name!r} in {module.__name__!r}." - ) from e - - # If the attribute is a function, call it with any args and kwargs - # to get the real application. - if inspect.isfunction(attr): - try: - app = call_factory(script_info, attr, args, kwargs) - except TypeError as e: - if not _called_with_wrong_args(attr): - raise - - raise NoAppException( - f"The factory {app_name!r} in module" - f" {module.__name__!r} could not be called with the" - " specified arguments." - ) from e - else: - app = attr - - if isinstance(app, Flask): - return app - - raise NoAppException( - "A valid Flask application was not obtained from" - f" '{module.__name__}:{app_name}'." - ) - - -def prepare_import(path): - """Given a filename this will try to calculate the python path, add it - to the search path and return the actual module name that is expected. - """ - path = os.path.realpath(path) - - fname, ext = os.path.splitext(path) - if ext == ".py": - path = fname - - if os.path.basename(path) == "__init__": - path = os.path.dirname(path) - - module_name = [] - - # move up until outside package structure (no __init__.py) - while True: - path, name = os.path.split(path) - module_name.append(name) - - if not os.path.exists(os.path.join(path, "__init__.py")): - break - - if sys.path[0] != path: - sys.path.insert(0, path) - - return ".".join(module_name[::-1]) - - -def locate_app(script_info, module_name, app_name, raise_if_not_found=True): - __traceback_hide__ = True # noqa: F841 - - try: - __import__(module_name) - except ImportError: - # Reraise the ImportError if it occurred within the imported module. - # Determine this by checking whether the trace has a depth > 1. - if sys.exc_info()[2].tb_next: - raise NoAppException( - f"While importing {module_name!r}, an ImportError was" - f" raised:\n\n{traceback.format_exc()}" - ) from None - elif raise_if_not_found: - raise NoAppException(f"Could not import {module_name!r}.") from None - else: - return - - module = sys.modules[module_name] - - if app_name is None: - return find_best_app(script_info, module) - else: - return find_app_by_string(script_info, module, app_name) - - -def get_version(ctx, param, value): - if not value or ctx.resilient_parsing: - return - - import werkzeug - from . import __version__ - - click.echo( - f"Python {platform.python_version()}\n" - f"Flask {__version__}\n" - f"Werkzeug {werkzeug.__version__}", - color=ctx.color, - ) - ctx.exit() - - -version_option = click.Option( - ["--version"], - help="Show the flask version", - expose_value=False, - callback=get_version, - is_flag=True, - is_eager=True, -) - - -class DispatchingApp: - """Special application that dispatches to a Flask application which - is imported by name in a background thread. If an error happens - it is recorded and shown as part of the WSGI handling which in case - of the Werkzeug debugger means that it shows up in the browser. - """ - - def __init__(self, loader, use_eager_loading=None): - self.loader = loader - self._app = None - self._lock = Lock() - self._bg_loading_exc = None - - if use_eager_loading is None: - use_eager_loading = os.environ.get("WERKZEUG_RUN_MAIN") != "true" - - if use_eager_loading: - self._load_unlocked() - else: - self._load_in_background() - - def _load_in_background(self): - def _load_app(): - __traceback_hide__ = True # noqa: F841 - with self._lock: - try: - self._load_unlocked() - except Exception as e: - self._bg_loading_exc = e - - t = Thread(target=_load_app, args=()) - t.start() - - def _flush_bg_loading_exception(self): - __traceback_hide__ = True # noqa: F841 - exc = self._bg_loading_exc - - if exc is not None: - self._bg_loading_exc = None - raise exc - - def _load_unlocked(self): - __traceback_hide__ = True # noqa: F841 - self._app = rv = self.loader() - self._bg_loading_exc = None - return rv - - def __call__(self, environ, start_response): - __traceback_hide__ = True # noqa: F841 - if self._app is not None: - return self._app(environ, start_response) - self._flush_bg_loading_exception() - with self._lock: - if self._app is not None: - rv = self._app - else: - rv = self._load_unlocked() - return rv(environ, start_response) - - -class ScriptInfo: - """Helper object to deal with Flask applications. This is usually not - necessary to interface with as it's used internally in the dispatching - to click. In future versions of Flask this object will most likely play - a bigger role. Typically it's created automatically by the - :class:`FlaskGroup` but you can also manually create it and pass it - onwards as click object. - """ - - def __init__(self, app_import_path=None, create_app=None, set_debug_flag=True): - #: Optionally the import path for the Flask application. - self.app_import_path = app_import_path or os.environ.get("FLASK_APP") - #: Optionally a function that is passed the script info to create - #: the instance of the application. - self.create_app = create_app - #: A dictionary with arbitrary data that can be associated with - #: this script info. - self.data = {} - self.set_debug_flag = set_debug_flag - self._loaded_app = None - - def load_app(self): - """Loads the Flask app (if not yet loaded) and returns it. Calling - this multiple times will just result in the already loaded app to - be returned. - """ - __traceback_hide__ = True # noqa: F841 - - if self._loaded_app is not None: - return self._loaded_app - - if self.create_app is not None: - app = call_factory(self, self.create_app) - else: - if self.app_import_path: - path, name = ( - re.split(r":(?![\\/])", self.app_import_path, 1) + [None] - )[:2] - import_name = prepare_import(path) - app = locate_app(self, import_name, name) - else: - for path in ("wsgi.py", "app.py"): - import_name = prepare_import(path) - app = locate_app(self, import_name, None, raise_if_not_found=False) - - if app: - break - - if not app: - raise NoAppException( - "Could not locate a Flask application. You did not provide " - 'the "FLASK_APP" environment variable, and a "wsgi.py" or ' - '"app.py" module was not found in the current directory.' - ) - - if self.set_debug_flag: - # Update the app's debug flag through the descriptor so that - # other values repopulate as well. - app.debug = get_debug_flag() - - self._loaded_app = app - return app - - -pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) - - -def with_appcontext(f): - """Wraps a callback so that it's guaranteed to be executed with the - script's application context. If callbacks are registered directly - to the ``app.cli`` object then they are wrapped with this function - by default unless it's disabled. - """ - - @click.pass_context - def decorator(__ctx, *args, **kwargs): - with __ctx.ensure_object(ScriptInfo).load_app().app_context(): - return __ctx.invoke(f, *args, **kwargs) - - return update_wrapper(decorator, f) - - -class AppGroup(click.Group): - """This works similar to a regular click :class:`~click.Group` but it - changes the behavior of the :meth:`command` decorator so that it - automatically wraps the functions in :func:`with_appcontext`. - - Not to be confused with :class:`FlaskGroup`. - """ - - def command(self, *args, **kwargs): - """This works exactly like the method of the same name on a regular - :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` - unless it's disabled by passing ``with_appcontext=False``. - """ - wrap_for_ctx = kwargs.pop("with_appcontext", True) - - def decorator(f): - if wrap_for_ctx: - f = with_appcontext(f) - return click.Group.command(self, *args, **kwargs)(f) - - return decorator - - def group(self, *args, **kwargs): - """This works exactly like the method of the same name on a regular - :class:`click.Group` but it defaults the group class to - :class:`AppGroup`. - """ - kwargs.setdefault("cls", AppGroup) - return click.Group.group(self, *args, **kwargs) - - -class FlaskGroup(AppGroup): - """Special subclass of the :class:`AppGroup` group that supports - loading more commands from the configured Flask app. Normally a - developer does not have to interface with this class but there are - some very advanced use cases for which it makes sense to create an - instance of this. see :ref:`custom-scripts`. - - :param add_default_commands: if this is True then the default run and - shell commands will be added. - :param add_version_option: adds the ``--version`` option. - :param create_app: an optional callback that is passed the script info and - returns the loaded app. - :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` - files to set environment variables. Will also change the working - directory to the directory containing the first file found. - :param set_debug_flag: Set the app's debug flag based on the active - environment - - .. versionchanged:: 1.0 - If installed, python-dotenv will be used to load environment variables - from :file:`.env` and :file:`.flaskenv` files. - """ - - def __init__( - self, - add_default_commands=True, - create_app=None, - add_version_option=True, - load_dotenv=True, - set_debug_flag=True, - **extra, - ): - params = list(extra.pop("params", None) or ()) - - if add_version_option: - params.append(version_option) - - AppGroup.__init__(self, params=params, **extra) - self.create_app = create_app - self.load_dotenv = load_dotenv - self.set_debug_flag = set_debug_flag - - if add_default_commands: - self.add_command(run_command) - self.add_command(shell_command) - self.add_command(routes_command) - - self._loaded_plugin_commands = False - - def _load_plugin_commands(self): - if self._loaded_plugin_commands: - return - try: - import pkg_resources - except ImportError: - self._loaded_plugin_commands = True - return - - for ep in pkg_resources.iter_entry_points("flask.commands"): - self.add_command(ep.load(), ep.name) - self._loaded_plugin_commands = True - - def get_command(self, ctx, name): - self._load_plugin_commands() - # Look up built-in and plugin commands, which should be - # available even if the app fails to load. - rv = super().get_command(ctx, name) - - if rv is not None: - return rv - - info = ctx.ensure_object(ScriptInfo) - - # Look up commands provided by the app, showing an error and - # continuing if the app couldn't be loaded. - try: - return info.load_app().cli.get_command(ctx, name) - except NoAppException as e: - click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") - - def list_commands(self, ctx): - self._load_plugin_commands() - # Start with the built-in and plugin commands. - rv = set(super().list_commands(ctx)) - info = ctx.ensure_object(ScriptInfo) - - # Add commands provided by the app, showing an error and - # continuing if the app couldn't be loaded. - try: - rv.update(info.load_app().cli.list_commands(ctx)) - except NoAppException as e: - # When an app couldn't be loaded, show the error message - # without the traceback. - click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") - except Exception: - # When any other errors occurred during loading, show the - # full traceback. - click.secho(f"{traceback.format_exc()}\n", err=True, fg="red") - - return sorted(rv) - - def main(self, *args, **kwargs): - # Set a global flag that indicates that we were invoked from the - # command line interface. This is detected by Flask.run to make the - # call into a no-op. This is necessary to avoid ugly errors when the - # script that is loaded here also attempts to start a server. - os.environ["FLASK_RUN_FROM_CLI"] = "true" - - if get_load_dotenv(self.load_dotenv): - load_dotenv() - - obj = kwargs.get("obj") - - if obj is None: - obj = ScriptInfo( - create_app=self.create_app, set_debug_flag=self.set_debug_flag - ) - - kwargs["obj"] = obj - kwargs.setdefault("auto_envvar_prefix", "FLASK") - return super().main(*args, **kwargs) - - -def _path_is_ancestor(path, other): - """Take ``other`` and remove the length of ``path`` from it. Then join it - to ``path``. If it is the original value, ``path`` is an ancestor of - ``other``.""" - return os.path.join(path, other[len(path) :].lstrip(os.sep)) == other - - -def load_dotenv(path=None): - """Load "dotenv" files in order of precedence to set environment variables. - - If an env var is already set it is not overwritten, so earlier files in the - list are preferred over later files. - - This is a no-op if `python-dotenv`_ is not installed. - - .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme - - :param path: Load the file at this location instead of searching. - :return: ``True`` if a file was loaded. - - .. versionchanged:: 1.1.0 - Returns ``False`` when python-dotenv is not installed, or when - the given path isn't a file. - - .. versionchanged:: 2.0 - When loading the env files, set the default encoding to UTF-8. - - .. versionadded:: 1.0 - """ - if dotenv is None: - if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"): - click.secho( - " * Tip: There are .env or .flaskenv files present." - ' Do "pip install python-dotenv" to use them.', - fg="yellow", - err=True, - ) - - return False - - # if the given path specifies the actual file then return True, - # else False - if path is not None: - if os.path.isfile(path): - return dotenv.load_dotenv(path, encoding="utf-8") - - return False - - new_dir = None - - for name in (".env", ".flaskenv"): - path = dotenv.find_dotenv(name, usecwd=True) - - if not path: - continue - - if new_dir is None: - new_dir = os.path.dirname(path) - - dotenv.load_dotenv(path, encoding="utf-8") - - return new_dir is not None # at least one file was located and loaded - - -def show_server_banner(env, debug, app_import_path, eager_loading): - """Show extra startup messages the first time the server is run, - ignoring the reloader. - """ - if os.environ.get("WERKZEUG_RUN_MAIN") == "true": - return - - if app_import_path is not None: - message = f" * Serving Flask app {app_import_path!r}" - - if not eager_loading: - message += " (lazy loading)" - - click.echo(message) - - click.echo(f" * Environment: {env}") - - if env == "production": - click.secho( - " WARNING: This is a development server. Do not use it in" - " a production deployment.", - fg="red", - ) - click.secho(" Use a production WSGI server instead.", dim=True) - - if debug is not None: - click.echo(f" * Debug mode: {'on' if debug else 'off'}") - - -class CertParamType(click.ParamType): - """Click option type for the ``--cert`` option. Allows either an - existing file, the string ``'adhoc'``, or an import for a - :class:`~ssl.SSLContext` object. - """ - - name = "path" - - def __init__(self): - self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) - - def convert(self, value, param, ctx): - if ssl is None: - raise click.BadParameter( - 'Using "--cert" requires Python to be compiled with SSL support.', - ctx, - param, - ) - - try: - return self.path_type(value, param, ctx) - except click.BadParameter: - value = click.STRING(value, param, ctx).lower() - - if value == "adhoc": - try: - import cryptography # noqa: F401 - except ImportError: - raise click.BadParameter( - "Using ad-hoc certificates requires the cryptography library.", - ctx, - param, - ) from None - - return value - - obj = import_string(value, silent=True) - - if isinstance(obj, ssl.SSLContext): - return obj - - raise - - -def _validate_key(ctx, param, value): - """The ``--key`` option must be specified when ``--cert`` is a file. - Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. - """ - cert = ctx.params.get("cert") - is_adhoc = cert == "adhoc" - is_context = ssl and isinstance(cert, ssl.SSLContext) - - if value is not None: - if is_adhoc: - raise click.BadParameter( - 'When "--cert" is "adhoc", "--key" is not used.', ctx, param - ) - - if is_context: - raise click.BadParameter( - 'When "--cert" is an SSLContext object, "--key is not used.', ctx, param - ) - - if not cert: - raise click.BadParameter('"--cert" must also be specified.', ctx, param) - - ctx.params["cert"] = cert, value - - else: - if cert and not (is_adhoc or is_context): - raise click.BadParameter('Required when using "--cert".', ctx, param) - - return value - - -class SeparatedPathType(click.Path): - """Click option type that accepts a list of values separated by the - OS's path separator (``:``, ``;`` on Windows). Each value is - validated as a :class:`click.Path` type. - """ - - def convert(self, value, param, ctx): - items = self.split_envvar_value(value) - super_convert = super().convert - return [super_convert(item, param, ctx) for item in items] - - -@click.command("run", short_help="Run a development server.") -@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.") -@click.option("--port", "-p", default=5000, help="The port to bind to.") -@click.option( - "--cert", type=CertParamType(), help="Specify a certificate file to use HTTPS." -) -@click.option( - "--key", - type=click.Path(exists=True, dir_okay=False, resolve_path=True), - callback=_validate_key, - expose_value=False, - help="The key file to use when specifying a certificate.", -) -@click.option( - "--reload/--no-reload", - default=None, - help="Enable or disable the reloader. By default the reloader " - "is active if debug is enabled.", -) -@click.option( - "--debugger/--no-debugger", - default=None, - help="Enable or disable the debugger. By default the debugger " - "is active if debug is enabled.", -) -@click.option( - "--eager-loading/--lazy-loading", - default=None, - help="Enable or disable eager loading. By default eager " - "loading is enabled if the reloader is disabled.", -) -@click.option( - "--with-threads/--without-threads", - default=True, - help="Enable or disable multithreading.", -) -@click.option( - "--extra-files", - default=None, - type=SeparatedPathType(), - help=( - "Extra files that trigger a reload on change. Multiple paths" - f" are separated by {os.path.pathsep!r}." - ), -) -@pass_script_info -def run_command( - info, host, port, reload, debugger, eager_loading, with_threads, cert, extra_files -): - """Run a local development server. - - This server is for development purposes only. It does not provide - the stability, security, or performance of production WSGI servers. - - The reloader and debugger are enabled by default if - FLASK_ENV=development or FLASK_DEBUG=1. - """ - debug = get_debug_flag() - - if reload is None: - reload = debug - - if debugger is None: - debugger = debug - - show_server_banner(get_env(), debug, info.app_import_path, eager_loading) - app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) - - from werkzeug.serving import run_simple - - run_simple( - host, - port, - app, - use_reloader=reload, - use_debugger=debugger, - threaded=with_threads, - ssl_context=cert, - extra_files=extra_files, - ) - - -@click.command("shell", short_help="Run a shell in the app context.") -@with_appcontext -def shell_command() -> None: - """Run an interactive Python shell in the context of a given - Flask application. The application will populate the default - namespace of this shell according to its configuration. - - This is useful for executing small snippets of management code - without having to manually configure the application. - """ - import code - from .globals import _app_ctx_stack - - app = _app_ctx_stack.top.app - banner = ( - f"Python {sys.version} on {sys.platform}\n" - f"App: {app.import_name} [{app.env}]\n" - f"Instance: {app.instance_path}" - ) - ctx: dict = {} - - # Support the regular Python interpreter startup script if someone - # is using it. - startup = os.environ.get("PYTHONSTARTUP") - if startup and os.path.isfile(startup): - with open(startup) as f: - eval(compile(f.read(), startup, "exec"), ctx) - - ctx.update(app.make_shell_context()) - - # Site, customize, or startup script can set a hook to call when - # entering interactive mode. The default one sets up readline with - # tab and history completion. - interactive_hook = getattr(sys, "__interactivehook__", None) - - if interactive_hook is not None: - try: - import readline - from rlcompleter import Completer - except ImportError: - pass - else: - # rlcompleter uses __main__.__dict__ by default, which is - # flask.__main__. Use the shell context instead. - readline.set_completer(Completer(ctx).complete) - - interactive_hook() - - code.interact(banner=banner, local=ctx) - - -@click.command("routes", short_help="Show the routes for the app.") -@click.option( - "--sort", - "-s", - type=click.Choice(("endpoint", "methods", "rule", "match")), - default="endpoint", - help=( - 'Method to sort routes by. "match" is the order that Flask will match ' - "routes when dispatching a request." - ), -) -@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") -@with_appcontext -def routes_command(sort: str, all_methods: bool) -> None: - """Show all registered routes with endpoints and methods.""" - - rules = list(current_app.url_map.iter_rules()) - if not rules: - click.echo("No routes were registered.") - return - - ignored_methods = set(() if all_methods else ("HEAD", "OPTIONS")) - - if sort in ("endpoint", "rule"): - rules = sorted(rules, key=attrgetter(sort)) - elif sort == "methods": - rules = sorted(rules, key=lambda rule: sorted(rule.methods)) # type: ignore - - rule_methods = [ - ", ".join(sorted(rule.methods - ignored_methods)) # type: ignore - for rule in rules - ] - - headers = ("Endpoint", "Methods", "Rule") - widths = ( - max(len(rule.endpoint) for rule in rules), - max(len(methods) for methods in rule_methods), - max(len(rule.rule) for rule in rules), - ) - widths = [max(len(h), w) for h, w in zip(headers, widths)] - row = "{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}".format(*widths) - - click.echo(row.format(*headers).strip()) - click.echo(row.format(*("-" * width for width in widths))) - - for rule, methods in zip(rules, rule_methods): - click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) - - -cli = FlaskGroup( - help="""\ -A general utility script for Flask applications. - -Provides commands from Flask, extensions, and the application. Loads the -application defined in the FLASK_APP environment variable, or from a wsgi.py -file. Setting the FLASK_ENV environment variable to 'development' will enable -debug mode. - -\b - {prefix}{cmd} FLASK_APP=hello.py - {prefix}{cmd} FLASK_ENV=development - {prefix}flask run -""".format( - cmd="export" if os.name == "posix" else "set", - prefix="$ " if os.name == "posix" else "> ", - ) -) - - -def main() -> None: - if int(click.__version__[0]) < 8: - warnings.warn( - "Using the `flask` cli with Click 7 is deprecated and" - " will not be supported starting with Flask 2.1." - " Please upgrade to Click 8 as soon as possible.", - DeprecationWarning, - ) - # TODO omit sys.argv once https://github.com/pallets/click/issues/536 is fixed - cli.main(args=sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.7/site-packages/flask/config.py b/venv/lib/python3.7/site-packages/flask/config.py deleted file mode 100644 index ca76902..0000000 --- a/venv/lib/python3.7/site-packages/flask/config.py +++ /dev/null @@ -1,295 +0,0 @@ -import errno -import os -import types -import typing as t - -from werkzeug.utils import import_string - - -class ConfigAttribute: - """Makes an attribute forward to the config""" - - def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None: - self.__name__ = name - self.get_converter = get_converter - - def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any: - if obj is None: - return self - rv = obj.config[self.__name__] - if self.get_converter is not None: - rv = self.get_converter(rv) - return rv - - def __set__(self, obj: t.Any, value: t.Any) -> None: - obj.config[self.__name__] = value - - -class Config(dict): - """Works exactly like a dict but provides ways to fill it from files - or special dictionaries. There are two common patterns to populate the - config. - - Either you can fill the config from a config file:: - - app.config.from_pyfile('yourconfig.cfg') - - Or alternatively you can define the configuration options in the - module that calls :meth:`from_object` or provide an import path to - a module that should be loaded. It is also possible to tell it to - use the same module and with that provide the configuration values - just before the call:: - - DEBUG = True - SECRET_KEY = 'development key' - app.config.from_object(__name__) - - In both cases (loading from any Python file or loading from modules), - only uppercase keys are added to the config. This makes it possible to use - lowercase values in the config file for temporary values that are not added - to the config or to define the config keys in the same file that implements - the application. - - Probably the most interesting way to load configurations is from an - environment variable pointing to a file:: - - app.config.from_envvar('YOURAPPLICATION_SETTINGS') - - In this case before launching the application you have to set this - environment variable to the file you want to use. On Linux and OS X - use the export statement:: - - export YOURAPPLICATION_SETTINGS='/path/to/config/file' - - On windows use `set` instead. - - :param root_path: path to which files are read relative from. When the - config object is created by the application, this is - the application's :attr:`~flask.Flask.root_path`. - :param defaults: an optional dictionary of default values - """ - - def __init__(self, root_path: str, defaults: t.Optional[dict] = None) -> None: - dict.__init__(self, defaults or {}) - self.root_path = root_path - - def from_envvar(self, variable_name: str, silent: bool = False) -> bool: - """Loads a configuration from an environment variable pointing to - a configuration file. This is basically just a shortcut with nicer - error messages for this line of code:: - - app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) - - :param variable_name: name of the environment variable - :param silent: set to ``True`` if you want silent failure for missing - files. - :return: ``True`` if the file was loaded successfully. - """ - rv = os.environ.get(variable_name) - if not rv: - if silent: - return False - raise RuntimeError( - f"The environment variable {variable_name!r} is not set" - " and as such configuration could not be loaded. Set" - " this variable and make it point to a configuration" - " file" - ) - return self.from_pyfile(rv, silent=silent) - - def from_pyfile(self, filename: str, silent: bool = False) -> bool: - """Updates the values in the config from a Python file. This function - behaves as if the file was imported as module with the - :meth:`from_object` function. - - :param filename: the filename of the config. This can either be an - absolute filename or a filename relative to the - root path. - :param silent: set to ``True`` if you want silent failure for missing - files. - :return: ``True`` if the file was loaded successfully. - - .. versionadded:: 0.7 - `silent` parameter. - """ - filename = os.path.join(self.root_path, filename) - d = types.ModuleType("config") - d.__file__ = filename - try: - with open(filename, mode="rb") as config_file: - exec(compile(config_file.read(), filename, "exec"), d.__dict__) - except OSError as e: - if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): - return False - e.strerror = f"Unable to load configuration file ({e.strerror})" - raise - self.from_object(d) - return True - - def from_object(self, obj: t.Union[object, str]) -> None: - """Updates the values from the given object. An object can be of one - of the following two types: - - - a string: in this case the object with that name will be imported - - an actual object reference: that object is used directly - - Objects are usually either modules or classes. :meth:`from_object` - loads only the uppercase attributes of the module/class. A ``dict`` - object will not work with :meth:`from_object` because the keys of a - ``dict`` are not attributes of the ``dict`` class. - - Example of module-based configuration:: - - app.config.from_object('yourapplication.default_config') - from yourapplication import default_config - app.config.from_object(default_config) - - Nothing is done to the object before loading. If the object is a - class and has ``@property`` attributes, it needs to be - instantiated before being passed to this method. - - You should not use this function to load the actual configuration but - rather configuration defaults. The actual config should be loaded - with :meth:`from_pyfile` and ideally from a location not within the - package because the package might be installed system wide. - - See :ref:`config-dev-prod` for an example of class-based configuration - using :meth:`from_object`. - - :param obj: an import name or object - """ - if isinstance(obj, str): - obj = import_string(obj) - for key in dir(obj): - if key.isupper(): - self[key] = getattr(obj, key) - - def from_file( - self, - filename: str, - load: t.Callable[[t.IO[t.Any]], t.Mapping], - silent: bool = False, - ) -> bool: - """Update the values in the config from a file that is loaded - using the ``load`` parameter. The loaded data is passed to the - :meth:`from_mapping` method. - - .. code-block:: python - - import toml - app.config.from_file("config.toml", load=toml.load) - - :param filename: The path to the data file. This can be an - absolute path or relative to the config root path. - :param load: A callable that takes a file handle and returns a - mapping of loaded data from the file. - :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` - implements a ``read`` method. - :param silent: Ignore the file if it doesn't exist. - :return: ``True`` if the file was loaded successfully. - - .. versionadded:: 2.0 - """ - filename = os.path.join(self.root_path, filename) - - try: - with open(filename) as f: - obj = load(f) - except OSError as e: - if silent and e.errno in (errno.ENOENT, errno.EISDIR): - return False - - e.strerror = f"Unable to load configuration file ({e.strerror})" - raise - - return self.from_mapping(obj) - - def from_json(self, filename: str, silent: bool = False) -> bool: - """Update the values in the config from a JSON file. The loaded - data is passed to the :meth:`from_mapping` method. - - :param filename: The path to the JSON file. This can be an - absolute path or relative to the config root path. - :param silent: Ignore the file if it doesn't exist. - :return: ``True`` if the file was loaded successfully. - - .. deprecated:: 2.0.0 - Will be removed in Flask 2.1. Use :meth:`from_file` instead. - This was removed early in 2.0.0, was added back in 2.0.1. - - .. versionadded:: 0.11 - """ - import warnings - from . import json - - warnings.warn( - "'from_json' is deprecated and will be removed in Flask" - " 2.1. Use 'from_file(path, json.load)' instead.", - DeprecationWarning, - stacklevel=2, - ) - return self.from_file(filename, json.load, silent=silent) - - def from_mapping( - self, mapping: t.Optional[t.Mapping[str, t.Any]] = None, **kwargs: t.Any - ) -> bool: - """Updates the config like :meth:`update` ignoring items with non-upper - keys. - :return: Always returns ``True``. - - .. versionadded:: 0.11 - """ - mappings: t.Dict[str, t.Any] = {} - if mapping is not None: - mappings.update(mapping) - mappings.update(kwargs) - for key, value in mappings.items(): - if key.isupper(): - self[key] = value - return True - - def get_namespace( - self, namespace: str, lowercase: bool = True, trim_namespace: bool = True - ) -> t.Dict[str, t.Any]: - """Returns a dictionary containing a subset of configuration options - that match the specified namespace/prefix. Example usage:: - - app.config['IMAGE_STORE_TYPE'] = 'fs' - app.config['IMAGE_STORE_PATH'] = '/var/app/images' - app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' - image_store_config = app.config.get_namespace('IMAGE_STORE_') - - The resulting dictionary `image_store_config` would look like:: - - { - 'type': 'fs', - 'path': '/var/app/images', - 'base_url': 'http://img.website.com' - } - - This is often useful when configuration options map directly to - keyword arguments in functions or class constructors. - - :param namespace: a configuration namespace - :param lowercase: a flag indicating if the keys of the resulting - dictionary should be lowercase - :param trim_namespace: a flag indicating if the keys of the resulting - dictionary should not include the namespace - - .. versionadded:: 0.11 - """ - rv = {} - for k, v in self.items(): - if not k.startswith(namespace): - continue - if trim_namespace: - key = k[len(namespace) :] - else: - key = k - if lowercase: - key = key.lower() - rv[key] = v - return rv - - def __repr__(self) -> str: - return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/venv/lib/python3.7/site-packages/flask/ctx.py b/venv/lib/python3.7/site-packages/flask/ctx.py deleted file mode 100644 index 47465fd..0000000 --- a/venv/lib/python3.7/site-packages/flask/ctx.py +++ /dev/null @@ -1,489 +0,0 @@ -import sys -import typing as t -from functools import update_wrapper -from types import TracebackType - -from werkzeug.exceptions import HTTPException - -from .globals import _app_ctx_stack -from .globals import _request_ctx_stack -from .signals import appcontext_popped -from .signals import appcontext_pushed -from .typing import AfterRequestCallable - -if t.TYPE_CHECKING: - from .app import Flask - from .sessions import SessionMixin - from .wrappers import Request - - -# a singleton sentinel value for parameter defaults -_sentinel = object() - - -class _AppCtxGlobals: - """A plain object. Used as a namespace for storing data during an - application context. - - Creating an app context automatically creates this object, which is - made available as the :data:`g` proxy. - - .. describe:: 'key' in g - - Check whether an attribute is present. - - .. versionadded:: 0.10 - - .. describe:: iter(g) - - Return an iterator over the attribute names. - - .. versionadded:: 0.10 - """ - - # Define attr methods to let mypy know this is a namespace object - # that has arbitrary attributes. - - def __getattr__(self, name: str) -> t.Any: - try: - return self.__dict__[name] - except KeyError: - raise AttributeError(name) from None - - def __setattr__(self, name: str, value: t.Any) -> None: - self.__dict__[name] = value - - def __delattr__(self, name: str) -> None: - try: - del self.__dict__[name] - except KeyError: - raise AttributeError(name) from None - - def get(self, name: str, default: t.Optional[t.Any] = None) -> t.Any: - """Get an attribute by name, or a default value. Like - :meth:`dict.get`. - - :param name: Name of attribute to get. - :param default: Value to return if the attribute is not present. - - .. versionadded:: 0.10 - """ - return self.__dict__.get(name, default) - - def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: - """Get and remove an attribute by name. Like :meth:`dict.pop`. - - :param name: Name of attribute to pop. - :param default: Value to return if the attribute is not present, - instead of raising a ``KeyError``. - - .. versionadded:: 0.11 - """ - if default is _sentinel: - return self.__dict__.pop(name) - else: - return self.__dict__.pop(name, default) - - def setdefault(self, name: str, default: t.Any = None) -> t.Any: - """Get the value of an attribute if it is present, otherwise - set and return a default value. Like :meth:`dict.setdefault`. - - :param name: Name of attribute to get. - :param default: Value to set and return if the attribute is not - present. - - .. versionadded:: 0.11 - """ - return self.__dict__.setdefault(name, default) - - def __contains__(self, item: str) -> bool: - return item in self.__dict__ - - def __iter__(self) -> t.Iterator[str]: - return iter(self.__dict__) - - def __repr__(self) -> str: - top = _app_ctx_stack.top - if top is not None: - return f"" - return object.__repr__(self) - - -def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable: - """Executes a function after this request. This is useful to modify - response objects. The function is passed the response object and has - to return the same or a new one. - - Example:: - - @app.route('/') - def index(): - @after_this_request - def add_header(response): - response.headers['X-Foo'] = 'Parachute' - return response - return 'Hello World!' - - This is more useful if a function other than the view function wants to - modify a response. For instance think of a decorator that wants to add - some headers without converting the return value into a response object. - - .. versionadded:: 0.9 - """ - top = _request_ctx_stack.top - - if top is None: - raise RuntimeError( - "This decorator can only be used when a request context is" - " active, such as within a view function." - ) - - top._after_request_functions.append(f) - return f - - -def copy_current_request_context(f: t.Callable) -> t.Callable: - """A helper function that decorates a function to retain the current - request context. This is useful when working with greenlets. The moment - the function is decorated a copy of the request context is created and - then pushed when the function is called. The current session is also - included in the copied request context. - - Example:: - - import gevent - from flask import copy_current_request_context - - @app.route('/') - def index(): - @copy_current_request_context - def do_some_work(): - # do some work here, it can access flask.request or - # flask.session like you would otherwise in the view function. - ... - gevent.spawn(do_some_work) - return 'Regular response' - - .. versionadded:: 0.10 - """ - top = _request_ctx_stack.top - - if top is None: - raise RuntimeError( - "This decorator can only be used when a request context is" - " active, such as within a view function." - ) - - reqctx = top.copy() - - def wrapper(*args, **kwargs): - with reqctx: - return f(*args, **kwargs) - - return update_wrapper(wrapper, f) - - -def has_request_context() -> bool: - """If you have code that wants to test if a request context is there or - not this function can be used. For instance, you may want to take advantage - of request information if the request object is available, but fail - silently if it is unavailable. - - :: - - class User(db.Model): - - def __init__(self, username, remote_addr=None): - self.username = username - if remote_addr is None and has_request_context(): - remote_addr = request.remote_addr - self.remote_addr = remote_addr - - Alternatively you can also just test any of the context bound objects - (such as :class:`request` or :class:`g`) for truthness:: - - class User(db.Model): - - def __init__(self, username, remote_addr=None): - self.username = username - if remote_addr is None and request: - remote_addr = request.remote_addr - self.remote_addr = remote_addr - - .. versionadded:: 0.7 - """ - return _request_ctx_stack.top is not None - - -def has_app_context() -> bool: - """Works like :func:`has_request_context` but for the application - context. You can also just do a boolean check on the - :data:`current_app` object instead. - - .. versionadded:: 0.9 - """ - return _app_ctx_stack.top is not None - - -class AppContext: - """The application context binds an application object implicitly - to the current thread or greenlet, similar to how the - :class:`RequestContext` binds request information. The application - context is also implicitly created if a request context is created - but the application is not on top of the individual application - context. - """ - - def __init__(self, app: "Flask") -> None: - self.app = app - self.url_adapter = app.create_url_adapter(None) - self.g = app.app_ctx_globals_class() - - # Like request context, app contexts can be pushed multiple times - # but there a basic "refcount" is enough to track them. - self._refcnt = 0 - - def push(self) -> None: - """Binds the app context to the current context.""" - self._refcnt += 1 - _app_ctx_stack.push(self) - appcontext_pushed.send(self.app) - - def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore - """Pops the app context.""" - try: - self._refcnt -= 1 - if self._refcnt <= 0: - if exc is _sentinel: - exc = sys.exc_info()[1] - self.app.do_teardown_appcontext(exc) - finally: - rv = _app_ctx_stack.pop() - assert rv is self, f"Popped wrong app context. ({rv!r} instead of {self!r})" - appcontext_popped.send(self.app) - - def __enter__(self) -> "AppContext": - self.push() - return self - - def __exit__( - self, exc_type: type, exc_value: BaseException, tb: TracebackType - ) -> None: - self.pop(exc_value) - - -class RequestContext: - """The request context contains all request relevant information. It is - created at the beginning of the request and pushed to the - `_request_ctx_stack` and removed at the end of it. It will create the - URL adapter and request object for the WSGI environment provided. - - Do not attempt to use this class directly, instead use - :meth:`~flask.Flask.test_request_context` and - :meth:`~flask.Flask.request_context` to create this object. - - When the request context is popped, it will evaluate all the - functions registered on the application for teardown execution - (:meth:`~flask.Flask.teardown_request`). - - The request context is automatically popped at the end of the request - for you. In debug mode the request context is kept around if - exceptions happen so that interactive debuggers have a chance to - introspect the data. With 0.4 this can also be forced for requests - that did not fail and outside of ``DEBUG`` mode. By setting - ``'flask._preserve_context'`` to ``True`` on the WSGI environment the - context will not pop itself at the end of the request. This is used by - the :meth:`~flask.Flask.test_client` for example to implement the - deferred cleanup functionality. - - You might find this helpful for unittests where you need the - information from the context local around for a little longer. Make - sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in - that situation, otherwise your unittests will leak memory. - """ - - def __init__( - self, - app: "Flask", - environ: dict, - request: t.Optional["Request"] = None, - session: t.Optional["SessionMixin"] = None, - ) -> None: - self.app = app - if request is None: - request = app.request_class(environ) - self.request = request - self.url_adapter = None - try: - self.url_adapter = app.create_url_adapter(self.request) - except HTTPException as e: - self.request.routing_exception = e - self.flashes = None - self.session = session - - # Request contexts can be pushed multiple times and interleaved with - # other request contexts. Now only if the last level is popped we - # get rid of them. Additionally if an application context is missing - # one is created implicitly so for each level we add this information - self._implicit_app_ctx_stack: t.List[t.Optional["AppContext"]] = [] - - # indicator if the context was preserved. Next time another context - # is pushed the preserved context is popped. - self.preserved = False - - # remembers the exception for pop if there is one in case the context - # preservation kicks in. - self._preserved_exc = None - - # Functions that should be executed after the request on the response - # object. These will be called before the regular "after_request" - # functions. - self._after_request_functions: t.List[AfterRequestCallable] = [] - - @property - def g(self) -> AppContext: - return _app_ctx_stack.top.g - - @g.setter - def g(self, value: AppContext) -> None: - _app_ctx_stack.top.g = value - - def copy(self) -> "RequestContext": - """Creates a copy of this request context with the same request object. - This can be used to move a request context to a different greenlet. - Because the actual request object is the same this cannot be used to - move a request context to a different thread unless access to the - request object is locked. - - .. versionadded:: 0.10 - - .. versionchanged:: 1.1 - The current session object is used instead of reloading the original - data. This prevents `flask.session` pointing to an out-of-date object. - """ - return self.__class__( - self.app, - environ=self.request.environ, - request=self.request, - session=self.session, - ) - - def match_request(self) -> None: - """Can be overridden by a subclass to hook into the matching - of the request. - """ - try: - result = self.url_adapter.match(return_rule=True) # type: ignore - self.request.url_rule, self.request.view_args = result # type: ignore - except HTTPException as e: - self.request.routing_exception = e - - def push(self) -> None: - """Binds the request context to the current context.""" - # If an exception occurs in debug mode or if context preservation is - # activated under exception situations exactly one context stays - # on the stack. The rationale is that you want to access that - # information under debug situations. However if someone forgets to - # pop that context again we want to make sure that on the next push - # it's invalidated, otherwise we run at risk that something leaks - # memory. This is usually only a problem in test suite since this - # functionality is not active in production environments. - top = _request_ctx_stack.top - if top is not None and top.preserved: - top.pop(top._preserved_exc) - - # Before we push the request context we have to ensure that there - # is an application context. - app_ctx = _app_ctx_stack.top - if app_ctx is None or app_ctx.app != self.app: - app_ctx = self.app.app_context() - app_ctx.push() - self._implicit_app_ctx_stack.append(app_ctx) - else: - self._implicit_app_ctx_stack.append(None) - - _request_ctx_stack.push(self) - - # Open the session at the moment that the request context is available. - # This allows a custom open_session method to use the request context. - # Only open a new session if this is the first time the request was - # pushed, otherwise stream_with_context loses the session. - if self.session is None: - session_interface = self.app.session_interface - self.session = session_interface.open_session(self.app, self.request) - - if self.session is None: - self.session = session_interface.make_null_session(self.app) - - # Match the request URL after loading the session, so that the - # session is available in custom URL converters. - if self.url_adapter is not None: - self.match_request() - - def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore - """Pops the request context and unbinds it by doing that. This will - also trigger the execution of functions registered by the - :meth:`~flask.Flask.teardown_request` decorator. - - .. versionchanged:: 0.9 - Added the `exc` argument. - """ - app_ctx = self._implicit_app_ctx_stack.pop() - clear_request = False - - try: - if not self._implicit_app_ctx_stack: - self.preserved = False - self._preserved_exc = None - if exc is _sentinel: - exc = sys.exc_info()[1] - self.app.do_teardown_request(exc) - - request_close = getattr(self.request, "close", None) - if request_close is not None: - request_close() - clear_request = True - finally: - rv = _request_ctx_stack.pop() - - # get rid of circular dependencies at the end of the request - # so that we don't require the GC to be active. - if clear_request: - rv.request.environ["werkzeug.request"] = None - - # Get rid of the app as well if necessary. - if app_ctx is not None: - app_ctx.pop(exc) - - assert ( - rv is self - ), f"Popped wrong request context. ({rv!r} instead of {self!r})" - - def auto_pop(self, exc: t.Optional[BaseException]) -> None: - if self.request.environ.get("flask._preserve_context") or ( - exc is not None and self.app.preserve_context_on_exception - ): - self.preserved = True - self._preserved_exc = exc # type: ignore - else: - self.pop(exc) - - def __enter__(self) -> "RequestContext": - self.push() - return self - - def __exit__( - self, exc_type: type, exc_value: BaseException, tb: TracebackType - ) -> None: - # do not pop the request stack if we are in debug mode and an - # exception happened. This will allow the debugger to still - # access the request object in the interactive shell. Furthermore - # the context can be force kept alive for the test client. - # See flask.testing for how this works. - self.auto_pop(exc_value) - - def __repr__(self) -> str: - return ( - f"<{type(self).__name__} {self.request.url!r}" - f" [{self.request.method}] of {self.app.name}>" - ) diff --git a/venv/lib/python3.7/site-packages/flask/debughelpers.py b/venv/lib/python3.7/site-packages/flask/debughelpers.py deleted file mode 100644 index 212f7d7..0000000 --- a/venv/lib/python3.7/site-packages/flask/debughelpers.py +++ /dev/null @@ -1,172 +0,0 @@ -import os -import typing as t -from warnings import warn - -from .app import Flask -from .blueprints import Blueprint -from .globals import _request_ctx_stack - - -class UnexpectedUnicodeError(AssertionError, UnicodeError): - """Raised in places where we want some better error reporting for - unexpected unicode or binary data. - """ - - -class DebugFilesKeyError(KeyError, AssertionError): - """Raised from request.files during debugging. The idea is that it can - provide a better error message than just a generic KeyError/BadRequest. - """ - - def __init__(self, request, key): - form_matches = request.form.getlist(key) - buf = [ - f"You tried to access the file {key!r} in the request.files" - " dictionary but it does not exist. The mimetype for the" - f" request is {request.mimetype!r} instead of" - " 'multipart/form-data' which means that no file contents" - " were transmitted. To fix this error you should provide" - ' enctype="multipart/form-data" in your form.' - ] - if form_matches: - names = ", ".join(repr(x) for x in form_matches) - buf.append( - "\n\nThe browser instead transmitted some file names. " - f"This was submitted: {names}" - ) - self.msg = "".join(buf) - - def __str__(self): - return self.msg - - -class FormDataRoutingRedirect(AssertionError): - """This exception is raised by Flask in debug mode if it detects a - redirect caused by the routing system when the request method is not - GET, HEAD or OPTIONS. Reasoning: form data will be dropped. - """ - - def __init__(self, request): - exc = request.routing_exception - buf = [ - f"A request was sent to this URL ({request.url}) but a" - " redirect was issued automatically by the routing system" - f" to {exc.new_url!r}." - ] - - # In case just a slash was appended we can be extra helpful - if f"{request.base_url}/" == exc.new_url.split("?")[0]: - buf.append( - " The URL was defined with a trailing slash so Flask" - " will automatically redirect to the URL with the" - " trailing slash if it was accessed without one." - ) - - buf.append( - " Make sure to directly send your" - f" {request.method}-request to this URL since we can't make" - " browsers or HTTP clients redirect with form data reliably" - " or without user interaction." - ) - buf.append("\n\nNote: this exception is only raised in debug mode") - AssertionError.__init__(self, "".join(buf).encode("utf-8")) - - -def attach_enctype_error_multidict(request): - """Since Flask 0.8 we're monkeypatching the files object in case a - request is detected that does not use multipart form data but the files - object is accessed. - """ - oldcls = request.files.__class__ - - class newcls(oldcls): - def __getitem__(self, key): - try: - return oldcls.__getitem__(self, key) - except KeyError as e: - if key not in request.form: - raise - - raise DebugFilesKeyError(request, key) from e - - newcls.__name__ = oldcls.__name__ - newcls.__module__ = oldcls.__module__ - request.files.__class__ = newcls - - -def _dump_loader_info(loader) -> t.Generator: - yield f"class: {type(loader).__module__}.{type(loader).__name__}" - for key, value in sorted(loader.__dict__.items()): - if key.startswith("_"): - continue - if isinstance(value, (tuple, list)): - if not all(isinstance(x, str) for x in value): - continue - yield f"{key}:" - for item in value: - yield f" - {item}" - continue - elif not isinstance(value, (str, int, float, bool)): - continue - yield f"{key}: {value!r}" - - -def explain_template_loading_attempts(app: Flask, template, attempts) -> None: - """This should help developers understand what failed""" - info = [f"Locating template {template!r}:"] - total_found = 0 - blueprint = None - reqctx = _request_ctx_stack.top - if reqctx is not None and reqctx.request.blueprint is not None: - blueprint = reqctx.request.blueprint - - for idx, (loader, srcobj, triple) in enumerate(attempts): - if isinstance(srcobj, Flask): - src_info = f"application {srcobj.import_name!r}" - elif isinstance(srcobj, Blueprint): - src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" - else: - src_info = repr(srcobj) - - info.append(f"{idx + 1:5}: trying loader of {src_info}") - - for line in _dump_loader_info(loader): - info.append(f" {line}") - - if triple is None: - detail = "no match" - else: - detail = f"found ({triple[1] or ''!r})" - total_found += 1 - info.append(f" -> {detail}") - - seems_fishy = False - if total_found == 0: - info.append("Error: the template could not be found.") - seems_fishy = True - elif total_found > 1: - info.append("Warning: multiple loaders returned a match for the template.") - seems_fishy = True - - if blueprint is not None and seems_fishy: - info.append( - " The template was looked up from an endpoint that belongs" - f" to the blueprint {blueprint!r}." - ) - info.append(" Maybe you did not place a template in the right folder?") - info.append(" See https://flask.palletsprojects.com/blueprints/#templates") - - app.logger.info("\n".join(info)) - - -def explain_ignored_app_run() -> None: - if os.environ.get("WERKZEUG_RUN_MAIN") != "true": - warn( - Warning( - "Silently ignoring app.run() because the application is" - " run from the flask command line executable. Consider" - ' putting app.run() behind an if __name__ == "__main__"' - " guard to silence this warning." - ), - stacklevel=3, - ) diff --git a/venv/lib/python3.7/site-packages/flask/globals.py b/venv/lib/python3.7/site-packages/flask/globals.py deleted file mode 100644 index 6d91c75..0000000 --- a/venv/lib/python3.7/site-packages/flask/globals.py +++ /dev/null @@ -1,59 +0,0 @@ -import typing as t -from functools import partial - -from werkzeug.local import LocalProxy -from werkzeug.local import LocalStack - -if t.TYPE_CHECKING: - from .app import Flask - from .ctx import _AppCtxGlobals - from .sessions import SessionMixin - from .wrappers import Request - -_request_ctx_err_msg = """\ -Working outside of request context. - -This typically means that you attempted to use functionality that needed -an active HTTP request. Consult the documentation on testing for -information about how to avoid this problem.\ -""" -_app_ctx_err_msg = """\ -Working outside of application context. - -This typically means that you attempted to use functionality that needed -to interface with the current application object in some way. To solve -this, set up an application context with app.app_context(). See the -documentation for more information.\ -""" - - -def _lookup_req_object(name): - top = _request_ctx_stack.top - if top is None: - raise RuntimeError(_request_ctx_err_msg) - return getattr(top, name) - - -def _lookup_app_object(name): - top = _app_ctx_stack.top - if top is None: - raise RuntimeError(_app_ctx_err_msg) - return getattr(top, name) - - -def _find_app(): - top = _app_ctx_stack.top - if top is None: - raise RuntimeError(_app_ctx_err_msg) - return top.app - - -# context locals -_request_ctx_stack = LocalStack() -_app_ctx_stack = LocalStack() -current_app: "Flask" = LocalProxy(_find_app) # type: ignore -request: "Request" = LocalProxy(partial(_lookup_req_object, "request")) # type: ignore -session: "SessionMixin" = LocalProxy( # type: ignore - partial(_lookup_req_object, "session") -) -g: "_AppCtxGlobals" = LocalProxy(partial(_lookup_app_object, "g")) # type: ignore diff --git a/venv/lib/python3.7/site-packages/flask/helpers.py b/venv/lib/python3.7/site-packages/flask/helpers.py deleted file mode 100644 index 4359780..0000000 --- a/venv/lib/python3.7/site-packages/flask/helpers.py +++ /dev/null @@ -1,836 +0,0 @@ -import os -import pkgutil -import socket -import sys -import typing as t -import warnings -from datetime import datetime -from datetime import timedelta -from functools import lru_cache -from functools import update_wrapper -from threading import RLock - -import werkzeug.utils -from werkzeug.exceptions import NotFound -from werkzeug.routing import BuildError -from werkzeug.urls import url_quote - -from .globals import _app_ctx_stack -from .globals import _request_ctx_stack -from .globals import current_app -from .globals import request -from .globals import session -from .signals import message_flashed - -if t.TYPE_CHECKING: - from .wrappers import Response - - -def get_env() -> str: - """Get the environment the app is running in, indicated by the - :envvar:`FLASK_ENV` environment variable. The default is - ``'production'``. - """ - return os.environ.get("FLASK_ENV") or "production" - - -def get_debug_flag() -> bool: - """Get whether debug mode should be enabled for the app, indicated - by the :envvar:`FLASK_DEBUG` environment variable. The default is - ``True`` if :func:`.get_env` returns ``'development'``, or ``False`` - otherwise. - """ - val = os.environ.get("FLASK_DEBUG") - - if not val: - return get_env() == "development" - - return val.lower() not in ("0", "false", "no") - - -def get_load_dotenv(default: bool = True) -> bool: - """Get whether the user has disabled loading dotenv files by setting - :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the - files. - - :param default: What to return if the env var isn't set. - """ - val = os.environ.get("FLASK_SKIP_DOTENV") - - if not val: - return default - - return val.lower() in ("0", "false", "no") - - -def stream_with_context( - generator_or_function: t.Union[ - t.Iterator[t.AnyStr], t.Callable[..., t.Iterator[t.AnyStr]] - ] -) -> t.Iterator[t.AnyStr]: - """Request contexts disappear when the response is started on the server. - This is done for efficiency reasons and to make it less likely to encounter - memory leaks with badly written WSGI middlewares. The downside is that if - you are using streamed responses, the generator cannot access request bound - information any more. - - This function however can help you keep the context around for longer:: - - from flask import stream_with_context, request, Response - - @app.route('/stream') - def streamed_response(): - @stream_with_context - def generate(): - yield 'Hello ' - yield request.args['name'] - yield '!' - return Response(generate()) - - Alternatively it can also be used around a specific generator:: - - from flask import stream_with_context, request, Response - - @app.route('/stream') - def streamed_response(): - def generate(): - yield 'Hello ' - yield request.args['name'] - yield '!' - return Response(stream_with_context(generate())) - - .. versionadded:: 0.9 - """ - try: - gen = iter(generator_or_function) # type: ignore - except TypeError: - - def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: - gen = generator_or_function(*args, **kwargs) # type: ignore - return stream_with_context(gen) - - return update_wrapper(decorator, generator_or_function) # type: ignore - - def generator() -> t.Generator: - ctx = _request_ctx_stack.top - if ctx is None: - raise RuntimeError( - "Attempted to stream with context but " - "there was no context in the first place to keep around." - ) - with ctx: - # Dummy sentinel. Has to be inside the context block or we're - # not actually keeping the context around. - yield None - - # The try/finally is here so that if someone passes a WSGI level - # iterator in we're still running the cleanup logic. Generators - # don't need that because they are closed on their destruction - # automatically. - try: - yield from gen - finally: - if hasattr(gen, "close"): - gen.close() # type: ignore - - # The trick is to start the generator. Then the code execution runs until - # the first dummy None is yielded at which point the context was already - # pushed. This item is discarded. Then when the iteration continues the - # real generator is executed. - wrapped_g = generator() - next(wrapped_g) - return wrapped_g - - -def make_response(*args: t.Any) -> "Response": - """Sometimes it is necessary to set additional headers in a view. Because - views do not have to return response objects but can return a value that - is converted into a response object by Flask itself, it becomes tricky to - add headers to it. This function can be called instead of using a return - and you will get a response object which you can use to attach headers. - - If view looked like this and you want to add a new header:: - - def index(): - return render_template('index.html', foo=42) - - You can now do something like this:: - - def index(): - response = make_response(render_template('index.html', foo=42)) - response.headers['X-Parachutes'] = 'parachutes are cool' - return response - - This function accepts the very same arguments you can return from a - view function. This for example creates a response with a 404 error - code:: - - response = make_response(render_template('not_found.html'), 404) - - The other use case of this function is to force the return value of a - view function into a response which is helpful with view - decorators:: - - response = make_response(view_function()) - response.headers['X-Parachutes'] = 'parachutes are cool' - - Internally this function does the following things: - - - if no arguments are passed, it creates a new response argument - - if one argument is passed, :meth:`flask.Flask.make_response` - is invoked with it. - - if more than one argument is passed, the arguments are passed - to the :meth:`flask.Flask.make_response` function as tuple. - - .. versionadded:: 0.6 - """ - if not args: - return current_app.response_class() - if len(args) == 1: - args = args[0] - return current_app.make_response(args) - - -def url_for(endpoint: str, **values: t.Any) -> str: - """Generates a URL to the given endpoint with the method provided. - - Variable arguments that are unknown to the target endpoint are appended - to the generated URL as query arguments. If the value of a query argument - is ``None``, the whole pair is skipped. In case blueprints are active - you can shortcut references to the same blueprint by prefixing the - local endpoint with a dot (``.``). - - This will reference the index function local to the current blueprint:: - - url_for('.index') - - See :ref:`url-building`. - - Configuration values ``APPLICATION_ROOT`` and ``SERVER_NAME`` are only used when - generating URLs outside of a request context. - - To integrate applications, :class:`Flask` has a hook to intercept URL build - errors through :attr:`Flask.url_build_error_handlers`. The `url_for` - function results in a :exc:`~werkzeug.routing.BuildError` when the current - app does not have a URL for the given endpoint and values. When it does, the - :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if - it is not ``None``, which can return a string to use as the result of - `url_for` (instead of `url_for`'s default to raise the - :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. - An example:: - - def external_url_handler(error, endpoint, values): - "Looks up an external URL when `url_for` cannot build a URL." - # This is an example of hooking the build_error_handler. - # Here, lookup_url is some utility function you've built - # which looks up the endpoint in some external URL registry. - url = lookup_url(endpoint, **values) - if url is None: - # External lookup did not have a URL. - # Re-raise the BuildError, in context of original traceback. - exc_type, exc_value, tb = sys.exc_info() - if exc_value is error: - raise exc_type(exc_value).with_traceback(tb) - else: - raise error - # url_for will use this result, instead of raising BuildError. - return url - - app.url_build_error_handlers.append(external_url_handler) - - Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and - `endpoint` and `values` are the arguments passed into `url_for`. Note - that this is for building URLs outside the current application, and not for - handling 404 NotFound errors. - - .. versionadded:: 0.10 - The `_scheme` parameter was added. - - .. versionadded:: 0.9 - The `_anchor` and `_method` parameters were added. - - .. versionadded:: 0.9 - Calls :meth:`Flask.handle_build_error` on - :exc:`~werkzeug.routing.BuildError`. - - :param endpoint: the endpoint of the URL (name of the function) - :param values: the variable arguments of the URL rule - :param _external: if set to ``True``, an absolute URL is generated. Server - address can be changed via ``SERVER_NAME`` configuration variable which - falls back to the `Host` header, then to the IP and port of the request. - :param _scheme: a string specifying the desired URL scheme. The `_external` - parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default - behavior uses the same scheme as the current request, or - :data:`PREFERRED_URL_SCHEME` if no request context is available. - This also can be set to an empty string to build protocol-relative - URLs. - :param _anchor: if provided this is added as anchor to the URL. - :param _method: if provided this explicitly specifies an HTTP method. - """ - appctx = _app_ctx_stack.top - reqctx = _request_ctx_stack.top - - if appctx is None: - raise RuntimeError( - "Attempted to generate a URL without the application context being" - " pushed. This has to be executed when application context is" - " available." - ) - - # If request specific information is available we have some extra - # features that support "relative" URLs. - if reqctx is not None: - url_adapter = reqctx.url_adapter - blueprint_name = request.blueprint - - if endpoint[:1] == ".": - if blueprint_name is not None: - endpoint = f"{blueprint_name}{endpoint}" - else: - endpoint = endpoint[1:] - - external = values.pop("_external", False) - - # Otherwise go with the url adapter from the appctx and make - # the URLs external by default. - else: - url_adapter = appctx.url_adapter - - if url_adapter is None: - raise RuntimeError( - "Application was not able to create a URL adapter for request" - " independent URL generation. You might be able to fix this by" - " setting the SERVER_NAME config variable." - ) - - external = values.pop("_external", True) - - anchor = values.pop("_anchor", None) - method = values.pop("_method", None) - scheme = values.pop("_scheme", None) - appctx.app.inject_url_defaults(endpoint, values) - - # This is not the best way to deal with this but currently the - # underlying Werkzeug router does not support overriding the scheme on - # a per build call basis. - old_scheme = None - if scheme is not None: - if not external: - raise ValueError("When specifying _scheme, _external must be True") - old_scheme = url_adapter.url_scheme - url_adapter.url_scheme = scheme - - try: - try: - rv = url_adapter.build( - endpoint, values, method=method, force_external=external - ) - finally: - if old_scheme is not None: - url_adapter.url_scheme = old_scheme - except BuildError as error: - # We need to inject the values again so that the app callback can - # deal with that sort of stuff. - values["_external"] = external - values["_anchor"] = anchor - values["_method"] = method - values["_scheme"] = scheme - return appctx.app.handle_url_build_error(error, endpoint, values) - - if anchor is not None: - rv += f"#{url_quote(anchor)}" - return rv - - -def get_template_attribute(template_name: str, attribute: str) -> t.Any: - """Loads a macro (or variable) a template exports. This can be used to - invoke a macro from within Python code. If you for example have a - template named :file:`_cider.html` with the following contents: - - .. sourcecode:: html+jinja - - {% macro hello(name) %}Hello {{ name }}!{% endmacro %} - - You can access this from Python code like this:: - - hello = get_template_attribute('_cider.html', 'hello') - return hello('World') - - .. versionadded:: 0.2 - - :param template_name: the name of the template - :param attribute: the name of the variable of macro to access - """ - return getattr(current_app.jinja_env.get_template(template_name).module, attribute) - - -def flash(message: str, category: str = "message") -> None: - """Flashes a message to the next request. In order to remove the - flashed message from the session and to display it to the user, - the template has to call :func:`get_flashed_messages`. - - .. versionchanged:: 0.3 - `category` parameter added. - - :param message: the message to be flashed. - :param category: the category for the message. The following values - are recommended: ``'message'`` for any kind of message, - ``'error'`` for errors, ``'info'`` for information - messages and ``'warning'`` for warnings. However any - kind of string can be used as category. - """ - # Original implementation: - # - # session.setdefault('_flashes', []).append((category, message)) - # - # This assumed that changes made to mutable structures in the session are - # always in sync with the session object, which is not true for session - # implementations that use external storage for keeping their keys/values. - flashes = session.get("_flashes", []) - flashes.append((category, message)) - session["_flashes"] = flashes - message_flashed.send( - current_app._get_current_object(), # type: ignore - message=message, - category=category, - ) - - -def get_flashed_messages( - with_categories: bool = False, category_filter: t.Iterable[str] = () -) -> t.Union[t.List[str], t.List[t.Tuple[str, str]]]: - """Pulls all flashed messages from the session and returns them. - Further calls in the same request to the function will return - the same messages. By default just the messages are returned, - but when `with_categories` is set to ``True``, the return value will - be a list of tuples in the form ``(category, message)`` instead. - - Filter the flashed messages to one or more categories by providing those - categories in `category_filter`. This allows rendering categories in - separate html blocks. The `with_categories` and `category_filter` - arguments are distinct: - - * `with_categories` controls whether categories are returned with message - text (``True`` gives a tuple, where ``False`` gives just the message text). - * `category_filter` filters the messages down to only those matching the - provided categories. - - See :doc:`/patterns/flashing` for examples. - - .. versionchanged:: 0.3 - `with_categories` parameter added. - - .. versionchanged:: 0.9 - `category_filter` parameter added. - - :param with_categories: set to ``True`` to also receive categories. - :param category_filter: filter of categories to limit return values. Only - categories in the list will be returned. - """ - flashes = _request_ctx_stack.top.flashes - if flashes is None: - _request_ctx_stack.top.flashes = flashes = ( - session.pop("_flashes") if "_flashes" in session else [] - ) - if category_filter: - flashes = list(filter(lambda f: f[0] in category_filter, flashes)) - if not with_categories: - return [x[1] for x in flashes] - return flashes - - -def _prepare_send_file_kwargs( - download_name: t.Optional[str] = None, - attachment_filename: t.Optional[str] = None, - etag: t.Optional[t.Union[bool, str]] = None, - add_etags: t.Optional[t.Union[bool]] = None, - max_age: t.Optional[ - t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] - ] = None, - cache_timeout: t.Optional[int] = None, - **kwargs: t.Any, -) -> t.Dict[str, t.Any]: - if attachment_filename is not None: - warnings.warn( - "The 'attachment_filename' parameter has been renamed to" - " 'download_name'. The old name will be removed in Flask" - " 2.1.", - DeprecationWarning, - stacklevel=3, - ) - download_name = attachment_filename - - if cache_timeout is not None: - warnings.warn( - "The 'cache_timeout' parameter has been renamed to" - " 'max_age'. The old name will be removed in Flask 2.1.", - DeprecationWarning, - stacklevel=3, - ) - max_age = cache_timeout - - if add_etags is not None: - warnings.warn( - "The 'add_etags' parameter has been renamed to 'etag'. The" - " old name will be removed in Flask 2.1.", - DeprecationWarning, - stacklevel=3, - ) - etag = add_etags - - if max_age is None: - max_age = current_app.get_send_file_max_age - - kwargs.update( - environ=request.environ, - download_name=download_name, - etag=etag, - max_age=max_age, - use_x_sendfile=current_app.use_x_sendfile, - response_class=current_app.response_class, - _root_path=current_app.root_path, # type: ignore - ) - return kwargs - - -def send_file( - path_or_file: t.Union[os.PathLike, str, t.BinaryIO], - mimetype: t.Optional[str] = None, - as_attachment: bool = False, - download_name: t.Optional[str] = None, - attachment_filename: t.Optional[str] = None, - conditional: bool = True, - etag: t.Union[bool, str] = True, - add_etags: t.Optional[bool] = None, - last_modified: t.Optional[t.Union[datetime, int, float]] = None, - max_age: t.Optional[ - t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] - ] = None, - cache_timeout: t.Optional[int] = None, -): - """Send the contents of a file to the client. - - The first argument can be a file path or a file-like object. Paths - are preferred in most cases because Werkzeug can manage the file and - get extra information from the path. Passing a file-like object - requires that the file is opened in binary mode, and is mostly - useful when building a file in memory with :class:`io.BytesIO`. - - Never pass file paths provided by a user. The path is assumed to be - trusted, so a user could craft a path to access a file you didn't - intend. Use :func:`send_from_directory` to safely serve - user-requested paths from within a directory. - - If the WSGI server sets a ``file_wrapper`` in ``environ``, it is - used, otherwise Werkzeug's built-in wrapper is used. Alternatively, - if the HTTP server supports ``X-Sendfile``, configuring Flask with - ``USE_X_SENDFILE = True`` will tell the server to send the given - path, which is much more efficient than reading it in Python. - - :param path_or_file: The path to the file to send, relative to the - current working directory if a relative path is given. - Alternatively, a file-like object opened in binary mode. Make - sure the file pointer is seeked to the start of the data. - :param mimetype: The MIME type to send for the file. If not - provided, it will try to detect it from the file name. - :param as_attachment: Indicate to a browser that it should offer to - save the file instead of displaying it. - :param download_name: The default name browsers will use when saving - the file. Defaults to the passed file name. - :param conditional: Enable conditional and range responses based on - request headers. Requires passing a file path and ``environ``. - :param etag: Calculate an ETag for the file, which requires passing - a file path. Can also be a string to use instead. - :param last_modified: The last modified time to send for the file, - in seconds. If not provided, it will try to detect it from the - file path. - :param max_age: How long the client should cache the file, in - seconds. If set, ``Cache-Control`` will be ``public``, otherwise - it will be ``no-cache`` to prefer conditional caching. - - .. versionchanged:: 2.0 - ``download_name`` replaces the ``attachment_filename`` - parameter. If ``as_attachment=False``, it is passed with - ``Content-Disposition: inline`` instead. - - .. versionchanged:: 2.0 - ``max_age`` replaces the ``cache_timeout`` parameter. - ``conditional`` is enabled and ``max_age`` is not set by - default. - - .. versionchanged:: 2.0 - ``etag`` replaces the ``add_etags`` parameter. It can be a - string to use instead of generating one. - - .. versionchanged:: 2.0 - Passing a file-like object that inherits from - :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather - than sending an empty file. - - .. versionadded:: 2.0 - Moved the implementation to Werkzeug. This is now a wrapper to - pass some Flask-specific arguments. - - .. versionchanged:: 1.1 - ``filename`` may be a :class:`~os.PathLike` object. - - .. versionchanged:: 1.1 - Passing a :class:`~io.BytesIO` object supports range requests. - - .. versionchanged:: 1.0.3 - Filenames are encoded with ASCII instead of Latin-1 for broader - compatibility with WSGI servers. - - .. versionchanged:: 1.0 - UTF-8 filenames as specified in :rfc:`2231` are supported. - - .. versionchanged:: 0.12 - The filename is no longer automatically inferred from file - objects. If you want to use automatic MIME and etag support, - pass a filename via ``filename_or_fp`` or - ``attachment_filename``. - - .. versionchanged:: 0.12 - ``attachment_filename`` is preferred over ``filename`` for MIME - detection. - - .. versionchanged:: 0.9 - ``cache_timeout`` defaults to - :meth:`Flask.get_send_file_max_age`. - - .. versionchanged:: 0.7 - MIME guessing and etag support for file-like objects was - deprecated because it was unreliable. Pass a filename if you are - able to, otherwise attach an etag yourself. - - .. versionchanged:: 0.5 - The ``add_etags``, ``cache_timeout`` and ``conditional`` - parameters were added. The default behavior is to add etags. - - .. versionadded:: 0.2 - """ - return werkzeug.utils.send_file( - **_prepare_send_file_kwargs( - path_or_file=path_or_file, - environ=request.environ, - mimetype=mimetype, - as_attachment=as_attachment, - download_name=download_name, - attachment_filename=attachment_filename, - conditional=conditional, - etag=etag, - add_etags=add_etags, - last_modified=last_modified, - max_age=max_age, - cache_timeout=cache_timeout, - ) - ) - - -def safe_join(directory: str, *pathnames: str) -> str: - """Safely join zero or more untrusted path components to a base - directory to avoid escaping the base directory. - - :param directory: The trusted base directory. - :param pathnames: The untrusted path components relative to the - base directory. - :return: A safe path, otherwise ``None``. - """ - warnings.warn( - "'flask.helpers.safe_join' is deprecated and will be removed in" - " Flask 2.1. Use 'werkzeug.utils.safe_join' instead.", - DeprecationWarning, - stacklevel=2, - ) - path = werkzeug.utils.safe_join(directory, *pathnames) - - if path is None: - raise NotFound() - - return path - - -def send_from_directory( - directory: t.Union[os.PathLike, str], - path: t.Union[os.PathLike, str], - filename: t.Optional[str] = None, - **kwargs: t.Any, -) -> "Response": - """Send a file from within a directory using :func:`send_file`. - - .. code-block:: python - - @app.route("/uploads/") - def download_file(name): - return send_from_directory( - app.config['UPLOAD_FOLDER'], name, as_attachment=True - ) - - This is a secure way to serve files from a folder, such as static - files or uploads. Uses :func:`~werkzeug.security.safe_join` to - ensure the path coming from the client is not maliciously crafted to - point outside the specified directory. - - If the final path does not point to an existing regular file, - raises a 404 :exc:`~werkzeug.exceptions.NotFound` error. - - :param directory: The directory that ``path`` must be located under. - :param path: The path to the file to send, relative to - ``directory``. - :param kwargs: Arguments to pass to :func:`send_file`. - - .. versionchanged:: 2.0 - ``path`` replaces the ``filename`` parameter. - - .. versionadded:: 2.0 - Moved the implementation to Werkzeug. This is now a wrapper to - pass some Flask-specific arguments. - - .. versionadded:: 0.5 - """ - if filename is not None: - warnings.warn( - "The 'filename' parameter has been renamed to 'path'. The" - " old name will be removed in Flask 2.1.", - DeprecationWarning, - stacklevel=2, - ) - path = filename - - return werkzeug.utils.send_from_directory( # type: ignore - directory, path, **_prepare_send_file_kwargs(**kwargs) - ) - - -def get_root_path(import_name: str) -> str: - """Find the root path of a package, or the path that contains a - module. If it cannot be found, returns the current working - directory. - - Not to be confused with the value returned by :func:`find_package`. - - :meta private: - """ - # Module already imported and has a file attribute. Use that first. - mod = sys.modules.get(import_name) - - if mod is not None and hasattr(mod, "__file__") and mod.__file__ is not None: - return os.path.dirname(os.path.abspath(mod.__file__)) - - # Next attempt: check the loader. - loader = pkgutil.get_loader(import_name) - - # Loader does not exist or we're referring to an unloaded main - # module or a main module without path (interactive sessions), go - # with the current working directory. - if loader is None or import_name == "__main__": - return os.getcwd() - - if hasattr(loader, "get_filename"): - filepath = loader.get_filename(import_name) # type: ignore - else: - # Fall back to imports. - __import__(import_name) - mod = sys.modules[import_name] - filepath = getattr(mod, "__file__", None) - - # If we don't have a file path it might be because it is a - # namespace package. In this case pick the root path from the - # first module that is contained in the package. - if filepath is None: - raise RuntimeError( - "No root path can be found for the provided module" - f" {import_name!r}. This can happen because the module" - " came from an import hook that does not provide file" - " name information or because it's a namespace package." - " In this case the root path needs to be explicitly" - " provided." - ) - - # filepath is import_name.py for a module, or __init__.py for a package. - return os.path.dirname(os.path.abspath(filepath)) - - -class locked_cached_property(werkzeug.utils.cached_property): - """A :func:`property` that is only evaluated once. Like - :class:`werkzeug.utils.cached_property` except access uses a lock - for thread safety. - - .. versionchanged:: 2.0 - Inherits from Werkzeug's ``cached_property`` (and ``property``). - """ - - def __init__( - self, - fget: t.Callable[[t.Any], t.Any], - name: t.Optional[str] = None, - doc: t.Optional[str] = None, - ) -> None: - super().__init__(fget, name=name, doc=doc) - self.lock = RLock() - - def __get__(self, obj: object, type: type = None) -> t.Any: # type: ignore - if obj is None: - return self - - with self.lock: - return super().__get__(obj, type=type) - - def __set__(self, obj: object, value: t.Any) -> None: - with self.lock: - super().__set__(obj, value) - - def __delete__(self, obj: object) -> None: - with self.lock: - super().__delete__(obj) - - -def total_seconds(td: timedelta) -> int: - """Returns the total seconds from a timedelta object. - - :param timedelta td: the timedelta to be converted in seconds - - :returns: number of seconds - :rtype: int - - .. deprecated:: 2.0 - Will be removed in Flask 2.1. Use - :meth:`timedelta.total_seconds` instead. - """ - warnings.warn( - "'total_seconds' is deprecated and will be removed in Flask" - " 2.1. Use 'timedelta.total_seconds' instead.", - DeprecationWarning, - stacklevel=2, - ) - return td.days * 60 * 60 * 24 + td.seconds - - -def is_ip(value: str) -> bool: - """Determine if the given string is an IP address. - - :param value: value to check - :type value: str - - :return: True if string is an IP address - :rtype: bool - """ - for family in (socket.AF_INET, socket.AF_INET6): - try: - socket.inet_pton(family, value) - except OSError: - pass - else: - return True - - return False - - -@lru_cache(maxsize=None) -def _split_blueprint_path(name: str) -> t.List[str]: - out: t.List[str] = [name] - - if "." in name: - out.extend(_split_blueprint_path(name.rpartition(".")[0])) - - return out diff --git a/venv/lib/python3.7/site-packages/flask/json/__init__.py b/venv/lib/python3.7/site-packages/flask/json/__init__.py deleted file mode 100644 index ccb9efb..0000000 --- a/venv/lib/python3.7/site-packages/flask/json/__init__.py +++ /dev/null @@ -1,363 +0,0 @@ -import decimal -import io -import json as _json -import typing as t -import uuid -import warnings -from datetime import date - -from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps -from werkzeug.http import http_date - -from ..globals import current_app -from ..globals import request - -if t.TYPE_CHECKING: - from ..app import Flask - from ..wrappers import Response - -try: - import dataclasses -except ImportError: - # Python < 3.7 - dataclasses = None # type: ignore - - -class JSONEncoder(_json.JSONEncoder): - """The default JSON encoder. Handles extra types compared to the - built-in :class:`json.JSONEncoder`. - - - :class:`datetime.datetime` and :class:`datetime.date` are - serialized to :rfc:`822` strings. This is the same as the HTTP - date format. - - :class:`uuid.UUID` is serialized to a string. - - :class:`dataclasses.dataclass` is passed to - :func:`dataclasses.asdict`. - - :class:`~markupsafe.Markup` (or any object with a ``__html__`` - method) will call the ``__html__`` method to get a string. - - Assign a subclass of this to :attr:`flask.Flask.json_encoder` or - :attr:`flask.Blueprint.json_encoder` to override the default. - """ - - def default(self, o: t.Any) -> t.Any: - """Convert ``o`` to a JSON serializable type. See - :meth:`json.JSONEncoder.default`. Python does not support - overriding how basic types like ``str`` or ``list`` are - serialized, they are handled before this method. - """ - if isinstance(o, date): - return http_date(o) - if isinstance(o, (decimal.Decimal, uuid.UUID)): - return str(o) - if dataclasses and dataclasses.is_dataclass(o): - return dataclasses.asdict(o) - if hasattr(o, "__html__"): - return str(o.__html__()) - return super().default(o) - - -class JSONDecoder(_json.JSONDecoder): - """The default JSON decoder. - - This does not change any behavior from the built-in - :class:`json.JSONDecoder`. - - Assign a subclass of this to :attr:`flask.Flask.json_decoder` or - :attr:`flask.Blueprint.json_decoder` to override the default. - """ - - -def _dump_arg_defaults( - kwargs: t.Dict[str, t.Any], app: t.Optional["Flask"] = None -) -> None: - """Inject default arguments for dump functions.""" - if app is None: - app = current_app - - if app: - cls = app.json_encoder - bp = app.blueprints.get(request.blueprint) if request else None # type: ignore - if bp is not None and bp.json_encoder is not None: - cls = bp.json_encoder - - # Only set a custom encoder if it has custom behavior. This is - # faster on PyPy. - if cls is not _json.JSONEncoder: - kwargs.setdefault("cls", cls) - - kwargs.setdefault("cls", cls) - kwargs.setdefault("ensure_ascii", app.config["JSON_AS_ASCII"]) - kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"]) - else: - kwargs.setdefault("sort_keys", True) - kwargs.setdefault("cls", JSONEncoder) - - -def _load_arg_defaults( - kwargs: t.Dict[str, t.Any], app: t.Optional["Flask"] = None -) -> None: - """Inject default arguments for load functions.""" - if app is None: - app = current_app - - if app: - cls = app.json_decoder - bp = app.blueprints.get(request.blueprint) if request else None # type: ignore - if bp is not None and bp.json_decoder is not None: - cls = bp.json_decoder - - # Only set a custom decoder if it has custom behavior. This is - # faster on PyPy. - if cls not in {JSONDecoder, _json.JSONDecoder}: - kwargs.setdefault("cls", cls) - - -def dumps(obj: t.Any, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> str: - """Serialize an object to a string of JSON. - - Takes the same arguments as the built-in :func:`json.dumps`, with - some defaults from application configuration. - - :param obj: Object to serialize to JSON. - :param app: Use this app's config instead of the active app context - or defaults. - :param kwargs: Extra arguments passed to :func:`json.dumps`. - - .. versionchanged:: 2.0.2 - :class:`decimal.Decimal` is supported by converting to a string. - - .. versionchanged:: 2.0 - ``encoding`` is deprecated and will be removed in Flask 2.1. - - .. versionchanged:: 1.0.3 - ``app`` can be passed directly, rather than requiring an app - context for configuration. - """ - _dump_arg_defaults(kwargs, app=app) - encoding = kwargs.pop("encoding", None) - rv = _json.dumps(obj, **kwargs) - - if encoding is not None: - warnings.warn( - "'encoding' is deprecated and will be removed in Flask 2.1.", - DeprecationWarning, - stacklevel=2, - ) - - if isinstance(rv, str): - return rv.encode(encoding) # type: ignore - - return rv - - -def dump( - obj: t.Any, fp: t.IO[str], app: t.Optional["Flask"] = None, **kwargs: t.Any -) -> None: - """Serialize an object to JSON written to a file object. - - Takes the same arguments as the built-in :func:`json.dump`, with - some defaults from application configuration. - - :param obj: Object to serialize to JSON. - :param fp: File object to write JSON to. - :param app: Use this app's config instead of the active app context - or defaults. - :param kwargs: Extra arguments passed to :func:`json.dump`. - - .. versionchanged:: 2.0 - Writing to a binary file, and the ``encoding`` argument, is - deprecated and will be removed in Flask 2.1. - """ - _dump_arg_defaults(kwargs, app=app) - encoding = kwargs.pop("encoding", None) - show_warning = encoding is not None - - try: - fp.write("") - except TypeError: - show_warning = True - fp = io.TextIOWrapper(fp, encoding or "utf-8") # type: ignore - - if show_warning: - warnings.warn( - "Writing to a binary file, and the 'encoding' argument, is" - " deprecated and will be removed in Flask 2.1.", - DeprecationWarning, - stacklevel=2, - ) - - _json.dump(obj, fp, **kwargs) - - -def loads(s: str, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> t.Any: - """Deserialize an object from a string of JSON. - - Takes the same arguments as the built-in :func:`json.loads`, with - some defaults from application configuration. - - :param s: JSON string to deserialize. - :param app: Use this app's config instead of the active app context - or defaults. - :param kwargs: Extra arguments passed to :func:`json.loads`. - - .. versionchanged:: 2.0 - ``encoding`` is deprecated and will be removed in Flask 2.1. The - data must be a string or UTF-8 bytes. - - .. versionchanged:: 1.0.3 - ``app`` can be passed directly, rather than requiring an app - context for configuration. - """ - _load_arg_defaults(kwargs, app=app) - encoding = kwargs.pop("encoding", None) - - if encoding is not None: - warnings.warn( - "'encoding' is deprecated and will be removed in Flask 2.1." - " The data must be a string or UTF-8 bytes.", - DeprecationWarning, - stacklevel=2, - ) - - if isinstance(s, bytes): - s = s.decode(encoding) - - return _json.loads(s, **kwargs) - - -def load(fp: t.IO[str], app: t.Optional["Flask"] = None, **kwargs: t.Any) -> t.Any: - """Deserialize an object from JSON read from a file object. - - Takes the same arguments as the built-in :func:`json.load`, with - some defaults from application configuration. - - :param fp: File object to read JSON from. - :param app: Use this app's config instead of the active app context - or defaults. - :param kwargs: Extra arguments passed to :func:`json.load`. - - .. versionchanged:: 2.0 - ``encoding`` is deprecated and will be removed in Flask 2.1. The - file must be text mode, or binary mode with UTF-8 bytes. - """ - _load_arg_defaults(kwargs, app=app) - encoding = kwargs.pop("encoding", None) - - if encoding is not None: - warnings.warn( - "'encoding' is deprecated and will be removed in Flask 2.1." - " The file must be text mode, or binary mode with UTF-8" - " bytes.", - DeprecationWarning, - stacklevel=2, - ) - - if isinstance(fp.read(0), bytes): - fp = io.TextIOWrapper(fp, encoding) # type: ignore - - return _json.load(fp, **kwargs) - - -def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str: - """Serialize an object to a string of JSON with :func:`dumps`, then - replace HTML-unsafe characters with Unicode escapes and mark the - result safe with :class:`~markupsafe.Markup`. - - This is available in templates as the ``|tojson`` filter. - - The returned string is safe to render in HTML documents and - `` - - - -

- -
-
-

Console Locked

-

- The console is locked and needs to be unlocked by entering the PIN. - You can find the PIN printed out on the standard output of your - shell that runs the server. -

-

PIN: - - -

-
-
- - -""" - -PAGE_HTML = ( - HEADER - + """\ -

%(exception_type)s

-
-

%(exception)s

-
-

Traceback (most recent call last)

-%(summary)s -
-

- This is the Copy/Paste friendly version of the traceback. -

- -
-
- The debugger caught an exception in your WSGI application. You can now - look at the traceback which led to the error. - If you enable JavaScript you can also use additional features such as code - execution (if the evalex feature is enabled), automatic pasting of the - exceptions and much more. -
-""" - + FOOTER - + """ - -""" -) - -CONSOLE_HTML = ( - HEADER - + """\ -

Interactive Console

-
-In this console you can execute Python expressions in the context of the -application. The initial namespace was created by the debugger automatically. -
-
The Console requires JavaScript.
-""" - + FOOTER -) - -SUMMARY_HTML = """\ -
- %(title)s -
    %(frames)s
- %(description)s -
-""" - -FRAME_HTML = """\ -
-

File "%(filename)s", - line %(lineno)s, - in %(function_name)s

-
%(lines)s
-
-""" - -SOURCE_LINE_HTML = """\ - - %(lineno)s - %(code)s - -""" - - -def render_console_html(secret: str, evalex_trusted: bool = True) -> str: - return CONSOLE_HTML % { - "evalex": "true", - "evalex_trusted": "true" if evalex_trusted else "false", - "console": "true", - "title": "Console", - "secret": secret, - "traceback_id": -1, - } - - -def get_current_traceback( - ignore_system_exceptions: bool = False, - show_hidden_frames: bool = False, - skip: int = 0, -) -> "Traceback": - """Get the current exception info as `Traceback` object. Per default - calling this method will reraise system exceptions such as generator exit, - system exit or others. This behavior can be disabled by passing `False` - to the function as first parameter. - """ - info = t.cast( - t.Tuple[t.Type[BaseException], BaseException, TracebackType], sys.exc_info() - ) - exc_type, exc_value, tb = info - - if ignore_system_exceptions and exc_type in { - SystemExit, - KeyboardInterrupt, - GeneratorExit, - }: - raise - for _ in range(skip): - if tb.tb_next is None: - break - tb = tb.tb_next - tb = Traceback(exc_type, exc_value, tb) - if not show_hidden_frames: - tb.filter_hidden_frames() - return tb - - -class Line: - """Helper for the source renderer.""" - - __slots__ = ("lineno", "code", "in_frame", "current") - - def __init__(self, lineno: int, code: str) -> None: - self.lineno = lineno - self.code = code - self.in_frame = False - self.current = False - - @property - def classes(self) -> t.List[str]: - rv = ["line"] - if self.in_frame: - rv.append("in-frame") - if self.current: - rv.append("current") - return rv - - def render(self) -> str: - return SOURCE_LINE_HTML % { - "classes": " ".join(self.classes), - "lineno": self.lineno, - "code": escape(self.code), - } - - -class Traceback: - """Wraps a traceback.""" - - def __init__( - self, - exc_type: t.Type[BaseException], - exc_value: BaseException, - tb: TracebackType, - ) -> None: - self.exc_type = exc_type - self.exc_value = exc_value - self.tb = tb - - exception_type = exc_type.__name__ - if exc_type.__module__ not in {"builtins", "__builtin__", "exceptions"}: - exception_type = f"{exc_type.__module__}.{exception_type}" - self.exception_type = exception_type - - self.groups = [] - memo = set() - while True: - self.groups.append(Group(exc_type, exc_value, tb)) - memo.add(id(exc_value)) - exc_value = exc_value.__cause__ or exc_value.__context__ # type: ignore - if exc_value is None or id(exc_value) in memo: - break - exc_type = type(exc_value) - tb = exc_value.__traceback__ # type: ignore - self.groups.reverse() - self.frames = [frame for group in self.groups for frame in group.frames] - - def filter_hidden_frames(self) -> None: - """Remove the frames according to the paste spec.""" - for group in self.groups: - group.filter_hidden_frames() - - self.frames[:] = [frame for group in self.groups for frame in group.frames] - - @property - def is_syntax_error(self) -> bool: - """Is it a syntax error?""" - return isinstance(self.exc_value, SyntaxError) - - @property - def exception(self) -> str: - """String representation of the final exception.""" - return self.groups[-1].exception - - def log(self, logfile: t.Optional[t.IO[str]] = None) -> None: - """Log the ASCII traceback into a file object.""" - if logfile is None: - logfile = sys.stderr - tb = f"{self.plaintext.rstrip()}\n" - logfile.write(tb) - - def render_summary(self, include_title: bool = True) -> str: - """Render the traceback for the interactive console.""" - title = "" - classes = ["traceback"] - if not self.frames: - classes.append("noframe-traceback") - frames = [] - else: - library_frames = sum(frame.is_library for frame in self.frames) - mark_lib = 0 < library_frames < len(self.frames) - frames = [group.render(mark_lib=mark_lib) for group in self.groups] - - if include_title: - if self.is_syntax_error: - title = "Syntax Error" - else: - title = "Traceback (most recent call last):" - - if self.is_syntax_error: - description = f"
{escape(self.exception)}
" - else: - description = f"
{escape(self.exception)}
" - - return SUMMARY_HTML % { - "classes": " ".join(classes), - "title": f"

{title if title else ''}

", - "frames": "\n".join(frames), - "description": description, - } - - def render_full( - self, - evalex: bool = False, - secret: t.Optional[str] = None, - evalex_trusted: bool = True, - ) -> str: - """Render the Full HTML page with the traceback info.""" - exc = escape(self.exception) - return PAGE_HTML % { - "evalex": "true" if evalex else "false", - "evalex_trusted": "true" if evalex_trusted else "false", - "console": "false", - "title": exc, - "exception": exc, - "exception_type": escape(self.exception_type), - "summary": self.render_summary(include_title=False), - "plaintext": escape(self.plaintext), - "plaintext_cs": re.sub("-{2,}", "-", self.plaintext), - "traceback_id": self.id, - "secret": secret, - } - - @cached_property - def plaintext(self) -> str: - return "\n".join([group.render_text() for group in self.groups]) - - @property - def id(self) -> int: - return id(self) - - -class Group: - """A group of frames for an exception in a traceback. If the - exception has a ``__cause__`` or ``__context__``, there are multiple - exception groups. - """ - - def __init__( - self, - exc_type: t.Type[BaseException], - exc_value: BaseException, - tb: TracebackType, - ) -> None: - self.exc_type = exc_type - self.exc_value = exc_value - self.info = None - if exc_value.__cause__ is not None: - self.info = ( - "The above exception was the direct cause of the following exception" - ) - elif exc_value.__context__ is not None: - self.info = ( - "During handling of the above exception, another exception occurred" - ) - - self.frames = [] - while tb is not None: - self.frames.append(Frame(exc_type, exc_value, tb)) - tb = tb.tb_next # type: ignore - - def filter_hidden_frames(self) -> None: - # An exception may not have a traceback to filter frames, such - # as one re-raised from ProcessPoolExecutor. - if not self.frames: - return - - new_frames: t.List[Frame] = [] - hidden = False - - for frame in self.frames: - hide = frame.hide - if hide in ("before", "before_and_this"): - new_frames = [] - hidden = False - if hide == "before_and_this": - continue - elif hide in ("reset", "reset_and_this"): - hidden = False - if hide == "reset_and_this": - continue - elif hide in ("after", "after_and_this"): - hidden = True - if hide == "after_and_this": - continue - elif hide or hidden: - continue - new_frames.append(frame) - - # if we only have one frame and that frame is from the codeop - # module, remove it. - if len(new_frames) == 1 and self.frames[0].module == "codeop": - del self.frames[:] - - # if the last frame is missing something went terrible wrong :( - elif self.frames[-1] in new_frames: - self.frames[:] = new_frames - - @property - def exception(self) -> str: - """String representation of the exception.""" - buf = traceback.format_exception_only(self.exc_type, self.exc_value) - rv = "".join(buf).strip() - return _to_str(rv, "utf-8", "replace") - - def render(self, mark_lib: bool = True) -> str: - out = [] - if self.info is not None: - out.append(f'
  • {self.info}:
    ') - for frame in self.frames: - title = f' title="{escape(frame.info)}"' if frame.info else "" - out.append(f"{frame.render(mark_lib=mark_lib)}") - return "\n".join(out) - - def render_text(self) -> str: - out = [] - if self.info is not None: - out.append(f"\n{self.info}:\n") - out.append("Traceback (most recent call last):") - for frame in self.frames: - out.append(frame.render_text()) - out.append(self.exception) - return "\n".join(out) - - -class Frame: - """A single frame in a traceback.""" - - def __init__( - self, - exc_type: t.Type[BaseException], - exc_value: BaseException, - tb: TracebackType, - ) -> None: - self.lineno = tb.tb_lineno - self.function_name = tb.tb_frame.f_code.co_name - self.locals = tb.tb_frame.f_locals - self.globals = tb.tb_frame.f_globals - - fn = inspect.getsourcefile(tb) or inspect.getfile(tb) - if fn[-4:] in (".pyo", ".pyc"): - fn = fn[:-1] - # if it's a file on the file system resolve the real filename. - if os.path.isfile(fn): - fn = os.path.realpath(fn) - self.filename = _to_str(fn, get_filesystem_encoding()) - self.module = self.globals.get("__name__", self.locals.get("__name__")) - self.loader = self.globals.get("__loader__", self.locals.get("__loader__")) - self.code = tb.tb_frame.f_code - - # support for paste's traceback extensions - self.hide = self.locals.get("__traceback_hide__", False) - info = self.locals.get("__traceback_info__") - if info is not None: - info = _to_str(info, "utf-8", "replace") - self.info = info - - def render(self, mark_lib: bool = True) -> str: - """Render a single frame in a traceback.""" - return FRAME_HTML % { - "id": self.id, - "filename": escape(self.filename), - "lineno": self.lineno, - "function_name": escape(self.function_name), - "lines": self.render_line_context(), - "library": "library" if mark_lib and self.is_library else "", - } - - @cached_property - def is_library(self) -> bool: - return any( - self.filename.startswith(os.path.realpath(path)) - for path in sysconfig.get_paths().values() - ) - - def render_text(self) -> str: - return ( - f' File "{self.filename}", line {self.lineno}, in {self.function_name}\n' - f" {self.current_line.strip()}" - ) - - def render_line_context(self) -> str: - before, current, after = self.get_context_lines() - rv = [] - - def render_line(line: str, cls: str) -> None: - line = line.expandtabs().rstrip() - stripped_line = line.strip() - prefix = len(line) - len(stripped_line) - rv.append( - f'
    {" " * prefix}'
    -                f"{escape(stripped_line) if stripped_line else ' '}
    " - ) - - for line in before: - render_line(line, "before") - render_line(current, "current") - for line in after: - render_line(line, "after") - - return "\n".join(rv) - - def get_annotated_lines(self) -> t.List[Line]: - """Helper function that returns lines with extra information.""" - lines = [Line(idx + 1, x) for idx, x in enumerate(self.sourcelines)] - - # find function definition and mark lines - if hasattr(self.code, "co_firstlineno"): - lineno = self.code.co_firstlineno - 1 - while lineno > 0: - if _funcdef_re.match(lines[lineno].code): - break - lineno -= 1 - try: - offset = len(inspect.getblock([f"{x.code}\n" for x in lines[lineno:]])) - except TokenError: - offset = 0 - for line in lines[lineno : lineno + offset]: - line.in_frame = True - - # mark current line - try: - lines[self.lineno - 1].current = True - except IndexError: - pass - - return lines - - def eval(self, code: t.Union[str, CodeType], mode: str = "single") -> t.Any: - """Evaluate code in the context of the frame.""" - if isinstance(code, str): - code = compile(code, "", mode) - return eval(code, self.globals, self.locals) - - @cached_property - def sourcelines(self) -> t.List[str]: - """The sourcecode of the file as list of strings.""" - # get sourcecode from loader or file - source = None - if self.loader is not None: - try: - if hasattr(self.loader, "get_source"): - source = self.loader.get_source(self.module) - elif hasattr(self.loader, "get_source_by_code"): - source = self.loader.get_source_by_code(self.code) - except Exception: - # we munch the exception so that we don't cause troubles - # if the loader is broken. - pass - - if source is None: - try: - with open(self.filename, mode="rb") as f: - source = f.read() - except OSError: - return [] - - # already str? return right away - if isinstance(source, str): - return source.splitlines() - - charset = "utf-8" - if source.startswith(codecs.BOM_UTF8): - source = source[3:] - else: - for idx, match in enumerate(_line_re.finditer(source)): - coding_match = _coding_re.search(match.group()) - if coding_match is not None: - charset = coding_match.group(1).decode("utf-8") - break - if idx > 1: - break - - # on broken cookies we fall back to utf-8 too - charset = _to_str(charset) - try: - codecs.lookup(charset) - except LookupError: - charset = "utf-8" - - return source.decode(charset, "replace").splitlines() - - def get_context_lines( - self, context: int = 5 - ) -> t.Tuple[t.List[str], str, t.List[str]]: - before = self.sourcelines[self.lineno - context - 1 : self.lineno - 1] - past = self.sourcelines[self.lineno : self.lineno + context] - return (before, self.current_line, past) - - @property - def current_line(self) -> str: - try: - return self.sourcelines[self.lineno - 1] - except IndexError: - return "" - - @cached_property - def console(self) -> Console: - return Console(self.globals, self.locals) - - @property - def id(self) -> int: - return id(self) diff --git a/venv/lib/python3.7/site-packages/werkzeug/exceptions.py b/venv/lib/python3.7/site-packages/werkzeug/exceptions.py deleted file mode 100644 index 8a31c4d..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/exceptions.py +++ /dev/null @@ -1,944 +0,0 @@ -"""Implements a number of Python exceptions which can be raised from within -a view to trigger a standard HTTP non-200 response. - -Usage Example -------------- - -.. code-block:: python - - from werkzeug.wrappers.request import Request - from werkzeug.exceptions import HTTPException, NotFound - - def view(request): - raise NotFound() - - @Request.application - def application(request): - try: - return view(request) - except HTTPException as e: - return e - -As you can see from this example those exceptions are callable WSGI -applications. However, they are not Werkzeug response objects. You -can get a response object by calling ``get_response()`` on a HTTP -exception. - -Keep in mind that you may have to pass an environ (WSGI) or scope -(ASGI) to ``get_response()`` because some errors fetch additional -information relating to the request. - -If you want to hook in a different exception page to say, a 404 status -code, you can add a second except for a specific subclass of an error: - -.. code-block:: python - - @Request.application - def application(request): - try: - return view(request) - except NotFound as e: - return not_found(request) - except HTTPException as e: - return e - -""" -import sys -import typing as t -import warnings -from datetime import datetime -from html import escape - -from ._internal import _get_environ - -if t.TYPE_CHECKING: - import typing_extensions as te - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIEnvironment - from .datastructures import WWWAuthenticate - from .sansio.response import Response - from .wrappers.request import Request as WSGIRequest # noqa: F401 - from .wrappers.response import Response as WSGIResponse # noqa: F401 - - -class HTTPException(Exception): - """The base class for all HTTP exceptions. This exception can be called as a WSGI - application to render a default error page or you can catch the subclasses - of it independently and render nicer error messages. - """ - - code: t.Optional[int] = None - description: t.Optional[str] = None - - def __init__( - self, - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - ) -> None: - super().__init__() - if description is not None: - self.description = description - self.response = response - - @classmethod - def wrap( - cls, exception: t.Type[BaseException], name: t.Optional[str] = None - ) -> t.Type["HTTPException"]: - """Create an exception that is a subclass of the calling HTTP - exception and the ``exception`` argument. - - The first argument to the class will be passed to the - wrapped ``exception``, the rest to the HTTP exception. If - ``e.args`` is not empty and ``e.show_exception`` is ``True``, - the wrapped exception message is added to the HTTP error - description. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Create a subclass manually - instead. - - .. versionchanged:: 0.15.5 - The ``show_exception`` attribute controls whether the - description includes the wrapped exception message. - - .. versionchanged:: 0.15.0 - The description includes the wrapped exception message. - """ - warnings.warn( - "'HTTPException.wrap' is deprecated and will be removed in" - " Werkzeug 2.1. Create a subclass manually instead.", - DeprecationWarning, - stacklevel=2, - ) - - class newcls(cls, exception): # type: ignore - _description = cls.description - show_exception = False - - def __init__( - self, arg: t.Optional[t.Any] = None, *args: t.Any, **kwargs: t.Any - ) -> None: - super().__init__(*args, **kwargs) - - if arg is None: - exception.__init__(self) - else: - exception.__init__(self, arg) - - @property - def description(self) -> str: - if self.show_exception: - return ( - f"{self._description}\n" - f"{exception.__name__}: {exception.__str__(self)}" - ) - - return self._description # type: ignore - - @description.setter - def description(self, value: str) -> None: - self._description = value - - newcls.__module__ = sys._getframe(1).f_globals["__name__"] - name = name or cls.__name__ + exception.__name__ - newcls.__name__ = newcls.__qualname__ = name - return newcls - - @property - def name(self) -> str: - """The status name.""" - from .http import HTTP_STATUS_CODES - - return HTTP_STATUS_CODES.get(self.code, "Unknown Error") # type: ignore - - def get_description( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> str: - """Get the description.""" - if self.description is None: - description = "" - elif not isinstance(self.description, str): - description = str(self.description) - else: - description = self.description - - description = escape(description).replace("\n", "
    ") - return f"

    {description}

    " - - def get_body( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> str: - """Get the HTML body.""" - return ( - '\n' - f"{self.code} {escape(self.name)}\n" - f"

    {escape(self.name)}

    \n" - f"{self.get_description(environ)}\n" - ) - - def get_headers( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> t.List[t.Tuple[str, str]]: - """Get a list of headers.""" - return [("Content-Type", "text/html; charset=utf-8")] - - def get_response( - self, - environ: t.Optional[t.Union["WSGIEnvironment", "WSGIRequest"]] = None, - scope: t.Optional[dict] = None, - ) -> "Response": - """Get a response object. If one was passed to the exception - it's returned directly. - - :param environ: the optional environ for the request. This - can be used to modify the response depending - on how the request looked like. - :return: a :class:`Response` object or a subclass thereof. - """ - from .wrappers.response import Response as WSGIResponse # noqa: F811 - - if self.response is not None: - return self.response - if environ is not None: - environ = _get_environ(environ) - headers = self.get_headers(environ, scope) - return WSGIResponse(self.get_body(environ, scope), self.code, headers) - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - """Call the exception as WSGI application. - - :param environ: the WSGI environment. - :param start_response: the response callable provided by the WSGI - server. - """ - response = t.cast("WSGIResponse", self.get_response(environ)) - return response(environ, start_response) - - def __str__(self) -> str: - code = self.code if self.code is not None else "???" - return f"{code} {self.name}: {self.description}" - - def __repr__(self) -> str: - code = self.code if self.code is not None else "???" - return f"<{type(self).__name__} '{code}: {self.name}'>" - - -class BadRequest(HTTPException): - """*400* `Bad Request` - - Raise if the browser sends something to the application the application - or server cannot handle. - """ - - code = 400 - description = ( - "The browser (or proxy) sent a request that this server could " - "not understand." - ) - - -class BadRequestKeyError(BadRequest, KeyError): - """An exception that is used to signal both a :exc:`KeyError` and a - :exc:`BadRequest`. Used by many of the datastructures. - """ - - _description = BadRequest.description - #: Show the KeyError along with the HTTP error message in the - #: response. This should be disabled in production, but can be - #: useful in a debug mode. - show_exception = False - - def __init__(self, arg: t.Optional[str] = None, *args: t.Any, **kwargs: t.Any): - super().__init__(*args, **kwargs) - - if arg is None: - KeyError.__init__(self) - else: - KeyError.__init__(self, arg) - - @property # type: ignore - def description(self) -> str: # type: ignore - if self.show_exception: - return ( - f"{self._description}\n" - f"{KeyError.__name__}: {KeyError.__str__(self)}" - ) - - return self._description - - @description.setter - def description(self, value: str) -> None: - self._description = value - - -class ClientDisconnected(BadRequest): - """Internal exception that is raised if Werkzeug detects a disconnected - client. Since the client is already gone at that point attempting to - send the error message to the client might not work and might ultimately - result in another exception in the server. Mainly this is here so that - it is silenced by default as far as Werkzeug is concerned. - - Since disconnections cannot be reliably detected and are unspecified - by WSGI to a large extent this might or might not be raised if a client - is gone. - - .. versionadded:: 0.8 - """ - - -class SecurityError(BadRequest): - """Raised if something triggers a security error. This is otherwise - exactly like a bad request error. - - .. versionadded:: 0.9 - """ - - -class BadHost(BadRequest): - """Raised if the submitted host is badly formatted. - - .. versionadded:: 0.11.2 - """ - - -class Unauthorized(HTTPException): - """*401* ``Unauthorized`` - - Raise if the user is not authorized to access a resource. - - The ``www_authenticate`` argument should be used to set the - ``WWW-Authenticate`` header. This is used for HTTP basic auth and - other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate` - to create correctly formatted values. Strictly speaking a 401 - response is invalid if it doesn't provide at least one value for - this header, although real clients typically don't care. - - :param description: Override the default message used for the body - of the response. - :param www-authenticate: A single value, or list of values, for the - WWW-Authenticate header(s). - - .. versionchanged:: 2.0 - Serialize multiple ``www_authenticate`` items into multiple - ``WWW-Authenticate`` headers, rather than joining them - into a single value, for better interoperability. - - .. versionchanged:: 0.15.3 - If the ``www_authenticate`` argument is not set, the - ``WWW-Authenticate`` header is not set. - - .. versionchanged:: 0.15.3 - The ``response`` argument was restored. - - .. versionchanged:: 0.15.1 - ``description`` was moved back as the first argument, restoring - its previous position. - - .. versionchanged:: 0.15.0 - ``www_authenticate`` was added as the first argument, ahead of - ``description``. - """ - - code = 401 - description = ( - "The server could not verify that you are authorized to access" - " the URL requested. You either supplied the wrong credentials" - " (e.g. a bad password), or your browser doesn't understand" - " how to supply the credentials required." - ) - - def __init__( - self, - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - www_authenticate: t.Optional[ - t.Union["WWWAuthenticate", t.Iterable["WWWAuthenticate"]] - ] = None, - ) -> None: - super().__init__(description, response) - - from .datastructures import WWWAuthenticate - - if isinstance(www_authenticate, WWWAuthenticate): - www_authenticate = (www_authenticate,) - - self.www_authenticate = www_authenticate - - def get_headers( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> t.List[t.Tuple[str, str]]: - headers = super().get_headers(environ, scope) - if self.www_authenticate: - headers.extend(("WWW-Authenticate", str(x)) for x in self.www_authenticate) - return headers - - -class Forbidden(HTTPException): - """*403* `Forbidden` - - Raise if the user doesn't have the permission for the requested resource - but was authenticated. - """ - - code = 403 - description = ( - "You don't have the permission to access the requested" - " resource. It is either read-protected or not readable by the" - " server." - ) - - -class NotFound(HTTPException): - """*404* `Not Found` - - Raise if a resource does not exist and never existed. - """ - - code = 404 - description = ( - "The requested URL was not found on the server. If you entered" - " the URL manually please check your spelling and try again." - ) - - -class MethodNotAllowed(HTTPException): - """*405* `Method Not Allowed` - - Raise if the server used a method the resource does not handle. For - example `POST` if the resource is view only. Especially useful for REST. - - The first argument for this exception should be a list of allowed methods. - Strictly speaking the response would be invalid if you don't provide valid - methods in the header which you can do with that list. - """ - - code = 405 - description = "The method is not allowed for the requested URL." - - def __init__( - self, - valid_methods: t.Optional[t.Iterable[str]] = None, - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - ) -> None: - """Takes an optional list of valid http methods - starting with werkzeug 0.3 the list will be mandatory.""" - super().__init__(description=description, response=response) - self.valid_methods = valid_methods - - def get_headers( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> t.List[t.Tuple[str, str]]: - headers = super().get_headers(environ, scope) - if self.valid_methods: - headers.append(("Allow", ", ".join(self.valid_methods))) - return headers - - -class NotAcceptable(HTTPException): - """*406* `Not Acceptable` - - Raise if the server can't return any content conforming to the - `Accept` headers of the client. - """ - - code = 406 - description = ( - "The resource identified by the request is only capable of" - " generating response entities which have content" - " characteristics not acceptable according to the accept" - " headers sent in the request." - ) - - -class RequestTimeout(HTTPException): - """*408* `Request Timeout` - - Raise to signalize a timeout. - """ - - code = 408 - description = ( - "The server closed the network connection because the browser" - " didn't finish the request within the specified time." - ) - - -class Conflict(HTTPException): - """*409* `Conflict` - - Raise to signal that a request cannot be completed because it conflicts - with the current state on the server. - - .. versionadded:: 0.7 - """ - - code = 409 - description = ( - "A conflict happened while processing the request. The" - " resource might have been modified while the request was being" - " processed." - ) - - -class Gone(HTTPException): - """*410* `Gone` - - Raise if a resource existed previously and went away without new location. - """ - - code = 410 - description = ( - "The requested URL is no longer available on this server and" - " there is no forwarding address. If you followed a link from a" - " foreign page, please contact the author of this page." - ) - - -class LengthRequired(HTTPException): - """*411* `Length Required` - - Raise if the browser submitted data but no ``Content-Length`` header which - is required for the kind of processing the server does. - """ - - code = 411 - description = ( - "A request with this method requires a valid Content-" - "Length header." - ) - - -class PreconditionFailed(HTTPException): - """*412* `Precondition Failed` - - Status code used in combination with ``If-Match``, ``If-None-Match``, or - ``If-Unmodified-Since``. - """ - - code = 412 - description = ( - "The precondition on the request for the URL failed positive evaluation." - ) - - -class RequestEntityTooLarge(HTTPException): - """*413* `Request Entity Too Large` - - The status code one should return if the data submitted exceeded a given - limit. - """ - - code = 413 - description = "The data value transmitted exceeds the capacity limit." - - -class RequestURITooLarge(HTTPException): - """*414* `Request URI Too Large` - - Like *413* but for too long URLs. - """ - - code = 414 - description = ( - "The length of the requested URL exceeds the capacity limit for" - " this server. The request cannot be processed." - ) - - -class UnsupportedMediaType(HTTPException): - """*415* `Unsupported Media Type` - - The status code returned if the server is unable to handle the media type - the client transmitted. - """ - - code = 415 - description = ( - "The server does not support the media type transmitted in the request." - ) - - -class RequestedRangeNotSatisfiable(HTTPException): - """*416* `Requested Range Not Satisfiable` - - The client asked for an invalid part of the file. - - .. versionadded:: 0.7 - """ - - code = 416 - description = "The server cannot provide the requested range." - - def __init__( - self, - length: t.Optional[int] = None, - units: str = "bytes", - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - ) -> None: - """Takes an optional `Content-Range` header value based on ``length`` - parameter. - """ - super().__init__(description=description, response=response) - self.length = length - self.units = units - - def get_headers( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> t.List[t.Tuple[str, str]]: - headers = super().get_headers(environ, scope) - if self.length is not None: - headers.append(("Content-Range", f"{self.units} */{self.length}")) - return headers - - -class ExpectationFailed(HTTPException): - """*417* `Expectation Failed` - - The server cannot meet the requirements of the Expect request-header. - - .. versionadded:: 0.7 - """ - - code = 417 - description = "The server could not meet the requirements of the Expect header" - - -class ImATeapot(HTTPException): - """*418* `I'm a teapot` - - The server should return this if it is a teapot and someone attempted - to brew coffee with it. - - .. versionadded:: 0.7 - """ - - code = 418 - description = "This server is a teapot, not a coffee machine" - - -class UnprocessableEntity(HTTPException): - """*422* `Unprocessable Entity` - - Used if the request is well formed, but the instructions are otherwise - incorrect. - """ - - code = 422 - description = ( - "The request was well-formed but was unable to be followed due" - " to semantic errors." - ) - - -class Locked(HTTPException): - """*423* `Locked` - - Used if the resource that is being accessed is locked. - """ - - code = 423 - description = "The resource that is being accessed is locked." - - -class FailedDependency(HTTPException): - """*424* `Failed Dependency` - - Used if the method could not be performed on the resource - because the requested action depended on another action and that action failed. - """ - - code = 424 - description = ( - "The method could not be performed on the resource because the" - " requested action depended on another action and that action" - " failed." - ) - - -class PreconditionRequired(HTTPException): - """*428* `Precondition Required` - - The server requires this request to be conditional, typically to prevent - the lost update problem, which is a race condition between two or more - clients attempting to update a resource through PUT or DELETE. By requiring - each client to include a conditional header ("If-Match" or "If-Unmodified- - Since") with the proper value retained from a recent GET request, the - server ensures that each client has at least seen the previous revision of - the resource. - """ - - code = 428 - description = ( - "This request is required to be conditional; try using" - ' "If-Match" or "If-Unmodified-Since".' - ) - - -class _RetryAfter(HTTPException): - """Adds an optional ``retry_after`` parameter which will set the - ``Retry-After`` header. May be an :class:`int` number of seconds or - a :class:`~datetime.datetime`. - """ - - def __init__( - self, - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - retry_after: t.Optional[t.Union[datetime, int]] = None, - ) -> None: - super().__init__(description, response) - self.retry_after = retry_after - - def get_headers( - self, - environ: t.Optional["WSGIEnvironment"] = None, - scope: t.Optional[dict] = None, - ) -> t.List[t.Tuple[str, str]]: - headers = super().get_headers(environ, scope) - - if self.retry_after: - if isinstance(self.retry_after, datetime): - from .http import http_date - - value = http_date(self.retry_after) - else: - value = str(self.retry_after) - - headers.append(("Retry-After", value)) - - return headers - - -class TooManyRequests(_RetryAfter): - """*429* `Too Many Requests` - - The server is limiting the rate at which this user receives - responses, and this request exceeds that rate. (The server may use - any convenient method to identify users and their request rates). - The server may include a "Retry-After" header to indicate how long - the user should wait before retrying. - - :param retry_after: If given, set the ``Retry-After`` header to this - value. May be an :class:`int` number of seconds or a - :class:`~datetime.datetime`. - - .. versionchanged:: 1.0 - Added ``retry_after`` parameter. - """ - - code = 429 - description = "This user has exceeded an allotted request count. Try again later." - - -class RequestHeaderFieldsTooLarge(HTTPException): - """*431* `Request Header Fields Too Large` - - The server refuses to process the request because the header fields are too - large. One or more individual fields may be too large, or the set of all - headers is too large. - """ - - code = 431 - description = "One or more header fields exceeds the maximum size." - - -class UnavailableForLegalReasons(HTTPException): - """*451* `Unavailable For Legal Reasons` - - This status code indicates that the server is denying access to the - resource as a consequence of a legal demand. - """ - - code = 451 - description = "Unavailable for legal reasons." - - -class InternalServerError(HTTPException): - """*500* `Internal Server Error` - - Raise if an internal server error occurred. This is a good fallback if an - unknown error occurred in the dispatcher. - - .. versionchanged:: 1.0.0 - Added the :attr:`original_exception` attribute. - """ - - code = 500 - description = ( - "The server encountered an internal error and was unable to" - " complete your request. Either the server is overloaded or" - " there is an error in the application." - ) - - def __init__( - self, - description: t.Optional[str] = None, - response: t.Optional["Response"] = None, - original_exception: t.Optional[BaseException] = None, - ) -> None: - #: The original exception that caused this 500 error. Can be - #: used by frameworks to provide context when handling - #: unexpected errors. - self.original_exception = original_exception - super().__init__(description=description, response=response) - - -class NotImplemented(HTTPException): - """*501* `Not Implemented` - - Raise if the application does not support the action requested by the - browser. - """ - - code = 501 - description = "The server does not support the action requested by the browser." - - -class BadGateway(HTTPException): - """*502* `Bad Gateway` - - If you do proxying in your application you should return this status code - if you received an invalid response from the upstream server it accessed - in attempting to fulfill the request. - """ - - code = 502 - description = ( - "The proxy server received an invalid response from an upstream server." - ) - - -class ServiceUnavailable(_RetryAfter): - """*503* `Service Unavailable` - - Status code you should return if a service is temporarily - unavailable. - - :param retry_after: If given, set the ``Retry-After`` header to this - value. May be an :class:`int` number of seconds or a - :class:`~datetime.datetime`. - - .. versionchanged:: 1.0 - Added ``retry_after`` parameter. - """ - - code = 503 - description = ( - "The server is temporarily unable to service your request due" - " to maintenance downtime or capacity problems. Please try" - " again later." - ) - - -class GatewayTimeout(HTTPException): - """*504* `Gateway Timeout` - - Status code you should return if a connection to an upstream server - times out. - """ - - code = 504 - description = "The connection to an upstream server timed out." - - -class HTTPVersionNotSupported(HTTPException): - """*505* `HTTP Version Not Supported` - - The server does not support the HTTP protocol version used in the request. - """ - - code = 505 - description = ( - "The server does not support the HTTP protocol version used in the request." - ) - - -default_exceptions: t.Dict[int, t.Type[HTTPException]] = {} - - -def _find_exceptions() -> None: - for obj in globals().values(): - try: - is_http_exception = issubclass(obj, HTTPException) - except TypeError: - is_http_exception = False - if not is_http_exception or obj.code is None: - continue - old_obj = default_exceptions.get(obj.code, None) - if old_obj is not None and issubclass(obj, old_obj): - continue - default_exceptions[obj.code] = obj - - -_find_exceptions() -del _find_exceptions - - -class Aborter: - """When passed a dict of code -> exception items it can be used as - callable that raises exceptions. If the first argument to the - callable is an integer it will be looked up in the mapping, if it's - a WSGI application it will be raised in a proxy exception. - - The rest of the arguments are forwarded to the exception constructor. - """ - - def __init__( - self, - mapping: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, - extra: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, - ) -> None: - if mapping is None: - mapping = default_exceptions - self.mapping = dict(mapping) - if extra is not None: - self.mapping.update(extra) - - def __call__( - self, code: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any - ) -> "te.NoReturn": - from .sansio.response import Response - - if isinstance(code, Response): - raise HTTPException(response=code) - - if code not in self.mapping: - raise LookupError(f"no exception for {code!r}") - - raise self.mapping[code](*args, **kwargs) - - -def abort( - status: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any -) -> "te.NoReturn": - """Raises an :py:exc:`HTTPException` for the given status code or WSGI - application. - - If a status code is given, it will be looked up in the list of - exceptions and will raise that exception. If passed a WSGI application, - it will wrap it in a proxy WSGI exception and raise that:: - - abort(404) # 404 Not Found - abort(Response('Hello World')) - - """ - _aborter(status, *args, **kwargs) - - -_aborter: Aborter = Aborter() diff --git a/venv/lib/python3.7/site-packages/werkzeug/filesystem.py b/venv/lib/python3.7/site-packages/werkzeug/filesystem.py deleted file mode 100644 index 36a3d12..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/filesystem.py +++ /dev/null @@ -1,55 +0,0 @@ -import codecs -import sys -import typing as t -import warnings - -# We do not trust traditional unixes. -has_likely_buggy_unicode_filesystem = ( - sys.platform.startswith("linux") or "bsd" in sys.platform -) - - -def _is_ascii_encoding(encoding: t.Optional[str]) -> bool: - """Given an encoding this figures out if the encoding is actually ASCII (which - is something we don't actually want in most cases). This is necessary - because ASCII comes under many names such as ANSI_X3.4-1968. - """ - if encoding is None: - return False - try: - return codecs.lookup(encoding).name == "ascii" - except LookupError: - return False - - -class BrokenFilesystemWarning(RuntimeWarning, UnicodeWarning): - """The warning used by Werkzeug to signal a broken filesystem. Will only be - used once per runtime.""" - - -_warned_about_filesystem_encoding = False - - -def get_filesystem_encoding() -> str: - """Returns the filesystem encoding that should be used. Note that this is - different from the Python understanding of the filesystem encoding which - might be deeply flawed. Do not use this value against Python's string APIs - because it might be different. See :ref:`filesystem-encoding` for the exact - behavior. - - The concept of a filesystem encoding in generally is not something you - should rely on. As such if you ever need to use this function except for - writing wrapper code reconsider. - """ - global _warned_about_filesystem_encoding - rv = sys.getfilesystemencoding() - if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv): - if not _warned_about_filesystem_encoding: - warnings.warn( - "Detected a misconfigured UNIX filesystem: Will use" - f" UTF-8 as filesystem encoding instead of {rv!r}", - BrokenFilesystemWarning, - ) - _warned_about_filesystem_encoding = True - return "utf-8" - return rv diff --git a/venv/lib/python3.7/site-packages/werkzeug/formparser.py b/venv/lib/python3.7/site-packages/werkzeug/formparser.py deleted file mode 100644 index 6cb758f..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/formparser.py +++ /dev/null @@ -1,495 +0,0 @@ -import typing as t -import warnings -from functools import update_wrapper -from io import BytesIO -from itertools import chain -from typing import Union - -from . import exceptions -from ._internal import _to_str -from .datastructures import FileStorage -from .datastructures import Headers -from .datastructures import MultiDict -from .http import parse_options_header -from .sansio.multipart import Data -from .sansio.multipart import Epilogue -from .sansio.multipart import Field -from .sansio.multipart import File -from .sansio.multipart import MultipartDecoder -from .sansio.multipart import NeedData -from .urls import url_decode_stream -from .wsgi import _make_chunk_iter -from .wsgi import get_content_length -from .wsgi import get_input_stream - -# there are some platforms where SpooledTemporaryFile is not available. -# In that case we need to provide a fallback. -try: - from tempfile import SpooledTemporaryFile -except ImportError: - from tempfile import TemporaryFile - - SpooledTemporaryFile = None # type: ignore - -if t.TYPE_CHECKING: - import typing as te - from _typeshed.wsgi import WSGIEnvironment - - t_parse_result = t.Tuple[t.IO[bytes], MultiDict, MultiDict] - - class TStreamFactory(te.Protocol): - def __call__( - self, - total_content_length: t.Optional[int], - content_type: t.Optional[str], - filename: t.Optional[str], - content_length: t.Optional[int] = None, - ) -> t.IO[bytes]: - ... - - -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) - - -def _exhaust(stream: t.IO[bytes]) -> None: - bts = stream.read(64 * 1024) - while bts: - bts = stream.read(64 * 1024) - - -def default_stream_factory( - total_content_length: t.Optional[int], - content_type: t.Optional[str], - filename: t.Optional[str], - content_length: t.Optional[int] = None, -) -> t.IO[bytes]: - max_size = 1024 * 500 - - if SpooledTemporaryFile is not None: - return t.cast(t.IO[bytes], SpooledTemporaryFile(max_size=max_size, mode="rb+")) - elif total_content_length is None or total_content_length > max_size: - return t.cast(t.IO[bytes], TemporaryFile("rb+")) - - return BytesIO() - - -def parse_form_data( - environ: "WSGIEnvironment", - stream_factory: t.Optional["TStreamFactory"] = None, - charset: str = "utf-8", - errors: str = "replace", - max_form_memory_size: t.Optional[int] = None, - max_content_length: t.Optional[int] = None, - cls: t.Optional[t.Type[MultiDict]] = None, - silent: bool = True, -) -> "t_parse_result": - """Parse the form data in the environ and return it as tuple in the form - ``(stream, form, files)``. You should only call this method if the - transport method is `POST`, `PUT`, or `PATCH`. - - If the mimetype of the data transmitted is `multipart/form-data` the - files multidict will be filled with `FileStorage` objects. If the - mimetype is unknown the input stream is wrapped and returned as first - argument, else the stream is empty. - - This is a shortcut for the common usage of :class:`FormDataParser`. - - Have a look at :doc:`/request_data` for more details. - - .. versionadded:: 0.5 - The `max_form_memory_size`, `max_content_length` and - `cls` parameters were added. - - .. versionadded:: 0.5.1 - The optional `silent` flag was added. - - :param environ: the WSGI environment to be used for parsing. - :param stream_factory: An optional callable that returns a new read and - writeable file descriptor. This callable works - the same as :meth:`Response._get_file_stream`. - :param charset: The character set for URL and url encoded form data. - :param errors: The encoding error behavior. - :param max_form_memory_size: the maximum number of bytes to be accepted for - in-memory stored form data. If the data - exceeds the value specified an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param max_content_length: If this is provided and the transmitted data - is longer than this value an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param silent: If set to False parsing errors will not be caught. - :return: A tuple in the form ``(stream, form, files)``. - """ - return FormDataParser( - stream_factory, - charset, - errors, - max_form_memory_size, - max_content_length, - cls, - silent, - ).parse_from_environ(environ) - - -def exhaust_stream(f: F) -> F: - """Helper decorator for methods that exhausts the stream on return.""" - - def wrapper(self, stream, *args, **kwargs): # type: ignore - try: - return f(self, stream, *args, **kwargs) - finally: - exhaust = getattr(stream, "exhaust", None) - - if exhaust is not None: - exhaust() - else: - while True: - chunk = stream.read(1024 * 64) - - if not chunk: - break - - return update_wrapper(t.cast(F, wrapper), f) - - -class FormDataParser: - """This class implements parsing of form data for Werkzeug. By itself - it can parse multipart and url encoded form data. It can be subclassed - and extended but for most mimetypes it is a better idea to use the - untouched stream and expose it as separate attributes on a request - object. - - .. versionadded:: 0.8 - - :param stream_factory: An optional callable that returns a new read and - writeable file descriptor. This callable works - the same as :meth:`Response._get_file_stream`. - :param charset: The character set for URL and url encoded form data. - :param errors: The encoding error behavior. - :param max_form_memory_size: the maximum number of bytes to be accepted for - in-memory stored form data. If the data - exceeds the value specified an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param max_content_length: If this is provided and the transmitted data - is longer than this value an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param silent: If set to False parsing errors will not be caught. - """ - - def __init__( - self, - stream_factory: t.Optional["TStreamFactory"] = None, - charset: str = "utf-8", - errors: str = "replace", - max_form_memory_size: t.Optional[int] = None, - max_content_length: t.Optional[int] = None, - cls: t.Optional[t.Type[MultiDict]] = None, - silent: bool = True, - ) -> None: - if stream_factory is None: - stream_factory = default_stream_factory - - self.stream_factory = stream_factory - self.charset = charset - self.errors = errors - self.max_form_memory_size = max_form_memory_size - self.max_content_length = max_content_length - - if cls is None: - cls = MultiDict - - self.cls = cls - self.silent = silent - - def get_parse_func( - self, mimetype: str, options: t.Dict[str, str] - ) -> t.Optional[ - t.Callable[ - ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], - "t_parse_result", - ] - ]: - return self.parse_functions.get(mimetype) - - def parse_from_environ(self, environ: "WSGIEnvironment") -> "t_parse_result": - """Parses the information from the environment as form data. - - :param environ: the WSGI environment to be used for parsing. - :return: A tuple in the form ``(stream, form, files)``. - """ - content_type = environ.get("CONTENT_TYPE", "") - content_length = get_content_length(environ) - mimetype, options = parse_options_header(content_type) - return self.parse(get_input_stream(environ), mimetype, content_length, options) - - def parse( - self, - stream: t.IO[bytes], - mimetype: str, - content_length: t.Optional[int], - options: t.Optional[t.Dict[str, str]] = None, - ) -> "t_parse_result": - """Parses the information from the given stream, mimetype, - content length and mimetype parameters. - - :param stream: an input stream - :param mimetype: the mimetype of the data - :param content_length: the content length of the incoming data - :param options: optional mimetype parameters (used for - the multipart boundary for instance) - :return: A tuple in the form ``(stream, form, files)``. - """ - if ( - self.max_content_length is not None - and content_length is not None - and content_length > self.max_content_length - ): - # if the input stream is not exhausted, firefox reports Connection Reset - _exhaust(stream) - raise exceptions.RequestEntityTooLarge() - - if options is None: - options = {} - - parse_func = self.get_parse_func(mimetype, options) - - if parse_func is not None: - try: - return parse_func(self, stream, mimetype, content_length, options) - except ValueError: - if not self.silent: - raise - - return stream, self.cls(), self.cls() - - @exhaust_stream - def _parse_multipart( - self, - stream: t.IO[bytes], - mimetype: str, - content_length: t.Optional[int], - options: t.Dict[str, str], - ) -> "t_parse_result": - parser = MultiPartParser( - self.stream_factory, - self.charset, - self.errors, - max_form_memory_size=self.max_form_memory_size, - cls=self.cls, - ) - boundary = options.get("boundary", "").encode("ascii") - - if not boundary: - raise ValueError("Missing boundary") - - form, files = parser.parse(stream, boundary, content_length) - return stream, form, files - - @exhaust_stream - def _parse_urlencoded( - self, - stream: t.IO[bytes], - mimetype: str, - content_length: t.Optional[int], - options: t.Dict[str, str], - ) -> "t_parse_result": - if ( - self.max_form_memory_size is not None - and content_length is not None - and content_length > self.max_form_memory_size - ): - # if the input stream is not exhausted, firefox reports Connection Reset - _exhaust(stream) - raise exceptions.RequestEntityTooLarge() - - form = url_decode_stream(stream, self.charset, errors=self.errors, cls=self.cls) - return stream, form, self.cls() - - #: mapping of mimetypes to parsing functions - parse_functions: t.Dict[ - str, - t.Callable[ - ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], - "t_parse_result", - ], - ] = { - "multipart/form-data": _parse_multipart, - "application/x-www-form-urlencoded": _parse_urlencoded, - "application/x-url-encoded": _parse_urlencoded, - } - - -def _line_parse(line: str) -> t.Tuple[str, bool]: - """Removes line ending characters and returns a tuple (`stripped_line`, - `is_terminated`). - """ - if line[-2:] == "\r\n": - return line[:-2], True - - elif line[-1:] in {"\r", "\n"}: - return line[:-1], True - - return line, False - - -def parse_multipart_headers(iterable: t.Iterable[bytes]) -> Headers: - """Parses multipart headers from an iterable that yields lines (including - the trailing newline symbol). The iterable has to be newline terminated. - The iterable will stop at the line where the headers ended so it can be - further consumed. - :param iterable: iterable of strings that are newline terminated - """ - warnings.warn( - "'parse_multipart_headers' is deprecated and will be removed in" - " Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - result: t.List[t.Tuple[str, str]] = [] - - for b_line in iterable: - line = _to_str(b_line) - line, line_terminated = _line_parse(line) - - if not line_terminated: - raise ValueError("unexpected end of line in multipart header") - - if not line: - break - elif line[0] in " \t" and result: - key, value = result[-1] - result[-1] = (key, f"{value}\n {line[1:]}") - else: - parts = line.split(":", 1) - - if len(parts) == 2: - result.append((parts[0].strip(), parts[1].strip())) - - # we link the list to the headers, no need to create a copy, the - # list was not shared anyways. - return Headers(result) - - -class MultiPartParser: - def __init__( - self, - stream_factory: t.Optional["TStreamFactory"] = None, - charset: str = "utf-8", - errors: str = "replace", - max_form_memory_size: t.Optional[int] = None, - cls: t.Optional[t.Type[MultiDict]] = None, - buffer_size: int = 64 * 1024, - ) -> None: - self.charset = charset - self.errors = errors - self.max_form_memory_size = max_form_memory_size - - if stream_factory is None: - stream_factory = default_stream_factory - - self.stream_factory = stream_factory - - if cls is None: - cls = MultiDict - - self.cls = cls - - self.buffer_size = buffer_size - - def fail(self, message: str) -> "te.NoReturn": - raise ValueError(message) - - def get_part_charset(self, headers: Headers) -> str: - # Figure out input charset for current part - content_type = headers.get("content-type") - - if content_type: - mimetype, ct_params = parse_options_header(content_type) - return ct_params.get("charset", self.charset) - - return self.charset - - def start_file_streaming( - self, event: File, total_content_length: t.Optional[int] - ) -> t.IO[bytes]: - content_type = event.headers.get("content-type") - - try: - content_length = int(event.headers["content-length"]) - except (KeyError, ValueError): - content_length = 0 - - container = self.stream_factory( - total_content_length=total_content_length, - filename=event.filename, - content_type=content_type, - content_length=content_length, - ) - return container - - def parse( - self, stream: t.IO[bytes], boundary: bytes, content_length: t.Optional[int] - ) -> t.Tuple[MultiDict, MultiDict]: - container: t.Union[t.IO[bytes], t.List[bytes]] - _write: t.Callable[[bytes], t.Any] - - iterator = chain( - _make_chunk_iter( - stream, - limit=content_length, - buffer_size=self.buffer_size, - ), - [None], - ) - - parser = MultipartDecoder(boundary, self.max_form_memory_size) - - fields = [] - files = [] - - current_part: Union[Field, File] - for data in iterator: - parser.receive_data(data) - event = parser.next_event() - while not isinstance(event, (Epilogue, NeedData)): - if isinstance(event, Field): - current_part = event - container = [] - _write = container.append - elif isinstance(event, File): - current_part = event - container = self.start_file_streaming(event, content_length) - _write = container.write - elif isinstance(event, Data): - _write(event.data) - if not event.more_data: - if isinstance(current_part, Field): - value = b"".join(container).decode( - self.get_part_charset(current_part.headers), self.errors - ) - fields.append((current_part.name, value)) - else: - container = t.cast(t.IO[bytes], container) - container.seek(0) - files.append( - ( - current_part.name, - FileStorage( - container, - current_part.filename, - current_part.name, - headers=current_part.headers, - ), - ) - ) - - event = parser.next_event() - - return self.cls(fields), self.cls(files) diff --git a/venv/lib/python3.7/site-packages/werkzeug/http.py b/venv/lib/python3.7/site-packages/werkzeug/http.py deleted file mode 100644 index 45799bf..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/http.py +++ /dev/null @@ -1,1393 +0,0 @@ -import base64 -import email.utils -import re -import typing -import typing as t -import warnings -from datetime import date -from datetime import datetime -from datetime import time -from datetime import timedelta -from datetime import timezone -from enum import Enum -from hashlib import sha1 -from time import mktime -from time import struct_time -from urllib.parse import unquote_to_bytes as _unquote -from urllib.request import parse_http_list as _parse_list_header - -from ._internal import _cookie_parse_impl -from ._internal import _cookie_quote -from ._internal import _make_cookie_domain -from ._internal import _to_bytes -from ._internal import _to_str -from ._internal import _wsgi_decoding_dance -from werkzeug._internal import _dt_as_utc - -if t.TYPE_CHECKING: - import typing_extensions as te - from _typeshed.wsgi import WSGIEnvironment - -# for explanation of "media-range", etc. see Sections 5.3.{1,2} of RFC 7231 -_accept_re = re.compile( - r""" - ( # media-range capturing-parenthesis - [^\s;,]+ # type/subtype - (?:[ \t]*;[ \t]* # ";" - (?: # parameter non-capturing-parenthesis - [^\s;,q][^\s;,]* # token that doesn't start with "q" - | # or - q[^\s;,=][^\s;,]* # token that is more than just "q" - ) - )* # zero or more parameters - ) # end of media-range - (?:[ \t]*;[ \t]*q= # weight is a "q" parameter - (\d*(?:\.\d+)?) # qvalue capturing-parentheses - [^,]* # "extension" accept params: who cares? - )? # accept params are optional - """, - re.VERBOSE, -) -_token_chars = frozenset( - "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~" -) -_etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)') -_option_header_piece_re = re.compile( - r""" - ;\s*,?\s* # newlines were replaced with commas - (?P - "[^"\\]*(?:\\.[^"\\]*)*" # quoted string - | - [^\s;,=*]+ # token - ) - (?:\*(?P\d+))? # *1, optional continuation index - \s* - (?: # optionally followed by =value - (?: # equals sign, possibly with encoding - \*\s*=\s* # * indicates extended notation - (?: # optional encoding - (?P[^\s]+?) - '(?P[^\s]*?)' - )? - | - =\s* # basic notation - ) - (?P - "[^"\\]*(?:\\.[^"\\]*)*" # quoted string - | - [^;,]+ # token - )? - )? - \s* - """, - flags=re.VERBOSE, -) -_option_header_start_mime_type = re.compile(r",\s*([^;,\s]+)([;,]\s*.+)?") -_entity_headers = frozenset( - [ - "allow", - "content-encoding", - "content-language", - "content-length", - "content-location", - "content-md5", - "content-range", - "content-type", - "expires", - "last-modified", - ] -) -_hop_by_hop_headers = frozenset( - [ - "connection", - "keep-alive", - "proxy-authenticate", - "proxy-authorization", - "te", - "trailer", - "transfer-encoding", - "upgrade", - ] -) -HTTP_STATUS_CODES = { - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 103: "Early Hints", # see RFC 8297 - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi Status", - 208: "Already Reported", # see RFC 5842 - 226: "IM Used", # see RFC 3229 - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 306: "Switch Proxy", # unused - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", # unused - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", # see RFC 2324 - 421: "Misdirected Request", # see RFC 7540 - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 425: "Too Early", # see RFC 8470 - 426: "Upgrade Required", - 428: "Precondition Required", # see RFC 6585 - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 449: "Retry With", # proprietary MS extension - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", # see RFC 2295 - 507: "Insufficient Storage", - 508: "Loop Detected", # see RFC 5842 - 510: "Not Extended", - 511: "Network Authentication Failed", -} - - -class COEP(Enum): - """Cross Origin Embedder Policies""" - - UNSAFE_NONE = "unsafe-none" - REQUIRE_CORP = "require-corp" - - -class COOP(Enum): - """Cross Origin Opener Policies""" - - UNSAFE_NONE = "unsafe-none" - SAME_ORIGIN_ALLOW_POPUPS = "same-origin-allow-popups" - SAME_ORIGIN = "same-origin" - - -def quote_header_value( - value: t.Union[str, int], extra_chars: str = "", allow_token: bool = True -) -> str: - """Quote a header value if necessary. - - .. versionadded:: 0.5 - - :param value: the value to quote. - :param extra_chars: a list of extra characters to skip quoting. - :param allow_token: if this is enabled token values are returned - unchanged. - """ - if isinstance(value, bytes): - value = value.decode("latin1") - value = str(value) - if allow_token: - token_chars = _token_chars | set(extra_chars) - if set(value).issubset(token_chars): - return value - value = value.replace("\\", "\\\\").replace('"', '\\"') - return f'"{value}"' - - -def unquote_header_value(value: str, is_filename: bool = False) -> str: - r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). - This does not use the real unquoting but what browsers are actually - using for quoting. - - .. versionadded:: 0.5 - - :param value: the header value to unquote. - :param is_filename: The value represents a filename or path. - """ - if value and value[0] == value[-1] == '"': - # this is not the real unquoting, but fixing this so that the - # RFC is met will result in bugs with internet explorer and - # probably some other browsers as well. IE for example is - # uploading files with "C:\foo\bar.txt" as filename - value = value[1:-1] - - # if this is a filename and the starting characters look like - # a UNC path, then just return the value without quotes. Using the - # replace sequence below on a UNC path has the effect of turning - # the leading double slash into a single slash and then - # _fix_ie_filename() doesn't work correctly. See #458. - if not is_filename or value[:2] != "\\\\": - return value.replace("\\\\", "\\").replace('\\"', '"') - return value - - -def dump_options_header( - header: t.Optional[str], options: t.Mapping[str, t.Optional[t.Union[str, int]]] -) -> str: - """The reverse function to :func:`parse_options_header`. - - :param header: the header to dump - :param options: a dict of options to append. - """ - segments = [] - if header is not None: - segments.append(header) - for key, value in options.items(): - if value is None: - segments.append(key) - else: - segments.append(f"{key}={quote_header_value(value)}") - return "; ".join(segments) - - -def dump_header( - iterable: t.Union[t.Dict[str, t.Union[str, int]], t.Iterable[str]], - allow_token: bool = True, -) -> str: - """Dump an HTTP header again. This is the reversal of - :func:`parse_list_header`, :func:`parse_set_header` and - :func:`parse_dict_header`. This also quotes strings that include an - equals sign unless you pass it as dict of key, value pairs. - - >>> dump_header({'foo': 'bar baz'}) - 'foo="bar baz"' - >>> dump_header(('foo', 'bar baz')) - 'foo, "bar baz"' - - :param iterable: the iterable or dict of values to quote. - :param allow_token: if set to `False` tokens as values are disallowed. - See :func:`quote_header_value` for more details. - """ - if isinstance(iterable, dict): - items = [] - for key, value in iterable.items(): - if value is None: - items.append(key) - else: - items.append( - f"{key}={quote_header_value(value, allow_token=allow_token)}" - ) - else: - items = [quote_header_value(x, allow_token=allow_token) for x in iterable] - return ", ".join(items) - - -def dump_csp_header(header: "ds.ContentSecurityPolicy") -> str: - """Dump a Content Security Policy header. - - These are structured into policies such as "default-src 'self'; - script-src 'self'". - - .. versionadded:: 1.0.0 - Support for Content Security Policy headers was added. - - """ - return "; ".join(f"{key} {value}" for key, value in header.items()) - - -def parse_list_header(value: str) -> t.List[str]: - """Parse lists as described by RFC 2068 Section 2. - - In particular, parse comma-separated lists where the elements of - the list may include quoted-strings. A quoted-string could - contain a comma. A non-quoted string could have quotes in the - middle. Quotes are removed automatically after parsing. - - It basically works like :func:`parse_set_header` just that items - may appear multiple times and case sensitivity is preserved. - - The return value is a standard :class:`list`: - - >>> parse_list_header('token, "quoted value"') - ['token', 'quoted value'] - - To create a header from the :class:`list` again, use the - :func:`dump_header` function. - - :param value: a string with a list header. - :return: :class:`list` - """ - result = [] - for item in _parse_list_header(value): - if item[:1] == item[-1:] == '"': - item = unquote_header_value(item[1:-1]) - result.append(item) - return result - - -def parse_dict_header(value: str, cls: t.Type[dict] = dict) -> t.Dict[str, str]: - """Parse lists of key, value pairs as described by RFC 2068 Section 2 and - convert them into a python dict (or any other mapping object created from - the type with a dict like interface provided by the `cls` argument): - - >>> d = parse_dict_header('foo="is a fish", bar="as well"') - >>> type(d) is dict - True - >>> sorted(d.items()) - [('bar', 'as well'), ('foo', 'is a fish')] - - If there is no value for a key it will be `None`: - - >>> parse_dict_header('key_without_value') - {'key_without_value': None} - - To create a header from the :class:`dict` again, use the - :func:`dump_header` function. - - .. versionchanged:: 0.9 - Added support for `cls` argument. - - :param value: a string with a dict header. - :param cls: callable to use for storage of parsed results. - :return: an instance of `cls` - """ - result = cls() - if isinstance(value, bytes): - value = value.decode("latin1") - for item in _parse_list_header(value): - if "=" not in item: - result[item] = None - continue - name, value = item.split("=", 1) - if value[:1] == value[-1:] == '"': - value = unquote_header_value(value[1:-1]) - result[name] = value - return result - - -@typing.overload -def parse_options_header( - value: t.Optional[str], multiple: "te.Literal[False]" = False -) -> t.Tuple[str, t.Dict[str, str]]: - ... - - -@typing.overload -def parse_options_header( - value: t.Optional[str], multiple: "te.Literal[True]" -) -> t.Tuple[t.Any, ...]: - ... - - -def parse_options_header( - value: t.Optional[str], multiple: bool = False -) -> t.Union[t.Tuple[str, t.Dict[str, str]], t.Tuple[t.Any, ...]]: - """Parse a ``Content-Type`` like header into a tuple with the content - type and the options: - - >>> parse_options_header('text/html; charset=utf8') - ('text/html', {'charset': 'utf8'}) - - This should not be used to parse ``Cache-Control`` like headers that use - a slightly different format. For these headers use the - :func:`parse_dict_header` function. - - .. versionchanged:: 0.15 - :rfc:`2231` parameter continuations are handled. - - .. versionadded:: 0.5 - - :param value: the header to parse. - :param multiple: Whether try to parse and return multiple MIME types - :return: (mimetype, options) or (mimetype, options, mimetype, options, …) - if multiple=True - """ - if not value: - return "", {} - - result: t.List[t.Any] = [] - - value = "," + value.replace("\n", ",") - while value: - match = _option_header_start_mime_type.match(value) - if not match: - break - result.append(match.group(1)) # mimetype - options: t.Dict[str, str] = {} - # Parse options - rest = match.group(2) - encoding: t.Optional[str] - continued_encoding: t.Optional[str] = None - while rest: - optmatch = _option_header_piece_re.match(rest) - if not optmatch: - break - option, count, encoding, language, option_value = optmatch.groups() - # Continuations don't have to supply the encoding after the - # first line. If we're in a continuation, track the current - # encoding to use for subsequent lines. Reset it when the - # continuation ends. - if not count: - continued_encoding = None - else: - if not encoding: - encoding = continued_encoding - continued_encoding = encoding - option = unquote_header_value(option) - - if option_value is not None: - option_value = unquote_header_value(option_value, option == "filename") - - if encoding is not None: - option_value = _unquote(option_value).decode(encoding) - - if count: - # Continuations append to the existing value. For - # simplicity, this ignores the possibility of - # out-of-order indices, which shouldn't happen anyway. - if option_value is not None: - options[option] = options.get(option, "") + option_value - else: - options[option] = option_value # type: ignore[assignment] - - rest = rest[optmatch.end() :] - result.append(options) - if multiple is False: - return tuple(result) - value = rest - - return tuple(result) if result else ("", {}) - - -_TAnyAccept = t.TypeVar("_TAnyAccept", bound="ds.Accept") - - -@typing.overload -def parse_accept_header(value: t.Optional[str]) -> "ds.Accept": - ... - - -@typing.overload -def parse_accept_header( - value: t.Optional[str], cls: t.Type[_TAnyAccept] -) -> _TAnyAccept: - ... - - -def parse_accept_header( - value: t.Optional[str], cls: t.Optional[t.Type[_TAnyAccept]] = None -) -> _TAnyAccept: - """Parses an HTTP Accept-* header. This does not implement a complete - valid algorithm but one that supports at least value and quality - extraction. - - Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` - tuples sorted by the quality with some additional accessor methods). - - The second parameter can be a subclass of :class:`Accept` that is created - with the parsed values and returned. - - :param value: the accept header string to be parsed. - :param cls: the wrapper class for the return value (can be - :class:`Accept` or a subclass thereof) - :return: an instance of `cls`. - """ - if cls is None: - cls = t.cast(t.Type[_TAnyAccept], ds.Accept) - - if not value: - return cls(None) - - result = [] - for match in _accept_re.finditer(value): - quality_match = match.group(2) - if not quality_match: - quality: float = 1 - else: - quality = max(min(float(quality_match), 1), 0) - result.append((match.group(1), quality)) - return cls(result) - - -_TAnyCC = t.TypeVar("_TAnyCC", bound="ds._CacheControl") -_t_cc_update = t.Optional[t.Callable[[_TAnyCC], None]] - - -@typing.overload -def parse_cache_control_header( - value: t.Optional[str], on_update: _t_cc_update, cls: None = None -) -> "ds.RequestCacheControl": - ... - - -@typing.overload -def parse_cache_control_header( - value: t.Optional[str], on_update: _t_cc_update, cls: t.Type[_TAnyCC] -) -> _TAnyCC: - ... - - -def parse_cache_control_header( - value: t.Optional[str], - on_update: _t_cc_update = None, - cls: t.Optional[t.Type[_TAnyCC]] = None, -) -> _TAnyCC: - """Parse a cache control header. The RFC differs between response and - request cache control, this method does not. It's your responsibility - to not use the wrong control statements. - - .. versionadded:: 0.5 - The `cls` was added. If not specified an immutable - :class:`~werkzeug.datastructures.RequestCacheControl` is returned. - - :param value: a cache control header to be parsed. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.CacheControl` - object is changed. - :param cls: the class for the returned object. By default - :class:`~werkzeug.datastructures.RequestCacheControl` is used. - :return: a `cls` object. - """ - if cls is None: - cls = t.cast(t.Type[_TAnyCC], ds.RequestCacheControl) - - if not value: - return cls((), on_update) - - return cls(parse_dict_header(value), on_update) - - -_TAnyCSP = t.TypeVar("_TAnyCSP", bound="ds.ContentSecurityPolicy") -_t_csp_update = t.Optional[t.Callable[[_TAnyCSP], None]] - - -@typing.overload -def parse_csp_header( - value: t.Optional[str], on_update: _t_csp_update, cls: None = None -) -> "ds.ContentSecurityPolicy": - ... - - -@typing.overload -def parse_csp_header( - value: t.Optional[str], on_update: _t_csp_update, cls: t.Type[_TAnyCSP] -) -> _TAnyCSP: - ... - - -def parse_csp_header( - value: t.Optional[str], - on_update: _t_csp_update = None, - cls: t.Optional[t.Type[_TAnyCSP]] = None, -) -> _TAnyCSP: - """Parse a Content Security Policy header. - - .. versionadded:: 1.0.0 - Support for Content Security Policy headers was added. - - :param value: a csp header to be parsed. - :param on_update: an optional callable that is called every time a value - on the object is changed. - :param cls: the class for the returned object. By default - :class:`~werkzeug.datastructures.ContentSecurityPolicy` is used. - :return: a `cls` object. - """ - if cls is None: - cls = t.cast(t.Type[_TAnyCSP], ds.ContentSecurityPolicy) - - if value is None: - return cls((), on_update) - - items = [] - - for policy in value.split(";"): - policy = policy.strip() - - # Ignore badly formatted policies (no space) - if " " in policy: - directive, value = policy.strip().split(" ", 1) - items.append((directive.strip(), value.strip())) - - return cls(items, on_update) - - -def parse_set_header( - value: t.Optional[str], - on_update: t.Optional[t.Callable[["ds.HeaderSet"], None]] = None, -) -> "ds.HeaderSet": - """Parse a set-like header and return a - :class:`~werkzeug.datastructures.HeaderSet` object: - - >>> hs = parse_set_header('token, "quoted value"') - - The return value is an object that treats the items case-insensitively - and keeps the order of the items: - - >>> 'TOKEN' in hs - True - >>> hs.index('quoted value') - 1 - >>> hs - HeaderSet(['token', 'quoted value']) - - To create a header from the :class:`HeaderSet` again, use the - :func:`dump_header` function. - - :param value: a set header to be parsed. - :param on_update: an optional callable that is called every time a - value on the :class:`~werkzeug.datastructures.HeaderSet` - object is changed. - :return: a :class:`~werkzeug.datastructures.HeaderSet` - """ - if not value: - return ds.HeaderSet(None, on_update) - return ds.HeaderSet(parse_list_header(value), on_update) - - -def parse_authorization_header( - value: t.Optional[str], -) -> t.Optional["ds.Authorization"]: - """Parse an HTTP basic/digest authorization header transmitted by the web - browser. The return value is either `None` if the header was invalid or - not given, otherwise an :class:`~werkzeug.datastructures.Authorization` - object. - - :param value: the authorization header to parse. - :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. - """ - if not value: - return None - value = _wsgi_decoding_dance(value) - try: - auth_type, auth_info = value.split(None, 1) - auth_type = auth_type.lower() - except ValueError: - return None - if auth_type == "basic": - try: - username, password = base64.b64decode(auth_info).split(b":", 1) - except Exception: - return None - try: - return ds.Authorization( - "basic", - { - "username": _to_str(username, "utf-8"), - "password": _to_str(password, "utf-8"), - }, - ) - except UnicodeDecodeError: - return None - elif auth_type == "digest": - auth_map = parse_dict_header(auth_info) - for key in "username", "realm", "nonce", "uri", "response": - if key not in auth_map: - return None - if "qop" in auth_map: - if not auth_map.get("nc") or not auth_map.get("cnonce"): - return None - return ds.Authorization("digest", auth_map) - return None - - -def parse_www_authenticate_header( - value: t.Optional[str], - on_update: t.Optional[t.Callable[["ds.WWWAuthenticate"], None]] = None, -) -> "ds.WWWAuthenticate": - """Parse an HTTP WWW-Authenticate header into a - :class:`~werkzeug.datastructures.WWWAuthenticate` object. - - :param value: a WWW-Authenticate header to parse. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.WWWAuthenticate` - object is changed. - :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. - """ - if not value: - return ds.WWWAuthenticate(on_update=on_update) - try: - auth_type, auth_info = value.split(None, 1) - auth_type = auth_type.lower() - except (ValueError, AttributeError): - return ds.WWWAuthenticate(value.strip().lower(), on_update=on_update) - return ds.WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update) - - -def parse_if_range_header(value: t.Optional[str]) -> "ds.IfRange": - """Parses an if-range header which can be an etag or a date. Returns - a :class:`~werkzeug.datastructures.IfRange` object. - - .. versionchanged:: 2.0 - If the value represents a datetime, it is timezone-aware. - - .. versionadded:: 0.7 - """ - if not value: - return ds.IfRange() - date = parse_date(value) - if date is not None: - return ds.IfRange(date=date) - # drop weakness information - return ds.IfRange(unquote_etag(value)[0]) - - -def parse_range_header( - value: t.Optional[str], make_inclusive: bool = True -) -> t.Optional["ds.Range"]: - """Parses a range header into a :class:`~werkzeug.datastructures.Range` - object. If the header is missing or malformed `None` is returned. - `ranges` is a list of ``(start, stop)`` tuples where the ranges are - non-inclusive. - - .. versionadded:: 0.7 - """ - if not value or "=" not in value: - return None - - ranges = [] - last_end = 0 - units, rng = value.split("=", 1) - units = units.strip().lower() - - for item in rng.split(","): - item = item.strip() - if "-" not in item: - return None - if item.startswith("-"): - if last_end < 0: - return None - try: - begin = int(item) - except ValueError: - return None - end = None - last_end = -1 - elif "-" in item: - begin_str, end_str = item.split("-", 1) - begin_str = begin_str.strip() - end_str = end_str.strip() - if not begin_str.isdigit(): - return None - begin = int(begin_str) - if begin < last_end or last_end < 0: - return None - if end_str: - if not end_str.isdigit(): - return None - end = int(end_str) + 1 - if begin >= end: - return None - else: - end = None - last_end = end if end is not None else -1 - ranges.append((begin, end)) - - return ds.Range(units, ranges) - - -def parse_content_range_header( - value: t.Optional[str], - on_update: t.Optional[t.Callable[["ds.ContentRange"], None]] = None, -) -> t.Optional["ds.ContentRange"]: - """Parses a range header into a - :class:`~werkzeug.datastructures.ContentRange` object or `None` if - parsing is not possible. - - .. versionadded:: 0.7 - - :param value: a content range header to be parsed. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.ContentRange` - object is changed. - """ - if value is None: - return None - try: - units, rangedef = (value or "").strip().split(None, 1) - except ValueError: - return None - - if "/" not in rangedef: - return None - rng, length_str = rangedef.split("/", 1) - if length_str == "*": - length = None - elif length_str.isdigit(): - length = int(length_str) - else: - return None - - if rng == "*": - return ds.ContentRange(units, None, None, length, on_update=on_update) - elif "-" not in rng: - return None - - start_str, stop_str = rng.split("-", 1) - try: - start = int(start_str) - stop = int(stop_str) + 1 - except ValueError: - return None - - if is_byte_range_valid(start, stop, length): - return ds.ContentRange(units, start, stop, length, on_update=on_update) - - return None - - -def quote_etag(etag: str, weak: bool = False) -> str: - """Quote an etag. - - :param etag: the etag to quote. - :param weak: set to `True` to tag it "weak". - """ - if '"' in etag: - raise ValueError("invalid etag") - etag = f'"{etag}"' - if weak: - etag = f"W/{etag}" - return etag - - -def unquote_etag( - etag: t.Optional[str], -) -> t.Union[t.Tuple[str, bool], t.Tuple[None, None]]: - """Unquote a single etag: - - >>> unquote_etag('W/"bar"') - ('bar', True) - >>> unquote_etag('"bar"') - ('bar', False) - - :param etag: the etag identifier to unquote. - :return: a ``(etag, weak)`` tuple. - """ - if not etag: - return None, None - etag = etag.strip() - weak = False - if etag.startswith(("W/", "w/")): - weak = True - etag = etag[2:] - if etag[:1] == etag[-1:] == '"': - etag = etag[1:-1] - return etag, weak - - -def parse_etags(value: t.Optional[str]) -> "ds.ETags": - """Parse an etag header. - - :param value: the tag header to parse - :return: an :class:`~werkzeug.datastructures.ETags` object. - """ - if not value: - return ds.ETags() - strong = [] - weak = [] - end = len(value) - pos = 0 - while pos < end: - match = _etag_re.match(value, pos) - if match is None: - break - is_weak, quoted, raw = match.groups() - if raw == "*": - return ds.ETags(star_tag=True) - elif quoted: - raw = quoted - if is_weak: - weak.append(raw) - else: - strong.append(raw) - pos = match.end() - return ds.ETags(strong, weak) - - -def generate_etag(data: bytes) -> str: - """Generate an etag for some data. - - .. versionchanged:: 2.0 - Use SHA-1. MD5 may not be available in some environments. - """ - return sha1(data).hexdigest() - - -def parse_date(value: t.Optional[str]) -> t.Optional[datetime]: - """Parse an :rfc:`2822` date into a timezone-aware - :class:`datetime.datetime` object, or ``None`` if parsing fails. - - This is a wrapper for :func:`email.utils.parsedate_to_datetime`. It - returns ``None`` if parsing fails instead of raising an exception, - and always returns a timezone-aware datetime object. If the string - doesn't have timezone information, it is assumed to be UTC. - - :param value: A string with a supported date format. - - .. versionchanged:: 2.0 - Return a timezone-aware datetime object. Use - ``email.utils.parsedate_to_datetime``. - """ - if value is None: - return None - - try: - dt = email.utils.parsedate_to_datetime(value) - except (TypeError, ValueError): - return None - - if dt.tzinfo is None: - return dt.replace(tzinfo=timezone.utc) - - return dt - - -def cookie_date( - expires: t.Optional[t.Union[datetime, date, int, float, struct_time]] = None -) -> str: - """Format a datetime object or timestamp into an :rfc:`2822` date - string for ``Set-Cookie expires``. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :func:`http_date` instead. - """ - warnings.warn( - "'cookie_date' is deprecated and will be removed in Werkzeug" - " 2.1. Use 'http_date' instead.", - DeprecationWarning, - stacklevel=2, - ) - return http_date(expires) - - -def http_date( - timestamp: t.Optional[t.Union[datetime, date, int, float, struct_time]] = None -) -> str: - """Format a datetime object or timestamp into an :rfc:`2822` date - string. - - This is a wrapper for :func:`email.utils.format_datetime`. It - assumes naive datetime objects are in UTC instead of raising an - exception. - - :param timestamp: The datetime or timestamp to format. Defaults to - the current time. - - .. versionchanged:: 2.0 - Use ``email.utils.format_datetime``. Accept ``date`` objects. - """ - if isinstance(timestamp, date): - if not isinstance(timestamp, datetime): - # Assume plain date is midnight UTC. - timestamp = datetime.combine(timestamp, time(), tzinfo=timezone.utc) - else: - # Ensure datetime is timezone-aware. - timestamp = _dt_as_utc(timestamp) - - return email.utils.format_datetime(timestamp, usegmt=True) - - if isinstance(timestamp, struct_time): - timestamp = mktime(timestamp) - - return email.utils.formatdate(timestamp, usegmt=True) - - -def parse_age(value: t.Optional[str] = None) -> t.Optional[timedelta]: - """Parses a base-10 integer count of seconds into a timedelta. - - If parsing fails, the return value is `None`. - - :param value: a string consisting of an integer represented in base-10 - :return: a :class:`datetime.timedelta` object or `None`. - """ - if not value: - return None - try: - seconds = int(value) - except ValueError: - return None - if seconds < 0: - return None - try: - return timedelta(seconds=seconds) - except OverflowError: - return None - - -def dump_age(age: t.Optional[t.Union[timedelta, int]] = None) -> t.Optional[str]: - """Formats the duration as a base-10 integer. - - :param age: should be an integer number of seconds, - a :class:`datetime.timedelta` object, or, - if the age is unknown, `None` (default). - """ - if age is None: - return None - if isinstance(age, timedelta): - age = int(age.total_seconds()) - else: - age = int(age) - - if age < 0: - raise ValueError("age cannot be negative") - - return str(age) - - -def is_resource_modified( - environ: "WSGIEnvironment", - etag: t.Optional[str] = None, - data: t.Optional[bytes] = None, - last_modified: t.Optional[t.Union[datetime, str]] = None, - ignore_if_range: bool = True, -) -> bool: - """Convenience method for conditional requests. - - :param environ: the WSGI environment of the request to be checked. - :param etag: the etag for the response for comparison. - :param data: or alternatively the data of the response to automatically - generate an etag using :func:`generate_etag`. - :param last_modified: an optional date of the last modification. - :param ignore_if_range: If `False`, `If-Range` header will be taken into - account. - :return: `True` if the resource was modified, otherwise `False`. - - .. versionchanged:: 2.0 - SHA-1 is used to generate an etag value for the data. MD5 may - not be available in some environments. - - .. versionchanged:: 1.0.0 - The check is run for methods other than ``GET`` and ``HEAD``. - """ - if etag is None and data is not None: - etag = generate_etag(data) - elif data is not None: - raise TypeError("both data and etag given") - - unmodified = False - if isinstance(last_modified, str): - last_modified = parse_date(last_modified) - - # HTTP doesn't use microsecond, remove it to avoid false positive - # comparisons. Mark naive datetimes as UTC. - if last_modified is not None: - last_modified = _dt_as_utc(last_modified.replace(microsecond=0)) - - if_range = None - if not ignore_if_range and "HTTP_RANGE" in environ: - # https://tools.ietf.org/html/rfc7233#section-3.2 - # A server MUST ignore an If-Range header field received in a request - # that does not contain a Range header field. - if_range = parse_if_range_header(environ.get("HTTP_IF_RANGE")) - - if if_range is not None and if_range.date is not None: - modified_since: t.Optional[datetime] = if_range.date - else: - modified_since = parse_date(environ.get("HTTP_IF_MODIFIED_SINCE")) - - if modified_since and last_modified and last_modified <= modified_since: - unmodified = True - - if etag: - etag, _ = unquote_etag(etag) - etag = t.cast(str, etag) - - if if_range is not None and if_range.etag is not None: - unmodified = parse_etags(if_range.etag).contains(etag) - else: - if_none_match = parse_etags(environ.get("HTTP_IF_NONE_MATCH")) - if if_none_match: - # https://tools.ietf.org/html/rfc7232#section-3.2 - # "A recipient MUST use the weak comparison function when comparing - # entity-tags for If-None-Match" - unmodified = if_none_match.contains_weak(etag) - - # https://tools.ietf.org/html/rfc7232#section-3.1 - # "Origin server MUST use the strong comparison function when - # comparing entity-tags for If-Match" - if_match = parse_etags(environ.get("HTTP_IF_MATCH")) - if if_match: - unmodified = not if_match.is_strong(etag) - - return not unmodified - - -def remove_entity_headers( - headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]], - allowed: t.Iterable[str] = ("expires", "content-location"), -) -> None: - """Remove all entity headers from a list or :class:`Headers` object. This - operation works in-place. `Expires` and `Content-Location` headers are - by default not removed. The reason for this is :rfc:`2616` section - 10.3.5 which specifies some entity headers that should be sent. - - .. versionchanged:: 0.5 - added `allowed` parameter. - - :param headers: a list or :class:`Headers` object. - :param allowed: a list of headers that should still be allowed even though - they are entity headers. - """ - allowed = {x.lower() for x in allowed} - headers[:] = [ - (key, value) - for key, value in headers - if not is_entity_header(key) or key.lower() in allowed - ] - - -def remove_hop_by_hop_headers( - headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]] -) -> None: - """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or - :class:`Headers` object. This operation works in-place. - - .. versionadded:: 0.5 - - :param headers: a list or :class:`Headers` object. - """ - headers[:] = [ - (key, value) for key, value in headers if not is_hop_by_hop_header(key) - ] - - -def is_entity_header(header: str) -> bool: - """Check if a header is an entity header. - - .. versionadded:: 0.5 - - :param header: the header to test. - :return: `True` if it's an entity header, `False` otherwise. - """ - return header.lower() in _entity_headers - - -def is_hop_by_hop_header(header: str) -> bool: - """Check if a header is an HTTP/1.1 "Hop-by-Hop" header. - - .. versionadded:: 0.5 - - :param header: the header to test. - :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise. - """ - return header.lower() in _hop_by_hop_headers - - -def parse_cookie( - header: t.Union["WSGIEnvironment", str, bytes, None], - charset: str = "utf-8", - errors: str = "replace", - cls: t.Optional[t.Type["ds.MultiDict"]] = None, -) -> "ds.MultiDict[str, str]": - """Parse a cookie from a string or WSGI environ. - - The same key can be provided multiple times, the values are stored - in-order. The default :class:`MultiDict` will have the first value - first, and all values can be retrieved with - :meth:`MultiDict.getlist`. - - :param header: The cookie header as a string, or a WSGI environ dict - with a ``HTTP_COOKIE`` key. - :param charset: The charset for the cookie values. - :param errors: The error behavior for the charset decoding. - :param cls: A dict-like class to store the parsed cookies in. - Defaults to :class:`MultiDict`. - - .. versionchanged:: 1.0.0 - Returns a :class:`MultiDict` instead of a - ``TypeConversionDict``. - - .. versionchanged:: 0.5 - Returns a :class:`TypeConversionDict` instead of a regular dict. - The ``cls`` parameter was added. - """ - if isinstance(header, dict): - header = header.get("HTTP_COOKIE", "") - elif header is None: - header = "" - - # PEP 3333 sends headers through the environ as latin1 decoded - # strings. Encode strings back to bytes for parsing. - if isinstance(header, str): - header = header.encode("latin1", "replace") - - if cls is None: - cls = ds.MultiDict - - def _parse_pairs() -> t.Iterator[t.Tuple[str, str]]: - for key, val in _cookie_parse_impl(header): # type: ignore - key_str = _to_str(key, charset, errors, allow_none_charset=True) - - if not key_str: - continue - - val_str = _to_str(val, charset, errors, allow_none_charset=True) - yield key_str, val_str - - return cls(_parse_pairs()) - - -def dump_cookie( - key: str, - value: t.Union[bytes, str] = "", - max_age: t.Optional[t.Union[timedelta, int]] = None, - expires: t.Optional[t.Union[str, datetime, int, float]] = None, - path: t.Optional[str] = "/", - domain: t.Optional[str] = None, - secure: bool = False, - httponly: bool = False, - charset: str = "utf-8", - sync_expires: bool = True, - max_size: int = 4093, - samesite: t.Optional[str] = None, -) -> str: - """Create a Set-Cookie header without the ``Set-Cookie`` prefix. - - The return value is usually restricted to ascii as the vast majority - of values are properly escaped, but that is no guarantee. It's - tunneled through latin1 as required by :pep:`3333`. - - The return value is not ASCII safe if the key contains unicode - characters. This is technically against the specification but - happens in the wild. It's strongly recommended to not use - non-ASCII values for the keys. - - :param max_age: should be a number of seconds, or `None` (default) if - the cookie should last only as long as the client's - browser session. Additionally `timedelta` objects - are accepted, too. - :param expires: should be a `datetime` object or unix timestamp. - :param path: limits the cookie to a given path, per default it will - span the whole domain. - :param domain: Use this if you want to set a cross-domain cookie. For - example, ``domain=".example.com"`` will set a cookie - that is readable by the domain ``www.example.com``, - ``foo.example.com`` etc. Otherwise, a cookie will only - be readable by the domain that set it. - :param secure: The cookie will only be available via HTTPS - :param httponly: disallow JavaScript to access the cookie. This is an - extension to the cookie standard and probably not - supported by all browsers. - :param charset: the encoding for string values. - :param sync_expires: automatically set expires if max_age is defined - but expires not. - :param max_size: Warn if the final header value exceeds this size. The - default, 4093, should be safely `supported by most browsers - `_. Set to 0 to disable this check. - :param samesite: Limits the scope of the cookie such that it will - only be attached to requests if those requests are same-site. - - .. _`cookie`: http://browsercookielimits.squawky.net/ - - .. versionchanged:: 1.0.0 - The string ``'None'`` is accepted for ``samesite``. - """ - key = _to_bytes(key, charset) - value = _to_bytes(value, charset) - - if path is not None: - from .urls import iri_to_uri - - path = iri_to_uri(path, charset) - - domain = _make_cookie_domain(domain) - - if isinstance(max_age, timedelta): - max_age = int(max_age.total_seconds()) - - if expires is not None: - if not isinstance(expires, str): - expires = http_date(expires) - elif max_age is not None and sync_expires: - expires = http_date(datetime.now(tz=timezone.utc).timestamp() + max_age) - - if samesite is not None: - samesite = samesite.title() - - if samesite not in {"Strict", "Lax", "None"}: - raise ValueError("SameSite must be 'Strict', 'Lax', or 'None'.") - - buf = [key + b"=" + _cookie_quote(value)] - - # XXX: In theory all of these parameters that are not marked with `None` - # should be quoted. Because stdlib did not quote it before I did not - # want to introduce quoting there now. - for k, v, q in ( - (b"Domain", domain, True), - (b"Expires", expires, False), - (b"Max-Age", max_age, False), - (b"Secure", secure, None), - (b"HttpOnly", httponly, None), - (b"Path", path, False), - (b"SameSite", samesite, False), - ): - if q is None: - if v: - buf.append(k) - continue - - if v is None: - continue - - tmp = bytearray(k) - if not isinstance(v, (bytes, bytearray)): - v = _to_bytes(str(v), charset) - if q: - v = _cookie_quote(v) - tmp += b"=" + v - buf.append(bytes(tmp)) - - # The return value will be an incorrectly encoded latin1 header for - # consistency with the headers object. - rv = b"; ".join(buf) - rv = rv.decode("latin1") - - # Warn if the final value of the cookie is larger than the limit. If the - # cookie is too large, then it may be silently ignored by the browser, - # which can be quite hard to debug. - cookie_size = len(rv) - - if max_size and cookie_size > max_size: - value_size = len(value) - warnings.warn( - f"The {key.decode(charset)!r} cookie is too large: the value was" - f" {value_size} bytes but the" - f" header required {cookie_size - value_size} extra bytes. The final size" - f" was {cookie_size} bytes but the limit is {max_size} bytes. Browsers may" - f" silently ignore cookies larger than this.", - stacklevel=2, - ) - - return rv - - -def is_byte_range_valid( - start: t.Optional[int], stop: t.Optional[int], length: t.Optional[int] -) -> bool: - """Checks if a given byte content range is valid for the given length. - - .. versionadded:: 0.7 - """ - if (start is None) != (stop is None): - return False - elif start is None: - return length is None or length >= 0 - elif length is None: - return 0 <= start < stop # type: ignore - elif start >= stop: # type: ignore - return False - return 0 <= start < length - - -# circular dependencies -from . import datastructures as ds diff --git a/venv/lib/python3.7/site-packages/werkzeug/local.py b/venv/lib/python3.7/site-packages/werkzeug/local.py deleted file mode 100644 index 2b22227..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/local.py +++ /dev/null @@ -1,690 +0,0 @@ -import copy -import math -import operator -import sys -import typing as t -import warnings -from functools import partial -from functools import update_wrapper - -from .wsgi import ClosingIterator - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) - -try: - from greenlet import getcurrent as _get_ident -except ImportError: - from threading import get_ident as _get_ident - - -def get_ident() -> int: - warnings.warn( - "'get_ident' is deprecated and will be removed in Werkzeug" - " 2.1. Use 'greenlet.getcurrent' or 'threading.get_ident' for" - " previous behavior.", - DeprecationWarning, - stacklevel=2, - ) - return _get_ident() # type: ignore - - -class _CannotUseContextVar(Exception): - pass - - -try: - from contextvars import ContextVar - - if "gevent" in sys.modules or "eventlet" in sys.modules: - # Both use greenlet, so first check it has patched - # ContextVars, Greenlet <0.4.17 does not. - import greenlet - - greenlet_patched = getattr(greenlet, "GREENLET_USE_CONTEXT_VARS", False) - - if not greenlet_patched: - # If Gevent is used, check it has patched ContextVars, - # <20.5 does not. - try: - from gevent.monkey import is_object_patched - except ImportError: - # Gevent isn't used, but Greenlet is and hasn't patched - raise _CannotUseContextVar() from None - else: - if is_object_patched("threading", "local") and not is_object_patched( - "contextvars", "ContextVar" - ): - raise _CannotUseContextVar() - - def __release_local__(storage: t.Any) -> None: - # Can remove when support for non-stdlib ContextVars is - # removed, see "Fake" version below. - storage.set({}) - -except (ImportError, _CannotUseContextVar): - - class ContextVar: # type: ignore - """A fake ContextVar based on the previous greenlet/threading - ident function. Used on Python 3.6, eventlet, and old versions - of gevent. - """ - - def __init__(self, _name: str) -> None: - self.storage: t.Dict[int, t.Dict[str, t.Any]] = {} - - def get(self, default: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: - return self.storage.get(_get_ident(), default) - - def set(self, value: t.Dict[str, t.Any]) -> None: - self.storage[_get_ident()] = value - - def __release_local__(storage: t.Any) -> None: - # Special version to ensure that the storage is cleaned up on - # release. - storage.storage.pop(_get_ident(), None) - - -def release_local(local: t.Union["Local", "LocalStack"]) -> None: - """Releases the contents of the local for the current context. - This makes it possible to use locals without a manager. - - Example:: - - >>> loc = Local() - >>> loc.foo = 42 - >>> release_local(loc) - >>> hasattr(loc, 'foo') - False - - With this function one can release :class:`Local` objects as well - as :class:`LocalStack` objects. However it is not possible to - release data held by proxies that way, one always has to retain - a reference to the underlying local object in order to be able - to release it. - - .. versionadded:: 0.6.1 - """ - local.__release_local__() - - -class Local: - __slots__ = ("_storage",) - - def __init__(self) -> None: - object.__setattr__(self, "_storage", ContextVar("local_storage")) - - @property - def __storage__(self) -> t.Dict[str, t.Any]: - warnings.warn( - "'__storage__' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return self._storage.get({}) # type: ignore - - @property - def __ident_func__(self) -> t.Callable[[], int]: - warnings.warn( - "'__ident_func__' is deprecated and will be removed in" - " Werkzeug 2.1. It should not be used in Python 3.7+.", - DeprecationWarning, - stacklevel=2, - ) - return _get_ident # type: ignore - - @__ident_func__.setter - def __ident_func__(self, func: t.Callable[[], int]) -> None: - warnings.warn( - "'__ident_func__' is deprecated and will be removed in" - " Werkzeug 2.1. Setting it no longer has any effect.", - DeprecationWarning, - stacklevel=2, - ) - - def __iter__(self) -> t.Iterator[t.Tuple[int, t.Any]]: - return iter(self._storage.get({}).items()) - - def __call__(self, proxy: str) -> "LocalProxy": - """Create a proxy for a name.""" - return LocalProxy(self, proxy) - - def __release_local__(self) -> None: - __release_local__(self._storage) - - def __getattr__(self, name: str) -> t.Any: - values = self._storage.get({}) - try: - return values[name] - except KeyError: - raise AttributeError(name) from None - - def __setattr__(self, name: str, value: t.Any) -> None: - values = self._storage.get({}).copy() - values[name] = value - self._storage.set(values) - - def __delattr__(self, name: str) -> None: - values = self._storage.get({}).copy() - try: - del values[name] - self._storage.set(values) - except KeyError: - raise AttributeError(name) from None - - -class LocalStack: - """This class works similar to a :class:`Local` but keeps a stack - of objects instead. This is best explained with an example:: - - >>> ls = LocalStack() - >>> ls.push(42) - >>> ls.top - 42 - >>> ls.push(23) - >>> ls.top - 23 - >>> ls.pop() - 23 - >>> ls.top - 42 - - They can be force released by using a :class:`LocalManager` or with - the :func:`release_local` function but the correct way is to pop the - item from the stack after using. When the stack is empty it will - no longer be bound to the current context (and as such released). - - By calling the stack without arguments it returns a proxy that resolves to - the topmost item on the stack. - - .. versionadded:: 0.6.1 - """ - - def __init__(self) -> None: - self._local = Local() - - def __release_local__(self) -> None: - self._local.__release_local__() - - @property - def __ident_func__(self) -> t.Callable[[], int]: - return self._local.__ident_func__ - - @__ident_func__.setter - def __ident_func__(self, value: t.Callable[[], int]) -> None: - object.__setattr__(self._local, "__ident_func__", value) - - def __call__(self) -> "LocalProxy": - def _lookup() -> t.Any: - rv = self.top - if rv is None: - raise RuntimeError("object unbound") - return rv - - return LocalProxy(_lookup) - - def push(self, obj: t.Any) -> t.List[t.Any]: - """Pushes a new item to the stack""" - rv = getattr(self._local, "stack", []).copy() - rv.append(obj) - self._local.stack = rv - return rv - - def pop(self) -> t.Any: - """Removes the topmost item from the stack, will return the - old value or `None` if the stack was already empty. - """ - stack = getattr(self._local, "stack", None) - if stack is None: - return None - elif len(stack) == 1: - release_local(self._local) - return stack[-1] - else: - return stack.pop() - - @property - def top(self) -> t.Any: - """The topmost item on the stack. If the stack is empty, - `None` is returned. - """ - try: - return self._local.stack[-1] - except (AttributeError, IndexError): - return None - - -class LocalManager: - """Local objects cannot manage themselves. For that you need a local - manager. You can pass a local manager multiple locals or add them - later by appending them to `manager.locals`. Every time the manager - cleans up, it will clean up all the data left in the locals for this - context. - - .. versionchanged:: 2.0 - ``ident_func`` is deprecated and will be removed in Werkzeug - 2.1. - - .. versionchanged:: 0.6.1 - The :func:`release_local` function can be used instead of a - manager. - - .. versionchanged:: 0.7 - The ``ident_func`` parameter was added. - """ - - def __init__( - self, - locals: t.Optional[t.Iterable[t.Union[Local, LocalStack]]] = None, - ident_func: None = None, - ) -> None: - if locals is None: - self.locals = [] - elif isinstance(locals, Local): - self.locals = [locals] - else: - self.locals = list(locals) - - if ident_func is not None: - warnings.warn( - "'ident_func' is deprecated and will be removed in" - " Werkzeug 2.1. Setting it no longer has any effect.", - DeprecationWarning, - stacklevel=2, - ) - - @property - def ident_func(self) -> t.Callable[[], int]: - warnings.warn( - "'ident_func' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return _get_ident # type: ignore - - @ident_func.setter - def ident_func(self, func: t.Callable[[], int]) -> None: - warnings.warn( - "'ident_func' is deprecated and will be removedin Werkzeug" - " 2.1. Setting it no longer has any effect.", - DeprecationWarning, - stacklevel=2, - ) - - def get_ident(self) -> int: - """Return the context identifier the local objects use internally for - this context. You cannot override this method to change the behavior - but use it to link other context local objects (such as SQLAlchemy's - scoped sessions) to the Werkzeug locals. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. - - .. versionchanged:: 0.7 - You can pass a different ident function to the local manager that - will then be propagated to all the locals passed to the - constructor. - """ - warnings.warn( - "'get_ident' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return self.ident_func() - - def cleanup(self) -> None: - """Manually clean up the data in the locals for this context. Call - this at the end of the request or use `make_middleware()`. - """ - for local in self.locals: - release_local(local) - - def make_middleware(self, app: "WSGIApplication") -> "WSGIApplication": - """Wrap a WSGI application so that cleaning up happens after - request end. - """ - - def application( - environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - return ClosingIterator(app(environ, start_response), self.cleanup) - - return application - - def middleware(self, func: "WSGIApplication") -> "WSGIApplication": - """Like `make_middleware` but for decorating functions. - - Example usage:: - - @manager.middleware - def application(environ, start_response): - ... - - The difference to `make_middleware` is that the function passed - will have all the arguments copied from the inner application - (name, docstring, module). - """ - return update_wrapper(self.make_middleware(func), func) - - def __repr__(self) -> str: - return f"<{type(self).__name__} storages: {len(self.locals)}>" - - -class _ProxyLookup: - """Descriptor that handles proxied attribute lookup for - :class:`LocalProxy`. - - :param f: The built-in function this attribute is accessed through. - Instead of looking up the special method, the function call - is redone on the object. - :param fallback: Return this function if the proxy is unbound - instead of raising a :exc:`RuntimeError`. - :param is_attr: This proxied name is an attribute, not a function. - Call the fallback immediately to get the value. - :param class_value: Value to return when accessed from the - ``LocalProxy`` class directly. Used for ``__doc__`` so building - docs still works. - """ - - __slots__ = ("bind_f", "fallback", "is_attr", "class_value", "name") - - def __init__( - self, - f: t.Optional[t.Callable] = None, - fallback: t.Optional[t.Callable] = None, - class_value: t.Optional[t.Any] = None, - is_attr: bool = False, - ) -> None: - bind_f: t.Optional[t.Callable[["LocalProxy", t.Any], t.Callable]] - - if hasattr(f, "__get__"): - # A Python function, can be turned into a bound method. - - def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: - return f.__get__(obj, type(obj)) # type: ignore - - elif f is not None: - # A C function, use partial to bind the first argument. - - def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: - return partial(f, obj) # type: ignore - - else: - # Use getattr, which will produce a bound method. - bind_f = None - - self.bind_f = bind_f - self.fallback = fallback - self.class_value = class_value - self.is_attr = is_attr - - def __set_name__(self, owner: "LocalProxy", name: str) -> None: - self.name = name - - def __get__(self, instance: "LocalProxy", owner: t.Optional[type] = None) -> t.Any: - if instance is None: - if self.class_value is not None: - return self.class_value - - return self - - try: - obj = instance._get_current_object() - except RuntimeError: - if self.fallback is None: - raise - - fallback = self.fallback.__get__(instance, owner) # type: ignore - - if self.is_attr: - # __class__ and __doc__ are attributes, not methods. - # Call the fallback to get the value. - return fallback() - - return fallback - - if self.bind_f is not None: - return self.bind_f(instance, obj) - - return getattr(obj, self.name) - - def __repr__(self) -> str: - return f"proxy {self.name}" - - def __call__(self, instance: "LocalProxy", *args: t.Any, **kwargs: t.Any) -> t.Any: - """Support calling unbound methods from the class. For example, - this happens with ``copy.copy``, which does - ``type(x).__copy__(x)``. ``type(x)`` can't be proxied, so it - returns the proxy type and descriptor. - """ - return self.__get__(instance, type(instance))(*args, **kwargs) - - -class _ProxyIOp(_ProxyLookup): - """Look up an augmented assignment method on a proxied object. The - method is wrapped to return the proxy instead of the object. - """ - - __slots__ = () - - def __init__( - self, f: t.Optional[t.Callable] = None, fallback: t.Optional[t.Callable] = None - ) -> None: - super().__init__(f, fallback) - - def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: - def i_op(self: t.Any, other: t.Any) -> "LocalProxy": - f(self, other) # type: ignore - return instance - - return i_op.__get__(obj, type(obj)) # type: ignore - - self.bind_f = bind_f - - -def _l_to_r_op(op: F) -> F: - """Swap the argument order to turn an l-op into an r-op.""" - - def r_op(obj: t.Any, other: t.Any) -> t.Any: - return op(other, obj) - - return t.cast(F, r_op) - - -class LocalProxy: - """A proxy to the object bound to a :class:`Local`. All operations - on the proxy are forwarded to the bound object. If no object is - bound, a :exc:`RuntimeError` is raised. - - .. code-block:: python - - from werkzeug.local import Local - l = Local() - - # a proxy to whatever l.user is set to - user = l("user") - - from werkzeug.local import LocalStack - _request_stack = LocalStack() - - # a proxy to _request_stack.top - request = _request_stack() - - # a proxy to the session attribute of the request proxy - session = LocalProxy(lambda: request.session) - - ``__repr__`` and ``__class__`` are forwarded, so ``repr(x)`` and - ``isinstance(x, cls)`` will look like the proxied object. Use - ``issubclass(type(x), LocalProxy)`` to check if an object is a - proxy. - - .. code-block:: python - - repr(user) # - isinstance(user, User) # True - issubclass(type(user), LocalProxy) # True - - :param local: The :class:`Local` or callable that provides the - proxied object. - :param name: The attribute name to look up on a :class:`Local`. Not - used if a callable is given. - - .. versionchanged:: 2.0 - Updated proxied attributes and methods to reflect the current - data model. - - .. versionchanged:: 0.6.1 - The class can be instantiated with a callable. - """ - - __slots__ = ("__local", "__name", "__wrapped__") - - def __init__( - self, - local: t.Union["Local", t.Callable[[], t.Any]], - name: t.Optional[str] = None, - ) -> None: - object.__setattr__(self, "_LocalProxy__local", local) - object.__setattr__(self, "_LocalProxy__name", name) - - if callable(local) and not hasattr(local, "__release_local__"): - # "local" is a callable that is not an instance of Local or - # LocalManager: mark it as a wrapped function. - object.__setattr__(self, "__wrapped__", local) - - def _get_current_object(self) -> t.Any: - """Return the current object. This is useful if you want the real - object behind the proxy at a time for performance reasons or because - you want to pass the object into a different context. - """ - if not hasattr(self.__local, "__release_local__"): # type: ignore - return self.__local() # type: ignore - - try: - return getattr(self.__local, self.__name) # type: ignore - except AttributeError: - name = self.__name # type: ignore - raise RuntimeError(f"no object bound to {name}") from None - - __doc__ = _ProxyLookup( # type: ignore - class_value=__doc__, fallback=lambda self: type(self).__doc__, is_attr=True - ) - # __del__ should only delete the proxy - __repr__ = _ProxyLookup( # type: ignore - repr, fallback=lambda self: f"<{type(self).__name__} unbound>" - ) - __str__ = _ProxyLookup(str) # type: ignore - __bytes__ = _ProxyLookup(bytes) - __format__ = _ProxyLookup() # type: ignore - __lt__ = _ProxyLookup(operator.lt) - __le__ = _ProxyLookup(operator.le) - __eq__ = _ProxyLookup(operator.eq) # type: ignore - __ne__ = _ProxyLookup(operator.ne) # type: ignore - __gt__ = _ProxyLookup(operator.gt) - __ge__ = _ProxyLookup(operator.ge) - __hash__ = _ProxyLookup(hash) # type: ignore - __bool__ = _ProxyLookup(bool, fallback=lambda self: False) - __getattr__ = _ProxyLookup(getattr) - # __getattribute__ triggered through __getattr__ - __setattr__ = _ProxyLookup(setattr) # type: ignore - __delattr__ = _ProxyLookup(delattr) # type: ignore - __dir__ = _ProxyLookup(dir, fallback=lambda self: []) # type: ignore - # __get__ (proxying descriptor not supported) - # __set__ (descriptor) - # __delete__ (descriptor) - # __set_name__ (descriptor) - # __objclass__ (descriptor) - # __slots__ used by proxy itself - # __dict__ (__getattr__) - # __weakref__ (__getattr__) - # __init_subclass__ (proxying metaclass not supported) - # __prepare__ (metaclass) - __class__ = _ProxyLookup( - fallback=lambda self: type(self), is_attr=True - ) # type: ignore - __instancecheck__ = _ProxyLookup(lambda self, other: isinstance(other, self)) - __subclasscheck__ = _ProxyLookup(lambda self, other: issubclass(other, self)) - # __class_getitem__ triggered through __getitem__ - __call__ = _ProxyLookup(lambda self, *args, **kwargs: self(*args, **kwargs)) - __len__ = _ProxyLookup(len) - __length_hint__ = _ProxyLookup(operator.length_hint) - __getitem__ = _ProxyLookup(operator.getitem) - __setitem__ = _ProxyLookup(operator.setitem) - __delitem__ = _ProxyLookup(operator.delitem) - # __missing__ triggered through __getitem__ - __iter__ = _ProxyLookup(iter) - __next__ = _ProxyLookup(next) - __reversed__ = _ProxyLookup(reversed) - __contains__ = _ProxyLookup(operator.contains) - __add__ = _ProxyLookup(operator.add) - __sub__ = _ProxyLookup(operator.sub) - __mul__ = _ProxyLookup(operator.mul) - __matmul__ = _ProxyLookup(operator.matmul) - __truediv__ = _ProxyLookup(operator.truediv) - __floordiv__ = _ProxyLookup(operator.floordiv) - __mod__ = _ProxyLookup(operator.mod) - __divmod__ = _ProxyLookup(divmod) - __pow__ = _ProxyLookup(pow) - __lshift__ = _ProxyLookup(operator.lshift) - __rshift__ = _ProxyLookup(operator.rshift) - __and__ = _ProxyLookup(operator.and_) - __xor__ = _ProxyLookup(operator.xor) - __or__ = _ProxyLookup(operator.or_) - __radd__ = _ProxyLookup(_l_to_r_op(operator.add)) - __rsub__ = _ProxyLookup(_l_to_r_op(operator.sub)) - __rmul__ = _ProxyLookup(_l_to_r_op(operator.mul)) - __rmatmul__ = _ProxyLookup(_l_to_r_op(operator.matmul)) - __rtruediv__ = _ProxyLookup(_l_to_r_op(operator.truediv)) - __rfloordiv__ = _ProxyLookup(_l_to_r_op(operator.floordiv)) - __rmod__ = _ProxyLookup(_l_to_r_op(operator.mod)) - __rdivmod__ = _ProxyLookup(_l_to_r_op(divmod)) - __rpow__ = _ProxyLookup(_l_to_r_op(pow)) - __rlshift__ = _ProxyLookup(_l_to_r_op(operator.lshift)) - __rrshift__ = _ProxyLookup(_l_to_r_op(operator.rshift)) - __rand__ = _ProxyLookup(_l_to_r_op(operator.and_)) - __rxor__ = _ProxyLookup(_l_to_r_op(operator.xor)) - __ror__ = _ProxyLookup(_l_to_r_op(operator.or_)) - __iadd__ = _ProxyIOp(operator.iadd) - __isub__ = _ProxyIOp(operator.isub) - __imul__ = _ProxyIOp(operator.imul) - __imatmul__ = _ProxyIOp(operator.imatmul) - __itruediv__ = _ProxyIOp(operator.itruediv) - __ifloordiv__ = _ProxyIOp(operator.ifloordiv) - __imod__ = _ProxyIOp(operator.imod) - __ipow__ = _ProxyIOp(operator.ipow) - __ilshift__ = _ProxyIOp(operator.ilshift) - __irshift__ = _ProxyIOp(operator.irshift) - __iand__ = _ProxyIOp(operator.iand) - __ixor__ = _ProxyIOp(operator.ixor) - __ior__ = _ProxyIOp(operator.ior) - __neg__ = _ProxyLookup(operator.neg) - __pos__ = _ProxyLookup(operator.pos) - __abs__ = _ProxyLookup(abs) - __invert__ = _ProxyLookup(operator.invert) - __complex__ = _ProxyLookup(complex) - __int__ = _ProxyLookup(int) - __float__ = _ProxyLookup(float) - __index__ = _ProxyLookup(operator.index) - __round__ = _ProxyLookup(round) - __trunc__ = _ProxyLookup(math.trunc) - __floor__ = _ProxyLookup(math.floor) - __ceil__ = _ProxyLookup(math.ceil) - __enter__ = _ProxyLookup() - __exit__ = _ProxyLookup() - __await__ = _ProxyLookup() - __aiter__ = _ProxyLookup() - __anext__ = _ProxyLookup() - __aenter__ = _ProxyLookup() - __aexit__ = _ProxyLookup() - __copy__ = _ProxyLookup(copy.copy) - __deepcopy__ = _ProxyLookup(copy.deepcopy) - # __getnewargs_ex__ (pickle through proxy not supported) - # __getnewargs__ (pickle) - # __getstate__ (pickle) - # __setstate__ (pickle) - # __reduce__ (pickle) - # __reduce_ex__ (pickle) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py deleted file mode 100644 index 6ddcf7f..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -Middleware -========== - -A WSGI middleware is a WSGI application that wraps another application -in order to observe or change its behavior. Werkzeug provides some -middleware for common use cases. - -.. toctree:: - :maxdepth: 1 - - proxy_fix - shared_data - dispatcher - http_proxy - lint - profiler - -The :doc:`interactive debugger ` is also a middleware that can -be applied manually, although it is typically used automatically with -the :doc:`development server `. -""" diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index a03165e16cb4dd96d42c51c80d1c619cc67e5499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmYjPv2GMG5Zy~dWGOAR+X%A0gIolwZ~~f$0-8jMM1jw1&#kT7wT*(Cnu!9`1a~W{byDbzb5byh>Q2Q;xTTj_*$shb#Zzmej`CX z8>L#79ApJOzh-7s(bnXxgU!n36pwOuT>?BOQa?*2;I|LGa$#+t-=>Bqa{%g(93h1K)v IdEzSm0S><9F8}}l diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc deleted file mode 100644 index b777a07da741b1d6aeea21d7d956626060efb3fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2754 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 Xw64+wNm1N{F;-w~`46V1YR3Np3z8d% diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc deleted file mode 100644 index 9af3ddfd0bc96a5764d1f4febb2eadf479843050..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12692 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 NE0-$sl~U!_{{bw^^XC8n diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-37.pyc deleted file mode 100644 index 9afdbd1bfcc283799b10bd58409fcdb0a2c4ca07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4923 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 diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc deleted file mode 100644 index f3ea598e9031327f09e6a63526330fce4031d3a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9882 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 R9|DT0KgEzQ1AN@0{tuHrMnC`n diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py deleted file mode 100644 index ace1c75..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py +++ /dev/null @@ -1,78 +0,0 @@ -""" -Application Dispatcher -====================== - -This middleware creates a single WSGI application that dispatches to -multiple other WSGI applications mounted at different URL paths. - -A common example is writing a Single Page Application, where you have a -backend API and a frontend written in JavaScript that does the routing -in the browser rather than requesting different pages from the server. -The frontend is a single HTML and JS file that should be served for any -path besides "/api". - -This example dispatches to an API app under "/api", an admin app -under "/admin", and an app that serves frontend files for all other -requests:: - - app = DispatcherMiddleware(serve_frontend, { - '/api': api_app, - '/admin': admin_app, - }) - -In production, you might instead handle this at the HTTP server level, -serving files or proxying to application servers based on location. The -API and admin apps would each be deployed with a separate WSGI server, -and the static files would be served directly by the HTTP server. - -.. autoclass:: DispatcherMiddleware - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import typing as t - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class DispatcherMiddleware: - """Combine multiple applications as a single WSGI application. - Requests are dispatched to an application based on the path it is - mounted under. - - :param app: The WSGI application to dispatch to if the request - doesn't match a mounted path. - :param mounts: Maps path prefixes to applications for dispatching. - """ - - def __init__( - self, - app: "WSGIApplication", - mounts: t.Optional[t.Dict[str, "WSGIApplication"]] = None, - ) -> None: - self.app = app - self.mounts = mounts or {} - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - script = environ.get("PATH_INFO", "") - path_info = "" - - while "/" in script: - if script in self.mounts: - app = self.mounts[script] - break - - script, last_item = script.rsplit("/", 1) - path_info = f"/{last_item}{path_info}" - else: - app = self.mounts.get(script, self.app) - - original_script_name = environ.get("SCRIPT_NAME", "") - environ["SCRIPT_NAME"] = original_script_name + script - environ["PATH_INFO"] = path_info - return app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/http_proxy.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/http_proxy.py deleted file mode 100644 index 1cde458..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/http_proxy.py +++ /dev/null @@ -1,230 +0,0 @@ -""" -Basic HTTP Proxy -================ - -.. autoclass:: ProxyMiddleware - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import typing as t -from http import client - -from ..datastructures import EnvironHeaders -from ..http import is_hop_by_hop_header -from ..urls import url_parse -from ..urls import url_quote -from ..wsgi import get_input_stream - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class ProxyMiddleware: - """Proxy requests under a path to an external server, routing other - requests to the app. - - This middleware can only proxy HTTP requests, as HTTP is the only - protocol handled by the WSGI server. Other protocols, such as - WebSocket requests, cannot be proxied at this layer. This should - only be used for development, in production a real proxy server - should be used. - - The middleware takes a dict mapping a path prefix to a dict - describing the host to be proxied to:: - - app = ProxyMiddleware(app, { - "/static/": { - "target": "http://127.0.0.1:5001/", - } - }) - - Each host has the following options: - - ``target``: - The target URL to dispatch to. This is required. - ``remove_prefix``: - Whether to remove the prefix from the URL before dispatching it - to the target. The default is ``False``. - ``host``: - ``""`` (default): - The host header is automatically rewritten to the URL of the - target. - ``None``: - The host header is unmodified from the client request. - Any other value: - The host header is overwritten with the value. - ``headers``: - A dictionary of headers to be sent with the request to the - target. The default is ``{}``. - ``ssl_context``: - A :class:`ssl.SSLContext` defining how to verify requests if the - target is HTTPS. The default is ``None``. - - In the example above, everything under ``"/static/"`` is proxied to - the server on port 5001. The host header is rewritten to the target, - and the ``"/static/"`` prefix is removed from the URLs. - - :param app: The WSGI application to wrap. - :param targets: Proxy target configurations. See description above. - :param chunk_size: Size of chunks to read from input stream and - write to target. - :param timeout: Seconds before an operation to a target fails. - - .. versionadded:: 0.14 - """ - - def __init__( - self, - app: "WSGIApplication", - targets: t.Mapping[str, t.Dict[str, t.Any]], - chunk_size: int = 2 << 13, - timeout: int = 10, - ) -> None: - def _set_defaults(opts: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: - opts.setdefault("remove_prefix", False) - opts.setdefault("host", "") - opts.setdefault("headers", {}) - opts.setdefault("ssl_context", None) - return opts - - self.app = app - self.targets = { - f"/{k.strip('/')}/": _set_defaults(v) for k, v in targets.items() - } - self.chunk_size = chunk_size - self.timeout = timeout - - def proxy_to( - self, opts: t.Dict[str, t.Any], path: str, prefix: str - ) -> "WSGIApplication": - target = url_parse(opts["target"]) - host = t.cast(str, target.ascii_host) - - def application( - environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - headers = list(EnvironHeaders(environ).items()) - headers[:] = [ - (k, v) - for k, v in headers - if not is_hop_by_hop_header(k) - and k.lower() not in ("content-length", "host") - ] - headers.append(("Connection", "close")) - - if opts["host"] == "": - headers.append(("Host", host)) - elif opts["host"] is None: - headers.append(("Host", environ["HTTP_HOST"])) - else: - headers.append(("Host", opts["host"])) - - headers.extend(opts["headers"].items()) - remote_path = path - - if opts["remove_prefix"]: - remote_path = remote_path[len(prefix) :].lstrip("/") - remote_path = f"{target.path.rstrip('/')}/{remote_path}" - - content_length = environ.get("CONTENT_LENGTH") - chunked = False - - if content_length not in ("", None): - headers.append(("Content-Length", content_length)) # type: ignore - elif content_length is not None: - headers.append(("Transfer-Encoding", "chunked")) - chunked = True - - try: - if target.scheme == "http": - con = client.HTTPConnection( - host, target.port or 80, timeout=self.timeout - ) - elif target.scheme == "https": - con = client.HTTPSConnection( - host, - target.port or 443, - timeout=self.timeout, - context=opts["ssl_context"], - ) - else: - raise RuntimeError( - "Target scheme must be 'http' or 'https', got" - f" {target.scheme!r}." - ) - - con.connect() - remote_url = url_quote(remote_path) - querystring = environ["QUERY_STRING"] - - if querystring: - remote_url = f"{remote_url}?{querystring}" - - con.putrequest(environ["REQUEST_METHOD"], remote_url, skip_host=True) - - for k, v in headers: - if k.lower() == "connection": - v = "close" - - con.putheader(k, v) - - con.endheaders() - stream = get_input_stream(environ) - - while True: - data = stream.read(self.chunk_size) - - if not data: - break - - if chunked: - con.send(b"%x\r\n%s\r\n" % (len(data), data)) - else: - con.send(data) - - resp = con.getresponse() - except OSError: - from ..exceptions import BadGateway - - return BadGateway()(environ, start_response) - - start_response( - f"{resp.status} {resp.reason}", - [ - (k.title(), v) - for k, v in resp.getheaders() - if not is_hop_by_hop_header(k) - ], - ) - - def read() -> t.Iterator[bytes]: - while True: - try: - data = resp.read(self.chunk_size) - except OSError: - break - - if not data: - break - - yield data - - return read() - - return application - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - path = environ["PATH_INFO"] - app = self.app - - for prefix, opts in self.targets.items(): - if path.startswith(prefix): - app = self.proxy_to(opts, path, prefix) - break - - return app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py deleted file mode 100644 index c74703b..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py +++ /dev/null @@ -1,420 +0,0 @@ -""" -WSGI Protocol Linter -==================== - -This module provides a middleware that performs sanity checks on the -behavior of the WSGI server and application. It checks that the -:pep:`3333` WSGI spec is properly implemented. It also warns on some -common HTTP errors such as non-empty responses for 304 status codes. - -.. autoclass:: LintMiddleware - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import typing as t -from types import TracebackType -from urllib.parse import urlparse -from warnings import warn - -from ..datastructures import Headers -from ..http import is_entity_header -from ..wsgi import FileWrapper - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class WSGIWarning(Warning): - """Warning class for WSGI warnings.""" - - -class HTTPWarning(Warning): - """Warning class for HTTP warnings.""" - - -def check_type(context: str, obj: object, need: t.Type = str) -> None: - if type(obj) is not need: - warn( - f"{context!r} requires {need.__name__!r}, got {type(obj).__name__!r}.", - WSGIWarning, - stacklevel=3, - ) - - -class InputStream: - def __init__(self, stream: t.IO[bytes]) -> None: - self._stream = stream - - def read(self, *args: t.Any) -> bytes: - if len(args) == 0: - warn( - "WSGI does not guarantee an EOF marker on the input stream, thus making" - " calls to 'wsgi.input.read()' unsafe. Conforming servers may never" - " return from this call.", - WSGIWarning, - stacklevel=2, - ) - elif len(args) != 1: - warn( - "Too many parameters passed to 'wsgi.input.read()'.", - WSGIWarning, - stacklevel=2, - ) - return self._stream.read(*args) - - def readline(self, *args: t.Any) -> bytes: - if len(args) == 0: - warn( - "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use" - " 'wsgi.input.read()' instead.", - WSGIWarning, - stacklevel=2, - ) - elif len(args) == 1: - warn( - "'wsgi.input.readline()' was called with a size hint. WSGI does not" - " support this, although it's available on all major servers.", - WSGIWarning, - stacklevel=2, - ) - else: - raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.") - return self._stream.readline(*args) - - def __iter__(self) -> t.Iterator[bytes]: - try: - return iter(self._stream) - except TypeError: - warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2) - return iter(()) - - def close(self) -> None: - warn("The application closed the input stream!", WSGIWarning, stacklevel=2) - self._stream.close() - - -class ErrorStream: - def __init__(self, stream: t.IO[str]) -> None: - self._stream = stream - - def write(self, s: str) -> None: - check_type("wsgi.error.write()", s, str) - self._stream.write(s) - - def flush(self) -> None: - self._stream.flush() - - def writelines(self, seq: t.Iterable[str]) -> None: - for line in seq: - self.write(line) - - def close(self) -> None: - warn("The application closed the error stream!", WSGIWarning, stacklevel=2) - self._stream.close() - - -class GuardedWrite: - def __init__(self, write: t.Callable[[bytes], None], chunks: t.List[int]) -> None: - self._write = write - self._chunks = chunks - - def __call__(self, s: bytes) -> None: - check_type("write()", s, bytes) - self._write(s) - self._chunks.append(len(s)) - - -class GuardedIterator: - def __init__( - self, - iterator: t.Iterable[bytes], - headers_set: t.Tuple[int, Headers], - chunks: t.List[int], - ) -> None: - self._iterator = iterator - self._next = iter(iterator).__next__ - self.closed = False - self.headers_set = headers_set - self.chunks = chunks - - def __iter__(self) -> "GuardedIterator": - return self - - def __next__(self) -> bytes: - if self.closed: - warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2) - - rv = self._next() - - if not self.headers_set: - warn( - "The application returned before it started the response.", - WSGIWarning, - stacklevel=2, - ) - - check_type("application iterator items", rv, bytes) - self.chunks.append(len(rv)) - return rv - - def close(self) -> None: - self.closed = True - - if hasattr(self._iterator, "close"): - self._iterator.close() # type: ignore - - if self.headers_set: - status_code, headers = self.headers_set - bytes_sent = sum(self.chunks) - content_length = headers.get("content-length", type=int) - - if status_code == 304: - for key, _value in headers: - key = key.lower() - if key not in ("expires", "content-location") and is_entity_header( - key - ): - warn( - f"Entity header {key!r} found in 304 response.", HTTPWarning - ) - if bytes_sent: - warn("304 responses must not have a body.", HTTPWarning) - elif 100 <= status_code < 200 or status_code == 204: - if content_length != 0: - warn( - f"{status_code} responses must have an empty content length.", - HTTPWarning, - ) - if bytes_sent: - warn(f"{status_code} responses must not have a body.", HTTPWarning) - elif content_length is not None and content_length != bytes_sent: - warn( - "Content-Length and the number of bytes sent to the" - " client do not match.", - WSGIWarning, - ) - - def __del__(self) -> None: - if not self.closed: - try: - warn( - "Iterator was garbage collected before it was closed.", WSGIWarning - ) - except Exception: - pass - - -class LintMiddleware: - """Warns about common errors in the WSGI and HTTP behavior of the - server and wrapped application. Some of the issues it checks are: - - - invalid status codes - - non-bytes sent to the WSGI server - - strings returned from the WSGI application - - non-empty conditional responses - - unquoted etags - - relative URLs in the Location header - - unsafe calls to wsgi.input - - unclosed iterators - - Error information is emitted using the :mod:`warnings` module. - - :param app: The WSGI application to wrap. - - .. code-block:: python - - from werkzeug.middleware.lint import LintMiddleware - app = LintMiddleware(app) - """ - - def __init__(self, app: "WSGIApplication") -> None: - self.app = app - - def check_environ(self, environ: "WSGIEnvironment") -> None: - if type(environ) is not dict: - warn( - "WSGI environment is not a standard Python dict.", - WSGIWarning, - stacklevel=4, - ) - for key in ( - "REQUEST_METHOD", - "SERVER_NAME", - "SERVER_PORT", - "wsgi.version", - "wsgi.input", - "wsgi.errors", - "wsgi.multithread", - "wsgi.multiprocess", - "wsgi.run_once", - ): - if key not in environ: - warn( - f"Required environment key {key!r} not found", - WSGIWarning, - stacklevel=3, - ) - if environ["wsgi.version"] != (1, 0): - warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3) - - script_name = environ.get("SCRIPT_NAME", "") - path_info = environ.get("PATH_INFO", "") - - if script_name and script_name[0] != "/": - warn( - f"'SCRIPT_NAME' does not start with a slash: {script_name!r}", - WSGIWarning, - stacklevel=3, - ) - - if path_info and path_info[0] != "/": - warn( - f"'PATH_INFO' does not start with a slash: {path_info!r}", - WSGIWarning, - stacklevel=3, - ) - - def check_start_response( - self, - status: str, - headers: t.List[t.Tuple[str, str]], - exc_info: t.Optional[ - t.Tuple[t.Type[BaseException], BaseException, TracebackType] - ], - ) -> t.Tuple[int, Headers]: - check_type("status", status, str) - status_code_str = status.split(None, 1)[0] - - if len(status_code_str) != 3 or not status_code_str.isdigit(): - warn("Status code must be three digits.", WSGIWarning, stacklevel=3) - - if len(status) < 4 or status[3] != " ": - warn( - f"Invalid value for status {status!r}. Valid status strings are three" - " digits, a space and a status explanation.", - WSGIWarning, - stacklevel=3, - ) - - status_code = int(status_code_str) - - if status_code < 100: - warn("Status code < 100 detected.", WSGIWarning, stacklevel=3) - - if type(headers) is not list: - warn("Header list is not a list.", WSGIWarning, stacklevel=3) - - for item in headers: - if type(item) is not tuple or len(item) != 2: - warn("Header items must be 2-item tuples.", WSGIWarning, stacklevel=3) - name, value = item - if type(name) is not str or type(value) is not str: - warn( - "Header keys and values must be strings.", WSGIWarning, stacklevel=3 - ) - if name.lower() == "status": - warn( - "The status header is not supported due to" - " conflicts with the CGI spec.", - WSGIWarning, - stacklevel=3, - ) - - if exc_info is not None and not isinstance(exc_info, tuple): - warn("Invalid value for exc_info.", WSGIWarning, stacklevel=3) - - headers = Headers(headers) - self.check_headers(headers) - - return status_code, headers - - def check_headers(self, headers: Headers) -> None: - etag = headers.get("etag") - - if etag is not None: - if etag.startswith(("W/", "w/")): - if etag.startswith("w/"): - warn( - "Weak etag indicator should be upper case.", - HTTPWarning, - stacklevel=4, - ) - - etag = etag[2:] - - if not (etag[:1] == etag[-1:] == '"'): - warn("Unquoted etag emitted.", HTTPWarning, stacklevel=4) - - location = headers.get("location") - - if location is not None: - if not urlparse(location).netloc: - warn( - "Absolute URLs required for location header.", - HTTPWarning, - stacklevel=4, - ) - - def check_iterator(self, app_iter: t.Iterable[bytes]) -> None: - if isinstance(app_iter, bytes): - warn( - "The application returned a bytestring. The response will send one" - " character at a time to the client, which will kill performance." - " Return a list or iterable instead.", - WSGIWarning, - stacklevel=3, - ) - - def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Iterable[bytes]: - if len(args) != 2: - warn("A WSGI app takes two arguments.", WSGIWarning, stacklevel=2) - - if kwargs: - warn( - "A WSGI app does not take keyword arguments.", WSGIWarning, stacklevel=2 - ) - - environ: "WSGIEnvironment" = args[0] - start_response: "StartResponse" = args[1] - - self.check_environ(environ) - environ["wsgi.input"] = InputStream(environ["wsgi.input"]) - environ["wsgi.errors"] = ErrorStream(environ["wsgi.errors"]) - - # Hook our own file wrapper in so that applications will always - # iterate to the end and we can check the content length. - environ["wsgi.file_wrapper"] = FileWrapper - - headers_set: t.List[t.Any] = [] - chunks: t.List[int] = [] - - def checking_start_response( - *args: t.Any, **kwargs: t.Any - ) -> t.Callable[[bytes], None]: - if len(args) not in {2, 3}: - warn( - f"Invalid number of arguments: {len(args)}, expected 2 or 3.", - WSGIWarning, - stacklevel=2, - ) - - if kwargs: - warn("'start_response' does not take keyword arguments.", WSGIWarning) - - status: str = args[0] - headers: t.List[t.Tuple[str, str]] = args[1] - exc_info: t.Optional[ - t.Tuple[t.Type[BaseException], BaseException, TracebackType] - ] = (args[2] if len(args) == 3 else None) - - headers_set[:] = self.check_start_response(status, headers, exc_info) - return GuardedWrite(start_response(status, headers, exc_info), chunks) - - app_iter = self.app(environ, t.cast("StartResponse", checking_start_response)) - self.check_iterator(app_iter) - return GuardedIterator( - app_iter, t.cast(t.Tuple[int, Headers], headers_set), chunks - ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py deleted file mode 100644 index 200dae0..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py +++ /dev/null @@ -1,139 +0,0 @@ -""" -Application Profiler -==================== - -This module provides a middleware that profiles each request with the -:mod:`cProfile` module. This can help identify bottlenecks in your code -that may be slowing down your application. - -.. autoclass:: ProfilerMiddleware - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import os.path -import sys -import time -import typing as t -from pstats import Stats - -try: - from cProfile import Profile -except ImportError: - from profile import Profile # type: ignore - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class ProfilerMiddleware: - """Wrap a WSGI application and profile the execution of each - request. Responses are buffered so that timings are more exact. - - If ``stream`` is given, :class:`pstats.Stats` are written to it - after each request. If ``profile_dir`` is given, :mod:`cProfile` - data files are saved to that directory, one file per request. - - The filename can be customized by passing ``filename_format``. If - it is a string, it will be formatted using :meth:`str.format` with - the following fields available: - - - ``{method}`` - The request method; GET, POST, etc. - - ``{path}`` - The request path or 'root' should one not exist. - - ``{elapsed}`` - The elapsed time of the request. - - ``{time}`` - The time of the request. - - If it is a callable, it will be called with the WSGI ``environ`` - dict and should return a filename. - - :param app: The WSGI application to wrap. - :param stream: Write stats to this stream. Disable with ``None``. - :param sort_by: A tuple of columns to sort stats by. See - :meth:`pstats.Stats.sort_stats`. - :param restrictions: A tuple of restrictions to filter stats by. See - :meth:`pstats.Stats.print_stats`. - :param profile_dir: Save profile data files to this directory. - :param filename_format: Format string for profile data file names, - or a callable returning a name. See explanation above. - - .. code-block:: python - - from werkzeug.middleware.profiler import ProfilerMiddleware - app = ProfilerMiddleware(app) - - .. versionchanged:: 0.15 - Stats are written even if ``profile_dir`` is given, and can be - disable by passing ``stream=None``. - - .. versionadded:: 0.15 - Added ``filename_format``. - - .. versionadded:: 0.9 - Added ``restrictions`` and ``profile_dir``. - """ - - def __init__( - self, - app: "WSGIApplication", - stream: t.IO[str] = sys.stdout, - sort_by: t.Iterable[str] = ("time", "calls"), - restrictions: t.Iterable[t.Union[str, int, float]] = (), - profile_dir: t.Optional[str] = None, - filename_format: str = "{method}.{path}.{elapsed:.0f}ms.{time:.0f}.prof", - ) -> None: - self._app = app - self._stream = stream - self._sort_by = sort_by - self._restrictions = restrictions - self._profile_dir = profile_dir - self._filename_format = filename_format - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - response_body: t.List[bytes] = [] - - def catching_start_response(status, headers, exc_info=None): # type: ignore - start_response(status, headers, exc_info) - return response_body.append - - def runapp() -> None: - app_iter = self._app( - environ, t.cast("StartResponse", catching_start_response) - ) - response_body.extend(app_iter) - - if hasattr(app_iter, "close"): - app_iter.close() # type: ignore - - profile = Profile() - start = time.time() - profile.runcall(runapp) - body = b"".join(response_body) - elapsed = time.time() - start - - if self._profile_dir is not None: - if callable(self._filename_format): - filename = self._filename_format(environ) - else: - filename = self._filename_format.format( - method=environ["REQUEST_METHOD"], - path=environ["PATH_INFO"].strip("/").replace("/", ".") or "root", - elapsed=elapsed * 1000.0, - time=time.time(), - ) - filename = os.path.join(self._profile_dir, filename) - profile.dump_stats(filename) - - if self._stream is not None: - stats = Stats(profile, stream=self._stream) - stats.sort_stats(*self._sort_by) - print("-" * 80, file=self._stream) - path_info = environ.get("PATH_INFO", "") - print(f"PATH: {path_info!r}", file=self._stream) - stats.print_stats(*self._restrictions) - print(f"{'-' * 80}\n", file=self._stream) - - return [body] diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py deleted file mode 100644 index 4cef7cc..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py +++ /dev/null @@ -1,187 +0,0 @@ -""" -X-Forwarded-For Proxy Fix -========================= - -This module provides a middleware that adjusts the WSGI environ based on -``X-Forwarded-`` headers that proxies in front of an application may -set. - -When an application is running behind a proxy server, WSGI may see the -request as coming from that server rather than the real client. Proxies -set various headers to track where the request actually came from. - -This middleware should only be used if the application is actually -behind such a proxy, and should be configured with the number of proxies -that are chained in front of it. Not all proxies set all the headers. -Since incoming headers can be faked, you must set how many proxies are -setting each header so the middleware knows what to trust. - -.. autoclass:: ProxyFix - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import typing as t - -from ..http import parse_list_header - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class ProxyFix: - """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in - front of the application may set. - - - ``X-Forwarded-For`` sets ``REMOTE_ADDR``. - - ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``. - - ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and - ``SERVER_PORT``. - - ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``. - - ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``. - - You must tell the middleware how many proxies set each header so it - knows what values to trust. It is a security issue to trust values - that came from the client rather than a proxy. - - The original values of the headers are stored in the WSGI - environ as ``werkzeug.proxy_fix.orig``, a dict. - - :param app: The WSGI application to wrap. - :param x_for: Number of values to trust for ``X-Forwarded-For``. - :param x_proto: Number of values to trust for ``X-Forwarded-Proto``. - :param x_host: Number of values to trust for ``X-Forwarded-Host``. - :param x_port: Number of values to trust for ``X-Forwarded-Port``. - :param x_prefix: Number of values to trust for - ``X-Forwarded-Prefix``. - - .. code-block:: python - - from werkzeug.middleware.proxy_fix import ProxyFix - # App is behind one proxy that sets the -For and -Host headers. - app = ProxyFix(app, x_for=1, x_host=1) - - .. versionchanged:: 1.0 - Deprecated code has been removed: - - * The ``num_proxies`` argument and attribute. - * The ``get_remote_addr`` method. - * The environ keys ``orig_remote_addr``, - ``orig_wsgi_url_scheme``, and ``orig_http_host``. - - .. versionchanged:: 0.15 - All headers support multiple values. The ``num_proxies`` - argument is deprecated. Each header is configured with a - separate number of trusted proxies. - - .. versionchanged:: 0.15 - Original WSGI environ values are stored in the - ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``, - ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated - and will be removed in 1.0. - - .. versionchanged:: 0.15 - Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``. - - .. versionchanged:: 0.15 - ``X-Forwarded-Host`` and ``X-Forwarded-Port`` modify - ``SERVER_NAME`` and ``SERVER_PORT``. - """ - - def __init__( - self, - app: "WSGIApplication", - x_for: int = 1, - x_proto: int = 1, - x_host: int = 0, - x_port: int = 0, - x_prefix: int = 0, - ) -> None: - self.app = app - self.x_for = x_for - self.x_proto = x_proto - self.x_host = x_host - self.x_port = x_port - self.x_prefix = x_prefix - - def _get_real_value(self, trusted: int, value: t.Optional[str]) -> t.Optional[str]: - """Get the real value from a list header based on the configured - number of trusted proxies. - - :param trusted: Number of values to trust in the header. - :param value: Comma separated list header value to parse. - :return: The real value, or ``None`` if there are fewer values - than the number of trusted proxies. - - .. versionchanged:: 1.0 - Renamed from ``_get_trusted_comma``. - - .. versionadded:: 0.15 - """ - if not (trusted and value): - return None - values = parse_list_header(value) - if len(values) >= trusted: - return values[-trusted] - return None - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - """Modify the WSGI environ based on the various ``Forwarded`` - headers before calling the wrapped application. Store the - original environ values in ``werkzeug.proxy_fix.orig_{key}``. - """ - environ_get = environ.get - orig_remote_addr = environ_get("REMOTE_ADDR") - orig_wsgi_url_scheme = environ_get("wsgi.url_scheme") - orig_http_host = environ_get("HTTP_HOST") - environ.update( - { - "werkzeug.proxy_fix.orig": { - "REMOTE_ADDR": orig_remote_addr, - "wsgi.url_scheme": orig_wsgi_url_scheme, - "HTTP_HOST": orig_http_host, - "SERVER_NAME": environ_get("SERVER_NAME"), - "SERVER_PORT": environ_get("SERVER_PORT"), - "SCRIPT_NAME": environ_get("SCRIPT_NAME"), - } - } - ) - - x_for = self._get_real_value(self.x_for, environ_get("HTTP_X_FORWARDED_FOR")) - if x_for: - environ["REMOTE_ADDR"] = x_for - - x_proto = self._get_real_value( - self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO") - ) - if x_proto: - environ["wsgi.url_scheme"] = x_proto - - x_host = self._get_real_value(self.x_host, environ_get("HTTP_X_FORWARDED_HOST")) - if x_host: - environ["HTTP_HOST"] = environ["SERVER_NAME"] = x_host - # "]" to check for IPv6 address without port - if ":" in x_host and not x_host.endswith("]"): - environ["SERVER_NAME"], environ["SERVER_PORT"] = x_host.rsplit(":", 1) - - x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT")) - if x_port: - host = environ.get("HTTP_HOST") - if host: - # "]" to check for IPv6 address without port - if ":" in host and not host.endswith("]"): - host = host.rsplit(":", 1)[0] - environ["HTTP_HOST"] = f"{host}:{x_port}" - environ["SERVER_PORT"] = x_port - - x_prefix = self._get_real_value( - self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX") - ) - if x_prefix: - environ["SCRIPT_NAME"] = x_prefix - - return self.app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py deleted file mode 100644 index 62da672..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py +++ /dev/null @@ -1,320 +0,0 @@ -""" -Serve Shared Static Files -========================= - -.. autoclass:: SharedDataMiddleware - :members: is_allowed - -:copyright: 2007 Pallets -:license: BSD-3-Clause -""" -import mimetypes -import os -import pkgutil -import posixpath -import typing as t -from datetime import datetime -from datetime import timezone -from io import BytesIO -from time import time -from zlib import adler32 - -from ..filesystem import get_filesystem_encoding -from ..http import http_date -from ..http import is_resource_modified -from ..security import safe_join -from ..utils import get_content_type -from ..wsgi import get_path_info -from ..wsgi import wrap_file - -_TOpener = t.Callable[[], t.Tuple[t.IO[bytes], datetime, int]] -_TLoader = t.Callable[[t.Optional[str]], t.Tuple[t.Optional[str], t.Optional[_TOpener]]] - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class SharedDataMiddleware: - - """A WSGI middleware which provides static content for development - environments or simple server setups. Its usage is quite simple:: - - import os - from werkzeug.middleware.shared_data import SharedDataMiddleware - - app = SharedDataMiddleware(app, { - '/shared': os.path.join(os.path.dirname(__file__), 'shared') - }) - - The contents of the folder ``./shared`` will now be available on - ``http://example.com/shared/``. This is pretty useful during development - because a standalone media server is not required. Files can also be - mounted on the root folder and still continue to use the application because - the shared data middleware forwards all unhandled requests to the - application, even if the requests are below one of the shared folders. - - If `pkg_resources` is available you can also tell the middleware to serve - files from package data:: - - app = SharedDataMiddleware(app, { - '/static': ('myapplication', 'static') - }) - - This will then serve the ``static`` folder in the `myapplication` - Python package. - - The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` - rules for files that are not accessible from the web. If `cache` is set to - `False` no caching headers are sent. - - Currently the middleware does not support non-ASCII filenames. If the - encoding on the file system happens to match the encoding of the URI it may - work but this could also be by accident. We strongly suggest using ASCII - only file names for static files. - - The middleware will guess the mimetype using the Python `mimetype` - module. If it's unable to figure out the charset it will fall back - to `fallback_mimetype`. - - :param app: the application to wrap. If you don't want to wrap an - application you can pass it :exc:`NotFound`. - :param exports: a list or dict of exported files and folders. - :param disallow: a list of :func:`~fnmatch.fnmatch` rules. - :param cache: enable or disable caching headers. - :param cache_timeout: the cache timeout in seconds for the headers. - :param fallback_mimetype: The fallback mimetype for unknown files. - - .. versionchanged:: 1.0 - The default ``fallback_mimetype`` is - ``application/octet-stream``. If a filename looks like a text - mimetype, the ``utf-8`` charset is added to it. - - .. versionadded:: 0.6 - Added ``fallback_mimetype``. - - .. versionchanged:: 0.5 - Added ``cache_timeout``. - """ - - def __init__( - self, - app: "WSGIApplication", - exports: t.Union[ - t.Dict[str, t.Union[str, t.Tuple[str, str]]], - t.Iterable[t.Tuple[str, t.Union[str, t.Tuple[str, str]]]], - ], - disallow: None = None, - cache: bool = True, - cache_timeout: int = 60 * 60 * 12, - fallback_mimetype: str = "application/octet-stream", - ) -> None: - self.app = app - self.exports: t.List[t.Tuple[str, _TLoader]] = [] - self.cache = cache - self.cache_timeout = cache_timeout - - if isinstance(exports, dict): - exports = exports.items() - - for key, value in exports: - if isinstance(value, tuple): - loader = self.get_package_loader(*value) - elif isinstance(value, str): - if os.path.isfile(value): - loader = self.get_file_loader(value) - else: - loader = self.get_directory_loader(value) - else: - raise TypeError(f"unknown def {value!r}") - - self.exports.append((key, loader)) - - if disallow is not None: - from fnmatch import fnmatch - - self.is_allowed = lambda x: not fnmatch(x, disallow) - - self.fallback_mimetype = fallback_mimetype - - def is_allowed(self, filename: str) -> bool: - """Subclasses can override this method to disallow the access to - certain files. However by providing `disallow` in the constructor - this method is overwritten. - """ - return True - - def _opener(self, filename: str) -> _TOpener: - return lambda: ( - open(filename, "rb"), - datetime.fromtimestamp(os.path.getmtime(filename), tz=timezone.utc), - int(os.path.getsize(filename)), - ) - - def get_file_loader(self, filename: str) -> _TLoader: - return lambda x: (os.path.basename(filename), self._opener(filename)) - - def get_package_loader(self, package: str, package_path: str) -> _TLoader: - load_time = datetime.now(timezone.utc) - provider = pkgutil.get_loader(package) - - if hasattr(provider, "get_resource_reader"): - # Python 3 - reader = provider.get_resource_reader(package) # type: ignore - - def loader( - path: t.Optional[str], - ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: - if path is None: - return None, None - - path = safe_join(package_path, path) - - if path is None: - return None, None - - basename = posixpath.basename(path) - - try: - resource = reader.open_resource(path) - except OSError: - return None, None - - if isinstance(resource, BytesIO): - return ( - basename, - lambda: (resource, load_time, len(resource.getvalue())), - ) - - return ( - basename, - lambda: ( - resource, - datetime.fromtimestamp( - os.path.getmtime(resource.name), tz=timezone.utc - ), - os.path.getsize(resource.name), - ), - ) - - else: - # Python 3.6 - package_filename = provider.get_filename(package) # type: ignore - is_filesystem = os.path.exists(package_filename) - root = os.path.join(os.path.dirname(package_filename), package_path) - - def loader( - path: t.Optional[str], - ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: - if path is None: - return None, None - - path = safe_join(root, path) - - if path is None: - return None, None - - basename = posixpath.basename(path) - - if is_filesystem: - if not os.path.isfile(path): - return None, None - - return basename, self._opener(path) - - try: - data = provider.get_data(path) # type: ignore - except OSError: - return None, None - - return basename, lambda: (BytesIO(data), load_time, len(data)) - - return loader - - def get_directory_loader(self, directory: str) -> _TLoader: - def loader( - path: t.Optional[str], - ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: - if path is not None: - path = safe_join(directory, path) - - if path is None: - return None, None - else: - path = directory - - if os.path.isfile(path): - return os.path.basename(path), self._opener(path) - - return None, None - - return loader - - def generate_etag(self, mtime: datetime, file_size: int, real_filename: str) -> str: - if not isinstance(real_filename, bytes): - real_filename = real_filename.encode( # type: ignore - get_filesystem_encoding() - ) - - timestamp = mtime.timestamp() - checksum = adler32(real_filename) & 0xFFFFFFFF # type: ignore - return f"wzsdm-{timestamp}-{file_size}-{checksum}" - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - path = get_path_info(environ) - file_loader = None - - for search_path, loader in self.exports: - if search_path == path: - real_filename, file_loader = loader(None) - - if file_loader is not None: - break - - if not search_path.endswith("/"): - search_path += "/" - - if path.startswith(search_path): - real_filename, file_loader = loader(path[len(search_path) :]) - - if file_loader is not None: - break - - if file_loader is None or not self.is_allowed(real_filename): # type: ignore - return self.app(environ, start_response) - - guessed_type = mimetypes.guess_type(real_filename) # type: ignore - mime_type = get_content_type(guessed_type[0] or self.fallback_mimetype, "utf-8") - f, mtime, file_size = file_loader() - - headers = [("Date", http_date())] - - if self.cache: - timeout = self.cache_timeout - etag = self.generate_etag(mtime, file_size, real_filename) # type: ignore - headers += [ - ("Etag", f'"{etag}"'), - ("Cache-Control", f"max-age={timeout}, public"), - ] - - if not is_resource_modified(environ, etag, last_modified=mtime): - f.close() - start_response("304 Not Modified", headers) - return [] - - headers.append(("Expires", http_date(time() + timeout))) - else: - headers.append(("Cache-Control", "public")) - - headers.extend( - ( - ("Content-Type", mime_type), - ("Content-Length", str(file_size)), - ("Last-Modified", http_date(mtime)), - ) - ) - start_response("200 OK", headers) - return wrap_file(environ, f) diff --git a/venv/lib/python3.7/site-packages/werkzeug/py.typed b/venv/lib/python3.7/site-packages/werkzeug/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.7/site-packages/werkzeug/routing.py b/venv/lib/python3.7/site-packages/werkzeug/routing.py deleted file mode 100644 index 937b42b..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/routing.py +++ /dev/null @@ -1,2342 +0,0 @@ -"""When it comes to combining multiple controller or view functions -(however you want to call them) you need a dispatcher. A simple way -would be applying regular expression tests on the ``PATH_INFO`` and -calling registered callback functions that return the value then. - -This module implements a much more powerful system than simple regular -expression matching because it can also convert values in the URLs and -build URLs. - -Here a simple example that creates a URL map for an application with -two subdomains (www and kb) and some URL rules: - -.. code-block:: python - - m = Map([ - # Static URLs - Rule('/', endpoint='static/index'), - Rule('/about', endpoint='static/about'), - Rule('/help', endpoint='static/help'), - # Knowledge Base - Subdomain('kb', [ - Rule('/', endpoint='kb/index'), - Rule('/browse/', endpoint='kb/browse'), - Rule('/browse//', endpoint='kb/browse'), - Rule('/browse//', endpoint='kb/browse') - ]) - ], default_subdomain='www') - -If the application doesn't use subdomains it's perfectly fine to not set -the default subdomain and not use the `Subdomain` rule factory. The -endpoint in the rules can be anything, for example import paths or -unique identifiers. The WSGI application can use those endpoints to get the -handler for that URL. It doesn't have to be a string at all but it's -recommended. - -Now it's possible to create a URL adapter for one of the subdomains and -build URLs: - -.. code-block:: python - - c = m.bind('example.com') - - c.build("kb/browse", dict(id=42)) - 'http://kb.example.com/browse/42/' - - c.build("kb/browse", dict()) - 'http://kb.example.com/browse/' - - c.build("kb/browse", dict(id=42, page=3)) - 'http://kb.example.com/browse/42/3' - - c.build("static/about") - '/about' - - c.build("static/index", force_external=True) - 'http://www.example.com/' - - c = m.bind('example.com', subdomain='kb') - - c.build("static/about") - 'http://www.example.com/about' - -The first argument to bind is the server name *without* the subdomain. -Per default it will assume that the script is mounted on the root, but -often that's not the case so you can provide the real mount point as -second argument: - -.. code-block:: python - - c = m.bind('example.com', '/applications/example') - -The third argument can be the subdomain, if not given the default -subdomain is used. For more details about binding have a look at the -documentation of the `MapAdapter`. - -And here is how you can match URLs: - -.. code-block:: python - - c = m.bind('example.com') - - c.match("/") - ('static/index', {}) - - c.match("/about") - ('static/about', {}) - - c = m.bind('example.com', '/', 'kb') - - c.match("/") - ('kb/index', {}) - - c.match("/browse/42/23") - ('kb/browse', {'id': 42, 'page': 23}) - -If matching fails you get a ``NotFound`` exception, if the rule thinks -it's a good idea to redirect (for example because the URL was defined -to have a slash at the end but the request was missing that slash) it -will raise a ``RequestRedirect`` exception. Both are subclasses of -``HTTPException`` so you can use those errors as responses in the -application. - -If matching succeeded but the URL rule was incompatible to the given -method (for example there were only rules for ``GET`` and ``HEAD`` but -routing tried to match a ``POST`` request) a ``MethodNotAllowed`` -exception is raised. -""" -import ast -import difflib -import posixpath -import re -import typing -import typing as t -import uuid -import warnings -from pprint import pformat -from string import Template -from threading import Lock -from types import CodeType - -from ._internal import _encode_idna -from ._internal import _get_environ -from ._internal import _to_bytes -from ._internal import _to_str -from ._internal import _wsgi_decoding_dance -from .datastructures import ImmutableDict -from .datastructures import MultiDict -from .exceptions import BadHost -from .exceptions import BadRequest -from .exceptions import HTTPException -from .exceptions import MethodNotAllowed -from .exceptions import NotFound -from .urls import _fast_url_quote -from .urls import url_encode -from .urls import url_join -from .urls import url_quote -from .urls import url_unquote -from .utils import cached_property -from .utils import redirect -from .wsgi import get_host - -if t.TYPE_CHECKING: - import typing_extensions as te - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - from .wrappers.request import Request - from .wrappers.response import Response - -_rule_re = re.compile( - r""" - (?P[^<]*) # static rule data - < - (?: - (?P[a-zA-Z_][a-zA-Z0-9_]*) # converter name - (?:\((?P.*?)\))? # converter arguments - \: # variable delimiter - )? - (?P[a-zA-Z_][a-zA-Z0-9_]*) # variable name - > - """, - re.VERBOSE, -) -_simple_rule_re = re.compile(r"<([^>]+)>") -_converter_args_re = re.compile( - r""" - ((?P\w+)\s*=\s*)? - (?P - True|False| - \d+.\d+| - \d+.| - \d+| - [\w\d_.]+| - [urUR]?(?P"[^"]*?"|'[^']*') - )\s*, - """, - re.VERBOSE, -) - - -_PYTHON_CONSTANTS = {"None": None, "True": True, "False": False} - - -def _pythonize(value: str) -> t.Union[None, bool, int, float, str]: - if value in _PYTHON_CONSTANTS: - return _PYTHON_CONSTANTS[value] - for convert in int, float: - try: - return convert(value) # type: ignore - except ValueError: - pass - if value[:1] == value[-1:] and value[0] in "\"'": - value = value[1:-1] - return str(value) - - -def parse_converter_args(argstr: str) -> t.Tuple[t.Tuple, t.Dict[str, t.Any]]: - argstr += "," - args = [] - kwargs = {} - - for item in _converter_args_re.finditer(argstr): - value = item.group("stringval") - if value is None: - value = item.group("value") - value = _pythonize(value) - if not item.group("name"): - args.append(value) - else: - name = item.group("name") - kwargs[name] = value - - return tuple(args), kwargs - - -def parse_rule(rule: str) -> t.Iterator[t.Tuple[t.Optional[str], t.Optional[str], str]]: - """Parse a rule and return it as generator. Each iteration yields tuples - in the form ``(converter, arguments, variable)``. If the converter is - `None` it's a static url part, otherwise it's a dynamic one. - - :internal: - """ - pos = 0 - end = len(rule) - do_match = _rule_re.match - used_names = set() - while pos < end: - m = do_match(rule, pos) - if m is None: - break - data = m.groupdict() - if data["static"]: - yield None, None, data["static"] - variable = data["variable"] - converter = data["converter"] or "default" - if variable in used_names: - raise ValueError(f"variable name {variable!r} used twice.") - used_names.add(variable) - yield converter, data["args"] or None, variable - pos = m.end() - if pos < end: - remaining = rule[pos:] - if ">" in remaining or "<" in remaining: - raise ValueError(f"malformed url rule: {rule!r}") - yield None, None, remaining - - -class RoutingException(Exception): - """Special exceptions that require the application to redirect, notifying - about missing urls, etc. - - :internal: - """ - - -class RequestRedirect(HTTPException, RoutingException): - """Raise if the map requests a redirect. This is for example the case if - `strict_slashes` are activated and an url that requires a trailing slash. - - The attribute `new_url` contains the absolute destination url. - """ - - code = 308 - - def __init__(self, new_url: str) -> None: - super().__init__(new_url) - self.new_url = new_url - - def get_response( - self, - environ: t.Optional[t.Union["WSGIEnvironment", "Request"]] = None, - scope: t.Optional[dict] = None, - ) -> "Response": - return redirect(self.new_url, self.code) - - -class RequestPath(RoutingException): - """Internal exception.""" - - __slots__ = ("path_info",) - - def __init__(self, path_info: str) -> None: - super().__init__() - self.path_info = path_info - - -class RequestAliasRedirect(RoutingException): # noqa: B903 - """This rule is an alias and wants to redirect to the canonical URL.""" - - def __init__(self, matched_values: t.Mapping[str, t.Any]) -> None: - super().__init__() - self.matched_values = matched_values - - -class BuildError(RoutingException, LookupError): - """Raised if the build system cannot find a URL for an endpoint with the - values provided. - """ - - def __init__( - self, - endpoint: str, - values: t.Mapping[str, t.Any], - method: t.Optional[str], - adapter: t.Optional["MapAdapter"] = None, - ) -> None: - super().__init__(endpoint, values, method) - self.endpoint = endpoint - self.values = values - self.method = method - self.adapter = adapter - - @cached_property - def suggested(self) -> t.Optional["Rule"]: - return self.closest_rule(self.adapter) - - def closest_rule(self, adapter: t.Optional["MapAdapter"]) -> t.Optional["Rule"]: - def _score_rule(rule: "Rule") -> float: - return sum( - [ - 0.98 - * difflib.SequenceMatcher( - None, rule.endpoint, self.endpoint - ).ratio(), - 0.01 * bool(set(self.values or ()).issubset(rule.arguments)), - 0.01 * bool(rule.methods and self.method in rule.methods), - ] - ) - - if adapter and adapter.map._rules: - return max(adapter.map._rules, key=_score_rule) - - return None - - def __str__(self) -> str: - message = [f"Could not build url for endpoint {self.endpoint!r}"] - if self.method: - message.append(f" ({self.method!r})") - if self.values: - message.append(f" with values {sorted(self.values)!r}") - message.append(".") - if self.suggested: - if self.endpoint == self.suggested.endpoint: - if ( - self.method - and self.suggested.methods is not None - and self.method not in self.suggested.methods - ): - message.append( - " Did you mean to use methods" - f" {sorted(self.suggested.methods)!r}?" - ) - missing_values = self.suggested.arguments.union( - set(self.suggested.defaults or ()) - ) - set(self.values.keys()) - if missing_values: - message.append( - f" Did you forget to specify values {sorted(missing_values)!r}?" - ) - else: - message.append(f" Did you mean {self.suggested.endpoint!r} instead?") - return "".join(message) - - -class WebsocketMismatch(BadRequest): - """The only matched rule is either a WebSocket and the request is - HTTP, or the rule is HTTP and the request is a WebSocket. - """ - - -class ValidationError(ValueError): - """Validation error. If a rule converter raises this exception the rule - does not match the current URL and the next URL is tried. - """ - - -class RuleFactory: - """As soon as you have more complex URL setups it's a good idea to use rule - factories to avoid repetitive tasks. Some of them are builtin, others can - be added by subclassing `RuleFactory` and overriding `get_rules`. - """ - - def get_rules(self, map: "Map") -> t.Iterable["Rule"]: - """Subclasses of `RuleFactory` have to override this method and return - an iterable of rules.""" - raise NotImplementedError() - - -class Subdomain(RuleFactory): - """All URLs provided by this factory have the subdomain set to a - specific domain. For example if you want to use the subdomain for - the current language this can be a good setup:: - - url_map = Map([ - Rule('/', endpoint='#select_language'), - Subdomain('', [ - Rule('/', endpoint='index'), - Rule('/about', endpoint='about'), - Rule('/help', endpoint='help') - ]) - ]) - - All the rules except for the ``'#select_language'`` endpoint will now - listen on a two letter long subdomain that holds the language code - for the current request. - """ - - def __init__(self, subdomain: str, rules: t.Iterable[RuleFactory]) -> None: - self.subdomain = subdomain - self.rules = rules - - def get_rules(self, map: "Map") -> t.Iterator["Rule"]: - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.subdomain = self.subdomain - yield rule - - -class Submount(RuleFactory): - """Like `Subdomain` but prefixes the URL rule with a given string:: - - url_map = Map([ - Rule('/', endpoint='index'), - Submount('/blog', [ - Rule('/', endpoint='blog/index'), - Rule('/entry/', endpoint='blog/show') - ]) - ]) - - Now the rule ``'blog/show'`` matches ``/blog/entry/``. - """ - - def __init__(self, path: str, rules: t.Iterable[RuleFactory]) -> None: - self.path = path.rstrip("/") - self.rules = rules - - def get_rules(self, map: "Map") -> t.Iterator["Rule"]: - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.rule = self.path + rule.rule - yield rule - - -class EndpointPrefix(RuleFactory): - """Prefixes all endpoints (which must be strings for this factory) with - another string. This can be useful for sub applications:: - - url_map = Map([ - Rule('/', endpoint='index'), - EndpointPrefix('blog/', [Submount('/blog', [ - Rule('/', endpoint='index'), - Rule('/entry/', endpoint='show') - ])]) - ]) - """ - - def __init__(self, prefix: str, rules: t.Iterable[RuleFactory]) -> None: - self.prefix = prefix - self.rules = rules - - def get_rules(self, map: "Map") -> t.Iterator["Rule"]: - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.endpoint = self.prefix + rule.endpoint - yield rule - - -class RuleTemplate: - """Returns copies of the rules wrapped and expands string templates in - the endpoint, rule, defaults or subdomain sections. - - Here a small example for such a rule template:: - - from werkzeug.routing import Map, Rule, RuleTemplate - - resource = RuleTemplate([ - Rule('/$name/', endpoint='$name.list'), - Rule('/$name/', endpoint='$name.show') - ]) - - url_map = Map([resource(name='user'), resource(name='page')]) - - When a rule template is called the keyword arguments are used to - replace the placeholders in all the string parameters. - """ - - def __init__(self, rules: t.Iterable["Rule"]) -> None: - self.rules = list(rules) - - def __call__(self, *args: t.Any, **kwargs: t.Any) -> "RuleTemplateFactory": - return RuleTemplateFactory(self.rules, dict(*args, **kwargs)) - - -class RuleTemplateFactory(RuleFactory): - """A factory that fills in template variables into rules. Used by - `RuleTemplate` internally. - - :internal: - """ - - def __init__( - self, rules: t.Iterable[RuleFactory], context: t.Dict[str, t.Any] - ) -> None: - self.rules = rules - self.context = context - - def get_rules(self, map: "Map") -> t.Iterator["Rule"]: - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - new_defaults = subdomain = None - if rule.defaults: - new_defaults = {} - for key, value in rule.defaults.items(): - if isinstance(value, str): - value = Template(value).substitute(self.context) - new_defaults[key] = value - if rule.subdomain is not None: - subdomain = Template(rule.subdomain).substitute(self.context) - new_endpoint = rule.endpoint - if isinstance(new_endpoint, str): - new_endpoint = Template(new_endpoint).substitute(self.context) - yield Rule( - Template(rule.rule).substitute(self.context), - new_defaults, - subdomain, - rule.methods, - rule.build_only, - new_endpoint, - rule.strict_slashes, - ) - - -def _prefix_names(src: str) -> ast.stmt: - """ast parse and prefix names with `.` to avoid collision with user vars""" - tree = ast.parse(src).body[0] - if isinstance(tree, ast.Expr): - tree = tree.value # type: ignore - for node in ast.walk(tree): - if isinstance(node, ast.Name): - node.id = f".{node.id}" - return tree - - -_CALL_CONVERTER_CODE_FMT = "self._converters[{elem!r}].to_url()" -_IF_KWARGS_URL_ENCODE_CODE = """\ -if kwargs: - q = '?' - params = self._encode_query_vars(kwargs) -else: - q = params = '' -""" -_IF_KWARGS_URL_ENCODE_AST = _prefix_names(_IF_KWARGS_URL_ENCODE_CODE) -_URL_ENCODE_AST_NAMES = (_prefix_names("q"), _prefix_names("params")) - - -class Rule(RuleFactory): - """A Rule represents one URL pattern. There are some options for `Rule` - that change the way it behaves and are passed to the `Rule` constructor. - Note that besides the rule-string all arguments *must* be keyword arguments - in order to not break the application on Werkzeug upgrades. - - `string` - Rule strings basically are just normal URL paths with placeholders in - the format ```` where the converter and the - arguments are optional. If no converter is defined the `default` - converter is used which means `string` in the normal configuration. - - URL rules that end with a slash are branch URLs, others are leaves. - If you have `strict_slashes` enabled (which is the default), all - branch URLs that are matched without a trailing slash will trigger a - redirect to the same URL with the missing slash appended. - - The converters are defined on the `Map`. - - `endpoint` - The endpoint for this rule. This can be anything. A reference to a - function, a string, a number etc. The preferred way is using a string - because the endpoint is used for URL generation. - - `defaults` - An optional dict with defaults for other rules with the same endpoint. - This is a bit tricky but useful if you want to have unique URLs:: - - url_map = Map([ - Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), - Rule('/all/page/', endpoint='all_entries') - ]) - - If a user now visits ``http://example.com/all/page/1`` he will be - redirected to ``http://example.com/all/``. If `redirect_defaults` is - disabled on the `Map` instance this will only affect the URL - generation. - - `subdomain` - The subdomain rule string for this rule. If not specified the rule - only matches for the `default_subdomain` of the map. If the map is - not bound to a subdomain this feature is disabled. - - Can be useful if you want to have user profiles on different subdomains - and all subdomains are forwarded to your application:: - - url_map = Map([ - Rule('/', subdomain='', endpoint='user/homepage'), - Rule('/stats', subdomain='', endpoint='user/stats') - ]) - - `methods` - A sequence of http methods this rule applies to. If not specified, all - methods are allowed. For example this can be useful if you want different - endpoints for `POST` and `GET`. If methods are defined and the path - matches but the method matched against is not in this list or in the - list of another rule for that path the error raised is of the type - `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the - list of methods and `HEAD` is not, `HEAD` is added automatically. - - `strict_slashes` - Override the `Map` setting for `strict_slashes` only for this rule. If - not specified the `Map` setting is used. - - `merge_slashes` - Override :attr:`Map.merge_slashes` for this rule. - - `build_only` - Set this to True and the rule will never match but will create a URL - that can be build. This is useful if you have resources on a subdomain - or folder that are not handled by the WSGI application (like static data) - - `redirect_to` - If given this must be either a string or callable. In case of a - callable it's called with the url adapter that triggered the match and - the values of the URL as keyword arguments and has to return the target - for the redirect, otherwise it has to be a string with placeholders in - rule syntax:: - - def foo_with_slug(adapter, id): - # ask the database for the slug for the old id. this of - # course has nothing to do with werkzeug. - return f'foo/{Foo.get_slug_for_id(id)}' - - url_map = Map([ - Rule('/foo/', endpoint='foo'), - Rule('/some/old/url/', redirect_to='foo/'), - Rule('/other/old/url/', redirect_to=foo_with_slug) - ]) - - When the rule is matched the routing system will raise a - `RequestRedirect` exception with the target for the redirect. - - Keep in mind that the URL will be joined against the URL root of the - script so don't use a leading slash on the target URL unless you - really mean root of that domain. - - `alias` - If enabled this rule serves as an alias for another rule with the same - endpoint and arguments. - - `host` - If provided and the URL map has host matching enabled this can be - used to provide a match rule for the whole host. This also means - that the subdomain feature is disabled. - - `websocket` - If ``True``, this rule is only matches for WebSocket (``ws://``, - ``wss://``) requests. By default, rules will only match for HTTP - requests. - - .. versionadded:: 1.0 - Added ``websocket``. - - .. versionadded:: 1.0 - Added ``merge_slashes``. - - .. versionadded:: 0.7 - Added ``alias`` and ``host``. - - .. versionchanged:: 0.6.1 - ``HEAD`` is added to ``methods`` if ``GET`` is present. - """ - - def __init__( - self, - string: str, - defaults: t.Optional[t.Mapping[str, t.Any]] = None, - subdomain: t.Optional[str] = None, - methods: t.Optional[t.Iterable[str]] = None, - build_only: bool = False, - endpoint: t.Optional[str] = None, - strict_slashes: t.Optional[bool] = None, - merge_slashes: t.Optional[bool] = None, - redirect_to: t.Optional[t.Union[str, t.Callable[..., str]]] = None, - alias: bool = False, - host: t.Optional[str] = None, - websocket: bool = False, - ) -> None: - if not string.startswith("/"): - raise ValueError("urls must start with a leading slash") - self.rule = string - self.is_leaf = not string.endswith("/") - - self.map: "Map" = None # type: ignore - self.strict_slashes = strict_slashes - self.merge_slashes = merge_slashes - self.subdomain = subdomain - self.host = host - self.defaults = defaults - self.build_only = build_only - self.alias = alias - self.websocket = websocket - - if methods is not None: - if isinstance(methods, str): - raise TypeError("'methods' should be a list of strings.") - - methods = {x.upper() for x in methods} - - if "HEAD" not in methods and "GET" in methods: - methods.add("HEAD") - - if websocket and methods - {"GET", "HEAD", "OPTIONS"}: - raise ValueError( - "WebSocket rules can only use 'GET', 'HEAD', and 'OPTIONS' methods." - ) - - self.methods = methods - self.endpoint: str = endpoint # type: ignore - self.redirect_to = redirect_to - - if defaults: - self.arguments = set(map(str, defaults)) - else: - self.arguments = set() - - self._trace: t.List[t.Tuple[bool, str]] = [] - - def empty(self) -> "Rule": - """ - Return an unbound copy of this rule. - - This can be useful if want to reuse an already bound URL for another - map. See ``get_empty_kwargs`` to override what keyword arguments are - provided to the new copy. - """ - return type(self)(self.rule, **self.get_empty_kwargs()) - - def get_empty_kwargs(self) -> t.Mapping[str, t.Any]: - """ - Provides kwargs for instantiating empty copy with empty() - - Use this method to provide custom keyword arguments to the subclass of - ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass - has custom keyword arguments that are needed at instantiation. - - Must return a ``dict`` that will be provided as kwargs to the new - instance of ``Rule``, following the initial ``self.rule`` value which - is always provided as the first, required positional argument. - """ - defaults = None - if self.defaults: - defaults = dict(self.defaults) - return dict( - defaults=defaults, - subdomain=self.subdomain, - methods=self.methods, - build_only=self.build_only, - endpoint=self.endpoint, - strict_slashes=self.strict_slashes, - redirect_to=self.redirect_to, - alias=self.alias, - host=self.host, - ) - - def get_rules(self, map: "Map") -> t.Iterator["Rule"]: - yield self - - def refresh(self) -> None: - """Rebinds and refreshes the URL. Call this if you modified the - rule in place. - - :internal: - """ - self.bind(self.map, rebind=True) - - def bind(self, map: "Map", rebind: bool = False) -> None: - """Bind the url to a map and create a regular expression based on - the information from the rule itself and the defaults from the map. - - :internal: - """ - if self.map is not None and not rebind: - raise RuntimeError(f"url rule {self!r} already bound to map {self.map!r}") - self.map = map - if self.strict_slashes is None: - self.strict_slashes = map.strict_slashes - if self.merge_slashes is None: - self.merge_slashes = map.merge_slashes - if self.subdomain is None: - self.subdomain = map.default_subdomain - self.compile() - - def get_converter( - self, - variable_name: str, - converter_name: str, - args: t.Tuple, - kwargs: t.Mapping[str, t.Any], - ) -> "BaseConverter": - """Looks up the converter for the given parameter. - - .. versionadded:: 0.9 - """ - if converter_name not in self.map.converters: - raise LookupError(f"the converter {converter_name!r} does not exist") - return self.map.converters[converter_name](self.map, *args, **kwargs) - - def _encode_query_vars(self, query_vars: t.Mapping[str, t.Any]) -> str: - return url_encode( - query_vars, - charset=self.map.charset, - sort=self.map.sort_parameters, - key=self.map.sort_key, - ) - - def compile(self) -> None: - """Compiles the regular expression and stores it.""" - assert self.map is not None, "rule not bound" - - if self.map.host_matching: - domain_rule = self.host or "" - else: - domain_rule = self.subdomain or "" - - self._trace = [] - self._converters: t.Dict[str, "BaseConverter"] = {} - self._static_weights: t.List[t.Tuple[int, int]] = [] - self._argument_weights: t.List[int] = [] - regex_parts = [] - - def _build_regex(rule: str) -> None: - index = 0 - for converter, arguments, variable in parse_rule(rule): - if converter is None: - for match in re.finditer(r"/+|[^/]+", variable): - part = match.group(0) - if part.startswith("/"): - if self.merge_slashes: - regex_parts.append(r"/+?") - self._trace.append((False, "/")) - else: - regex_parts.append(part) - self._trace.append((False, part)) - continue - self._trace.append((False, part)) - regex_parts.append(re.escape(part)) - if part: - self._static_weights.append((index, -len(part))) - else: - if arguments: - c_args, c_kwargs = parse_converter_args(arguments) - else: - c_args = () - c_kwargs = {} - convobj = self.get_converter(variable, converter, c_args, c_kwargs) - regex_parts.append(f"(?P<{variable}>{convobj.regex})") - self._converters[variable] = convobj - self._trace.append((True, variable)) - self._argument_weights.append(convobj.weight) - self.arguments.add(str(variable)) - index = index + 1 - - _build_regex(domain_rule) - regex_parts.append("\\|") - self._trace.append((False, "|")) - _build_regex(self.rule if self.is_leaf else self.rule.rstrip("/")) - if not self.is_leaf: - self._trace.append((False, "/")) - - self._build: t.Callable[..., t.Tuple[str, str]] - self._build = self._compile_builder(False).__get__(self, None) # type: ignore - self._build_unknown: t.Callable[..., t.Tuple[str, str]] - self._build_unknown = self._compile_builder(True).__get__( # type: ignore - self, None - ) - - if self.build_only: - return - - if not (self.is_leaf and self.strict_slashes): - reps = "*" if self.merge_slashes else "?" - tail = f"(?/{reps})" - else: - tail = "" - - regex = f"^{''.join(regex_parts)}{tail}$" - self._regex = re.compile(regex) - - def match( - self, path: str, method: t.Optional[str] = None - ) -> t.Optional[t.MutableMapping[str, t.Any]]: - """Check if the rule matches a given path. Path is a string in the - form ``"subdomain|/path"`` and is assembled by the map. If - the map is doing host matching the subdomain part will be the host - instead. - - If the rule matches a dict with the converted values is returned, - otherwise the return value is `None`. - - :internal: - """ - if not self.build_only: - require_redirect = False - - m = self._regex.search(path) - if m is not None: - groups = m.groupdict() - # we have a folder like part of the url without a trailing - # slash and strict slashes enabled. raise an exception that - # tells the map to redirect to the same url but with a - # trailing slash - if ( - self.strict_slashes - and not self.is_leaf - and not groups.pop("__suffix__") - and ( - method is None or self.methods is None or method in self.methods - ) - ): - path += "/" - require_redirect = True - # if we are not in strict slashes mode we have to remove - # a __suffix__ - elif not self.strict_slashes: - del groups["__suffix__"] - - result = {} - for name, value in groups.items(): - try: - value = self._converters[name].to_python(value) - except ValidationError: - return None - result[str(name)] = value - if self.defaults: - result.update(self.defaults) - - if self.merge_slashes: - new_path = "|".join(self.build(result, False)) # type: ignore - if path.endswith("/") and not new_path.endswith("/"): - new_path += "/" - if new_path.count("/") < path.count("/"): - # The URL will be encoded when MapAdapter.match - # handles the RequestPath raised below. Decode - # the URL here to avoid a double encoding. - path = url_unquote(new_path) - require_redirect = True - - if require_redirect: - path = path.split("|", 1)[1] - raise RequestPath(path) - - if self.alias and self.map.redirect_defaults: - raise RequestAliasRedirect(result) - - return result - - return None - - @staticmethod - def _get_func_code(code: CodeType, name: str) -> t.Callable[..., t.Tuple[str, str]]: - globs: t.Dict[str, t.Any] = {} - locs: t.Dict[str, t.Any] = {} - exec(code, globs, locs) - return locs[name] # type: ignore - - def _compile_builder( - self, append_unknown: bool = True - ) -> t.Callable[..., t.Tuple[str, str]]: - defaults = self.defaults or {} - dom_ops: t.List[t.Tuple[bool, str]] = [] - url_ops: t.List[t.Tuple[bool, str]] = [] - - opl = dom_ops - for is_dynamic, data in self._trace: - if data == "|" and opl is dom_ops: - opl = url_ops - continue - # this seems like a silly case to ever come up but: - # if a default is given for a value that appears in the rule, - # resolve it to a constant ahead of time - if is_dynamic and data in defaults: - data = self._converters[data].to_url(defaults[data]) - opl.append((False, data)) - elif not is_dynamic: - opl.append( - (False, url_quote(_to_bytes(data, self.map.charset), safe="/:|+")) - ) - else: - opl.append((True, data)) - - def _convert(elem: str) -> ast.stmt: - ret = _prefix_names(_CALL_CONVERTER_CODE_FMT.format(elem=elem)) - ret.args = [ast.Name(str(elem), ast.Load())] # type: ignore # str for py2 - return ret - - def _parts(ops: t.List[t.Tuple[bool, str]]) -> t.List[ast.AST]: - parts = [ - _convert(elem) if is_dynamic else ast.Str(s=elem) - for is_dynamic, elem in ops - ] - parts = parts or [ast.Str("")] - # constant fold - ret = [parts[0]] - for p in parts[1:]: - if isinstance(p, ast.Str) and isinstance(ret[-1], ast.Str): - ret[-1] = ast.Str(ret[-1].s + p.s) - else: - ret.append(p) - return ret - - dom_parts = _parts(dom_ops) - url_parts = _parts(url_ops) - if not append_unknown: - body = [] - else: - body = [_IF_KWARGS_URL_ENCODE_AST] - url_parts.extend(_URL_ENCODE_AST_NAMES) - - def _join(parts: t.List[ast.AST]) -> ast.AST: - if len(parts) == 1: # shortcut - return parts[0] - return ast.JoinedStr(parts) - - body.append( - ast.Return(ast.Tuple([_join(dom_parts), _join(url_parts)], ast.Load())) - ) - - pargs = [ - elem - for is_dynamic, elem in dom_ops + url_ops - if is_dynamic and elem not in defaults - ] - kargs = [str(k) for k in defaults] - - func_ast: ast.FunctionDef = _prefix_names("def _(): pass") # type: ignore - func_ast.name = f"" - func_ast.args.args.append(ast.arg(".self", None)) - for arg in pargs + kargs: - func_ast.args.args.append(ast.arg(arg, None)) - func_ast.args.kwarg = ast.arg(".kwargs", None) - for _ in kargs: - func_ast.args.defaults.append(ast.Str("")) - func_ast.body = body - - # use `ast.parse` instead of `ast.Module` for better portability - # Python 3.8 changes the signature of `ast.Module` - module = ast.parse("") - module.body = [func_ast] - - # mark everything as on line 1, offset 0 - # less error-prone than `ast.fix_missing_locations` - # bad line numbers cause an assert to fail in debug builds - for node in ast.walk(module): - if "lineno" in node._attributes: - node.lineno = 1 - if "col_offset" in node._attributes: - node.col_offset = 0 - - code = compile(module, "", "exec") - return self._get_func_code(code, func_ast.name) - - def build( - self, values: t.Mapping[str, t.Any], append_unknown: bool = True - ) -> t.Optional[t.Tuple[str, str]]: - """Assembles the relative url for that rule and the subdomain. - If building doesn't work for some reasons `None` is returned. - - :internal: - """ - try: - if append_unknown: - return self._build_unknown(**values) - else: - return self._build(**values) - except ValidationError: - return None - - def provides_defaults_for(self, rule: "Rule") -> bool: - """Check if this rule has defaults for a given rule. - - :internal: - """ - return bool( - not self.build_only - and self.defaults - and self.endpoint == rule.endpoint - and self != rule - and self.arguments == rule.arguments - ) - - def suitable_for( - self, values: t.Mapping[str, t.Any], method: t.Optional[str] = None - ) -> bool: - """Check if the dict of values has enough data for url generation. - - :internal: - """ - # if a method was given explicitly and that method is not supported - # by this rule, this rule is not suitable. - if ( - method is not None - and self.methods is not None - and method not in self.methods - ): - return False - - defaults = self.defaults or () - - # all arguments required must be either in the defaults dict or - # the value dictionary otherwise it's not suitable - for key in self.arguments: - if key not in defaults and key not in values: - return False - - # in case defaults are given we ensure that either the value was - # skipped or the value is the same as the default value. - if defaults: - for key, value in defaults.items(): - if key in values and value != values[key]: - return False - - return True - - def match_compare_key( - self, - ) -> t.Tuple[bool, int, t.Iterable[t.Tuple[int, int]], int, t.Iterable[int]]: - """The match compare key for sorting. - - Current implementation: - - 1. rules without any arguments come first for performance - reasons only as we expect them to match faster and some - common ones usually don't have any arguments (index pages etc.) - 2. rules with more static parts come first so the second argument - is the negative length of the number of the static weights. - 3. we order by static weights, which is a combination of index - and length - 4. The more complex rules come first so the next argument is the - negative length of the number of argument weights. - 5. lastly we order by the actual argument weights. - - :internal: - """ - return ( - bool(self.arguments), - -len(self._static_weights), - self._static_weights, - -len(self._argument_weights), - self._argument_weights, - ) - - def build_compare_key(self) -> t.Tuple[int, int, int]: - """The build compare key for sorting. - - :internal: - """ - return (1 if self.alias else 0, -len(self.arguments), -len(self.defaults or ())) - - def __eq__(self, other: object) -> bool: - return isinstance(other, type(self)) and self._trace == other._trace - - __hash__ = None # type: ignore - - def __str__(self) -> str: - return self.rule - - def __repr__(self) -> str: - if self.map is None: - return f"<{type(self).__name__} (unbound)>" - parts = [] - for is_dynamic, data in self._trace: - if is_dynamic: - parts.append(f"<{data}>") - else: - parts.append(data) - parts = "".join(parts).lstrip("|") - methods = f" ({', '.join(self.methods)})" if self.methods is not None else "" - return f"<{type(self).__name__} {parts!r}{methods} -> {self.endpoint}>" - - -class BaseConverter: - """Base class for all converters.""" - - regex = "[^/]+" - weight = 100 - - def __init__(self, map: "Map", *args: t.Any, **kwargs: t.Any) -> None: - self.map = map - - def to_python(self, value: str) -> t.Any: - return value - - def to_url(self, value: t.Any) -> str: - if isinstance(value, (bytes, bytearray)): - return _fast_url_quote(value) - return _fast_url_quote(str(value).encode(self.map.charset)) - - -class UnicodeConverter(BaseConverter): - """This converter is the default converter and accepts any string but - only one path segment. Thus the string can not include a slash. - - This is the default validator. - - Example:: - - Rule('/pages/'), - Rule('/') - - :param map: the :class:`Map`. - :param minlength: the minimum length of the string. Must be greater - or equal 1. - :param maxlength: the maximum length of the string. - :param length: the exact length of the string. - """ - - def __init__( - self, - map: "Map", - minlength: int = 1, - maxlength: t.Optional[int] = None, - length: t.Optional[int] = None, - ) -> None: - super().__init__(map) - if length is not None: - length_regex = f"{{{int(length)}}}" - else: - if maxlength is None: - maxlength_value = "" - else: - maxlength_value = str(int(maxlength)) - length_regex = f"{{{int(minlength)},{maxlength_value}}}" - self.regex = f"[^/]{length_regex}" - - -class AnyConverter(BaseConverter): - """Matches one of the items provided. Items can either be Python - identifiers or strings:: - - Rule('/') - - :param map: the :class:`Map`. - :param items: this function accepts the possible items as positional - arguments. - """ - - def __init__(self, map: "Map", *items: str) -> None: - super().__init__(map) - self.regex = f"(?:{'|'.join([re.escape(x) for x in items])})" - - -class PathConverter(BaseConverter): - """Like the default :class:`UnicodeConverter`, but it also matches - slashes. This is useful for wikis and similar applications:: - - Rule('/') - Rule('//edit') - - :param map: the :class:`Map`. - """ - - regex = "[^/].*?" - weight = 200 - - -class NumberConverter(BaseConverter): - """Baseclass for `IntegerConverter` and `FloatConverter`. - - :internal: - """ - - weight = 50 - num_convert: t.Callable = int - - def __init__( - self, - map: "Map", - fixed_digits: int = 0, - min: t.Optional[int] = None, - max: t.Optional[int] = None, - signed: bool = False, - ) -> None: - if signed: - self.regex = self.signed_regex - super().__init__(map) - self.fixed_digits = fixed_digits - self.min = min - self.max = max - self.signed = signed - - def to_python(self, value: str) -> t.Any: - if self.fixed_digits and len(value) != self.fixed_digits: - raise ValidationError() - value = self.num_convert(value) - if (self.min is not None and value < self.min) or ( - self.max is not None and value > self.max - ): - raise ValidationError() - return value - - def to_url(self, value: t.Any) -> str: - value = str(self.num_convert(value)) - if self.fixed_digits: - value = value.zfill(self.fixed_digits) - return value - - @property - def signed_regex(self) -> str: - return f"-?{self.regex}" - - -class IntegerConverter(NumberConverter): - """This converter only accepts integer values:: - - Rule("/page/") - - By default it only accepts unsigned, positive values. The ``signed`` - parameter will enable signed, negative values. :: - - Rule("/page/") - - :param map: The :class:`Map`. - :param fixed_digits: The number of fixed digits in the URL. If you - set this to ``4`` for example, the rule will only match if the - URL looks like ``/0001/``. The default is variable length. - :param min: The minimal value. - :param max: The maximal value. - :param signed: Allow signed (negative) values. - - .. versionadded:: 0.15 - The ``signed`` parameter. - """ - - regex = r"\d+" - - -class FloatConverter(NumberConverter): - """This converter only accepts floating point values:: - - Rule("/probability/") - - By default it only accepts unsigned, positive values. The ``signed`` - parameter will enable signed, negative values. :: - - Rule("/offset/") - - :param map: The :class:`Map`. - :param min: The minimal value. - :param max: The maximal value. - :param signed: Allow signed (negative) values. - - .. versionadded:: 0.15 - The ``signed`` parameter. - """ - - regex = r"\d+\.\d+" - num_convert = float - - def __init__( - self, - map: "Map", - min: t.Optional[float] = None, - max: t.Optional[float] = None, - signed: bool = False, - ) -> None: - super().__init__(map, min=min, max=max, signed=signed) # type: ignore - - -class UUIDConverter(BaseConverter): - """This converter only accepts UUID strings:: - - Rule('/object/') - - .. versionadded:: 0.10 - - :param map: the :class:`Map`. - """ - - regex = ( - r"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-" - r"[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}" - ) - - def to_python(self, value: str) -> uuid.UUID: - return uuid.UUID(value) - - def to_url(self, value: uuid.UUID) -> str: - return str(value) - - -#: the default converter mapping for the map. -DEFAULT_CONVERTERS: t.Mapping[str, t.Type[BaseConverter]] = { - "default": UnicodeConverter, - "string": UnicodeConverter, - "any": AnyConverter, - "path": PathConverter, - "int": IntegerConverter, - "float": FloatConverter, - "uuid": UUIDConverter, -} - - -class Map: - """The map class stores all the URL rules and some configuration - parameters. Some of the configuration values are only stored on the - `Map` instance since those affect all rules, others are just defaults - and can be overridden for each rule. Note that you have to specify all - arguments besides the `rules` as keyword arguments! - - :param rules: sequence of url rules for this map. - :param default_subdomain: The default subdomain for rules without a - subdomain defined. - :param charset: charset of the url. defaults to ``"utf-8"`` - :param strict_slashes: If a rule ends with a slash but the matched - URL does not, redirect to the URL with a trailing slash. - :param merge_slashes: Merge consecutive slashes when matching or - building URLs. Matches will redirect to the normalized URL. - Slashes in variable parts are not merged. - :param redirect_defaults: This will redirect to the default rule if it - wasn't visited that way. This helps creating - unique URLs. - :param converters: A dict of converters that adds additional converters - to the list of converters. If you redefine one - converter this will override the original one. - :param sort_parameters: If set to `True` the url parameters are sorted. - See `url_encode` for more details. - :param sort_key: The sort key function for `url_encode`. - :param encoding_errors: the error method to use for decoding - :param host_matching: if set to `True` it enables the host matching - feature and disables the subdomain one. If - enabled the `host` parameter to rules is used - instead of the `subdomain` one. - - .. versionchanged:: 1.0 - If ``url_scheme`` is ``ws`` or ``wss``, only WebSocket rules - will match. - - .. versionchanged:: 1.0 - Added ``merge_slashes``. - - .. versionchanged:: 0.7 - Added ``encoding_errors`` and ``host_matching``. - - .. versionchanged:: 0.5 - Added ``sort_parameters`` and ``sort_key``. - """ - - #: A dict of default converters to be used. - default_converters = ImmutableDict(DEFAULT_CONVERTERS) - - #: The type of lock to use when updating. - #: - #: .. versionadded:: 1.0 - lock_class = Lock - - def __init__( - self, - rules: t.Optional[t.Iterable[RuleFactory]] = None, - default_subdomain: str = "", - charset: str = "utf-8", - strict_slashes: bool = True, - merge_slashes: bool = True, - redirect_defaults: bool = True, - converters: t.Optional[t.Mapping[str, t.Type[BaseConverter]]] = None, - sort_parameters: bool = False, - sort_key: t.Optional[t.Callable[[t.Any], t.Any]] = None, - encoding_errors: str = "replace", - host_matching: bool = False, - ) -> None: - self._rules: t.List[Rule] = [] - self._rules_by_endpoint: t.Dict[str, t.List[Rule]] = {} - self._remap = True - self._remap_lock = self.lock_class() - - self.default_subdomain = default_subdomain - self.charset = charset - self.encoding_errors = encoding_errors - self.strict_slashes = strict_slashes - self.merge_slashes = merge_slashes - self.redirect_defaults = redirect_defaults - self.host_matching = host_matching - - self.converters = self.default_converters.copy() - if converters: - self.converters.update(converters) - - self.sort_parameters = sort_parameters - self.sort_key = sort_key - - for rulefactory in rules or (): - self.add(rulefactory) - - def is_endpoint_expecting(self, endpoint: str, *arguments: str) -> bool: - """Iterate over all rules and check if the endpoint expects - the arguments provided. This is for example useful if you have - some URLs that expect a language code and others that do not and - you want to wrap the builder a bit so that the current language - code is automatically added if not provided but endpoints expect - it. - - :param endpoint: the endpoint to check. - :param arguments: this function accepts one or more arguments - as positional arguments. Each one of them is - checked. - """ - self.update() - arguments = set(arguments) - for rule in self._rules_by_endpoint[endpoint]: - if arguments.issubset(rule.arguments): - return True - return False - - def iter_rules(self, endpoint: t.Optional[str] = None) -> t.Iterator[Rule]: - """Iterate over all rules or the rules of an endpoint. - - :param endpoint: if provided only the rules for that endpoint - are returned. - :return: an iterator - """ - self.update() - if endpoint is not None: - return iter(self._rules_by_endpoint[endpoint]) - return iter(self._rules) - - def add(self, rulefactory: RuleFactory) -> None: - """Add a new rule or factory to the map and bind it. Requires that the - rule is not bound to another map. - - :param rulefactory: a :class:`Rule` or :class:`RuleFactory` - """ - for rule in rulefactory.get_rules(self): - rule.bind(self) - self._rules.append(rule) - self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule) - self._remap = True - - def bind( - self, - server_name: str, - script_name: t.Optional[str] = None, - subdomain: t.Optional[str] = None, - url_scheme: str = "http", - default_method: str = "GET", - path_info: t.Optional[str] = None, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - ) -> "MapAdapter": - """Return a new :class:`MapAdapter` with the details specified to the - call. Note that `script_name` will default to ``'/'`` if not further - specified or `None`. The `server_name` at least is a requirement - because the HTTP RFC requires absolute URLs for redirects and so all - redirect exceptions raised by Werkzeug will contain the full canonical - URL. - - If no path_info is passed to :meth:`match` it will use the default path - info passed to bind. While this doesn't really make sense for - manual bind calls, it's useful if you bind a map to a WSGI - environment which already contains the path info. - - `subdomain` will default to the `default_subdomain` for this map if - no defined. If there is no `default_subdomain` you cannot use the - subdomain feature. - - .. versionchanged:: 1.0 - If ``url_scheme`` is ``ws`` or ``wss``, only WebSocket rules - will match. - - .. versionchanged:: 0.15 - ``path_info`` defaults to ``'/'`` if ``None``. - - .. versionchanged:: 0.8 - ``query_args`` can be a string. - - .. versionchanged:: 0.7 - Added ``query_args``. - """ - server_name = server_name.lower() - if self.host_matching: - if subdomain is not None: - raise RuntimeError("host matching enabled and a subdomain was provided") - elif subdomain is None: - subdomain = self.default_subdomain - if script_name is None: - script_name = "/" - if path_info is None: - path_info = "/" - - try: - server_name = _encode_idna(server_name) # type: ignore - except UnicodeError as e: - raise BadHost() from e - - return MapAdapter( - self, - server_name, - script_name, - subdomain, - url_scheme, - path_info, - default_method, - query_args, - ) - - def bind_to_environ( - self, - environ: t.Union["WSGIEnvironment", "Request"], - server_name: t.Optional[str] = None, - subdomain: t.Optional[str] = None, - ) -> "MapAdapter": - """Like :meth:`bind` but you can pass it an WSGI environment and it - will fetch the information from that dictionary. Note that because of - limitations in the protocol there is no way to get the current - subdomain and real `server_name` from the environment. If you don't - provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or - `HTTP_HOST` if provided) as used `server_name` with disabled subdomain - feature. - - If `subdomain` is `None` but an environment and a server name is - provided it will calculate the current subdomain automatically. - Example: `server_name` is ``'example.com'`` and the `SERVER_NAME` - in the wsgi `environ` is ``'staging.dev.example.com'`` the calculated - subdomain will be ``'staging.dev'``. - - If the object passed as environ has an environ attribute, the value of - this attribute is used instead. This allows you to pass request - objects. Additionally `PATH_INFO` added as a default of the - :class:`MapAdapter` so that you don't have to pass the path info to - the match method. - - .. versionchanged:: 1.0.0 - If the passed server name specifies port 443, it will match - if the incoming scheme is ``https`` without a port. - - .. versionchanged:: 1.0.0 - A warning is shown when the passed server name does not - match the incoming WSGI server name. - - .. versionchanged:: 0.8 - This will no longer raise a ValueError when an unexpected server - name was passed. - - .. versionchanged:: 0.5 - previously this method accepted a bogus `calculate_subdomain` - parameter that did not have any effect. It was removed because - of that. - - :param environ: a WSGI environment. - :param server_name: an optional server name hint (see above). - :param subdomain: optionally the current subdomain (see above). - """ - env = _get_environ(environ) - wsgi_server_name = get_host(env).lower() - scheme = env["wsgi.url_scheme"] - upgrade = any( - v.strip() == "upgrade" - for v in env.get("HTTP_CONNECTION", "").lower().split(",") - ) - - if upgrade and env.get("HTTP_UPGRADE", "").lower() == "websocket": - scheme = "wss" if scheme == "https" else "ws" - - if server_name is None: - server_name = wsgi_server_name - else: - server_name = server_name.lower() - - # strip standard port to match get_host() - if scheme in {"http", "ws"} and server_name.endswith(":80"): - server_name = server_name[:-3] - elif scheme in {"https", "wss"} and server_name.endswith(":443"): - server_name = server_name[:-4] - - if subdomain is None and not self.host_matching: - cur_server_name = wsgi_server_name.split(".") - real_server_name = server_name.split(".") - offset = -len(real_server_name) - - if cur_server_name[offset:] != real_server_name: - # This can happen even with valid configs if the server was - # accessed directly by IP address under some situations. - # Instead of raising an exception like in Werkzeug 0.7 or - # earlier we go by an invalid subdomain which will result - # in a 404 error on matching. - warnings.warn( - f"Current server name {wsgi_server_name!r} doesn't match configured" - f" server name {server_name!r}", - stacklevel=2, - ) - subdomain = "" - else: - subdomain = ".".join(filter(None, cur_server_name[:offset])) - - def _get_wsgi_string(name: str) -> t.Optional[str]: - val = env.get(name) - if val is not None: - return _wsgi_decoding_dance(val, self.charset) - return None - - script_name = _get_wsgi_string("SCRIPT_NAME") - path_info = _get_wsgi_string("PATH_INFO") - query_args = _get_wsgi_string("QUERY_STRING") - return Map.bind( - self, - server_name, - script_name, - subdomain, - scheme, - env["REQUEST_METHOD"], - path_info, - query_args=query_args, - ) - - def update(self) -> None: - """Called before matching and building to keep the compiled rules - in the correct order after things changed. - """ - if not self._remap: - return - - with self._remap_lock: - if not self._remap: - return - - self._rules.sort(key=lambda x: x.match_compare_key()) - for rules in self._rules_by_endpoint.values(): - rules.sort(key=lambda x: x.build_compare_key()) - self._remap = False - - def __repr__(self) -> str: - rules = self.iter_rules() - return f"{type(self).__name__}({pformat(list(rules))})" - - -class MapAdapter: - - """Returned by :meth:`Map.bind` or :meth:`Map.bind_to_environ` and does - the URL matching and building based on runtime information. - """ - - def __init__( - self, - map: Map, - server_name: str, - script_name: str, - subdomain: t.Optional[str], - url_scheme: str, - path_info: str, - default_method: str, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - ): - self.map = map - self.server_name = _to_str(server_name) - script_name = _to_str(script_name) - if not script_name.endswith("/"): - script_name += "/" - self.script_name = script_name - self.subdomain = _to_str(subdomain) - self.url_scheme = _to_str(url_scheme) - self.path_info = _to_str(path_info) - self.default_method = _to_str(default_method) - self.query_args = query_args - self.websocket = self.url_scheme in {"ws", "wss"} - - def dispatch( - self, - view_func: t.Callable[[str, t.Mapping[str, t.Any]], "WSGIApplication"], - path_info: t.Optional[str] = None, - method: t.Optional[str] = None, - catch_http_exceptions: bool = False, - ) -> "WSGIApplication": - """Does the complete dispatching process. `view_func` is called with - the endpoint and a dict with the values for the view. It should - look up the view function, call it, and return a response object - or WSGI application. http exceptions are not caught by default - so that applications can display nicer error messages by just - catching them by hand. If you want to stick with the default - error messages you can pass it ``catch_http_exceptions=True`` and - it will catch the http exceptions. - - Here a small example for the dispatch usage:: - - from werkzeug.wrappers import Request, Response - from werkzeug.wsgi import responder - from werkzeug.routing import Map, Rule - - def on_index(request): - return Response('Hello from the index') - - url_map = Map([Rule('/', endpoint='index')]) - views = {'index': on_index} - - @responder - def application(environ, start_response): - request = Request(environ) - urls = url_map.bind_to_environ(environ) - return urls.dispatch(lambda e, v: views[e](request, **v), - catch_http_exceptions=True) - - Keep in mind that this method might return exception objects, too, so - use :class:`Response.force_type` to get a response object. - - :param view_func: a function that is called with the endpoint as - first argument and the value dict as second. Has - to dispatch to the actual view function with this - information. (see above) - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - :param catch_http_exceptions: set to `True` to catch any of the - werkzeug :class:`HTTPException`\\s. - """ - try: - try: - endpoint, args = self.match(path_info, method) - except RequestRedirect as e: - return e - return view_func(endpoint, args) - except HTTPException as e: - if catch_http_exceptions: - return e - raise - - @typing.overload - def match( # type: ignore - self, - path_info: t.Optional[str] = None, - method: t.Optional[str] = None, - return_rule: "te.Literal[False]" = False, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - websocket: t.Optional[bool] = None, - ) -> t.Tuple[str, t.Mapping[str, t.Any]]: - ... - - @typing.overload - def match( - self, - path_info: t.Optional[str] = None, - method: t.Optional[str] = None, - return_rule: "te.Literal[True]" = True, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - websocket: t.Optional[bool] = None, - ) -> t.Tuple[Rule, t.Mapping[str, t.Any]]: - ... - - def match( - self, - path_info: t.Optional[str] = None, - method: t.Optional[str] = None, - return_rule: bool = False, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - websocket: t.Optional[bool] = None, - ) -> t.Tuple[t.Union[str, Rule], t.Mapping[str, t.Any]]: - """The usage is simple: you just pass the match method the current - path info as well as the method (which defaults to `GET`). The - following things can then happen: - - - you receive a `NotFound` exception that indicates that no URL is - matching. A `NotFound` exception is also a WSGI application you - can call to get a default page not found page (happens to be the - same object as `werkzeug.exceptions.NotFound`) - - - you receive a `MethodNotAllowed` exception that indicates that there - is a match for this URL but not for the current request method. - This is useful for RESTful applications. - - - you receive a `RequestRedirect` exception with a `new_url` - attribute. This exception is used to notify you about a request - Werkzeug requests from your WSGI application. This is for example the - case if you request ``/foo`` although the correct URL is ``/foo/`` - You can use the `RequestRedirect` instance as response-like object - similar to all other subclasses of `HTTPException`. - - - you receive a ``WebsocketMismatch`` exception if the only - match is a WebSocket rule but the bind is an HTTP request, or - if the match is an HTTP rule but the bind is a WebSocket - request. - - - you get a tuple in the form ``(endpoint, arguments)`` if there is - a match (unless `return_rule` is True, in which case you get a tuple - in the form ``(rule, arguments)``) - - If the path info is not passed to the match method the default path - info of the map is used (defaults to the root URL if not defined - explicitly). - - All of the exceptions raised are subclasses of `HTTPException` so they - can be used as WSGI responses. They will all render generic error or - redirect pages. - - Here is a small example for matching: - - >>> m = Map([ - ... Rule('/', endpoint='index'), - ... Rule('/downloads/', endpoint='downloads/index'), - ... Rule('/downloads/', endpoint='downloads/show') - ... ]) - >>> urls = m.bind("example.com", "/") - >>> urls.match("/", "GET") - ('index', {}) - >>> urls.match("/downloads/42") - ('downloads/show', {'id': 42}) - - And here is what happens on redirect and missing URLs: - - >>> urls.match("/downloads") - Traceback (most recent call last): - ... - RequestRedirect: http://example.com/downloads/ - >>> urls.match("/missing") - Traceback (most recent call last): - ... - NotFound: 404 Not Found - - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - :param return_rule: return the rule that matched instead of just the - endpoint (defaults to `False`). - :param query_args: optional query arguments that are used for - automatic redirects as string or dictionary. It's - currently not possible to use the query arguments - for URL matching. - :param websocket: Match WebSocket instead of HTTP requests. A - websocket request has a ``ws`` or ``wss`` - :attr:`url_scheme`. This overrides that detection. - - .. versionadded:: 1.0 - Added ``websocket``. - - .. versionchanged:: 0.8 - ``query_args`` can be a string. - - .. versionadded:: 0.7 - Added ``query_args``. - - .. versionadded:: 0.6 - Added ``return_rule``. - """ - self.map.update() - if path_info is None: - path_info = self.path_info - else: - path_info = _to_str(path_info, self.map.charset) - if query_args is None: - query_args = self.query_args or {} - method = (method or self.default_method).upper() - - if websocket is None: - websocket = self.websocket - - require_redirect = False - - domain_part = self.server_name if self.map.host_matching else self.subdomain - path_part = f"/{path_info.lstrip('/')}" if path_info else "" - path = f"{domain_part}|{path_part}" - - have_match_for = set() - websocket_mismatch = False - - for rule in self.map._rules: - try: - rv = rule.match(path, method) - except RequestPath as e: - raise RequestRedirect( - self.make_redirect_url( - url_quote(e.path_info, self.map.charset, safe="/:|+"), - query_args, - ) - ) from None - except RequestAliasRedirect as e: - raise RequestRedirect( - self.make_alias_redirect_url( - path, rule.endpoint, e.matched_values, method, query_args - ) - ) from None - if rv is None: - continue - if rule.methods is not None and method not in rule.methods: - have_match_for.update(rule.methods) - continue - - if rule.websocket != websocket: - websocket_mismatch = True - continue - - if self.map.redirect_defaults: - redirect_url = self.get_default_redirect(rule, method, rv, query_args) - if redirect_url is not None: - raise RequestRedirect(redirect_url) - - if rule.redirect_to is not None: - if isinstance(rule.redirect_to, str): - - def _handle_match(match: t.Match[str]) -> str: - value = rv[match.group(1)] # type: ignore - return rule._converters[match.group(1)].to_url(value) - - redirect_url = _simple_rule_re.sub(_handle_match, rule.redirect_to) - else: - redirect_url = rule.redirect_to(self, **rv) - - if self.subdomain: - netloc = f"{self.subdomain}.{self.server_name}" - else: - netloc = self.server_name - - raise RequestRedirect( - url_join( - f"{self.url_scheme or 'http'}://{netloc}{self.script_name}", - redirect_url, - ) - ) - - if require_redirect: - raise RequestRedirect( - self.make_redirect_url( - url_quote(path_info, self.map.charset, safe="/:|+"), query_args - ) - ) - - if return_rule: - return rule, rv - else: - return rule.endpoint, rv - - if have_match_for: - raise MethodNotAllowed(valid_methods=list(have_match_for)) - - if websocket_mismatch: - raise WebsocketMismatch() - - raise NotFound() - - def test( - self, path_info: t.Optional[str] = None, method: t.Optional[str] = None - ) -> bool: - """Test if a rule would match. Works like `match` but returns `True` - if the URL matches, or `False` if it does not exist. - - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - """ - try: - self.match(path_info, method) - except RequestRedirect: - pass - except HTTPException: - return False - return True - - def allowed_methods(self, path_info: t.Optional[str] = None) -> t.Iterable[str]: - """Returns the valid methods that match for a given path. - - .. versionadded:: 0.7 - """ - try: - self.match(path_info, method="--") - except MethodNotAllowed as e: - return e.valid_methods # type: ignore - except HTTPException: - pass - return [] - - def get_host(self, domain_part: t.Optional[str]) -> str: - """Figures out the full host name for the given domain part. The - domain part is a subdomain in case host matching is disabled or - a full host name. - """ - if self.map.host_matching: - if domain_part is None: - return self.server_name - return _to_str(domain_part, "ascii") - subdomain = domain_part - if subdomain is None: - subdomain = self.subdomain - else: - subdomain = _to_str(subdomain, "ascii") - - if subdomain: - return f"{subdomain}.{self.server_name}" - else: - return self.server_name - - def get_default_redirect( - self, - rule: Rule, - method: str, - values: t.MutableMapping[str, t.Any], - query_args: t.Union[t.Mapping[str, t.Any], str], - ) -> t.Optional[str]: - """A helper that returns the URL to redirect to if it finds one. - This is used for default redirecting only. - - :internal: - """ - assert self.map.redirect_defaults - for r in self.map._rules_by_endpoint[rule.endpoint]: - # every rule that comes after this one, including ourself - # has a lower priority for the defaults. We order the ones - # with the highest priority up for building. - if r is rule: - break - if r.provides_defaults_for(rule) and r.suitable_for(values, method): - values.update(r.defaults) # type: ignore - domain_part, path = r.build(values) # type: ignore - return self.make_redirect_url(path, query_args, domain_part=domain_part) - return None - - def encode_query_args(self, query_args: t.Union[t.Mapping[str, t.Any], str]) -> str: - if not isinstance(query_args, str): - return url_encode(query_args, self.map.charset) - return query_args - - def make_redirect_url( - self, - path_info: str, - query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, - domain_part: t.Optional[str] = None, - ) -> str: - """Creates a redirect URL. - - :internal: - """ - if query_args: - suffix = f"?{self.encode_query_args(query_args)}" - else: - suffix = "" - - scheme = self.url_scheme or "http" - host = self.get_host(domain_part) - path = posixpath.join(self.script_name.strip("/"), path_info.lstrip("/")) - return f"{scheme}://{host}/{path}{suffix}" - - def make_alias_redirect_url( - self, - path: str, - endpoint: str, - values: t.Mapping[str, t.Any], - method: str, - query_args: t.Union[t.Mapping[str, t.Any], str], - ) -> str: - """Internally called to make an alias redirect URL.""" - url = self.build( - endpoint, values, method, append_unknown=False, force_external=True - ) - if query_args: - url += f"?{self.encode_query_args(query_args)}" - assert url != path, "detected invalid alias setting. No canonical URL found" - return url - - def _partial_build( - self, - endpoint: str, - values: t.Mapping[str, t.Any], - method: t.Optional[str], - append_unknown: bool, - ) -> t.Optional[t.Tuple[str, str, bool]]: - """Helper for :meth:`build`. Returns subdomain and path for the - rule that accepts this endpoint, values and method. - - :internal: - """ - # in case the method is none, try with the default method first - if method is None: - rv = self._partial_build( - endpoint, values, self.default_method, append_unknown - ) - if rv is not None: - return rv - - # Default method did not match or a specific method is passed. - # Check all for first match with matching host. If no matching - # host is found, go with first result. - first_match = None - - for rule in self.map._rules_by_endpoint.get(endpoint, ()): - if rule.suitable_for(values, method): - build_rv = rule.build(values, append_unknown) - - if build_rv is not None: - rv = (build_rv[0], build_rv[1], rule.websocket) - if self.map.host_matching: - if rv[0] == self.server_name: - return rv - elif first_match is None: - first_match = rv - else: - return rv - - return first_match - - def build( - self, - endpoint: str, - values: t.Optional[t.Mapping[str, t.Any]] = None, - method: t.Optional[str] = None, - force_external: bool = False, - append_unknown: bool = True, - url_scheme: t.Optional[str] = None, - ) -> str: - """Building URLs works pretty much the other way round. Instead of - `match` you call `build` and pass it the endpoint and a dict of - arguments for the placeholders. - - The `build` function also accepts an argument called `force_external` - which, if you set it to `True` will force external URLs. Per default - external URLs (include the server name) will only be used if the - target URL is on a different subdomain. - - >>> m = Map([ - ... Rule('/', endpoint='index'), - ... Rule('/downloads/', endpoint='downloads/index'), - ... Rule('/downloads/', endpoint='downloads/show') - ... ]) - >>> urls = m.bind("example.com", "/") - >>> urls.build("index", {}) - '/' - >>> urls.build("downloads/show", {'id': 42}) - '/downloads/42' - >>> urls.build("downloads/show", {'id': 42}, force_external=True) - 'http://example.com/downloads/42' - - Because URLs cannot contain non ASCII data you will always get - bytes back. Non ASCII characters are urlencoded with the - charset defined on the map instance. - - Additional values are converted to strings and appended to the URL as - URL querystring parameters: - - >>> urls.build("index", {'q': 'My Searchstring'}) - '/?q=My+Searchstring' - - When processing those additional values, lists are furthermore - interpreted as multiple values (as per - :py:class:`werkzeug.datastructures.MultiDict`): - - >>> urls.build("index", {'q': ['a', 'b', 'c']}) - '/?q=a&q=b&q=c' - - Passing a ``MultiDict`` will also add multiple values: - - >>> urls.build("index", MultiDict((('p', 'z'), ('q', 'a'), ('q', 'b')))) - '/?p=z&q=a&q=b' - - If a rule does not exist when building a `BuildError` exception is - raised. - - The build method accepts an argument called `method` which allows you - to specify the method you want to have an URL built for if you have - different methods for the same endpoint specified. - - :param endpoint: the endpoint of the URL to build. - :param values: the values for the URL to build. Unhandled values are - appended to the URL as query parameters. - :param method: the HTTP method for the rule if there are different - URLs for different methods on the same endpoint. - :param force_external: enforce full canonical external URLs. If the URL - scheme is not provided, this will generate - a protocol-relative URL. - :param append_unknown: unknown parameters are appended to the generated - URL as query string argument. Disable this - if you want the builder to ignore those. - :param url_scheme: Scheme to use in place of the bound - :attr:`url_scheme`. - - .. versionchanged:: 2.0 - Added the ``url_scheme`` parameter. - - .. versionadded:: 0.6 - Added the ``append_unknown`` parameter. - """ - self.map.update() - - if values: - temp_values: t.Dict[str, t.Union[t.List[t.Any], t.Any]] = {} - always_list = isinstance(values, MultiDict) - key: str - value: t.Optional[t.Union[t.List[t.Any], t.Any]] - - # For MultiDict, dict.items(values) is like values.lists() - # without the call or list coercion overhead. - for key, value in dict.items(values): # type: ignore - if value is None: - continue - - if always_list or isinstance(value, (list, tuple)): - value = [v for v in value if v is not None] - - if not value: - continue - - if len(value) == 1: - value = value[0] - - temp_values[key] = value - - values = temp_values - else: - values = {} - - rv = self._partial_build(endpoint, values, method, append_unknown) - if rv is None: - raise BuildError(endpoint, values, method, self) - - domain_part, path, websocket = rv - host = self.get_host(domain_part) - - if url_scheme is None: - url_scheme = self.url_scheme - - # Always build WebSocket routes with the scheme (browsers - # require full URLs). If bound to a WebSocket, ensure that HTTP - # routes are built with an HTTP scheme. - secure = url_scheme in {"https", "wss"} - - if websocket: - force_external = True - url_scheme = "wss" if secure else "ws" - elif url_scheme: - url_scheme = "https" if secure else "http" - - # shortcut this. - if not force_external and ( - (self.map.host_matching and host == self.server_name) - or (not self.map.host_matching and domain_part == self.subdomain) - ): - return f"{self.script_name.rstrip('/')}/{path.lstrip('/')}" - - scheme = f"{url_scheme}:" if url_scheme else "" - return f"{scheme}//{host}{self.script_name[:-1]}/{path.lstrip('/')}" diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/__init__.py b/venv/lib/python3.7/site-packages/werkzeug/sansio/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index a0002b1882d3b8b1c7edc745a16af3dcf8bf601a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmZ?b<>g`kg1OB0$sqbMh=2h`Aj1KOi&=m~3PUi1CZpde*Dua2 zN!2X?X-H2k)-O*j%C1T+P1i3@%qz~!*N>0S%*!l^kJl@xyv1RYo1apelWGUDz8HuZ E07T6)ga7~l diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-37.pyc deleted file mode 100644 index 96e7cd1bd056732f8778b775cc0cd4cb26339797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6536 zcma)ANpl;=6`mCs3>H!pMM~5*mPA`{OfiX_IFT2vuq|7H6p4ysc$o~*O%mW>0QWRx zku|JTOy_1->2AA<^eyMya?X!P=HN>zsdBEqquITrZbh z4ZknVE6w?Hn)Y|<41YF&t0?i7u4znTdZ;z1HA1~(Gz^_!Gc-F^!&0yX*lySgw!>T} z-^eRC2iR#i3eE#AGztoK0J{wraDlmDu~TZ46kG&cZj=>V3M-wl#+ZW3;dtjr@3#SXK$=Xvy=X3wDa40;!s z{y?i<{D$OKuj*-m1u|%cK^&uF1%272wifj})HZ`yQhU3lTIX(0wz^ReV$5FX_d@=S zfql>`__FISu1QYYl&`hKU&`XRw3-~X^5 zgc;_KnmCFrRQ27`{KFWe%`b|8g?ufXUkRG4fn4cE^UW3BT*<`CM5aiC4nXo5xy zG}@{4S}Ww@B$lMk5{?o#Hfxe}GQni-!{DP!XM=l*SIH^#9_bbrXUW)7T^} zbh?83nV|P`Q5?q%MO|twcDv!BZ1gba8I)Z%(#YY&eZSt-daba#+~YOuT3QT>UDjj;*1#JG);bD*m^$$PnSzv~m!%cW#OVzfj zbE?j(+8Mf>2QVmJuNL;xVPYp3=l$BXJJ)a5QtRHe`wOXc^V-6-)T!OOb^Gq?4{ND& zcosv+=uL z;r%^#-HFaCSTejT(;Frm=N4=ucLJ`3nO~U9V)iF?BhPaz_l3^#%=yG>IAlF)M&S#C zxvYq>0(aGn5-X!u#4aU9*a{m%zpNb9k#zjd&=KC`%`O7L`kyi&_5yFmNqQX~$MBJHQ2Za6Bw*jV7>Gy!xEiTJji=TY|GoYPJe4i`{<20f7F%!E)EE#1&3bT^l^>nHZB=B454sxB^JX_LGW z{YaD!%8n@4#uKfrZ9$aV`iB0t7M-y)X{@^9lCIHTnuOm3?j0>MexvQoH!$BAng7AQ z`9?NhT2KgMQ^orFw?u}k>N4W|kI{p&wIaqJr|z$Vu+M8kbVX_+ilt_!6~R4T#-v6b zNuBhgZ~!#Lh`&+nDrFP+M`0`CeJqJ7bJN>97 zzA2u)2_Qkvw(5v+rT$vtx zc~WnqzJP4vC)hO8f~y1(Uql%dbn3C>5d&GohK#m-ic%81$y<-Ip!$2viYW!r5Vjq| z)sGv_VRs%~v!ffdj)K0r=L&8uwG9|^8@FkjtAkpsvjNET@g(=fBNt^L6`LHa~`m5r5Y>=jK`5|f#qLDQb-(O-b2bKO#XY=EYy-5oT}dAM0`=u^58Drv9F>VQ=K* zQ8}69wvI8}Ytz`sD>#pxoW!9!f`U_WDsd7kK@j=O+<+wIwCWW;Gd76M<8)8ZO%hgp z&~1nuQL=S{kygx1Yuh@@?h}IYliQl5Z4@>Tf;NiLB4(UAa7SJIc`tWC$<{&sW_;Z! zpv8?hT%uxke0>5zd$$5#Rx6UmCVE0%c9%wr7nVqknu+?xgx5xhSFG-WvcihWNO0H)r%!9 zU%!2={+6$z%l%qf@v~>;-~l48&`Qdf1SLZ%t53~kE>)tg-WB2^5UI5U-ok#) zG2v0AJkEK7C}T|B7I+H!q9#|#WwoRnPHL-!CAB+&#BE3_ihqsbh)6K$u@u2B*MUVs zhGG=Iz|cej@u8^*lYddfq<|}QF9mq z$Sv-;MuyI^wqZyWHsQ=+CXe4t^etmsyQ#hZDqNenWo{!2T{XoF0w4kc^|x$>oOIiO z)3G*e7;7%EXgsm0UV`(~wGU_B)?^+5lgz@-0;cyZ@#H)GvZ$f0I_cCKwQDzP_x&4p z>kGH)53eoUx?A_5CT84UgqrojmZUHklU|8dPZY5XFpa0Vpw}ZcBWI7uvl~{(E>eru zDM_X_ECG+Bz0pS0G3#$ADqmM}QgS)2&*?wX*M-f$u9m>o)P4SC2o+ zGE);7vv>)RP)d7~Ao}hg9#TbwD>6n%Q$(uw|Brxu3q{fA*p}_;m9v%7WU+Eb5Uz=` z^D_ZmMTwt7HGD~Mlj+Pr_77Ph`==L$$!zpfNT zN#tI_$Z_oC^jG11B}kJ9f8qk%vmwp4g^+&%EoJpcXWF?3*&O8dOGxO%*TZ=<2c@uL zuI9wo1knmgj@s@ttY8|pf*@ofVCe1Araq;;sH_L)IoRh@;4FnJ4{;bVXwKu8Wd+s% zs@h|)tmj}kCc?Y9H4f{tVO?J(23DG%YYeu8I{&4$sng02zj_<#Mz%|Wj_$dEgG3IqrjfA8NmfV@yciOjwt*mq^FBuM2Wu_Xl`zWg z+?)zzWj7`_e@L9Vyc=I$^5}ETE9Yk8b1~`oOWyDkjv6~W1{#;WbpzX5STHwNcGt&m zWKn9F!+P;j@z#rYc6#d7a@ngM6TiYt6l6Q2OED|xxp<&T>@`;weJ2dot-ds*OD^wS5fEZoy~xDjz&pziBbDVOpy zf?lBNMXK(gYLs`Mu81At9YTneSdbVM Z8znbrt#K=7j=L6QS}`Zg%I~z3{{ygXmAe1{ diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/request.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/request.cpython-37.pyc deleted file mode 100644 index 9f4d367576dee4601ef0f9f03c1f6303286c3464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17118 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 IbL!Op1@gQ?IRF3v diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/sansio/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index 8b736b908f83aa2c607cd5e06fc3f24721c8dd76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3848 zcmcInO>Y~=8Q$4lu9h?iPTQ&w1|K}H7pw`1hnLeGZfcc z?$R?u+Z0wgRPM2tqBlE$T=dd^(ciJxo^)@eX9FLlS>j>jDI{nQ`Vc51d?OM~&! z&XVm1=!ZKYb7Wnz2Mt+YcjN`J^xPAns6X|0nqt*bmMw)nSO(Y1eCFc1GjP`(NL2Gy z8l$>sJgXyJP<45B6!yX+jd%O$2f(vb?l;Tv9j5f zSw9!Dn}{sNczIj)rz$bCUnrF;Of)d+n!KB+1f%*?rQL_q+{l(!hQnN&EFR0UY1C93 zDY|K*O&KU@rYh^x67($Lt>e9o*BY^KbV!>qPQeU2bk*g8?Xd&&jVs*eFs<;P`Umc; zS-6FB$PT=(o$QkD7;n^2UowY&B>!vY$)sRkIKLSl_=SJui`omOCWS8ovGjYG?!Xt} zK`rwIJE&P*K6C|Vbp7e9t|BPBk*oeJ!fmIhsXK*tR1@_gc*}v-J2d<7&ewL`R%8F4 zw}-Mn;>m!=oXo(-vFQ(`#*l2l^8ugRgp-AI)M#)#ok^_Xv6Z0d4!<{)mVuj`L%u(X z&hni#YlnY+qWV#sCZbYIf_CkQZ_;K+tyMwGX%j1>`QyY4K@z#)iNPpMD-j-}r>DCj zAIC|y*kcs&M^fn|&tf5@=ydpp(NC?)U$$ID&Q#>hK0`wfeSN&!cr`~OSmBHUIMq2q zU$`&eP&mUem_MW#^tWEJ&N0a;YFaKrMo-ejD36BBF7j7LEo1a@w|!q@JMCQ+i&W0i z_Au^`Vl&LMwl!EjHMf@?9J*nG|r5f$a>0VpM z8P3<9nk3cHWL7r1S+2$~>b|^;HFbc-VIf;}_unD!b`#y5`y%=@&HHhxZ$_swC5zMr zNNnBv2c0Ks1!W`Au&9Z%zAQa$R9V}d8L7+W{Vbt;v*}efDhH8&%1~xPQ?IpD8JTcL zT|~39vPiUUrNmQmu+!Aj!613kwa(wEW2&NBt5wYkgv*Ps9e{kNBQ#FkXTIBDfx8;G ztjSi;Yp@1-f$O`AnGif{EOga6BwDpH(6BmE{(@CIl(CQslTsmO%H>7C5>Z!SLZLxV z4KMX?-rg`Zt!|03AKhFI4oxvwDvZlz!nIy7~y%(=7aFu2}xoJ7mAZ zJVJFPeit!$*8&d2hf^?qc_lAk)gG7PThN!m8z1|s<^?Ej6 z6LU@T40$n`$W{ixzeRHiz>po$-F286>Y=VUjCk_<)i; z(N>8_1_P;}81%SeqM#J965MhxPBKxs$@_UaKf$jihVnm6XBz|t$zVnbNXy&;*wO;u zrik=CyIN;3&HA0{n5P-j<5-ZZIMI^F6`y{c7-1;wf;u{P{ov&D!;p>6LueI- z6@V@_Z?~u9!>NSj$zmHo%#q~1-qoQo6MYp{uQqTB!`&)`D@DEDmvApEUQKe~>{Ol; zseA$~76KmA7UyA;YC6J7*U3K{*0`-+Z-eK`u1IJM;sn68!ME~Ef@s5Nnk7%T&if;2 z5I)25H+4nmifBez$ zzd+ls(eC;FDn&hI#$u6{r{01-i$jWlq*YUI)5Q0v`93v2K!dd)|2hbUd(w1?@CjJ- z6*SJkz1g2p}UdhjaRrRWW@|qdMgdkY73)3xZhp16~>2f)?L}RH>q{_{kvb;0FC)P zqpAWUS;fe<i)1jZR}6wX2R$$5J_q zs+2VM_?KoPWN3dvo*ugEJMtPzatwsmHO#frP~B5#N?4yI#cWdB8e}!4AKJ z3m?dFg39p(1ynyK*e2_Z^J#{HoKG{{&vbFjF9b3U$hdAMs5iiXQ}=ol(63=5P0i62 zy~@{A)B^0tLGb{_hUCePUK2l?9CJ0eoM?03Q9>%O-nv?$2tcCUMtRs)l%y}&t^H=_ z{r7(Mqj!J!!L{qH4g3Z1bv%%$umYSIM^Kb>rT-vLGDSH@r6f{vQUQ*4y$M}qxCxnfH;_wj=s(pJ F_8;T>Jc9rL diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/multipart.py b/venv/lib/python3.7/site-packages/werkzeug/sansio/multipart.py deleted file mode 100644 index 2d54422..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/sansio/multipart.py +++ /dev/null @@ -1,260 +0,0 @@ -import re -from dataclasses import dataclass -from enum import auto -from enum import Enum -from typing import cast -from typing import List -from typing import Optional -from typing import Tuple - -from .._internal import _to_bytes -from .._internal import _to_str -from ..datastructures import Headers -from ..exceptions import RequestEntityTooLarge -from ..http import parse_options_header - - -class Event: - pass - - -@dataclass(frozen=True) -class Preamble(Event): - data: bytes - - -@dataclass(frozen=True) -class Field(Event): - name: str - headers: Headers - - -@dataclass(frozen=True) -class File(Event): - name: str - filename: str - headers: Headers - - -@dataclass(frozen=True) -class Data(Event): - data: bytes - more_data: bool - - -@dataclass(frozen=True) -class Epilogue(Event): - data: bytes - - -class NeedData(Event): - pass - - -NEED_DATA = NeedData() - - -class State(Enum): - PREAMBLE = auto() - PART = auto() - DATA = auto() - EPILOGUE = auto() - COMPLETE = auto() - - -# Multipart line breaks MUST be CRLF (\r\n) by RFC-7578, except that -# many implementations break this and either use CR or LF alone. -LINE_BREAK = b"(?:\r\n|\n|\r)" -BLANK_LINE_RE = re.compile(b"(?:\r\n\r\n|\r\r|\n\n)", re.MULTILINE) -LINE_BREAK_RE = re.compile(LINE_BREAK, re.MULTILINE) -# Header values can be continued via a space or tab after the linebreak, as -# per RFC2231 -HEADER_CONTINUATION_RE = re.compile(b"%s[ \t]" % LINE_BREAK, re.MULTILINE) - - -class MultipartDecoder: - """Decodes a multipart message as bytes into Python events. - - The part data is returned as available to allow the caller to save - the data from memory to disk, if desired. - """ - - def __init__( - self, - boundary: bytes, - max_form_memory_size: Optional[int] = None, - ) -> None: - self.buffer = bytearray() - self.complete = False - self.max_form_memory_size = max_form_memory_size - self.state = State.PREAMBLE - self.boundary = boundary - - # Note in the below \h i.e. horizontal whitespace is used - # as [^\S\n\r] as \h isn't supported in python. - - # The preamble must end with a boundary where the boundary is - # prefixed by a line break, RFC2046. Except that many - # implementations including Werkzeug's tests omit the line - # break prefix. In addition the first boundary could be the - # epilogue boundary (for empty form-data) hence the matching - # group to understand if it is an epilogue boundary. - self.preamble_re = re.compile( - rb"%s?--%s(--[^\S\n\r]*%s?|[^\S\n\r]*%s)" - % (LINE_BREAK, re.escape(boundary), LINE_BREAK, LINE_BREAK), - re.MULTILINE, - ) - # A boundary must include a line break prefix and suffix, and - # may include trailing whitespace. In addition the boundary - # could be the epilogue boundary hence the matching group to - # understand if it is an epilogue boundary. - self.boundary_re = re.compile( - rb"%s--%s(--[^\S\n\r]*%s?|[^\S\n\r]*%s)" - % (LINE_BREAK, re.escape(boundary), LINE_BREAK, LINE_BREAK), - re.MULTILINE, - ) - - def last_newline(self) -> int: - try: - last_nl = self.buffer.rindex(b"\n") - except ValueError: - last_nl = len(self.buffer) - try: - last_cr = self.buffer.rindex(b"\r") - except ValueError: - last_cr = len(self.buffer) - - return min(last_nl, last_cr) - - def receive_data(self, data: Optional[bytes]) -> None: - if data is None: - self.complete = True - elif ( - self.max_form_memory_size is not None - and len(self.buffer) + len(data) > self.max_form_memory_size - ): - raise RequestEntityTooLarge() - else: - self.buffer.extend(data) - - def next_event(self) -> Event: - event: Event = NEED_DATA - - if self.state == State.PREAMBLE: - match = self.preamble_re.search(self.buffer) - if match is not None: - if match.group(1).startswith(b"--"): - self.state = State.EPILOGUE - else: - self.state = State.PART - data = bytes(self.buffer[: match.start()]) - del self.buffer[: match.end()] - event = Preamble(data=data) - - elif self.state == State.PART: - match = BLANK_LINE_RE.search(self.buffer) - if match is not None: - headers = self._parse_headers(self.buffer[: match.start()]) - del self.buffer[: match.end()] - - if "content-disposition" not in headers: - raise ValueError("Missing Content-Disposition header") - - disposition, extra = parse_options_header( - headers["content-disposition"] - ) - name = cast(str, extra.get("name")) - filename = extra.get("filename") - if filename is not None: - event = File( - filename=filename, - headers=headers, - name=name, - ) - else: - event = Field( - headers=headers, - name=name, - ) - self.state = State.DATA - - elif self.state == State.DATA: - if self.buffer.find(b"--" + self.boundary) == -1: - # No complete boundary in the buffer, but there may be - # a partial boundary at the end. As the boundary - # starts with either a nl or cr find the earliest and - # return up to that as data. - data_length = del_index = self.last_newline() - more_data = True - else: - match = self.boundary_re.search(self.buffer) - if match is not None: - if match.group(1).startswith(b"--"): - self.state = State.EPILOGUE - else: - self.state = State.PART - data_length = match.start() - del_index = match.end() - else: - data_length = del_index = self.last_newline() - more_data = match is None - - data = bytes(self.buffer[:data_length]) - del self.buffer[:del_index] - if data or not more_data: - event = Data(data=data, more_data=more_data) - - elif self.state == State.EPILOGUE and self.complete: - event = Epilogue(data=bytes(self.buffer)) - del self.buffer[:] - self.state = State.COMPLETE - - if self.complete and isinstance(event, NeedData): - raise ValueError(f"Invalid form-data cannot parse beyond {self.state}") - - return event - - def _parse_headers(self, data: bytes) -> Headers: - headers: List[Tuple[str, str]] = [] - # Merge the continued headers into one line - data = HEADER_CONTINUATION_RE.sub(b" ", data) - # Now there is one header per line - for line in data.splitlines(): - if line.strip() != b"": - name, value = _to_str(line).strip().split(":", 1) - headers.append((name.strip(), value.strip())) - return Headers(headers) - - -class MultipartEncoder: - def __init__(self, boundary: bytes) -> None: - self.boundary = boundary - self.state = State.PREAMBLE - - def send_event(self, event: Event) -> bytes: - if isinstance(event, Preamble) and self.state == State.PREAMBLE: - self.state = State.PART - return event.data - elif isinstance(event, (Field, File)) and self.state in { - State.PREAMBLE, - State.PART, - State.DATA, - }: - self.state = State.DATA - data = b"\r\n--" + self.boundary + b"\r\n" - data += b'Content-Disposition: form-data; name="%s"' % _to_bytes(event.name) - if isinstance(event, File): - data += b'; filename="%s"' % _to_bytes(event.filename) - data += b"\r\n" - for name, value in cast(Field, event).headers: - if name.lower() != "content-disposition": - data += _to_bytes(f"{name}: {value}\r\n") - data += b"\r\n" - return data - elif isinstance(event, Data) and self.state == State.DATA: - return event.data - elif isinstance(event, Epilogue): - self.state = State.COMPLETE - return b"\r\n--" + self.boundary + b"--\r\n" + event.data - else: - raise ValueError(f"Cannot generate {event} in state: {self.state}") diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/request.py b/venv/lib/python3.7/site-packages/werkzeug/sansio/request.py deleted file mode 100644 index adafc26..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/sansio/request.py +++ /dev/null @@ -1,548 +0,0 @@ -import typing as t -from datetime import datetime - -from .._internal import _to_str -from ..datastructures import Accept -from ..datastructures import Authorization -from ..datastructures import CharsetAccept -from ..datastructures import ETags -from ..datastructures import Headers -from ..datastructures import HeaderSet -from ..datastructures import IfRange -from ..datastructures import ImmutableList -from ..datastructures import ImmutableMultiDict -from ..datastructures import LanguageAccept -from ..datastructures import MIMEAccept -from ..datastructures import MultiDict -from ..datastructures import Range -from ..datastructures import RequestCacheControl -from ..http import parse_accept_header -from ..http import parse_authorization_header -from ..http import parse_cache_control_header -from ..http import parse_cookie -from ..http import parse_date -from ..http import parse_etags -from ..http import parse_if_range_header -from ..http import parse_list_header -from ..http import parse_options_header -from ..http import parse_range_header -from ..http import parse_set_header -from ..urls import url_decode -from ..user_agent import UserAgent -from ..useragents import _UserAgent as _DeprecatedUserAgent -from ..utils import cached_property -from ..utils import header_property -from .utils import get_current_url -from .utils import get_host - - -class Request: - """Represents the non-IO parts of a HTTP request, including the - method, URL info, and headers. - - This class is not meant for general use. It should only be used when - implementing WSGI, ASGI, or another HTTP application spec. Werkzeug - provides a WSGI implementation at :cls:`werkzeug.wrappers.Request`. - - :param method: The method the request was made with, such as - ``GET``. - :param scheme: The URL scheme of the protocol the request used, such - as ``https`` or ``wss``. - :param server: The address of the server. ``(host, port)``, - ``(path, None)`` for unix sockets, or ``None`` if not known. - :param root_path: The prefix that the application is mounted under. - This is prepended to generated URLs, but is not part of route - matching. - :param path: The path part of the URL after ``root_path``. - :param query_string: The part of the URL after the "?". - :param headers: The headers received with the request. - :param remote_addr: The address of the client sending the request. - - .. versionadded:: 2.0 - """ - - #: The charset used to decode most data in the request. - charset = "utf-8" - - #: the error handling procedure for errors, defaults to 'replace' - encoding_errors = "replace" - - #: the class to use for `args` and `form`. The default is an - #: :class:`~werkzeug.datastructures.ImmutableMultiDict` which supports - #: multiple values per key. alternatively it makes sense to use an - #: :class:`~werkzeug.datastructures.ImmutableOrderedMultiDict` which - #: preserves order or a :class:`~werkzeug.datastructures.ImmutableDict` - #: which is the fastest but only remembers the last key. It is also - #: possible to use mutable structures, but this is not recommended. - #: - #: .. versionadded:: 0.6 - parameter_storage_class: t.Type[MultiDict] = ImmutableMultiDict - - #: The type to be used for dict values from the incoming WSGI - #: environment. (For example for :attr:`cookies`.) By default an - #: :class:`~werkzeug.datastructures.ImmutableMultiDict` is used. - #: - #: .. versionchanged:: 1.0.0 - #: Changed to ``ImmutableMultiDict`` to support multiple values. - #: - #: .. versionadded:: 0.6 - dict_storage_class: t.Type[MultiDict] = ImmutableMultiDict - - #: the type to be used for list values from the incoming WSGI environment. - #: By default an :class:`~werkzeug.datastructures.ImmutableList` is used - #: (for example for :attr:`access_list`). - #: - #: .. versionadded:: 0.6 - list_storage_class: t.Type[t.List] = ImmutableList - - user_agent_class: t.Type[UserAgent] = _DeprecatedUserAgent - """The class used and returned by the :attr:`user_agent` property to - parse the header. Defaults to - :class:`~werkzeug.user_agent.UserAgent`, which does no parsing. An - extension can provide a subclass that uses a parser to provide other - data. - - .. versionadded:: 2.0 - """ - - #: Valid host names when handling requests. By default all hosts are - #: trusted, which means that whatever the client says the host is - #: will be accepted. - #: - #: Because ``Host`` and ``X-Forwarded-Host`` headers can be set to - #: any value by a malicious client, it is recommended to either set - #: this property or implement similar validation in the proxy (if - #: the application is being run behind one). - #: - #: .. versionadded:: 0.9 - trusted_hosts: t.Optional[t.List[str]] = None - - def __init__( - self, - method: str, - scheme: str, - server: t.Optional[t.Tuple[str, t.Optional[int]]], - root_path: str, - path: str, - query_string: bytes, - headers: Headers, - remote_addr: t.Optional[str], - ) -> None: - #: The method the request was made with, such as ``GET``. - self.method = method.upper() - #: The URL scheme of the protocol the request used, such as - #: ``https`` or ``wss``. - self.scheme = scheme - #: The address of the server. ``(host, port)``, ``(path, None)`` - #: for unix sockets, or ``None`` if not known. - self.server = server - #: The prefix that the application is mounted under, without a - #: trailing slash. :attr:`path` comes after this. - self.root_path = root_path.rstrip("/") - #: The path part of the URL after :attr:`root_path`. This is the - #: path used for routing within the application. - self.path = "/" + path.lstrip("/") - #: The part of the URL after the "?". This is the raw value, use - #: :attr:`args` for the parsed values. - self.query_string = query_string - #: The headers received with the request. - self.headers = headers - #: The address of the client sending the request. - self.remote_addr = remote_addr - - def __repr__(self) -> str: - try: - url = self.url - except Exception as e: - url = f"(invalid URL: {e})" - - return f"<{type(self).__name__} {url!r} [{self.method}]>" - - @property - def url_charset(self) -> str: - """The charset that is assumed for URLs. Defaults to the value - of :attr:`charset`. - - .. versionadded:: 0.6 - """ - return self.charset - - @cached_property - def args(self) -> "MultiDict[str, str]": - """The parsed URL parameters (the part in the URL after the question - mark). - - By default an - :class:`~werkzeug.datastructures.ImmutableMultiDict` - is returned from this function. This can be changed by setting - :attr:`parameter_storage_class` to a different type. This might - be necessary if the order of the form data is important. - """ - return url_decode( - self.query_string, - self.url_charset, - errors=self.encoding_errors, - cls=self.parameter_storage_class, - ) - - @cached_property - def access_route(self) -> t.List[str]: - """If a forwarded header exists this is a list of all ip addresses - from the client ip to the last proxy server. - """ - if "X-Forwarded-For" in self.headers: - return self.list_storage_class( - parse_list_header(self.headers["X-Forwarded-For"]) - ) - elif self.remote_addr is not None: - return self.list_storage_class([self.remote_addr]) - return self.list_storage_class() - - @cached_property - def full_path(self) -> str: - """Requested path, including the query string.""" - return f"{self.path}?{_to_str(self.query_string, self.url_charset)}" - - @property - def is_secure(self) -> bool: - """``True`` if the request was made with a secure protocol - (HTTPS or WSS). - """ - return self.scheme in {"https", "wss"} - - @cached_property - def url(self) -> str: - """The full request URL with the scheme, host, root path, path, - and query string.""" - return get_current_url( - self.scheme, self.host, self.root_path, self.path, self.query_string - ) - - @cached_property - def base_url(self) -> str: - """Like :attr:`url` but without the query string.""" - return get_current_url(self.scheme, self.host, self.root_path, self.path) - - @cached_property - def root_url(self) -> str: - """The request URL scheme, host, and root path. This is the root - that the application is accessed from. - """ - return get_current_url(self.scheme, self.host, self.root_path) - - @cached_property - def host_url(self) -> str: - """The request URL scheme and host only.""" - return get_current_url(self.scheme, self.host) - - @cached_property - def host(self) -> str: - """The host name the request was made to, including the port if - it's non-standard. Validated with :attr:`trusted_hosts`. - """ - return get_host( - self.scheme, self.headers.get("host"), self.server, self.trusted_hosts - ) - - @cached_property - def cookies(self) -> "ImmutableMultiDict[str, str]": - """A :class:`dict` with the contents of all cookies transmitted with - the request.""" - wsgi_combined_cookie = ";".join(self.headers.getlist("Cookie")) - return parse_cookie( # type: ignore - wsgi_combined_cookie, - self.charset, - self.encoding_errors, - cls=self.dict_storage_class, - ) - - # Common Descriptors - - content_type = header_property[str]( - "Content-Type", - doc="""The Content-Type entity-header field indicates the media - type of the entity-body sent to the recipient or, in the case of - the HEAD method, the media type that would have been sent had - the request been a GET.""", - read_only=True, - ) - - @cached_property - def content_length(self) -> t.Optional[int]: - """The Content-Length entity-header field indicates the size of the - entity-body in bytes or, in the case of the HEAD method, the size of - the entity-body that would have been sent had the request been a - GET. - """ - if self.headers.get("Transfer-Encoding", "") == "chunked": - return None - - content_length = self.headers.get("Content-Length") - if content_length is not None: - try: - return max(0, int(content_length)) - except (ValueError, TypeError): - pass - - return None - - content_encoding = header_property[str]( - "Content-Encoding", - doc="""The Content-Encoding entity-header field is used as a - modifier to the media-type. When present, its value indicates - what additional content codings have been applied to the - entity-body, and thus what decoding mechanisms must be applied - in order to obtain the media-type referenced by the Content-Type - header field. - - .. versionadded:: 0.9""", - read_only=True, - ) - content_md5 = header_property[str]( - "Content-MD5", - doc="""The Content-MD5 entity-header field, as defined in - RFC 1864, is an MD5 digest of the entity-body for the purpose of - providing an end-to-end message integrity check (MIC) of the - entity-body. (Note: a MIC is good for detecting accidental - modification of the entity-body in transit, but is not proof - against malicious attacks.) - - .. versionadded:: 0.9""", - read_only=True, - ) - referrer = header_property[str]( - "Referer", - doc="""The Referer[sic] request-header field allows the client - to specify, for the server's benefit, the address (URI) of the - resource from which the Request-URI was obtained (the - "referrer", although the header field is misspelled).""", - read_only=True, - ) - date = header_property( - "Date", - None, - parse_date, - doc="""The Date general-header field represents the date and - time at which the message was originated, having the same - semantics as orig-date in RFC 822. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """, - read_only=True, - ) - max_forwards = header_property( - "Max-Forwards", - None, - int, - doc="""The Max-Forwards request-header field provides a - mechanism with the TRACE and OPTIONS methods to limit the number - of proxies or gateways that can forward the request to the next - inbound server.""", - read_only=True, - ) - - def _parse_content_type(self) -> None: - if not hasattr(self, "_parsed_content_type"): - self._parsed_content_type = parse_options_header( - self.headers.get("Content-Type", "") - ) - - @property - def mimetype(self) -> str: - """Like :attr:`content_type`, but without parameters (eg, without - charset, type etc.) and always lowercase. For example if the content - type is ``text/HTML; charset=utf-8`` the mimetype would be - ``'text/html'``. - """ - self._parse_content_type() - return self._parsed_content_type[0].lower() - - @property - def mimetype_params(self) -> t.Dict[str, str]: - """The mimetype parameters as dict. For example if the content - type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - """ - self._parse_content_type() - return self._parsed_content_type[1] - - @cached_property - def pragma(self) -> HeaderSet: - """The Pragma general-header field is used to include - implementation-specific directives that might apply to any recipient - along the request/response chain. All pragma directives specify - optional behavior from the viewpoint of the protocol; however, some - systems MAY require that behavior be consistent with the directives. - """ - return parse_set_header(self.headers.get("Pragma", "")) - - # Accept - - @cached_property - def accept_mimetypes(self) -> MIMEAccept: - """List of mimetypes this client supports as - :class:`~werkzeug.datastructures.MIMEAccept` object. - """ - return parse_accept_header(self.headers.get("Accept"), MIMEAccept) - - @cached_property - def accept_charsets(self) -> CharsetAccept: - """List of charsets this client supports as - :class:`~werkzeug.datastructures.CharsetAccept` object. - """ - return parse_accept_header(self.headers.get("Accept-Charset"), CharsetAccept) - - @cached_property - def accept_encodings(self) -> Accept: - """List of encodings this client accepts. Encodings in a HTTP term - are compression encodings such as gzip. For charsets have a look at - :attr:`accept_charset`. - """ - return parse_accept_header(self.headers.get("Accept-Encoding")) - - @cached_property - def accept_languages(self) -> LanguageAccept: - """List of languages this client accepts as - :class:`~werkzeug.datastructures.LanguageAccept` object. - - .. versionchanged 0.5 - In previous versions this was a regular - :class:`~werkzeug.datastructures.Accept` object. - """ - return parse_accept_header(self.headers.get("Accept-Language"), LanguageAccept) - - # ETag - - @cached_property - def cache_control(self) -> RequestCacheControl: - """A :class:`~werkzeug.datastructures.RequestCacheControl` object - for the incoming cache control headers. - """ - cache_control = self.headers.get("Cache-Control") - return parse_cache_control_header(cache_control, None, RequestCacheControl) - - @cached_property - def if_match(self) -> ETags: - """An object containing all the etags in the `If-Match` header. - - :rtype: :class:`~werkzeug.datastructures.ETags` - """ - return parse_etags(self.headers.get("If-Match")) - - @cached_property - def if_none_match(self) -> ETags: - """An object containing all the etags in the `If-None-Match` header. - - :rtype: :class:`~werkzeug.datastructures.ETags` - """ - return parse_etags(self.headers.get("If-None-Match")) - - @cached_property - def if_modified_since(self) -> t.Optional[datetime]: - """The parsed `If-Modified-Since` header as a datetime object. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """ - return parse_date(self.headers.get("If-Modified-Since")) - - @cached_property - def if_unmodified_since(self) -> t.Optional[datetime]: - """The parsed `If-Unmodified-Since` header as a datetime object. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """ - return parse_date(self.headers.get("If-Unmodified-Since")) - - @cached_property - def if_range(self) -> IfRange: - """The parsed ``If-Range`` header. - - .. versionchanged:: 2.0 - ``IfRange.date`` is timezone-aware. - - .. versionadded:: 0.7 - """ - return parse_if_range_header(self.headers.get("If-Range")) - - @cached_property - def range(self) -> t.Optional[Range]: - """The parsed `Range` header. - - .. versionadded:: 0.7 - - :rtype: :class:`~werkzeug.datastructures.Range` - """ - return parse_range_header(self.headers.get("Range")) - - # User Agent - - @cached_property - def user_agent(self) -> UserAgent: - """The user agent. Use ``user_agent.string`` to get the header - value. Set :attr:`user_agent_class` to a subclass of - :class:`~werkzeug.user_agent.UserAgent` to provide parsing for - the other properties or other extended data. - - .. versionchanged:: 2.0 - The built in parser is deprecated and will be removed in - Werkzeug 2.1. A ``UserAgent`` subclass must be set to parse - data from the string. - """ - return self.user_agent_class(self.headers.get("User-Agent", "")) - - # Authorization - - @cached_property - def authorization(self) -> t.Optional[Authorization]: - """The `Authorization` object in parsed form.""" - return parse_authorization_header(self.headers.get("Authorization")) - - # CORS - - origin = header_property[str]( - "Origin", - doc=( - "The host that the request originated from. Set" - " :attr:`~CORSResponseMixin.access_control_allow_origin` on" - " the response to indicate which origins are allowed." - ), - read_only=True, - ) - - access_control_request_headers = header_property( - "Access-Control-Request-Headers", - load_func=parse_set_header, - doc=( - "Sent with a preflight request to indicate which headers" - " will be sent with the cross origin request. Set" - " :attr:`~CORSResponseMixin.access_control_allow_headers`" - " on the response to indicate which headers are allowed." - ), - read_only=True, - ) - - access_control_request_method = header_property[str]( - "Access-Control-Request-Method", - doc=( - "Sent with a preflight request to indicate which method" - " will be used for the cross origin request. Set" - " :attr:`~CORSResponseMixin.access_control_allow_methods`" - " on the response to indicate which methods are allowed." - ), - read_only=True, - ) - - @property - def is_json(self) -> bool: - """Check if the mimetype indicates JSON data, either - :mimetype:`application/json` or :mimetype:`application/*+json`. - """ - mt = self.mimetype - return ( - mt == "application/json" - or mt.startswith("application/") - and mt.endswith("+json") - ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/response.py b/venv/lib/python3.7/site-packages/werkzeug/sansio/response.py deleted file mode 100644 index 82817e8..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/sansio/response.py +++ /dev/null @@ -1,704 +0,0 @@ -import typing as t -from datetime import datetime -from datetime import timedelta -from datetime import timezone -from http import HTTPStatus - -from .._internal import _to_str -from ..datastructures import Headers -from ..datastructures import HeaderSet -from ..http import dump_cookie -from ..http import HTTP_STATUS_CODES -from ..utils import get_content_type -from werkzeug.datastructures import CallbackDict -from werkzeug.datastructures import ContentRange -from werkzeug.datastructures import ContentSecurityPolicy -from werkzeug.datastructures import ResponseCacheControl -from werkzeug.datastructures import WWWAuthenticate -from werkzeug.http import COEP -from werkzeug.http import COOP -from werkzeug.http import dump_age -from werkzeug.http import dump_header -from werkzeug.http import dump_options_header -from werkzeug.http import http_date -from werkzeug.http import parse_age -from werkzeug.http import parse_cache_control_header -from werkzeug.http import parse_content_range_header -from werkzeug.http import parse_csp_header -from werkzeug.http import parse_date -from werkzeug.http import parse_options_header -from werkzeug.http import parse_set_header -from werkzeug.http import parse_www_authenticate_header -from werkzeug.http import quote_etag -from werkzeug.http import unquote_etag -from werkzeug.utils import header_property - - -def _set_property(name: str, doc: t.Optional[str] = None) -> property: - def fget(self: "Response") -> HeaderSet: - def on_update(header_set: HeaderSet) -> None: - if not header_set and name in self.headers: - del self.headers[name] - elif header_set: - self.headers[name] = header_set.to_header() - - return parse_set_header(self.headers.get(name), on_update) - - def fset( - self: "Response", - value: t.Optional[ - t.Union[str, t.Dict[str, t.Union[str, int]], t.Iterable[str]] - ], - ) -> None: - if not value: - del self.headers[name] - elif isinstance(value, str): - self.headers[name] = value - else: - self.headers[name] = dump_header(value) - - return property(fget, fset, doc=doc) - - -class Response: - """Represents the non-IO parts of an HTTP response, specifically the - status and headers but not the body. - - This class is not meant for general use. It should only be used when - implementing WSGI, ASGI, or another HTTP application spec. Werkzeug - provides a WSGI implementation at :cls:`werkzeug.wrappers.Response`. - - :param status: The status code for the response. Either an int, in - which case the default status message is added, or a string in - the form ``{code} {message}``, like ``404 Not Found``. Defaults - to 200. - :param headers: A :class:`~werkzeug.datastructures.Headers` object, - or a list of ``(key, value)`` tuples that will be converted to a - ``Headers`` object. - :param mimetype: The mime type (content type without charset or - other parameters) of the response. If the value starts with - ``text/`` (or matches some other special cases), the charset - will be added to create the ``content_type``. - :param content_type: The full content type of the response. - Overrides building the value from ``mimetype``. - - .. versionadded:: 2.0 - """ - - #: the charset of the response. - charset = "utf-8" - - #: the default status if none is provided. - default_status = 200 - - #: the default mimetype if none is provided. - default_mimetype = "text/plain" - - #: Warn if a cookie header exceeds this size. The default, 4093, should be - #: safely `supported by most browsers `_. A cookie larger than - #: this size will still be sent, but it may be ignored or handled - #: incorrectly by some browsers. Set to 0 to disable this check. - #: - #: .. versionadded:: 0.13 - #: - #: .. _`cookie`: http://browsercookielimits.squawky.net/ - max_cookie_size = 4093 - - # A :class:`Headers` object representing the response headers. - headers: Headers - - def __init__( - self, - status: t.Optional[t.Union[int, str, HTTPStatus]] = None, - headers: t.Optional[ - t.Union[ - t.Mapping[str, t.Union[str, int, t.Iterable[t.Union[str, int]]]], - t.Iterable[t.Tuple[str, t.Union[str, int]]], - ] - ] = None, - mimetype: t.Optional[str] = None, - content_type: t.Optional[str] = None, - ) -> None: - if isinstance(headers, Headers): - self.headers = headers - elif not headers: - self.headers = Headers() - else: - self.headers = Headers(headers) - - if content_type is None: - if mimetype is None and "content-type" not in self.headers: - mimetype = self.default_mimetype - if mimetype is not None: - mimetype = get_content_type(mimetype, self.charset) - content_type = mimetype - if content_type is not None: - self.headers["Content-Type"] = content_type - if status is None: - status = self.default_status - self.status = status # type: ignore - - def __repr__(self) -> str: - return f"<{type(self).__name__} [{self.status}]>" - - @property - def status_code(self) -> int: - """The HTTP status code as a number.""" - return self._status_code - - @status_code.setter - def status_code(self, code: int) -> None: - self.status = code # type: ignore - - @property - def status(self) -> str: - """The HTTP status code as a string.""" - return self._status - - @status.setter - def status(self, value: t.Union[str, int, HTTPStatus]) -> None: - if not isinstance(value, (str, bytes, int, HTTPStatus)): - raise TypeError("Invalid status argument") - - self._status, self._status_code = self._clean_status(value) - - def _clean_status(self, value: t.Union[str, int, HTTPStatus]) -> t.Tuple[str, int]: - if isinstance(value, HTTPStatus): - value = int(value) - status = _to_str(value, self.charset) - split_status = status.split(None, 1) - - if len(split_status) == 0: - raise ValueError("Empty status argument") - - if len(split_status) > 1: - if split_status[0].isdigit(): - # code and message - return status, int(split_status[0]) - - # multi-word message - return f"0 {status}", 0 - - if split_status[0].isdigit(): - # code only - status_code = int(split_status[0]) - - try: - status = f"{status_code} {HTTP_STATUS_CODES[status_code].upper()}" - except KeyError: - status = f"{status_code} UNKNOWN" - - return status, status_code - - # one-word message - return f"0 {status}", 0 - - def set_cookie( - self, - key: str, - value: str = "", - max_age: t.Optional[t.Union[timedelta, int]] = None, - expires: t.Optional[t.Union[str, datetime, int, float]] = None, - path: t.Optional[str] = "/", - domain: t.Optional[str] = None, - secure: bool = False, - httponly: bool = False, - samesite: t.Optional[str] = None, - ) -> None: - """Sets a cookie. - - A warning is raised if the size of the cookie header exceeds - :attr:`max_cookie_size`, but the header will still be set. - - :param key: the key (name) of the cookie to be set. - :param value: the value of the cookie. - :param max_age: should be a number of seconds, or `None` (default) if - the cookie should last only as long as the client's - browser session. - :param expires: should be a `datetime` object or UNIX timestamp. - :param path: limits the cookie to a given path, per default it will - span the whole domain. - :param domain: if you want to set a cross-domain cookie. For example, - ``domain=".example.com"`` will set a cookie that is - readable by the domain ``www.example.com``, - ``foo.example.com`` etc. Otherwise, a cookie will only - be readable by the domain that set it. - :param secure: If ``True``, the cookie will only be available - via HTTPS. - :param httponly: Disallow JavaScript access to the cookie. - :param samesite: Limit the scope of the cookie to only be - attached to requests that are "same-site". - """ - self.headers.add( - "Set-Cookie", - dump_cookie( - key, - value=value, - max_age=max_age, - expires=expires, - path=path, - domain=domain, - secure=secure, - httponly=httponly, - charset=self.charset, - max_size=self.max_cookie_size, - samesite=samesite, - ), - ) - - def delete_cookie( - self, - key: str, - path: str = "/", - domain: t.Optional[str] = None, - secure: bool = False, - httponly: bool = False, - samesite: t.Optional[str] = None, - ) -> None: - """Delete a cookie. Fails silently if key doesn't exist. - - :param key: the key (name) of the cookie to be deleted. - :param path: if the cookie that should be deleted was limited to a - path, the path has to be defined here. - :param domain: if the cookie that should be deleted was limited to a - domain, that domain has to be defined here. - :param secure: If ``True``, the cookie will only be available - via HTTPS. - :param httponly: Disallow JavaScript access to the cookie. - :param samesite: Limit the scope of the cookie to only be - attached to requests that are "same-site". - """ - self.set_cookie( - key, - expires=0, - max_age=0, - path=path, - domain=domain, - secure=secure, - httponly=httponly, - samesite=samesite, - ) - - @property - def is_json(self) -> bool: - """Check if the mimetype indicates JSON data, either - :mimetype:`application/json` or :mimetype:`application/*+json`. - """ - mt = self.mimetype - return mt is not None and ( - mt == "application/json" - or mt.startswith("application/") - and mt.endswith("+json") - ) - - # Common Descriptors - - @property - def mimetype(self) -> t.Optional[str]: - """The mimetype (content type without charset etc.)""" - ct = self.headers.get("content-type") - - if ct: - return ct.split(";")[0].strip() - else: - return None - - @mimetype.setter - def mimetype(self, value: str) -> None: - self.headers["Content-Type"] = get_content_type(value, self.charset) - - @property - def mimetype_params(self) -> t.Dict[str, str]: - """The mimetype parameters as dict. For example if the - content type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - - .. versionadded:: 0.5 - """ - - def on_update(d: CallbackDict) -> None: - self.headers["Content-Type"] = dump_options_header(self.mimetype, d) - - d = parse_options_header(self.headers.get("content-type", ""))[1] - return CallbackDict(d, on_update) - - location = header_property[str]( - "Location", - doc="""The Location response-header field is used to redirect - the recipient to a location other than the Request-URI for - completion of the request or identification of a new - resource.""", - ) - age = header_property( - "Age", - None, - parse_age, - dump_age, # type: ignore - doc="""The Age response-header field conveys the sender's - estimate of the amount of time since the response (or its - revalidation) was generated at the origin server. - - Age values are non-negative decimal integers, representing time - in seconds.""", - ) - content_type = header_property[str]( - "Content-Type", - doc="""The Content-Type entity-header field indicates the media - type of the entity-body sent to the recipient or, in the case of - the HEAD method, the media type that would have been sent had - the request been a GET.""", - ) - content_length = header_property( - "Content-Length", - None, - int, - str, - doc="""The Content-Length entity-header field indicates the size - of the entity-body, in decimal number of OCTETs, sent to the - recipient or, in the case of the HEAD method, the size of the - entity-body that would have been sent had the request been a - GET.""", - ) - content_location = header_property[str]( - "Content-Location", - doc="""The Content-Location entity-header field MAY be used to - supply the resource location for the entity enclosed in the - message when that entity is accessible from a location separate - from the requested resource's URI.""", - ) - content_encoding = header_property[str]( - "Content-Encoding", - doc="""The Content-Encoding entity-header field is used as a - modifier to the media-type. When present, its value indicates - what additional content codings have been applied to the - entity-body, and thus what decoding mechanisms must be applied - in order to obtain the media-type referenced by the Content-Type - header field.""", - ) - content_md5 = header_property[str]( - "Content-MD5", - doc="""The Content-MD5 entity-header field, as defined in - RFC 1864, is an MD5 digest of the entity-body for the purpose of - providing an end-to-end message integrity check (MIC) of the - entity-body. (Note: a MIC is good for detecting accidental - modification of the entity-body in transit, but is not proof - against malicious attacks.)""", - ) - date = header_property( - "Date", - None, - parse_date, - http_date, - doc="""The Date general-header field represents the date and - time at which the message was originated, having the same - semantics as orig-date in RFC 822. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """, - ) - expires = header_property( - "Expires", - None, - parse_date, - http_date, - doc="""The Expires entity-header field gives the date/time after - which the response is considered stale. A stale cache entry may - not normally be returned by a cache. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """, - ) - last_modified = header_property( - "Last-Modified", - None, - parse_date, - http_date, - doc="""The Last-Modified entity-header field indicates the date - and time at which the origin server believes the variant was - last modified. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """, - ) - - @property - def retry_after(self) -> t.Optional[datetime]: - """The Retry-After response-header field can be used with a - 503 (Service Unavailable) response to indicate how long the - service is expected to be unavailable to the requesting client. - - Time in seconds until expiration or date. - - .. versionchanged:: 2.0 - The datetime object is timezone-aware. - """ - value = self.headers.get("retry-after") - if value is None: - return None - elif value.isdigit(): - return datetime.now(timezone.utc) + timedelta(seconds=int(value)) - return parse_date(value) - - @retry_after.setter - def retry_after(self, value: t.Optional[t.Union[datetime, int, str]]) -> None: - if value is None: - if "retry-after" in self.headers: - del self.headers["retry-after"] - return - elif isinstance(value, datetime): - value = http_date(value) - else: - value = str(value) - self.headers["Retry-After"] = value - - vary = _set_property( - "Vary", - doc="""The Vary field value indicates the set of request-header - fields that fully determines, while the response is fresh, - whether a cache is permitted to use the response to reply to a - subsequent request without revalidation.""", - ) - content_language = _set_property( - "Content-Language", - doc="""The Content-Language entity-header field describes the - natural language(s) of the intended audience for the enclosed - entity. Note that this might not be equivalent to all the - languages used within the entity-body.""", - ) - allow = _set_property( - "Allow", - doc="""The Allow entity-header field lists the set of methods - supported by the resource identified by the Request-URI. The - purpose of this field is strictly to inform the recipient of - valid methods associated with the resource. An Allow header - field MUST be present in a 405 (Method Not Allowed) - response.""", - ) - - # ETag - - @property - def cache_control(self) -> ResponseCacheControl: - """The Cache-Control general-header field is used to specify - directives that MUST be obeyed by all caching mechanisms along the - request/response chain. - """ - - def on_update(cache_control: ResponseCacheControl) -> None: - if not cache_control and "cache-control" in self.headers: - del self.headers["cache-control"] - elif cache_control: - self.headers["Cache-Control"] = cache_control.to_header() - - return parse_cache_control_header( - self.headers.get("cache-control"), on_update, ResponseCacheControl - ) - - def set_etag(self, etag: str, weak: bool = False) -> None: - """Set the etag, and override the old one if there was one.""" - self.headers["ETag"] = quote_etag(etag, weak) - - def get_etag(self) -> t.Union[t.Tuple[str, bool], t.Tuple[None, None]]: - """Return a tuple in the form ``(etag, is_weak)``. If there is no - ETag the return value is ``(None, None)``. - """ - return unquote_etag(self.headers.get("ETag")) - - accept_ranges = header_property[str]( - "Accept-Ranges", - doc="""The `Accept-Ranges` header. Even though the name would - indicate that multiple values are supported, it must be one - string token only. - - The values ``'bytes'`` and ``'none'`` are common. - - .. versionadded:: 0.7""", - ) - - @property - def content_range(self) -> ContentRange: - """The ``Content-Range`` header as a - :class:`~werkzeug.datastructures.ContentRange` object. Available - even if the header is not set. - - .. versionadded:: 0.7 - """ - - def on_update(rng: ContentRange) -> None: - if not rng: - del self.headers["content-range"] - else: - self.headers["Content-Range"] = rng.to_header() - - rv = parse_content_range_header(self.headers.get("content-range"), on_update) - # always provide a content range object to make the descriptor - # more user friendly. It provides an unset() method that can be - # used to remove the header quickly. - if rv is None: - rv = ContentRange(None, None, None, on_update=on_update) - return rv - - @content_range.setter - def content_range(self, value: t.Optional[t.Union[ContentRange, str]]) -> None: - if not value: - del self.headers["content-range"] - elif isinstance(value, str): - self.headers["Content-Range"] = value - else: - self.headers["Content-Range"] = value.to_header() - - # Authorization - - @property - def www_authenticate(self) -> WWWAuthenticate: - """The ``WWW-Authenticate`` header in a parsed form.""" - - def on_update(www_auth: WWWAuthenticate) -> None: - if not www_auth and "www-authenticate" in self.headers: - del self.headers["www-authenticate"] - elif www_auth: - self.headers["WWW-Authenticate"] = www_auth.to_header() - - header = self.headers.get("www-authenticate") - return parse_www_authenticate_header(header, on_update) - - # CSP - - @property - def content_security_policy(self) -> ContentSecurityPolicy: - """The ``Content-Security-Policy`` header as a - :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available - even if the header is not set. - - The Content-Security-Policy header adds an additional layer of - security to help detect and mitigate certain types of attacks. - """ - - def on_update(csp: ContentSecurityPolicy) -> None: - if not csp: - del self.headers["content-security-policy"] - else: - self.headers["Content-Security-Policy"] = csp.to_header() - - rv = parse_csp_header(self.headers.get("content-security-policy"), on_update) - if rv is None: - rv = ContentSecurityPolicy(None, on_update=on_update) - return rv - - @content_security_policy.setter - def content_security_policy( - self, value: t.Optional[t.Union[ContentSecurityPolicy, str]] - ) -> None: - if not value: - del self.headers["content-security-policy"] - elif isinstance(value, str): - self.headers["Content-Security-Policy"] = value - else: - self.headers["Content-Security-Policy"] = value.to_header() - - @property - def content_security_policy_report_only(self) -> ContentSecurityPolicy: - """The ``Content-Security-policy-report-only`` header as a - :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available - even if the header is not set. - - The Content-Security-Policy-Report-Only header adds a csp policy - that is not enforced but is reported thereby helping detect - certain types of attacks. - """ - - def on_update(csp: ContentSecurityPolicy) -> None: - if not csp: - del self.headers["content-security-policy-report-only"] - else: - self.headers["Content-Security-policy-report-only"] = csp.to_header() - - rv = parse_csp_header( - self.headers.get("content-security-policy-report-only"), on_update - ) - if rv is None: - rv = ContentSecurityPolicy(None, on_update=on_update) - return rv - - @content_security_policy_report_only.setter - def content_security_policy_report_only( - self, value: t.Optional[t.Union[ContentSecurityPolicy, str]] - ) -> None: - if not value: - del self.headers["content-security-policy-report-only"] - elif isinstance(value, str): - self.headers["Content-Security-policy-report-only"] = value - else: - self.headers["Content-Security-policy-report-only"] = value.to_header() - - # CORS - - @property - def access_control_allow_credentials(self) -> bool: - """Whether credentials can be shared by the browser to - JavaScript code. As part of the preflight request it indicates - whether credentials can be used on the cross origin request. - """ - return "Access-Control-Allow-Credentials" in self.headers - - @access_control_allow_credentials.setter - def access_control_allow_credentials(self, value: t.Optional[bool]) -> None: - if value is True: - self.headers["Access-Control-Allow-Credentials"] = "true" - else: - self.headers.pop("Access-Control-Allow-Credentials", None) - - access_control_allow_headers = header_property( - "Access-Control-Allow-Headers", - load_func=parse_set_header, - dump_func=dump_header, - doc="Which headers can be sent with the cross origin request.", - ) - - access_control_allow_methods = header_property( - "Access-Control-Allow-Methods", - load_func=parse_set_header, - dump_func=dump_header, - doc="Which methods can be used for the cross origin request.", - ) - - access_control_allow_origin = header_property[str]( - "Access-Control-Allow-Origin", - doc="The origin or '*' for any origin that may make cross origin requests.", - ) - - access_control_expose_headers = header_property( - "Access-Control-Expose-Headers", - load_func=parse_set_header, - dump_func=dump_header, - doc="Which headers can be shared by the browser to JavaScript code.", - ) - - access_control_max_age = header_property( - "Access-Control-Max-Age", - load_func=int, - dump_func=str, - doc="The maximum age in seconds the access control settings can be cached for.", - ) - - cross_origin_opener_policy = header_property[COOP]( - "Cross-Origin-Opener-Policy", - load_func=lambda value: COOP(value), - dump_func=lambda value: value.value, - default=COOP.UNSAFE_NONE, - doc="""Allows control over sharing of browsing context group with cross-origin - documents. Values must be a member of the :class:`werkzeug.http.COOP` enum.""", - ) - - cross_origin_embedder_policy = header_property[COEP]( - "Cross-Origin-Embedder-Policy", - load_func=lambda value: COEP(value), - dump_func=lambda value: value.value, - default=COEP.UNSAFE_NONE, - doc="""Prevents a document from loading any cross-origin resources that do not - explicitly grant the document permission. Values must be a member of the - :class:`werkzeug.http.COEP` enum.""", - ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/sansio/utils.py b/venv/lib/python3.7/site-packages/werkzeug/sansio/utils.py deleted file mode 100644 index 1b4d892..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/sansio/utils.py +++ /dev/null @@ -1,142 +0,0 @@ -import typing as t - -from .._internal import _encode_idna -from ..exceptions import SecurityError -from ..urls import uri_to_iri -from ..urls import url_quote - - -def host_is_trusted(hostname: str, trusted_list: t.Iterable[str]) -> bool: - """Check if a host matches a list of trusted names. - - :param hostname: The name to check. - :param trusted_list: A list of valid names to match. If a name - starts with a dot it will match all subdomains. - - .. versionadded:: 0.9 - """ - if not hostname: - return False - - if isinstance(trusted_list, str): - trusted_list = [trusted_list] - - def _normalize(hostname: str) -> bytes: - if ":" in hostname: - hostname = hostname.rsplit(":", 1)[0] - - return _encode_idna(hostname) - - try: - hostname_bytes = _normalize(hostname) - except UnicodeError: - return False - - for ref in trusted_list: - if ref.startswith("."): - ref = ref[1:] - suffix_match = True - else: - suffix_match = False - - try: - ref_bytes = _normalize(ref) - except UnicodeError: - return False - - if ref_bytes == hostname_bytes: - return True - - if suffix_match and hostname_bytes.endswith(b"." + ref_bytes): - return True - - return False - - -def get_host( - scheme: str, - host_header: t.Optional[str], - server: t.Optional[t.Tuple[str, t.Optional[int]]] = None, - trusted_hosts: t.Optional[t.Iterable[str]] = None, -) -> str: - """Return the host for the given parameters. - - This first checks the ``host_header``. If it's not present, then - ``server`` is used. The host will only contain the port if it is - different than the standard port for the protocol. - - Optionally, verify that the host is trusted using - :func:`host_is_trusted` and raise a - :exc:`~werkzeug.exceptions.SecurityError` if it is not. - - :param scheme: The protocol the request used, like ``"https"``. - :param host_header: The ``Host`` header value. - :param server: Address of the server. ``(host, port)``, or - ``(path, None)`` for unix sockets. - :param trusted_hosts: A list of trusted host names. - - :return: Host, with port if necessary. - :raise ~werkzeug.exceptions.SecurityError: If the host is not - trusted. - """ - host = "" - - if host_header is not None: - host = host_header - elif server is not None: - host = server[0] - - if server[1] is not None: - host = f"{host}:{server[1]}" - - if scheme in {"http", "ws"} and host.endswith(":80"): - host = host[:-3] - elif scheme in {"https", "wss"} and host.endswith(":443"): - host = host[:-4] - - if trusted_hosts is not None: - if not host_is_trusted(host, trusted_hosts): - raise SecurityError(f"Host {host!r} is not trusted.") - - return host - - -def get_current_url( - scheme: str, - host: str, - root_path: t.Optional[str] = None, - path: t.Optional[str] = None, - query_string: t.Optional[bytes] = None, -) -> str: - """Recreate the URL for a request. If an optional part isn't - provided, it and subsequent parts are not included in the URL. - - The URL is an IRI, not a URI, so it may contain Unicode characters. - Use :func:`~werkzeug.urls.iri_to_uri` to convert it to ASCII. - - :param scheme: The protocol the request used, like ``"https"``. - :param host: The host the request was made to. See :func:`get_host`. - :param root_path: Prefix that the application is mounted under. This - is prepended to ``path``. - :param path: The path part of the URL after ``root_path``. - :param query_string: The portion of the URL after the "?". - """ - url = [scheme, "://", host] - - if root_path is None: - url.append("/") - return uri_to_iri("".join(url)) - - url.append(url_quote(root_path.rstrip("/"))) - url.append("/") - - if path is None: - return uri_to_iri("".join(url)) - - url.append(url_quote(path.lstrip("/"))) - - if query_string: - url.append("?") - url.append(url_quote(query_string, safe=":&%=+$!*'(),")) - - return uri_to_iri("".join(url)) diff --git a/venv/lib/python3.7/site-packages/werkzeug/security.py b/venv/lib/python3.7/site-packages/werkzeug/security.py deleted file mode 100644 index e23040a..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/security.py +++ /dev/null @@ -1,247 +0,0 @@ -import hashlib -import hmac -import os -import posixpath -import secrets -import typing as t -import warnings - -if t.TYPE_CHECKING: - pass - -SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" -DEFAULT_PBKDF2_ITERATIONS = 260000 - -_os_alt_seps: t.List[str] = list( - sep for sep in [os.path.sep, os.path.altsep] if sep is not None and sep != "/" -) - - -def pbkdf2_hex( - data: t.Union[str, bytes], - salt: t.Union[str, bytes], - iterations: int = DEFAULT_PBKDF2_ITERATIONS, - keylen: t.Optional[int] = None, - hashfunc: t.Optional[t.Union[str, t.Callable]] = None, -) -> str: - """Like :func:`pbkdf2_bin`, but returns a hex-encoded string. - - :param data: the data to derive. - :param salt: the salt for the derivation. - :param iterations: the number of iterations. - :param keylen: the length of the resulting key. If not provided, - the digest size will be used. - :param hashfunc: the hash function to use. This can either be the - string name of a known hash function, or a function - from the hashlib module. Defaults to sha256. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :func:`hashlib.pbkdf2_hmac` - instead. - - .. versionadded:: 0.9 - """ - warnings.warn( - "'pbkdf2_hex' is deprecated and will be removed in Werkzeug" - " 2.1. Use 'hashlib.pbkdf2_hmac().hex()' instead.", - DeprecationWarning, - stacklevel=2, - ) - return pbkdf2_bin(data, salt, iterations, keylen, hashfunc).hex() - - -def pbkdf2_bin( - data: t.Union[str, bytes], - salt: t.Union[str, bytes], - iterations: int = DEFAULT_PBKDF2_ITERATIONS, - keylen: t.Optional[int] = None, - hashfunc: t.Optional[t.Union[str, t.Callable]] = None, -) -> bytes: - """Returns a binary digest for the PBKDF2 hash algorithm of `data` - with the given `salt`. It iterates `iterations` times and produces a - key of `keylen` bytes. By default, SHA-256 is used as hash function; - a different hashlib `hashfunc` can be provided. - - :param data: the data to derive. - :param salt: the salt for the derivation. - :param iterations: the number of iterations. - :param keylen: the length of the resulting key. If not provided - the digest size will be used. - :param hashfunc: the hash function to use. This can either be the - string name of a known hash function or a function - from the hashlib module. Defaults to sha256. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :func:`hashlib.pbkdf2_hmac` - instead. - - .. versionadded:: 0.9 - """ - warnings.warn( - "'pbkdf2_bin' is deprecated and will be removed in Werkzeug" - " 2.1. Use 'hashlib.pbkdf2_hmac()' instead.", - DeprecationWarning, - stacklevel=2, - ) - - if isinstance(data, str): - data = data.encode("utf8") - - if isinstance(salt, str): - salt = salt.encode("utf8") - - if not hashfunc: - hash_name = "sha256" - elif callable(hashfunc): - hash_name = hashfunc().name - else: - hash_name = hashfunc - - return hashlib.pbkdf2_hmac(hash_name, data, salt, iterations, keylen) - - -def safe_str_cmp(a: str, b: str) -> bool: - """This function compares strings in somewhat constant time. This - requires that the length of at least one string is known in advance. - - Returns `True` if the two strings are equal, or `False` if they are not. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use - :func:`hmac.compare_digest` instead. - - .. versionadded:: 0.7 - """ - warnings.warn( - "'safe_str_cmp' is deprecated and will be removed in Werkzeug" - " 2.1. Use 'hmac.compare_digest' instead.", - DeprecationWarning, - stacklevel=2, - ) - - if isinstance(a, str): - a = a.encode("utf-8") # type: ignore - - if isinstance(b, str): - b = b.encode("utf-8") # type: ignore - - return hmac.compare_digest(a, b) - - -def gen_salt(length: int) -> str: - """Generate a random string of SALT_CHARS with specified ``length``.""" - if length <= 0: - raise ValueError("Salt length must be positive") - - return "".join(secrets.choice(SALT_CHARS) for _ in range(length)) - - -def _hash_internal(method: str, salt: str, password: str) -> t.Tuple[str, str]: - """Internal password hash helper. Supports plaintext without salt, - unsalted and salted passwords. In case salted passwords are used - hmac is used. - """ - if method == "plain": - return password, method - - salt = salt.encode("utf-8") - password = password.encode("utf-8") - - if method.startswith("pbkdf2:"): - if not salt: - raise ValueError("Salt is required for PBKDF2") - - args = method[7:].split(":") - - if len(args) not in (1, 2): - raise ValueError("Invalid number of arguments for PBKDF2") - - method = args.pop(0) - iterations = int(args[0] or 0) if args else DEFAULT_PBKDF2_ITERATIONS - return ( - hashlib.pbkdf2_hmac(method, password, salt, iterations).hex(), - f"pbkdf2:{method}:{iterations}", - ) - - if salt: - return hmac.new(salt, password, method).hexdigest(), method - - return hashlib.new(method, password).hexdigest(), method - - -def generate_password_hash( - password: str, method: str = "pbkdf2:sha256", salt_length: int = 16 -) -> str: - """Hash a password with the given method and salt with a string of - the given length. The format of the string returned includes the method - that was used so that :func:`check_password_hash` can check the hash. - - The format for the hashed string looks like this:: - - method$salt$hash - - This method can **not** generate unsalted passwords but it is possible - to set param method='plain' in order to enforce plaintext passwords. - If a salt is used, hmac is used internally to salt the password. - - If PBKDF2 is wanted it can be enabled by setting the method to - ``pbkdf2:method:iterations`` where iterations is optional:: - - pbkdf2:sha256:80000$salt$hash - pbkdf2:sha256$salt$hash - - :param password: the password to hash. - :param method: the hash method to use (one that hashlib supports). Can - optionally be in the format ``pbkdf2:method:iterations`` - to enable PBKDF2. - :param salt_length: the length of the salt in letters. - """ - salt = gen_salt(salt_length) if method != "plain" else "" - h, actual_method = _hash_internal(method, salt, password) - return f"{actual_method}${salt}${h}" - - -def check_password_hash(pwhash: str, password: str) -> bool: - """Check a password against a given salted and hashed password value. - In order to support unsalted legacy passwords this method supports - plain text passwords, md5 and sha1 hashes (both salted and unsalted). - - Returns `True` if the password matched, `False` otherwise. - - :param pwhash: a hashed string like returned by - :func:`generate_password_hash`. - :param password: the plaintext password to compare against the hash. - """ - if pwhash.count("$") < 2: - return False - - method, salt, hashval = pwhash.split("$", 2) - return hmac.compare_digest(_hash_internal(method, salt, password)[0], hashval) - - -def safe_join(directory: str, *pathnames: str) -> t.Optional[str]: - """Safely join zero or more untrusted path components to a base - directory to avoid escaping the base directory. - - :param directory: The trusted base directory. - :param pathnames: The untrusted path components relative to the - base directory. - :return: A safe path, otherwise ``None``. - """ - parts = [directory] - - for filename in pathnames: - if filename != "": - filename = posixpath.normpath(filename) - - if ( - any(sep in filename for sep in _os_alt_seps) - or os.path.isabs(filename) - or filename == ".." - or filename.startswith("../") - ): - return None - - parts.append(filename) - - return posixpath.join(*parts) diff --git a/venv/lib/python3.7/site-packages/werkzeug/serving.py b/venv/lib/python3.7/site-packages/werkzeug/serving.py deleted file mode 100644 index 80e4192..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/serving.py +++ /dev/null @@ -1,1088 +0,0 @@ -"""A WSGI and HTTP server for use **during development only**. This -server is convenient to use, but is not designed to be particularly -stable, secure, or efficient. Use a dedicate WSGI server and HTTP -server when deploying to production. - -It provides features like interactive debugging and code reloading. Use -``run_simple`` to start the server. Put this in a ``run.py`` script: - -.. code-block:: python - - from myapp import create_app - from werkzeug import run_simple -""" -import io -import os -import platform -import signal -import socket -import socketserver -import sys -import typing as t -import warnings -from datetime import datetime as dt -from datetime import timedelta -from datetime import timezone -from http.server import BaseHTTPRequestHandler -from http.server import HTTPServer - -from ._internal import _log -from ._internal import _wsgi_encoding_dance -from .exceptions import InternalServerError -from .urls import uri_to_iri -from .urls import url_parse -from .urls import url_unquote - -try: - import ssl -except ImportError: - - class _SslDummy: - def __getattr__(self, name: str) -> t.Any: - raise RuntimeError( # noqa: B904 - "SSL is unavailable because this Python runtime was not" - " compiled with SSL/TLS support." - ) - - ssl = _SslDummy() # type: ignore - -_log_add_style = True - -if os.name == "nt": - try: - __import__("colorama") - except ImportError: - _log_add_style = False - -can_fork = hasattr(os, "fork") - -if can_fork: - ForkingMixIn = socketserver.ForkingMixIn -else: - - class ForkingMixIn: # type: ignore - pass - - -try: - af_unix = socket.AF_UNIX -except AttributeError: - af_unix = None # type: ignore - -LISTEN_QUEUE = 128 -can_open_by_fd = not platform.system() == "Windows" and hasattr(socket, "fromfd") - -_TSSLContextArg = t.Optional[ - t.Union["ssl.SSLContext", t.Tuple[str, t.Optional[str]], "te.Literal['adhoc']"] -] - -if t.TYPE_CHECKING: - import typing_extensions as te # noqa: F401 - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - from cryptography.hazmat.primitives.asymmetric.rsa import ( - RSAPrivateKeyWithSerialization, - ) - from cryptography.x509 import Certificate - - -class DechunkedInput(io.RawIOBase): - """An input stream that handles Transfer-Encoding 'chunked'""" - - def __init__(self, rfile: t.IO[bytes]) -> None: - self._rfile = rfile - self._done = False - self._len = 0 - - def readable(self) -> bool: - return True - - def read_chunk_len(self) -> int: - try: - line = self._rfile.readline().decode("latin1") - _len = int(line.strip(), 16) - except ValueError as e: - raise OSError("Invalid chunk header") from e - if _len < 0: - raise OSError("Negative chunk length not allowed") - return _len - - def readinto(self, buf: bytearray) -> int: # type: ignore - read = 0 - while not self._done and read < len(buf): - if self._len == 0: - # This is the first chunk or we fully consumed the previous - # one. Read the next length of the next chunk - self._len = self.read_chunk_len() - - if self._len == 0: - # Found the final chunk of size 0. The stream is now exhausted, - # but there is still a final newline that should be consumed - self._done = True - - if self._len > 0: - # There is data (left) in this chunk, so append it to the - # buffer. If this operation fully consumes the chunk, this will - # reset self._len to 0. - n = min(len(buf), self._len) - - # If (read + chunk size) becomes more than len(buf), buf will - # grow beyond the original size and read more data than - # required. So only read as much data as can fit in buf. - if read + n > len(buf): - buf[read:] = self._rfile.read(len(buf) - read) - self._len -= len(buf) - read - read = len(buf) - else: - buf[read : read + n] = self._rfile.read(n) - self._len -= n - read += n - - if self._len == 0: - # Skip the terminating newline of a chunk that has been fully - # consumed. This also applies to the 0-sized final chunk - terminator = self._rfile.readline() - if terminator not in (b"\n", b"\r\n", b"\r"): - raise OSError("Missing chunk terminating newline") - - return read - - -class WSGIRequestHandler(BaseHTTPRequestHandler): - """A request handler that implements WSGI dispatching.""" - - server: "BaseWSGIServer" - - @property - def server_version(self) -> str: # type: ignore - from . import __version__ - - return f"Werkzeug/{__version__}" - - def make_environ(self) -> "WSGIEnvironment": - request_url = url_parse(self.path) - - def shutdown_server() -> None: - warnings.warn( - "The 'environ['werkzeug.server.shutdown']' function is" - " deprecated and will be removed in Werkzeug 2.1.", - stacklevel=2, - ) - self.server.shutdown_signal = True - - url_scheme = "http" if self.server.ssl_context is None else "https" - - if not self.client_address: - self.client_address = ("", 0) - elif isinstance(self.client_address, str): - self.client_address = (self.client_address, 0) - - # If there was no scheme but the path started with two slashes, - # the first segment may have been incorrectly parsed as the - # netloc, prepend it to the path again. - if not request_url.scheme and request_url.netloc: - path_info = f"/{request_url.netloc}{request_url.path}" - else: - path_info = request_url.path - - path_info = url_unquote(path_info) - - environ: "WSGIEnvironment" = { - "wsgi.version": (1, 0), - "wsgi.url_scheme": url_scheme, - "wsgi.input": self.rfile, - "wsgi.errors": sys.stderr, - "wsgi.multithread": self.server.multithread, - "wsgi.multiprocess": self.server.multiprocess, - "wsgi.run_once": False, - "werkzeug.server.shutdown": shutdown_server, - "werkzeug.socket": self.connection, - "SERVER_SOFTWARE": self.server_version, - "REQUEST_METHOD": self.command, - "SCRIPT_NAME": "", - "PATH_INFO": _wsgi_encoding_dance(path_info), - "QUERY_STRING": _wsgi_encoding_dance(request_url.query), - # Non-standard, added by mod_wsgi, uWSGI - "REQUEST_URI": _wsgi_encoding_dance(self.path), - # Non-standard, added by gunicorn - "RAW_URI": _wsgi_encoding_dance(self.path), - "REMOTE_ADDR": self.address_string(), - "REMOTE_PORT": self.port_integer(), - "SERVER_NAME": self.server.server_address[0], - "SERVER_PORT": str(self.server.server_address[1]), - "SERVER_PROTOCOL": self.request_version, - } - - for key, value in self.headers.items(): - key = key.upper().replace("-", "_") - value = value.replace("\r\n", "") - if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): - key = f"HTTP_{key}" - if key in environ: - value = f"{environ[key]},{value}" - environ[key] = value - - if environ.get("HTTP_TRANSFER_ENCODING", "").strip().lower() == "chunked": - environ["wsgi.input_terminated"] = True - environ["wsgi.input"] = DechunkedInput(environ["wsgi.input"]) - - # Per RFC 2616, if the URL is absolute, use that as the host. - # We're using "has a scheme" to indicate an absolute URL. - if request_url.scheme and request_url.netloc: - environ["HTTP_HOST"] = request_url.netloc - - try: - # binary_form=False gives nicer information, but wouldn't be compatible with - # what Nginx or Apache could return. - peer_cert = self.connection.getpeercert( # type: ignore[attr-defined] - binary_form=True - ) - if peer_cert is not None: - # Nginx and Apache use PEM format. - environ["SSL_CLIENT_CERT"] = ssl.DER_cert_to_PEM_cert(peer_cert) - except ValueError: - # SSL handshake hasn't finished. - self.server.log("error", "Cannot fetch SSL peer certificate info") - except AttributeError: - # Not using TLS, the socket will not have getpeercert(). - pass - - return environ - - def run_wsgi(self) -> None: - if self.headers.get("Expect", "").lower().strip() == "100-continue": - self.wfile.write(b"HTTP/1.1 100 Continue\r\n\r\n") - - self.environ = environ = self.make_environ() - status_set: t.Optional[str] = None - headers_set: t.Optional[t.List[t.Tuple[str, str]]] = None - status_sent: t.Optional[str] = None - headers_sent: t.Optional[t.List[t.Tuple[str, str]]] = None - - def write(data: bytes) -> None: - nonlocal status_sent, headers_sent - assert status_set is not None, "write() before start_response" - assert headers_set is not None, "write() before start_response" - if status_sent is None: - status_sent = status_set - headers_sent = headers_set - try: - code_str, msg = status_sent.split(None, 1) - except ValueError: - code_str, msg = status_sent, "" - code = int(code_str) - self.send_response(code, msg) - header_keys = set() - for key, value in headers_sent: - self.send_header(key, value) - key = key.lower() - header_keys.add(key) - if not ( - "content-length" in header_keys - or environ["REQUEST_METHOD"] == "HEAD" - or code < 200 - or code in (204, 304) - ): - self.close_connection = True - self.send_header("Connection", "close") - if "server" not in header_keys: - self.send_header("Server", self.version_string()) - if "date" not in header_keys: - self.send_header("Date", self.date_time_string()) - self.end_headers() - - assert isinstance(data, bytes), "applications must write bytes" - self.wfile.write(data) - self.wfile.flush() - - def start_response(status, headers, exc_info=None): # type: ignore - nonlocal status_set, headers_set - if exc_info: - try: - if headers_sent: - raise exc_info[1].with_traceback(exc_info[2]) - finally: - exc_info = None - elif headers_set: - raise AssertionError("Headers already set") - status_set = status - headers_set = headers - return write - - def execute(app: "WSGIApplication") -> None: - application_iter = app(environ, start_response) - try: - for data in application_iter: - write(data) - if not headers_sent: - write(b"") - finally: - if hasattr(application_iter, "close"): - application_iter.close() # type: ignore - - try: - execute(self.server.app) - except (ConnectionError, socket.timeout) as e: - self.connection_dropped(e, environ) - except Exception: - if self.server.passthrough_errors: - raise - from .debug.tbtools import get_current_traceback - - traceback = get_current_traceback(ignore_system_exceptions=True) - try: - # if we haven't yet sent the headers but they are set - # we roll back to be able to set them again. - if status_sent is None: - status_set = None - headers_set = None - execute(InternalServerError()) - except Exception: - pass - self.server.log("error", "Error on request:\n%s", traceback.plaintext) - - def handle(self) -> None: - """Handles a request ignoring dropped connections.""" - try: - BaseHTTPRequestHandler.handle(self) - except (ConnectionError, socket.timeout) as e: - self.connection_dropped(e) - except Exception as e: - if self.server.ssl_context is not None and is_ssl_error(e): - self.log_error("SSL error occurred: %s", e) - else: - raise - if self.server.shutdown_signal: - self.initiate_shutdown() - - def initiate_shutdown(self) -> None: - if is_running_from_reloader(): - # Windows does not provide SIGKILL, go with SIGTERM then. - sig = getattr(signal, "SIGKILL", signal.SIGTERM) - os.kill(os.getpid(), sig) - - self.server._BaseServer__shutdown_request = True # type: ignore - - def connection_dropped( - self, error: BaseException, environ: t.Optional["WSGIEnvironment"] = None - ) -> None: - """Called if the connection was closed by the client. By default - nothing happens. - """ - - def handle_one_request(self) -> None: - """Handle a single HTTP request.""" - self.raw_requestline = self.rfile.readline() - if not self.raw_requestline: - self.close_connection = True - elif self.parse_request(): - self.run_wsgi() - - def send_response(self, code: int, message: t.Optional[str] = None) -> None: - """Send the response header and log the response code.""" - self.log_request(code) - if message is None: - message = self.responses[code][0] if code in self.responses else "" - if self.request_version != "HTTP/0.9": - hdr = f"{self.protocol_version} {code} {message}\r\n" - self.wfile.write(hdr.encode("ascii")) - - def version_string(self) -> str: - return super().version_string().strip() - - def address_string(self) -> str: - if getattr(self, "environ", None): - return self.environ["REMOTE_ADDR"] # type: ignore - - if not self.client_address: - return "" - - return self.client_address[0] - - def port_integer(self) -> int: - return self.client_address[1] - - def log_request( - self, code: t.Union[int, str] = "-", size: t.Union[int, str] = "-" - ) -> None: - try: - path = uri_to_iri(self.path) - msg = f"{self.command} {path} {self.request_version}" - except AttributeError: - # path isn't set if the requestline was bad - msg = self.requestline - - code = str(code) - - if _log_add_style: - if code[0] == "1": # 1xx - Informational - msg = _ansi_style(msg, "bold") - elif code == "200": # 2xx - Success - pass - elif code == "304": # 304 - Resource Not Modified - msg = _ansi_style(msg, "cyan") - elif code[0] == "3": # 3xx - Redirection - msg = _ansi_style(msg, "green") - elif code == "404": # 404 - Resource Not Found - msg = _ansi_style(msg, "yellow") - elif code[0] == "4": # 4xx - Client Error - msg = _ansi_style(msg, "bold", "red") - else: # 5xx, or any other response - msg = _ansi_style(msg, "bold", "magenta") - - self.log("info", '"%s" %s %s', msg, code, size) - - def log_error(self, format: str, *args: t.Any) -> None: - self.log("error", format, *args) - - def log_message(self, format: str, *args: t.Any) -> None: - self.log("info", format, *args) - - def log(self, type: str, message: str, *args: t.Any) -> None: - _log( - type, - f"{self.address_string()} - - [{self.log_date_time_string()}] {message}\n", - *args, - ) - - -def _ansi_style(value: str, *styles: str) -> str: - codes = { - "bold": 1, - "red": 31, - "green": 32, - "yellow": 33, - "magenta": 35, - "cyan": 36, - } - - for style in styles: - value = f"\x1b[{codes[style]}m{value}" - - return f"{value}\x1b[0m" - - -def generate_adhoc_ssl_pair( - cn: t.Optional[str] = None, -) -> t.Tuple["Certificate", "RSAPrivateKeyWithSerialization"]: - try: - from cryptography import x509 - from cryptography.x509.oid import NameOID - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives import hashes - from cryptography.hazmat.primitives.asymmetric import rsa - except ImportError: - raise TypeError( - "Using ad-hoc certificates requires the cryptography library." - ) from None - - backend = default_backend() - pkey = rsa.generate_private_key( - public_exponent=65537, key_size=2048, backend=backend - ) - - # pretty damn sure that this is not actually accepted by anyone - if cn is None: - cn = "*" - - subject = x509.Name( - [ - x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Dummy Certificate"), - x509.NameAttribute(NameOID.COMMON_NAME, cn), - ] - ) - - backend = default_backend() - cert = ( - x509.CertificateBuilder() - .subject_name(subject) - .issuer_name(subject) - .public_key(pkey.public_key()) - .serial_number(x509.random_serial_number()) - .not_valid_before(dt.now(timezone.utc)) - .not_valid_after(dt.now(timezone.utc) + timedelta(days=365)) - .add_extension(x509.ExtendedKeyUsage([x509.OID_SERVER_AUTH]), critical=False) - .add_extension(x509.SubjectAlternativeName([x509.DNSName(cn)]), critical=False) - .sign(pkey, hashes.SHA256(), backend) - ) - return cert, pkey - - -def make_ssl_devcert( - base_path: str, host: t.Optional[str] = None, cn: t.Optional[str] = None -) -> t.Tuple[str, str]: - """Creates an SSL key for development. This should be used instead of - the ``'adhoc'`` key which generates a new cert on each server start. - It accepts a path for where it should store the key and cert and - either a host or CN. If a host is given it will use the CN - ``*.host/CN=host``. - - For more information see :func:`run_simple`. - - .. versionadded:: 0.9 - - :param base_path: the path to the certificate and key. The extension - ``.crt`` is added for the certificate, ``.key`` is - added for the key. - :param host: the name of the host. This can be used as an alternative - for the `cn`. - :param cn: the `CN` to use. - """ - - if host is not None: - cn = f"*.{host}/CN={host}" - cert, pkey = generate_adhoc_ssl_pair(cn=cn) - - from cryptography.hazmat.primitives import serialization - - cert_file = f"{base_path}.crt" - pkey_file = f"{base_path}.key" - - with open(cert_file, "wb") as f: - f.write(cert.public_bytes(serialization.Encoding.PEM)) - with open(pkey_file, "wb") as f: - f.write( - pkey.private_bytes( - encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.TraditionalOpenSSL, - encryption_algorithm=serialization.NoEncryption(), - ) - ) - - return cert_file, pkey_file - - -def generate_adhoc_ssl_context() -> "ssl.SSLContext": - """Generates an adhoc SSL context for the development server.""" - import tempfile - import atexit - - cert, pkey = generate_adhoc_ssl_pair() - - from cryptography.hazmat.primitives import serialization - - cert_handle, cert_file = tempfile.mkstemp() - pkey_handle, pkey_file = tempfile.mkstemp() - atexit.register(os.remove, pkey_file) - atexit.register(os.remove, cert_file) - - os.write(cert_handle, cert.public_bytes(serialization.Encoding.PEM)) - os.write( - pkey_handle, - pkey.private_bytes( - encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.TraditionalOpenSSL, - encryption_algorithm=serialization.NoEncryption(), - ), - ) - - os.close(cert_handle) - os.close(pkey_handle) - ctx = load_ssl_context(cert_file, pkey_file) - return ctx - - -def load_ssl_context( - cert_file: str, pkey_file: t.Optional[str] = None, protocol: t.Optional[int] = None -) -> "ssl.SSLContext": - """Loads SSL context from cert/private key files and optional protocol. - Many parameters are directly taken from the API of - :py:class:`ssl.SSLContext`. - - :param cert_file: Path of the certificate to use. - :param pkey_file: Path of the private key to use. If not given, the key - will be obtained from the certificate file. - :param protocol: A ``PROTOCOL`` constant from the :mod:`ssl` module. - Defaults to :data:`ssl.PROTOCOL_TLS_SERVER`. - """ - if protocol is None: - protocol = ssl.PROTOCOL_TLS_SERVER - - ctx = ssl.SSLContext(protocol) - ctx.load_cert_chain(cert_file, pkey_file) - return ctx - - -def is_ssl_error(error: t.Optional[Exception] = None) -> bool: - """Checks if the given error (or the current one) is an SSL error.""" - if error is None: - error = t.cast(Exception, sys.exc_info()[1]) - return isinstance(error, ssl.SSLError) - - -def select_address_family(host: str, port: int) -> socket.AddressFamily: - """Return ``AF_INET4``, ``AF_INET6``, or ``AF_UNIX`` depending on - the host and port.""" - if host.startswith("unix://"): - return socket.AF_UNIX - elif ":" in host and hasattr(socket, "AF_INET6"): - return socket.AF_INET6 - return socket.AF_INET - - -def get_sockaddr( - host: str, port: int, family: socket.AddressFamily -) -> t.Union[t.Tuple[str, int], str]: - """Return a fully qualified socket address that can be passed to - :func:`socket.bind`.""" - if family == af_unix: - return host.split("://", 1)[1] - try: - res = socket.getaddrinfo( - host, port, family, socket.SOCK_STREAM, socket.IPPROTO_TCP - ) - except socket.gaierror: - return host, port - return res[0][4] # type: ignore - - -def get_interface_ip(family: socket.AddressFamily) -> str: - """Get the IP address of an external interface. Used when binding to - 0.0.0.0 or ::1 to show a more useful URL. - - :meta private: - """ - # arbitrary private address - host = "fd31:f903:5ab5:1::1" if family == socket.AF_INET6 else "10.253.155.219" - - with socket.socket(family, socket.SOCK_DGRAM) as s: - try: - s.connect((host, 58162)) - except OSError: - return "::1" if family == socket.AF_INET6 else "127.0.0.1" - - return s.getsockname()[0] # type: ignore - - -class BaseWSGIServer(HTTPServer): - - """Simple single-threaded, single-process WSGI server.""" - - multithread = False - multiprocess = False - request_queue_size = LISTEN_QUEUE - - def __init__( - self, - host: str, - port: int, - app: "WSGIApplication", - handler: t.Optional[t.Type[WSGIRequestHandler]] = None, - passthrough_errors: bool = False, - ssl_context: t.Optional[_TSSLContextArg] = None, - fd: t.Optional[int] = None, - ) -> None: - if handler is None: - handler = WSGIRequestHandler - - self.address_family = select_address_family(host, port) - - if fd is not None: - real_sock = socket.fromfd(fd, self.address_family, socket.SOCK_STREAM) - port = 0 - - server_address = get_sockaddr(host, int(port), self.address_family) - - # remove socket file if it already exists - if self.address_family == af_unix: - server_address = t.cast(str, server_address) - - if os.path.exists(server_address): - os.unlink(server_address) - - super().__init__(server_address, handler) # type: ignore - - self.app = app - self.passthrough_errors = passthrough_errors - self.shutdown_signal = False - self.host = host - self.port = self.socket.getsockname()[1] - - # Patch in the original socket. - if fd is not None: - self.socket.close() - self.socket = real_sock - self.server_address = self.socket.getsockname() - - if ssl_context is not None: - if isinstance(ssl_context, tuple): - ssl_context = load_ssl_context(*ssl_context) - if ssl_context == "adhoc": - ssl_context = generate_adhoc_ssl_context() - - self.socket = ssl_context.wrap_socket(self.socket, server_side=True) - self.ssl_context: t.Optional["ssl.SSLContext"] = ssl_context - else: - self.ssl_context = None - - def log(self, type: str, message: str, *args: t.Any) -> None: - _log(type, message, *args) - - def serve_forever(self, poll_interval: float = 0.5) -> None: - self.shutdown_signal = False - try: - super().serve_forever(poll_interval=poll_interval) - except KeyboardInterrupt: - pass - finally: - self.server_close() - - def handle_error( - self, request: t.Any, client_address: t.Union[t.Tuple[str, int], str] - ) -> None: - if self.passthrough_errors: - raise - - return super().handle_error(request, client_address) - - -class ThreadedWSGIServer(socketserver.ThreadingMixIn, BaseWSGIServer): - - """A WSGI server that does threading.""" - - multithread = True - daemon_threads = True - - -class ForkingWSGIServer(ForkingMixIn, BaseWSGIServer): - - """A WSGI server that does forking.""" - - multiprocess = True - - def __init__( - self, - host: str, - port: int, - app: "WSGIApplication", - processes: int = 40, - handler: t.Optional[t.Type[WSGIRequestHandler]] = None, - passthrough_errors: bool = False, - ssl_context: t.Optional[_TSSLContextArg] = None, - fd: t.Optional[int] = None, - ) -> None: - if not can_fork: - raise ValueError("Your platform does not support forking.") - BaseWSGIServer.__init__( - self, host, port, app, handler, passthrough_errors, ssl_context, fd - ) - self.max_children = processes - - -def make_server( - host: str, - port: int, - app: "WSGIApplication", - threaded: bool = False, - processes: int = 1, - request_handler: t.Optional[t.Type[WSGIRequestHandler]] = None, - passthrough_errors: bool = False, - ssl_context: t.Optional[_TSSLContextArg] = None, - fd: t.Optional[int] = None, -) -> BaseWSGIServer: - """Create a new server instance that is either threaded, or forks - or just processes one request after another. - """ - if threaded and processes > 1: - raise ValueError("cannot have a multithreaded and multi process server.") - elif threaded: - return ThreadedWSGIServer( - host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd - ) - elif processes > 1: - return ForkingWSGIServer( - host, - port, - app, - processes, - request_handler, - passthrough_errors, - ssl_context, - fd=fd, - ) - else: - return BaseWSGIServer( - host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd - ) - - -def is_running_from_reloader() -> bool: - """Checks if the application is running from within the Werkzeug - reloader subprocess. - - .. versionadded:: 0.10 - """ - return os.environ.get("WERKZEUG_RUN_MAIN") == "true" - - -def run_simple( - hostname: str, - port: int, - application: "WSGIApplication", - use_reloader: bool = False, - use_debugger: bool = False, - use_evalex: bool = True, - extra_files: t.Optional[t.Iterable[str]] = None, - exclude_patterns: t.Optional[t.Iterable[str]] = None, - reloader_interval: int = 1, - reloader_type: str = "auto", - threaded: bool = False, - processes: int = 1, - request_handler: t.Optional[t.Type[WSGIRequestHandler]] = None, - static_files: t.Optional[t.Dict[str, t.Union[str, t.Tuple[str, str]]]] = None, - passthrough_errors: bool = False, - ssl_context: t.Optional[_TSSLContextArg] = None, -) -> None: - """Start a WSGI application. Optional features include a reloader, - multithreading and fork support. - - This function has a command-line interface too:: - - python -m werkzeug.serving --help - - .. versionchanged:: 2.0 - Added ``exclude_patterns`` parameter. - - .. versionadded:: 0.5 - `static_files` was added to simplify serving of static files as well - as `passthrough_errors`. - - .. versionadded:: 0.6 - support for SSL was added. - - .. versionadded:: 0.8 - Added support for automatically loading a SSL context from certificate - file and private key. - - .. versionadded:: 0.9 - Added command-line interface. - - .. versionadded:: 0.10 - Improved the reloader and added support for changing the backend - through the `reloader_type` parameter. See :ref:`reloader` - for more information. - - .. versionchanged:: 0.15 - Bind to a Unix socket by passing a path that starts with - ``unix://`` as the ``hostname``. - - :param hostname: The host to bind to, for example ``'localhost'``. - If the value is a path that starts with ``unix://`` it will bind - to a Unix socket instead of a TCP socket.. - :param port: The port for the server. eg: ``8080`` - :param application: the WSGI application to execute - :param use_reloader: should the server automatically restart the python - process if modules were changed? - :param use_debugger: should the werkzeug debugging system be used? - :param use_evalex: should the exception evaluation feature be enabled? - :param extra_files: a list of files the reloader should watch - additionally to the modules. For example configuration - files. - :param exclude_patterns: List of :mod:`fnmatch` patterns to ignore - when running the reloader. For example, ignore cache files that - shouldn't reload when updated. - :param reloader_interval: the interval for the reloader in seconds. - :param reloader_type: the type of reloader to use. The default is - auto detection. Valid values are ``'stat'`` and - ``'watchdog'``. See :ref:`reloader` for more - information. - :param threaded: should the process handle each request in a separate - thread? - :param processes: if greater than 1 then handle each request in a new process - up to this maximum number of concurrent processes. - :param request_handler: optional parameter that can be used to replace - the default one. You can use this to replace it - with a different - :class:`~BaseHTTPServer.BaseHTTPRequestHandler` - subclass. - :param static_files: a list or dict of paths for static files. This works - exactly like :class:`SharedDataMiddleware`, it's actually - just wrapping the application in that middleware before - serving. - :param passthrough_errors: set this to `True` to disable the error catching. - This means that the server will die on errors but - it can be useful to hook debuggers in (pdb etc.) - :param ssl_context: an SSL context for the connection. Either an - :class:`ssl.SSLContext`, a tuple in the form - ``(cert_file, pkey_file)``, the string ``'adhoc'`` if - the server should automatically create one, or ``None`` - to disable SSL (which is the default). - """ - if not isinstance(port, int): - raise TypeError("port must be an integer") - if use_debugger: - from .debug import DebuggedApplication - - application = DebuggedApplication(application, use_evalex) - if static_files: - from .middleware.shared_data import SharedDataMiddleware - - application = SharedDataMiddleware(application, static_files) - - def log_startup(sock: socket.socket) -> None: - all_addresses_message = ( - " * Running on all addresses.\n" - " WARNING: This is a development server. Do not use it in" - " a production deployment." - ) - - if sock.family == af_unix: - _log("info", " * Running on %s (Press CTRL+C to quit)", hostname) - else: - if hostname == "0.0.0.0": - _log("warning", all_addresses_message) - display_hostname = get_interface_ip(socket.AF_INET) - elif hostname == "::": - _log("warning", all_addresses_message) - display_hostname = get_interface_ip(socket.AF_INET6) - else: - display_hostname = hostname - - if ":" in display_hostname: - display_hostname = f"[{display_hostname}]" - - _log( - "info", - " * Running on %s://%s:%d/ (Press CTRL+C to quit)", - "http" if ssl_context is None else "https", - display_hostname, - sock.getsockname()[1], - ) - - def inner() -> None: - try: - fd: t.Optional[int] = int(os.environ["WERKZEUG_SERVER_FD"]) - except (LookupError, ValueError): - fd = None - srv = make_server( - hostname, - port, - application, - threaded, - processes, - request_handler, - passthrough_errors, - ssl_context, - fd=fd, - ) - if fd is None: - log_startup(srv.socket) - srv.serve_forever() - - if use_reloader: - # If we're not running already in the subprocess that is the - # reloader we want to open up a socket early to make sure the - # port is actually available. - if not is_running_from_reloader(): - if port == 0 and not can_open_by_fd: - raise ValueError( - "Cannot bind to a random port with enabled " - "reloader if the Python interpreter does " - "not support socket opening by fd." - ) - - # Create and destroy a socket so that any exceptions are - # raised before we spawn a separate Python interpreter and - # lose this ability. - address_family = select_address_family(hostname, port) - server_address = get_sockaddr(hostname, port, address_family) - s = socket.socket(address_family, socket.SOCK_STREAM) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(server_address) - s.set_inheritable(True) - - # If we can open the socket by file descriptor, then we can just - # reuse this one and our socket will survive the restarts. - if can_open_by_fd: - os.environ["WERKZEUG_SERVER_FD"] = str(s.fileno()) - s.listen(LISTEN_QUEUE) - log_startup(s) - else: - s.close() - if address_family == af_unix: - server_address = t.cast(str, server_address) - _log("info", "Unlinking %s", server_address) - os.unlink(server_address) - - from ._reloader import run_with_reloader as _rwr - - _rwr( - inner, - extra_files=extra_files, - exclude_patterns=exclude_patterns, - interval=reloader_interval, - reloader_type=reloader_type, - ) - else: - inner() - - -def run_with_reloader(*args: t.Any, **kwargs: t.Any) -> None: - """Run a process with the reloader. This is not a public API, do - not use this function. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. - """ - from ._reloader import run_with_reloader as _rwr - - warnings.warn( - ( - "'run_with_reloader' is a private API, it will no longer be" - " accessible in Werkzeug 2.1. Use 'run_simple' instead." - ), - DeprecationWarning, - stacklevel=2, - ) - _rwr(*args, **kwargs) - - -def main() -> None: - """A simple command-line interface for :py:func:`run_simple`.""" - import argparse - from .utils import import_string - - _log("warning", "This CLI is deprecated and will be removed in version 2.1.") - - parser = argparse.ArgumentParser( - description="Run the given WSGI application with the development server.", - allow_abbrev=False, - ) - parser.add_argument( - "-b", - "--bind", - dest="address", - help="The hostname:port the app should listen on.", - ) - parser.add_argument( - "-d", - "--debug", - action="store_true", - help="Show the interactive debugger for unhandled exceptions.", - ) - parser.add_argument( - "-r", - "--reload", - action="store_true", - help="Reload the process if modules change.", - ) - parser.add_argument( - "application", help="Application to import and serve, in the form module:app." - ) - args = parser.parse_args() - hostname, port = None, None - - if args.address: - hostname, _, port = args.address.partition(":") - - run_simple( - hostname=hostname or "127.0.0.1", - port=int(port or 5000), - application=import_string(args.application), - use_reloader=args.reload, - use_debugger=args.debug, - ) - - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.7/site-packages/werkzeug/test.py b/venv/lib/python3.7/site-packages/werkzeug/test.py deleted file mode 100644 index 448dbbd..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/test.py +++ /dev/null @@ -1,1331 +0,0 @@ -import mimetypes -import sys -import typing as t -import warnings -from collections import defaultdict -from datetime import datetime -from datetime import timedelta -from http.cookiejar import CookieJar -from io import BytesIO -from itertools import chain -from random import random -from tempfile import TemporaryFile -from time import time -from urllib.request import Request as _UrllibRequest - -from ._internal import _get_environ -from ._internal import _make_encode_wrapper -from ._internal import _wsgi_decoding_dance -from ._internal import _wsgi_encoding_dance -from .datastructures import Authorization -from .datastructures import CallbackDict -from .datastructures import CombinedMultiDict -from .datastructures import EnvironHeaders -from .datastructures import FileMultiDict -from .datastructures import Headers -from .datastructures import MultiDict -from .http import dump_cookie -from .http import dump_options_header -from .http import parse_options_header -from .sansio.multipart import Data -from .sansio.multipart import Epilogue -from .sansio.multipart import Field -from .sansio.multipart import File -from .sansio.multipart import MultipartEncoder -from .sansio.multipart import Preamble -from .urls import iri_to_uri -from .urls import url_encode -from .urls import url_fix -from .urls import url_parse -from .urls import url_unparse -from .urls import url_unquote -from .utils import get_content_type -from .wrappers.request import Request -from .wrappers.response import Response -from .wsgi import ClosingIterator -from .wsgi import get_current_url - -if t.TYPE_CHECKING: - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -def stream_encode_multipart( - data: t.Mapping[str, t.Any], - use_tempfile: bool = True, - threshold: int = 1024 * 500, - boundary: t.Optional[str] = None, - charset: str = "utf-8", -) -> t.Tuple[t.IO[bytes], int, str]: - """Encode a dict of values (either strings or file descriptors or - :class:`FileStorage` objects.) into a multipart encoded string stored - in a file descriptor. - """ - if boundary is None: - boundary = f"---------------WerkzeugFormPart_{time()}{random()}" - - stream: t.IO[bytes] = BytesIO() - total_length = 0 - on_disk = False - - if use_tempfile: - - def write_binary(s: bytes) -> int: - nonlocal stream, total_length, on_disk - - if on_disk: - return stream.write(s) - else: - length = len(s) - - if length + total_length <= threshold: - stream.write(s) - else: - new_stream = t.cast(t.IO[bytes], TemporaryFile("wb+")) - new_stream.write(stream.getvalue()) # type: ignore - new_stream.write(s) - stream = new_stream - on_disk = True - - total_length += length - return length - - else: - write_binary = stream.write - - encoder = MultipartEncoder(boundary.encode()) - write_binary(encoder.send_event(Preamble(data=b""))) - for key, value in _iter_data(data): - reader = getattr(value, "read", None) - if reader is not None: - filename = getattr(value, "filename", getattr(value, "name", None)) - content_type = getattr(value, "content_type", None) - if content_type is None: - content_type = ( - filename - and mimetypes.guess_type(filename)[0] - or "application/octet-stream" - ) - headers = Headers([("Content-Type", content_type)]) - if filename is None: - write_binary(encoder.send_event(Field(name=key, headers=headers))) - else: - write_binary( - encoder.send_event( - File(name=key, filename=filename, headers=headers) - ) - ) - while True: - chunk = reader(16384) - - if not chunk: - break - - write_binary(encoder.send_event(Data(data=chunk, more_data=True))) - else: - if not isinstance(value, str): - value = str(value) - write_binary(encoder.send_event(Field(name=key, headers=Headers()))) - write_binary( - encoder.send_event(Data(data=value.encode(charset), more_data=False)) - ) - - write_binary(encoder.send_event(Epilogue(data=b""))) - - length = stream.tell() - stream.seek(0) - return stream, length, boundary - - -def encode_multipart( - values: t.Mapping[str, t.Any], - boundary: t.Optional[str] = None, - charset: str = "utf-8", -) -> t.Tuple[str, bytes]: - """Like `stream_encode_multipart` but returns a tuple in the form - (``boundary``, ``data``) where data is bytes. - """ - stream, length, boundary = stream_encode_multipart( - values, use_tempfile=False, boundary=boundary, charset=charset - ) - return boundary, stream.read() - - -class _TestCookieHeaders: - """A headers adapter for cookielib""" - - def __init__(self, headers: t.Union[Headers, t.List[t.Tuple[str, str]]]) -> None: - self.headers = headers - - def getheaders(self, name: str) -> t.Iterable[str]: - headers = [] - name = name.lower() - for k, v in self.headers: - if k.lower() == name: - headers.append(v) - return headers - - def get_all( - self, name: str, default: t.Optional[t.Iterable[str]] = None - ) -> t.Iterable[str]: - headers = self.getheaders(name) - - if not headers: - return default # type: ignore - - return headers - - -class _TestCookieResponse: - """Something that looks like a httplib.HTTPResponse, but is actually just an - adapter for our test responses to make them available for cookielib. - """ - - def __init__(self, headers: t.Union[Headers, t.List[t.Tuple[str, str]]]) -> None: - self.headers = _TestCookieHeaders(headers) - - def info(self) -> _TestCookieHeaders: - return self.headers - - -class _TestCookieJar(CookieJar): - """A cookielib.CookieJar modified to inject and read cookie headers from - and to wsgi environments, and wsgi application responses. - """ - - def inject_wsgi(self, environ: "WSGIEnvironment") -> None: - """Inject the cookies as client headers into the server's wsgi - environment. - """ - cvals = [f"{c.name}={c.value}" for c in self] - - if cvals: - environ["HTTP_COOKIE"] = "; ".join(cvals) - else: - environ.pop("HTTP_COOKIE", None) - - def extract_wsgi( - self, - environ: "WSGIEnvironment", - headers: t.Union[Headers, t.List[t.Tuple[str, str]]], - ) -> None: - """Extract the server's set-cookie headers as cookies into the - cookie jar. - """ - self.extract_cookies( - _TestCookieResponse(headers), # type: ignore - _UrllibRequest(get_current_url(environ)), - ) - - -def _iter_data(data: t.Mapping[str, t.Any]) -> t.Iterator[t.Tuple[str, t.Any]]: - """Iterate over a mapping that might have a list of values, yielding - all key, value pairs. Almost like iter_multi_items but only allows - lists, not tuples, of values so tuples can be used for files. - """ - if isinstance(data, MultiDict): - yield from data.items(multi=True) - else: - for key, value in data.items(): - if isinstance(value, list): - for v in value: - yield key, v - else: - yield key, value - - -_TAnyMultiDict = t.TypeVar("_TAnyMultiDict", bound=MultiDict) - - -class EnvironBuilder: - """This class can be used to conveniently create a WSGI environment - for testing purposes. It can be used to quickly create WSGI environments - or request objects from arbitrary data. - - The signature of this class is also used in some other places as of - Werkzeug 0.5 (:func:`create_environ`, :meth:`Response.from_values`, - :meth:`Client.open`). Because of this most of the functionality is - available through the constructor alone. - - Files and regular form data can be manipulated independently of each - other with the :attr:`form` and :attr:`files` attributes, but are - passed with the same argument to the constructor: `data`. - - `data` can be any of these values: - - - a `str` or `bytes` object: The object is converted into an - :attr:`input_stream`, the :attr:`content_length` is set and you have to - provide a :attr:`content_type`. - - a `dict` or :class:`MultiDict`: The keys have to be strings. The values - have to be either any of the following objects, or a list of any of the - following objects: - - - a :class:`file`-like object: These are converted into - :class:`FileStorage` objects automatically. - - a `tuple`: The :meth:`~FileMultiDict.add_file` method is called - with the key and the unpacked `tuple` items as positional - arguments. - - a `str`: The string is set as form data for the associated key. - - a file-like object: The object content is loaded in memory and then - handled like a regular `str` or a `bytes`. - - :param path: the path of the request. In the WSGI environment this will - end up as `PATH_INFO`. If the `query_string` is not defined - and there is a question mark in the `path` everything after - it is used as query string. - :param base_url: the base URL is a URL that is used to extract the WSGI - URL scheme, host (server name + server port) and the - script root (`SCRIPT_NAME`). - :param query_string: an optional string or dict with URL parameters. - :param method: the HTTP method to use, defaults to `GET`. - :param input_stream: an optional input stream. Do not specify this and - `data`. As soon as an input stream is set you can't - modify :attr:`args` and :attr:`files` unless you - set the :attr:`input_stream` to `None` again. - :param content_type: The content type for the request. As of 0.5 you - don't have to provide this when specifying files - and form data via `data`. - :param content_length: The content length for the request. You don't - have to specify this when providing data via - `data`. - :param errors_stream: an optional error stream that is used for - `wsgi.errors`. Defaults to :data:`stderr`. - :param multithread: controls `wsgi.multithread`. Defaults to `False`. - :param multiprocess: controls `wsgi.multiprocess`. Defaults to `False`. - :param run_once: controls `wsgi.run_once`. Defaults to `False`. - :param headers: an optional list or :class:`Headers` object of headers. - :param data: a string or dict of form data or a file-object. - See explanation above. - :param json: An object to be serialized and assigned to ``data``. - Defaults the content type to ``"application/json"``. - Serialized with the function assigned to :attr:`json_dumps`. - :param environ_base: an optional dict of environment defaults. - :param environ_overrides: an optional dict of environment overrides. - :param charset: the charset used to encode string data. - :param auth: An authorization object to use for the - ``Authorization`` header value. A ``(username, password)`` tuple - is a shortcut for ``Basic`` authorization. - - .. versionchanged:: 2.0 - ``REQUEST_URI`` and ``RAW_URI`` is the full raw URI including - the query string, not only the path. - - .. versionchanged:: 2.0 - The default :attr:`request_class` is ``Request`` instead of - ``BaseRequest``. - - .. versionadded:: 2.0 - Added the ``auth`` parameter. - - .. versionadded:: 0.15 - The ``json`` param and :meth:`json_dumps` method. - - .. versionadded:: 0.15 - The environ has keys ``REQUEST_URI`` and ``RAW_URI`` containing - the path before perecent-decoding. This is not part of the WSGI - PEP, but many WSGI servers include it. - - .. versionchanged:: 0.6 - ``path`` and ``base_url`` can now be unicode strings that are - encoded with :func:`iri_to_uri`. - """ - - #: the server protocol to use. defaults to HTTP/1.1 - server_protocol = "HTTP/1.1" - - #: the wsgi version to use. defaults to (1, 0) - wsgi_version = (1, 0) - - #: The default request class used by :meth:`get_request`. - request_class = Request - - import json - - #: The serialization function used when ``json`` is passed. - json_dumps = staticmethod(json.dumps) - del json - - _args: t.Optional[MultiDict] - _query_string: t.Optional[str] - _input_stream: t.Optional[t.IO[bytes]] - _form: t.Optional[MultiDict] - _files: t.Optional[FileMultiDict] - - def __init__( - self, - path: str = "/", - base_url: t.Optional[str] = None, - query_string: t.Optional[t.Union[t.Mapping[str, str], str]] = None, - method: str = "GET", - input_stream: t.Optional[t.IO[bytes]] = None, - content_type: t.Optional[str] = None, - content_length: t.Optional[int] = None, - errors_stream: t.Optional[t.IO[str]] = None, - multithread: bool = False, - multiprocess: bool = False, - run_once: bool = False, - headers: t.Optional[t.Union[Headers, t.Iterable[t.Tuple[str, str]]]] = None, - data: t.Optional[ - t.Union[t.IO[bytes], str, bytes, t.Mapping[str, t.Any]] - ] = None, - environ_base: t.Optional[t.Mapping[str, t.Any]] = None, - environ_overrides: t.Optional[t.Mapping[str, t.Any]] = None, - charset: str = "utf-8", - mimetype: t.Optional[str] = None, - json: t.Optional[t.Mapping[str, t.Any]] = None, - auth: t.Optional[t.Union[Authorization, t.Tuple[str, str]]] = None, - ) -> None: - path_s = _make_encode_wrapper(path) - if query_string is not None and path_s("?") in path: - raise ValueError("Query string is defined in the path and as an argument") - request_uri = url_parse(path) - if query_string is None and path_s("?") in path: - query_string = request_uri.query - self.charset = charset - self.path = iri_to_uri(request_uri.path) - self.request_uri = path - if base_url is not None: - base_url = url_fix(iri_to_uri(base_url, charset), charset) - self.base_url = base_url # type: ignore - if isinstance(query_string, (bytes, str)): - self.query_string = query_string - else: - if query_string is None: - query_string = MultiDict() - elif not isinstance(query_string, MultiDict): - query_string = MultiDict(query_string) - self.args = query_string - self.method = method - if headers is None: - headers = Headers() - elif not isinstance(headers, Headers): - headers = Headers(headers) - self.headers = headers - if content_type is not None: - self.content_type = content_type - if errors_stream is None: - errors_stream = sys.stderr - self.errors_stream = errors_stream - self.multithread = multithread - self.multiprocess = multiprocess - self.run_once = run_once - self.environ_base = environ_base - self.environ_overrides = environ_overrides - self.input_stream = input_stream - self.content_length = content_length - self.closed = False - - if auth is not None: - if isinstance(auth, tuple): - auth = Authorization( - "basic", {"username": auth[0], "password": auth[1]} - ) - - self.headers.set("Authorization", auth.to_header()) - - if json is not None: - if data is not None: - raise TypeError("can't provide both json and data") - - data = self.json_dumps(json) - - if self.content_type is None: - self.content_type = "application/json" - - if data: - if input_stream is not None: - raise TypeError("can't provide input stream and data") - if hasattr(data, "read"): - data = data.read() # type: ignore - if isinstance(data, str): - data = data.encode(self.charset) - if isinstance(data, bytes): - self.input_stream = BytesIO(data) - if self.content_length is None: - self.content_length = len(data) - else: - for key, value in _iter_data(data): # type: ignore - if isinstance(value, (tuple, dict)) or hasattr(value, "read"): - self._add_file_from_data(key, value) - else: - self.form.setlistdefault(key).append(value) - - if mimetype is not None: - self.mimetype = mimetype - - @classmethod - def from_environ( - cls, environ: "WSGIEnvironment", **kwargs: t.Any - ) -> "EnvironBuilder": - """Turn an environ dict back into a builder. Any extra kwargs - override the args extracted from the environ. - - .. versionchanged:: 2.0 - Path and query values are passed through the WSGI decoding - dance to avoid double encoding. - - .. versionadded:: 0.15 - """ - headers = Headers(EnvironHeaders(environ)) - out = { - "path": _wsgi_decoding_dance(environ["PATH_INFO"]), - "base_url": cls._make_base_url( - environ["wsgi.url_scheme"], - headers.pop("Host"), - _wsgi_decoding_dance(environ["SCRIPT_NAME"]), - ), - "query_string": _wsgi_decoding_dance(environ["QUERY_STRING"]), - "method": environ["REQUEST_METHOD"], - "input_stream": environ["wsgi.input"], - "content_type": headers.pop("Content-Type", None), - "content_length": headers.pop("Content-Length", None), - "errors_stream": environ["wsgi.errors"], - "multithread": environ["wsgi.multithread"], - "multiprocess": environ["wsgi.multiprocess"], - "run_once": environ["wsgi.run_once"], - "headers": headers, - } - out.update(kwargs) - return cls(**out) - - def _add_file_from_data( - self, - key: str, - value: t.Union[ - t.IO[bytes], t.Tuple[t.IO[bytes], str], t.Tuple[t.IO[bytes], str, str] - ], - ) -> None: - """Called in the EnvironBuilder to add files from the data dict.""" - if isinstance(value, tuple): - self.files.add_file(key, *value) - else: - self.files.add_file(key, value) - - @staticmethod - def _make_base_url(scheme: str, host: str, script_root: str) -> str: - return url_unparse((scheme, host, script_root, "", "")).rstrip("/") + "/" - - @property - def base_url(self) -> str: - """The base URL is used to extract the URL scheme, host name, - port, and root path. - """ - return self._make_base_url(self.url_scheme, self.host, self.script_root) - - @base_url.setter - def base_url(self, value: t.Optional[str]) -> None: - if value is None: - scheme = "http" - netloc = "localhost" - script_root = "" - else: - scheme, netloc, script_root, qs, anchor = url_parse(value) - if qs or anchor: - raise ValueError("base url must not contain a query string or fragment") - self.script_root = script_root.rstrip("/") - self.host = netloc - self.url_scheme = scheme - - @property - def content_type(self) -> t.Optional[str]: - """The content type for the request. Reflected from and to - the :attr:`headers`. Do not set if you set :attr:`files` or - :attr:`form` for auto detection. - """ - ct = self.headers.get("Content-Type") - if ct is None and not self._input_stream: - if self._files: - return "multipart/form-data" - if self._form: - return "application/x-www-form-urlencoded" - return None - return ct - - @content_type.setter - def content_type(self, value: t.Optional[str]) -> None: - if value is None: - self.headers.pop("Content-Type", None) - else: - self.headers["Content-Type"] = value - - @property - def mimetype(self) -> t.Optional[str]: - """The mimetype (content type without charset etc.) - - .. versionadded:: 0.14 - """ - ct = self.content_type - return ct.split(";")[0].strip() if ct else None - - @mimetype.setter - def mimetype(self, value: str) -> None: - self.content_type = get_content_type(value, self.charset) - - @property - def mimetype_params(self) -> t.Mapping[str, str]: - """The mimetype parameters as dict. For example if the - content type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - - .. versionadded:: 0.14 - """ - - def on_update(d: CallbackDict) -> None: - self.headers["Content-Type"] = dump_options_header(self.mimetype, d) - - d = parse_options_header(self.headers.get("content-type", ""))[1] - return CallbackDict(d, on_update) - - @property - def content_length(self) -> t.Optional[int]: - """The content length as integer. Reflected from and to the - :attr:`headers`. Do not set if you set :attr:`files` or - :attr:`form` for auto detection. - """ - return self.headers.get("Content-Length", type=int) - - @content_length.setter - def content_length(self, value: t.Optional[int]) -> None: - if value is None: - self.headers.pop("Content-Length", None) - else: - self.headers["Content-Length"] = str(value) - - def _get_form(self, name: str, storage: t.Type[_TAnyMultiDict]) -> _TAnyMultiDict: - """Common behavior for getting the :attr:`form` and - :attr:`files` properties. - - :param name: Name of the internal cached attribute. - :param storage: Storage class used for the data. - """ - if self.input_stream is not None: - raise AttributeError("an input stream is defined") - - rv = getattr(self, name) - - if rv is None: - rv = storage() - setattr(self, name, rv) - - return rv # type: ignore - - def _set_form(self, name: str, value: MultiDict) -> None: - """Common behavior for setting the :attr:`form` and - :attr:`files` properties. - - :param name: Name of the internal cached attribute. - :param value: Value to assign to the attribute. - """ - self._input_stream = None - setattr(self, name, value) - - @property - def form(self) -> MultiDict: - """A :class:`MultiDict` of form values.""" - return self._get_form("_form", MultiDict) - - @form.setter - def form(self, value: MultiDict) -> None: - self._set_form("_form", value) - - @property - def files(self) -> FileMultiDict: - """A :class:`FileMultiDict` of uploaded files. Use - :meth:`~FileMultiDict.add_file` to add new files. - """ - return self._get_form("_files", FileMultiDict) - - @files.setter - def files(self, value: FileMultiDict) -> None: - self._set_form("_files", value) - - @property - def input_stream(self) -> t.Optional[t.IO[bytes]]: - """An optional input stream. This is mutually exclusive with - setting :attr:`form` and :attr:`files`, setting it will clear - those. Do not provide this if the method is not ``POST`` or - another method that has a body. - """ - return self._input_stream - - @input_stream.setter - def input_stream(self, value: t.Optional[t.IO[bytes]]) -> None: - self._input_stream = value - self._form = None - self._files = None - - @property - def query_string(self) -> str: - """The query string. If you set this to a string - :attr:`args` will no longer be available. - """ - if self._query_string is None: - if self._args is not None: - return url_encode(self._args, charset=self.charset) - return "" - return self._query_string - - @query_string.setter - def query_string(self, value: t.Optional[str]) -> None: - self._query_string = value - self._args = None - - @property - def args(self) -> MultiDict: - """The URL arguments as :class:`MultiDict`.""" - if self._query_string is not None: - raise AttributeError("a query string is defined") - if self._args is None: - self._args = MultiDict() - return self._args - - @args.setter - def args(self, value: t.Optional[MultiDict]) -> None: - self._query_string = None - self._args = value - - @property - def server_name(self) -> str: - """The server name (read-only, use :attr:`host` to set)""" - return self.host.split(":", 1)[0] - - @property - def server_port(self) -> int: - """The server port as integer (read-only, use :attr:`host` to set)""" - pieces = self.host.split(":", 1) - if len(pieces) == 2 and pieces[1].isdigit(): - return int(pieces[1]) - if self.url_scheme == "https": - return 443 - return 80 - - def __del__(self) -> None: - try: - self.close() - except Exception: - pass - - def close(self) -> None: - """Closes all files. If you put real :class:`file` objects into the - :attr:`files` dict you can call this method to automatically close - them all in one go. - """ - if self.closed: - return - try: - files = self.files.values() - except AttributeError: - files = () # type: ignore - for f in files: - try: - f.close() - except Exception: - pass - self.closed = True - - def get_environ(self) -> "WSGIEnvironment": - """Return the built environ. - - .. versionchanged:: 0.15 - The content type and length headers are set based on - input stream detection. Previously this only set the WSGI - keys. - """ - input_stream = self.input_stream - content_length = self.content_length - - mimetype = self.mimetype - content_type = self.content_type - - if input_stream is not None: - start_pos = input_stream.tell() - input_stream.seek(0, 2) - end_pos = input_stream.tell() - input_stream.seek(start_pos) - content_length = end_pos - start_pos - elif mimetype == "multipart/form-data": - input_stream, content_length, boundary = stream_encode_multipart( - CombinedMultiDict([self.form, self.files]), charset=self.charset - ) - content_type = f'{mimetype}; boundary="{boundary}"' - elif mimetype == "application/x-www-form-urlencoded": - form_encoded = url_encode(self.form, charset=self.charset).encode("ascii") - content_length = len(form_encoded) - input_stream = BytesIO(form_encoded) - else: - input_stream = BytesIO() - - result: "WSGIEnvironment" = {} - if self.environ_base: - result.update(self.environ_base) - - def _path_encode(x: str) -> str: - return _wsgi_encoding_dance(url_unquote(x, self.charset), self.charset) - - raw_uri = _wsgi_encoding_dance(self.request_uri, self.charset) - result.update( - { - "REQUEST_METHOD": self.method, - "SCRIPT_NAME": _path_encode(self.script_root), - "PATH_INFO": _path_encode(self.path), - "QUERY_STRING": _wsgi_encoding_dance(self.query_string, self.charset), - # Non-standard, added by mod_wsgi, uWSGI - "REQUEST_URI": raw_uri, - # Non-standard, added by gunicorn - "RAW_URI": raw_uri, - "SERVER_NAME": self.server_name, - "SERVER_PORT": str(self.server_port), - "HTTP_HOST": self.host, - "SERVER_PROTOCOL": self.server_protocol, - "wsgi.version": self.wsgi_version, - "wsgi.url_scheme": self.url_scheme, - "wsgi.input": input_stream, - "wsgi.errors": self.errors_stream, - "wsgi.multithread": self.multithread, - "wsgi.multiprocess": self.multiprocess, - "wsgi.run_once": self.run_once, - } - ) - - headers = self.headers.copy() - - if content_type is not None: - result["CONTENT_TYPE"] = content_type - headers.set("Content-Type", content_type) - - if content_length is not None: - result["CONTENT_LENGTH"] = str(content_length) - headers.set("Content-Length", content_length) - - combined_headers = defaultdict(list) - - for key, value in headers.to_wsgi_list(): - combined_headers[f"HTTP_{key.upper().replace('-', '_')}"].append(value) - - for key, values in combined_headers.items(): - result[key] = ", ".join(values) - - if self.environ_overrides: - result.update(self.environ_overrides) - - return result - - def get_request(self, cls: t.Optional[t.Type[Request]] = None) -> Request: - """Returns a request with the data. If the request class is not - specified :attr:`request_class` is used. - - :param cls: The request wrapper to use. - """ - if cls is None: - cls = self.request_class - - return cls(self.get_environ()) - - -class ClientRedirectError(Exception): - """If a redirect loop is detected when using follow_redirects=True with - the :cls:`Client`, then this exception is raised. - """ - - -class Client: - """This class allows you to send requests to a wrapped application. - - The use_cookies parameter indicates whether cookies should be stored and - sent for subsequent requests. This is True by default, but passing False - will disable this behaviour. - - If you want to request some subdomain of your application you may set - `allow_subdomain_redirects` to `True` as if not no external redirects - are allowed. - - .. versionchanged:: 2.0 - ``response_wrapper`` is always a subclass of - :class:``TestResponse``. - - .. versionchanged:: 0.5 - Added the ``use_cookies`` parameter. - """ - - def __init__( - self, - application: "WSGIApplication", - response_wrapper: t.Optional[t.Type["Response"]] = None, - use_cookies: bool = True, - allow_subdomain_redirects: bool = False, - ) -> None: - self.application = application - - if response_wrapper in {None, Response}: - response_wrapper = TestResponse - elif not isinstance(response_wrapper, TestResponse): - response_wrapper = type( - "WrapperTestResponse", - (TestResponse, response_wrapper), # type: ignore - {}, - ) - - self.response_wrapper = t.cast(t.Type["TestResponse"], response_wrapper) - - if use_cookies: - self.cookie_jar: t.Optional[_TestCookieJar] = _TestCookieJar() - else: - self.cookie_jar = None - - self.allow_subdomain_redirects = allow_subdomain_redirects - - def set_cookie( - self, - server_name: str, - key: str, - value: str = "", - max_age: t.Optional[t.Union[timedelta, int]] = None, - expires: t.Optional[t.Union[str, datetime, int, float]] = None, - path: str = "/", - domain: t.Optional[str] = None, - secure: bool = False, - httponly: bool = False, - samesite: t.Optional[str] = None, - charset: str = "utf-8", - ) -> None: - """Sets a cookie in the client's cookie jar. The server name - is required and has to match the one that is also passed to - the open call. - """ - assert self.cookie_jar is not None, "cookies disabled" - header = dump_cookie( - key, - value, - max_age, - expires, - path, - domain, - secure, - httponly, - charset, - samesite=samesite, - ) - environ = create_environ(path, base_url=f"http://{server_name}") - headers = [("Set-Cookie", header)] - self.cookie_jar.extract_wsgi(environ, headers) - - def delete_cookie( - self, - server_name: str, - key: str, - path: str = "/", - domain: t.Optional[str] = None, - secure: bool = False, - httponly: bool = False, - samesite: t.Optional[str] = None, - ) -> None: - """Deletes a cookie in the test client.""" - self.set_cookie( - server_name, - key, - expires=0, - max_age=0, - path=path, - domain=domain, - secure=secure, - httponly=httponly, - samesite=samesite, - ) - - def run_wsgi_app( - self, environ: "WSGIEnvironment", buffered: bool = False - ) -> t.Tuple[t.Iterable[bytes], str, Headers]: - """Runs the wrapped WSGI app with the given environment. - - :meta private: - """ - if self.cookie_jar is not None: - self.cookie_jar.inject_wsgi(environ) - - rv = run_wsgi_app(self.application, environ, buffered=buffered) - - if self.cookie_jar is not None: - self.cookie_jar.extract_wsgi(environ, rv[2]) - - return rv - - def resolve_redirect( - self, response: "TestResponse", buffered: bool = False - ) -> "TestResponse": - """Perform a new request to the location given by the redirect - response to the previous request. - - :meta private: - """ - scheme, netloc, path, qs, anchor = url_parse(response.location) - builder = EnvironBuilder.from_environ( - response.request.environ, path=path, query_string=qs - ) - - to_name_parts = netloc.split(":", 1)[0].split(".") - from_name_parts = builder.server_name.split(".") - - if to_name_parts != [""]: - # The new location has a host, use it for the base URL. - builder.url_scheme = scheme - builder.host = netloc - else: - # A local redirect with autocorrect_location_header=False - # doesn't have a host, so use the request's host. - to_name_parts = from_name_parts - - # Explain why a redirect to a different server name won't be followed. - if to_name_parts != from_name_parts: - if to_name_parts[-len(from_name_parts) :] == from_name_parts: - if not self.allow_subdomain_redirects: - raise RuntimeError("Following subdomain redirects is not enabled.") - else: - raise RuntimeError("Following external redirects is not supported.") - - path_parts = path.split("/") - root_parts = builder.script_root.split("/") - - if path_parts[: len(root_parts)] == root_parts: - # Strip the script root from the path. - builder.path = path[len(builder.script_root) :] - else: - # The new location is not under the script root, so use the - # whole path and clear the previous root. - builder.path = path - builder.script_root = "" - - # Only 307 and 308 preserve all of the original request. - if response.status_code not in {307, 308}: - # HEAD is preserved, everything else becomes GET. - if builder.method != "HEAD": - builder.method = "GET" - - # Clear the body and the headers that describe it. - - if builder.input_stream is not None: - builder.input_stream.close() - builder.input_stream = None - - builder.content_type = None - builder.content_length = None - builder.headers.pop("Transfer-Encoding", None) - - return self.open(builder, buffered=buffered) - - def open( - self, - *args: t.Any, - as_tuple: bool = False, - buffered: bool = False, - follow_redirects: bool = False, - **kwargs: t.Any, - ) -> "TestResponse": - """Generate an environ dict from the given arguments, make a - request to the application using it, and return the response. - - :param args: Passed to :class:`EnvironBuilder` to create the - environ for the request. If a single arg is passed, it can - be an existing :class:`EnvironBuilder` or an environ dict. - :param buffered: Convert the iterator returned by the app into - a list. If the iterator has a ``close()`` method, it is - called automatically. - :param follow_redirects: Make additional requests to follow HTTP - redirects until a non-redirect status is returned. - :attr:`TestResponse.history` lists the intermediate - responses. - - .. versionchanged:: 2.0 - ``as_tuple`` is deprecated and will be removed in Werkzeug - 2.1. Use :attr:`TestResponse.request` and - ``request.environ`` instead. - - .. versionchanged:: 2.0 - The request input stream is closed when calling - ``response.close()``. Input streams for redirects are - automatically closed. - - .. versionchanged:: 0.5 - If a dict is provided as file in the dict for the ``data`` - parameter the content type has to be called ``content_type`` - instead of ``mimetype``. This change was made for - consistency with :class:`werkzeug.FileWrapper`. - - .. versionchanged:: 0.5 - Added the ``follow_redirects`` parameter. - """ - request: t.Optional["Request"] = None - - if not kwargs and len(args) == 1: - arg = args[0] - - if isinstance(arg, EnvironBuilder): - request = arg.get_request() - elif isinstance(arg, dict): - request = EnvironBuilder.from_environ(arg).get_request() - elif isinstance(arg, Request): - request = arg - - if request is None: - builder = EnvironBuilder(*args, **kwargs) - - try: - request = builder.get_request() - finally: - builder.close() - - response = self.run_wsgi_app(request.environ, buffered=buffered) - response = self.response_wrapper(*response, request=request) - - redirects = set() - history: t.List["TestResponse"] = [] - - while follow_redirects and response.status_code in { - 301, - 302, - 303, - 305, - 307, - 308, - }: - # Exhaust intermediate response bodies to ensure middleware - # that returns an iterator runs any cleanup code. - if not buffered: - response.make_sequence() - response.close() - - new_redirect_entry = (response.location, response.status_code) - - if new_redirect_entry in redirects: - raise ClientRedirectError( - f"Loop detected: A {response.status_code} redirect" - f" to {response.location} was already made." - ) - - redirects.add(new_redirect_entry) - response.history = tuple(history) - history.append(response) - response = self.resolve_redirect(response, buffered=buffered) - else: - # This is the final request after redirects, or not - # following redirects. - response.history = tuple(history) - # Close the input stream when closing the response, in case - # the input is an open temporary file. - response.call_on_close(request.input_stream.close) - - if as_tuple: - warnings.warn( - "'as_tuple' is deprecated and will be removed in" - " Werkzeug 2.1. Access 'response.request.environ'" - " instead.", - DeprecationWarning, - stacklevel=2, - ) - return request.environ, response # type: ignore - - return response - - def get(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``GET``.""" - kw["method"] = "GET" - return self.open(*args, **kw) - - def post(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``POST``.""" - kw["method"] = "POST" - return self.open(*args, **kw) - - def put(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``PUT``.""" - kw["method"] = "PUT" - return self.open(*args, **kw) - - def delete(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``DELETE``.""" - kw["method"] = "DELETE" - return self.open(*args, **kw) - - def patch(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``PATCH``.""" - kw["method"] = "PATCH" - return self.open(*args, **kw) - - def options(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``OPTIONS``.""" - kw["method"] = "OPTIONS" - return self.open(*args, **kw) - - def head(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``HEAD``.""" - kw["method"] = "HEAD" - return self.open(*args, **kw) - - def trace(self, *args: t.Any, **kw: t.Any) -> "TestResponse": - """Call :meth:`open` with ``method`` set to ``TRACE``.""" - kw["method"] = "TRACE" - return self.open(*args, **kw) - - def __repr__(self) -> str: - return f"<{type(self).__name__} {self.application!r}>" - - -def create_environ(*args: t.Any, **kwargs: t.Any) -> "WSGIEnvironment": - """Create a new WSGI environ dict based on the values passed. The first - parameter should be the path of the request which defaults to '/'. The - second one can either be an absolute path (in that case the host is - localhost:80) or a full path to the request with scheme, netloc port and - the path to the script. - - This accepts the same arguments as the :class:`EnvironBuilder` - constructor. - - .. versionchanged:: 0.5 - This function is now a thin wrapper over :class:`EnvironBuilder` which - was added in 0.5. The `headers`, `environ_base`, `environ_overrides` - and `charset` parameters were added. - """ - builder = EnvironBuilder(*args, **kwargs) - - try: - return builder.get_environ() - finally: - builder.close() - - -def run_wsgi_app( - app: "WSGIApplication", environ: "WSGIEnvironment", buffered: bool = False -) -> t.Tuple[t.Iterable[bytes], str, Headers]: - """Return a tuple in the form (app_iter, status, headers) of the - application output. This works best if you pass it an application that - returns an iterator all the time. - - Sometimes applications may use the `write()` callable returned - by the `start_response` function. This tries to resolve such edge - cases automatically. But if you don't get the expected output you - should set `buffered` to `True` which enforces buffering. - - If passed an invalid WSGI application the behavior of this function is - undefined. Never pass non-conforming WSGI applications to this function. - - :param app: the application to execute. - :param buffered: set to `True` to enforce buffering. - :return: tuple in the form ``(app_iter, status, headers)`` - """ - # Copy environ to ensure any mutations by the app (ProxyFix, for - # example) don't affect subsequent requests (such as redirects). - environ = _get_environ(environ).copy() - status: str - response: t.Optional[t.Tuple[str, t.List[t.Tuple[str, str]]]] = None - buffer: t.List[bytes] = [] - - def start_response(status, headers, exc_info=None): # type: ignore - nonlocal response - - if exc_info: - try: - raise exc_info[1].with_traceback(exc_info[2]) - finally: - exc_info = None - - response = (status, headers) - return buffer.append - - app_rv = app(environ, start_response) - close_func = getattr(app_rv, "close", None) - app_iter: t.Iterable[bytes] = iter(app_rv) - - # when buffering we emit the close call early and convert the - # application iterator into a regular list - if buffered: - try: - app_iter = list(app_iter) - finally: - if close_func is not None: - close_func() - - # otherwise we iterate the application iter until we have a response, chain - # the already received data with the already collected data and wrap it in - # a new `ClosingIterator` if we need to restore a `close` callable from the - # original return value. - else: - for item in app_iter: - buffer.append(item) - - if response is not None: - break - - if buffer: - app_iter = chain(buffer, app_iter) - - if close_func is not None and app_iter is not app_rv: - app_iter = ClosingIterator(app_iter, close_func) - - status, headers = response # type: ignore - return app_iter, status, Headers(headers) - - -class TestResponse(Response): - """:class:`~werkzeug.wrappers.Response` subclass that provides extra - information about requests made with the test :class:`Client`. - - Test client requests will always return an instance of this class. - If a custom response class is passed to the client, it is - subclassed along with this to support test information. - - If the test request included large files, or if the application is - serving a file, call :meth:`close` to close any open files and - prevent Python showing a ``ResourceWarning``. - """ - - request: Request - """A request object with the environ used to make the request that - resulted in this response. - """ - - history: t.Tuple["TestResponse", ...] - """A list of intermediate responses. Populated when the test request - is made with ``follow_redirects`` enabled. - """ - - # Tell Pytest to ignore this, it's not a test class. - __test__ = False - - def __init__( - self, - response: t.Iterable[bytes], - status: str, - headers: Headers, - request: Request, - history: t.Tuple["TestResponse"] = (), # type: ignore - **kwargs: t.Any, - ) -> None: - super().__init__(response, status, headers, **kwargs) - self.request = request - self.history = history - self._compat_tuple = response, status, headers - - def __iter__(self) -> t.Iterator: - warnings.warn( - ( - "The test client no longer returns a tuple, it returns" - " a 'TestResponse'. Tuple unpacking is deprecated and" - " will be removed in Werkzeug 2.1. Access the" - " attributes 'data', 'status', and 'headers' instead." - ), - DeprecationWarning, - stacklevel=2, - ) - return iter(self._compat_tuple) - - def __getitem__(self, item: int) -> t.Any: - warnings.warn( - ( - "The test client no longer returns a tuple, it returns" - " a 'TestResponse'. Item indexing is deprecated and" - " will be removed in Werkzeug 2.1. Access the" - " attributes 'data', 'status', and 'headers' instead." - ), - DeprecationWarning, - stacklevel=2, - ) - return self._compat_tuple[item] diff --git a/venv/lib/python3.7/site-packages/werkzeug/testapp.py b/venv/lib/python3.7/site-packages/werkzeug/testapp.py deleted file mode 100644 index 981f887..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/testapp.py +++ /dev/null @@ -1,240 +0,0 @@ -"""A small application that can be used to test a WSGI server and check -it for WSGI compliance. -""" -import base64 -import os -import sys -import typing as t -from html import escape -from textwrap import wrap - -from . import __version__ as _werkzeug_version -from .wrappers.request import Request -from .wrappers.response import Response - -if t.TYPE_CHECKING: - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIEnvironment - - -logo = Response( - base64.b64decode( - """ -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 -=""" - ), - mimetype="image/png", -) - - -TEMPLATE = """\ - -WSGI Information - -
    - -

    WSGI Information

    -

    - This page displays all available information about the WSGI server and - the underlying Python interpreter. -

    Python Interpreter

    - - - - - - -
    Python Version - %(python_version)s -
    Platform - %(platform)s [%(os)s] -
    API Version - %(api_version)s -
    Byteorder - %(byteorder)s -
    Werkzeug Version - %(werkzeug_version)s -
    -

    WSGI Environment

    - %(wsgi_env)s
    -

    Installed Eggs

    -

    - The following python packages were installed on the system as - Python eggs: -

      %(python_eggs)s
    -

    System Path

    -

    - The following paths are the current contents of the load path. The - following entries are looked up for Python packages. Note that not - all items in this path are folders. Gray and underlined items are - entries pointing to invalid resources or used by custom import hooks - such as the zip importer. -

    - Items with a bright background were expanded for display from a relative - path. If you encounter such paths in the output you might want to check - your setup as relative paths are usually problematic in multithreaded - environments. -

      %(sys_path)s
    -
    -""" - - -def iter_sys_path() -> t.Iterator[t.Tuple[str, bool, bool]]: - if os.name == "posix": - - def strip(x: str) -> str: - prefix = os.path.expanduser("~") - if x.startswith(prefix): - x = f"~{x[len(prefix) :]}" - return x - - else: - - def strip(x: str) -> str: - return x - - cwd = os.path.abspath(os.getcwd()) - for item in sys.path: - path = os.path.join(cwd, item or os.path.curdir) - yield strip(os.path.normpath(path)), not os.path.isdir(path), path != item - - -def render_testapp(req: Request) -> bytes: - try: - import pkg_resources - except ImportError: - eggs: t.Iterable[t.Any] = () - else: - eggs = sorted( - pkg_resources.working_set, - key=lambda x: x.project_name.lower(), # type: ignore - ) - python_eggs = [] - for egg in eggs: - try: - version = egg.version - except (ValueError, AttributeError): - version = "unknown" - python_eggs.append( - f"
  • {escape(egg.project_name)} [{escape(version)}]" - ) - - wsgi_env = [] - sorted_environ = sorted(req.environ.items(), key=lambda x: repr(x[0]).lower()) - for key, value in sorted_environ: - value = "".join(wrap(escape(repr(value)))) - wsgi_env.append(f"{escape(str(key))}{value}") - - sys_path = [] - for item, virtual, expanded in iter_sys_path(): - class_ = [] - if virtual: - class_.append("virtual") - if expanded: - class_.append("exp") - class_ = f' class="{" ".join(class_)}"' if class_ else "" - sys_path.append(f"{escape(item)}") - - return ( - TEMPLATE - % { - "python_version": "
    ".join(escape(sys.version).splitlines()), - "platform": escape(sys.platform), - "os": escape(os.name), - "api_version": sys.api_version, - "byteorder": sys.byteorder, - "werkzeug_version": _werkzeug_version, - "python_eggs": "\n".join(python_eggs), - "wsgi_env": "\n".join(wsgi_env), - "sys_path": "\n".join(sys_path), - } - ).encode("utf-8") - - -def test_app( - environ: "WSGIEnvironment", start_response: "StartResponse" -) -> t.Iterable[bytes]: - """Simple test application that dumps the environment. You can use - it to check if Werkzeug is working properly: - - .. sourcecode:: pycon - - >>> from werkzeug.serving import run_simple - >>> from werkzeug.testapp import test_app - >>> run_simple('localhost', 3000, test_app) - * Running on http://localhost:3000/ - - The application displays important information from the WSGI environment, - the Python interpreter and the installed libraries. - """ - req = Request(environ, populate_request=False) - if req.args.get("resource") == "logo": - response = logo - else: - response = Response(render_testapp(req), mimetype="text/html") - return response(environ, start_response) - - -if __name__ == "__main__": - from .serving import run_simple - - run_simple("localhost", 5000, test_app, use_reloader=True) diff --git a/venv/lib/python3.7/site-packages/werkzeug/urls.py b/venv/lib/python3.7/site-packages/werkzeug/urls.py deleted file mode 100644 index 9529da0..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/urls.py +++ /dev/null @@ -1,1211 +0,0 @@ -"""Functions for working with URLs. - -Contains implementations of functions from :mod:`urllib.parse` that -handle bytes and strings. -""" -import codecs -import os -import re -import typing as t -import warnings - -from ._internal import _check_str_tuple -from ._internal import _decode_idna -from ._internal import _encode_idna -from ._internal import _make_encode_wrapper -from ._internal import _to_str - -if t.TYPE_CHECKING: - from . import datastructures as ds - -# A regular expression for what a valid schema looks like -_scheme_re = re.compile(r"^[a-zA-Z0-9+-.]+$") - -# Characters that are safe in any part of an URL. -_always_safe = frozenset( - bytearray( - b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789" - b"-._~" - ) -) - -_hexdigits = "0123456789ABCDEFabcdef" -_hextobyte = { - f"{a}{b}".encode("ascii"): int(f"{a}{b}", 16) - for a in _hexdigits - for b in _hexdigits -} -_bytetohex = [f"%{char:02X}".encode("ascii") for char in range(256)] - - -class _URLTuple(t.NamedTuple): - scheme: str - netloc: str - path: str - query: str - fragment: str - - -class BaseURL(_URLTuple): - """Superclass of :py:class:`URL` and :py:class:`BytesURL`.""" - - __slots__ = () - _at: str - _colon: str - _lbracket: str - _rbracket: str - - def __str__(self) -> str: - return self.to_url() - - def replace(self, **kwargs: t.Any) -> "BaseURL": - """Return an URL with the same values, except for those parameters - given new values by whichever keyword arguments are specified.""" - return self._replace(**kwargs) - - @property - def host(self) -> t.Optional[str]: - """The host part of the URL if available, otherwise `None`. The - host is either the hostname or the IP address mentioned in the - URL. It will not contain the port. - """ - return self._split_host()[0] - - @property - def ascii_host(self) -> t.Optional[str]: - """Works exactly like :attr:`host` but will return a result that - is restricted to ASCII. If it finds a netloc that is not ASCII - it will attempt to idna decode it. This is useful for socket - operations when the URL might include internationalized characters. - """ - rv = self.host - if rv is not None and isinstance(rv, str): - try: - rv = _encode_idna(rv) # type: ignore - except UnicodeError: - rv = rv.encode("ascii", "ignore") # type: ignore - return _to_str(rv, "ascii", "ignore") - - @property - def port(self) -> t.Optional[int]: - """The port in the URL as an integer if it was present, `None` - otherwise. This does not fill in default ports. - """ - try: - rv = int(_to_str(self._split_host()[1])) - if 0 <= rv <= 65535: - return rv - except (ValueError, TypeError): - pass - return None - - @property - def auth(self) -> t.Optional[str]: - """The authentication part in the URL if available, `None` - otherwise. - """ - return self._split_netloc()[0] - - @property - def username(self) -> t.Optional[str]: - """The username if it was part of the URL, `None` otherwise. - This undergoes URL decoding and will always be a string. - """ - rv = self._split_auth()[0] - if rv is not None: - return _url_unquote_legacy(rv) - return None - - @property - def raw_username(self) -> t.Optional[str]: - """The username if it was part of the URL, `None` otherwise. - Unlike :attr:`username` this one is not being decoded. - """ - return self._split_auth()[0] - - @property - def password(self) -> t.Optional[str]: - """The password if it was part of the URL, `None` otherwise. - This undergoes URL decoding and will always be a string. - """ - rv = self._split_auth()[1] - if rv is not None: - return _url_unquote_legacy(rv) - return None - - @property - def raw_password(self) -> t.Optional[str]: - """The password if it was part of the URL, `None` otherwise. - Unlike :attr:`password` this one is not being decoded. - """ - return self._split_auth()[1] - - def decode_query(self, *args: t.Any, **kwargs: t.Any) -> "ds.MultiDict[str, str]": - """Decodes the query part of the URL. Ths is a shortcut for - calling :func:`url_decode` on the query argument. The arguments and - keyword arguments are forwarded to :func:`url_decode` unchanged. - """ - return url_decode(self.query, *args, **kwargs) - - def join(self, *args: t.Any, **kwargs: t.Any) -> "BaseURL": - """Joins this URL with another one. This is just a convenience - function for calling into :meth:`url_join` and then parsing the - return value again. - """ - return url_parse(url_join(self, *args, **kwargs)) - - def to_url(self) -> str: - """Returns a URL string or bytes depending on the type of the - information stored. This is just a convenience function - for calling :meth:`url_unparse` for this URL. - """ - return url_unparse(self) - - def encode_netloc(self) -> str: - """Encodes the netloc part to an ASCII safe URL as bytes.""" - rv = self.ascii_host or "" - if ":" in rv: - rv = f"[{rv}]" - port = self.port - if port is not None: - rv = f"{rv}:{port}" - auth = ":".join( - filter( - None, - [ - url_quote(self.raw_username or "", "utf-8", "strict", "/:%"), - url_quote(self.raw_password or "", "utf-8", "strict", "/:%"), - ], - ) - ) - if auth: - rv = f"{auth}@{rv}" - return rv - - def decode_netloc(self) -> str: - """Decodes the netloc part into a string.""" - rv = _decode_idna(self.host or "") - - if ":" in rv: - rv = f"[{rv}]" - port = self.port - if port is not None: - rv = f"{rv}:{port}" - auth = ":".join( - filter( - None, - [ - _url_unquote_legacy(self.raw_username or "", "/:%@"), - _url_unquote_legacy(self.raw_password or "", "/:%@"), - ], - ) - ) - if auth: - rv = f"{auth}@{rv}" - return rv - - def to_uri_tuple(self) -> "BaseURL": - """Returns a :class:`BytesURL` tuple that holds a URI. This will - encode all the information in the URL properly to ASCII using the - rules a web browser would follow. - - It's usually more interesting to directly call :meth:`iri_to_uri` which - will return a string. - """ - return url_parse(iri_to_uri(self)) - - def to_iri_tuple(self) -> "BaseURL": - """Returns a :class:`URL` tuple that holds a IRI. This will try - to decode as much information as possible in the URL without - losing information similar to how a web browser does it for the - URL bar. - - It's usually more interesting to directly call :meth:`uri_to_iri` which - will return a string. - """ - return url_parse(uri_to_iri(self)) - - def get_file_location( - self, pathformat: t.Optional[str] = None - ) -> t.Tuple[t.Optional[str], t.Optional[str]]: - """Returns a tuple with the location of the file in the form - ``(server, location)``. If the netloc is empty in the URL or - points to localhost, it's represented as ``None``. - - The `pathformat` by default is autodetection but needs to be set - when working with URLs of a specific system. The supported values - are ``'windows'`` when working with Windows or DOS paths and - ``'posix'`` when working with posix paths. - - If the URL does not point to a local file, the server and location - are both represented as ``None``. - - :param pathformat: The expected format of the path component. - Currently ``'windows'`` and ``'posix'`` are - supported. Defaults to ``None`` which is - autodetect. - """ - if self.scheme != "file": - return None, None - - path = url_unquote(self.path) - host = self.netloc or None - - if pathformat is None: - if os.name == "nt": - pathformat = "windows" - else: - pathformat = "posix" - - if pathformat == "windows": - if path[:1] == "/" and path[1:2].isalpha() and path[2:3] in "|:": - path = f"{path[1:2]}:{path[3:]}" - windows_share = path[:3] in ("\\" * 3, "/" * 3) - import ntpath - - path = ntpath.normpath(path) - # Windows shared drives are represented as ``\\host\\directory``. - # That results in a URL like ``file://///host/directory``, and a - # path like ``///host/directory``. We need to special-case this - # because the path contains the hostname. - if windows_share and host is None: - parts = path.lstrip("\\").split("\\", 1) - if len(parts) == 2: - host, path = parts - else: - host = parts[0] - path = "" - elif pathformat == "posix": - import posixpath - - path = posixpath.normpath(path) - else: - raise TypeError(f"Invalid path format {pathformat!r}") - - if host in ("127.0.0.1", "::1", "localhost"): - host = None - - return host, path - - def _split_netloc(self) -> t.Tuple[t.Optional[str], str]: - if self._at in self.netloc: - auth, _, netloc = self.netloc.partition(self._at) - return auth, netloc - return None, self.netloc - - def _split_auth(self) -> t.Tuple[t.Optional[str], t.Optional[str]]: - auth = self._split_netloc()[0] - if not auth: - return None, None - if self._colon not in auth: - return auth, None - - username, _, password = auth.partition(self._colon) - return username, password - - def _split_host(self) -> t.Tuple[t.Optional[str], t.Optional[str]]: - rv = self._split_netloc()[1] - if not rv: - return None, None - - if not rv.startswith(self._lbracket): - if self._colon in rv: - host, _, port = rv.partition(self._colon) - return host, port - return rv, None - - idx = rv.find(self._rbracket) - if idx < 0: - return rv, None - - host = rv[1:idx] - rest = rv[idx + 1 :] - if rest.startswith(self._colon): - return host, rest[1:] - return host, None - - -class URL(BaseURL): - """Represents a parsed URL. This behaves like a regular tuple but - also has some extra attributes that give further insight into the - URL. - """ - - __slots__ = () - _at = "@" - _colon = ":" - _lbracket = "[" - _rbracket = "]" - - def encode(self, charset: str = "utf-8", errors: str = "replace") -> "BytesURL": - """Encodes the URL to a tuple made out of bytes. The charset is - only being used for the path, query and fragment. - """ - return BytesURL( - self.scheme.encode("ascii"), # type: ignore - self.encode_netloc(), - self.path.encode(charset, errors), # type: ignore - self.query.encode(charset, errors), # type: ignore - self.fragment.encode(charset, errors), # type: ignore - ) - - -class BytesURL(BaseURL): - """Represents a parsed URL in bytes.""" - - __slots__ = () - _at = b"@" # type: ignore - _colon = b":" # type: ignore - _lbracket = b"[" # type: ignore - _rbracket = b"]" # type: ignore - - def __str__(self) -> str: - return self.to_url().decode("utf-8", "replace") # type: ignore - - def encode_netloc(self) -> bytes: # type: ignore - """Returns the netloc unchanged as bytes.""" - return self.netloc # type: ignore - - def decode(self, charset: str = "utf-8", errors: str = "replace") -> "URL": - """Decodes the URL to a tuple made out of strings. The charset is - only being used for the path, query and fragment. - """ - return URL( - self.scheme.decode("ascii"), # type: ignore - self.decode_netloc(), - self.path.decode(charset, errors), # type: ignore - self.query.decode(charset, errors), # type: ignore - self.fragment.decode(charset, errors), # type: ignore - ) - - -_unquote_maps: t.Dict[t.FrozenSet[int], t.Dict[bytes, int]] = {frozenset(): _hextobyte} - - -def _unquote_to_bytes( - string: t.Union[str, bytes], unsafe: t.Union[str, bytes] = "" -) -> bytes: - if isinstance(string, str): - string = string.encode("utf-8") - - if isinstance(unsafe, str): - unsafe = unsafe.encode("utf-8") - - unsafe = frozenset(bytearray(unsafe)) - groups = iter(string.split(b"%")) - result = bytearray(next(groups, b"")) - - try: - hex_to_byte = _unquote_maps[unsafe] - except KeyError: - hex_to_byte = _unquote_maps[unsafe] = { - h: b for h, b in _hextobyte.items() if b not in unsafe - } - - for group in groups: - code = group[:2] - - if code in hex_to_byte: - result.append(hex_to_byte[code]) - result.extend(group[2:]) - else: - result.append(37) # % - result.extend(group) - - return bytes(result) - - -def _url_encode_impl( - obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], - charset: str, - sort: bool, - key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]], -) -> t.Iterator[str]: - from .datastructures import iter_multi_items - - iterable: t.Iterable[t.Tuple[str, str]] = iter_multi_items(obj) - - if sort: - iterable = sorted(iterable, key=key) - - for key_str, value_str in iterable: - if value_str is None: - continue - - if not isinstance(key_str, bytes): - key_bytes = str(key_str).encode(charset) - else: - key_bytes = key_str - - if not isinstance(value_str, bytes): - value_bytes = str(value_str).encode(charset) - else: - value_bytes = value_str - - yield f"{_fast_url_quote_plus(key_bytes)}={_fast_url_quote_plus(value_bytes)}" - - -def _url_unquote_legacy(value: str, unsafe: str = "") -> str: - try: - return url_unquote(value, charset="utf-8", errors="strict", unsafe=unsafe) - except UnicodeError: - return url_unquote(value, charset="latin1", unsafe=unsafe) - - -def url_parse( - url: str, scheme: t.Optional[str] = None, allow_fragments: bool = True -) -> BaseURL: - """Parses a URL from a string into a :class:`URL` tuple. If the URL - is lacking a scheme it can be provided as second argument. Otherwise, - it is ignored. Optionally fragments can be stripped from the URL - by setting `allow_fragments` to `False`. - - The inverse of this function is :func:`url_unparse`. - - :param url: the URL to parse. - :param scheme: the default schema to use if the URL is schemaless. - :param allow_fragments: if set to `False` a fragment will be removed - from the URL. - """ - s = _make_encode_wrapper(url) - is_text_based = isinstance(url, str) - - if scheme is None: - scheme = s("") - netloc = query = fragment = s("") - i = url.find(s(":")) - if i > 0 and _scheme_re.match(_to_str(url[:i], errors="replace")): - # make sure "iri" is not actually a port number (in which case - # "scheme" is really part of the path) - rest = url[i + 1 :] - if not rest or any(c not in s("0123456789") for c in rest): - # not a port number - scheme, url = url[:i].lower(), rest - - if url[:2] == s("//"): - delim = len(url) - for c in s("/?#"): - wdelim = url.find(c, 2) - if wdelim >= 0: - delim = min(delim, wdelim) - netloc, url = url[2:delim], url[delim:] - if (s("[") in netloc and s("]") not in netloc) or ( - s("]") in netloc and s("[") not in netloc - ): - raise ValueError("Invalid IPv6 URL") - - if allow_fragments and s("#") in url: - url, fragment = url.split(s("#"), 1) - if s("?") in url: - url, query = url.split(s("?"), 1) - - result_type = URL if is_text_based else BytesURL - return result_type(scheme, netloc, url, query, fragment) - - -def _make_fast_url_quote( - charset: str = "utf-8", - errors: str = "strict", - safe: t.Union[str, bytes] = "/:", - unsafe: t.Union[str, bytes] = "", -) -> t.Callable[[bytes], str]: - """Precompile the translation table for a URL encoding function. - - Unlike :func:`url_quote`, the generated function only takes the - string to quote. - - :param charset: The charset to encode the result with. - :param errors: How to handle encoding errors. - :param safe: An optional sequence of safe characters to never encode. - :param unsafe: An optional sequence of unsafe characters to always encode. - """ - if isinstance(safe, str): - safe = safe.encode(charset, errors) - - if isinstance(unsafe, str): - unsafe = unsafe.encode(charset, errors) - - safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) - table = [chr(c) if c in safe else f"%{c:02X}" for c in range(256)] - - def quote(string: bytes) -> str: - return "".join([table[c] for c in string]) - - return quote - - -_fast_url_quote = _make_fast_url_quote() -_fast_quote_plus = _make_fast_url_quote(safe=" ", unsafe="+") - - -def _fast_url_quote_plus(string: bytes) -> str: - return _fast_quote_plus(string).replace(" ", "+") - - -def url_quote( - string: t.Union[str, bytes], - charset: str = "utf-8", - errors: str = "strict", - safe: t.Union[str, bytes] = "/:", - unsafe: t.Union[str, bytes] = "", -) -> str: - """URL encode a single string with a given encoding. - - :param s: the string to quote. - :param charset: the charset to be used. - :param safe: an optional sequence of safe characters. - :param unsafe: an optional sequence of unsafe characters. - - .. versionadded:: 0.9.2 - The `unsafe` parameter was added. - """ - if not isinstance(string, (str, bytes, bytearray)): - string = str(string) - if isinstance(string, str): - string = string.encode(charset, errors) - if isinstance(safe, str): - safe = safe.encode(charset, errors) - if isinstance(unsafe, str): - unsafe = unsafe.encode(charset, errors) - safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) - rv = bytearray() - for char in bytearray(string): - if char in safe: - rv.append(char) - else: - rv.extend(_bytetohex[char]) - return bytes(rv).decode(charset) - - -def url_quote_plus( - string: str, charset: str = "utf-8", errors: str = "strict", safe: str = "" -) -> str: - """URL encode a single string with the given encoding and convert - whitespace to "+". - - :param s: The string to quote. - :param charset: The charset to be used. - :param safe: An optional sequence of safe characters. - """ - return url_quote(string, charset, errors, safe + " ", "+").replace(" ", "+") - - -def url_unparse(components: t.Tuple[str, str, str, str, str]) -> str: - """The reverse operation to :meth:`url_parse`. This accepts arbitrary - as well as :class:`URL` tuples and returns a URL as a string. - - :param components: the parsed URL as tuple which should be converted - into a URL string. - """ - _check_str_tuple(components) - scheme, netloc, path, query, fragment = components - s = _make_encode_wrapper(scheme) - url = s("") - - # We generally treat file:///x and file:/x the same which is also - # what browsers seem to do. This also allows us to ignore a schema - # register for netloc utilization or having to differentiate between - # empty and missing netloc. - if netloc or (scheme and path.startswith(s("/"))): - if path and path[:1] != s("/"): - path = s("/") + path - url = s("//") + (netloc or s("")) + path - elif path: - url += path - if scheme: - url = scheme + s(":") + url - if query: - url = url + s("?") + query - if fragment: - url = url + s("#") + fragment - return url - - -def url_unquote( - s: t.Union[str, bytes], - charset: str = "utf-8", - errors: str = "replace", - unsafe: str = "", -) -> str: - """URL decode a single string with a given encoding. If the charset - is set to `None` no decoding is performed and raw bytes are - returned. - - :param s: the string to unquote. - :param charset: the charset of the query string. If set to `None` - no decoding will take place. - :param errors: the error handling for the charset decoding. - """ - rv = _unquote_to_bytes(s, unsafe) - if charset is None: - return rv - return rv.decode(charset, errors) - - -def url_unquote_plus( - s: t.Union[str, bytes], charset: str = "utf-8", errors: str = "replace" -) -> str: - """URL decode a single string with the given `charset` and decode "+" to - whitespace. - - Per default encoding errors are ignored. If you want a different behavior - you can set `errors` to ``'replace'`` or ``'strict'``. - - :param s: The string to unquote. - :param charset: the charset of the query string. If set to `None` - no decoding will take place. - :param errors: The error handling for the `charset` decoding. - """ - if isinstance(s, str): - s = s.replace("+", " ") - else: - s = s.replace(b"+", b" ") - return url_unquote(s, charset, errors) - - -def url_fix(s: str, charset: str = "utf-8") -> str: - r"""Sometimes you get an URL by a user that just isn't a real URL because - it contains unsafe characters like ' ' and so on. This function can fix - some of the problems in a similar way browsers handle data entered by the - user: - - >>> url_fix('http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)') - 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)' - - :param s: the string with the URL to fix. - :param charset: The target charset for the URL if the url was given - as a string. - """ - # First step is to switch to text processing and to convert - # backslashes (which are invalid in URLs anyways) to slashes. This is - # consistent with what Chrome does. - s = _to_str(s, charset, "replace").replace("\\", "/") - - # For the specific case that we look like a malformed windows URL - # we want to fix this up manually: - if s.startswith("file://") and s[7:8].isalpha() and s[8:10] in (":/", "|/"): - s = f"file:///{s[7:]}" - - url = url_parse(s) - path = url_quote(url.path, charset, safe="/%+$!*'(),") - qs = url_quote_plus(url.query, charset, safe=":&%=+$!*'(),") - anchor = url_quote_plus(url.fragment, charset, safe=":&%=+$!*'(),") - return url_unparse((url.scheme, url.encode_netloc(), path, qs, anchor)) - - -# not-unreserved characters remain quoted when unquoting to IRI -_to_iri_unsafe = "".join([chr(c) for c in range(128) if c not in _always_safe]) - - -def _codec_error_url_quote(e: UnicodeError) -> t.Tuple[str, int]: - """Used in :func:`uri_to_iri` after unquoting to re-quote any - invalid bytes. - """ - # the docs state that UnicodeError does have these attributes, - # but mypy isn't picking them up - out = _fast_url_quote(e.object[e.start : e.end]) # type: ignore - return out, e.end # type: ignore - - -codecs.register_error("werkzeug.url_quote", _codec_error_url_quote) - - -def uri_to_iri( - uri: t.Union[str, t.Tuple[str, str, str, str, str]], - charset: str = "utf-8", - errors: str = "werkzeug.url_quote", -) -> str: - """Convert a URI to an IRI. All valid UTF-8 characters are unquoted, - leaving all reserved and invalid characters quoted. If the URL has - a domain, it is decoded from Punycode. - - >>> uri_to_iri("http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF") - 'http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF' - - :param uri: The URI to convert. - :param charset: The encoding to encode unquoted bytes with. - :param errors: Error handler to use during ``bytes.encode``. By - default, invalid bytes are left quoted. - - .. versionchanged:: 0.15 - All reserved and invalid characters remain quoted. Previously, - only some reserved characters were preserved, and invalid bytes - were replaced instead of left quoted. - - .. versionadded:: 0.6 - """ - if isinstance(uri, tuple): - uri = url_unparse(uri) - - uri = url_parse(_to_str(uri, charset)) - path = url_unquote(uri.path, charset, errors, _to_iri_unsafe) - query = url_unquote(uri.query, charset, errors, _to_iri_unsafe) - fragment = url_unquote(uri.fragment, charset, errors, _to_iri_unsafe) - return url_unparse((uri.scheme, uri.decode_netloc(), path, query, fragment)) - - -# reserved characters remain unquoted when quoting to URI -_to_uri_safe = ":/?#[]@!$&'()*+,;=%" - - -def iri_to_uri( - iri: t.Union[str, t.Tuple[str, str, str, str, str]], - charset: str = "utf-8", - errors: str = "strict", - safe_conversion: bool = False, -) -> str: - """Convert an IRI to a URI. All non-ASCII and unsafe characters are - quoted. If the URL has a domain, it is encoded to Punycode. - - >>> iri_to_uri('http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF') - 'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF' - - :param iri: The IRI to convert. - :param charset: The encoding of the IRI. - :param errors: Error handler to use during ``bytes.encode``. - :param safe_conversion: Return the URL unchanged if it only contains - ASCII characters and no whitespace. See the explanation below. - - There is a general problem with IRI conversion with some protocols - that are in violation of the URI specification. Consider the - following two IRIs:: - - magnet:?xt=uri:whatever - itms-services://?action=download-manifest - - After parsing, we don't know if the scheme requires the ``//``, - which is dropped if empty, but conveys different meanings in the - final URL if it's present or not. In this case, you can use - ``safe_conversion``, which will return the URL unchanged if it only - contains ASCII characters and no whitespace. This can result in a - URI with unquoted characters if it was not already quoted correctly, - but preserves the URL's semantics. Werkzeug uses this for the - ``Location`` header for redirects. - - .. versionchanged:: 0.15 - All reserved characters remain unquoted. Previously, only some - reserved characters were left unquoted. - - .. versionchanged:: 0.9.6 - The ``safe_conversion`` parameter was added. - - .. versionadded:: 0.6 - """ - if isinstance(iri, tuple): - iri = url_unparse(iri) - - if safe_conversion: - # If we're not sure if it's safe to convert the URL, and it only - # contains ASCII characters, return it unconverted. - try: - native_iri = _to_str(iri) - ascii_iri = native_iri.encode("ascii") - - # Only return if it doesn't have whitespace. (Why?) - if len(ascii_iri.split()) == 1: - return native_iri - except UnicodeError: - pass - - iri = url_parse(_to_str(iri, charset, errors)) - path = url_quote(iri.path, charset, errors, _to_uri_safe) - query = url_quote(iri.query, charset, errors, _to_uri_safe) - fragment = url_quote(iri.fragment, charset, errors, _to_uri_safe) - return url_unparse((iri.scheme, iri.encode_netloc(), path, query, fragment)) - - -def url_decode( - s: t.AnyStr, - charset: str = "utf-8", - decode_keys: None = None, - include_empty: bool = True, - errors: str = "replace", - separator: str = "&", - cls: t.Optional[t.Type["ds.MultiDict"]] = None, -) -> "ds.MultiDict[str, str]": - """Parse a query string and return it as a :class:`MultiDict`. - - :param s: The query string to parse. - :param charset: Decode bytes to string with this charset. If not - given, bytes are returned as-is. - :param include_empty: Include keys with empty values in the dict. - :param errors: Error handling behavior when decoding bytes. - :param separator: Separator character between pairs. - :param cls: Container to hold result instead of :class:`MultiDict`. - - .. versionchanged:: 2.0 - The ``decode_keys`` parameter is deprecated and will be removed - in Werkzeug 2.1. - - .. versionchanged:: 0.5 - In previous versions ";" and "&" could be used for url decoding. - Now only "&" is supported. If you want to use ";", a different - ``separator`` can be provided. - - .. versionchanged:: 0.5 - The ``cls`` parameter was added. - """ - if decode_keys is not None: - warnings.warn( - "'decode_keys' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - if cls is None: - from .datastructures import MultiDict # noqa: F811 - - cls = MultiDict - if isinstance(s, str) and not isinstance(separator, str): - separator = separator.decode(charset or "ascii") - elif isinstance(s, bytes) and not isinstance(separator, bytes): - separator = separator.encode(charset or "ascii") # type: ignore - return cls( - _url_decode_impl( - s.split(separator), charset, include_empty, errors # type: ignore - ) - ) - - -def url_decode_stream( - stream: t.IO[bytes], - charset: str = "utf-8", - decode_keys: None = None, - include_empty: bool = True, - errors: str = "replace", - separator: bytes = b"&", - cls: t.Optional[t.Type["ds.MultiDict"]] = None, - limit: t.Optional[int] = None, - return_iterator: bool = False, -) -> "ds.MultiDict[str, str]": - """Works like :func:`url_decode` but decodes a stream. The behavior - of stream and limit follows functions like - :func:`~werkzeug.wsgi.make_line_iter`. The generator of pairs is - directly fed to the `cls` so you can consume the data while it's - parsed. - - :param stream: a stream with the encoded querystring - :param charset: the charset of the query string. If set to `None` - no decoding will take place. - :param include_empty: Set to `False` if you don't want empty values to - appear in the dict. - :param errors: the decoding error behavior. - :param separator: the pair separator to be used, defaults to ``&`` - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param limit: the content length of the URL data. Not necessary if - a limited stream is provided. - - .. versionchanged:: 2.0 - The ``decode_keys`` and ``return_iterator`` parameters are - deprecated and will be removed in Werkzeug 2.1. - - .. versionadded:: 0.8 - """ - from .wsgi import make_chunk_iter - - if decode_keys is not None: - warnings.warn( - "'decode_keys' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - - pair_iter = make_chunk_iter(stream, separator, limit) - decoder = _url_decode_impl(pair_iter, charset, include_empty, errors) - - if return_iterator: - warnings.warn( - "'return_iterator' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return decoder # type: ignore - - if cls is None: - from .datastructures import MultiDict # noqa: F811 - - cls = MultiDict - - return cls(decoder) - - -def _url_decode_impl( - pair_iter: t.Iterable[t.AnyStr], charset: str, include_empty: bool, errors: str -) -> t.Iterator[t.Tuple[str, str]]: - for pair in pair_iter: - if not pair: - continue - s = _make_encode_wrapper(pair) - equal = s("=") - if equal in pair: - key, value = pair.split(equal, 1) - else: - if not include_empty: - continue - key = pair - value = s("") - yield ( - url_unquote_plus(key, charset, errors), - url_unquote_plus(value, charset, errors), - ) - - -def url_encode( - obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], - charset: str = "utf-8", - encode_keys: None = None, - sort: bool = False, - key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]] = None, - separator: str = "&", -) -> str: - """URL encode a dict/`MultiDict`. If a value is `None` it will not appear - in the result string. Per default only values are encoded into the target - charset strings. - - :param obj: the object to encode into a query string. - :param charset: the charset of the query string. - :param sort: set to `True` if you want parameters to be sorted by `key`. - :param separator: the separator to be used for the pairs. - :param key: an optional function to be used for sorting. For more details - check out the :func:`sorted` documentation. - - .. versionchanged:: 2.0 - The ``encode_keys`` parameter is deprecated and will be removed - in Werkzeug 2.1. - - .. versionchanged:: 0.5 - Added the ``sort``, ``key``, and ``separator`` parameters. - """ - if encode_keys is not None: - warnings.warn( - "'encode_keys' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - separator = _to_str(separator, "ascii") - return separator.join(_url_encode_impl(obj, charset, sort, key)) - - -def url_encode_stream( - obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], - stream: t.Optional[t.IO[str]] = None, - charset: str = "utf-8", - encode_keys: None = None, - sort: bool = False, - key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]] = None, - separator: str = "&", -) -> None: - """Like :meth:`url_encode` but writes the results to a stream - object. If the stream is `None` a generator over all encoded - pairs is returned. - - :param obj: the object to encode into a query string. - :param stream: a stream to write the encoded object into or `None` if - an iterator over the encoded pairs should be returned. In - that case the separator argument is ignored. - :param charset: the charset of the query string. - :param sort: set to `True` if you want parameters to be sorted by `key`. - :param separator: the separator to be used for the pairs. - :param key: an optional function to be used for sorting. For more details - check out the :func:`sorted` documentation. - - .. versionchanged:: 2.0 - The ``encode_keys`` parameter is deprecated and will be removed - in Werkzeug 2.1. - - .. versionadded:: 0.8 - """ - if encode_keys is not None: - warnings.warn( - "'encode_keys' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - separator = _to_str(separator, "ascii") - gen = _url_encode_impl(obj, charset, sort, key) - if stream is None: - return gen # type: ignore - for idx, chunk in enumerate(gen): - if idx: - stream.write(separator) - stream.write(chunk) - return None - - -def url_join( - base: t.Union[str, t.Tuple[str, str, str, str, str]], - url: t.Union[str, t.Tuple[str, str, str, str, str]], - allow_fragments: bool = True, -) -> str: - """Join a base URL and a possibly relative URL to form an absolute - interpretation of the latter. - - :param base: the base URL for the join operation. - :param url: the URL to join. - :param allow_fragments: indicates whether fragments should be allowed. - """ - if isinstance(base, tuple): - base = url_unparse(base) - if isinstance(url, tuple): - url = url_unparse(url) - - _check_str_tuple((base, url)) - s = _make_encode_wrapper(base) - - if not base: - return url - if not url: - return base - - bscheme, bnetloc, bpath, bquery, bfragment = url_parse( - base, allow_fragments=allow_fragments - ) - scheme, netloc, path, query, fragment = url_parse(url, bscheme, allow_fragments) - if scheme != bscheme: - return url - if netloc: - return url_unparse((scheme, netloc, path, query, fragment)) - netloc = bnetloc - - if path[:1] == s("/"): - segments = path.split(s("/")) - elif not path: - segments = bpath.split(s("/")) - if not query: - query = bquery - else: - segments = bpath.split(s("/"))[:-1] + path.split(s("/")) - - # If the rightmost part is "./" we want to keep the slash but - # remove the dot. - if segments[-1] == s("."): - segments[-1] = s("") - - # Resolve ".." and "." - segments = [segment for segment in segments if segment != s(".")] - while True: - i = 1 - n = len(segments) - 1 - while i < n: - if segments[i] == s("..") and segments[i - 1] not in (s(""), s("..")): - del segments[i - 1 : i + 1] - break - i += 1 - else: - break - - # Remove trailing ".." if the URL is absolute - unwanted_marker = [s(""), s("..")] - while segments[:2] == unwanted_marker: - del segments[1] - - path = s("/").join(segments) - return url_unparse((scheme, netloc, path, query, fragment)) - - -class Href: - """Implements a callable that constructs URLs with the given base. The - function can be called with any number of positional and keyword - arguments which than are used to assemble the URL. Works with URLs - and posix paths. - - Positional arguments are appended as individual segments to - the path of the URL: - - >>> href = Href('/foo') - >>> href('bar', 23) - '/foo/bar/23' - >>> href('foo', bar=23) - '/foo/foo?bar=23' - - If any of the arguments (positional or keyword) evaluates to `None` it - will be skipped. If no keyword arguments are given the last argument - can be a :class:`dict` or :class:`MultiDict` (or any other dict subclass), - otherwise the keyword arguments are used for the query parameters, cutting - off the first trailing underscore of the parameter name: - - >>> href(is_=42) - '/foo?is=42' - >>> href({'foo': 'bar'}) - '/foo?foo=bar' - - Combining of both methods is not allowed: - - >>> href({'foo': 'bar'}, bar=42) - Traceback (most recent call last): - ... - TypeError: keyword arguments and query-dicts can't be combined - - Accessing attributes on the href object creates a new href object with - the attribute name as prefix: - - >>> bar_href = href.bar - >>> bar_href("blub") - '/foo/bar/blub' - - If `sort` is set to `True` the items are sorted by `key` or the default - sorting algorithm: - - >>> href = Href("/", sort=True) - >>> href(a=1, b=2, c=3) - '/?a=1&b=2&c=3' - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :mod:`werkzeug.routing` - instead. - - .. versionadded:: 0.5 - `sort` and `key` were added. - """ - - def __init__( # type: ignore - self, base="./", charset="utf-8", sort=False, key=None - ): - warnings.warn( - "'Href' is deprecated and will be removed in Werkzeug 2.1." - " Use 'werkzeug.routing' instead.", - DeprecationWarning, - stacklevel=2, - ) - - if not base: - base = "./" - self.base = base - self.charset = charset - self.sort = sort - self.key = key - - def __getattr__(self, name): # type: ignore - if name[:2] == "__": - raise AttributeError(name) - base = self.base - if base[-1:] != "/": - base += "/" - return Href(url_join(base, name), self.charset, self.sort, self.key) - - def __call__(self, *path, **query): # type: ignore - if path and isinstance(path[-1], dict): - if query: - raise TypeError("keyword arguments and query-dicts can't be combined") - query, path = path[-1], path[:-1] - elif query: - query = {k[:-1] if k.endswith("_") else k: v for k, v in query.items()} - path = "/".join( - [ - _to_str(url_quote(x, self.charset), "ascii") - for x in path - if x is not None - ] - ).lstrip("/") - rv = self.base - if path: - if not rv.endswith("/"): - rv += "/" - rv = url_join(rv, f"./{path}") - if query: - rv += "?" + _to_str( - url_encode(query, self.charset, sort=self.sort, key=self.key), "ascii" - ) - return rv diff --git a/venv/lib/python3.7/site-packages/werkzeug/user_agent.py b/venv/lib/python3.7/site-packages/werkzeug/user_agent.py deleted file mode 100644 index 66ffcbe..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/user_agent.py +++ /dev/null @@ -1,47 +0,0 @@ -import typing as t - - -class UserAgent: - """Represents a parsed user agent header value. - - The default implementation does no parsing, only the :attr:`string` - attribute is set. A subclass may parse the string to set the - common attributes or expose other information. Set - :attr:`werkzeug.wrappers.Request.user_agent_class` to use a - subclass. - - :param string: The header value to parse. - - .. versionadded:: 2.0 - This replaces the previous ``useragents`` module, but does not - provide a built-in parser. - """ - - platform: t.Optional[str] = None - """The OS name, if it could be parsed from the string.""" - - browser: t.Optional[str] = None - """The browser name, if it could be parsed from the string.""" - - version: t.Optional[str] = None - """The browser version, if it could be parsed from the string.""" - - language: t.Optional[str] = None - """The browser language, if it could be parsed from the string.""" - - def __init__(self, string: str) -> None: - self.string: str = string - """The original header value.""" - - def __repr__(self) -> str: - return f"<{type(self).__name__} {self.browser}/{self.version}>" - - def __str__(self) -> str: - return self.string - - def __bool__(self) -> bool: - return bool(self.browser) - - def to_header(self) -> str: - """Convert to a header value.""" - return self.string diff --git a/venv/lib/python3.7/site-packages/werkzeug/useragents.py b/venv/lib/python3.7/site-packages/werkzeug/useragents.py deleted file mode 100644 index 4deed8f..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/useragents.py +++ /dev/null @@ -1,215 +0,0 @@ -import re -import typing as t -import warnings - -from .user_agent import UserAgent as _BaseUserAgent - -if t.TYPE_CHECKING: - from _typeshed.wsgi import WSGIEnvironment - - -class _UserAgentParser: - platform_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = ( - (" cros ", "chromeos"), - ("iphone|ios", "iphone"), - ("ipad", "ipad"), - (r"darwin\b|mac\b|os\s*x", "macos"), - ("win", "windows"), - (r"android", "android"), - ("netbsd", "netbsd"), - ("openbsd", "openbsd"), - ("freebsd", "freebsd"), - ("dragonfly", "dragonflybsd"), - ("(sun|i86)os", "solaris"), - (r"x11\b|lin(\b|ux)?", "linux"), - (r"nintendo\s+wii", "wii"), - ("irix", "irix"), - ("hp-?ux", "hpux"), - ("aix", "aix"), - ("sco|unix_sv", "sco"), - ("bsd", "bsd"), - ("amiga", "amiga"), - ("blackberry|playbook", "blackberry"), - ("symbian", "symbian"), - ) - browser_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = ( - ("googlebot", "google"), - ("msnbot", "msn"), - ("yahoo", "yahoo"), - ("ask jeeves", "ask"), - (r"aol|america\s+online\s+browser", "aol"), - (r"opera|opr", "opera"), - ("edge|edg", "edge"), - ("chrome|crios", "chrome"), - ("seamonkey", "seamonkey"), - ("firefox|firebird|phoenix|iceweasel", "firefox"), - ("galeon", "galeon"), - ("safari|version", "safari"), - ("webkit", "webkit"), - ("camino", "camino"), - ("konqueror", "konqueror"), - ("k-meleon", "kmeleon"), - ("netscape", "netscape"), - (r"msie|microsoft\s+internet\s+explorer|trident/.+? rv:", "msie"), - ("lynx", "lynx"), - ("links", "links"), - ("Baiduspider", "baidu"), - ("bingbot", "bing"), - ("mozilla", "mozilla"), - ) - - _browser_version_re = r"(?:{pattern})[/\sa-z(]*(\d+[.\da-z]+)?" - _language_re = re.compile( - r"(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|" - r"(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)" - ) - - def __init__(self) -> None: - self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platform_rules] - self.browsers = [ - (b, re.compile(self._browser_version_re.format(pattern=a), re.I)) - for a, b in self.browser_rules - ] - - def __call__( - self, user_agent: str - ) -> t.Tuple[t.Optional[str], t.Optional[str], t.Optional[str], t.Optional[str]]: - platform: t.Optional[str] - browser: t.Optional[str] - version: t.Optional[str] - language: t.Optional[str] - - for platform, regex in self.platforms: # noqa: B007 - match = regex.search(user_agent) - if match is not None: - break - else: - platform = None - - # Except for Trident, all browser key words come after the last ')' - last_closing_paren = 0 - if ( - not re.compile(r"trident/.+? rv:", re.I).search(user_agent) - and ")" in user_agent - and user_agent[-1] != ")" - ): - last_closing_paren = user_agent.rindex(")") - - for browser, regex in self.browsers: # noqa: B007 - match = regex.search(user_agent[last_closing_paren:]) - if match is not None: - version = match.group(1) - break - else: - browser = version = None - match = self._language_re.search(user_agent) - if match is not None: - language = match.group(1) or match.group(2) - else: - language = None - return platform, browser, version, language - - -# It wasn't public, but users might have imported it anyway, show a -# warning if a user created an instance. -class UserAgentParser(_UserAgentParser): - """A simple user agent parser. Used by the `UserAgent`. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use a dedicated parser library - instead. - """ - - def __init__(self) -> None: - warnings.warn( - "'UserAgentParser' is deprecated and will be removed in" - " Werkzeug 2.1. Use a dedicated parser library instead.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__() - - -class _deprecated_property(property): - def __init__(self, fget: t.Callable[["_UserAgent"], t.Any]) -> None: - super().__init__(fget) - self.message = ( - "The built-in user agent parser is deprecated and will be" - f" removed in Werkzeug 2.1. The {fget.__name__!r} property" - " will be 'None'. Subclass 'werkzeug.user_agent.UserAgent'" - " and set 'Request.user_agent_class' to use a different" - " parser." - ) - - def __get__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: - warnings.warn(self.message, DeprecationWarning, stacklevel=3) - return super().__get__(*args, **kwargs) - - -# This is what Request.user_agent returns for now, only show warnings on -# attribute access, not creation. -class _UserAgent(_BaseUserAgent): - _parser = _UserAgentParser() - - def __init__(self, string: str) -> None: - super().__init__(string) - info = self._parser(string) - self._platform, self._browser, self._version, self._language = info - - @_deprecated_property - def platform(self) -> t.Optional[str]: # type: ignore - return self._platform - - @_deprecated_property - def browser(self) -> t.Optional[str]: # type: ignore - return self._browser - - @_deprecated_property - def version(self) -> t.Optional[str]: # type: ignore - return self._version - - @_deprecated_property - def language(self) -> t.Optional[str]: # type: ignore - return self._language - - -# This is what users might be importing, show warnings on create. -class UserAgent(_UserAgent): - """Represents a parsed user agent header value. - - This uses a basic parser to try to extract some information from the - header. - - :param environ_or_string: The header value to parse, or a WSGI - environ containing the header. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Subclass - :class:`werkzeug.user_agent.UserAgent` (note the new module - name) to use a dedicated parser instead. - - .. versionchanged:: 2.0 - Passing a WSGI environ is deprecated and will be removed in 2.1. - """ - - def __init__(self, environ_or_string: "t.Union[str, WSGIEnvironment]") -> None: - if isinstance(environ_or_string, dict): - warnings.warn( - "Passing an environ to 'UserAgent' is deprecated and" - " will be removed in Werkzeug 2.1. Pass the header" - " value string instead.", - DeprecationWarning, - stacklevel=2, - ) - string = environ_or_string.get("HTTP_USER_AGENT", "") - else: - string = environ_or_string - - warnings.warn( - "The 'werkzeug.useragents' module is deprecated and will be" - " removed in Werkzeug 2.1. The new base API is" - " 'werkzeug.user_agent.UserAgent'.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(string) diff --git a/venv/lib/python3.7/site-packages/werkzeug/utils.py b/venv/lib/python3.7/site-packages/werkzeug/utils.py deleted file mode 100644 index 9007231..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/utils.py +++ /dev/null @@ -1,1099 +0,0 @@ -import codecs -import io -import mimetypes -import os -import pkgutil -import re -import sys -import typing as t -import unicodedata -import warnings -from datetime import datetime -from html.entities import name2codepoint -from time import time -from zlib import adler32 - -from ._internal import _DictAccessorProperty -from ._internal import _missing -from ._internal import _parse_signature -from ._internal import _TAccessorValue -from .datastructures import Headers -from .exceptions import NotFound -from .exceptions import RequestedRangeNotSatisfiable -from .security import safe_join -from .urls import url_quote -from .wsgi import wrap_file - -if t.TYPE_CHECKING: - from _typeshed.wsgi import WSGIEnvironment - from .wrappers.request import Request - from .wrappers.response import Response - -_T = t.TypeVar("_T") - -_entity_re = re.compile(r"&([^;]+);") -_filename_ascii_strip_re = re.compile(r"[^A-Za-z0-9_.-]") -_windows_device_files = ( - "CON", - "AUX", - "COM1", - "COM2", - "COM3", - "COM4", - "LPT1", - "LPT2", - "LPT3", - "PRN", - "NUL", -) - - -class cached_property(property, t.Generic[_T]): - """A :func:`property` that is only evaluated once. Subsequent access - returns the cached value. Setting the property sets the cached - value. Deleting the property clears the cached value, accessing it - again will evaluate it again. - - .. code-block:: python - - class Example: - @cached_property - def value(self): - # calculate something important here - return 42 - - e = Example() - e.value # evaluates - e.value # uses cache - e.value = 16 # sets cache - del e.value # clears cache - - The class must have a ``__dict__`` for this to work. - - .. versionchanged:: 2.0 - ``del obj.name`` clears the cached value. - """ - - def __init__( - self, - fget: t.Callable[[t.Any], _T], - name: t.Optional[str] = None, - doc: t.Optional[str] = None, - ) -> None: - super().__init__(fget, doc=doc) - self.__name__ = name or fget.__name__ - self.__module__ = fget.__module__ - - def __set__(self, obj: object, value: _T) -> None: - obj.__dict__[self.__name__] = value - - def __get__(self, obj: object, type: type = None) -> _T: # type: ignore - if obj is None: - return self # type: ignore - - value: _T = obj.__dict__.get(self.__name__, _missing) - - if value is _missing: - value = self.fget(obj) # type: ignore - obj.__dict__[self.__name__] = value - - return value - - def __delete__(self, obj: object) -> None: - del obj.__dict__[self.__name__] - - -def invalidate_cached_property(obj: object, name: str) -> None: - """Invalidates the cache for a :class:`cached_property`: - - >>> class Test(object): - ... @cached_property - ... def magic_number(self): - ... print("recalculating...") - ... return 42 - ... - >>> var = Test() - >>> var.magic_number - recalculating... - 42 - >>> var.magic_number - 42 - >>> invalidate_cached_property(var, "magic_number") - >>> var.magic_number - recalculating... - 42 - - You must pass the name of the cached property as the second argument. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use ``del obj.name`` instead. - """ - warnings.warn( - "'invalidate_cached_property' is deprecated and will be removed" - " in Werkzeug 2.1. Use 'del obj.name' instead.", - DeprecationWarning, - stacklevel=2, - ) - delattr(obj, name) - - -class environ_property(_DictAccessorProperty[_TAccessorValue]): - """Maps request attributes to environment variables. This works not only - for the Werkzeug request object, but also any other class with an - environ attribute: - - >>> class Test(object): - ... environ = {'key': 'value'} - ... test = environ_property('key') - >>> var = Test() - >>> var.test - 'value' - - If you pass it a second value it's used as default if the key does not - exist, the third one can be a converter that takes a value and converts - it. If it raises :exc:`ValueError` or :exc:`TypeError` the default value - is used. If no default value is provided `None` is used. - - Per default the property is read only. You have to explicitly enable it - by passing ``read_only=False`` to the constructor. - """ - - read_only = True - - def lookup(self, obj: "Request") -> "WSGIEnvironment": - return obj.environ - - -class header_property(_DictAccessorProperty[_TAccessorValue]): - """Like `environ_property` but for headers.""" - - def lookup(self, obj: t.Union["Request", "Response"]) -> Headers: - return obj.headers - - -class HTMLBuilder: - """Helper object for HTML generation. - - Per default there are two instances of that class. The `html` one, and - the `xhtml` one for those two dialects. The class uses keyword parameters - and positional parameters to generate small snippets of HTML. - - Keyword parameters are converted to XML/SGML attributes, positional - arguments are used as children. Because Python accepts positional - arguments before keyword arguments it's a good idea to use a list with the - star-syntax for some children: - - >>> html.p(class_='foo', *[html.a('foo', href='foo.html'), ' ', - ... html.a('bar', href='bar.html')]) - '

    foo bar

    ' - - This class works around some browser limitations and can not be used for - arbitrary SGML/XML generation. For that purpose lxml and similar - libraries exist. - - Calling the builder escapes the string passed: - - >>> html.p(html("")) - '

    <foo>

    ' - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. - """ - - _entity_re = re.compile(r"&([^;]+);") - _entities = name2codepoint.copy() - _entities["apos"] = 39 - _empty_elements = { - "area", - "base", - "basefont", - "br", - "col", - "command", - "embed", - "frame", - "hr", - "img", - "input", - "keygen", - "isindex", - "link", - "meta", - "param", - "source", - "wbr", - } - _boolean_attributes = { - "selected", - "checked", - "compact", - "declare", - "defer", - "disabled", - "ismap", - "multiple", - "nohref", - "noresize", - "noshade", - "nowrap", - } - _plaintext_elements = {"textarea"} - _c_like_cdata = {"script", "style"} - - def __init__(self, dialect): # type: ignore - self._dialect = dialect - - def __call__(self, s): # type: ignore - import html - - warnings.warn( - "'utils.HTMLBuilder' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return html.escape(s) - - def __getattr__(self, tag): # type: ignore - import html - - warnings.warn( - "'utils.HTMLBuilder' is deprecated and will be removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - if tag[:2] == "__": - raise AttributeError(tag) - - def proxy(*children, **arguments): # type: ignore - buffer = f"<{tag}" - for key, value in arguments.items(): - if value is None: - continue - if key[-1] == "_": - key = key[:-1] - if key in self._boolean_attributes: - if not value: - continue - if self._dialect == "xhtml": - value = f'="{key}"' - else: - value = "" - else: - value = f'="{html.escape(value)}"' - buffer += f" {key}{value}" - if not children and tag in self._empty_elements: - if self._dialect == "xhtml": - buffer += " />" - else: - buffer += ">" - return buffer - buffer += ">" - - children_as_string = "".join([str(x) for x in children if x is not None]) - - if children_as_string: - if tag in self._plaintext_elements: - children_as_string = html.escape(children_as_string) - elif tag in self._c_like_cdata and self._dialect == "xhtml": - children_as_string = f"/**/" - buffer += children_as_string + f"" - return buffer - - return proxy - - def __repr__(self) -> str: - return f"<{type(self).__name__} for {self._dialect!r}>" - - -html = HTMLBuilder("html") -xhtml = HTMLBuilder("xhtml") - -# https://cgit.freedesktop.org/xdg/shared-mime-info/tree/freedesktop.org.xml.in -# https://www.iana.org/assignments/media-types/media-types.xhtml -# Types listed in the XDG mime info that have a charset in the IANA registration. -_charset_mimetypes = { - "application/ecmascript", - "application/javascript", - "application/sql", - "application/xml", - "application/xml-dtd", - "application/xml-external-parsed-entity", -} - - -def get_content_type(mimetype: str, charset: str) -> str: - """Returns the full content type string with charset for a mimetype. - - If the mimetype represents text, the charset parameter will be - appended, otherwise the mimetype is returned unchanged. - - :param mimetype: The mimetype to be used as content type. - :param charset: The charset to be appended for text mimetypes. - :return: The content type. - - .. versionchanged:: 0.15 - Any type that ends with ``+xml`` gets a charset, not just those - that start with ``application/``. Known text types such as - ``application/javascript`` are also given charsets. - """ - if ( - mimetype.startswith("text/") - or mimetype in _charset_mimetypes - or mimetype.endswith("+xml") - ): - mimetype += f"; charset={charset}" - - return mimetype - - -def detect_utf_encoding(data: bytes) -> str: - """Detect which UTF encoding was used to encode the given bytes. - - The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 is - accepted. Older documents allowed 8, 16, or 32. 16 and 32 can be big - or little endian. Some editors or libraries may prepend a BOM. - - :internal: - - :param data: Bytes in unknown UTF encoding. - :return: UTF encoding name - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. This is built in to - :func:`json.loads`. - - .. versionadded:: 0.15 - """ - warnings.warn( - "'detect_utf_encoding' is deprecated and will be removed in" - " Werkzeug 2.1. This is built in to 'json.loads'.", - DeprecationWarning, - stacklevel=2, - ) - head = data[:4] - - if head[:3] == codecs.BOM_UTF8: - return "utf-8-sig" - - if b"\x00" not in head: - return "utf-8" - - if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE): - return "utf-32" - - if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE): - return "utf-16" - - if len(head) == 4: - if head[:3] == b"\x00\x00\x00": - return "utf-32-be" - - if head[::2] == b"\x00\x00": - return "utf-16-be" - - if head[1:] == b"\x00\x00\x00": - return "utf-32-le" - - if head[1::2] == b"\x00\x00": - return "utf-16-le" - - if len(head) == 2: - return "utf-16-be" if head.startswith(b"\x00") else "utf-16-le" - - return "utf-8" - - -def format_string(string: str, context: t.Mapping[str, t.Any]) -> str: - """String-template format a string: - - >>> format_string('$foo and ${foo}s', dict(foo=42)) - '42 and 42s' - - This does not do any attribute lookup. - - :param string: the format string. - :param context: a dict with the variables to insert. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :class:`string.Template` - instead. - """ - from string import Template - - warnings.warn( - "'utils.format_string' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'string.Template' instead.", - DeprecationWarning, - stacklevel=2, - ) - return Template(string).substitute(context) - - -def secure_filename(filename: str) -> str: - r"""Pass it a filename and it will return a secure version of it. This - filename can then safely be stored on a regular file system and passed - to :func:`os.path.join`. The filename returned is an ASCII only string - for maximum portability. - - On windows systems the function also makes sure that the file is not - named after one of the special device files. - - >>> secure_filename("My cool movie.mov") - 'My_cool_movie.mov' - >>> secure_filename("../../../etc/passwd") - 'etc_passwd' - >>> secure_filename('i contain cool \xfcml\xe4uts.txt') - 'i_contain_cool_umlauts.txt' - - The function might return an empty filename. It's your responsibility - to ensure that the filename is unique and that you abort or - generate a random filename if the function returned an empty one. - - .. versionadded:: 0.5 - - :param filename: the filename to secure - """ - filename = unicodedata.normalize("NFKD", filename) - filename = filename.encode("ascii", "ignore").decode("ascii") - - for sep in os.path.sep, os.path.altsep: - if sep: - filename = filename.replace(sep, " ") - filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip( - "._" - ) - - # on nt a couple of special files are present in each folder. We - # have to ensure that the target file is not such a filename. In - # this case we prepend an underline - if ( - os.name == "nt" - and filename - and filename.split(".")[0].upper() in _windows_device_files - ): - filename = f"_{filename}" - - return filename - - -def escape(s: t.Any) -> str: - """Replace ``&``, ``<``, ``>``, ``"``, and ``'`` with HTML-safe - sequences. - - ``None`` is escaped to an empty string. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use MarkupSafe instead. - """ - import html - - warnings.warn( - "'utils.escape' is deprecated and will be removed in Werkzeug" - " 2.1. Use MarkupSafe instead.", - DeprecationWarning, - stacklevel=2, - ) - - if s is None: - return "" - - if hasattr(s, "__html__"): - return s.__html__() # type: ignore - - if not isinstance(s, str): - s = str(s) - - return html.escape(s, quote=True) # type: ignore - - -def unescape(s: str) -> str: - """The reverse of :func:`escape`. This unescapes all the HTML - entities, not only those inserted by ``escape``. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use MarkupSafe instead. - """ - import html - - warnings.warn( - "'utils.unescape' is deprecated and will be removed in Werkzueg" - " 2.1. Use MarkupSafe instead.", - DeprecationWarning, - stacklevel=2, - ) - return html.unescape(s) - - -def redirect( - location: str, code: int = 302, Response: t.Optional[t.Type["Response"]] = None -) -> "Response": - """Returns a response object (a WSGI application) that, if called, - redirects the client to the target location. Supported codes are - 301, 302, 303, 305, 307, and 308. 300 is not supported because - it's not a real redirect and 304 because it's the answer for a - request with a request with defined If-Modified-Since headers. - - .. versionadded:: 0.6 - The location can now be a unicode string that is encoded using - the :func:`iri_to_uri` function. - - .. versionadded:: 0.10 - The class used for the Response object can now be passed in. - - :param location: the location the response should redirect to. - :param code: the redirect status code. defaults to 302. - :param class Response: a Response class to use when instantiating a - response. The default is :class:`werkzeug.wrappers.Response` if - unspecified. - """ - import html - - if Response is None: - from .wrappers import Response # type: ignore - - display_location = html.escape(location) - if isinstance(location, str): - # Safe conversion is necessary here as we might redirect - # to a broken URI scheme (for instance itms-services). - from .urls import iri_to_uri - - location = iri_to_uri(location, safe_conversion=True) - response = Response( # type: ignore - '\n' - "Redirecting...\n" - "

    Redirecting...

    \n" - "

    You should be redirected automatically to target URL: " - f'{display_location}. If' - " not click the link.", - code, - mimetype="text/html", - ) - response.headers["Location"] = location - return response - - -def append_slash_redirect(environ: "WSGIEnvironment", code: int = 301) -> "Response": - """Redirects to the same URL but with a slash appended. The behavior - of this function is undefined if the path ends with a slash already. - - :param environ: the WSGI environment for the request that triggers - the redirect. - :param code: the status code for the redirect. - """ - new_path = environ["PATH_INFO"].strip("/") + "/" - query_string = environ.get("QUERY_STRING") - if query_string: - new_path += f"?{query_string}" - return redirect(new_path, code) - - -def send_file( - path_or_file: t.Union[os.PathLike, str, t.IO[bytes]], - environ: "WSGIEnvironment", - mimetype: t.Optional[str] = None, - as_attachment: bool = False, - download_name: t.Optional[str] = None, - conditional: bool = True, - etag: t.Union[bool, str] = True, - last_modified: t.Optional[t.Union[datetime, int, float]] = None, - max_age: t.Optional[ - t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] - ] = None, - use_x_sendfile: bool = False, - response_class: t.Optional[t.Type["Response"]] = None, - _root_path: t.Optional[t.Union[os.PathLike, str]] = None, -) -> "Response": - """Send the contents of a file to the client. - - The first argument can be a file path or a file-like object. Paths - are preferred in most cases because Werkzeug can manage the file and - get extra information from the path. Passing a file-like object - requires that the file is opened in binary mode, and is mostly - useful when building a file in memory with :class:`io.BytesIO`. - - Never pass file paths provided by a user. The path is assumed to be - trusted, so a user could craft a path to access a file you didn't - intend. - - If the WSGI server sets a ``file_wrapper`` in ``environ``, it is - used, otherwise Werkzeug's built-in wrapper is used. Alternatively, - if the HTTP server supports ``X-Sendfile``, ``use_x_sendfile=True`` - will tell the server to send the given path, which is much more - efficient than reading it in Python. - - :param path_or_file: The path to the file to send, relative to the - current working directory if a relative path is given. - Alternatively, a file-like object opened in binary mode. Make - sure the file pointer is seeked to the start of the data. - :param environ: The WSGI environ for the current request. - :param mimetype: The MIME type to send for the file. If not - provided, it will try to detect it from the file name. - :param as_attachment: Indicate to a browser that it should offer to - save the file instead of displaying it. - :param download_name: The default name browsers will use when saving - the file. Defaults to the passed file name. - :param conditional: Enable conditional and range responses based on - request headers. Requires passing a file path and ``environ``. - :param etag: Calculate an ETag for the file, which requires passing - a file path. Can also be a string to use instead. - :param last_modified: The last modified time to send for the file, - in seconds. If not provided, it will try to detect it from the - file path. - :param max_age: How long the client should cache the file, in - seconds. If set, ``Cache-Control`` will be ``public``, otherwise - it will be ``no-cache`` to prefer conditional caching. - :param use_x_sendfile: Set the ``X-Sendfile`` header to let the - server to efficiently send the file. Requires support from the - HTTP server. Requires passing a file path. - :param response_class: Build the response using this class. Defaults - to :class:`~werkzeug.wrappers.Response`. - :param _root_path: Do not use. For internal use only. Use - :func:`send_from_directory` to safely send files under a path. - - .. versionchanged:: 2.0.2 - ``send_file`` only sets a detected ``Content-Encoding`` if - ``as_attachment`` is disabled. - - .. versionadded:: 2.0 - Adapted from Flask's implementation. - - .. versionchanged:: 2.0 - ``download_name`` replaces Flask's ``attachment_filename`` - parameter. If ``as_attachment=False``, it is passed with - ``Content-Disposition: inline`` instead. - - .. versionchanged:: 2.0 - ``max_age`` replaces Flask's ``cache_timeout`` parameter. - ``conditional`` is enabled and ``max_age`` is not set by - default. - - .. versionchanged:: 2.0 - ``etag`` replaces Flask's ``add_etags`` parameter. It can be a - string to use instead of generating one. - - .. versionchanged:: 2.0 - If an encoding is returned when guessing ``mimetype`` from - ``download_name``, set the ``Content-Encoding`` header. - """ - if response_class is None: - from .wrappers import Response - - response_class = Response - - path: t.Optional[str] = None - file: t.Optional[t.IO[bytes]] = None - size: t.Optional[int] = None - mtime: t.Optional[float] = None - headers = Headers() - - if isinstance(path_or_file, (os.PathLike, str)) or hasattr( - path_or_file, "__fspath__" - ): - path_or_file = t.cast(t.Union[os.PathLike, str], path_or_file) - - # Flask will pass app.root_path, allowing its send_file wrapper - # to not have to deal with paths. - if _root_path is not None: - path = os.path.join(_root_path, path_or_file) - else: - path = os.path.abspath(path_or_file) - - stat = os.stat(path) - size = stat.st_size - mtime = stat.st_mtime - else: - file = path_or_file - - if download_name is None and path is not None: - download_name = os.path.basename(path) - - if mimetype is None: - if download_name is None: - raise TypeError( - "Unable to detect the MIME type because a file name is" - " not available. Either set 'download_name', pass a" - " path instead of a file, or set 'mimetype'." - ) - - mimetype, encoding = mimetypes.guess_type(download_name) - - if mimetype is None: - mimetype = "application/octet-stream" - - # Don't send encoding for attachments, it causes browsers to - # save decompress tar.gz files. - if encoding is not None and not as_attachment: - headers.set("Content-Encoding", encoding) - - if download_name is not None: - try: - download_name.encode("ascii") - except UnicodeEncodeError: - simple = unicodedata.normalize("NFKD", download_name) - simple = simple.encode("ascii", "ignore").decode("ascii") - quoted = url_quote(download_name, safe="") - names = {"filename": simple, "filename*": f"UTF-8''{quoted}"} - else: - names = {"filename": download_name} - - value = "attachment" if as_attachment else "inline" - headers.set("Content-Disposition", value, **names) - elif as_attachment: - raise TypeError( - "No name provided for attachment. Either set" - " 'download_name' or pass a path instead of a file." - ) - - if use_x_sendfile and path is not None: - headers["X-Sendfile"] = path - data = None - else: - if file is None: - file = open(path, "rb") # type: ignore - elif isinstance(file, io.BytesIO): - size = file.getbuffer().nbytes - elif isinstance(file, io.TextIOBase): - raise ValueError("Files must be opened in binary mode or use BytesIO.") - - data = wrap_file(environ, file) - - rv = response_class( - data, mimetype=mimetype, headers=headers, direct_passthrough=True - ) - - if size is not None: - rv.content_length = size - - if last_modified is not None: - rv.last_modified = last_modified # type: ignore - elif mtime is not None: - rv.last_modified = mtime # type: ignore - - rv.cache_control.no_cache = True - - # Flask will pass app.get_send_file_max_age, allowing its send_file - # wrapper to not have to deal with paths. - if callable(max_age): - max_age = max_age(path) - - if max_age is not None: - if max_age > 0: - rv.cache_control.no_cache = None - rv.cache_control.public = True - - rv.cache_control.max_age = max_age - rv.expires = int(time() + max_age) # type: ignore - - if isinstance(etag, str): - rv.set_etag(etag) - elif etag and path is not None: - check = adler32(path.encode("utf-8")) & 0xFFFFFFFF - rv.set_etag(f"{mtime}-{size}-{check}") - - if conditional: - try: - rv = rv.make_conditional(environ, accept_ranges=True, complete_length=size) - except RequestedRangeNotSatisfiable: - if file is not None: - file.close() - - raise - - # Some x-sendfile implementations incorrectly ignore the 304 - # status code and send the file anyway. - if rv.status_code == 304: - rv.headers.pop("x-sendfile", None) - - return rv - - -def send_from_directory( - directory: t.Union[os.PathLike, str], - path: t.Union[os.PathLike, str], - environ: "WSGIEnvironment", - **kwargs: t.Any, -) -> "Response": - """Send a file from within a directory using :func:`send_file`. - - This is a secure way to serve files from a folder, such as static - files or uploads. Uses :func:`~werkzeug.security.safe_join` to - ensure the path coming from the client is not maliciously crafted to - point outside the specified directory. - - If the final path does not point to an existing regular file, - returns a 404 :exc:`~werkzeug.exceptions.NotFound` error. - - :param directory: The directory that ``path`` must be located under. - :param path: The path to the file to send, relative to - ``directory``. - :param environ: The WSGI environ for the current request. - :param kwargs: Arguments to pass to :func:`send_file`. - - .. versionadded:: 2.0 - Adapted from Flask's implementation. - """ - path = safe_join(os.fspath(directory), os.fspath(path)) - - if path is None: - raise NotFound() - - # Flask will pass app.root_path, allowing its send_from_directory - # wrapper to not have to deal with paths. - if "_root_path" in kwargs: - path = os.path.join(kwargs["_root_path"], path) - - try: - if not os.path.isfile(path): - raise NotFound() - except ValueError: - # path contains null byte on Python < 3.8 - raise NotFound() from None - - return send_file(path, environ, **kwargs) - - -def import_string(import_name: str, silent: bool = False) -> t.Any: - """Imports an object based on a string. This is useful if you want to - use import paths as endpoints or something similar. An import path can - be specified either in dotted notation (``xml.sax.saxutils.escape``) - or with a colon as object delimiter (``xml.sax.saxutils:escape``). - - If `silent` is True the return value will be `None` if the import fails. - - :param import_name: the dotted name for the object to import. - :param silent: if set to `True` import errors are ignored and - `None` is returned instead. - :return: imported object - """ - import_name = import_name.replace(":", ".") - try: - try: - __import__(import_name) - except ImportError: - if "." not in import_name: - raise - else: - return sys.modules[import_name] - - module_name, obj_name = import_name.rsplit(".", 1) - module = __import__(module_name, globals(), locals(), [obj_name]) - try: - return getattr(module, obj_name) - except AttributeError as e: - raise ImportError(e) from None - - except ImportError as e: - if not silent: - raise ImportStringError(import_name, e).with_traceback( - sys.exc_info()[2] - ) from None - - return None - - -def find_modules( - import_path: str, include_packages: bool = False, recursive: bool = False -) -> t.Iterator[str]: - """Finds all the modules below a package. This can be useful to - automatically import all views / controllers so that their metaclasses / - function decorators have a chance to register themselves on the - application. - - Packages are not returned unless `include_packages` is `True`. This can - also recursively list modules but in that case it will import all the - packages to get the correct load path of that module. - - :param import_path: the dotted name for the package to find child modules. - :param include_packages: set to `True` if packages should be returned, too. - :param recursive: set to `True` if recursion should happen. - :return: generator - """ - module = import_string(import_path) - path = getattr(module, "__path__", None) - if path is None: - raise ValueError(f"{import_path!r} is not a package") - basename = f"{module.__name__}." - for _importer, modname, ispkg in pkgutil.iter_modules(path): - modname = basename + modname - if ispkg: - if include_packages: - yield modname - if recursive: - yield from find_modules(modname, include_packages, True) - else: - yield modname - - -def validate_arguments(func, args, kwargs, drop_extra=True): # type: ignore - """Checks if the function accepts the arguments and keyword arguments. - Returns a new ``(args, kwargs)`` tuple that can safely be passed to - the function without causing a `TypeError` because the function signature - is incompatible. If `drop_extra` is set to `True` (which is the default) - any extra positional or keyword arguments are dropped automatically. - - The exception raised provides three attributes: - - `missing` - A set of argument names that the function expected but where - missing. - - `extra` - A dict of keyword arguments that the function can not handle but - where provided. - - `extra_positional` - A list of values that where given by positional argument but the - function cannot accept. - - This can be useful for decorators that forward user submitted data to - a view function:: - - from werkzeug.utils import ArgumentValidationError, validate_arguments - - def sanitize(f): - def proxy(request): - data = request.values.to_dict() - try: - args, kwargs = validate_arguments(f, (request,), data) - except ArgumentValidationError: - raise BadRequest('The browser failed to transmit all ' - 'the data expected.') - return f(*args, **kwargs) - return proxy - - :param func: the function the validation is performed against. - :param args: a tuple of positional arguments. - :param kwargs: a dict of keyword arguments. - :param drop_extra: set to `False` if you don't want extra arguments - to be silently dropped. - :return: tuple in the form ``(args, kwargs)``. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :func:`inspect.signature` - instead. - """ - warnings.warn( - "'utils.validate_arguments' is deprecated and will be removed" - " in Werkzeug 2.1. Use 'inspect.signature' instead.", - DeprecationWarning, - stacklevel=2, - ) - parser = _parse_signature(func) - args, kwargs, missing, extra, extra_positional = parser(args, kwargs)[:5] - if missing: - raise ArgumentValidationError(tuple(missing)) - elif (extra or extra_positional) and not drop_extra: - raise ArgumentValidationError(None, extra, extra_positional) - return tuple(args), kwargs - - -def bind_arguments(func, args, kwargs): # type: ignore - """Bind the arguments provided into a dict. When passed a function, - a tuple of arguments and a dict of keyword arguments `bind_arguments` - returns a dict of names as the function would see it. This can be useful - to implement a cache decorator that uses the function arguments to build - the cache key based on the values of the arguments. - - :param func: the function the arguments should be bound for. - :param args: tuple of positional arguments. - :param kwargs: a dict of keyword arguments. - :return: a :class:`dict` of bound keyword arguments. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Use :meth:`Signature.bind` - instead. - """ - warnings.warn( - "'utils.bind_arguments' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'Signature.bind' instead.", - DeprecationWarning, - stacklevel=2, - ) - ( - args, - kwargs, - missing, - extra, - extra_positional, - arg_spec, - vararg_var, - kwarg_var, - ) = _parse_signature(func)(args, kwargs) - values = {} - for (name, _has_default, _default), value in zip(arg_spec, args): - values[name] = value - if vararg_var is not None: - values[vararg_var] = tuple(extra_positional) - elif extra_positional: - raise TypeError("too many positional arguments") - if kwarg_var is not None: - multikw = set(extra) & {x[0] for x in arg_spec} - if multikw: - raise TypeError( - f"got multiple values for keyword argument {next(iter(multikw))!r}" - ) - values[kwarg_var] = extra - elif extra: - raise TypeError(f"got unexpected keyword argument {next(iter(extra))!r}") - return values - - -class ArgumentValidationError(ValueError): - """Raised if :func:`validate_arguments` fails to validate - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1 along with ``utils.bind`` and - ``validate_arguments``. - """ - - def __init__(self, missing=None, extra=None, extra_positional=None): # type: ignore - self.missing = set(missing or ()) - self.extra = extra or {} - self.extra_positional = extra_positional or [] - super().__init__( - "function arguments invalid." - f" ({len(self.missing)} missing," - f" {len(self.extra) + len(self.extra_positional)} additional)" - ) - - -class ImportStringError(ImportError): - """Provides information about a failed :func:`import_string` attempt.""" - - #: String in dotted notation that failed to be imported. - import_name: str - #: Wrapped exception. - exception: BaseException - - def __init__(self, import_name: str, exception: BaseException) -> None: - self.import_name = import_name - self.exception = exception - msg = import_name - name = "" - tracked = [] - for part in import_name.replace(":", ".").split("."): - name = f"{name}.{part}" if name else part - imported = import_string(name, silent=True) - if imported: - tracked.append((name, getattr(imported, "__file__", None))) - else: - track = [f"- {n!r} found in {i!r}." for n, i in tracked] - track.append(f"- {name!r} not found.") - track_str = "\n".join(track) - msg = ( - f"import_string() failed for {import_name!r}. Possible reasons" - f" are:\n\n" - "- missing __init__.py in a package;\n" - "- package or module path not included in sys.path;\n" - "- duplicated package or module name taking precedence in" - " sys.path;\n" - "- missing module, class, function or variable;\n\n" - f"Debugged import:\n\n{track_str}\n\n" - f"Original exception:\n\n{type(exception).__name__}: {exception}" - ) - break - - super().__init__(msg) - - def __repr__(self) -> str: - return f"<{type(self).__name__}({self.import_name!r}, {self.exception!r})>" diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py deleted file mode 100644 index eb69a99..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -from .accept import AcceptMixin -from .auth import AuthorizationMixin -from .auth import WWWAuthenticateMixin -from .base_request import BaseRequest -from .base_response import BaseResponse -from .common_descriptors import CommonRequestDescriptorsMixin -from .common_descriptors import CommonResponseDescriptorsMixin -from .etag import ETagRequestMixin -from .etag import ETagResponseMixin -from .request import PlainRequest -from .request import Request as Request -from .request import StreamOnlyMixin -from .response import Response as Response -from .response import ResponseStream -from .response import ResponseStreamMixin -from .user_agent import UserAgentMixin diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index ab6f7261bf322afecaa24ff982b9bf34109a2c4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 911 zcmaKq&5qMB5XX~k+NRA%KeoG+1AFg*&4B|K1audUd}tR`$(P7Yt<;m6;3BUXfX5(yJ z=5QCeuI3|l#5<^CxC87V&#=e3yoY**yR6TB0Ux5F;XZJH0>eHFd4wXv1K=3N zhKFp#$7pOg0G^bPT1(xKBe5#35kQ}zItjaO^QECB9=J}!6P{SXUP_4I}9(NNU|--c4e(DVRnin zH>9{p7+ojTUT;4+f0{_D$m2>UfSCuZBrnI0cP0y=+<3Ho&re@^1 Nes=NIYa{q9BnKaNvS~0um>B0HI2`SX+DAxN)7W?M+D4TPyVh zUqC;AU)n3D{sJdvHYs$Z89#gM@q1&x+uGV-XjkHmzT%Airpb*71aHyfV+@8F?%0@j zV>Zq{GLso`!HhW1#=`I~Y?xo;KDMhV-dMf{@d*Ox&W|$?M>)CSCi^Ka*#S4gYI=qh}*I_zWiv#59n8w!pM@je#iB1mr>Eb+R*GIh&T!Sgf1ea&(;`$02VwVyg7i z!5kdQEl`)Y9wp|4+D9MOM6kf#D%JL4Q$uJArL4C}De6iDcMwQ@pjKnqyGm(S#i-OT z_6N$Z5kf5YLuDK+T{*!kt2CMUQcplnXH9w^0M(Xr@bl8y{jy$C`o-vF8Et~6H61vF zST5GG%SEVaq!G)id!SLh44Zg$A3b)TiRU~M885Qa?OWX){bPNH6!_{GlxjDWI-Z%v z5#Chlq^aCG!&57E{Hk`lwHBqpIi&)0#=&wOeUV0Z|2*5(QK{|c)qe{*<(h?cXSpH_~bc= zy9Y`TK{e^o>I{0pYa#-{4vAm~L63nKiW+z|@Ipb~k#_wUZjp@)_2LQVhPwlXtg`h2 z$#y~%K}GO|9g!_6mH}>36Qjhl1F{qD)BWHxr2r91g&Wgp>uj-BtXwQ) zZe^BwDdNdA*)=jsxhjP0JPM(`=ySNNNBd0X(A&APvzfS6|H=fdt)IsI0jn zm$r;JS4MfxaX3!uEsI02ICx0A%z36$=Q#gHeq_meC#_31Z7Q^!=%f!NQ<$Rx=g2atHRl#L zUa2;<7ty|q3Wtk)aA-ud^8XV**Sg&cCqmj3ld0g diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc deleted file mode 100644 index 574cd478735fc7f7cbb87c3a49d76bb70838305a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1746 zcmc&!&2Jnv6t`zQADbq$O#?`Lhyfv`Q^8Jw0~Z9Pso<6a1y$OMH9LOEPS!iKwLMvF zlv^V8RF0g=AHcsfS5EmCIPu=>Y?Ba#kT_t;&-SzZzJKrW*475Y@vHw$@rz*WcRH*` zh?_?^?Gq%5DX!UwcdIw@l&5^{&%{V@_B~TV1?Nl!5S;m=5YM5C@En1FP{l9BC{p|> zO9vMyiS1u-q$zKsAK-Zd))mBE4<9#=aN37Rpwl?=z&{cYDE_L`doD&Haw6mi>!1FkVu;h}gMv<5i$aN2i}ICjJpcb%q} zK4;E9XlhP&%<_3z~flBg9C5uw)WDJRcS$&MWvPzzTnVvv% zn0!9`Y?%CHA=xeM+MxS|wx1-uz!W7`)^YI{4veY3}dsg$(4qs&L*fNcayrx3JO`> zxIF{tRCWy2ai+_0Heb^97sD?zTRQl3P9F}zW{cjtY+>^Gyc3EMl4h0L;e6TNm2&NE zCtS)HZLnSCalt*$26mCr!Rc0rMdUowChG1Y$A+2wzP@)_MqcjLpa^g zun&-2LpY*bapk@8U$6tNd?n5|N5Kmw*eFEw1?{aX*xOJ2R^$ee5Ka*ahjvvC)LLjz z;Zwm=ME9f?zZ>ix_)wzn0$?SF>%?(5!A)eA&(p&JD@aT7=mnyPRJ)LfTt znWz%mhSSU8KUYX#8w3?)tE@^VCAn=uADH*hDf2!OY!U-0yLKn#WxbdW@Qxl`R*2sL zZRbi95n;X9$n227H;KGOgr z0X8w}$Jn4lx13`KTgfLlv{BzHIs~)=@1d)j?)w!KbfwloA^vJruwPTUEkP^B7P9Hz G+4&Pk)w$RJ diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc deleted file mode 100644 index cbc98567b6c9a6644922dd69d46ebd0020252728..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1757 zcmc&!PjB2r6!+L;uQw#L4J}Cg5e6Y`UBMdK0~Z9Pso<6a1y%B8sB{)r7JzZAl?HNR55vRFW1QwwB+#i$UGU}{e92yQiqCl(AZLUejvQYG z$O+{LRfKj|e3LEUSv$*BX3X9Z3)_{z%Qbwynsb~g~hGlh(yrPVrgI=6K zdl)^Oem0GMFc3`&Ggx##SLWkrkQk%L(ln6C=>?gFaoRFXmM;_>gNl6{t}4mVu}Vnsp-QZm}J$vm#lPF*PT#|kJkyAVV1aNrG@FW`4nu>A zpNgJBXFf!76WnLcoS(8&_b0}%%WXj3{&$d120%}uvRWagbJa>PQF8>*L0jex!ZlMx zvyNne-J?5E)R?hT2hF<1Mz)bpkg(y+4lG7p7)tjKnqp<_1%vv z=hj^bQyU7I8=1sTiZIq9oTN&HeHj`#%Es_4)!~LT!(CZyg^#)qyWz?V#7d~M34{|> z2x&t%kl|*b6PIQ>R;inYB89w8O}j@PT)0EaCF|m3sN`5GXh{G_b*cfhk5;+7HoFKU z*r-Eg!xp(TWx#o=Q^z^>$x5|pupb7;0cjUGPgHCz=ikVWo#?%l#zuV;3niy28bHa| z4Kf`i1DOo7!mSz!Xrr;z<4C3bD4$~Zara4NQz!4|cwkG~XflHxO-!7_HEfhrL*xK= zKE7@~H7&SC6U0_jq(1eSM+0y7?zz419%EWSd^#RU&dVjvN0}%T+AYp^idfAe)RpX| zuB(;p8RSGN#koONRH{SGMYJ!Y!mcA{EE)l={QpGf+jD3(&$N|i@cCpy2Ji5%L_Rzw z^4S&tmdSOtKc}+6K|_}paBG+VHnWHdXKyZ`LOOJqX`_9LruAT|NmbLq*OozkWzBDZ zo}!Jpf+aAAxr*u;rt3~5;a diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/cors.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/cors.cpython-37.pyc deleted file mode 100644 index 680e106baf2c1778e615187cd9af860f7218e388..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1351 zcmb_c&2G~`5Z<+&)GbMA%b(z6afw3JI4Nxf5<>h*oG4O@R4E5mu6NVA*>2ojJ87cc zTB#>^0$zYu@|9CxffF;fL#x680V~b7GhXlfe)g++eU8BTxVpUCvI+Ty#&m&AUVxZ3 z04JPE(xv%sb*;CATiiY)+&;CsHdqd?fK>s@;dGlcs~2#KY=(%_<&=tf1d7PLbuD2Z zI4GQQ>x+F(dX(GTIjeOm=fol1D)_2o3$NdAZEuOARG8#lbR4P8rky!~-ZNRXKPq-D zl2ogZmO(K63dl_m^AI2*2b9yq!o)w>lqB{kIdD$siS?OMC=dcUo0H?l^-v8jG9DMP z7GaPG?gff_qex0`S9n?+4uER=yUjD02FV?Wl>5UTNqf%ba?$%Qulc-`M%>rcmF zzteug+wAetTG-$3hvCLr8`fUzfAHfdUWpW>DCNp}9PFx2r|(Zo_eW(9{E-e~$jSKO zK$})P)-}kY3Sx4;QHNT#MO|xh|9ZDuKdYF*id1kY7|Z4uI~?#-qF!U{C=FzJLX*sX zsfqwuy(}^mQZlA-^f@%Co=1HF0sD-^FsQgRxBnAO7mI34JWxhVd3repjbZx4^wjFdAq$r;Q7LyBt1sRH#8Ox*yJgQy$c|S zpo;Wqd3t^CH4&a*M?|ngug}2pMFXq`SiYd|NVj$v*bHpZ98Ig!NS7O( z&^ig0-vGG;Vs8OBvO@)R9v1$QQR3Jk+3^qPf%l10Xb=+l8}t3n`Ba@SwV{xikxA^N z2xBe6X{uDXB|{^3#}oK1)#0Wzqq)on;r-sdUf8LN?Sy(f1$UxyA#Lb}GThE};?l8> zRqAG;NFlCMv)+jZHFjySVqKh!l$=NfjR(-2PBrxDqgJfHtP6nvo0Y3**gTV_2slr5 z>Nv;ISgE!Rj=M!14-6#>JU zYY4wz`E_vN<;BX;hWDxIW*NLrRiLsPq=Z55X`o8Os*B)JMZ(AUS+O{bfClVh>jyYR BK{NmW diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/json.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/json.cpython-37.pyc deleted file mode 100644 index 4d9b038455fc4536503bb8894525f7598df82b19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 810 zcmYLH(QeZ)6t$hSWYr32;sY#Rs)E+6W1T=k2oMqy5=CN2lk$L-#qQ?DbyM4EX|=aa znuG*jzz^_CdF5%pz!TSLJFaxEk8_=yb58uW-EJX>uZK_1zGH;`_{}x~0IwnKV<;SP ztWbjMl_can;)Dm+hzD0B2{=AM-S8I9p<(9hHo^_CPXLJe{e*~M9Qx##lV8CN8etyr z@On3C+@KI8O_M!-@g@0*F=+8@hpSoV?i(E{E#;yxB1@g%G}W9gq*C-uP$MSOIXsh^ zo(hw%M0rjRd;K2md=|4(Sl6L?x`1}3N-ivQ7lMvTojEzxsgiC#}LU2S@dv`YX z?&#n1Qgk{Ij8!ehCR1K2k9QfHm8sfvuuFnBdOf*nZ`5T%DaMTd*>&k+bKm2KzIcQE sRj?jJxZZces_B*mIBXvIGm$U8|9{3B`3Y6@a!uxyzg^Zl8{sJU2mI~R8~^|S diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc deleted file mode 100644 index 4bc9db95dd912abec0f3f443fe160af51c03f617..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21164 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 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/response.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/response.cpython-37.pyc deleted file mode 100644 index 5558c199e5f6ff43da442434c9d7a4297aac500a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29643 zcmdUYTZ|mnnO@(!=hhsKNQ$H=syLF!8HsFC6fMhRNft$sB5i3Xb4H@wwzj*bt7h0U zeHm3%lbrU9cVjB??j|yf*x6lV<%9&Bg%byklOO?hgN=;@NjAyG8z4{V_+f!O=_vv7 z6k{LqegC;sbkjsPFFMXovmi^ooVIT`D#9$^0Hp8RcIHhMY+$nO6{@gnA{hT zXS_Nt_r=ykd$Kwu_oY_3y|21Y?#FOHU7eQu@z(zKOm#-?Ct44+4^$7x{Uq)WRuAGn z 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 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc deleted file mode 100644 index 4fad230fa7686123fa6fe2b33b8b385d803af787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 818 zcmY*X!EO^V5VhBvuvBS52#Kr3B?=N*0S7J!C?Ij72N0^1i?vx#6F082wY>?6dTXVg z;0xfyiC@|)r~U#bW;Q9PmS+6CV?Vz)>o>c*I}FDU@v8jE8T(C(>md-l#t08FX{Nbl zBi_!*D0$CxqQwQ%;yf7%%|Ee0dWHMgK}q>~q+1XkA%OP$C;@StQfRJ|@8XgjaV>Ou z(HnIxS;|IT)3Ap&dd@=4|AeyxBlhAZ$%gyW|*4~vUyB#FAgK-C=l^oeI z*E}X9^sC@3igR|Hp7FEf8|P?oaOey0`REioCz#e&OfTxBd?QNw> zTZEw0FZRdeWHIDpUuX*}n@{n|B2MQnFQ-t>=5>7Q0o~>caEsiUabB&c{A~C<4<^Fn ziVjR5?CF=(_n>_p{{uUW=#R(|Y z>?n0I*R>_wQ|h!X?6$&VBlg{fzS-S+E5TZ&JpJ!B4Y=PUe3ufnmtI34knwgsNSkh4 gRoGvDpY~*wsQ#a0gNUKYUTnm?qz4wLuNlw8Uujm`g8%>k diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py deleted file mode 100644 index da24dba..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py +++ /dev/null @@ -1,14 +0,0 @@ -import typing as t -import warnings - - -class AcceptMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'AcceptMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py deleted file mode 100644 index f7f5815..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py +++ /dev/null @@ -1,26 +0,0 @@ -import typing as t -import warnings - - -class AuthorizationMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'AuthorizationMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) - - -class WWWAuthenticateMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'WWWAuthenticateMixin' is deprecated and will be removed" - " in Werkzeug 2.1. 'Response' now includes the" - " functionality directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py deleted file mode 100644 index 451989f..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py +++ /dev/null @@ -1,36 +0,0 @@ -import typing as t -import warnings - -from .request import Request - - -class _FakeSubclassCheck(type): - def __subclasscheck__(cls, subclass: t.Type) -> bool: - warnings.warn( - "'BaseRequest' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'issubclass(cls, Request)' instead.", - DeprecationWarning, - stacklevel=2, - ) - return issubclass(subclass, Request) - - def __instancecheck__(cls, instance: t.Any) -> bool: - warnings.warn( - "'BaseRequest' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'isinstance(obj, Request)' instead.", - DeprecationWarning, - stacklevel=2, - ) - return isinstance(instance, Request) - - -class BaseRequest(Request, metaclass=_FakeSubclassCheck): - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'BaseRequest' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py deleted file mode 100644 index 3e0dc67..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py +++ /dev/null @@ -1,36 +0,0 @@ -import typing as t -import warnings - -from .response import Response - - -class _FakeSubclassCheck(type): - def __subclasscheck__(cls, subclass: t.Type) -> bool: - warnings.warn( - "'BaseResponse' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'issubclass(cls, Response)' instead.", - DeprecationWarning, - stacklevel=2, - ) - return issubclass(subclass, Response) - - def __instancecheck__(cls, instance: t.Any) -> bool: - warnings.warn( - "'BaseResponse' is deprecated and will be removed in" - " Werkzeug 2.1. Use 'isinstance(obj, Response)' instead.", - DeprecationWarning, - stacklevel=2, - ) - return isinstance(instance, Response) - - -class BaseResponse(Response, metaclass=_FakeSubclassCheck): - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'BaseResponse' is deprecated and will be removed in" - " Werkzeug 2.1. 'Response' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py deleted file mode 100644 index 6436b4c..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py +++ /dev/null @@ -1,26 +0,0 @@ -import typing as t -import warnings - - -class CommonRequestDescriptorsMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'CommonRequestDescriptorsMixin' is deprecated and will be" - " removed in Werkzeug 2.1. 'Request' now includes the" - " functionality directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) - - -class CommonResponseDescriptorsMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'CommonResponseDescriptorsMixin' is deprecated and will be" - " removed in Werkzeug 2.1. 'Response' now includes the" - " functionality directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/cors.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/cors.py deleted file mode 100644 index efd8537..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/cors.py +++ /dev/null @@ -1,26 +0,0 @@ -import typing as t -import warnings - - -class CORSRequestMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'CORSRequestMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) - - -class CORSResponseMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'CORSResponseMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Response' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py deleted file mode 100644 index 9131b93..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py +++ /dev/null @@ -1,26 +0,0 @@ -import typing as t -import warnings - - -class ETagRequestMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'ETagRequestMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) - - -class ETagResponseMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'ETagResponseMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Response' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py deleted file mode 100644 index a4dd7c2..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py +++ /dev/null @@ -1,13 +0,0 @@ -import typing as t -import warnings - - -class JSONMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'JSONMixin' is deprecated and will be removed in Werkzeug" - " 2.1. 'Request' now includes the functionality directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py deleted file mode 100644 index f68dd5a..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py +++ /dev/null @@ -1,660 +0,0 @@ -import functools -import json -import typing -import typing as t -import warnings -from io import BytesIO - -from .._internal import _wsgi_decoding_dance -from ..datastructures import CombinedMultiDict -from ..datastructures import EnvironHeaders -from ..datastructures import FileStorage -from ..datastructures import ImmutableMultiDict -from ..datastructures import iter_multi_items -from ..datastructures import MultiDict -from ..formparser import default_stream_factory -from ..formparser import FormDataParser -from ..sansio.request import Request as _SansIORequest -from ..utils import cached_property -from ..utils import environ_property -from ..wsgi import _get_server -from ..wsgi import get_input_stream -from werkzeug.exceptions import BadRequest - -if t.TYPE_CHECKING: - import typing_extensions as te - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -class Request(_SansIORequest): - """Represents an incoming WSGI HTTP request, with headers and body - taken from the WSGI environment. Has properties and methods for - using the functionality defined by various HTTP specs. The data in - requests object is read-only. - - Text data is assumed to use UTF-8 encoding, which should be true for - the vast majority of modern clients. Using an encoding set by the - client is unsafe in Python due to extra encodings it provides, such - as ``zip``. To change the assumed encoding, subclass and replace - :attr:`charset`. - - :param environ: The WSGI environ is generated by the WSGI server and - contains information about the server configuration and client - request. - :param populate_request: Add this request object to the WSGI environ - as ``environ['werkzeug.request']``. Can be useful when - debugging. - :param shallow: Makes reading from :attr:`stream` (and any method - that would read from it) raise a :exc:`RuntimeError`. Useful to - prevent consuming the form data in middleware, which would make - it unavailable to the final application. - - .. versionchanged:: 2.0 - Combine ``BaseRequest`` and mixins into a single ``Request`` - class. Using the old classes is deprecated and will be removed - in Werkzeug 2.1. - - .. versionchanged:: 0.5 - Read-only mode is enforced with immutable classes for all data. - """ - - #: the maximum content length. This is forwarded to the form data - #: parsing function (:func:`parse_form_data`). When set and the - #: :attr:`form` or :attr:`files` attribute is accessed and the - #: parsing fails because more than the specified value is transmitted - #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. - #: - #: Have a look at :doc:`/request_data` for more details. - #: - #: .. versionadded:: 0.5 - max_content_length: t.Optional[int] = None - - #: the maximum form field size. This is forwarded to the form data - #: parsing function (:func:`parse_form_data`). When set and the - #: :attr:`form` or :attr:`files` attribute is accessed and the - #: data in memory for post data is longer than the specified value a - #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. - #: - #: Have a look at :doc:`/request_data` for more details. - #: - #: .. versionadded:: 0.5 - max_form_memory_size: t.Optional[int] = None - - #: The form data parser that shoud be used. Can be replaced to customize - #: the form date parsing. - form_data_parser_class: t.Type[FormDataParser] = FormDataParser - - #: Disable the :attr:`data` property to avoid reading from the input - #: stream. - #: - #: .. deprecated:: 2.0 - #: Will be removed in Werkzeug 2.1. Create the request with - #: ``shallow=True`` instead. - #: - #: .. versionadded:: 0.9 - disable_data_descriptor: t.Optional[bool] = None - - #: The WSGI environment containing HTTP headers and information from - #: the WSGI server. - environ: "WSGIEnvironment" - - #: Set when creating the request object. If ``True``, reading from - #: the request body will cause a ``RuntimeException``. Useful to - #: prevent modifying the stream from middleware. - shallow: bool - - def __init__( - self, - environ: "WSGIEnvironment", - populate_request: bool = True, - shallow: bool = False, - ) -> None: - super().__init__( - method=environ.get("REQUEST_METHOD", "GET"), - scheme=environ.get("wsgi.url_scheme", "http"), - server=_get_server(environ), - root_path=_wsgi_decoding_dance( - environ.get("SCRIPT_NAME") or "", self.charset, self.encoding_errors - ), - path=_wsgi_decoding_dance( - environ.get("PATH_INFO") or "", self.charset, self.encoding_errors - ), - query_string=environ.get("QUERY_STRING", "").encode("latin1"), - headers=EnvironHeaders(environ), - remote_addr=environ.get("REMOTE_ADDR"), - ) - self.environ = environ - - if self.disable_data_descriptor is not None: - warnings.warn( - "'disable_data_descriptor' is deprecated and will be" - " removed in Werkzeug 2.1. Create the request with" - " 'shallow=True' instead.", - DeprecationWarning, - stacklevel=2, - ) - shallow = shallow or self.disable_data_descriptor - - self.shallow = shallow - - if populate_request and not shallow: - self.environ["werkzeug.request"] = self - - @classmethod - def from_values(cls, *args: t.Any, **kwargs: t.Any) -> "Request": - """Create a new request object based on the values provided. If - environ is given missing values are filled from there. This method is - useful for small scripts when you need to simulate a request from an URL. - Do not use this method for unittesting, there is a full featured client - object (:class:`Client`) that allows to create multipart requests, - support for cookies etc. - - This accepts the same options as the - :class:`~werkzeug.test.EnvironBuilder`. - - .. versionchanged:: 0.5 - This method now accepts the same arguments as - :class:`~werkzeug.test.EnvironBuilder`. Because of this the - `environ` parameter is now called `environ_overrides`. - - :return: request object - """ - from ..test import EnvironBuilder - - charset = kwargs.pop("charset", cls.charset) - kwargs["charset"] = charset - builder = EnvironBuilder(*args, **kwargs) - try: - return builder.get_request(cls) - finally: - builder.close() - - @classmethod - def application( - cls, f: t.Callable[["Request"], "WSGIApplication"] - ) -> "WSGIApplication": - """Decorate a function as responder that accepts the request as - the last argument. This works like the :func:`responder` - decorator but the function is passed the request object as the - last argument and the request object will be closed - automatically:: - - @Request.application - def my_wsgi_app(request): - return Response('Hello World!') - - As of Werkzeug 0.14 HTTP exceptions are automatically caught and - converted to responses instead of failing. - - :param f: the WSGI callable to decorate - :return: a new WSGI callable - """ - #: return a callable that wraps the -2nd argument with the request - #: and calls the function with all the arguments up to that one and - #: the request. The return value is then called with the latest - #: two arguments. This makes it possible to use this decorator for - #: both standalone WSGI functions as well as bound methods and - #: partially applied functions. - from ..exceptions import HTTPException - - @functools.wraps(f) - def application(*args): # type: ignore - request = cls(args[-2]) - with request: - try: - resp = f(*args[:-2] + (request,)) - except HTTPException as e: - resp = e.get_response(args[-2]) - return resp(*args[-2:]) - - return t.cast("WSGIApplication", application) - - def _get_file_stream( - self, - total_content_length: t.Optional[int], - content_type: t.Optional[str], - filename: t.Optional[str] = None, - content_length: t.Optional[int] = None, - ) -> t.IO[bytes]: - """Called to get a stream for the file upload. - - This must provide a file-like class with `read()`, `readline()` - and `seek()` methods that is both writeable and readable. - - The default implementation returns a temporary file if the total - content length is higher than 500KB. Because many browsers do not - provide a content length for the files only the total content - length matters. - - :param total_content_length: the total content length of all the - data in the request combined. This value - is guaranteed to be there. - :param content_type: the mimetype of the uploaded file. - :param filename: the filename of the uploaded file. May be `None`. - :param content_length: the length of this file. This value is usually - not provided because webbrowsers do not provide - this value. - """ - return default_stream_factory( - total_content_length=total_content_length, - filename=filename, - content_type=content_type, - content_length=content_length, - ) - - @property - def want_form_data_parsed(self) -> bool: - """``True`` if the request method carries content. By default - this is true if a ``Content-Type`` is sent. - - .. versionadded:: 0.8 - """ - return bool(self.environ.get("CONTENT_TYPE")) - - def make_form_data_parser(self) -> FormDataParser: - """Creates the form data parser. Instantiates the - :attr:`form_data_parser_class` with some parameters. - - .. versionadded:: 0.8 - """ - return self.form_data_parser_class( - self._get_file_stream, - self.charset, - self.encoding_errors, - self.max_form_memory_size, - self.max_content_length, - self.parameter_storage_class, - ) - - def _load_form_data(self) -> None: - """Method used internally to retrieve submitted data. After calling - this sets `form` and `files` on the request object to multi dicts - filled with the incoming form data. As a matter of fact the input - stream will be empty afterwards. You can also call this method to - force the parsing of the form data. - - .. versionadded:: 0.8 - """ - # abort early if we have already consumed the stream - if "form" in self.__dict__: - return - - if self.want_form_data_parsed: - parser = self.make_form_data_parser() - data = parser.parse( - self._get_stream_for_parsing(), - self.mimetype, - self.content_length, - self.mimetype_params, - ) - else: - data = ( - self.stream, - self.parameter_storage_class(), - self.parameter_storage_class(), - ) - - # inject the values into the instance dict so that we bypass - # our cached_property non-data descriptor. - d = self.__dict__ - d["stream"], d["form"], d["files"] = data - - def _get_stream_for_parsing(self) -> t.IO[bytes]: - """This is the same as accessing :attr:`stream` with the difference - that if it finds cached data from calling :meth:`get_data` first it - will create a new stream out of the cached data. - - .. versionadded:: 0.9.3 - """ - cached_data = getattr(self, "_cached_data", None) - if cached_data is not None: - return BytesIO(cached_data) - return self.stream - - def close(self) -> None: - """Closes associated resources of this request object. This - closes all file handles explicitly. You can also use the request - object in a with statement which will automatically close it. - - .. versionadded:: 0.9 - """ - files = self.__dict__.get("files") - for _key, value in iter_multi_items(files or ()): - value.close() - - def __enter__(self) -> "Request": - return self - - def __exit__(self, exc_type, exc_value, tb) -> None: # type: ignore - self.close() - - @cached_property - def stream(self) -> t.IO[bytes]: - """ - If the incoming form data was not encoded with a known mimetype - the data is stored unmodified in this stream for consumption. Most - of the time it is a better idea to use :attr:`data` which will give - you that data as a string. The stream only returns the data once. - - Unlike :attr:`input_stream` this stream is properly guarded that you - can't accidentally read past the length of the input. Werkzeug will - internally always refer to this stream to read data which makes it - possible to wrap this object with a stream that does filtering. - - .. versionchanged:: 0.9 - This stream is now always available but might be consumed by the - form parser later on. Previously the stream was only set if no - parsing happened. - """ - if self.shallow: - raise RuntimeError( - "This request was created with 'shallow=True', reading" - " from the input stream is disabled." - ) - - return get_input_stream(self.environ) - - input_stream = environ_property[t.IO[bytes]]( - "wsgi.input", - doc="""The WSGI input stream. - - In general it's a bad idea to use this one because you can - easily read past the boundary. Use the :attr:`stream` - instead.""", - ) - - @cached_property - def data(self) -> bytes: - """ - Contains the incoming request data as string in case it came with - a mimetype Werkzeug does not handle. - """ - return self.get_data(parse_form_data=True) - - @typing.overload - def get_data( # type: ignore - self, - cache: bool = True, - as_text: "te.Literal[False]" = False, - parse_form_data: bool = False, - ) -> bytes: - ... - - @typing.overload - def get_data( - self, - cache: bool = True, - as_text: "te.Literal[True]" = ..., - parse_form_data: bool = False, - ) -> str: - ... - - def get_data( - self, cache: bool = True, as_text: bool = False, parse_form_data: bool = False - ) -> t.Union[bytes, str]: - """This reads the buffered incoming data from the client into one - bytes object. By default this is cached but that behavior can be - changed by setting `cache` to `False`. - - Usually it's a bad idea to call this method without checking the - content length first as a client could send dozens of megabytes or more - to cause memory problems on the server. - - Note that if the form data was already parsed this method will not - return anything as form data parsing does not cache the data like - this method does. To implicitly invoke form data parsing function - set `parse_form_data` to `True`. When this is done the return value - of this method will be an empty string if the form parser handles - the data. This generally is not necessary as if the whole data is - cached (which is the default) the form parser will used the cached - data to parse the form data. Please be generally aware of checking - the content length first in any case before calling this method - to avoid exhausting server memory. - - If `as_text` is set to `True` the return value will be a decoded - string. - - .. versionadded:: 0.9 - """ - rv = getattr(self, "_cached_data", None) - if rv is None: - if parse_form_data: - self._load_form_data() - rv = self.stream.read() - if cache: - self._cached_data = rv - if as_text: - rv = rv.decode(self.charset, self.encoding_errors) - return rv - - @cached_property - def form(self) -> "ImmutableMultiDict[str, str]": - """The form parameters. By default an - :class:`~werkzeug.datastructures.ImmutableMultiDict` - is returned from this function. This can be changed by setting - :attr:`parameter_storage_class` to a different type. This might - be necessary if the order of the form data is important. - - Please keep in mind that file uploads will not end up here, but instead - in the :attr:`files` attribute. - - .. versionchanged:: 0.9 - - Previous to Werkzeug 0.9 this would only contain form data for POST - and PUT requests. - """ - self._load_form_data() - return self.form - - @cached_property - def values(self) -> "CombinedMultiDict[str, str]": - """A :class:`werkzeug.datastructures.CombinedMultiDict` that - combines :attr:`args` and :attr:`form`. - - For GET requests, only ``args`` are present, not ``form``. - - .. versionchanged:: 2.0 - For GET requests, only ``args`` are present, not ``form``. - """ - sources = [self.args] - - if self.method != "GET": - # GET requests can have a body, and some caching proxies - # might not treat that differently than a normal GET - # request, allowing form data to "invisibly" affect the - # cache without indication in the query string / URL. - sources.append(self.form) - - args = [] - - for d in sources: - if not isinstance(d, MultiDict): - d = MultiDict(d) - - args.append(d) - - return CombinedMultiDict(args) - - @cached_property - def files(self) -> "ImmutableMultiDict[str, FileStorage]": - """:class:`~werkzeug.datastructures.MultiDict` object containing - all uploaded files. Each key in :attr:`files` is the name from the - ````. Each value in :attr:`files` is a - Werkzeug :class:`~werkzeug.datastructures.FileStorage` object. - - It basically behaves like a standard file object you know from Python, - with the difference that it also has a - :meth:`~werkzeug.datastructures.FileStorage.save` function that can - store the file on the filesystem. - - Note that :attr:`files` will only contain data if the request method was - POST, PUT or PATCH and the ``

    `` that posted to the request had - ``enctype="multipart/form-data"``. It will be empty otherwise. - - See the :class:`~werkzeug.datastructures.MultiDict` / - :class:`~werkzeug.datastructures.FileStorage` documentation for - more details about the used data structure. - """ - self._load_form_data() - return self.files - - @property - def script_root(self) -> str: - """Alias for :attr:`self.root_path`. ``environ["SCRIPT_ROOT"]`` - without a trailing slash. - """ - return self.root_path - - @cached_property - def url_root(self) -> str: - """Alias for :attr:`root_url`. The URL with scheme, host, and - root path. For example, ``https://example.com/app/``. - """ - return self.root_url - - remote_user = environ_property[str]( - "REMOTE_USER", - doc="""If the server supports user authentication, and the - script is protected, this attribute contains the username the - user has authenticated as.""", - ) - is_multithread = environ_property[bool]( - "wsgi.multithread", - doc="""boolean that is `True` if the application is served by a - multithreaded WSGI server.""", - ) - is_multiprocess = environ_property[bool]( - "wsgi.multiprocess", - doc="""boolean that is `True` if the application is served by a - WSGI server that spawns multiple processes.""", - ) - is_run_once = environ_property[bool]( - "wsgi.run_once", - doc="""boolean that is `True` if the application will be - executed only once in a process lifetime. This is the case for - CGI for example, but it's not guaranteed that the execution only - happens one time.""", - ) - - # JSON - - #: A module or other object that has ``dumps`` and ``loads`` - #: functions that match the API of the built-in :mod:`json` module. - json_module = json - - @property - def json(self) -> t.Optional[t.Any]: - """The parsed JSON data if :attr:`mimetype` indicates JSON - (:mimetype:`application/json`, see :attr:`is_json`). - - Calls :meth:`get_json` with default arguments. - """ - return self.get_json() - - # Cached values for ``(silent=False, silent=True)``. Initialized - # with sentinel values. - _cached_json: t.Tuple[t.Any, t.Any] = (Ellipsis, Ellipsis) - - def get_json( - self, force: bool = False, silent: bool = False, cache: bool = True - ) -> t.Optional[t.Any]: - """Parse :attr:`data` as JSON. - - If the mimetype does not indicate JSON - (:mimetype:`application/json`, see :attr:`is_json`), this - returns ``None``. - - If parsing fails, :meth:`on_json_loading_failed` is called and - its return value is used as the return value. - - :param force: Ignore the mimetype and always try to parse JSON. - :param silent: Silence parsing errors and return ``None`` - instead. - :param cache: Store the parsed JSON to return for subsequent - calls. - """ - if cache and self._cached_json[silent] is not Ellipsis: - return self._cached_json[silent] - - if not (force or self.is_json): - return None - - data = self.get_data(cache=cache) - - try: - rv = self.json_module.loads(data) - except ValueError as e: - if silent: - rv = None - - if cache: - normal_rv, _ = self._cached_json - self._cached_json = (normal_rv, rv) - else: - rv = self.on_json_loading_failed(e) - - if cache: - _, silent_rv = self._cached_json - self._cached_json = (rv, silent_rv) - else: - if cache: - self._cached_json = (rv, rv) - - return rv - - def on_json_loading_failed(self, e: ValueError) -> t.Any: - """Called if :meth:`get_json` parsing fails and isn't silenced. - If this method returns a value, it is used as the return value - for :meth:`get_json`. The default implementation raises - :exc:`~werkzeug.exceptions.BadRequest`. - """ - raise BadRequest(f"Failed to decode JSON object: {e}") - - -class StreamOnlyMixin: - """Mixin to create a ``Request`` that disables the ``data``, - ``form``, and ``files`` properties. Only ``stream`` is available. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Create the request with - ``shallow=True`` instead. - - .. versionadded:: 0.9 - """ - - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'StreamOnlyMixin' is deprecated and will be removed in" - " Werkzeug 2.1. Create the request with 'shallow=True'" - " instead.", - DeprecationWarning, - stacklevel=2, - ) - kwargs["shallow"] = True - super().__init__(*args, **kwargs) - - -class PlainRequest(StreamOnlyMixin, Request): - """A request object without ``data``, ``form``, and ``files``. - - .. deprecated:: 2.0 - Will be removed in Werkzeug 2.1. Create the request with - ``shallow=True`` instead. - - .. versionadded:: 0.9 - """ - - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'PlainRequest' is deprecated and will be removed in" - " Werkzeug 2.1. Create the request with 'shallow=True'" - " instead.", - DeprecationWarning, - stacklevel=2, - ) - - # Don't show the DeprecationWarning for StreamOnlyMixin. - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py deleted file mode 100644 index 8378e74..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py +++ /dev/null @@ -1,891 +0,0 @@ -import json -import typing -import typing as t -import warnings -from http import HTTPStatus - -from .._internal import _to_bytes -from ..datastructures import Headers -from ..http import remove_entity_headers -from ..sansio.response import Response as _SansIOResponse -from ..urls import iri_to_uri -from ..urls import url_join -from ..utils import cached_property -from ..wsgi import ClosingIterator -from ..wsgi import get_current_url -from werkzeug._internal import _get_environ -from werkzeug.http import generate_etag -from werkzeug.http import http_date -from werkzeug.http import is_resource_modified -from werkzeug.http import parse_etags -from werkzeug.http import parse_range_header -from werkzeug.wsgi import _RangeWrapper - -if t.TYPE_CHECKING: - import typing_extensions as te - from _typeshed.wsgi import StartResponse - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - from .request import Request - - -def _warn_if_string(iterable: t.Iterable) -> None: - """Helper for the response objects to check if the iterable returned - to the WSGI server is not a string. - """ - if isinstance(iterable, str): - warnings.warn( - "Response iterable was set to a string. This will appear to" - " work but means that the server will send the data to the" - " client one character at a time. This is almost never" - " intended behavior, use 'response.data' to assign strings" - " to the response object.", - stacklevel=2, - ) - - -def _iter_encoded( - iterable: t.Iterable[t.Union[str, bytes]], charset: str -) -> t.Iterator[bytes]: - for item in iterable: - if isinstance(item, str): - yield item.encode(charset) - else: - yield item - - -def _clean_accept_ranges(accept_ranges: t.Union[bool, str]) -> str: - if accept_ranges is True: - return "bytes" - elif accept_ranges is False: - return "none" - elif isinstance(accept_ranges, str): - return accept_ranges - raise ValueError("Invalid accept_ranges value") - - -class Response(_SansIOResponse): - """Represents an outgoing WSGI HTTP response with body, status, and - headers. Has properties and methods for using the functionality - defined by various HTTP specs. - - The response body is flexible to support different use cases. The - simple form is passing bytes, or a string which will be encoded as - UTF-8. Passing an iterable of bytes or strings makes this a - streaming response. A generator is particularly useful for building - a CSV file in memory or using SSE (Server Sent Events). A file-like - object is also iterable, although the - :func:`~werkzeug.utils.send_file` helper should be used in that - case. - - The response object is itself a WSGI application callable. When - called (:meth:`__call__`) with ``environ`` and ``start_response``, - it will pass its status and headers to ``start_response`` then - return its body as an iterable. - - .. code-block:: python - - from werkzeug.wrappers.response import Response - - def index(): - return Response("Hello, World!") - - def application(environ, start_response): - path = environ.get("PATH_INFO") or "/" - - if path == "/": - response = index() - else: - response = Response("Not Found", status=404) - - return response(environ, start_response) - - :param response: The data for the body of the response. A string or - bytes, or tuple or list of strings or bytes, for a fixed-length - response, or any other iterable of strings or bytes for a - streaming response. Defaults to an empty body. - :param status: The status code for the response. Either an int, in - which case the default status message is added, or a string in - the form ``{code} {message}``, like ``404 Not Found``. Defaults - to 200. - :param headers: A :class:`~werkzeug.datastructures.Headers` object, - or a list of ``(key, value)`` tuples that will be converted to a - ``Headers`` object. - :param mimetype: The mime type (content type without charset or - other parameters) of the response. If the value starts with - ``text/`` (or matches some other special cases), the charset - will be added to create the ``content_type``. - :param content_type: The full content type of the response. - Overrides building the value from ``mimetype``. - :param direct_passthrough: Pass the response body directly through - as the WSGI iterable. This can be used when the body is a binary - file or other iterator of bytes, to skip some unnecessary - checks. Use :func:`~werkzeug.utils.send_file` instead of setting - this manually. - - .. versionchanged:: 2.0 - Combine ``BaseResponse`` and mixins into a single ``Response`` - class. Using the old classes is deprecated and will be removed - in Werkzeug 2.1. - - .. versionchanged:: 0.5 - The ``direct_passthrough`` parameter was added. - """ - - #: if set to `False` accessing properties on the response object will - #: not try to consume the response iterator and convert it into a list. - #: - #: .. versionadded:: 0.6.2 - #: - #: That attribute was previously called `implicit_seqence_conversion`. - #: (Notice the typo). If you did use this feature, you have to adapt - #: your code to the name change. - implicit_sequence_conversion = True - - #: Should this response object correct the location header to be RFC - #: conformant? This is true by default. - #: - #: .. versionadded:: 0.8 - autocorrect_location_header = True - - #: Should this response object automatically set the content-length - #: header if possible? This is true by default. - #: - #: .. versionadded:: 0.8 - automatically_set_content_length = True - - #: The response body to send as the WSGI iterable. A list of strings - #: or bytes represents a fixed-length response, any other iterable - #: is a streaming response. Strings are encoded to bytes as UTF-8. - #: - #: Do not set to a plain string or bytes, that will cause sending - #: the response to be very inefficient as it will iterate one byte - #: at a time. - response: t.Union[t.Iterable[str], t.Iterable[bytes]] - - def __init__( - self, - response: t.Optional[ - t.Union[t.Iterable[bytes], bytes, t.Iterable[str], str] - ] = None, - status: t.Optional[t.Union[int, str, HTTPStatus]] = None, - headers: t.Optional[ - t.Union[ - t.Mapping[str, t.Union[str, int, t.Iterable[t.Union[str, int]]]], - t.Iterable[t.Tuple[str, t.Union[str, int]]], - ] - ] = None, - mimetype: t.Optional[str] = None, - content_type: t.Optional[str] = None, - direct_passthrough: bool = False, - ) -> None: - super().__init__( - status=status, - headers=headers, - mimetype=mimetype, - content_type=content_type, - ) - - #: Pass the response body directly through as the WSGI iterable. - #: This can be used when the body is a binary file or other - #: iterator of bytes, to skip some unnecessary checks. Use - #: :func:`~werkzeug.utils.send_file` instead of setting this - #: manually. - self.direct_passthrough = direct_passthrough - self._on_close: t.List[t.Callable[[], t.Any]] = [] - - # we set the response after the headers so that if a class changes - # the charset attribute, the data is set in the correct charset. - if response is None: - self.response = [] - elif isinstance(response, (str, bytes, bytearray)): - self.set_data(response) - else: - self.response = response - - def call_on_close(self, func: t.Callable[[], t.Any]) -> t.Callable[[], t.Any]: - """Adds a function to the internal list of functions that should - be called as part of closing down the response. Since 0.7 this - function also returns the function that was passed so that this - can be used as a decorator. - - .. versionadded:: 0.6 - """ - self._on_close.append(func) - return func - - def __repr__(self) -> str: - if self.is_sequence: - body_info = f"{sum(map(len, self.iter_encoded()))} bytes" - else: - body_info = "streamed" if self.is_streamed else "likely-streamed" - return f"<{type(self).__name__} {body_info} [{self.status}]>" - - @classmethod - def force_type( - cls, response: "Response", environ: t.Optional["WSGIEnvironment"] = None - ) -> "Response": - """Enforce that the WSGI response is a response object of the current - type. Werkzeug will use the :class:`Response` internally in many - situations like the exceptions. If you call :meth:`get_response` on an - exception you will get back a regular :class:`Response` object, even - if you are using a custom subclass. - - This method can enforce a given response type, and it will also - convert arbitrary WSGI callables into response objects if an environ - is provided:: - - # convert a Werkzeug response object into an instance of the - # MyResponseClass subclass. - response = MyResponseClass.force_type(response) - - # convert any WSGI application into a response object - response = MyResponseClass.force_type(response, environ) - - This is especially useful if you want to post-process responses in - the main dispatcher and use functionality provided by your subclass. - - Keep in mind that this will modify response objects in place if - possible! - - :param response: a response object or wsgi application. - :param environ: a WSGI environment object. - :return: a response object. - """ - if not isinstance(response, Response): - if environ is None: - raise TypeError( - "cannot convert WSGI application into response" - " objects without an environ" - ) - - from ..test import run_wsgi_app - - response = Response(*run_wsgi_app(response, environ)) - - response.__class__ = cls - return response - - @classmethod - def from_app( - cls, app: "WSGIApplication", environ: "WSGIEnvironment", buffered: bool = False - ) -> "Response": - """Create a new response object from an application output. This - works best if you pass it an application that returns a generator all - the time. Sometimes applications may use the `write()` callable - returned by the `start_response` function. This tries to resolve such - edge cases automatically. But if you don't get the expected output - you should set `buffered` to `True` which enforces buffering. - - :param app: the WSGI application to execute. - :param environ: the WSGI environment to execute against. - :param buffered: set to `True` to enforce buffering. - :return: a response object. - """ - from ..test import run_wsgi_app - - return cls(*run_wsgi_app(app, environ, buffered)) - - @typing.overload - def get_data(self, as_text: "te.Literal[False]" = False) -> bytes: - ... - - @typing.overload - def get_data(self, as_text: "te.Literal[True]") -> str: - ... - - def get_data(self, as_text: bool = False) -> t.Union[bytes, str]: - """The string representation of the response body. Whenever you call - this property the response iterable is encoded and flattened. This - can lead to unwanted behavior if you stream big data. - - This behavior can be disabled by setting - :attr:`implicit_sequence_conversion` to `False`. - - If `as_text` is set to `True` the return value will be a decoded - string. - - .. versionadded:: 0.9 - """ - self._ensure_sequence() - rv = b"".join(self.iter_encoded()) - - if as_text: - return rv.decode(self.charset) - - return rv - - def set_data(self, value: t.Union[bytes, str]) -> None: - """Sets a new string as response. The value must be a string or - bytes. If a string is set it's encoded to the charset of the - response (utf-8 by default). - - .. versionadded:: 0.9 - """ - # if a string is set, it's encoded directly so that we - # can set the content length - if isinstance(value, str): - value = value.encode(self.charset) - else: - value = bytes(value) - self.response = [value] - if self.automatically_set_content_length: - self.headers["Content-Length"] = str(len(value)) - - data = property( - get_data, - set_data, - doc="A descriptor that calls :meth:`get_data` and :meth:`set_data`.", - ) - - def calculate_content_length(self) -> t.Optional[int]: - """Returns the content length if available or `None` otherwise.""" - try: - self._ensure_sequence() - except RuntimeError: - return None - return sum(len(x) for x in self.iter_encoded()) - - def _ensure_sequence(self, mutable: bool = False) -> None: - """This method can be called by methods that need a sequence. If - `mutable` is true, it will also ensure that the response sequence - is a standard Python list. - - .. versionadded:: 0.6 - """ - if self.is_sequence: - # if we need a mutable object, we ensure it's a list. - if mutable and not isinstance(self.response, list): - self.response = list(self.response) # type: ignore - return - if self.direct_passthrough: - raise RuntimeError( - "Attempted implicit sequence conversion but the" - " response object is in direct passthrough mode." - ) - if not self.implicit_sequence_conversion: - raise RuntimeError( - "The response object required the iterable to be a" - " sequence, but the implicit conversion was disabled." - " Call make_sequence() yourself." - ) - self.make_sequence() - - def make_sequence(self) -> None: - """Converts the response iterator in a list. By default this happens - automatically if required. If `implicit_sequence_conversion` is - disabled, this method is not automatically called and some properties - might raise exceptions. This also encodes all the items. - - .. versionadded:: 0.6 - """ - if not self.is_sequence: - # if we consume an iterable we have to ensure that the close - # method of the iterable is called if available when we tear - # down the response - close = getattr(self.response, "close", None) - self.response = list(self.iter_encoded()) - if close is not None: - self.call_on_close(close) - - def iter_encoded(self) -> t.Iterator[bytes]: - """Iter the response encoded with the encoding of the response. - If the response object is invoked as WSGI application the return - value of this method is used as application iterator unless - :attr:`direct_passthrough` was activated. - """ - if __debug__: - _warn_if_string(self.response) - # Encode in a separate function so that self.response is fetched - # early. This allows us to wrap the response with the return - # value from get_app_iter or iter_encoded. - return _iter_encoded(self.response, self.charset) - - @property - def is_streamed(self) -> bool: - """If the response is streamed (the response is not an iterable with - a length information) this property is `True`. In this case streamed - means that there is no information about the number of iterations. - This is usually `True` if a generator is passed to the response object. - - This is useful for checking before applying some sort of post - filtering that should not take place for streamed responses. - """ - try: - len(self.response) # type: ignore - except (TypeError, AttributeError): - return True - return False - - @property - def is_sequence(self) -> bool: - """If the iterator is buffered, this property will be `True`. A - response object will consider an iterator to be buffered if the - response attribute is a list or tuple. - - .. versionadded:: 0.6 - """ - return isinstance(self.response, (tuple, list)) - - def close(self) -> None: - """Close the wrapped response if possible. You can also use the object - in a with statement which will automatically close it. - - .. versionadded:: 0.9 - Can now be used in a with statement. - """ - if hasattr(self.response, "close"): - self.response.close() # type: ignore - for func in self._on_close: - func() - - def __enter__(self) -> "Response": - return self - - def __exit__(self, exc_type, exc_value, tb): # type: ignore - self.close() - - def freeze(self, no_etag: None = None) -> None: - """Make the response object ready to be pickled. Does the - following: - - * Buffer the response into a list, ignoring - :attr:`implicity_sequence_conversion` and - :attr:`direct_passthrough`. - * Set the ``Content-Length`` header. - * Generate an ``ETag`` header if one is not already set. - - .. versionchanged:: 2.0 - An ``ETag`` header is added, the ``no_etag`` parameter is - deprecated and will be removed in Werkzeug 2.1. - - .. versionchanged:: 0.6 - The ``Content-Length`` header is set. - """ - # Always freeze the encoded response body, ignore - # implicit_sequence_conversion and direct_passthrough. - self.response = list(self.iter_encoded()) - self.headers["Content-Length"] = str(sum(map(len, self.response))) - - if no_etag is not None: - warnings.warn( - "The 'no_etag' parameter is deprecated and will be" - " removed in Werkzeug 2.1.", - DeprecationWarning, - stacklevel=2, - ) - - self.add_etag() - - def get_wsgi_headers(self, environ: "WSGIEnvironment") -> Headers: - """This is automatically called right before the response is started - and returns headers modified for the given environment. It returns a - copy of the headers from the response with some modifications applied - if necessary. - - For example the location header (if present) is joined with the root - URL of the environment. Also the content length is automatically set - to zero here for certain status codes. - - .. versionchanged:: 0.6 - Previously that function was called `fix_headers` and modified - the response object in place. Also since 0.6, IRIs in location - and content-location headers are handled properly. - - Also starting with 0.6, Werkzeug will attempt to set the content - length if it is able to figure it out on its own. This is the - case if all the strings in the response iterable are already - encoded and the iterable is buffered. - - :param environ: the WSGI environment of the request. - :return: returns a new :class:`~werkzeug.datastructures.Headers` - object. - """ - headers = Headers(self.headers) - location: t.Optional[str] = None - content_location: t.Optional[str] = None - content_length: t.Optional[t.Union[str, int]] = None - status = self.status_code - - # iterate over the headers to find all values in one go. Because - # get_wsgi_headers is used each response that gives us a tiny - # speedup. - for key, value in headers: - ikey = key.lower() - if ikey == "location": - location = value - elif ikey == "content-location": - content_location = value - elif ikey == "content-length": - content_length = value - - # make sure the location header is an absolute URL - if location is not None: - old_location = location - if isinstance(location, str): - # Safe conversion is necessary here as we might redirect - # to a broken URI scheme (for instance itms-services). - location = iri_to_uri(location, safe_conversion=True) - - if self.autocorrect_location_header: - current_url = get_current_url(environ, strip_querystring=True) - if isinstance(current_url, str): - current_url = iri_to_uri(current_url) - location = url_join(current_url, location) - if location != old_location: - headers["Location"] = location - - # make sure the content location is a URL - if content_location is not None and isinstance(content_location, str): - headers["Content-Location"] = iri_to_uri(content_location) - - if 100 <= status < 200 or status == 204: - # Per section 3.3.2 of RFC 7230, "a server MUST NOT send a - # Content-Length header field in any response with a status - # code of 1xx (Informational) or 204 (No Content)." - headers.remove("Content-Length") - elif status == 304: - remove_entity_headers(headers) - - # if we can determine the content length automatically, we - # should try to do that. But only if this does not involve - # flattening the iterator or encoding of strings in the - # response. We however should not do that if we have a 304 - # response. - if ( - self.automatically_set_content_length - and self.is_sequence - and content_length is None - and status not in (204, 304) - and not (100 <= status < 200) - ): - try: - content_length = sum(len(_to_bytes(x, "ascii")) for x in self.response) - except UnicodeError: - # Something other than bytes, can't safely figure out - # the length of the response. - pass - else: - headers["Content-Length"] = str(content_length) - - return headers - - def get_app_iter(self, environ: "WSGIEnvironment") -> t.Iterable[bytes]: - """Returns the application iterator for the given environ. Depending - on the request method and the current status code the return value - might be an empty response rather than the one from the response. - - If the request method is `HEAD` or the status code is in a range - where the HTTP specification requires an empty response, an empty - iterable is returned. - - .. versionadded:: 0.6 - - :param environ: the WSGI environment of the request. - :return: a response iterable. - """ - status = self.status_code - if ( - environ["REQUEST_METHOD"] == "HEAD" - or 100 <= status < 200 - or status in (204, 304) - ): - iterable: t.Iterable[bytes] = () - elif self.direct_passthrough: - if __debug__: - _warn_if_string(self.response) - return self.response # type: ignore - else: - iterable = self.iter_encoded() - return ClosingIterator(iterable, self.close) - - def get_wsgi_response( - self, environ: "WSGIEnvironment" - ) -> t.Tuple[t.Iterable[bytes], str, t.List[t.Tuple[str, str]]]: - """Returns the final WSGI response as tuple. The first item in - the tuple is the application iterator, the second the status and - the third the list of headers. The response returned is created - specially for the given environment. For example if the request - method in the WSGI environment is ``'HEAD'`` the response will - be empty and only the headers and status code will be present. - - .. versionadded:: 0.6 - - :param environ: the WSGI environment of the request. - :return: an ``(app_iter, status, headers)`` tuple. - """ - headers = self.get_wsgi_headers(environ) - app_iter = self.get_app_iter(environ) - return app_iter, self.status, headers.to_wsgi_list() - - def __call__( - self, environ: "WSGIEnvironment", start_response: "StartResponse" - ) -> t.Iterable[bytes]: - """Process this response as WSGI application. - - :param environ: the WSGI environment. - :param start_response: the response callable provided by the WSGI - server. - :return: an application iterator - """ - app_iter, status, headers = self.get_wsgi_response(environ) - start_response(status, headers) - return app_iter - - # JSON - - #: A module or other object that has ``dumps`` and ``loads`` - #: functions that match the API of the built-in :mod:`json` module. - json_module = json - - @property - def json(self) -> t.Optional[t.Any]: - """The parsed JSON data if :attr:`mimetype` indicates JSON - (:mimetype:`application/json`, see :attr:`is_json`). - - Calls :meth:`get_json` with default arguments. - """ - return self.get_json() - - def get_json(self, force: bool = False, silent: bool = False) -> t.Optional[t.Any]: - """Parse :attr:`data` as JSON. Useful during testing. - - If the mimetype does not indicate JSON - (:mimetype:`application/json`, see :attr:`is_json`), this - returns ``None``. - - Unlike :meth:`Request.get_json`, the result is not cached. - - :param force: Ignore the mimetype and always try to parse JSON. - :param silent: Silence parsing errors and return ``None`` - instead. - """ - if not (force or self.is_json): - return None - - data = self.get_data() - - try: - return self.json_module.loads(data) - except ValueError: - if not silent: - raise - - return None - - # Stream - - @cached_property - def stream(self) -> "ResponseStream": - """The response iterable as write-only stream.""" - return ResponseStream(self) - - def _wrap_range_response(self, start: int, length: int) -> None: - """Wrap existing Response in case of Range Request context.""" - if self.status_code == 206: - self.response = _RangeWrapper(self.response, start, length) # type: ignore - - def _is_range_request_processable(self, environ: "WSGIEnvironment") -> bool: - """Return ``True`` if `Range` header is present and if underlying - resource is considered unchanged when compared with `If-Range` header. - """ - return ( - "HTTP_IF_RANGE" not in environ - or not is_resource_modified( - environ, - self.headers.get("etag"), - None, - self.headers.get("last-modified"), - ignore_if_range=False, - ) - ) and "HTTP_RANGE" in environ - - def _process_range_request( - self, - environ: "WSGIEnvironment", - complete_length: t.Optional[int] = None, - accept_ranges: t.Optional[t.Union[bool, str]] = None, - ) -> bool: - """Handle Range Request related headers (RFC7233). If `Accept-Ranges` - header is valid, and Range Request is processable, we set the headers - as described by the RFC, and wrap the underlying response in a - RangeWrapper. - - Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise. - - :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` - if `Range` header could not be parsed or satisfied. - - .. versionchanged:: 2.0 - Returns ``False`` if the length is 0. - """ - from ..exceptions import RequestedRangeNotSatisfiable - - if ( - accept_ranges is None - or complete_length is None - or complete_length == 0 - or not self._is_range_request_processable(environ) - ): - return False - - parsed_range = parse_range_header(environ.get("HTTP_RANGE")) - - if parsed_range is None: - raise RequestedRangeNotSatisfiable(complete_length) - - range_tuple = parsed_range.range_for_length(complete_length) - content_range_header = parsed_range.to_content_range_header(complete_length) - - if range_tuple is None or content_range_header is None: - raise RequestedRangeNotSatisfiable(complete_length) - - content_length = range_tuple[1] - range_tuple[0] - self.headers["Content-Length"] = content_length - self.headers["Accept-Ranges"] = accept_ranges - self.content_range = content_range_header # type: ignore - self.status_code = 206 - self._wrap_range_response(range_tuple[0], content_length) - return True - - def make_conditional( - self, - request_or_environ: t.Union["WSGIEnvironment", "Request"], - accept_ranges: t.Union[bool, str] = False, - complete_length: t.Optional[int] = None, - ) -> "Response": - """Make the response conditional to the request. This method works - best if an etag was defined for the response already. The `add_etag` - method can be used to do that. If called without etag just the date - header is set. - - This does nothing if the request method in the request or environ is - anything but GET or HEAD. - - For optimal performance when handling range requests, it's recommended - that your response data object implements `seekable`, `seek` and `tell` - methods as described by :py:class:`io.IOBase`. Objects returned by - :meth:`~werkzeug.wsgi.wrap_file` automatically implement those methods. - - It does not remove the body of the response because that's something - the :meth:`__call__` function does for us automatically. - - Returns self so that you can do ``return resp.make_conditional(req)`` - but modifies the object in-place. - - :param request_or_environ: a request object or WSGI environment to be - used to make the response conditional - against. - :param accept_ranges: This parameter dictates the value of - `Accept-Ranges` header. If ``False`` (default), - the header is not set. If ``True``, it will be set - to ``"bytes"``. If ``None``, it will be set to - ``"none"``. If it's a string, it will use this - value. - :param complete_length: Will be used only in valid Range Requests. - It will set `Content-Range` complete length - value and compute `Content-Length` real value. - This parameter is mandatory for successful - Range Requests completion. - :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` - if `Range` header could not be parsed or satisfied. - - .. versionchanged:: 2.0 - Range processing is skipped if length is 0 instead of - raising a 416 Range Not Satisfiable error. - """ - environ = _get_environ(request_or_environ) - if environ["REQUEST_METHOD"] in ("GET", "HEAD"): - # if the date is not in the headers, add it now. We however - # will not override an already existing header. Unfortunately - # this header will be overriden by many WSGI servers including - # wsgiref. - if "date" not in self.headers: - self.headers["Date"] = http_date() - accept_ranges = _clean_accept_ranges(accept_ranges) - is206 = self._process_range_request(environ, complete_length, accept_ranges) - if not is206 and not is_resource_modified( - environ, - self.headers.get("etag"), - None, - self.headers.get("last-modified"), - ): - if parse_etags(environ.get("HTTP_IF_MATCH")): - self.status_code = 412 - else: - self.status_code = 304 - if ( - self.automatically_set_content_length - and "content-length" not in self.headers - ): - length = self.calculate_content_length() - if length is not None: - self.headers["Content-Length"] = length - return self - - def add_etag(self, overwrite: bool = False, weak: bool = False) -> None: - """Add an etag for the current response if there is none yet. - - .. versionchanged:: 2.0 - SHA-1 is used to generate the value. MD5 may not be - available in some environments. - """ - if overwrite or "etag" not in self.headers: - self.set_etag(generate_etag(self.get_data()), weak) - - -class ResponseStream: - """A file descriptor like object used by the :class:`ResponseStreamMixin` to - represent the body of the stream. It directly pushes into the response - iterable of the response object. - """ - - mode = "wb+" - - def __init__(self, response: Response): - self.response = response - self.closed = False - - def write(self, value: bytes) -> int: - if self.closed: - raise ValueError("I/O operation on closed file") - self.response._ensure_sequence(mutable=True) - self.response.response.append(value) # type: ignore - self.response.headers.pop("Content-Length", None) - return len(value) - - def writelines(self, seq: t.Iterable[bytes]) -> None: - for item in seq: - self.write(item) - - def close(self) -> None: - self.closed = True - - def flush(self) -> None: - if self.closed: - raise ValueError("I/O operation on closed file") - - def isatty(self) -> bool: - if self.closed: - raise ValueError("I/O operation on closed file") - return False - - def tell(self) -> int: - self.response._ensure_sequence() - return sum(map(len, self.response.response)) - - @property - def encoding(self) -> str: - return self.response.charset - - -class ResponseStreamMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'ResponseStreamMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Response' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py deleted file mode 100644 index e69ab05..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py +++ /dev/null @@ -1,14 +0,0 @@ -import typing as t -import warnings - - -class UserAgentMixin: - def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: - warnings.warn( - "'UserAgentMixin' is deprecated and will be removed in" - " Werkzeug 2.1. 'Request' now includes the functionality" - " directly.", - DeprecationWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wsgi.py b/venv/lib/python3.7/site-packages/werkzeug/wsgi.py deleted file mode 100644 index 9cfa74d..0000000 --- a/venv/lib/python3.7/site-packages/werkzeug/wsgi.py +++ /dev/null @@ -1,982 +0,0 @@ -import io -import re -import typing as t -from functools import partial -from functools import update_wrapper -from itertools import chain - -from ._internal import _make_encode_wrapper -from ._internal import _to_bytes -from ._internal import _to_str -from .sansio import utils as _sansio_utils -from .sansio.utils import host_is_trusted # noqa: F401 # Imported as part of API -from .urls import _URLTuple -from .urls import uri_to_iri -from .urls import url_join -from .urls import url_parse -from .urls import url_quote - -if t.TYPE_CHECKING: - from _typeshed.wsgi import WSGIApplication - from _typeshed.wsgi import WSGIEnvironment - - -def responder(f: t.Callable[..., "WSGIApplication"]) -> "WSGIApplication": - """Marks a function as responder. Decorate a function with it and it - will automatically call the return value as WSGI application. - - Example:: - - @responder - def application(environ, start_response): - return Response('Hello World!') - """ - return update_wrapper(lambda *a: f(*a)(*a[-2:]), f) - - -def get_current_url( - environ: "WSGIEnvironment", - root_only: bool = False, - strip_querystring: bool = False, - host_only: bool = False, - trusted_hosts: t.Optional[t.Iterable[str]] = None, -) -> str: - """Recreate the URL for a request from the parts in a WSGI - environment. - - The URL is an IRI, not a URI, so it may contain Unicode characters. - Use :func:`~werkzeug.urls.iri_to_uri` to convert it to ASCII. - - :param environ: The WSGI environment to get the URL parts from. - :param root_only: Only build the root path, don't include the - remaining path or query string. - :param strip_querystring: Don't include the query string. - :param host_only: Only build the scheme and host. - :param trusted_hosts: A list of trusted host names to validate the - host against. - """ - parts = { - "scheme": environ["wsgi.url_scheme"], - "host": get_host(environ, trusted_hosts), - } - - if not host_only: - parts["root_path"] = environ.get("SCRIPT_NAME", "") - - if not root_only: - parts["path"] = environ.get("PATH_INFO", "") - - if not strip_querystring: - parts["query_string"] = environ.get("QUERY_STRING", "").encode("latin1") - - return _sansio_utils.get_current_url(**parts) - - -def _get_server( - environ: "WSGIEnvironment", -) -> t.Optional[t.Tuple[str, t.Optional[int]]]: - name = environ.get("SERVER_NAME") - - if name is None: - return None - - try: - port: t.Optional[int] = int(environ.get("SERVER_PORT", None)) - except (TypeError, ValueError): - # unix socket - port = None - - return name, port - - -def get_host( - environ: "WSGIEnvironment", trusted_hosts: t.Optional[t.Iterable[str]] = None -) -> str: - """Return the host for the given WSGI environment. - - The ``Host`` header is preferred, then ``SERVER_NAME`` if it's not - set. The returned host will only contain the port if it is different - than the standard port for the protocol. - - Optionally, verify that the host is trusted using - :func:`host_is_trusted` and raise a - :exc:`~werkzeug.exceptions.SecurityError` if it is not. - - :param environ: A WSGI environment dict. - :param trusted_hosts: A list of trusted host names. - - :return: Host, with port if necessary. - :raise ~werkzeug.exceptions.SecurityError: If the host is not - trusted. - """ - return _sansio_utils.get_host( - environ["wsgi.url_scheme"], - environ.get("HTTP_HOST"), - _get_server(environ), - trusted_hosts, - ) - - -def get_content_length(environ: "WSGIEnvironment") -> t.Optional[int]: - """Returns the content length from the WSGI environment as - integer. If it's not available or chunked transfer encoding is used, - ``None`` is returned. - - .. versionadded:: 0.9 - - :param environ: the WSGI environ to fetch the content length from. - """ - if environ.get("HTTP_TRANSFER_ENCODING", "") == "chunked": - return None - - content_length = environ.get("CONTENT_LENGTH") - if content_length is not None: - try: - return max(0, int(content_length)) - except (ValueError, TypeError): - pass - return None - - -def get_input_stream( - environ: "WSGIEnvironment", safe_fallback: bool = True -) -> t.IO[bytes]: - """Returns the input stream from the WSGI environment and wraps it - in the most sensible way possible. The stream returned is not the - raw WSGI stream in most cases but one that is safe to read from - without taking into account the content length. - - If content length is not set, the stream will be empty for safety reasons. - If the WSGI server supports chunked or infinite streams, it should set - the ``wsgi.input_terminated`` value in the WSGI environ to indicate that. - - .. versionadded:: 0.9 - - :param environ: the WSGI environ to fetch the stream from. - :param safe_fallback: use an empty stream as a safe fallback when the - content length is not set. Disabling this allows infinite streams, - which can be a denial-of-service risk. - """ - stream = t.cast(t.IO[bytes], environ["wsgi.input"]) - content_length = get_content_length(environ) - - # A wsgi extension that tells us if the input is terminated. In - # that case we return the stream unchanged as we know we can safely - # read it until the end. - if environ.get("wsgi.input_terminated"): - return stream - - # If the request doesn't specify a content length, returning the stream is - # potentially dangerous because it could be infinite, malicious or not. If - # safe_fallback is true, return an empty stream instead for safety. - if content_length is None: - return io.BytesIO() if safe_fallback else stream - - # Otherwise limit the stream to the content length - return t.cast(t.IO[bytes], LimitedStream(stream, content_length)) - - -def get_query_string(environ: "WSGIEnvironment") -> str: - """Returns the ``QUERY_STRING`` from the WSGI environment. This also - takes care of the WSGI decoding dance. The string returned will be - restricted to ASCII characters. - - :param environ: WSGI environment to get the query string from. - - .. versionadded:: 0.9 - """ - qs = environ.get("QUERY_STRING", "").encode("latin1") - # QUERY_STRING really should be ascii safe but some browsers - # will send us some unicode stuff (I am looking at you IE). - # In that case we want to urllib quote it badly. - return url_quote(qs, safe=":&%=+$!*'(),") - - -def get_path_info( - environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" -) -> str: - """Return the ``PATH_INFO`` from the WSGI environment and decode it - unless ``charset`` is ``None``. - - :param environ: WSGI environment to get the path from. - :param charset: The charset for the path info, or ``None`` if no - decoding should be performed. - :param errors: The decoding error handling. - - .. versionadded:: 0.9 - """ - path = environ.get("PATH_INFO", "").encode("latin1") - return _to_str(path, charset, errors, allow_none_charset=True) # type: ignore - - -def get_script_name( - environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" -) -> str: - """Return the ``SCRIPT_NAME`` from the WSGI environment and decode - it unless `charset` is set to ``None``. - - :param environ: WSGI environment to get the path from. - :param charset: The charset for the path, or ``None`` if no decoding - should be performed. - :param errors: The decoding error handling. - - .. versionadded:: 0.9 - """ - path = environ.get("SCRIPT_NAME", "").encode("latin1") - return _to_str(path, charset, errors, allow_none_charset=True) # type: ignore - - -def pop_path_info( - environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" -) -> t.Optional[str]: - """Removes and returns the next segment of `PATH_INFO`, pushing it onto - `SCRIPT_NAME`. Returns `None` if there is nothing left on `PATH_INFO`. - - If the `charset` is set to `None` bytes are returned. - - If there are empty segments (``'/foo//bar``) these are ignored but - properly pushed to the `SCRIPT_NAME`: - - >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} - >>> pop_path_info(env) - 'a' - >>> env['SCRIPT_NAME'] - '/foo/a' - >>> pop_path_info(env) - 'b' - >>> env['SCRIPT_NAME'] - '/foo/a/b' - - .. versionadded:: 0.5 - - .. versionchanged:: 0.9 - The path is now decoded and a charset and encoding - parameter can be provided. - - :param environ: the WSGI environment that is modified. - :param charset: The ``encoding`` parameter passed to - :func:`bytes.decode`. - :param errors: The ``errors`` paramater passed to - :func:`bytes.decode`. - """ - path = environ.get("PATH_INFO") - if not path: - return None - - script_name = environ.get("SCRIPT_NAME", "") - - # shift multiple leading slashes over - old_path = path - path = path.lstrip("/") - if path != old_path: - script_name += "/" * (len(old_path) - len(path)) - - if "/" not in path: - environ["PATH_INFO"] = "" - environ["SCRIPT_NAME"] = script_name + path - rv = path.encode("latin1") - else: - segment, path = path.split("/", 1) - environ["PATH_INFO"] = f"/{path}" - environ["SCRIPT_NAME"] = script_name + segment - rv = segment.encode("latin1") - - return _to_str(rv, charset, errors, allow_none_charset=True) # type: ignore - - -def peek_path_info( - environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" -) -> t.Optional[str]: - """Returns the next segment on the `PATH_INFO` or `None` if there - is none. Works like :func:`pop_path_info` without modifying the - environment: - - >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} - >>> peek_path_info(env) - 'a' - >>> peek_path_info(env) - 'a' - - If the `charset` is set to `None` bytes are returned. - - .. versionadded:: 0.5 - - .. versionchanged:: 0.9 - The path is now decoded and a charset and encoding - parameter can be provided. - - :param environ: the WSGI environment that is checked. - """ - segments = environ.get("PATH_INFO", "").lstrip("/").split("/", 1) - if segments: - return _to_str( # type: ignore - segments[0].encode("latin1"), charset, errors, allow_none_charset=True - ) - return None - - -def extract_path_info( - environ_or_baseurl: t.Union[str, "WSGIEnvironment"], - path_or_url: t.Union[str, _URLTuple], - charset: str = "utf-8", - errors: str = "werkzeug.url_quote", - collapse_http_schemes: bool = True, -) -> t.Optional[str]: - """Extracts the path info from the given URL (or WSGI environment) and - path. The path info returned is a string. The URLs might also be IRIs. - - If the path info could not be determined, `None` is returned. - - Some examples: - - >>> extract_path_info('http://example.com/app', '/app/hello') - '/hello' - >>> extract_path_info('http://example.com/app', - ... 'https://example.com/app/hello') - '/hello' - >>> extract_path_info('http://example.com/app', - ... 'https://example.com/app/hello', - ... collapse_http_schemes=False) is None - True - - Instead of providing a base URL you can also pass a WSGI environment. - - :param environ_or_baseurl: a WSGI environment dict, a base URL or - base IRI. This is the root of the - application. - :param path_or_url: an absolute path from the server root, a - relative path (in which case it's the path info) - or a full URL. - :param charset: the charset for byte data in URLs - :param errors: the error handling on decode - :param collapse_http_schemes: if set to `False` the algorithm does - not assume that http and https on the - same server point to the same - resource. - - .. versionchanged:: 0.15 - The ``errors`` parameter defaults to leaving invalid bytes - quoted instead of replacing them. - - .. versionadded:: 0.6 - """ - - def _normalize_netloc(scheme: str, netloc: str) -> str: - parts = netloc.split("@", 1)[-1].split(":", 1) - port: t.Optional[str] - - if len(parts) == 2: - netloc, port = parts - if (scheme == "http" and port == "80") or ( - scheme == "https" and port == "443" - ): - port = None - else: - netloc = parts[0] - port = None - - if port is not None: - netloc += f":{port}" - - return netloc - - # make sure whatever we are working on is a IRI and parse it - path = uri_to_iri(path_or_url, charset, errors) - if isinstance(environ_or_baseurl, dict): - environ_or_baseurl = get_current_url(environ_or_baseurl, root_only=True) - base_iri = uri_to_iri(environ_or_baseurl, charset, errors) - base_scheme, base_netloc, base_path = url_parse(base_iri)[:3] - cur_scheme, cur_netloc, cur_path = url_parse(url_join(base_iri, path))[:3] - - # normalize the network location - base_netloc = _normalize_netloc(base_scheme, base_netloc) - cur_netloc = _normalize_netloc(cur_scheme, cur_netloc) - - # is that IRI even on a known HTTP scheme? - if collapse_http_schemes: - for scheme in base_scheme, cur_scheme: - if scheme not in ("http", "https"): - return None - else: - if not (base_scheme in ("http", "https") and base_scheme == cur_scheme): - return None - - # are the netlocs compatible? - if base_netloc != cur_netloc: - return None - - # are we below the application path? - base_path = base_path.rstrip("/") - if not cur_path.startswith(base_path): - return None - - return f"/{cur_path[len(base_path) :].lstrip('/')}" - - -class ClosingIterator: - """The WSGI specification requires that all middlewares and gateways - respect the `close` callback of the iterable returned by the application. - Because it is useful to add another close action to a returned iterable - and adding a custom iterable is a boring task this class can be used for - that:: - - return ClosingIterator(app(environ, start_response), [cleanup_session, - cleanup_locals]) - - If there is just one close function it can be passed instead of the list. - - A closing iterator is not needed if the application uses response objects - and finishes the processing if the response is started:: - - try: - return response(environ, start_response) - finally: - cleanup_session() - cleanup_locals() - """ - - def __init__( - self, - iterable: t.Iterable[bytes], - callbacks: t.Optional[ - t.Union[t.Callable[[], None], t.Iterable[t.Callable[[], None]]] - ] = None, - ) -> None: - iterator = iter(iterable) - self._next = t.cast(t.Callable[[], bytes], partial(next, iterator)) - if callbacks is None: - callbacks = [] - elif callable(callbacks): - callbacks = [callbacks] - else: - callbacks = list(callbacks) - iterable_close = getattr(iterable, "close", None) - if iterable_close: - callbacks.insert(0, iterable_close) - self._callbacks = callbacks - - def __iter__(self) -> "ClosingIterator": - return self - - def __next__(self) -> bytes: - return self._next() - - def close(self) -> None: - for callback in self._callbacks: - callback() - - -def wrap_file( - environ: "WSGIEnvironment", file: t.IO[bytes], buffer_size: int = 8192 -) -> t.Iterable[bytes]: - """Wraps a file. This uses the WSGI server's file wrapper if available - or otherwise the generic :class:`FileWrapper`. - - .. versionadded:: 0.5 - - If the file wrapper from the WSGI server is used it's important to not - iterate over it from inside the application but to pass it through - unchanged. If you want to pass out a file wrapper inside a response - object you have to set :attr:`Response.direct_passthrough` to `True`. - - More information about file wrappers are available in :pep:`333`. - - :param file: a :class:`file`-like object with a :meth:`~file.read` method. - :param buffer_size: number of bytes for one iteration. - """ - return environ.get("wsgi.file_wrapper", FileWrapper)( # type: ignore - file, buffer_size - ) - - -class FileWrapper: - """This class can be used to convert a :class:`file`-like object into - an iterable. It yields `buffer_size` blocks until the file is fully - read. - - You should not use this class directly but rather use the - :func:`wrap_file` function that uses the WSGI server's file wrapper - support if it's available. - - .. versionadded:: 0.5 - - If you're using this object together with a :class:`Response` you have - to use the `direct_passthrough` mode. - - :param file: a :class:`file`-like object with a :meth:`~file.read` method. - :param buffer_size: number of bytes for one iteration. - """ - - def __init__(self, file: t.IO[bytes], buffer_size: int = 8192) -> None: - self.file = file - self.buffer_size = buffer_size - - def close(self) -> None: - if hasattr(self.file, "close"): - self.file.close() - - def seekable(self) -> bool: - if hasattr(self.file, "seekable"): - return self.file.seekable() - if hasattr(self.file, "seek"): - return True - return False - - def seek(self, *args: t.Any) -> None: - if hasattr(self.file, "seek"): - self.file.seek(*args) - - def tell(self) -> t.Optional[int]: - if hasattr(self.file, "tell"): - return self.file.tell() - return None - - def __iter__(self) -> "FileWrapper": - return self - - def __next__(self) -> bytes: - data = self.file.read(self.buffer_size) - if data: - return data - raise StopIteration() - - -class _RangeWrapper: - # private for now, but should we make it public in the future ? - - """This class can be used to convert an iterable object into - an iterable that will only yield a piece of the underlying content. - It yields blocks until the underlying stream range is fully read. - The yielded blocks will have a size that can't exceed the original - iterator defined block size, but that can be smaller. - - If you're using this object together with a :class:`Response` you have - to use the `direct_passthrough` mode. - - :param iterable: an iterable object with a :meth:`__next__` method. - :param start_byte: byte from which read will start. - :param byte_range: how many bytes to read. - """ - - def __init__( - self, - iterable: t.Union[t.Iterable[bytes], t.IO[bytes]], - start_byte: int = 0, - byte_range: t.Optional[int] = None, - ): - self.iterable = iter(iterable) - self.byte_range = byte_range - self.start_byte = start_byte - self.end_byte = None - - if byte_range is not None: - self.end_byte = start_byte + byte_range - - self.read_length = 0 - self.seekable = ( - hasattr(iterable, "seekable") and iterable.seekable() # type: ignore - ) - self.end_reached = False - - def __iter__(self) -> "_RangeWrapper": - return self - - def _next_chunk(self) -> bytes: - try: - chunk = next(self.iterable) - self.read_length += len(chunk) - return chunk - except StopIteration: - self.end_reached = True - raise - - def _first_iteration(self) -> t.Tuple[t.Optional[bytes], int]: - chunk = None - if self.seekable: - self.iterable.seek(self.start_byte) # type: ignore - self.read_length = self.iterable.tell() # type: ignore - contextual_read_length = self.read_length - else: - while self.read_length <= self.start_byte: - chunk = self._next_chunk() - if chunk is not None: - chunk = chunk[self.start_byte - self.read_length :] - contextual_read_length = self.start_byte - return chunk, contextual_read_length - - def _next(self) -> bytes: - if self.end_reached: - raise StopIteration() - chunk = None - contextual_read_length = self.read_length - if self.read_length == 0: - chunk, contextual_read_length = self._first_iteration() - if chunk is None: - chunk = self._next_chunk() - if self.end_byte is not None and self.read_length >= self.end_byte: - self.end_reached = True - return chunk[: self.end_byte - contextual_read_length] - return chunk - - def __next__(self) -> bytes: - chunk = self._next() - if chunk: - return chunk - self.end_reached = True - raise StopIteration() - - def close(self) -> None: - if hasattr(self.iterable, "close"): - self.iterable.close() # type: ignore - - -def _make_chunk_iter( - stream: t.Union[t.Iterable[bytes], t.IO[bytes]], - limit: t.Optional[int], - buffer_size: int, -) -> t.Iterator[bytes]: - """Helper for the line and chunk iter functions.""" - if isinstance(stream, (bytes, bytearray, str)): - raise TypeError( - "Passed a string or byte object instead of true iterator or stream." - ) - if not hasattr(stream, "read"): - for item in stream: - if item: - yield item - return - stream = t.cast(t.IO[bytes], stream) - if not isinstance(stream, LimitedStream) and limit is not None: - stream = t.cast(t.IO[bytes], LimitedStream(stream, limit)) - _read = stream.read - while True: - item = _read(buffer_size) - if not item: - break - yield item - - -def make_line_iter( - stream: t.Union[t.Iterable[bytes], t.IO[bytes]], - limit: t.Optional[int] = None, - buffer_size: int = 10 * 1024, - cap_at_buffer: bool = False, -) -> t.Iterator[bytes]: - """Safely iterates line-based over an input stream. If the input stream - is not a :class:`LimitedStream` the `limit` parameter is mandatory. - - This uses the stream's :meth:`~file.read` method internally as opposite - to the :meth:`~file.readline` method that is unsafe and can only be used - in violation of the WSGI specification. The same problem applies to the - `__iter__` function of the input stream which calls :meth:`~file.readline` - without arguments. - - If you need line-by-line processing it's strongly recommended to iterate - over the input stream using this helper function. - - .. versionchanged:: 0.8 - This function now ensures that the limit was reached. - - .. versionadded:: 0.9 - added support for iterators as input stream. - - .. versionadded:: 0.11.10 - added support for the `cap_at_buffer` parameter. - - :param stream: the stream or iterate to iterate over. - :param limit: the limit in bytes for the stream. (Usually - content length. Not necessary if the `stream` - is a :class:`LimitedStream`. - :param buffer_size: The optional buffer size. - :param cap_at_buffer: if this is set chunks are split if they are longer - than the buffer size. Internally this is implemented - that the buffer size might be exhausted by a factor - of two however. - """ - _iter = _make_chunk_iter(stream, limit, buffer_size) - - first_item = next(_iter, "") - if not first_item: - return - - s = _make_encode_wrapper(first_item) - empty = t.cast(bytes, s("")) - cr = t.cast(bytes, s("\r")) - lf = t.cast(bytes, s("\n")) - crlf = t.cast(bytes, s("\r\n")) - - _iter = t.cast(t.Iterator[bytes], chain((first_item,), _iter)) - - def _iter_basic_lines() -> t.Iterator[bytes]: - _join = empty.join - buffer: t.List[bytes] = [] - while True: - new_data = next(_iter, "") - if not new_data: - break - new_buf: t.List[bytes] = [] - buf_size = 0 - for item in t.cast( - t.Iterator[bytes], chain(buffer, new_data.splitlines(True)) - ): - new_buf.append(item) - buf_size += len(item) - if item and item[-1:] in crlf: - yield _join(new_buf) - new_buf = [] - elif cap_at_buffer and buf_size >= buffer_size: - rv = _join(new_buf) - while len(rv) >= buffer_size: - yield rv[:buffer_size] - rv = rv[buffer_size:] - new_buf = [rv] - buffer = new_buf - if buffer: - yield _join(buffer) - - # This hackery is necessary to merge 'foo\r' and '\n' into one item - # of 'foo\r\n' if we were unlucky and we hit a chunk boundary. - previous = empty - for item in _iter_basic_lines(): - if item == lf and previous[-1:] == cr: - previous += item - item = empty - if previous: - yield previous - previous = item - if previous: - yield previous - - -def make_chunk_iter( - stream: t.Union[t.Iterable[bytes], t.IO[bytes]], - separator: bytes, - limit: t.Optional[int] = None, - buffer_size: int = 10 * 1024, - cap_at_buffer: bool = False, -) -> t.Iterator[bytes]: - """Works like :func:`make_line_iter` but accepts a separator - which divides chunks. If you want newline based processing - you should use :func:`make_line_iter` instead as it - supports arbitrary newline markers. - - .. versionadded:: 0.8 - - .. versionadded:: 0.9 - added support for iterators as input stream. - - .. versionadded:: 0.11.10 - added support for the `cap_at_buffer` parameter. - - :param stream: the stream or iterate to iterate over. - :param separator: the separator that divides chunks. - :param limit: the limit in bytes for the stream. (Usually - content length. Not necessary if the `stream` - is otherwise already limited). - :param buffer_size: The optional buffer size. - :param cap_at_buffer: if this is set chunks are split if they are longer - than the buffer size. Internally this is implemented - that the buffer size might be exhausted by a factor - of two however. - """ - _iter = _make_chunk_iter(stream, limit, buffer_size) - - first_item = next(_iter, b"") - if not first_item: - return - - _iter = t.cast(t.Iterator[bytes], chain((first_item,), _iter)) - if isinstance(first_item, str): - separator = _to_str(separator) - _split = re.compile(f"({re.escape(separator)})").split - _join = "".join - else: - separator = _to_bytes(separator) - _split = re.compile(b"(" + re.escape(separator) + b")").split - _join = b"".join - - buffer: t.List[bytes] = [] - while True: - new_data = next(_iter, b"") - if not new_data: - break - chunks = _split(new_data) - new_buf: t.List[bytes] = [] - buf_size = 0 - for item in chain(buffer, chunks): - if item == separator: - yield _join(new_buf) - new_buf = [] - buf_size = 0 - else: - buf_size += len(item) - new_buf.append(item) - - if cap_at_buffer and buf_size >= buffer_size: - rv = _join(new_buf) - while len(rv) >= buffer_size: - yield rv[:buffer_size] - rv = rv[buffer_size:] - new_buf = [rv] - buf_size = len(rv) - - buffer = new_buf - if buffer: - yield _join(buffer) - - -class LimitedStream(io.IOBase): - """Wraps a stream so that it doesn't read more than n bytes. If the - stream is exhausted and the caller tries to get more bytes from it - :func:`on_exhausted` is called which by default returns an empty - string. The return value of that function is forwarded - to the reader function. So if it returns an empty string - :meth:`read` will return an empty string as well. - - The limit however must never be higher than what the stream can - output. Otherwise :meth:`readlines` will try to read past the - limit. - - .. admonition:: Note on WSGI compliance - - calls to :meth:`readline` and :meth:`readlines` are not - WSGI compliant because it passes a size argument to the - readline methods. Unfortunately the WSGI PEP is not safely - implementable without a size argument to :meth:`readline` - because there is no EOF marker in the stream. As a result - of that the use of :meth:`readline` is discouraged. - - For the same reason iterating over the :class:`LimitedStream` - is not portable. It internally calls :meth:`readline`. - - We strongly suggest using :meth:`read` only or using the - :func:`make_line_iter` which safely iterates line-based - over a WSGI input stream. - - :param stream: the stream to wrap. - :param limit: the limit for the stream, must not be longer than - what the string can provide if the stream does not - end with `EOF` (like `wsgi.input`) - """ - - def __init__(self, stream: t.IO[bytes], limit: int) -> None: - self._read = stream.read - self._readline = stream.readline - self._pos = 0 - self.limit = limit - - def __iter__(self) -> "LimitedStream": - return self - - @property - def is_exhausted(self) -> bool: - """If the stream is exhausted this attribute is `True`.""" - return self._pos >= self.limit - - def on_exhausted(self) -> bytes: - """This is called when the stream tries to read past the limit. - The return value of this function is returned from the reading - function. - """ - # Read null bytes from the stream so that we get the - # correct end of stream marker. - return self._read(0) - - def on_disconnect(self) -> bytes: - """What should happen if a disconnect is detected? The return - value of this function is returned from read functions in case - the client went away. By default a - :exc:`~werkzeug.exceptions.ClientDisconnected` exception is raised. - """ - from .exceptions import ClientDisconnected - - raise ClientDisconnected() - - def exhaust(self, chunk_size: int = 1024 * 64) -> None: - """Exhaust the stream. This consumes all the data left until the - limit is reached. - - :param chunk_size: the size for a chunk. It will read the chunk - until the stream is exhausted and throw away - the results. - """ - to_read = self.limit - self._pos - chunk = chunk_size - while to_read > 0: - chunk = min(to_read, chunk) - self.read(chunk) - to_read -= chunk - - def read(self, size: t.Optional[int] = None) -> bytes: - """Read `size` bytes or if size is not provided everything is read. - - :param size: the number of bytes read. - """ - if self._pos >= self.limit: - return self.on_exhausted() - if size is None or size == -1: # -1 is for consistence with file - size = self.limit - to_read = min(self.limit - self._pos, size) - try: - read = self._read(to_read) - except (OSError, ValueError): - return self.on_disconnect() - if to_read and len(read) != to_read: - return self.on_disconnect() - self._pos += len(read) - return read - - def readline(self, size: t.Optional[int] = None) -> bytes: - """Reads one line from the stream.""" - if self._pos >= self.limit: - return self.on_exhausted() - if size is None: - size = self.limit - self._pos - else: - size = min(size, self.limit - self._pos) - try: - line = self._readline(size) - except (ValueError, OSError): - return self.on_disconnect() - if size and not line: - return self.on_disconnect() - self._pos += len(line) - return line - - def readlines(self, size: t.Optional[int] = None) -> t.List[bytes]: - """Reads a file into a list of strings. It calls :meth:`readline` - until the file is read to the end. It does support the optional - `size` argument if the underlying stream supports it for - `readline`. - """ - last_pos = self._pos - result = [] - if size is not None: - end = min(self.limit, last_pos + size) - else: - end = self.limit - while True: - if size is not None: - size -= last_pos - self._pos - if self._pos >= end: - break - result.append(self.readline(size)) - if size is not None: - last_pos = self._pos - return result - - def tell(self) -> int: - """Returns the position of the stream. - - .. versionadded:: 0.9 - """ - return self._pos - - def __next__(self) -> bytes: - line = self.readline() - if not line: - raise StopIteration() - return line - - def readable(self) -> bool: - return True diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/LICENSE b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/LICENSE deleted file mode 100644 index 353924b..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright Jason R. Coombs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/METADATA b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/METADATA deleted file mode 100644 index b1308b5..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/METADATA +++ /dev/null @@ -1,58 +0,0 @@ -Metadata-Version: 2.1 -Name: zipp -Version: 3.7.0 -Summary: Backport of pathlib-compatible object wrapper for zip files -Home-page: https://github.com/jaraco/zipp -Author: Jason R. Coombs -Author-email: jaraco@jaraco.com -License: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Requires-Python: >=3.7 -License-File: LICENSE -Provides-Extra: docs -Requires-Dist: sphinx ; extra == 'docs' -Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs' -Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' -Provides-Extra: testing -Requires-Dist: pytest (>=6) ; extra == 'testing' -Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing' -Requires-Dist: pytest-flake8 ; extra == 'testing' -Requires-Dist: pytest-cov ; extra == 'testing' -Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing' -Requires-Dist: jaraco.itertools ; extra == 'testing' -Requires-Dist: func-timeout ; extra == 'testing' -Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' -Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing' - -.. image:: https://img.shields.io/pypi/v/zipp.svg - :target: `PyPI link`_ - -.. image:: https://img.shields.io/pypi/pyversions/zipp.svg - :target: `PyPI link`_ - -.. _PyPI link: https://pypi.org/project/zipp - -.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg - :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22 - :alt: tests - -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - :alt: Code style: Black - -.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest -.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest - -.. image:: https://img.shields.io/badge/skeleton-2021-informational - :target: https://blog.jaraco.com/skeleton - - -A pathlib-compatible Zipfile object wrapper. Official backport of the standard library -`Path object `_. - - diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/RECORD b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/RECORD deleted file mode 100644 index 6fda5e4..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/RECORD +++ /dev/null @@ -1,8 +0,0 @@ -__pycache__/zipp.cpython-37.pyc,, -zipp-3.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -zipp-3.7.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050 -zipp-3.7.0.dist-info/METADATA,sha256=ZLzgaXTyZX_MxTU0lcGfhdPY4CjFrT_3vyQ2Fo49pl8,2261 -zipp-3.7.0.dist-info/RECORD,, -zipp-3.7.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 -zipp-3.7.0.dist-info/top_level.txt,sha256=iAbdoSHfaGqBfVb2XuR9JqSQHCoOsOtG6y9C_LSpqFw,5 -zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425 diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/WHEEL b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/WHEEL deleted file mode 100644 index becc9a6..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/top_level.txt deleted file mode 100644 index e82f676..0000000 --- a/venv/lib/python3.7/site-packages/zipp-3.7.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -zipp diff --git a/venv/lib/python3.7/site-packages/zipp.py b/venv/lib/python3.7/site-packages/zipp.py deleted file mode 100644 index 26b723c..0000000 --- a/venv/lib/python3.7/site-packages/zipp.py +++ /dev/null @@ -1,329 +0,0 @@ -import io -import posixpath -import zipfile -import itertools -import contextlib -import sys -import pathlib - -if sys.version_info < (3, 7): - from collections import OrderedDict -else: - OrderedDict = dict - - -__all__ = ['Path'] - - -def _parents(path): - """ - Given a path with elements separated by - posixpath.sep, generate all parents of that path. - - >>> list(_parents('b/d')) - ['b'] - >>> list(_parents('/b/d/')) - ['/b'] - >>> list(_parents('b/d/f/')) - ['b/d', 'b'] - >>> list(_parents('b')) - [] - >>> list(_parents('')) - [] - """ - return itertools.islice(_ancestry(path), 1, None) - - -def _ancestry(path): - """ - Given a path with elements separated by - posixpath.sep, generate all elements of that path - - >>> list(_ancestry('b/d')) - ['b/d', 'b'] - >>> list(_ancestry('/b/d/')) - ['/b/d', '/b'] - >>> list(_ancestry('b/d/f/')) - ['b/d/f', 'b/d', 'b'] - >>> list(_ancestry('b')) - ['b'] - >>> list(_ancestry('')) - [] - """ - path = path.rstrip(posixpath.sep) - while path and path != posixpath.sep: - yield path - path, tail = posixpath.split(path) - - -_dedupe = OrderedDict.fromkeys -"""Deduplicate an iterable in original order""" - - -def _difference(minuend, subtrahend): - """ - Return items in minuend not in subtrahend, retaining order - with O(1) lookup. - """ - return itertools.filterfalse(set(subtrahend).__contains__, minuend) - - -class CompleteDirs(zipfile.ZipFile): - """ - A ZipFile subclass that ensures that implied directories - are always included in the namelist. - """ - - @staticmethod - def _implied_dirs(names): - parents = itertools.chain.from_iterable(map(_parents, names)) - as_dirs = (p + posixpath.sep for p in parents) - return _dedupe(_difference(as_dirs, names)) - - def namelist(self): - names = super(CompleteDirs, self).namelist() - return names + list(self._implied_dirs(names)) - - def _name_set(self): - return set(self.namelist()) - - def resolve_dir(self, name): - """ - If the name represents a directory, return that name - as a directory (with the trailing slash). - """ - names = self._name_set() - dirname = name + '/' - dir_match = name not in names and dirname in names - return dirname if dir_match else name - - @classmethod - def make(cls, source): - """ - Given a source (filename or zipfile), return an - appropriate CompleteDirs subclass. - """ - if isinstance(source, CompleteDirs): - return source - - if not isinstance(source, zipfile.ZipFile): - return cls(_pathlib_compat(source)) - - # Only allow for FastLookup when supplied zipfile is read-only - if 'r' not in source.mode: - cls = CompleteDirs - - source.__class__ = cls - return source - - -class FastLookup(CompleteDirs): - """ - ZipFile subclass to ensure implicit - dirs exist and are resolved rapidly. - """ - - def namelist(self): - with contextlib.suppress(AttributeError): - return self.__names - self.__names = super(FastLookup, self).namelist() - return self.__names - - def _name_set(self): - with contextlib.suppress(AttributeError): - return self.__lookup - self.__lookup = super(FastLookup, self)._name_set() - return self.__lookup - - -def _pathlib_compat(path): - """ - For path-like objects, convert to a filename for compatibility - on Python 3.6.1 and earlier. - """ - try: - return path.__fspath__() - except AttributeError: - return str(path) - - -class Path: - """ - A pathlib-compatible interface for zip files. - - Consider a zip file with this structure:: - - . - ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt - - >>> data = io.BytesIO() - >>> zf = zipfile.ZipFile(data, 'w') - >>> zf.writestr('a.txt', 'content of a') - >>> zf.writestr('b/c.txt', 'content of c') - >>> zf.writestr('b/d/e.txt', 'content of e') - >>> zf.filename = 'mem/abcde.zip' - - Path accepts the zipfile object itself or a filename - - >>> root = Path(zf) - - From there, several path operations are available. - - Directory iteration (including the zip file itself): - - >>> a, b = root.iterdir() - >>> a - Path('mem/abcde.zip', 'a.txt') - >>> b - Path('mem/abcde.zip', 'b/') - - name property: - - >>> b.name - 'b' - - join with divide operator: - - >>> c = b / 'c.txt' - >>> c - Path('mem/abcde.zip', 'b/c.txt') - >>> c.name - 'c.txt' - - Read text: - - >>> c.read_text() - 'content of c' - - existence: - - >>> c.exists() - True - >>> (b / 'missing.txt').exists() - False - - Coercion to string: - - >>> import os - >>> str(c).replace(os.sep, posixpath.sep) - 'mem/abcde.zip/b/c.txt' - - At the root, ``name``, ``filename``, and ``parent`` - resolve to the zipfile. Note these attributes are not - valid and will raise a ``ValueError`` if the zipfile - has no filename. - - >>> root.name - 'abcde.zip' - >>> str(root.filename).replace(os.sep, posixpath.sep) - 'mem/abcde.zip' - >>> str(root.parent) - 'mem' - """ - - __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" - - def __init__(self, root, at=""): - """ - Construct a Path from a ZipFile or filename. - - Note: When the source is an existing ZipFile object, - its type (__class__) will be mutated to a - specialized type. If the caller wishes to retain the - original type, the caller should either create a - separate ZipFile object or pass a filename. - """ - self.root = FastLookup.make(root) - self.at = at - - def open(self, mode='r', *args, pwd=None, **kwargs): - """ - Open this entry as text or binary following the semantics - of ``pathlib.Path.open()`` by passing arguments through - to io.TextIOWrapper(). - """ - if self.is_dir(): - raise IsADirectoryError(self) - zip_mode = mode[0] - if not self.exists() and zip_mode == 'r': - raise FileNotFoundError(self) - stream = self.root.open(self.at, zip_mode, pwd=pwd) - if 'b' in mode: - if args or kwargs: - raise ValueError("encoding args invalid for binary operation") - return stream - return io.TextIOWrapper(stream, *args, **kwargs) - - @property - def name(self): - return pathlib.Path(self.at).name or self.filename.name - - @property - def suffix(self): - return pathlib.Path(self.at).suffix or self.filename.suffix - - @property - def suffixes(self): - return pathlib.Path(self.at).suffixes or self.filename.suffixes - - @property - def stem(self): - return pathlib.Path(self.at).stem or self.filename.stem - - @property - def filename(self): - return pathlib.Path(self.root.filename).joinpath(self.at) - - def read_text(self, *args, **kwargs): - with self.open('r', *args, **kwargs) as strm: - return strm.read() - - def read_bytes(self): - with self.open('rb') as strm: - return strm.read() - - def _is_child(self, path): - return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") - - def _next(self, at): - return self.__class__(self.root, at) - - def is_dir(self): - return not self.at or self.at.endswith("/") - - def is_file(self): - return self.exists() and not self.is_dir() - - def exists(self): - return self.at in self.root._name_set() - - def iterdir(self): - if not self.is_dir(): - raise ValueError("Can't listdir a file") - subs = map(self._next, self.root.namelist()) - return filter(self._is_child, subs) - - def __str__(self): - return posixpath.join(self.root.filename, self.at) - - def __repr__(self): - return self.__repr.format(self=self) - - def joinpath(self, *other): - next = posixpath.join(self.at, *map(_pathlib_compat, other)) - return self._next(self.root.resolve_dir(next)) - - __truediv__ = joinpath - - @property - def parent(self): - if not self.at: - return self.filename.parent - parent_at = posixpath.dirname(self.at.rstrip('/')) - if parent_at: - parent_at += '/' - return self._next(parent_at) diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg deleted file mode 100644 index 1b78b7b..0000000 --- a/venv/pyvenv.cfg +++ /dev/null @@ -1,3 +0,0 @@ -home = /Users/bradleyl/hackathon/checkoutCreate/venv/bin -include-system-site-packages = false -version = 3.7.2 From 9b9a86fc4af915b447eea3ed4c61dc51df7d7e11 Mon Sep 17 00:00:00 2001 From: anamotaadyen Date: Fri, 4 Nov 2022 12:34:58 +0000 Subject: [PATCH 2/2] FLASK_ENV is deprecated - updating to FLASK_DEBUG --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index 234acb0..fd1405c 100755 --- a/start.sh +++ b/start.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -export FLASK_ENV=development +export FLASK_DEBUG=development python3 -m venv venv . venv/bin/activate python3 app/app.py