From 0ce099c0b1ec4d6ced87dffb6fbd679f67f9e8e7 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 8 Oct 2023 23:49:47 +0200 Subject: [PATCH] control --- main.go | 14 + modules/structs/robot.go | 6 + modules/utils/globals.go | 8 + public/swagger/favicon-16x16.png | Bin 0 -> 665 bytes public/swagger/favicon-32x32.png | Bin 0 -> 628 bytes public/swagger/index.css | 59 + public/swagger/index.html | 19 + public/swagger/oauth2-redirect.html | 79 + public/swagger/swagger-initializer.js | 11 + public/swagger/swagger-ui-bundle.js | 3 + public/swagger/swagger-ui-bundle.js.map | 1 + public/swagger/swagger-ui-es-bundle-core.js | 3 + .../swagger/swagger-ui-es-bundle-core.js.map | 1 + public/swagger/swagger-ui-es-bundle.js | 3 + public/swagger/swagger-ui-es-bundle.js.map | 1 + .../swagger/swagger-ui-standalone-preset.js | 3 + .../swagger-ui-standalone-preset.js.map | 1 + public/swagger/swagger-ui.css | 3 + public/swagger/swagger-ui.css.map | 1 + public/swagger/swagger-ui.js | 2 + public/swagger/swagger-ui.js.map | 1 + public/swagger/swagger.json | 81 + routers/api/v1/control/control.go | 14 + routers/api/v1/robot/robot.go | 52 + routers/api/v1/robots/robots.go | 18 - routers/router/router.go | 12 +- swagger-gen.sh | 4 + testclient/.venv/bin/Activate.ps1 | 241 + testclient/.venv/bin/activate | 66 + testclient/.venv/bin/activate.csh | 25 + testclient/.venv/bin/activate.fish | 64 + testclient/.venv/bin/easy_install | 8 + testclient/.venv/bin/easy_install-3.9 | 8 + testclient/.venv/bin/flask | 8 + testclient/.venv/bin/normalizer | 8 + testclient/.venv/bin/pip | 8 + testclient/.venv/bin/pip3 | 8 + testclient/.venv/bin/pip3.9 | 8 + testclient/.venv/bin/python | 1 + testclient/.venv/bin/python3 | 1 + testclient/.venv/bin/python3.9 | 1 + .../Jinja2-3.1.2.dist-info/INSTALLER | 1 + .../Jinja2-3.1.2.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.2.dist-info/METADATA | 113 + .../Jinja2-3.1.2.dist-info/RECORD | 58 + .../Jinja2-3.1.2.dist-info/WHEEL | 5 + .../Jinja2-3.1.2.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.2.dist-info/top_level.txt | 1 + .../MarkupSafe-2.1.3.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.3.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.3.dist-info/METADATA | 93 + .../MarkupSafe-2.1.3.dist-info/RECORD | 14 + .../MarkupSafe-2.1.3.dist-info/WHEEL | 6 + .../MarkupSafe-2.1.3.dist-info/top_level.txt | 1 + .../__pycache__/easy_install.cpython-39.pyc | Bin 0 -> 334 bytes .../blinker-1.6.3.dist-info/INSTALLER | 1 + .../blinker-1.6.3.dist-info/LICENSE.rst | 20 + .../blinker-1.6.3.dist-info/METADATA | 62 + .../blinker-1.6.3.dist-info/RECORD | 14 + .../blinker-1.6.3.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 19 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 519 bytes .../__pycache__/_saferef.cpython-39.pyc | Bin 0 -> 7197 bytes .../__pycache__/_utilities.cpython-39.pyc | Bin 0 -> 4211 bytes .../blinker/__pycache__/base.cpython-39.pyc | Bin 0 -> 17218 bytes .../site-packages/blinker/_saferef.py | 230 + .../site-packages/blinker/_utilities.py | 142 + .../python3.9/site-packages/blinker/base.py | 548 ++ .../python3.9/site-packages/blinker/py.typed | 0 .../certifi-2023.7.22.dist-info/INSTALLER | 1 + .../certifi-2023.7.22.dist-info/LICENSE | 21 + .../certifi-2023.7.22.dist-info/METADATA | 69 + .../certifi-2023.7.22.dist-info/RECORD | 14 + .../certifi-2023.7.22.dist-info/WHEEL | 5 + .../certifi-2023.7.22.dist-info/top_level.txt | 1 + .../site-packages/certifi/__init__.py | 4 + .../site-packages/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 309 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 445 bytes .../certifi/__pycache__/core.cpython-39.pyc | Bin 0 -> 1916 bytes .../site-packages/certifi/cacert.pem | 4635 +++++++++ .../python3.9/site-packages/certifi/core.py | 108 + .../python3.9/site-packages/certifi/py.typed | 0 .../INSTALLER | 1 + .../LICENSE | 21 + .../METADATA | 668 ++ .../charset_normalizer-3.3.0.dist-info/RECORD | 35 + .../charset_normalizer-3.3.0.dist-info/WHEEL | 6 + .../entry_points.txt | 2 + .../top_level.txt | 1 + .../charset_normalizer/__init__.py | 46 + .../charset_normalizer/__main__.py | 4 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1605 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 283 bytes .../__pycache__/api.cpython-39.pyc | Bin 0 -> 11446 bytes .../__pycache__/cd.cpython-39.pyc | Bin 0 -> 9678 bytes .../__pycache__/constant.cpython-39.pyc | Bin 0 -> 25281 bytes .../__pycache__/legacy.cpython-39.pyc | Bin 0 -> 1857 bytes .../__pycache__/md.cpython-39.pyc | Bin 0 -> 15432 bytes .../__pycache__/models.cpython-39.pyc | Bin 0 -> 11457 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 8712 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 291 bytes .../site-packages/charset_normalizer/api.py | 626 ++ .../site-packages/charset_normalizer/cd.py | 395 + .../charset_normalizer/cli/__init__.py | 6 + .../charset_normalizer/cli/__main__.py | 296 + .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 292 bytes .../cli/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 6508 bytes .../charset_normalizer/constant.py | 1995 ++++ .../charset_normalizer/legacy.py | 54 + .../md.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 16064 bytes .../site-packages/charset_normalizer/md.py | 581 ++ .../md__mypyc.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 257368 bytes .../charset_normalizer/models.py | 337 + .../site-packages/charset_normalizer/py.typed | 0 .../site-packages/charset_normalizer/utils.py | 399 + .../charset_normalizer/version.py | 6 + .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 39 + .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .../python3.9/site-packages/click/__init__.py | 73 + .../click/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2638 bytes .../click/__pycache__/_compat.cpython-39.pyc | Bin 0 -> 16013 bytes .../__pycache__/_termui_impl.cpython-39.pyc | Bin 0 -> 16258 bytes .../__pycache__/_textwrap.cpython-39.pyc | Bin 0 -> 1554 bytes .../__pycache__/_winconsole.cpython-39.pyc | Bin 0 -> 7805 bytes .../click/__pycache__/core.cpython-39.pyc | Bin 0 -> 90639 bytes .../__pycache__/decorators.cpython-39.pyc | Bin 0 -> 17060 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 10217 bytes .../__pycache__/formatting.cpython-39.pyc | Bin 0 -> 9433 bytes .../click/__pycache__/globals.cpython-39.pyc | Bin 0 -> 2445 bytes .../click/__pycache__/parser.cpython-39.pyc | Bin 0 -> 13590 bytes .../shell_completion.cpython-39.pyc | Bin 0 -> 17019 bytes .../click/__pycache__/termui.cpython-39.pyc | Bin 0 -> 25890 bytes .../click/__pycache__/testing.cpython-39.pyc | Bin 0 -> 15169 bytes .../click/__pycache__/types.cpython-39.pyc | Bin 0 -> 33427 bytes .../click/__pycache__/utils.cpython-39.pyc | Bin 0 -> 18776 bytes .../python3.9/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 739 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../lib/python3.9/site-packages/click/core.py | 3042 ++++++ .../site-packages/click/decorators.py | 561 ++ .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.9/site-packages/click/globals.py | 68 + .../python3.9/site-packages/click/parser.py | 529 + .../python3.9/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.9/site-packages/click/termui.py | 784 ++ .../python3.9/site-packages/click/testing.py | 479 + .../python3.9/site-packages/click/types.py | 1089 +++ .../python3.9/site-packages/click/utils.py | 624 ++ .../python3.9/site-packages/easy_install.py | 5 + .../flask-3.0.0.dist-info/INSTALLER | 1 + .../flask-3.0.0.dist-info/LICENSE.rst | 28 + .../flask-3.0.0.dist-info/METADATA | 116 + .../flask-3.0.0.dist-info/RECORD | 58 + .../flask-3.0.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.0.0.dist-info/WHEEL | 4 + .../flask-3.0.0.dist-info/entry_points.txt | 3 + .../python3.9/site-packages/flask/__init__.py | 60 + .../python3.9/site-packages/flask/__main__.py | 3 + .../flask/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2299 bytes .../flask/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 234 bytes .../flask/__pycache__/app.cpython-39.pyc | Bin 0 -> 49163 bytes .../__pycache__/blueprints.cpython-39.pyc | Bin 0 -> 3396 bytes .../flask/__pycache__/cli.cpython-39.pyc | Bin 0 -> 26795 bytes .../flask/__pycache__/config.cpython-39.pyc | Bin 0 -> 12686 bytes .../flask/__pycache__/ctx.cpython-39.pyc | Bin 0 -> 14536 bytes .../__pycache__/debughelpers.cpython-39.pyc | Bin 0 -> 6013 bytes .../flask/__pycache__/globals.cpython-39.pyc | Bin 0 -> 1602 bytes .../flask/__pycache__/helpers.cpython-39.pyc | Bin 0 -> 21246 bytes .../flask/__pycache__/logging.cpython-39.pyc | Bin 0 -> 2525 bytes .../flask/__pycache__/sessions.cpython-39.pyc | Bin 0 -> 13119 bytes .../flask/__pycache__/signals.cpython-39.pyc | Bin 0 -> 832 bytes .../__pycache__/templating.cpython-39.pyc | Bin 0 -> 7014 bytes .../flask/__pycache__/testing.cpython-39.pyc | Bin 0 -> 9468 bytes .../flask/__pycache__/typing.cpython-39.pyc | Bin 0 -> 1834 bytes .../flask/__pycache__/views.cpython-39.pyc | Bin 0 -> 5398 bytes .../flask/__pycache__/wrappers.cpython-39.pyc | Bin 0 -> 5171 bytes .../lib/python3.9/site-packages/flask/app.py | 1478 +++ .../site-packages/flask/blueprints.py | 91 + .../lib/python3.9/site-packages/flask/cli.py | 1068 ++ .../python3.9/site-packages/flask/config.py | 347 + .../lib/python3.9/site-packages/flask/ctx.py | 440 + .../site-packages/flask/debughelpers.py | 160 + .../python3.9/site-packages/flask/globals.py | 51 + .../python3.9/site-packages/flask/helpers.py | 623 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 5988 bytes .../json/__pycache__/provider.cpython-39.pyc | Bin 0 -> 7576 bytes .../flask/json/__pycache__/tag.cpython-39.pyc | Bin 0 -> 11438 bytes .../site-packages/flask/json/provider.py | 216 + .../python3.9/site-packages/flask/json/tag.py | 314 + .../python3.9/site-packages/flask/logging.py | 76 + .../python3.9/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-39.pyc | Bin 0 -> 28184 bytes .../__pycache__/blueprints.cpython-39.pyc | Bin 0 -> 22685 bytes .../__pycache__/scaffold.cpython-39.pyc | Bin 0 -> 23763 bytes .../site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 626 ++ .../site-packages/flask/sansio/scaffold.py | 802 ++ .../python3.9/site-packages/flask/sessions.py | 367 + .../python3.9/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 221 + .../python3.9/site-packages/flask/testing.py | 295 + .../python3.9/site-packages/flask/typing.py | 88 + .../python3.9/site-packages/flask/views.py | 190 + .../python3.9/site-packages/flask/wrappers.py | 173 + .../idna-3.4.dist-info/INSTALLER | 1 + .../idna-3.4.dist-info/LICENSE.md | 29 + .../site-packages/idna-3.4.dist-info/METADATA | 242 + .../site-packages/idna-3.4.dist-info/RECORD | 22 + .../site-packages/idna-3.4.dist-info/WHEEL | 4 + .../python3.9/site-packages/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 852 bytes .../idna/__pycache__/codec.cpython-39.pyc | Bin 0 -> 3089 bytes .../idna/__pycache__/compat.cpython-39.pyc | Bin 0 -> 771 bytes .../idna/__pycache__/core.cpython-39.pyc | Bin 0 -> 9883 bytes .../idna/__pycache__/idnadata.cpython-39.pyc | Bin 0 -> 23206 bytes .../idna/__pycache__/intranges.cpython-39.pyc | Bin 0 -> 2002 bytes .../__pycache__/package_data.cpython-39.pyc | Bin 0 -> 216 bytes .../idna/__pycache__/uts46data.cpython-39.pyc | Bin 0 -> 153211 bytes .../lib/python3.9/site-packages/idna/codec.py | 112 + .../python3.9/site-packages/idna/compat.py | 13 + .../lib/python3.9/site-packages/idna/core.py | 400 + .../python3.9/site-packages/idna/idnadata.py | 2151 +++++ .../python3.9/site-packages/idna/intranges.py | 54 + .../site-packages/idna/package_data.py | 2 + .../lib/python3.9/site-packages/idna/py.typed | 0 .../python3.9/site-packages/idna/uts46data.py | 8600 +++++++++++++++++ .../INSTALLER | 1 + .../LICENSE | 202 + .../METADATA | 138 + .../importlib_metadata-6.8.0.dist-info/RECORD | 25 + .../importlib_metadata-6.8.0.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../importlib_metadata/__init__.py | 1015 ++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 37072 bytes .../__pycache__/_adapters.cpython-39.pyc | Bin 0 -> 2979 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 0 -> 1577 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 2078 bytes .../__pycache__/_functools.cpython-39.pyc | Bin 0 -> 3167 bytes .../__pycache__/_itertools.cpython-39.pyc | Bin 0 -> 2044 bytes .../__pycache__/_meta.cpython-39.pyc | Bin 0 -> 2895 bytes .../__pycache__/_py39compat.cpython-39.pyc | Bin 0 -> 1213 bytes .../__pycache__/_text.cpython-39.pyc | Bin 0 -> 3110 bytes .../importlib_metadata/_adapters.py | 90 + .../importlib_metadata/_collections.py | 30 + .../importlib_metadata/_compat.py | 67 + .../importlib_metadata/_functools.py | 104 + .../importlib_metadata/_itertools.py | 73 + .../site-packages/importlib_metadata/_meta.py | 63 + .../importlib_metadata/_py39compat.py | 35 + .../site-packages/importlib_metadata/_text.py | 99 + .../site-packages/importlib_metadata/py.typed | 0 .../itsdangerous-2.1.2.dist-info/INSTALLER | 1 + .../itsdangerous-2.1.2.dist-info/LICENSE.rst | 28 + .../itsdangerous-2.1.2.dist-info/METADATA | 97 + .../itsdangerous-2.1.2.dist-info/RECORD | 23 + .../itsdangerous-2.1.2.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 19 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 887 bytes .../__pycache__/_json.cpython-39.pyc | Bin 0 -> 943 bytes .../__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1900 bytes .../__pycache__/exc.cpython-39.pyc | Bin 0 -> 3456 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 0 -> 9764 bytes .../__pycache__/signer.cpython-39.pyc | Bin 0 -> 8455 bytes .../__pycache__/timed.cpython-39.pyc | Bin 0 -> 6501 bytes .../__pycache__/url_safe.cpython-39.pyc | Bin 0 -> 2736 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 | 234 + .../site-packages/itsdangerous/url_safe.py | 80 + .../site-packages/jinja2/__init__.py | 37 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1623 bytes .../__pycache__/_identifier.cpython-39.pyc | Bin 0 -> 2098 bytes .../__pycache__/async_utils.cpython-39.pyc | Bin 0 -> 2682 bytes .../jinja2/__pycache__/bccache.cpython-39.pyc | Bin 0 -> 13919 bytes .../__pycache__/compiler.cpython-39.pyc | Bin 0 -> 54199 bytes .../__pycache__/constants.cpython-39.pyc | Bin 0 -> 1559 bytes .../jinja2/__pycache__/debug.cpython-39.pyc | Bin 0 -> 3997 bytes .../__pycache__/defaults.cpython-39.pyc | Bin 0 -> 1359 bytes .../__pycache__/environment.cpython-39.pyc | Bin 0 -> 53127 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 5600 bytes .../jinja2/__pycache__/ext.cpython-39.pyc | Bin 0 -> 25555 bytes .../jinja2/__pycache__/filters.cpython-39.pyc | Bin 0 -> 50422 bytes .../__pycache__/idtracking.cpython-39.pyc | Bin 0 -> 11109 bytes .../jinja2/__pycache__/lexer.cpython-39.pyc | Bin 0 -> 20285 bytes .../jinja2/__pycache__/loaders.cpython-39.pyc | Bin 0 -> 20454 bytes .../jinja2/__pycache__/meta.cpython-39.pyc | Bin 0 -> 3817 bytes .../__pycache__/nativetypes.cpython-39.pyc | Bin 0 -> 4981 bytes .../jinja2/__pycache__/nodes.cpython-39.pyc | Bin 0 -> 40894 bytes .../__pycache__/optimizer.cpython-39.pyc | Bin 0 -> 1948 bytes .../jinja2/__pycache__/parser.cpython-39.pyc | Bin 0 -> 27596 bytes .../jinja2/__pycache__/runtime.cpython-39.pyc | Bin 0 -> 32186 bytes .../jinja2/__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 11939 bytes .../jinja2/__pycache__/tests.cpython-39.pyc | Bin 0 -> 6591 bytes .../jinja2/__pycache__/utils.cpython-39.pyc | Bin 0 -> 24559 bytes .../jinja2/__pycache__/visitor.cpython-39.pyc | Bin 0 -> 3942 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../python3.9/site-packages/jinja2/bccache.py | 406 + .../site-packages/jinja2/compiler.py | 1957 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.9/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1667 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../lib/python3.9/site-packages/jinja2/ext.py | 859 ++ .../python3.9/site-packages/jinja2/filters.py | 1840 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.9/site-packages/jinja2/lexer.py | 866 ++ .../python3.9/site-packages/jinja2/loaders.py | 661 ++ .../python3.9/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.9/site-packages/jinja2/nodes.py | 1204 +++ .../site-packages/jinja2/optimizer.py | 47 + .../python3.9/site-packages/jinja2/parser.py | 1032 ++ .../python3.9/site-packages/jinja2/py.typed | 0 .../python3.9/site-packages/jinja2/runtime.py | 1053 ++ .../python3.9/site-packages/jinja2/sandbox.py | 428 + .../python3.9/site-packages/jinja2/tests.py | 255 + .../python3.9/site-packages/jinja2/utils.py | 755 ++ .../python3.9/site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 304 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 11364 bytes .../__pycache__/_native.cpython-39.pyc | Bin 0 -> 2029 bytes .../site-packages/markupsafe/_native.py | 63 + .../site-packages/markupsafe/_speedups.c | 320 + .../_speedups.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 44024 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-20.3.4.dist-info/INSTALLER | 1 + .../pip-20.3.4.dist-info/LICENSE.txt | 20 + .../pip-20.3.4.dist-info/METADATA | 94 + .../site-packages/pip-20.3.4.dist-info/RECORD | 284 + .../pip-20.3.4.dist-info/REQUESTED | 0 .../site-packages/pip-20.3.4.dist-info/WHEEL | 6 + .../pip-20.3.4.dist-info/entry_points.txt | 5 + .../pip-20.3.4.dist-info/top_level.txt | 1 + .../python3.9/site-packages/pip/__init__.py | 18 + .../python3.9/site-packages/pip/__main__.py | 26 + .../pip/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 682 bytes .../pip/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 526 bytes .../site-packages/pip/_internal/__init__.py | 17 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 731 bytes .../__pycache__/build_env.cpython-39.pyc | Bin 0 -> 7566 bytes .../__pycache__/cache.cpython-39.pyc | Bin 0 -> 9123 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 10866 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 14955 bytes .../__pycache__/locations.cpython-39.pyc | Bin 0 -> 4589 bytes .../_internal/__pycache__/main.cpython-39.pyc | Bin 0 -> 668 bytes .../__pycache__/pyproject.cpython-39.pyc | Bin 0 -> 3771 bytes .../self_outdated_check.cpython-39.pyc | Bin 0 -> 4602 bytes .../__pycache__/wheel_builder.cpython-39.pyc | Bin 0 -> 8644 bytes .../site-packages/pip/_internal/build_env.py | 242 + .../site-packages/pip/_internal/cache.py | 346 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 289 bytes .../__pycache__/autocompletion.cpython-39.pyc | Bin 0 -> 4968 bytes .../__pycache__/base_command.cpython-39.pyc | Bin 0 -> 6876 bytes .../cli/__pycache__/cmdoptions.cpython-39.pyc | Bin 0 -> 20805 bytes .../command_context.cpython-39.pyc | Bin 0 -> 1369 bytes .../cli/__pycache__/main.cpython-39.pyc | Bin 0 -> 1473 bytes .../__pycache__/main_parser.cpython-39.pyc | Bin 0 -> 2260 bytes .../cli/__pycache__/parser.cpython-39.pyc | Bin 0 -> 9362 bytes .../__pycache__/progress_bars.cpython-39.pyc | Bin 0 -> 7724 bytes .../__pycache__/req_command.cpython-39.pyc | Bin 0 -> 10575 bytes .../cli/__pycache__/spinners.cpython-39.pyc | Bin 0 -> 4818 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 0 -> 418 bytes .../pip/_internal/cli/autocompletion.py | 164 + .../pip/_internal/cli/base_command.py | 260 + .../pip/_internal/cli/cmdoptions.py | 971 ++ .../pip/_internal/cli/command_context.py | 36 + .../site-packages/pip/_internal/cli/main.py | 75 + .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 285 + .../pip/_internal/cli/progress_bars.py | 280 + .../pip/_internal/cli/req_command.py | 436 + .../pip/_internal/cli/spinners.py | 173 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 123 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2989 bytes .../commands/__pycache__/cache.cpython-39.pyc | Bin 0 -> 5888 bytes .../commands/__pycache__/check.cpython-39.pyc | Bin 0 -> 1605 bytes .../__pycache__/completion.cpython-39.pyc | Bin 0 -> 3211 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 8161 bytes .../commands/__pycache__/debug.cpython-39.pyc | Bin 0 -> 7485 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 3993 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 3328 bytes .../commands/__pycache__/hash.cpython-39.pyc | Bin 0 -> 2172 bytes .../commands/__pycache__/help.cpython-39.pyc | Bin 0 -> 1398 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 17345 bytes .../commands/__pycache__/list.cpython-39.pyc | Bin 0 -> 9036 bytes .../__pycache__/search.cpython-39.pyc | Bin 0 -> 5120 bytes .../commands/__pycache__/show.cpython-39.pyc | Bin 0 -> 6447 bytes .../__pycache__/uninstall.cpython-39.pyc | Bin 0 -> 2983 bytes .../commands/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 5209 bytes .../pip/_internal/commands/cache.py | 234 + .../pip/_internal/commands/check.py | 51 + .../pip/_internal/commands/completion.py | 98 + .../pip/_internal/commands/configuration.py | 280 + .../pip/_internal/commands/debug.py | 251 + .../pip/_internal/commands/download.py | 143 + .../pip/_internal/commands/freeze.py | 116 + .../pip/_internal/commands/hash.py | 63 + .../pip/_internal/commands/help.py | 46 + .../pip/_internal/commands/install.py | 763 ++ .../pip/_internal/commands/list.py | 328 + .../pip/_internal/commands/search.py | 169 + .../pip/_internal/commands/show.py | 186 + .../pip/_internal/commands/uninstall.py | 95 + .../pip/_internal/commands/wheel.py | 198 + .../pip/_internal/configuration.py | 407 + .../pip/_internal/distributions/__init__.py | 24 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 865 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 1981 bytes .../__pycache__/installed.cpython-39.pyc | Bin 0 -> 1261 bytes .../__pycache__/sdist.cpython-39.pyc | Bin 0 -> 3540 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1605 bytes .../pip/_internal/distributions/base.py | 46 + .../pip/_internal/distributions/installed.py | 25 + .../pip/_internal/distributions/sdist.py | 105 + .../pip/_internal/distributions/wheel.py | 37 + .../site-packages/pip/_internal/exceptions.py | 391 + .../pip/_internal/index/__init__.py | 2 + .../index/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 243 bytes .../__pycache__/collector.cpython-39.pyc | Bin 0 -> 17768 bytes .../__pycache__/package_finder.cpython-39.pyc | Bin 0 -> 26096 bytes .../pip/_internal/index/collector.py | 667 ++ .../pip/_internal/index/package_finder.py | 1015 ++ .../site-packages/pip/_internal/locations.py | 199 + .../site-packages/pip/_internal/main.py | 16 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 277 bytes .../__pycache__/candidate.cpython-39.pyc | Bin 0 -> 1504 bytes .../__pycache__/direct_url.cpython-39.pyc | Bin 0 -> 6528 bytes .../__pycache__/format_control.cpython-39.pyc | Bin 0 -> 2762 bytes .../models/__pycache__/index.cpython-39.pyc | Bin 0 -> 1243 bytes .../models/__pycache__/link.cpython-39.pyc | Bin 0 -> 7173 bytes .../models/__pycache__/scheme.cpython-39.pyc | Bin 0 -> 965 bytes .../__pycache__/search_scope.cpython-39.pyc | Bin 0 -> 3458 bytes .../selection_prefs.cpython-39.pyc | Bin 0 -> 1675 bytes .../__pycache__/target_python.cpython-39.pyc | Bin 0 -> 3381 bytes .../models/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 3229 bytes .../pip/_internal/models/candidate.py | 39 + .../pip/_internal/models/direct_url.py | 243 + .../pip/_internal/models/format_control.py | 92 + .../pip/_internal/models/index.py | 34 + .../pip/_internal/models/link.py | 246 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 135 + .../pip/_internal/models/selection_prefs.py | 50 + .../pip/_internal/models/target_python.py | 117 + .../pip/_internal/models/wheel.py | 78 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 265 bytes .../network/__pycache__/auth.cpython-39.pyc | Bin 0 -> 7117 bytes .../network/__pycache__/cache.cpython-39.pyc | Bin 0 -> 2841 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 5292 bytes .../__pycache__/lazy_wheel.cpython-39.pyc | Bin 0 -> 8081 bytes .../__pycache__/session.cpython-39.pyc | Bin 0 -> 9526 bytes .../network/__pycache__/utils.cpython-39.pyc | Bin 0 -> 1418 bytes .../network/__pycache__/xmlrpc.cpython-39.pyc | Bin 0 -> 1880 bytes .../pip/_internal/network/auth.py | 310 + .../pip/_internal/network/cache.py | 79 + .../pip/_internal/network/download.py | 202 + .../pip/_internal/network/lazy_wheel.py | 231 + .../pip/_internal/network/session.py | 428 + .../pip/_internal/network/utils.py | 97 + .../pip/_internal/network/xmlrpc.py | 53 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 213 bytes .../__pycache__/check.cpython-39.pyc | Bin 0 -> 3635 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 5955 bytes .../__pycache__/prepare.cpython-39.pyc | Bin 0 -> 13681 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 219 bytes .../build/__pycache__/metadata.cpython-39.pyc | Bin 0 -> 1240 bytes .../metadata_legacy.cpython-39.pyc | Bin 0 -> 2016 bytes .../build/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1357 bytes .../__pycache__/wheel_legacy.cpython-39.pyc | Bin 0 -> 2639 bytes .../_internal/operations/build/metadata.py | 38 + .../operations/build/metadata_legacy.py | 77 + .../pip/_internal/operations/build/wheel.py | 47 + .../operations/build/wheel_legacy.py | 113 + .../pip/_internal/operations/check.py | 155 + .../pip/_internal/operations/freeze.py | 277 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 277 bytes .../editable_legacy.cpython-39.pyc | Bin 0 -> 1395 bytes .../install/__pycache__/legacy.cpython-39.pyc | Bin 0 -> 3285 bytes .../install/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 21269 bytes .../operations/install/editable_legacy.py | 52 + .../_internal/operations/install/legacy.py | 130 + .../pip/_internal/operations/install/wheel.py | 846 ++ .../pip/_internal/operations/prepare.py | 608 ++ .../site-packages/pip/_internal/pyproject.py | 196 + .../pip/_internal/req/__init__.py | 103 + .../req/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2514 bytes .../__pycache__/constructors.cpython-39.pyc | Bin 0 -> 11044 bytes .../req/__pycache__/req_file.cpython-39.pyc | Bin 0 -> 12730 bytes .../__pycache__/req_install.cpython-39.pyc | Bin 0 -> 21481 bytes .../req/__pycache__/req_set.cpython-39.pyc | Bin 0 -> 5833 bytes .../__pycache__/req_tracker.cpython-39.pyc | Bin 0 -> 4255 bytes .../__pycache__/req_uninstall.cpython-39.pyc | Bin 0 -> 17583 bytes .../pip/_internal/req/constructors.py | 476 + .../pip/_internal/req/req_file.py | 574 ++ .../pip/_internal/req/req_install.py | 915 ++ .../pip/_internal/req/req_set.py | 204 + .../pip/_internal/req/req_tracker.py | 151 + .../pip/_internal/req/req_uninstall.py | 657 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 213 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 1045 bytes .../pip/_internal/resolution/base.py | 21 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 220 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 11600 bytes .../_internal/resolution/legacy/resolver.py | 473 + .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 224 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 5803 bytes .../__pycache__/candidates.cpython-39.pyc | Bin 0 -> 18028 bytes .../__pycache__/factory.cpython-39.pyc | Bin 0 -> 11573 bytes .../found_candidates.cpython-39.pyc | Bin 0 -> 3482 bytes .../__pycache__/provider.cpython-39.pyc | Bin 0 -> 6345 bytes .../__pycache__/reporter.cpython-39.pyc | Bin 0 -> 3231 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 7069 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 7918 bytes .../_internal/resolution/resolvelib/base.py | 156 + .../resolution/resolvelib/candidates.py | 604 ++ .../resolution/resolvelib/factory.py | 504 + .../resolution/resolvelib/found_candidates.py | 101 + .../resolution/resolvelib/provider.py | 174 + .../resolution/resolvelib/reporter.py | 84 + .../resolution/resolvelib/requirements.py | 201 + .../resolution/resolvelib/resolver.py | 297 + .../pip/_internal/self_outdated_check.py | 197 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 208 bytes .../utils/__pycache__/appdirs.cpython-39.pyc | Bin 0 -> 1398 bytes .../utils/__pycache__/compat.cpython-39.pyc | Bin 0 -> 6723 bytes .../compatibility_tags.cpython-39.pyc | Bin 0 -> 3957 bytes .../utils/__pycache__/datetime.cpython-39.pyc | Bin 0 -> 529 bytes .../__pycache__/deprecation.cpython-39.pyc | Bin 0 -> 2855 bytes .../direct_url_helpers.cpython-39.pyc | Bin 0 -> 2676 bytes .../__pycache__/distutils_args.cpython-39.pyc | Bin 0 -> 1148 bytes .../utils/__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1328 bytes .../__pycache__/entrypoints.cpython-39.pyc | Bin 0 -> 1352 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 0 -> 5689 bytes .../__pycache__/filetypes.cpython-39.pyc | Bin 0 -> 897 bytes .../utils/__pycache__/glibc.cpython-39.pyc | Bin 0 -> 1755 bytes .../utils/__pycache__/hashes.cpython-39.pyc | Bin 0 -> 5275 bytes .../inject_securetransport.cpython-39.pyc | Bin 0 -> 981 bytes .../utils/__pycache__/logging.cpython-39.pyc | Bin 0 -> 9248 bytes .../utils/__pycache__/misc.cpython-39.pyc | Bin 0 -> 25533 bytes .../utils/__pycache__/models.cpython-39.pyc | Bin 0 -> 2008 bytes .../__pycache__/packaging.cpython-39.pyc | Bin 0 -> 2661 bytes .../utils/__pycache__/parallel.cpython-39.pyc | Bin 0 -> 3226 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 0 -> 1877 bytes .../setuptools_build.cpython-39.pyc | Bin 0 -> 2954 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 0 -> 6091 bytes .../utils/__pycache__/temp_dir.cpython-39.pyc | Bin 0 -> 7236 bytes .../utils/__pycache__/typing.cpython-39.pyc | Bin 0 -> 1490 bytes .../__pycache__/unpacking.cpython-39.pyc | Bin 0 -> 6652 bytes .../utils/__pycache__/urls.cpython-39.pyc | Bin 0 -> 1552 bytes .../__pycache__/virtualenv.cpython-39.pyc | Bin 0 -> 3385 bytes .../utils/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 6364 bytes .../pip/_internal/utils/appdirs.py | 44 + .../pip/_internal/utils/compat.py | 293 + .../pip/_internal/utils/compatibility_tags.py | 178 + .../pip/_internal/utils/datetime.py | 14 + .../pip/_internal/utils/deprecation.py | 104 + .../pip/_internal/utils/direct_url_helpers.py | 126 + .../pip/_internal/utils/distutils_args.py | 48 + .../pip/_internal/utils/encoding.py | 41 + .../pip/_internal/utils/entrypoints.py | 31 + .../pip/_internal/utils/filesystem.py | 224 + .../pip/_internal/utils/filetypes.py | 26 + .../pip/_internal/utils/glibc.py | 98 + .../pip/_internal/utils/hashes.py | 169 + .../_internal/utils/inject_securetransport.py | 36 + .../pip/_internal/utils/logging.py | 399 + .../site-packages/pip/_internal/utils/misc.py | 977 ++ .../pip/_internal/utils/models.py | 44 + .../pip/_internal/utils/packaging.py | 95 + .../pip/_internal/utils/parallel.py | 107 + .../pip/_internal/utils/pkg_resources.py | 44 + .../pip/_internal/utils/setuptools_build.py | 181 + .../pip/_internal/utils/subprocess.py | 299 + .../pip/_internal/utils/temp_dir.py | 284 + .../pip/_internal/utils/typing.py | 38 + .../pip/_internal/utils/unpacking.py | 281 + .../site-packages/pip/_internal/utils/urls.py | 55 + .../pip/_internal/utils/virtualenv.py | 119 + .../pip/_internal/utils/wheel.py | 225 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 501 bytes .../vcs/__pycache__/bazaar.cpython-39.pyc | Bin 0 -> 3823 bytes .../vcs/__pycache__/git.cpython-39.pyc | Bin 0 -> 10636 bytes .../vcs/__pycache__/mercurial.cpython-39.pyc | Bin 0 -> 5198 bytes .../vcs/__pycache__/subversion.cpython-39.pyc | Bin 0 -> 8623 bytes .../__pycache__/versioncontrol.cpython-39.pyc | Bin 0 -> 19711 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 123 + .../site-packages/pip/_internal/vcs/git.py | 460 + .../pip/_internal/vcs/mercurial.py | 172 + .../pip/_internal/vcs/subversion.py | 340 + .../pip/_internal/vcs/versioncontrol.py | 735 ++ .../pip/_internal/wheel_builder.py | 363 + .../site-packages/pip/_vendor/__init__.py | 123 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3328 bytes .../site-packages/pip/_vendor/vendor.txt | 24 + .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 590 ++ .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 + .../pkg_resources-0.0.0.dist-info/LICENSE.txt | 20 + .../pkg_resources-0.0.0.dist-info/METADATA | 13 + .../pkg_resources-0.0.0.dist-info/RECORD | 39 + .../pkg_resources-0.0.0.dist-info/REQUESTED | 0 .../pkg_resources-0.0.0.dist-info/WHEEL | 6 + .../site-packages/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 100390 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 0 -> 655 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 210 bytes .../__pycache__/appdirs.cpython-39.pyc | Bin 0 -> 20527 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 0 -> 201363 bytes .../_vendor/__pycache__/six.cpython-39.pyc | Bin 0 -> 24493 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 734 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 572 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 1034 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 0 -> 2816 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 8944 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 3931 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 0 -> 19820 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 519 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 10655 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-39.pyc | Bin 0 -> 2461 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../requests-2.31.0.dist-info/INSTALLER | 1 + .../requests-2.31.0.dist-info/LICENSE | 175 + .../requests-2.31.0.dist-info/METADATA | 122 + .../requests-2.31.0.dist-info/RECORD | 43 + .../requests-2.31.0.dist-info/REQUESTED | 0 .../requests-2.31.0.dist-info/WHEEL | 5 + .../requests-2.31.0.dist-info/top_level.txt | 1 + .../site-packages/requests/__init__.py | 180 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3873 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 0 -> 555 bytes .../_internal_utils.cpython-39.pyc | Bin 0 -> 1630 bytes .../__pycache__/adapters.cpython-39.pyc | Bin 0 -> 16222 bytes .../requests/__pycache__/api.cpython-39.pyc | Bin 0 -> 6796 bytes .../requests/__pycache__/auth.cpython-39.pyc | Bin 0 -> 8361 bytes .../requests/__pycache__/certs.cpython-39.pyc | Bin 0 -> 626 bytes .../__pycache__/compat.cpython-39.pyc | Bin 0 -> 1525 bytes .../__pycache__/cookies.cpython-39.pyc | Bin 0 -> 18823 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 6124 bytes .../requests/__pycache__/help.cpython-39.pyc | Bin 0 -> 2838 bytes .../requests/__pycache__/hooks.cpython-39.pyc | Bin 0 -> 995 bytes .../__pycache__/models.cpython-39.pyc | Bin 0 -> 24243 bytes .../__pycache__/packages.cpython-39.pyc | Bin 0 -> 716 bytes .../__pycache__/sessions.cpython-39.pyc | Bin 0 -> 19656 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 0 -> 4240 bytes .../__pycache__/structures.cpython-39.pyc | Bin 0 -> 4452 bytes .../requests/__pycache__/utils.cpython-39.pyc | Bin 0 -> 24337 bytes .../site-packages/requests/__version__.py | 14 + .../site-packages/requests/_internal_utils.py | 50 + .../site-packages/requests/adapters.py | 538 ++ .../python3.9/site-packages/requests/api.py | 157 + .../python3.9/site-packages/requests/auth.py | 315 + .../python3.9/site-packages/requests/certs.py | 17 + .../site-packages/requests/compat.py | 79 + .../site-packages/requests/cookies.py | 561 ++ .../site-packages/requests/exceptions.py | 141 + .../python3.9/site-packages/requests/help.py | 134 + .../python3.9/site-packages/requests/hooks.py | 33 + .../site-packages/requests/models.py | 1034 ++ .../site-packages/requests/packages.py | 28 + .../site-packages/requests/sessions.py | 833 ++ .../site-packages/requests/status_codes.py | 128 + .../site-packages/requests/structures.py | 99 + .../python3.9/site-packages/requests/utils.py | 1094 +++ .../setuptools-44.1.1.dist-info/AUTHORS.txt | 590 ++ .../setuptools-44.1.1.dist-info/INSTALLER | 1 + .../setuptools-44.1.1.dist-info/LICENSE.txt | 20 + .../setuptools-44.1.1.dist-info/METADATA | 82 + .../setuptools-44.1.1.dist-info/RECORD | 164 + .../setuptools-44.1.1.dist-info/REQUESTED | 0 .../setuptools-44.1.1.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 68 + .../setuptools-44.1.1.dist-info/top_level.txt | 3 + .../setuptools-44.1.1.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 245 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 8651 bytes .../_deprecation_warning.cpython-39.pyc | Bin 0 -> 569 bytes .../__pycache__/_imp.cpython-39.pyc | Bin 0 -> 1939 bytes .../__pycache__/archive_util.cpython-39.pyc | Bin 0 -> 5241 bytes .../__pycache__/build_meta.cpython-39.pyc | Bin 0 -> 8656 bytes .../__pycache__/config.cpython-39.pyc | Bin 0 -> 17962 bytes .../__pycache__/dep_util.cpython-39.pyc | Bin 0 -> 872 bytes .../__pycache__/depends.cpython-39.pyc | Bin 0 -> 5290 bytes .../__pycache__/dist.cpython-39.pyc | Bin 0 -> 42496 bytes .../__pycache__/errors.cpython-39.pyc | Bin 0 -> 869 bytes .../__pycache__/extension.cpython-39.pyc | Bin 0 -> 2018 bytes .../__pycache__/glob.cpython-39.pyc | Bin 0 -> 3776 bytes .../__pycache__/installer.cpython-39.pyc | Bin 0 -> 4123 bytes .../__pycache__/launch.cpython-39.pyc | Bin 0 -> 877 bytes .../__pycache__/lib2to3_ex.cpython-39.pyc | Bin 0 -> 2470 bytes .../__pycache__/monkey.cpython-39.pyc | Bin 0 -> 4691 bytes .../__pycache__/msvc.cpython-39.pyc | Bin 0 -> 39679 bytes .../__pycache__/namespaces.cpython-39.pyc | Bin 0 -> 3689 bytes .../__pycache__/package_index.cpython-39.pyc | Bin 0 -> 33127 bytes .../__pycache__/py27compat.cpython-39.pyc | Bin 0 -> 1802 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 0 -> 1244 bytes .../__pycache__/py33compat.cpython-39.pyc | Bin 0 -> 1459 bytes .../__pycache__/py34compat.cpython-39.pyc | Bin 0 -> 499 bytes .../__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 15929 bytes .../__pycache__/site-patch.cpython-39.pyc | Bin 0 -> 1529 bytes .../__pycache__/ssl_support.cpython-39.pyc | Bin 0 -> 6897 bytes .../__pycache__/unicode_utils.cpython-39.pyc | Bin 0 -> 1198 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 343 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 7482 bytes .../windows_support.cpython-39.pyc | Bin 0 -> 1042 bytes .../setuptools/_deprecation_warning.py | 7 + .../site-packages/setuptools/_imp.py | 73 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 207 bytes .../__pycache__/ordered_set.cpython-39.pyc | Bin 0 -> 16401 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 0 -> 201360 bytes .../_vendor/__pycache__/six.cpython-39.pyc | Bin 0 -> 24490 bytes .../setuptools/_vendor/ordered_set.py | 488 + .../setuptools/_vendor/packaging/__about__.py | 27 + .../setuptools/_vendor/packaging/__init__.py | 26 + .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 731 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 569 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 1031 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 0 -> 2813 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 8952 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 4044 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 0 -> 19765 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 10843 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 1478 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 12098 bytes .../setuptools/_vendor/packaging/_compat.py | 31 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 296 + .../_vendor/packaging/requirements.py | 138 + .../_vendor/packaging/specifiers.py | 749 ++ .../setuptools/_vendor/packaging/tags.py | 404 + .../setuptools/_vendor/packaging/utils.py | 57 + .../setuptools/_vendor/packaging/version.py | 420 + .../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 | 264 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 17 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 687 bytes .../command/__pycache__/alias.cpython-39.pyc | Bin 0 -> 2445 bytes .../__pycache__/bdist_egg.cpython-39.pyc | Bin 0 -> 14233 bytes .../__pycache__/bdist_rpm.cpython-39.pyc | Bin 0 -> 1835 bytes .../__pycache__/bdist_wininst.cpython-39.pyc | Bin 0 -> 1011 bytes .../__pycache__/build_clib.cpython-39.pyc | Bin 0 -> 2490 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 0 -> 9880 bytes .../__pycache__/build_py.cpython-39.pyc | Bin 0 -> 8711 bytes .../__pycache__/develop.cpython-39.pyc | Bin 0 -> 6590 bytes .../__pycache__/dist_info.cpython-39.pyc | Bin 0 -> 1414 bytes .../__pycache__/easy_install.cpython-39.pyc | Bin 0 -> 67024 bytes .../__pycache__/egg_info.cpython-39.pyc | Bin 0 -> 21841 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 4055 bytes .../install_egg_info.cpython-39.pyc | Bin 0 -> 2943 bytes .../__pycache__/install_lib.cpython-39.pyc | Bin 0 -> 5108 bytes .../install_scripts.cpython-39.pyc | Bin 0 -> 2322 bytes .../__pycache__/py36compat.cpython-39.pyc | Bin 0 -> 4663 bytes .../__pycache__/register.cpython-39.pyc | Bin 0 -> 864 bytes .../command/__pycache__/rotate.cpython-39.pyc | Bin 0 -> 2559 bytes .../__pycache__/saveopts.cpython-39.pyc | Bin 0 -> 942 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 0 -> 7952 bytes .../command/__pycache__/setopt.cpython-39.pyc | Bin 0 -> 4594 bytes .../command/__pycache__/test.cpython-39.pyc | Bin 0 -> 8692 bytes .../command/__pycache__/upload.cpython-39.pyc | Bin 0 -> 837 bytes .../__pycache__/upload_docs.cpython-39.pyc | Bin 0 -> 6231 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 | 327 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 221 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2402 +++++ .../setuptools/command/egg_info.py | 717 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 82 + .../setuptools/command/install_lib.py | 147 + .../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 | 252 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 279 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 659 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 176 + .../site-packages/setuptools/dist.py | 1274 +++ .../site-packages/setuptools/errors.py | 16 + .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2475 bytes .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/installer.py | 150 + .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1679 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1136 +++ .../site-packages/setuptools/py27compat.py | 60 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 59 + .../site-packages/setuptools/py34compat.py | 13 + .../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 | 220 + .../setuptools/windows_support.py | 29 + .../urllib3-2.0.6.dist-info/INSTALLER | 1 + .../urllib3-2.0.6.dist-info/METADATA | 158 + .../urllib3-2.0.6.dist-info/RECORD | 70 + .../urllib3-2.0.6.dist-info/WHEEL | 4 + .../licenses/LICENSE.txt | 21 + .../site-packages/urllib3/__init__.py | 166 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 4108 bytes .../_base_connection.cpython-39.pyc | Bin 0 -> 5509 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 0 -> 15294 bytes .../_request_methods.cpython-39.pyc | Bin 0 -> 6778 bytes .../__pycache__/_version.cpython-39.pyc | Bin 0 -> 268 bytes .../__pycache__/connection.cpython-39.pyc | Bin 0 -> 21140 bytes .../__pycache__/connectionpool.cpython-39.pyc | Bin 0 -> 28456 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 13536 bytes .../urllib3/__pycache__/fields.cpython-39.pyc | Bin 0 -> 9727 bytes .../__pycache__/filepost.cpython-39.pyc | Bin 0 -> 2336 bytes .../__pycache__/poolmanager.cpython-39.pyc | Bin 0 -> 17716 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 30428 bytes .../site-packages/urllib3/_base_connection.py | 173 + .../site-packages/urllib3/_collections.py | 463 + .../site-packages/urllib3/_request_methods.py | 217 + .../site-packages/urllib3/_version.py | 4 + .../site-packages/urllib3/connection.py | 906 ++ .../site-packages/urllib3/connectionpool.py | 1178 +++ .../site-packages/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 204 bytes .../__pycache__/pyopenssl.cpython-39.pyc | Bin 0 -> 16975 bytes .../securetransport.cpython-39.pyc | Bin 0 -> 21832 bytes .../contrib/__pycache__/socks.cpython-39.pyc | Bin 0 -> 6206 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 221 bytes .../__pycache__/bindings.cpython-39.pyc | Bin 0 -> 7754 bytes .../__pycache__/low_level.cpython-39.pyc | Bin 0 -> 11429 bytes .../contrib/_securetransport/bindings.py | 430 + .../contrib/_securetransport/low_level.py | 474 + .../urllib3/contrib/pyopenssl.py | 548 ++ .../urllib3/contrib/securetransport.py | 913 ++ .../site-packages/urllib3/contrib/socks.py | 233 + .../site-packages/urllib3/exceptions.py | 318 + .../python3.9/site-packages/urllib3/fields.py | 345 + .../site-packages/urllib3/filepost.py | 89 + .../site-packages/urllib3/poolmanager.py | 634 ++ .../python3.9/site-packages/urllib3/py.typed | 2 + .../site-packages/urllib3/response.py | 1132 +++ .../site-packages/urllib3/util/__init__.py | 44 + .../util/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1018 bytes .../__pycache__/connection.cpython-39.pyc | Bin 0 -> 3447 bytes .../util/__pycache__/proxy.cpython-39.pyc | Bin 0 -> 1080 bytes .../util/__pycache__/request.cpython-39.pyc | Bin 0 -> 6118 bytes .../util/__pycache__/response.cpython-39.pyc | Bin 0 -> 2330 bytes .../util/__pycache__/retry.cpython-39.pyc | Bin 0 -> 15273 bytes .../util/__pycache__/ssl_.cpython-39.pyc | Bin 0 -> 11883 bytes .../ssl_match_hostname.cpython-39.pyc | Bin 0 -> 3676 bytes .../__pycache__/ssltransport.cpython-39.pyc | Bin 0 -> 9387 bytes .../util/__pycache__/timeout.cpython-39.pyc | Bin 0 -> 9737 bytes .../util/__pycache__/url.cpython-39.pyc | Bin 0 -> 11063 bytes .../util/__pycache__/util.cpython-39.pyc | Bin 0 -> 1269 bytes .../util/__pycache__/wait.cpython-39.pyc | Bin 0 -> 2410 bytes .../site-packages/urllib3/util/connection.py | 137 + .../site-packages/urllib3/util/proxy.py | 43 + .../site-packages/urllib3/util/request.py | 256 + .../site-packages/urllib3/util/response.py | 101 + .../site-packages/urllib3/util/retry.py | 529 + .../site-packages/urllib3/util/ssl_.py | 513 + .../urllib3/util/ssl_match_hostname.py | 159 + .../urllib3/util/ssltransport.py | 280 + .../site-packages/urllib3/util/timeout.py | 279 + .../site-packages/urllib3/util/url.py | 471 + .../site-packages/urllib3/util/util.py | 42 + .../site-packages/urllib3/util/wait.py | 124 + .../werkzeug-3.0.0.dist-info/INSTALLER | 1 + .../werkzeug-3.0.0.dist-info/LICENSE.rst | 28 + .../werkzeug-3.0.0.dist-info/METADATA | 118 + .../werkzeug-3.0.0.dist-info/RECORD | 125 + .../werkzeug-3.0.0.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 25 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 945 bytes .../__pycache__/_internal.cpython-39.pyc | Bin 0 -> 6801 bytes .../__pycache__/_reloader.cpython-39.pyc | Bin 0 -> 12424 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 27699 bytes .../__pycache__/formparser.cpython-39.pyc | Bin 0 -> 12259 bytes .../werkzeug/__pycache__/http.cpython-39.pyc | Bin 0 -> 37756 bytes .../werkzeug/__pycache__/local.cpython-39.pyc | Bin 0 -> 20515 bytes .../__pycache__/security.cpython-39.pyc | Bin 0 -> 5279 bytes .../__pycache__/serving.cpython-39.pyc | Bin 0 -> 29705 bytes .../werkzeug/__pycache__/test.cpython-39.pyc | Bin 0 -> 42150 bytes .../__pycache__/testapp.cpython-39.pyc | Bin 0 -> 6379 bytes .../werkzeug/__pycache__/urls.cpython-39.pyc | Bin 0 -> 6375 bytes .../__pycache__/user_agent.cpython-39.pyc | Bin 0 -> 1856 bytes .../werkzeug/__pycache__/utils.cpython-39.pyc | Bin 0 -> 21976 bytes .../werkzeug/__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 19618 bytes .../site-packages/werkzeug/_internal.py | 214 + .../site-packages/werkzeug/_reloader.py | 458 + .../werkzeug/datastructures/__init__.py | 34 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1577 bytes .../__pycache__/accept.cpython-39.pyc | Bin 0 -> 10632 bytes .../__pycache__/auth.cpython-39.pyc | Bin 0 -> 10430 bytes .../__pycache__/cache_control.cpython-39.pyc | Bin 0 -> 6594 bytes .../__pycache__/csp.cpython-39.pyc | Bin 0 -> 4162 bytes .../__pycache__/etag.cpython-39.pyc | Bin 0 -> 3963 bytes .../__pycache__/file_storage.cpython-39.pyc | Bin 0 -> 6059 bytes .../__pycache__/headers.cpython-39.pyc | Bin 0 -> 17724 bytes .../__pycache__/mixins.cpython-39.pyc | Bin 0 -> 9592 bytes .../__pycache__/range.cpython-39.pyc | Bin 0 -> 6098 bytes .../__pycache__/structures.cpython-39.pyc | Bin 0 -> 36254 bytes .../werkzeug/datastructures/accept.py | 326 + .../werkzeug/datastructures/accept.pyi | 54 + .../werkzeug/datastructures/auth.py | 318 + .../werkzeug/datastructures/cache_control.py | 175 + .../werkzeug/datastructures/cache_control.pyi | 109 + .../werkzeug/datastructures/csp.py | 94 + .../werkzeug/datastructures/csp.pyi | 169 + .../werkzeug/datastructures/etag.py | 95 + .../werkzeug/datastructures/etag.pyi | 30 + .../werkzeug/datastructures/file_storage.py | 196 + .../werkzeug/datastructures/file_storage.pyi | 47 + .../werkzeug/datastructures/headers.py | 515 + .../werkzeug/datastructures/headers.pyi | 109 + .../werkzeug/datastructures/mixins.py | 242 + .../werkzeug/datastructures/mixins.pyi | 97 + .../werkzeug/datastructures/range.py | 180 + .../werkzeug/datastructures/range.pyi | 57 + .../werkzeug/datastructures/structures.py | 1006 ++ .../werkzeug/datastructures/structures.pyi | 208 + .../site-packages/werkzeug/debug/__init__.py | 534 + .../debug/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 14094 bytes .../debug/__pycache__/console.cpython-39.pyc | Bin 0 -> 8113 bytes .../debug/__pycache__/repr.cpython-39.pyc | Bin 0 -> 8863 bytes .../debug/__pycache__/tbtools.cpython-39.pyc | Bin 0 -> 11522 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../site-packages/werkzeug/debug/repr.py | 283 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 360 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/style.css | 150 + .../site-packages/werkzeug/debug/tbtools.py | 437 + .../site-packages/werkzeug/exceptions.py | 879 ++ .../site-packages/werkzeug/formparser.py | 421 + .../python3.9/site-packages/werkzeug/http.py | 1372 +++ .../python3.9/site-packages/werkzeug/local.py | 643 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 208 bytes .../__pycache__/dispatcher.cpython-39.pyc | Bin 0 -> 2804 bytes .../__pycache__/http_proxy.cpython-39.pyc | Bin 0 -> 6827 bytes .../__pycache__/lint.cpython-39.pyc | Bin 0 -> 12724 bytes .../__pycache__/profiler.cpython-39.pyc | Bin 0 -> 5562 bytes .../__pycache__/proxy_fix.cpython-39.pyc | Bin 0 -> 5960 bytes .../__pycache__/shared_data.cpython-39.pyc | Bin 0 -> 9105 bytes .../werkzeug/middleware/dispatcher.py | 80 + .../werkzeug/middleware/http_proxy.py | 235 + .../site-packages/werkzeug/middleware/lint.py | 420 + .../werkzeug/middleware/profiler.py | 154 + .../werkzeug/middleware/proxy_fix.py | 182 + .../werkzeug/middleware/shared_data.py | 282 + .../python3.9/site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 133 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 4646 bytes .../__pycache__/converters.cpython-39.pyc | Bin 0 -> 8886 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 5502 bytes .../routing/__pycache__/map.cpython-39.pyc | Bin 0 -> 30348 bytes .../__pycache__/matcher.cpython-39.pyc | Bin 0 -> 5084 bytes .../routing/__pycache__/rules.cpython-39.pyc | Bin 0 -> 27321 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 148 + .../site-packages/werkzeug/routing/map.py | 946 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 909 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 204 bytes .../sansio/__pycache__/http.cpython-39.pyc | Bin 0 -> 4026 bytes .../__pycache__/multipart.cpython-39.pyc | Bin 0 -> 7426 bytes .../sansio/__pycache__/request.cpython-39.pyc | Bin 0 -> 17266 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 24273 bytes .../sansio/__pycache__/utils.cpython-39.pyc | Bin 0 -> 4521 bytes .../site-packages/werkzeug/sansio/http.py | 171 + .../werkzeug/sansio/multipart.py | 313 + .../site-packages/werkzeug/sansio/request.py | 536 + .../site-packages/werkzeug/sansio/response.py | 751 ++ .../site-packages/werkzeug/sansio/utils.py | 159 + .../site-packages/werkzeug/security.py | 157 + .../site-packages/werkzeug/serving.py | 1109 +++ .../python3.9/site-packages/werkzeug/test.py | 1462 +++ .../site-packages/werkzeug/testapp.py | 181 + .../python3.9/site-packages/werkzeug/urls.py | 216 + .../site-packages/werkzeug/user_agent.py | 47 + .../python3.9/site-packages/werkzeug/utils.py | 690 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 323 bytes .../__pycache__/request.cpython-39.pyc | Bin 0 -> 21356 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 28048 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 835 ++ .../python3.9/site-packages/werkzeug/wsgi.py | 595 ++ .../zipp-3.17.0.dist-info/INSTALLER | 1 + .../zipp-3.17.0.dist-info/LICENSE | 17 + .../zipp-3.17.0.dist-info/METADATA | 104 + .../zipp-3.17.0.dist-info/RECORD | 12 + .../site-packages/zipp-3.17.0.dist-info/WHEEL | 5 + .../zipp-3.17.0.dist-info/top_level.txt | 1 + .../python3.9/site-packages/zipp/__init__.py | 428 + .../zipp/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 13769 bytes .../zipp/__pycache__/glob.cpython-39.pyc | Bin 0 -> 1224 bytes .../__pycache__/py310compat.cpython-39.pyc | Bin 0 -> 432 bytes .../lib/python3.9/site-packages/zipp/glob.py | 40 + .../site-packages/zipp/py310compat.py | 11 + testclient/.venv/lib64 | 1 + testclient/.venv/pyvenv.cfg | 3 + .../CacheControl-0.12.6-py2.py3-none-any.whl | Bin 0 -> 23441 bytes .../appdirs-1.4.4-py2.py3-none-any.whl | Bin 0 -> 14285 bytes .../certifi-2020.6.20-py2.py3-none-any.whl | Bin 0 -> 161344 bytes .../chardet-4.0.0-py2.py3-none-any.whl | Bin 0 -> 174749 bytes .../colorama-0.4.4-py2.py3-none-any.whl | Bin 0 -> 20722 bytes ...ntextlib2-0.6.0.post1-py2.py3-none-any.whl | Bin 0 -> 12692 bytes .../distlib-0.3.1-py2.py3-none-any.whl | Bin 0 -> 147633 bytes .../distro-1.5.0-py2.py3-none-any.whl | Bin 0 -> 19426 bytes .../html5lib-1.1-py2.py3-none-any.whl | Bin 0 -> 116071 bytes .../idna-2.10-py2.py3-none-any.whl | Bin 0 -> 63344 bytes .../ipaddr-2.2.0-py2.py3-none-any.whl | Bin 0 -> 19706 bytes .../msgpack-1.0.0-py2.py3-none-any.whl | Bin 0 -> 75866 bytes .../packaging-20.9-py2.py3-none-any.whl | Bin 0 -> 41435 bytes .../pep517-0.9.1-py2.py3-none-any.whl | Bin 0 -> 22249 bytes .../pip-20.3.4-py2.py3-none-any.whl | Bin 0 -> 311123 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 0 -> 122731 bytes .../progress-1.5-py2.py3-none-any.whl | Bin 0 -> 12965 bytes .../pyparsing-2.4.7-py2.py3-none-any.whl | Bin 0 -> 72626 bytes .../requests-2.25.1-py2.py3-none-any.whl | Bin 0 -> 62975 bytes .../resolvelib-0.5.4-py2.py3-none-any.whl | Bin 0 -> 17707 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 0 -> 11776 bytes .../setuptools-44.1.1-py2.py3-none-any.whl | Bin 0 -> 473123 bytes .../six-1.16.0-py2.py3-none-any.whl | Bin 0 -> 15791 bytes .../toml-0.10.1-py2.py3-none-any.whl | Bin 0 -> 21108 bytes .../urllib3-1.26.5-py2.py3-none-any.whl | Bin 0 -> 134200 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 0 -> 15904 bytes .../wheel-0.34.2-py2.py3-none-any.whl | Bin 0 -> 31030 bytes testclient/activate.sh | 4 + testclient/testrobot.py | 25 + 1104 files changed, 166967 insertions(+), 21 deletions(-) create mode 100644 modules/utils/globals.go create mode 100755 public/swagger/favicon-16x16.png create mode 100755 public/swagger/favicon-32x32.png create mode 100755 public/swagger/index.css create mode 100755 public/swagger/index.html create mode 100755 public/swagger/oauth2-redirect.html create mode 100755 public/swagger/swagger-initializer.js create mode 100755 public/swagger/swagger-ui-bundle.js create mode 100755 public/swagger/swagger-ui-bundle.js.map create mode 100755 public/swagger/swagger-ui-es-bundle-core.js create mode 100755 public/swagger/swagger-ui-es-bundle-core.js.map create mode 100755 public/swagger/swagger-ui-es-bundle.js create mode 100755 public/swagger/swagger-ui-es-bundle.js.map create mode 100755 public/swagger/swagger-ui-standalone-preset.js create mode 100755 public/swagger/swagger-ui-standalone-preset.js.map create mode 100755 public/swagger/swagger-ui.css create mode 100755 public/swagger/swagger-ui.css.map create mode 100755 public/swagger/swagger-ui.js create mode 100755 public/swagger/swagger-ui.js.map create mode 100644 public/swagger/swagger.json create mode 100644 routers/api/v1/control/control.go create mode 100644 routers/api/v1/robot/robot.go delete mode 100644 routers/api/v1/robots/robots.go create mode 100755 swagger-gen.sh create mode 100644 testclient/.venv/bin/Activate.ps1 create mode 100644 testclient/.venv/bin/activate create mode 100644 testclient/.venv/bin/activate.csh create mode 100644 testclient/.venv/bin/activate.fish create mode 100755 testclient/.venv/bin/easy_install create mode 100755 testclient/.venv/bin/easy_install-3.9 create mode 100755 testclient/.venv/bin/flask create mode 100755 testclient/.venv/bin/normalizer create mode 100755 testclient/.venv/bin/pip create mode 100755 testclient/.venv/bin/pip3 create mode 100755 testclient/.venv/bin/pip3.9 create mode 120000 testclient/.venv/bin/python create mode 120000 testclient/.venv/bin/python3 create mode 120000 testclient/.venv/bin/python3.9 create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/_saferef.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/_utilities.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/base.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/_saferef.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/_utilities.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/base.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/blinker/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/LICENSE create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/__main__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__main__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/core.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/cacert.pem create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/core.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/certifi/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__main__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__main__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/api.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/cd.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/constant.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/legacy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/md.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/models.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/version.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/api.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cd.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__main__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/constant.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/legacy.py create mode 100755 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.cpython-39-x86_64-linux-gnu.so create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.py create mode 100755 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md__mypyc.cpython-39-x86_64-linux-gnu.so create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/models.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/charset_normalizer/version.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_termui_impl.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_textwrap.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_winconsole.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/decorators.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/termui.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/_compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/_termui_impl.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/_textwrap.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/_winconsole.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/core.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/decorators.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/formatting.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/globals.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/parser.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/shell_completion.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/termui.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/testing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/types.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/click/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/easy_install.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/REQUESTED create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/entry_points.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__main__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__main__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/config.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/ctx.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/logging.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/templating.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/typing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/app.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/blueprints.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/cli.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/config.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/ctx.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/debughelpers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/globals.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/helpers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/provider.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/tag.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/provider.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/json/tag.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/logging.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/README.md create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/app.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/blueprints.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/scaffold.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/app.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/blueprints.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sansio/scaffold.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/sessions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/signals.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/templating.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/testing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/typing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/views.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/flask/wrappers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/LICENSE.md create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/codec.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/core.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/idnadata.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/intranges.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/package_data.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/uts46data.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/codec.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/core.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/idnadata.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/intranges.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/package_data.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/idna/uts46data.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/LICENSE create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_adapters.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_collections.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_functools.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_itertools.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_meta.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_py39compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_text.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_adapters.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_collections.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_functools.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_itertools.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_meta.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_py39compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_text.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/importlib_metadata/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/_json.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/encoding.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/exc.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/serializer.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/signer.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/timed.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/url_safe.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/_json.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/encoding.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/exc.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/serializer.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/signer.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/timed.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/itsdangerous/url_safe.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/_identifier.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/async_utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/bccache.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/compiler.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/constants.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/debug.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/defaults.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/environment.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/ext.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/filters.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/idtracking.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/lexer.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/loaders.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/meta.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nativetypes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nodes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/optimizer.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/parser.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/runtime.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/sandbox.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/tests.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/visitor.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/_identifier.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/async_utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/bccache.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/compiler.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/constants.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/debug.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/defaults.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/environment.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/ext.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/filters.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/idtracking.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/lexer.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/loaders.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/meta.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/nativetypes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/nodes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/optimizer.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/parser.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/runtime.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/sandbox.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/tests.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/jinja2/visitor.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/_native.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/_speedups.c create mode 100755 testclient/.venv/lib/python3.9/site-packages/markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/_speedups.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/markupsafe/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/LICENSE.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/REQUESTED create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/entry_points.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/__main__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/__pycache__/__main__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/cache.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/configuration.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/locations.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/main.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/pyproject.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/build_env.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cache.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/base_command.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/command_context.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/main.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/main_parser.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/parser.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/req_command.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/spinners.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/cli/status_codes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/cache.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/check.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/completion.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/debug.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/download.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/hash.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/help.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/list.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/search.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/show.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/cache.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/check.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/completion.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/configuration.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/debug.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/download.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/freeze.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/hash.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/help.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/install.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/list.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/search.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/show.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/uninstall.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/commands/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/configuration.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/base.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/installed.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/sdist.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/distributions/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/collector.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/index/package_finder.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/locations.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/main.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/candidate.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/format_control.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/link.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/scheme.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/target_python.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/candidate.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/direct_url.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/format_control.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/index.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/link.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/scheme.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/search_scope.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/target_python.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/models/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/auth.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/cache.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/session.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/auth.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/cache.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/download.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/session.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/check.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/check.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/freeze.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/operations/prepare.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/pyproject.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/constructors.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_file.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_install.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/constructors.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/req_file.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/req_install.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/req_set.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/req_tracker.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/base.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/base.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/self_outdated_check.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/logging.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/typing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/urls.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/appdirs.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/datetime.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/deprecation.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/encoding.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/filesystem.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/filetypes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/glibc.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/hashes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/logging.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/misc.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/models.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/packaging.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/parallel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/pkg_resources.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/subprocess.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/typing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/unpacking.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/urls.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/utils/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/git.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/subversion.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_internal/wheel_builder.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_vendor/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pip/_vendor/vendor.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/REQUESTED create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/__pycache__/py31compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/_vendor/six.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/extern/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/pkg_resources/py31compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/LICENSE create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/REQUESTED create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests-2.31.0.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/__version__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/_internal_utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/adapters.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/api.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/auth.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/certs.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/cookies.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/help.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/hooks.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/models.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/packages.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/sessions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/status_codes.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/structures.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/__version__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/_internal_utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/adapters.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/api.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/auth.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/certs.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/cookies.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/help.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/hooks.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/models.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/packages.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/sessions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/status_codes.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/structures.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/requests/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/AUTHORS.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/LICENSE.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/REQUESTED create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/dependency_links.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/entry_points.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/zip-safe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/_imp.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/archive_util.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/build_meta.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/config.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/dep_util.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/depends.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/dist.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/errors.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/extension.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/glob.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/installer.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/launch.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/monkey.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/msvc.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/namespaces.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/package_index.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/py27compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/py31compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/py33compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/py34compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/sandbox.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/site-patch.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/ssl_support.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/unicode_utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/version.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/wheel.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/__pycache__/windows_support.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_deprecation_warning.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_imp.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/six.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/_vendor/six.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/archive_util.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/build_meta.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/cli-32.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/cli-64.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/cli.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/alias.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/build_clib.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/build_ext.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/build_py.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/develop.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/dist_info.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/easy_install.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/egg_info.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/install.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/install_lib.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/install_scripts.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/py36compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/register.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/rotate.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/saveopts.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/sdist.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/setopt.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/test.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/upload.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/__pycache__/upload_docs.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/alias.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/bdist_egg.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/bdist_rpm.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/bdist_wininst.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/build_clib.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/build_ext.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/build_py.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/develop.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/dist_info.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/easy_install.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/egg_info.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/install.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/install_egg_info.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/install_lib.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/install_scripts.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/launcher manifest.xml create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/py36compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/register.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/rotate.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/saveopts.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/sdist.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/setopt.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/test.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/upload.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/command/upload_docs.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/config.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/dep_util.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/depends.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/dist.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/errors.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/extension.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/extern/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/extern/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/glob.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/gui-32.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/gui-64.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/gui.exe create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/installer.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/launch.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/lib2to3_ex.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/monkey.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/msvc.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/namespaces.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/package_index.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/py27compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/py31compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/py33compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/py34compat.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/sandbox.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/script (dev).tmpl create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/script.tmpl create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/site-patch.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/ssl_support.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/unicode_utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/version.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/wheel.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/setuptools/windows_support.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3-2.0.6.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3-2.0.6.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3-2.0.6.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3-2.0.6.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3-2.0.6.dist-info/licenses/LICENSE.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/_base_connection.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/_collections.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/_request_methods.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/_version.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/connection.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/connectionpool.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/fields.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/filepost.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/poolmanager.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/__pycache__/response.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/_base_connection.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/_collections.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/_request_methods.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/_version.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/connection.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/connectionpool.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/__pycache__/pyopenssl.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/__pycache__/securetransport.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/__pycache__/socks.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/bindings.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/_securetransport/low_level.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/pyopenssl.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/securetransport.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/contrib/socks.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/fields.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/filepost.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/poolmanager.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/response.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/connection.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/proxy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/request.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/response.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/retry.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/ssl_.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/ssltransport.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/timeout.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/url.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/util.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/__pycache__/wait.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/connection.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/proxy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/request.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/response.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/retry.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/ssl_.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/ssl_match_hostname.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/ssltransport.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/timeout.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/url.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/util.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/urllib3/util/wait.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug-3.0.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug-3.0.0.dist-info/LICENSE.rst create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug-3.0.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug-3.0.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug-3.0.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/_internal.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/_reloader.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/formparser.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/http.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/local.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/security.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/serving.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/test.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/testapp.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/urls.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/user_agent.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/__pycache__/wsgi.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/_internal.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/_reloader.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/range.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/accept.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/accept.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/auth.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/cache_control.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/csp.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/csp.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/etag.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/etag.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/file_storage.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/headers.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/headers.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/mixins.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/mixins.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/range.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/range.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/structures.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/datastructures/structures.pyi create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/console.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/repr.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/console.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/repr.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/console.png create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/less.png create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/more.png create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/shared/style.css create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/debug/tbtools.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/formparser.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/http.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/local.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/lint.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/lint.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/profiler.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/py.typed create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/converters.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/map.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/matcher.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/__pycache__/rules.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/converters.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/exceptions.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/map.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/matcher.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/routing/rules.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/http.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/response.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/utils.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/http.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/multipart.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/request.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/response.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/sansio/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/security.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/serving.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/test.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/testapp.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/urls.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/user_agent.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/utils.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/request.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wrappers/response.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/werkzeug/wsgi.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/INSTALLER create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/LICENSE create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/METADATA create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/RECORD create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/WHEEL create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp-3.17.0.dist-info/top_level.txt create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/__init__.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/__pycache__/__init__.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/__pycache__/glob.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/__pycache__/py310compat.cpython-39.pyc create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/glob.py create mode 100644 testclient/.venv/lib/python3.9/site-packages/zipp/py310compat.py create mode 120000 testclient/.venv/lib64 create mode 100644 testclient/.venv/pyvenv.cfg create mode 100644 testclient/.venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/certifi-2020.6.20-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/chardet-4.0.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/colorama-0.4.4-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/contextlib2-0.6.0.post1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/distlib-0.3.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/distro-1.5.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/html5lib-1.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/idna-2.10-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/msgpack-1.0.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/packaging-20.9-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/pep517-0.9.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/pip-20.3.4-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/progress-1.5-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/requests-2.25.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/resolvelib-0.5.4-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/setuptools-44.1.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/six-1.16.0-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/urllib3-1.26.5-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl create mode 100644 testclient/.venv/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl create mode 100644 testclient/activate.sh create mode 100644 testclient/testrobot.py diff --git a/main.go b/main.go index 124e8fc..b705d09 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,17 @@ +// Package classification JNX Robot Control Manager API Documentation. +// +// Schemes: https +// Host: jannex +// BasePath: /v1 +// Version: 1.0.0 +// +// Consumes: +// - application/json +// +// Produces: +// - application/json +// +// swagger:meta package main import ( diff --git a/modules/structs/robot.go b/modules/structs/robot.go index 63c0dc6..72f18cd 100644 --- a/modules/structs/robot.go +++ b/modules/structs/robot.go @@ -13,6 +13,7 @@ type Robot struct { ConnectedAt time.Time } +// swagger:model FirstRequestBody type FirstRequestBody struct { // robot id Id string @@ -21,3 +22,8 @@ type FirstRequestBody struct { // connected modul like a gripper //ConnectedModul uint8 } + +// swagger:model StatusResponse +type StatusResponse struct { + Status string +} diff --git a/modules/utils/globals.go b/modules/utils/globals.go new file mode 100644 index 0000000..1dd6b64 --- /dev/null +++ b/modules/utils/globals.go @@ -0,0 +1,8 @@ +package utils + +const ( + RobotStatusIdle uint8 = iota + RobotStatusRunning + RobotStatusError + RobotStatusOffline +) diff --git a/public/swagger/favicon-16x16.png b/public/swagger/favicon-16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..8b194e617af1c135e6b37939591d24ac3a5efa18 GIT binary patch literal 665 zcmV;K0%rY*P)}JKSduyL>)s!A4EhTMMEM%Q;aL6%l#xiZiF>S;#Y{N2Zz%pvTGHJduXuC6Lx-)0EGfRy*N{Tv4i8@4oJ41gw zKzThrcRe|7J~(YYIBq{SYCkn-KQm=N8$CrEK1CcqMI1dv9z#VRL_{D)L|`QmF8}}l zJ9JV`Q}p!p_4f7m_U`WQ@apR4;o;!mnU<7}iG_qr zF(e)x9~BG-3IzcG2M4an0002kNkl41`ZiN1i62V%{PM@Ry|IS_+Yc7{bb`MM~xm(7p4|kMHP&!VGuDW4kFixat zXw43VmgwEvB$hXt_u=vZ>+v4i7E}n~eG6;n4Z=zF1n?T*yg<;W6kOfxpC6nao>VR% z?fpr=asSJ&`L*wu^rLJ5Peq*PB0;alL#XazZCBxJLd&giTfw@!hW167F^`7kobi;( ze<<>qNlP|xy7S1zl@lZNIBR7#o9ybJsptO#%}P0hz~sBp00000NkvXXu0mjfUsDF? literal 0 HcmV?d00001 diff --git a/public/swagger/favicon-32x32.png b/public/swagger/favicon-32x32.png new file mode 100755 index 0000000000000000000000000000000000000000..249737fe44558e679f0b67134e274461d988fa98 GIT binary patch literal 628 zcmV-)0*n2LP)Ma*GM0}OV<074bNCP7P7GVd{iMr*I6y~TMLss@FjvgL~HxU z%Vvj33AwpD(Z4*$Mfx=HaU16axM zt2xG_rloN<$iy9j9I5 + + + + + Swagger UI + + + + + + + +
+ + + + + diff --git a/public/swagger/oauth2-redirect.html b/public/swagger/oauth2-redirect.html new file mode 100755 index 0000000..5640917 --- /dev/null +++ b/public/swagger/oauth2-redirect.html @@ -0,0 +1,79 @@ + + + + Swagger UI: OAuth2 Redirect + + + + + diff --git a/public/swagger/swagger-initializer.js b/public/swagger/swagger-initializer.js new file mode 100755 index 0000000..99397cd --- /dev/null +++ b/public/swagger/swagger-initializer.js @@ -0,0 +1,11 @@ +window.onload = function() { + window.ui = SwaggerUIBundle({ + url: 'swagger.json', + dom_id: '#swagger-ui', + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + layout: "StandaloneLayout", + }); +} \ No newline at end of file diff --git a/public/swagger/swagger-ui-bundle.js b/public/swagger/swagger-ui-bundle.js new file mode 100755 index 0000000..f646cb2 --- /dev/null +++ b/public/swagger/swagger-ui-bundle.js @@ -0,0 +1,3 @@ +/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}(this,(function(){return(()=>{var e={17967:(e,t)=>{"use strict";t.N=void 0;var r=/^([^\w]*)(javascript|data|vbscript)/im,n=/&#(\w+)(^\w|;)?/g,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^([^:]+):/gm,i=[".","/"];t.N=function(e){var t,s=(t=e||"",t.replace(n,(function(e,t){return String.fromCharCode(t)}))).replace(o,"").trim();if(!s)return"about:blank";if(function(e){return i.indexOf(e[0])>-1}(s))return s;var l=s.match(a);if(!l)return s;var u=l[0];return r.test(u)?"about:blank":s}},53795:(e,t,r)=>{"use strict";r.d(t,{Z:()=>P});var n=r(23101),o=r.n(n),a=r(61125),i=r.n(a),s=r(11882),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294),f=r(43393);function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function m(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=k(t,r),o=e||Object.keys(y({},r,{},t));return o.every(n)}function k(e,t){return function(r){if("string"==typeof r)return(0,f.is)(t[r],e[r]);if(Array.isArray(r))return(0,f.is)(S(t,r),S(e,r));throw new TypeError("Invalid key: expected Array or string: "+r)}}var C=function(e){function t(){return d(this,t),E(this,b(t).apply(this,arguments))}var r,n,o;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(t,e),r=t,n=[{key:"shouldComponentUpdate",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return!A(this.updateOnProps,this.props,e,"updateOnProps")||!A(this.updateOnStates,this.state,t,"updateOnStates")}}],n&&m(r.prototype,n),o&&m(r,o),t}(p.Component);const O=C;var j=r(23930),I=r.n(j),N=r(45697),T=r.n(N);class P extends O{constructor(){super(...arguments),i()(this,"getModelName",(e=>-1!==l()(e).call(e,"#/definitions/")?e.replace(/^.*#\/definitions\//,""):-1!==l()(e).call(e,"#/components/schemas/")?e.replace(/^.*#\/components\/schemas\//,""):void 0)),i()(this,"getRefSchema",(e=>{let{specSelectors:t}=this.props;return t.findDefinition(e)}))}render(){let{getComponent:e,getConfigs:t,specSelectors:n,schema:a,required:i,name:s,isRef:l,specPath:u,displayName:c,includeReadOnly:f,includeWriteOnly:h}=this.props;const d=e("ObjectModel"),m=e("ArrayModel"),g=e("PrimitiveModel");let v="object",y=a&&a.get("$$ref");if(!s&&y&&(s=this.getModelName(y)),!a&&y&&(a=this.getRefSchema(s)),!a)return p.createElement("span",{className:"model model-title"},p.createElement("span",{className:"model-title__text"},c||s),p.createElement("img",{src:r(2517),height:"20px",width:"20px"}));const b=n.isOAS3()&&a.get("deprecated");switch(l=void 0!==l?l:!!y,v=a&&a.get("type")||v,v){case"object":return p.createElement(d,o()({className:"object"},this.props,{specPath:u,getConfigs:t,schema:a,name:s,deprecated:b,isRef:l,includeReadOnly:f,includeWriteOnly:h}));case"array":return p.createElement(m,o()({className:"array"},this.props,{getConfigs:t,schema:a,name:s,deprecated:b,required:i,includeReadOnly:f,includeWriteOnly:h}));default:return p.createElement(g,o()({},this.props,{getComponent:e,getConfigs:t,schema:a,name:s,deprecated:b,required:i}))}}}i()(P,"propTypes",{schema:c()(I()).isRequired,getComponent:T().func.isRequired,getConfigs:T().func.isRequired,specSelectors:T().object.isRequired,name:T().string,displayName:T().string,isRef:T().bool,required:T().bool,expandDepth:T().number,depth:T().number,specPath:I().list.isRequired,includeReadOnly:T().bool,includeWriteOnly:T().bool})},5623:(e,t,r)=>{"use strict";r.d(t,{Z:()=>f});var n=r(61125),o=r.n(n),a=r(28222),i=r.n(a),s=r(67294),l=r(84564),u=r.n(l),c=r(90242),p=r(27504);class f extends s.Component{constructor(e,t){super(e,t),o()(this,"getDefinitionUrl",(()=>{let{specSelectors:e}=this.props;return new(u())(e.url(),p.Z.location).toString()}));let{getConfigs:r}=e,{validatorUrl:n}=r();this.state={url:this.getDefinitionUrl(),validatorUrl:void 0===n?"https://validator.swagger.io/validator":n}}UNSAFE_componentWillReceiveProps(e){let{getConfigs:t}=e,{validatorUrl:r}=t();this.setState({url:this.getDefinitionUrl(),validatorUrl:void 0===r?"https://validator.swagger.io/validator":r})}render(){let{getConfigs:e}=this.props,{spec:t}=e(),r=(0,c.Nm)(this.state.validatorUrl);return"object"==typeof t&&i()(t).length?null:this.state.url&&(0,c.hW)(this.state.validatorUrl)&&(0,c.hW)(this.state.url)?s.createElement("span",{className:"float-right"},s.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:`${r}/debug?url=${encodeURIComponent(this.state.url)}`},s.createElement(h,{src:`${r}?url=${encodeURIComponent(this.state.url)}`,alt:"Online validator badge"}))):null}}class h extends s.Component{constructor(e){super(e),this.state={loaded:!1,error:!1}}componentDidMount(){const e=new Image;e.onload=()=>{this.setState({loaded:!0})},e.onerror=()=>{this.setState({error:!0})},e.src=this.props.src}UNSAFE_componentWillReceiveProps(e){if(e.src!==this.props.src){const t=new Image;t.onload=()=>{this.setState({loaded:!0})},t.onerror=()=>{this.setState({error:!0})},t.src=e.src}}render(){return this.state.error?s.createElement("img",{alt:"Error"}):this.state.loaded?s.createElement("img",{src:this.props.src,alt:this.props.alt}):null}}},86019:(e,t,r)=>{"use strict";r.d(t,{Z:()=>me,s:()=>ge});var n=r(67294),o=r(89927);function a(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,n=e.length;r=0;r--)!0===t(e[r])&&e.splice(r,1)}function s(e){throw new Error("Unhandled case for value: '"+e+"'")}var l=function(){function e(e){void 0===e&&(e={}),this.tagName="",this.attrs={},this.innerHTML="",this.whitespaceRegex=/\s+/,this.tagName=e.tagName||"",this.attrs=e.attrs||{},this.innerHTML=e.innerHtml||e.innerHTML||""}return e.prototype.setTagName=function(e){return this.tagName=e,this},e.prototype.getTagName=function(){return this.tagName||""},e.prototype.setAttr=function(e,t){return this.getAttrs()[e]=t,this},e.prototype.getAttr=function(e){return this.getAttrs()[e]},e.prototype.setAttrs=function(e){return Object.assign(this.getAttrs(),e),this},e.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},e.prototype.setClass=function(e){return this.setAttr("class",e)},e.prototype.addClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],i=e.split(n);t=i.shift();)-1===a(o,t)&&o.push(t);return this.getAttrs().class=o.join(" "),this},e.prototype.removeClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],i=e.split(n);o.length&&(t=i.shift());){var s=a(o,t);-1!==s&&o.splice(s,1)}return this.getAttrs().class=o.join(" "),this},e.prototype.getClass=function(){return this.getAttrs().class||""},e.prototype.hasClass=function(e){return-1!==(" "+this.getClass()+" ").indexOf(" "+e+" ")},e.prototype.setInnerHTML=function(e){return this.innerHTML=e,this},e.prototype.setInnerHtml=function(e){return this.setInnerHTML(e)},e.prototype.getInnerHTML=function(){return this.innerHTML||""},e.prototype.getInnerHtml=function(){return this.getInnerHTML()},e.prototype.toAnchorString=function(){var e=this.getTagName(),t=this.buildAttrsStr();return["<",e,t=t?" "+t:"",">",this.getInnerHtml(),""].join("")},e.prototype.buildAttrsStr=function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")},e}();var u=function(){function e(e){void 0===e&&(e={}),this.newWindow=!1,this.truncate={},this.className="",this.newWindow=e.newWindow||!1,this.truncate=e.truncate||{},this.className=e.className||""}return e.prototype.build=function(e){return new l({tagName:"a",attrs:this.createAttrs(e),innerHtml:this.processAnchorText(e.getAnchorText())})},e.prototype.createAttrs=function(e){var t={href:e.getAnchorHref()},r=this.createCssClass(e);return r&&(t.class=r),this.newWindow&&(t.target="_blank",t.rel="noopener noreferrer"),this.truncate&&this.truncate.length&&this.truncate.length=s)return l.host.length==t?(l.host.substr(0,t-o)+r).substr(0,s+n):i(c,s).substr(0,s+n);var p="";if(l.path&&(p+="/"+l.path),l.query&&(p+="?"+l.query),p){if((c+p).length>=s)return(c+p).length==t?(c+p).substr(0,t):(c+i(p,s-c.length)).substr(0,s+n);c+=p}if(l.fragment){var f="#"+l.fragment;if((c+f).length>=s)return(c+f).length==t?(c+f).substr(0,t):(c+i(f,s-c.length)).substr(0,s+n);c+=f}if(l.scheme&&l.host){var h=l.scheme+"://";if((c+h).length0&&(d=c.substr(-1*Math.floor(s/2))),(c.substr(0,Math.ceil(s/2))+r+d).substr(0,s+n)}(e,r):"middle"===n?function(e,t,r){if(e.length<=t)return e;var n,o;null==r?(r="…",n=8,o=3):(n=r.length,o=r.length);var a=t-o,i="";return a>0&&(i=e.substr(-1*Math.floor(a/2))),(e.substr(0,Math.ceil(a/2))+r+i).substr(0,a+n)}(e,r):function(e,t,r){return function(e,t,r){var n;return e.length>t&&(null==r?(r="…",n=3):n=r.length,e=e.substring(0,t-n)+r),e}(e,t,r)}(e,r)},e}(),c=function(){function e(e){this.__jsduckDummyDocProp=null,this.matchedText="",this.offset=0,this.tagBuilder=e.tagBuilder,this.matchedText=e.matchedText,this.offset=e.offset}return e.prototype.getMatchedText=function(){return this.matchedText},e.prototype.setOffset=function(e){this.offset=e},e.prototype.getOffset=function(){return this.offset},e.prototype.getCssClassSuffixes=function(){return[this.getType()]},e.prototype.buildTag=function(){return this.tagBuilder.build(this)},e}(),p=function(e,t){return p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])},p(e,t)};function f(e,t){function r(){this.constructor=e}p(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var h=function(){return h=Object.assign||function(e){for(var t,r=1,n=arguments.length;r-1},e.isValidUriScheme=function(e){var t=e.match(this.uriSchemeRegex),r=t&&t[0].toLowerCase();return"javascript:"!==r&&"vbscript:"!==r},e.urlMatchDoesNotHaveProtocolOrDot=function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},e.urlMatchDoesNotHaveAtLeastOneWordChar=function(e,t){return!(!e||!t)&&(!this.hasFullProtocolRegex.test(t)&&!this.hasWordCharAfterProtocolRegex.test(e))},e.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\/\//,e.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,e.hasWordCharAfterProtocolRegex=new RegExp(":[^\\s]*?["+C+"]"),e.ipRegex=/[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/,e}(),V=(d=new RegExp("[/?#](?:["+N+"\\-+&@#/%=~_()|'$*\\[\\]{}?!:,.;^✓]*["+N+"\\-+&@#/%=~_()|'$*\\[\\]{}✓])?"),new RegExp(["(?:","(",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/.source,M(2),")","|","(","(//)?",/(?:www\.)/.source,M(6),")","|","(","(//)?",M(10)+"\\.",L.source,"(?![-"+I+"])",")",")","(?::[0-9]+)?","(?:"+d.source+")?"].join(""),"gi")),$=new RegExp("["+N+"]"),W=function(e){function t(t){var r=e.call(this,t)||this;return r.stripPrefix={scheme:!0,www:!0},r.stripTrailingSlash=!0,r.decodePercentEncoding=!0,r.matcherRegex=V,r.wordCharRegExp=$,r.stripPrefix=t.stripPrefix,r.stripTrailingSlash=t.stripTrailingSlash,r.decodePercentEncoding=t.decodePercentEncoding,r}return f(t,e),t.prototype.parseMatches=function(e){for(var t,r=this.matcherRegex,n=this.stripPrefix,o=this.stripTrailingSlash,a=this.decodePercentEncoding,i=this.tagBuilder,s=[],l=function(){var r=t[0],l=t[1],c=t[4],p=t[5],f=t[9],h=t.index,d=p||f,m=e.charAt(h-1);if(!q.isValid(r,l))return"continue";if(h>0&&"@"===m)return"continue";if(h>0&&d&&u.wordCharRegExp.test(m))return"continue";if(/\?$/.test(r)&&(r=r.substr(0,r.length-1)),u.matchHasUnbalancedClosingParen(r))r=r.substr(0,r.length-1);else{var g=u.matchHasInvalidCharAfterTld(r,l);g>-1&&(r=r.substr(0,g))}var v=["http://","https://"].find((function(e){return!!l&&-1!==l.indexOf(e)}));if(v){var y=r.indexOf(v);r=r.substr(y),l=l.substr(y),h+=y}var w=l?"scheme":c?"www":"tld",E=!!l;s.push(new b({tagBuilder:i,matchedText:r,offset:h,urlMatchType:w,url:r,protocolUrlMatch:E,protocolRelativeMatch:!!d,stripPrefix:n,stripTrailingSlash:o,decodePercentEncoding:a}))},u=this;null!==(t=r.exec(e));)l();return s},t.prototype.matchHasUnbalancedClosingParen=function(e){var t,r=e.charAt(e.length-1);if(")"===r)t="(";else if("]"===r)t="[";else{if("}"!==r)return!1;t="{"}for(var n=0,o=0,a=e.length-1;o"===e?(m=new ne(h(h({},m),{name:H()})),W()):E.test(e)||x.test(e)||":"===e||V()}function w(e){">"===e?V():E.test(e)?f=3:V()}function _(e){S.test(e)||("/"===e?f=12:">"===e?W():"<"===e?$():"="===e||A.test(e)||k.test(e)?V():f=5)}function C(e){S.test(e)?f=6:"/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?$():A.test(e)&&V()}function O(e){S.test(e)||("/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?$():A.test(e)?V():f=5)}function j(e){S.test(e)||('"'===e?f=8:"'"===e?f=9:/[>=`]/.test(e)?V():"<"===e?$():f=10)}function I(e){'"'===e&&(f=11)}function N(e){"'"===e&&(f=11)}function T(e){S.test(e)?f=4:">"===e?W():"<"===e&&$()}function P(e){S.test(e)?f=4:"/"===e?f=12:">"===e?W():"<"===e?$():(f=4,c--)}function R(e){">"===e?(m=new ne(h(h({},m),{isClosing:!0})),W()):f=4}function M(t){"--"===e.substr(c,2)?(c+=2,m=new ne(h(h({},m),{type:"comment"})),f=14):"DOCTYPE"===e.substr(c,7).toUpperCase()?(c+=7,m=new ne(h(h({},m),{type:"doctype"})),f=20):V()}function D(e){"-"===e?f=15:">"===e?V():f=16}function L(e){"-"===e?f=18:">"===e?V():f=16}function B(e){"-"===e&&(f=17)}function F(e){f="-"===e?18:16}function z(e){">"===e?W():"!"===e?f=19:"-"===e||(f=16)}function U(e){"-"===e?f=17:">"===e?W():f=16}function q(e){">"===e?W():"<"===e&&$()}function V(){f=0,m=u}function $(){f=1,m=new ne({idx:c})}function W(){var t=e.slice(d,m.idx);t&&a(t,d),"comment"===m.type?i(m.idx):"doctype"===m.type?l(m.idx):(m.isOpening&&n(m.name,m.idx),m.isClosing&&o(m.name,m.idx)),V(),d=c+1}function H(){var t=m.idx+(m.isClosing?2:1);return e.slice(t,c).toLowerCase()}d=0&&n++},onText:function(e,r){if(0===n){var a=function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var r,n=[],o=0;r=t.exec(e);)n.push(e.substring(o,r.index)),n.push(r[0]),o=r.index+r[0].length;return n.push(e.substring(o)),n}(e,/( | |<|<|>|>|"|"|')/gi),i=r;a.forEach((function(e,r){if(r%2==0){var n=t.parseText(e,i);o.push.apply(o,n)}i+=e.length}))}},onCloseTag:function(e){r.indexOf(e)>=0&&(n=Math.max(n-1,0))},onComment:function(e){},onDoctype:function(e){}}),o=this.compactMatches(o),o=this.removeUnwantedMatches(o)},e.prototype.compactMatches=function(e){e.sort((function(e,t){return e.getOffset()-t.getOffset()}));for(var t=0;to?t:t+1;e.splice(i,1);continue}e[t+1].getOffset()/g,">"));for(var t=this.parse(e),r=[],n=0,o=0,a=t.length;o/i.test(e)}function se(){var e=[],t=new oe({stripPrefix:!1,url:!0,email:!0,replaceFn:function(t){switch(t.getType()){case"url":e.push({text:t.matchedText,url:t.getUrl()});break;case"email":e.push({text:t.matchedText,url:"mailto:"+t.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:e,autolinker:t}}function le(e){var t,r,n,o,a,i,s,l,u,c,p,f,h,d,m=e.tokens,g=null;for(r=0,n=m.length;r=0;t--)if("link_close"!==(a=o[t]).type){if("htmltag"===a.type&&(d=a.content,/^\s]/i.test(d)&&p>0&&p--,ie(a.content)&&p++),!(p>0)&&"text"===a.type&&ae.test(a.content)){if(g||(f=(g=se()).links,h=g.autolinker),i=a.content,f.length=0,h.link(i),!f.length)continue;for(s=[],c=a.level,l=0;l({useUnsafeMarkdown:!1})};const me=de;function ge(e){let{useUnsafeMarkdown:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=t,n=t?[]:["style","class"];return t&&!ge.hasWarnedAboutDeprecation&&(console.warn("useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0."),ge.hasWarnedAboutDeprecation=!0),pe().sanitize(e,{ADD_ATTR:["target"],FORBID_TAGS:["style","form"],ALLOW_DATA_ATTR:r,FORBID_ATTR:n})}ge.hasWarnedAboutDeprecation=!1},45308:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>f});var n,o=r(86),a=r.n(o),i=r(8712),s=r.n(i),l=r(90242),u=r(27621);const c=r(95102),p={},f=p;a()(n=s()(c).call(c)).call(n,(function(e){if("./index.js"===e)return;let t=c(e);p[(0,l.Zl)(e)]=t.default?t.default:t})),p.SafeRender=u.default},55812:(e,t,r)=>{"use strict";r.r(t),r.d(t,{SHOW_AUTH_POPUP:()=>p,AUTHORIZE:()=>f,LOGOUT:()=>h,PRE_AUTHORIZE_OAUTH2:()=>d,AUTHORIZE_OAUTH2:()=>m,VALIDATE:()=>g,CONFIGURE_AUTH:()=>v,RESTORE_AUTHORIZATION:()=>y,showDefinitions:()=>b,authorize:()=>w,authorizeWithPersistOption:()=>E,logout:()=>x,logoutWithPersistOption:()=>_,preAuthorizeImplicit:()=>S,authorizeOauth2:()=>A,authorizeOauth2WithPersistOption:()=>k,authorizePassword:()=>C,authorizeApplication:()=>O,authorizeAccessCodeWithFormParams:()=>j,authorizeAccessCodeWithBasicAuthentication:()=>I,authorizeRequest:()=>N,configureAuth:()=>T,restoreAuthorization:()=>P,persistAuthorizationIfNeeded:()=>R,authPopup:()=>M});var n=r(35627),o=r.n(n),a=r(76986),i=r.n(a),s=r(84564),l=r.n(s),u=r(27504),c=r(90242);const p="show_popup",f="authorize",h="logout",d="pre_authorize_oauth2",m="authorize_oauth2",g="validate",v="configure_auth",y="restore_authorization";function b(e){return{type:p,payload:e}}function w(e){return{type:f,payload:e}}const E=e=>t=>{let{authActions:r}=t;r.authorize(e),r.persistAuthorizationIfNeeded()};function x(e){return{type:h,payload:e}}const _=e=>t=>{let{authActions:r}=t;r.logout(e),r.persistAuthorizationIfNeeded()},S=e=>t=>{let{authActions:r,errActions:n}=t,{auth:a,token:i,isValid:s}=e,{schema:l,name:c}=a,p=l.get("flow");delete u.Z.swaggerUIRedirectOauth2,"accessCode"===p||s||n.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),i.error?n.newAuthErr({authId:c,source:"auth",level:"error",message:o()(i)}):r.authorizeOauth2WithPersistOption({auth:a,token:i})};function A(e){return{type:m,payload:e}}const k=e=>t=>{let{authActions:r}=t;r.authorizeOauth2(e),r.persistAuthorizationIfNeeded()},C=e=>t=>{let{authActions:r}=t,{schema:n,name:o,username:a,password:s,passwordType:l,clientId:u,clientSecret:p}=e,f={grant_type:"password",scope:e.scopes.join(" "),username:a,password:s},h={};switch(l){case"request-body":!function(e,t,r){t&&i()(e,{client_id:t});r&&i()(e,{client_secret:r})}(f,u,p);break;case"basic":h.Authorization="Basic "+(0,c.r3)(u+":"+p);break;default:console.warn(`Warning: invalid passwordType ${l} was passed, not including client id and secret`)}return r.authorizeRequest({body:(0,c.GZ)(f),url:n.get("tokenUrl"),name:o,headers:h,query:{},auth:e})};const O=e=>t=>{let{authActions:r}=t,{schema:n,scopes:o,name:a,clientId:i,clientSecret:s}=e,l={Authorization:"Basic "+(0,c.r3)(i+":"+s)},u={grant_type:"client_credentials",scope:o.join(" ")};return r.authorizeRequest({body:(0,c.GZ)(u),name:a,url:n.get("tokenUrl"),auth:e,headers:l})},j=e=>{let{auth:t,redirectUrl:r}=e;return e=>{let{authActions:n}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={grant_type:"authorization_code",code:t.code,client_id:i,client_secret:s,redirect_uri:r,code_verifier:l};return n.authorizeRequest({body:(0,c.GZ)(u),name:a,url:o.get("tokenUrl"),auth:t})}},I=e=>{let{auth:t,redirectUrl:r}=e;return e=>{let{authActions:n}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={Authorization:"Basic "+(0,c.r3)(i+":"+s)},p={grant_type:"authorization_code",code:t.code,client_id:i,redirect_uri:r,code_verifier:l};return n.authorizeRequest({body:(0,c.GZ)(p),name:a,url:o.get("tokenUrl"),auth:t,headers:u})}},N=e=>t=>{let r,{fn:n,getConfigs:a,authActions:s,errActions:u,oas3Selectors:c,specSelectors:p,authSelectors:f}=t,{body:h,query:d={},headers:m={},name:g,url:v,auth:y}=e,{additionalQueryStringParams:b}=f.getConfigs()||{};if(p.isOAS3()){let e=c.serverEffectiveValue(c.selectedServer());r=l()(v,e,!0)}else r=l()(v,p.url(),!0);"object"==typeof b&&(r.query=i()({},r.query,b));const w=r.toString();let E=i()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},m);n.fetch({url:w,method:"post",headers:E,query:d,body:h,requestInterceptor:a().requestInterceptor,responseInterceptor:a().responseInterceptor}).then((function(e){let t=JSON.parse(e.data),r=t&&(t.error||""),n=t&&(t.parseError||"");e.ok?r||n?u.newAuthErr({authId:g,level:"error",source:"auth",message:o()(t)}):s.authorizeOauth2WithPersistOption({auth:y,token:t}):u.newAuthErr({authId:g,level:"error",source:"auth",message:e.statusText})})).catch((e=>{let t=new Error(e).message;if(e.response&&e.response.data){const r=e.response.data;try{const e="string"==typeof r?JSON.parse(r):r;e.error&&(t+=`, error: ${e.error}`),e.error_description&&(t+=`, description: ${e.error_description}`)}catch(e){}}u.newAuthErr({authId:g,level:"error",source:"auth",message:t})}))};function T(e){return{type:v,payload:e}}function P(e){return{type:y,payload:e}}const R=()=>e=>{let{authSelectors:t,getConfigs:r}=e;if(r().persistAuthorization){const e=t.authorized();localStorage.setItem("authorized",o()(e.toJS()))}},M=(e,t)=>()=>{u.Z.swaggerUIRedirectOauth2=t,u.Z.open(e)}},93705:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u,preauthorizeBasic:()=>c,preauthorizeApiKey:()=>p});var n=r(11189),o=r.n(n),a=r(43962),i=r(55812),s=r(60035),l=r(48302);function u(){return{afterLoad(e){this.rootInjects=this.rootInjects||{},this.rootInjects.initOAuth=e.authActions.configureAuth,this.rootInjects.preauthorizeApiKey=o()(p).call(p,null,e),this.rootInjects.preauthorizeBasic=o()(c).call(c,null,e)},statePlugins:{auth:{reducers:a.default,actions:i,selectors:s},spec:{wrapActions:l}}}}function c(e,t,r,n){const{authActions:{authorize:o},specSelectors:{specJson:a,isOAS3:i}}=e,s=i()?["components","securitySchemes"]:["securityDefinitions"],l=a().getIn([...s,t]);return l?o({[t]:{value:{username:r,password:n},schema:l.toJS()}}):null}function p(e,t,r){const{authActions:{authorize:n},specSelectors:{specJson:o,isOAS3:a}}=e,i=a()?["components","securitySchemes"]:["securityDefinitions"],s=o().getIn([...i,t]);return s?n({[t]:{value:r,schema:s.toJS()}}):null}},43962:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(86),o=r.n(n),a=r(76986),i=r.n(a),s=r(43393),l=r(90242),u=r(55812);const c={[u.SHOW_AUTH_POPUP]:(e,t)=>{let{payload:r}=t;return e.set("showDefinitions",r)},[u.AUTHORIZE]:(e,t)=>{var r;let{payload:n}=t,a=(0,s.fromJS)(n),i=e.get("authorized")||(0,s.Map)();return o()(r=a.entrySeq()).call(r,(t=>{let[r,n]=t;if(!(0,l.Wl)(n.getIn))return e.set("authorized",i);let o=n.getIn(["schema","type"]);if("apiKey"===o||"http"===o)i=i.set(r,n);else if("basic"===o){let e=n.getIn(["value","username"]),t=n.getIn(["value","password"]);i=i.setIn([r,"value"],{username:e,header:"Basic "+(0,l.r3)(e+":"+t)}),i=i.setIn([r,"schema"],n.get("schema"))}})),e.set("authorized",i)},[u.AUTHORIZE_OAUTH2]:(e,t)=>{let r,{payload:n}=t,{auth:o,token:a}=n;o.token=i()({},a),r=(0,s.fromJS)(o);let l=e.get("authorized")||(0,s.Map)();return l=l.set(r.get("name"),r),e.set("authorized",l)},[u.LOGOUT]:(e,t)=>{let{payload:r}=t,n=e.get("authorized").withMutations((e=>{o()(r).call(r,(t=>{e.delete(t)}))}));return e.set("authorized",n)},[u.CONFIGURE_AUTH]:(e,t)=>{let{payload:r}=t;return e.set("configs",r)},[u.RESTORE_AUTHORIZATION]:(e,t)=>{let{payload:r}=t;return e.set("authorized",(0,s.fromJS)(r.authorized))}}},60035:(e,t,r)=>{"use strict";r.r(t),r.d(t,{shownDefinitions:()=>y,definitionsToAuthorize:()=>b,getDefinitionsByNames:()=>w,definitionsForRequirements:()=>E,authorized:()=>x,isAuthorized:()=>_,getConfigs:()=>S});var n=r(86),o=r.n(n),a=r(51679),i=r.n(a),s=r(14418),l=r.n(s),u=r(11882),c=r.n(u),p=r(97606),f=r.n(p),h=r(28222),d=r.n(h),m=r(20573),g=r(43393);const v=e=>e,y=(0,m.P1)(v,(e=>e.get("showDefinitions"))),b=(0,m.P1)(v,(()=>e=>{var t;let{specSelectors:r}=e,n=r.securityDefinitions()||(0,g.Map)({}),a=(0,g.List)();return o()(t=n.entrySeq()).call(t,(e=>{let[t,r]=e,n=(0,g.Map)();n=n.set(t,r),a=a.push(n)})),a})),w=(e,t)=>e=>{var r;let{specSelectors:n}=e;console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.");let a=n.securityDefinitions(),i=(0,g.List)();return o()(r=t.valueSeq()).call(r,(e=>{var t;let r=(0,g.Map)();o()(t=e.entrySeq()).call(t,(e=>{let t,[n,i]=e,s=a.get(n);var l;"oauth2"===s.get("type")&&i.size&&(t=s.get("scopes"),o()(l=t.keySeq()).call(l,(e=>{i.contains(e)||(t=t.delete(e))})),s=s.set("allowedScopes",t));r=r.set(n,s)})),i=i.push(r)})),i},E=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,g.List)();return e=>{let{authSelectors:r}=e;const n=r.definitionsToAuthorize()||(0,g.List)();let a=(0,g.List)();return o()(n).call(n,(e=>{let r=i()(t).call(t,(t=>t.get(e.keySeq().first())));r&&(o()(e).call(e,((t,n)=>{if("oauth2"===t.get("type")){const i=r.get(n);let s=t.get("scopes");var a;if(g.List.isList(i)&&g.Map.isMap(s))o()(a=s.keySeq()).call(a,(e=>{i.contains(e)||(s=s.delete(e))})),e=e.set(n,t.set("scopes",s))}})),a=a.push(e))})),a}},x=(0,m.P1)(v,(e=>e.get("authorized")||(0,g.Map)())),_=(e,t)=>e=>{var r;let{authSelectors:n}=e,o=n.authorized();return g.List.isList(t)?!!l()(r=t.toJS()).call(r,(e=>{var t,r;return-1===c()(t=f()(r=d()(e)).call(r,(e=>!!o.get(e)))).call(t,!1)})).length:null},S=(0,m.P1)(v,(e=>e.get("configs")))},48302:(e,t,r)=>{"use strict";r.r(t),r.d(t,{execute:()=>n});const n=(e,t)=>{let{authSelectors:r,specSelectors:n}=t;return t=>{let{path:o,method:a,operation:i,extras:s}=t,l={authorized:r.authorized()&&r.authorized().toJS(),definitions:n.securityDefinitions()&&n.securityDefinitions().toJS(),specSecurity:n.security()&&n.security().toJS()};return e({path:o,method:a,operation:i,securities:l,...s})}}},70714:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_CONFIGS:()=>n,TOGGLE_CONFIGS:()=>o,update:()=>a,toggle:()=>i,loaded:()=>s});const n="configs_update",o="configs_toggle";function a(e,t){return{type:n,payload:{[e]:t}}}function i(e){return{type:o,payload:e}}const s=()=>e=>{let{getConfigs:t,authActions:r}=e;if(t().persistAuthorization){const e=localStorage.getItem("authorized");e&&r.restoreAuthorization({authorized:JSON.parse(e)})}}},92256:(e,t,r)=>{"use strict";r.r(t),r.d(t,{parseYamlConfig:()=>o});var n=r(1272);const o=(e,t)=>{try{return n.ZP.load(e)}catch(e){return t&&t.errActions.newThrownErr(new Error(e)),{}}}},1661:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(15163),o=r(92256),a=r(70714),i=r(22698),s=r(69018),l=r(37743);const u={getLocalConfig:()=>(0,o.parseYamlConfig)(n)};function c(){return{statePlugins:{spec:{actions:i,selectors:u},configs:{reducers:l.default,actions:a,selectors:s}}}}},37743:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(43393),o=r(70714);const a={[o.UPDATE_CONFIGS]:(e,t)=>e.merge((0,n.fromJS)(t.payload)),[o.TOGGLE_CONFIGS]:(e,t)=>{const r=t.payload,n=e.get(r);return e.set(r,!n)}}},69018:(e,t,r)=>{"use strict";r.r(t),r.d(t,{get:()=>a});var n=r(58309),o=r.n(n);const a=(e,t)=>e.getIn(o()(t)?t:[t])},22698:(e,t,r)=>{"use strict";r.r(t),r.d(t,{downloadConfig:()=>o,getConfigByUrl:()=>a});var n=r(92256);const o=e=>t=>{const{fn:{fetch:r}}=t;return r(e)},a=(e,t)=>r=>{let{specActions:o}=r;if(e)return o.downloadConfig(e).then(a,a);function a(r){r instanceof Error||r.status>=400?(o.updateLoadingStatus("failedConfig"),o.updateLoadingStatus("failedConfig"),o.updateUrl(""),console.error(r.statusText+" "+e.url),t(null)):t((0,n.parseYamlConfig)(r.text))}}},31970:(e,t,r)=>{"use strict";r.r(t),r.d(t,{setHash:()=>n});const n=e=>e?history.pushState(null,null,`#${e}`):window.location.hash=""},34980:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(41599),o=r(60877),a=r(34584);function i(){return[n.default,{statePlugins:{configs:{wrapActions:{loaded:(e,t)=>function(){e(...arguments);const r=decodeURIComponent(window.location.hash);t.layoutActions.parseDeepLinkHash(r)}}}},wrapComponents:{operation:o.default,OperationTag:a.default}}]}},41599:(e,t,r)=>{"use strict";r.r(t),r.d(t,{show:()=>b,scrollTo:()=>w,parseDeepLinkHash:()=>E,readyToScroll:()=>x,scrollToElement:()=>_,clearScrollTo:()=>S,default:()=>A});var n=r(58309),o=r.n(n),a=r(24278),i=r.n(a),s=r(97606),l=r.n(s),u=r(11882),c=r.n(u),p=r(31970),f=r(45172),h=r.n(f),d=r(90242),m=r(43393),g=r.n(m);const v="layout_scroll_to",y="layout_clear_scroll",b=(e,t)=>{let{getConfigs:r,layoutSelectors:n}=t;return function(){for(var t=arguments.length,a=new Array(t),i=0;i({type:v,payload:o()(e)?e:[e]}),E=e=>t=>{let{layoutActions:r,layoutSelectors:n,getConfigs:o}=t;if(o().deepLinking&&e){var a;let t=i()(e).call(e,1);"!"===t[0]&&(t=i()(t).call(t,1)),"/"===t[0]&&(t=i()(t).call(t,1));const o=l()(a=t.split("/")).call(a,(e=>e||"")),s=n.isShownKeyFromUrlHashArray(o),[u,p="",f=""]=s;if("operations"===u){const e=n.isShownKeyFromUrlHashArray([p]);c()(p).call(p,"_")>-1&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),r.show(l()(e).call(e,(e=>e.replace(/_/g," "))),!0)),r.show(e,!0)}(c()(p).call(p,"_")>-1||c()(f).call(f,"_")>-1)&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),r.show(l()(s).call(s,(e=>e.replace(/_/g," "))),!0)),r.show(s,!0),r.scrollTo(s)}},x=(e,t)=>r=>{const n=r.layoutSelectors.getScrollToKey();g().is(n,(0,m.fromJS)(e))&&(r.layoutActions.scrollToElement(t),r.layoutActions.clearScrollTo())},_=(e,t)=>r=>{try{t=t||r.fn.getScrollParent(e),h().createScroller(t).to(e)}catch(e){console.error(e)}},S=()=>({type:y});const A={fn:{getScrollParent:function(e,t){const r=document.documentElement;let n=getComputedStyle(e);const o="absolute"===n.position,a=t?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===n.position)return r;for(let t=e;t=t.parentElement;)if(n=getComputedStyle(t),(!o||"static"!==n.position)&&a.test(n.overflow+n.overflowY+n.overflowX))return t;return r}},statePlugins:{layout:{actions:{scrollToElement:_,scrollTo:w,clearScrollTo:S,readyToScroll:x,parseDeepLinkHash:E},selectors:{getScrollToKey:e=>e.get("scrollToKey"),isShownKeyFromUrlHashArray(e,t){const[r,n]=t;return n?["operations",r,n]:r?["operations-tag",r]:[]},urlHashArrayFromIsShownKey(e,t){let[r,n,o]=t;return"operations"==r?[n,o]:"operations-tag"==r?[n]:[]}},reducers:{[v]:(e,t)=>e.set("scrollToKey",g().fromJS(t.payload)),[y]:e=>e.delete("scrollToKey")},wrapActions:{show:b}}}}},34584:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{tag:r}=this.props,n=["operations-tag",r];t.layoutActions.readyToScroll(n,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},60877:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);r(23930);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{operation:r}=this.props,{tag:n,operationId:o}=r.toObject();let{isShownKey:a}=r.toObject();a=a||["operations",n,o],t.layoutActions.readyToScroll(a,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},48011:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>d});var n=r(76986),o=r.n(n),a=r(63460),i=r.n(a),s=r(11882),l=r.n(s),u=r(35627),c=r.n(u),p=r(20573),f=r(43393),h=r(27504);function d(e){let{fn:t}=e;return{statePlugins:{spec:{actions:{download:e=>r=>{let{errActions:n,specSelectors:a,specActions:s,getConfigs:l}=r,{fetch:u}=t;const c=l();function p(t){if(t instanceof Error||t.status>=400)return s.updateLoadingStatus("failed"),n.newThrownErr(o()(new Error((t.message||t.statusText)+" "+e),{source:"fetch"})),void(!t.status&&t instanceof Error&&function(){try{let t;if("URL"in h.Z?t=new(i())(e):(t=document.createElement("a"),t.href=e),"https:"!==t.protocol&&"https:"===h.Z.location.protocol){const e=o()(new Error(`Possible mixed-content issue? The page was loaded over https:// but a ${t.protocol}// URL was specified. Check that you are not attempting to load mixed content.`),{source:"fetch"});return void n.newThrownErr(e)}if(t.origin!==h.Z.location.origin){const e=o()(new Error(`Possible cross-origin (CORS) issue? The URL origin (${t.origin}) does not match the page (${h.Z.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.`),{source:"fetch"});n.newThrownErr(e)}}catch(e){return}}());s.updateLoadingStatus("success"),s.updateSpec(t.text),a.url()!==e&&s.updateUrl(e)}e=e||a.url(),s.updateLoadingStatus("loading"),n.clear({source:"fetch"}),u({url:e,loadSpec:!0,requestInterceptor:c.requestInterceptor||(e=>e),responseInterceptor:c.responseInterceptor||(e=>e),credentials:"same-origin",headers:{Accept:"application/json,*/*"}}).then(p,p)},updateLoadingStatus:e=>{let t=[null,"loading","failed","success","failedConfig"];return-1===l()(t).call(t,e)&&console.error(`Error: ${e} is not one of ${c()(t)}`),{type:"spec_update_loading_status",payload:e}}},reducers:{spec_update_loading_status:(e,t)=>"string"==typeof t.payload?e.set("loadingStatus",t.payload):e},selectors:{loadingStatus:(0,p.P1)((e=>e||(0,f.Map)()),(e=>e.get("loadingStatus")||null))}}}}}},34966:(e,t,r)=>{"use strict";r.r(t),r.d(t,{NEW_THROWN_ERR:()=>o,NEW_THROWN_ERR_BATCH:()=>a,NEW_SPEC_ERR:()=>i,NEW_SPEC_ERR_BATCH:()=>s,NEW_AUTH_ERR:()=>l,CLEAR:()=>u,CLEAR_BY:()=>c,newThrownErr:()=>p,newThrownErrBatch:()=>f,newSpecErr:()=>h,newSpecErrBatch:()=>d,newAuthErr:()=>m,clear:()=>g,clearBy:()=>v});var n=r(7710);const o="err_new_thrown_err",a="err_new_thrown_err_batch",i="err_new_spec_err",s="err_new_spec_err_batch",l="err_new_auth_err",u="err_clear",c="err_clear_by";function p(e){return{type:o,payload:(0,n.serializeError)(e)}}function f(e){return{type:a,payload:e}}function h(e){return{type:i,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:l,payload:e}}function g(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:u,payload:e}}function v(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:()=>!0;return{type:c,payload:e}}},56982:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(14418),o=r.n(n),a=r(97606),i=r.n(a),s=r(54061),l=r.n(s);const u=[r(2392),r(21835)];function c(e){var t;let r={jsSpec:{}},n=l()(u,((e,t)=>{try{let n=t.transform(e,r);return o()(n).call(n,(e=>!!e))}catch(t){return console.error("Transformer error:",t),e}}),e);return i()(t=o()(n).call(n,(e=>!!e))).call(t,(e=>(!e.get("line")&&e.get("path"),e)))}},2392:(e,t,r)=>{"use strict";r.r(t),r.d(t,{transform:()=>p});var n=r(97606),o=r.n(n),a=r(11882),i=r.n(a),s=r(24278),l=r.n(s),u=r(24282),c=r.n(u);function p(e){return o()(e).call(e,(e=>{var t;let r="is not of a type(s)",n=i()(t=e.get("message")).call(t,r);if(n>-1){var o,a;let t=l()(o=e.get("message")).call(o,n+r.length).split(",");return e.set("message",l()(a=e.get("message")).call(a,0,n)+function(e){return c()(e).call(e,((e,t,r,n)=>r===n.length-1&&n.length>1?e+"or "+t:n[r+1]&&n.length>2?e+t+", ":n[r+1]?e+t+" ":e+t),"should be a")}(t))}return e}))}},21835:(e,t,r)=>{"use strict";r.r(t),r.d(t,{transform:()=>n});r(97606),r(11882),r(27361),r(43393);function n(e,t){let{jsSpec:r}=t;return e}},77793:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(93527),o=r(34966),a=r(87667);function i(e){return{statePlugins:{err:{reducers:(0,n.default)(e),actions:o,selectors:a}}}}},93527:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>v});var n=r(76986),o=r.n(n),a=r(97606),i=r.n(a),s=r(39022),l=r.n(s),u=r(14418),c=r.n(u),p=r(2250),f=r.n(p),h=r(34966),d=r(43393),m=r(56982);let g={line:0,level:"error",message:"Unknown error"};function v(){return{[h.NEW_THROWN_ERR]:(e,t)=>{let{payload:r}=t,n=o()(g,r,{type:"thrown"});return e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_THROWN_ERR_BATCH]:(e,t)=>{let{payload:r}=t;return r=i()(r).call(r,(e=>(0,d.fromJS)(o()(g,e,{type:"thrown"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(r))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR]:(e,t)=>{let{payload:r}=t,n=(0,d.fromJS)(r);return n=n.set("type","spec"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)).sortBy((e=>e.get("line"))))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR_BATCH]:(e,t)=>{let{payload:r}=t;return r=i()(r).call(r,(e=>(0,d.fromJS)(o()(g,e,{type:"spec"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(r))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_AUTH_ERR]:(e,t)=>{let{payload:r}=t,n=(0,d.fromJS)(o()({},r));return n=n.set("type","auth"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)))).update("errors",(e=>(0,m.default)(e)))},[h.CLEAR]:(e,t)=>{var r;let{payload:n}=t;if(!n||!e.get("errors"))return e;let o=c()(r=e.get("errors")).call(r,(e=>{var t;return f()(t=e.keySeq()).call(t,(t=>{const r=e.get(t),o=n[t];return!o||r!==o}))}));return e.merge({errors:o})},[h.CLEAR_BY]:(e,t)=>{var r;let{payload:n}=t;if(!n||"function"!=typeof n)return e;let o=c()(r=e.get("errors")).call(r,(e=>n(e)));return e.merge({errors:o})}}}},87667:(e,t,r)=>{"use strict";r.r(t),r.d(t,{allErrors:()=>a,lastError:()=>i});var n=r(43393),o=r(20573);const a=(0,o.P1)((e=>e),(e=>e.get("errors",(0,n.List)()))),i=(0,o.P1)(a,(e=>e.last()))},49978:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(4309);function o(){return{fn:{opsFilter:n.default}}}},4309:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(14418),o=r.n(n),a=r(11882),i=r.n(a);function s(e,t){return o()(e).call(e,((e,r)=>-1!==i()(r).call(r,t)))}},25474:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_LAYOUT:()=>o,UPDATE_FILTER:()=>a,UPDATE_MODE:()=>i,SHOW:()=>s,updateLayout:()=>l,updateFilter:()=>u,show:()=>c,changeMode:()=>p});var n=r(90242);const o="layout_update_layout",a="layout_update_filter",i="layout_update_mode",s="layout_show";function l(e){return{type:o,payload:e}}function u(e){return{type:a,payload:e}}function c(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=(0,n.AF)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=(0,n.AF)(e),{type:i,payload:{thing:e,mode:t}}}},26821:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(5672),o=r(25474),a=r(4400),i=r(28989);function s(){return{statePlugins:{layout:{reducers:n.default,actions:o,selectors:a},spec:{wrapSelectors:i}}}}},5672:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(39022),o=r.n(n),a=r(43393),i=r(25474);const s={[i.UPDATE_LAYOUT]:(e,t)=>e.set("layout",t.payload),[i.UPDATE_FILTER]:(e,t)=>e.set("filter",t.payload),[i.SHOW]:(e,t)=>{const r=t.payload.shown,n=(0,a.fromJS)(t.payload.thing);return e.update("shown",(0,a.fromJS)({}),(e=>e.set(n,r)))},[i.UPDATE_MODE]:(e,t)=>{var r;let n=t.payload.thing,a=t.payload.mode;return e.setIn(o()(r=["modes"]).call(r,n),(a||"")+"")}}},4400:(e,t,r)=>{"use strict";r.r(t),r.d(t,{current:()=>i,currentFilter:()=>s,isShown:()=>l,whatMode:()=>u,showSummary:()=>c});var n=r(20573),o=r(90242),a=r(43393);const i=e=>e.get("layout"),s=e=>e.get("filter"),l=(e,t,r)=>(t=(0,o.AF)(t),e.get("shown",(0,a.fromJS)({})).get((0,a.fromJS)(t),r)),u=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return t=(0,o.AF)(t),e.getIn(["modes",...t],r)},c=(0,n.P1)((e=>e),(e=>!l(e,"editor")))},28989:(e,t,r)=>{"use strict";r.r(t),r.d(t,{taggedOperations:()=>a});var n=r(24278),o=r.n(n);const a=(e,t)=>function(r){for(var n=arguments.length,a=new Array(n>1?n-1:0),i=1;i=0&&(s=o()(s).call(s,0,f)),s}},9150:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(11189),o=r.n(n);function a(e){let{configs:t}=e;const r={debug:0,info:1,log:2,warn:3,error:4},n=e=>r[e]||-1;let{logLevel:a}=t,i=n(a);function s(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),o=1;o=i&&console[e](...r)}return s.warn=o()(s).call(s,null,"warn"),s.error=o()(s).call(s,null,"error"),s.info=o()(s).call(s,null,"info"),s.debug=o()(s).call(s,null,"debug"),{rootInjects:{log:s}}}},67002:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_SELECTED_SERVER:()=>n,UPDATE_REQUEST_BODY_VALUE:()=>o,UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG:()=>a,UPDATE_REQUEST_BODY_INCLUSION:()=>i,UPDATE_ACTIVE_EXAMPLES_MEMBER:()=>s,UPDATE_REQUEST_CONTENT_TYPE:()=>l,UPDATE_RESPONSE_CONTENT_TYPE:()=>u,UPDATE_SERVER_VARIABLE_VALUE:()=>c,SET_REQUEST_BODY_VALIDATE_ERROR:()=>p,CLEAR_REQUEST_BODY_VALIDATE_ERROR:()=>f,CLEAR_REQUEST_BODY_VALUE:()=>h,setSelectedServer:()=>d,setRequestBodyValue:()=>m,setRetainRequestBodyValueFlag:()=>g,setRequestBodyInclusion:()=>v,setActiveExamplesMember:()=>y,setRequestContentType:()=>b,setResponseContentType:()=>w,setServerVariableValue:()=>E,setRequestBodyValidateError:()=>x,clearRequestBodyValidateError:()=>_,initRequestBodyValidateError:()=>S,clearRequestBodyValue:()=>A});const n="oas3_set_servers",o="oas3_set_request_body_value",a="oas3_set_request_body_retain_flag",i="oas3_set_request_body_inclusion",s="oas3_set_active_examples_member",l="oas3_set_request_content_type",u="oas3_set_response_content_type",c="oas3_set_server_variable_value",p="oas3_set_request_body_validate_error",f="oas3_clear_request_body_validate_error",h="oas3_clear_request_body_value";function d(e,t){return{type:n,payload:{selectedServerUrl:e,namespace:t}}}function m(e){let{value:t,pathMethod:r}=e;return{type:o,payload:{value:t,pathMethod:r}}}const g=e=>{let{value:t,pathMethod:r}=e;return{type:a,payload:{value:t,pathMethod:r}}};function v(e){let{value:t,pathMethod:r,name:n}=e;return{type:i,payload:{value:t,pathMethod:r,name:n}}}function y(e){let{name:t,pathMethod:r,contextType:n,contextName:o}=e;return{type:s,payload:{name:t,pathMethod:r,contextType:n,contextName:o}}}function b(e){let{value:t,pathMethod:r}=e;return{type:l,payload:{value:t,pathMethod:r}}}function w(e){let{value:t,path:r,method:n}=e;return{type:u,payload:{value:t,path:r,method:n}}}function E(e){let{server:t,namespace:r,key:n,val:o}=e;return{type:c,payload:{server:t,namespace:r,key:n,val:o}}}const x=e=>{let{path:t,method:r,validationErrors:n}=e;return{type:p,payload:{path:t,method:r,validationErrors:n}}},_=e=>{let{path:t,method:r}=e;return{type:f,payload:{path:t,method:r}}},S=e=>{let{pathMethod:t}=e;return{type:f,payload:{path:t[0],method:t[1]}}},A=e=>{let{pathMethod:t}=e;return{type:h,payload:{pathMethod:t}}}},73723:(e,t,r)=>{"use strict";r.r(t),r.d(t,{definitionsToAuthorize:()=>f});var n=r(86),o=r.n(n),a=r(14418),i=r.n(a),s=r(24282),l=r.n(s),u=r(20573),c=r(43393),p=r(7779);const f=(h=(0,u.P1)((e=>e),(e=>{let{specSelectors:t}=e;return t.securityDefinitions()}),((e,t)=>{var r;let n=(0,c.List)();return t?(o()(r=t.entrySeq()).call(r,(e=>{let[t,r]=e;const a=r.get("type");var s;if("oauth2"===a&&o()(s=r.get("flows").entrySeq()).call(s,(e=>{let[o,a]=e,s=(0,c.fromJS)({flow:o,authorizationUrl:a.get("authorizationUrl"),tokenUrl:a.get("tokenUrl"),scopes:a.get("scopes"),type:r.get("type"),description:r.get("description")});n=n.push(new c.Map({[t]:i()(s).call(s,(e=>void 0!==e))}))})),"http"!==a&&"apiKey"!==a||(n=n.push(new c.Map({[t]:r}))),"openIdConnect"===a&&r.get("openIdConnectData")){let e=r.get("openIdConnectData"),a=e.get("grant_types_supported")||["authorization_code","implicit"];o()(a).call(a,(o=>{var a;let s=e.get("scopes_supported")&&l()(a=e.get("scopes_supported")).call(a,((e,t)=>e.set(t,"")),new c.Map),u=(0,c.fromJS)({flow:o,authorizationUrl:e.get("authorization_endpoint"),tokenUrl:e.get("token_endpoint"),scopes:s,type:"oauth2",openIdConnectUrl:r.get("openIdConnectUrl")});n=n.push(new c.Map({[t]:i()(u).call(u,(e=>void 0!==e))}))}))}})),n):n})),(e,t)=>function(){const r=t.getSystem().specSelectors.specJson();for(var n=arguments.length,o=new Array(n),a=0;a{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(23101),o=r.n(n),a=r(97606),i=r.n(a),s=r(67294),l=(r(23930),r(43393));const u=e=>{var t;let{callbacks:r,getComponent:n,specPath:a}=e;const u=n("OperationContainer",!0);if(!r)return s.createElement("span",null,"No callbacks");let c=i()(t=r.entrySeq()).call(t,(t=>{var r;let[n,c]=t;return s.createElement("div",{key:n},s.createElement("h2",null,n),i()(r=c.entrySeq()).call(r,(t=>{var r;let[c,p]=t;return"$$ref"===c?null:s.createElement("div",{key:c},i()(r=p.entrySeq()).call(r,(t=>{let[r,i]=t;if("$$ref"===r)return null;let p=(0,l.fromJS)({operation:i});return s.createElement(u,o()({},e,{op:p,key:r,tag:"",method:r,path:c,specPath:a.push(n,c,r),allowTryItOut:!1}))})))})))}));return s.createElement("div",null,c)}},86775:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>f});var n=r(61125),o=r.n(n),a=r(76986),i=r.n(a),s=r(14418),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294);class f extends p.Component{constructor(e,t){super(e,t),o()(this,"onChange",(e=>{let{onChange:t}=this.props,{value:r,name:n}=e.target,o=i()({},this.state.value);n?o[n]=r:o=r,this.setState({value:o},(()=>t(this.state)))}));let{name:r,schema:n}=this.props,a=this.getValue();this.state={name:r,schema:n,value:a}}getValue(){let{name:e,authorized:t}=this.props;return t&&t.getIn([e,"value"])}render(){var e;let{schema:t,getComponent:r,errSelectors:n,name:o}=this.props;const a=r("Input"),i=r("Row"),s=r("Col"),u=r("authError"),f=r("Markdown",!0),h=r("JumpToPath",!0),d=(t.get("scheme")||"").toLowerCase();let m=this.getValue(),g=l()(e=n.allErrors()).call(e,(e=>e.get("authId")===o));if("basic"===d){var v;let e=m?m.get("username"):null;return p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Basic)",p.createElement(h,{path:["securityDefinitions",o]})),e&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Username:"),e?p.createElement("code",null," ",e," "):p.createElement(s,null,p.createElement(a,{type:"text",required:"required",name:"username","aria-label":"auth-basic-username",onChange:this.onChange,autoFocus:!0}))),p.createElement(i,null,p.createElement("label",null,"Password:"),e?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{autoComplete:"new-password",name:"password",type:"password","aria-label":"auth-basic-password",onChange:this.onChange}))),c()(v=g.valueSeq()).call(v,((e,t)=>p.createElement(u,{error:e,key:t}))))}var y;return"bearer"===d?p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Bearer)",p.createElement(h,{path:["securityDefinitions",o]})),m&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Value:"),m?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{type:"text","aria-label":"auth-bearer-value",onChange:this.onChange,autoFocus:!0}))),c()(y=g.valueSeq()).call(y,((e,t)=>p.createElement(u,{error:e,key:t})))):p.createElement("div",null,p.createElement("em",null,p.createElement("b",null,o)," HTTP authentication: unsupported scheme ",`'${d}'`))}}},76467:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(33427),o=r(42458),a=r(15757),i=r(56617),s=r(9928),l=r(45327),u=r(86775),c=r(96796);const p={Callbacks:n.default,HttpAuth:u.default,RequestBody:o.default,Servers:i.default,ServersContainer:s.default,RequestBodyEditor:l.default,OperationServers:c.default,operationLink:a.default}},15757:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(35627),o=r.n(n),a=r(97606),i=r.n(a),s=r(67294);r(23930);class l extends s.Component{render(){const{link:e,name:t,getComponent:r}=this.props,n=r("Markdown",!0);let a=e.get("operationId")||e.get("operationRef"),l=e.get("parameters")&&e.get("parameters").toJS(),u=e.get("description");return s.createElement("div",{className:"operation-link"},s.createElement("div",{className:"description"},s.createElement("b",null,s.createElement("code",null,t)),u?s.createElement(n,{source:u}):null),s.createElement("pre",null,"Operation `",a,"`",s.createElement("br",null),s.createElement("br",null),"Parameters ",function(e,t){var r;if("string"!=typeof t)return"";return i()(r=t.split("\n")).call(r,((t,r)=>r>0?Array(e+1).join(" ")+t:t)).join("\n")}(0,o()(l,null,2))||"{}",s.createElement("br",null)))}}const u=l},96796:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);r(23930);class i extends a.Component{constructor(){super(...arguments),o()(this,"setSelectedServer",(e=>{const{path:t,method:r}=this.props;return this.forceUpdate(),this.props.setSelectedServer(e,`${t}:${r}`)})),o()(this,"setServerVariableValue",(e=>{const{path:t,method:r}=this.props;return this.forceUpdate(),this.props.setServerVariableValue({...e,namespace:`${t}:${r}`})})),o()(this,"getSelectedServer",(()=>{const{path:e,method:t}=this.props;return this.props.getSelectedServer(`${e}:${t}`)})),o()(this,"getServerVariable",((e,t)=>{const{path:r,method:n}=this.props;return this.props.getServerVariable({namespace:`${r}:${n}`,server:e},t)})),o()(this,"getEffectiveServerValue",(e=>{const{path:t,method:r}=this.props;return this.props.getEffectiveServerValue({server:e,namespace:`${t}:${r}`})}))}render(){const{operationServers:e,pathServers:t,getComponent:r}=this.props;if(!e&&!t)return null;const n=r("Servers"),o=e||t,i=e?"operation":"path";return a.createElement("div",{className:"opblock-section operation-servers"},a.createElement("div",{className:"opblock-section-header"},a.createElement("div",{className:"tab-header"},a.createElement("h4",{className:"opblock-title"},"Servers"))),a.createElement("div",{className:"opblock-description-wrapper"},a.createElement("h4",{className:"message"},"These ",i,"-level options override the global server options."),a.createElement(n,{servers:o,currentServer:this.getSelectedServer(),setSelectedServer:this.setSelectedServer,setServerVariableValue:this.setServerVariableValue,getServerVariable:this.getServerVariable,getEffectiveServerValue:this.getEffectiveServerValue})))}}},45327:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(61125),o=r.n(n),a=r(67294),i=r(94184),s=r.n(i),l=r(90242);const u=Function.prototype;class c extends a.PureComponent{constructor(e,t){super(e,t),o()(this,"applyDefaultValue",(e=>{const{onChange:t,defaultValue:r}=e||this.props;return this.setState({value:r}),t(r)})),o()(this,"onChange",(e=>{this.props.onChange((0,l.Pz)(e))})),o()(this,"onDomChange",(e=>{const t=e.target.value;this.setState({value:t},(()=>this.onChange(t)))})),this.state={value:(0,l.Pz)(e.value)||e.defaultValue},e.onChange(e.value)}UNSAFE_componentWillReceiveProps(e){this.props.value!==e.value&&e.value!==this.state.value&&this.setState({value:(0,l.Pz)(e.value)}),!e.value&&e.defaultValue&&this.state.value&&this.applyDefaultValue(e)}render(){let{getComponent:e,errors:t}=this.props,{value:r}=this.state,n=t.size>0;const o=e("TextArea");return a.createElement("div",{className:"body-param"},a.createElement(o,{className:s()("body-param__text",{invalid:n}),title:t.size?t.join(", "):"",value:r,onChange:this.onDomChange}))}}o()(c,"defaultProps",{onChange:u,userHasEditedBody:!1})},42458:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getDefaultRequestBodyValue:()=>m,default:()=>g});var n=r(97606),o=r.n(n),a=r(11882),i=r.n(a),s=r(58118),l=r.n(s),u=r(58309),c=r.n(u),p=r(67294),f=(r(23930),r(43393)),h=r(90242),d=r(2518);const m=(e,t,r)=>{const n=e.getIn(["content",t]),o=n.get("schema").toJS(),a=void 0!==n.get("examples"),i=n.get("example"),s=a?n.getIn(["examples",r,"value"]):i,l=(0,h.xi)(o,t,{includeWriteOnly:!0},s);return(0,h.Pz)(l)},g=e=>{let{userHasEditedBody:t,requestBody:r,requestBodyValue:n,requestBodyInclusionSetting:a,requestBodyErrors:s,getComponent:u,getConfigs:g,specSelectors:v,fn:y,contentType:b,isExecute:w,specPath:E,onChange:x,onChangeIncludeEmpty:_,activeExamplesKey:S,updateActiveExamplesKey:A,setRetainRequestBodyValueFlag:k}=e;const C=e=>{x(e.target.files[0])},O=e=>{let t={key:e,shouldDispatchInit:!1,defaultValue:!0};return"no value"===a.get(e,"no value")&&(t.shouldDispatchInit=!0),t},j=u("Markdown",!0),I=u("modelExample"),N=u("RequestBodyEditor"),T=u("highlightCode"),P=u("ExamplesSelectValueRetainer"),R=u("Example"),M=u("ParameterIncludeEmpty"),{showCommonExtensions:D}=g(),L=r&&r.get("description")||null,B=r&&r.get("content")||new f.OrderedMap;b=b||B.keySeq().first()||"";const F=B.get(b,(0,f.OrderedMap)()),z=F.get("schema",(0,f.OrderedMap)()),U=F.get("examples",null),q=null==U?void 0:o()(U).call(U,((e,t)=>{var n;const o=null===(n=e)||void 0===n?void 0:n.get("value",null);return o&&(e=e.set("value",m(r,b,t),o)),e}));if(s=f.List.isList(s)?s:(0,f.List)(),!F.size)return null;const V="object"===F.getIn(["schema","type"]),$="binary"===F.getIn(["schema","format"]),W="base64"===F.getIn(["schema","format"]);if("application/octet-stream"===b||0===i()(b).call(b,"image/")||0===i()(b).call(b,"audio/")||0===i()(b).call(b,"video/")||$||W){const e=u("Input");return w?p.createElement(e,{type:"file",onChange:C}):p.createElement("i",null,"Example values are not available for ",p.createElement("code",null,b)," media types.")}if(V&&("application/x-www-form-urlencoded"===b||0===i()(b).call(b,"multipart/"))&&z.get("properties",(0,f.OrderedMap)()).size>0){var H;const e=u("JsonSchemaForm"),t=u("ParameterExt"),r=z.get("properties",(0,f.OrderedMap)());return n=f.Map.isMap(n)?n:(0,f.OrderedMap)(),p.createElement("div",{className:"table-container"},L&&p.createElement(j,{source:L}),p.createElement("table",null,p.createElement("tbody",null,f.Map.isMap(r)&&o()(H=r.entrySeq()).call(H,(r=>{var i,d;let[m,g]=r;if(g.get("readOnly"))return;let v=D?(0,h.po)(g):null;const b=l()(i=z.get("required",(0,f.List)())).call(i,m),E=g.get("type"),S=g.get("format"),A=g.get("description"),k=n.getIn([m,"value"]),C=n.getIn([m,"errors"])||s,I=a.get(m)||!1,N=g.has("default")||g.has("example")||g.hasIn(["items","example"])||g.hasIn(["items","default"]),T=g.has("enum")&&(1===g.get("enum").size||b),P=N||T;let R="";"array"!==E||P||(R=[]),("object"===E||P)&&(R=(0,h.xi)(g,!1,{includeWriteOnly:!0})),"string"!=typeof R&&"object"===E&&(R=(0,h.Pz)(R)),"string"==typeof R&&"array"===E&&(R=JSON.parse(R));const L="string"===E&&("binary"===S||"base64"===S);return p.createElement("tr",{key:m,className:"parameters","data-property-name":m},p.createElement("td",{className:"parameters-col_name"},p.createElement("div",{className:b?"parameter__name required":"parameter__name"},m,b?p.createElement("span",null," *"):null),p.createElement("div",{className:"parameter__type"},E,S&&p.createElement("span",{className:"prop-format"},"($",S,")"),D&&v.size?o()(d=v.entrySeq()).call(d,(e=>{let[r,n]=e;return p.createElement(t,{key:`${r}-${n}`,xKey:r,xVal:n})})):null),p.createElement("div",{className:"parameter__deprecated"},g.get("deprecated")?"deprecated":null)),p.createElement("td",{className:"parameters-col_description"},p.createElement(j,{source:A}),w?p.createElement("div",null,p.createElement(e,{fn:y,dispatchInitialValue:!L,schema:g,description:m,getComponent:u,value:void 0===k?R:k,required:b,errors:C,onChange:e=>{x(e,[m])}}),b?null:p.createElement(M,{onChange:e=>_(m,e),isIncluded:I,isIncludedOptions:O(m),isDisabled:c()(k)?0!==k.length:!(0,h.O2)(k)})):null))})))))}const J=m(r,b,S);let K=null;return(0,d.O)(J)&&(K="json"),p.createElement("div",null,L&&p.createElement(j,{source:L}),q?p.createElement(P,{userHasEditedBody:t,examples:q,currentKey:S,currentUserInputValue:n,onSelect:e=>{A(e)},updateValue:x,defaultToFirstExample:!0,getComponent:u,setRetainRequestBodyValueFlag:k}):null,w?p.createElement("div",null,p.createElement(N,{value:n,errors:s,defaultValue:J,onChange:x,getComponent:u})):p.createElement(I,{getComponent:u,getConfigs:g,specSelectors:v,expandDepth:1,isExecute:w,schema:F.get("schema"),specPath:E.push("content",b),example:p.createElement(T,{className:"body-param__example",getConfigs:g,language:K,value:(0,h.Pz)(n)||J}),includeWriteOnly:!0}),q?p.createElement(R,{example:q.get(S),getComponent:u,getConfigs:g}):null)}},9928:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);class o extends n.Component{render(){const{specSelectors:e,oas3Selectors:t,oas3Actions:r,getComponent:o}=this.props,a=e.servers(),i=o("Servers");return a&&a.size?n.createElement("div",null,n.createElement("span",{className:"servers-title"},"Servers"),n.createElement(i,{servers:a,currentServer:t.selectedServer(),setSelectedServer:r.setSelectedServer,setServerVariableValue:r.setServerVariableValue,getServerVariable:t.serverVariableValue,getEffectiveServerValue:t.serverEffectiveValue})):null}}},56617:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(61125),o=r.n(n),a=r(51679),i=r.n(a),s=r(97606),l=r.n(s),u=r(67294),c=r(43393);r(23930);class p extends u.Component{constructor(){super(...arguments),o()(this,"onServerChange",(e=>{this.setServer(e.target.value)})),o()(this,"onServerVariableValueChange",(e=>{let{setServerVariableValue:t,currentServer:r}=this.props,n=e.target.getAttribute("data-variable"),o=e.target.value;"function"==typeof t&&t({server:r,key:n,val:o})})),o()(this,"setServer",(e=>{let{setSelectedServer:t}=this.props;t(e)}))}componentDidMount(){var e;let{servers:t,currentServer:r}=this.props;r||this.setServer(null===(e=t.first())||void 0===e?void 0:e.get("url"))}UNSAFE_componentWillReceiveProps(e){let{servers:t,setServerVariableValue:r,getServerVariable:n}=e;if(this.props.currentServer!==e.currentServer||this.props.servers!==e.servers){var o;let a=i()(t).call(t,(t=>t.get("url")===e.currentServer)),s=i()(o=this.props.servers).call(o,(e=>e.get("url")===this.props.currentServer))||(0,c.OrderedMap)();if(!a)return this.setServer(t.first().get("url"));let u=s.get("variables")||(0,c.OrderedMap)(),p=(i()(u).call(u,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default"),f=a.get("variables")||(0,c.OrderedMap)(),h=(i()(f).call(f,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default");l()(f).call(f,((t,o)=>{n(e.currentServer,o)&&p===h||r({server:e.currentServer,key:o,val:t.get("default")||""})}))}}render(){var e,t;let{servers:r,currentServer:n,getServerVariable:o,getEffectiveServerValue:a}=this.props,s=(i()(r).call(r,(e=>e.get("url")===n))||(0,c.OrderedMap)()).get("variables")||(0,c.OrderedMap)(),p=0!==s.size;return u.createElement("div",{className:"servers"},u.createElement("label",{htmlFor:"servers"},u.createElement("select",{onChange:this.onServerChange,value:n},l()(e=r.valueSeq()).call(e,(e=>u.createElement("option",{value:e.get("url"),key:e.get("url")},e.get("url"),e.get("description")&&` - ${e.get("description")}`))).toArray())),p?u.createElement("div",null,u.createElement("div",{className:"computed-url"},"Computed URL:",u.createElement("code",null,a(n))),u.createElement("h4",null,"Server variables"),u.createElement("table",null,u.createElement("tbody",null,l()(t=s.entrySeq()).call(t,(e=>{var t;let[r,a]=e;return u.createElement("tr",{key:r},u.createElement("td",null,r),u.createElement("td",null,a.get("enum")?u.createElement("select",{"data-variable":r,onChange:this.onServerVariableValueChange},l()(t=a.get("enum")).call(t,(e=>u.createElement("option",{selected:e===o(n,r),key:e,value:e},e)))):u.createElement("input",{type:"text",value:o(n,r)||"",onChange:this.onServerVariableValueChange,"data-variable":r})))}))))):null)}}},7779:(e,t,r)=>{"use strict";r.r(t),r.d(t,{isOAS3:()=>l,isSwagger2:()=>u,OAS3ComponentWrapFactory:()=>c});var n=r(23101),o=r.n(n),a=r(27043),i=r.n(a),s=r(67294);function l(e){const t=e.get("openapi");return"string"==typeof t&&(i()(t).call(t,"3.0.")&&t.length>4)}function u(e){const t=e.get("swagger");return"string"==typeof t&&i()(t).call(t,"2.0")}function c(e){return(t,r)=>n=>{if(r&&r.specSelectors&&r.specSelectors.specJson){return l(r.specSelectors.specJson())?s.createElement(e,o()({},n,r,{Ori:t})):s.createElement(t,n)}return console.warn("OAS3 wrapper: couldn't get spec"),null}}},97451:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(92044),o=r(73723),a=r(91741),i=r(76467),s=r(37761),l=r(67002),u=r(5065),c=r(62109);function p(){return{components:i.default,wrapComponents:s.default,statePlugins:{spec:{wrapSelectors:n,selectors:a},auth:{wrapSelectors:o},oas3:{actions:l,reducers:c.default,selectors:u}}}}},62109:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(8712),o=r.n(n),a=r(86),i=r.n(a),s=r(24282),l=r.n(s),u=r(43393),c=r(67002);const p={[c.UPDATE_SELECTED_SERVER]:(e,t)=>{let{payload:{selectedServerUrl:r,namespace:n}}=t;const o=n?[n,"selectedServer"]:["selectedServer"];return e.setIn(o,r)},[c.UPDATE_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[a,s]=n;if(!u.Map.isMap(r))return e.setIn(["requestData",a,s,"bodyValue"],r);let l,c=e.getIn(["requestData",a,s,"bodyValue"])||(0,u.Map)();u.Map.isMap(c)||(c=(0,u.Map)());const[...p]=o()(r).call(r);return i()(p).call(p,(e=>{let t=r.getIn([e]);c.has(e)&&u.Map.isMap(t)||(l=c.setIn([e,"value"],t))})),e.setIn(["requestData",a,s,"bodyValue"],l)},[c.UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[o,a]=n;return e.setIn(["requestData",o,a,"retainBodyValue"],r)},[c.UPDATE_REQUEST_BODY_INCLUSION]:(e,t)=>{let{payload:{value:r,pathMethod:n,name:o}}=t,[a,i]=n;return e.setIn(["requestData",a,i,"bodyInclusion",o],r)},[c.UPDATE_ACTIVE_EXAMPLES_MEMBER]:(e,t)=>{let{payload:{name:r,pathMethod:n,contextType:o,contextName:a}}=t,[i,s]=n;return e.setIn(["examples",i,s,o,a,"activeExample"],r)},[c.UPDATE_REQUEST_CONTENT_TYPE]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[o,a]=n;return e.setIn(["requestData",o,a,"requestContentType"],r)},[c.UPDATE_RESPONSE_CONTENT_TYPE]:(e,t)=>{let{payload:{value:r,path:n,method:o}}=t;return e.setIn(["requestData",n,o,"responseContentType"],r)},[c.UPDATE_SERVER_VARIABLE_VALUE]:(e,t)=>{let{payload:{server:r,namespace:n,key:o,val:a}}=t;const i=n?[n,"serverVariableValues",r,o]:["serverVariableValues",r,o];return e.setIn(i,a)},[c.SET_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:r,method:n,validationErrors:o}}=t,a=[];if(a.push("Required field is not provided"),o.missingBodyValue)return e.setIn(["requestData",r,n,"errors"],(0,u.fromJS)(a));if(o.missingRequiredKeys&&o.missingRequiredKeys.length>0){const{missingRequiredKeys:t}=o;return e.updateIn(["requestData",r,n,"bodyValue"],(0,u.fromJS)({}),(e=>l()(t).call(t,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)(a))),e)))}return console.warn("unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR"),e},[c.CLEAR_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:r,method:n}}=t;const a=e.getIn(["requestData",r,n,"bodyValue"]);if(!u.Map.isMap(a))return e.setIn(["requestData",r,n,"errors"],(0,u.fromJS)([]));const[...i]=o()(a).call(a);return i?e.updateIn(["requestData",r,n,"bodyValue"],(0,u.fromJS)({}),(e=>l()(i).call(i,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)([]))),e))):e},[c.CLEAR_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{pathMethod:r}}=t,[n,o]=r;const a=e.getIn(["requestData",n,o,"bodyValue"]);return a?u.Map.isMap(a)?e.setIn(["requestData",n,o,"bodyValue"],(0,u.Map)()):e.setIn(["requestData",n,o,"bodyValue"],""):e}}},5065:(e,t,r)=>{"use strict";r.r(t),r.d(t,{selectedServer:()=>g,requestBodyValue:()=>v,shouldRetainRequestBodyValue:()=>y,hasUserEditedBody:()=>b,requestBodyInclusionSetting:()=>w,requestBodyErrors:()=>E,activeExamplesMember:()=>x,requestContentType:()=>_,responseContentType:()=>S,serverVariableValue:()=>A,serverVariables:()=>k,serverEffectiveValue:()=>C,validateBeforeExecute:()=>O,validateShallowRequired:()=>I});var n=r(97606),o=r.n(n),a=r(86),i=r.n(a),s=r(28222),l=r.n(s),u=r(11882),c=r.n(u),p=r(43393),f=r(7779),h=r(42458),d=r(90242);function m(e){return function(){for(var t=arguments.length,r=new Array(t),n=0;n{const n=t.getSystem().specSelectors.specJson();return(0,f.isOAS3)(n)?e(...r):null}}}const g=m(((e,t)=>{const r=t?[t,"selectedServer"]:["selectedServer"];return e.getIn(r)||""})),v=m(((e,t,r)=>e.getIn(["requestData",t,r,"bodyValue"])||null)),y=m(((e,t,r)=>e.getIn(["requestData",t,r,"retainBodyValue"])||!1)),b=(e,t,r)=>e=>{const{oas3Selectors:n,specSelectors:o}=e.getSystem(),a=o.specJson();if((0,f.isOAS3)(a)){let e=!1;const a=n.requestContentType(t,r);let i=n.requestBodyValue(t,r);if(p.Map.isMap(i)&&(i=(0,d.Pz)(i.mapEntries((e=>p.Map.isMap(e[1])?[e[0],e[1].get("value")]:e)).toJS())),p.List.isList(i)&&(i=(0,d.Pz)(i)),a){const s=(0,h.getDefaultRequestBodyValue)(o.specResolvedSubtree(["paths",t,r,"requestBody"]),a,n.activeExamplesMember(t,r,"requestBody","requestBody"));e=!!i&&i!==s}return e}return null},w=m(((e,t,r)=>e.getIn(["requestData",t,r,"bodyInclusion"])||(0,p.Map)())),E=m(((e,t,r)=>e.getIn(["requestData",t,r,"errors"])||null)),x=m(((e,t,r,n,o)=>e.getIn(["examples",t,r,n,o,"activeExample"])||null)),_=m(((e,t,r)=>e.getIn(["requestData",t,r,"requestContentType"])||null)),S=m(((e,t,r)=>e.getIn(["requestData",t,r,"responseContentType"])||null)),A=m(((e,t,r)=>{let n;if("string"!=typeof t){const{server:e,namespace:o}=t;n=o?[o,"serverVariableValues",e,r]:["serverVariableValues",e,r]}else{n=["serverVariableValues",t,r]}return e.getIn(n)||null})),k=m(((e,t)=>{let r;if("string"!=typeof t){const{server:e,namespace:n}=t;r=n?[n,"serverVariableValues",e]:["serverVariableValues",e]}else{r=["serverVariableValues",t]}return e.getIn(r)||(0,p.OrderedMap)()})),C=m(((e,t)=>{var r,n;if("string"!=typeof t){const{server:o,namespace:a}=t;n=o,r=a?e.getIn([a,"serverVariableValues",n]):e.getIn(["serverVariableValues",n])}else n=t,r=e.getIn(["serverVariableValues",n]);r=r||(0,p.OrderedMap)();let a=n;return o()(r).call(r,((e,t)=>{a=a.replace(new RegExp(`{${t}}`,"g"),e)})),a})),O=(j=(e,t)=>((e,t)=>(t=t||[],!!e.getIn(["requestData",...t,"bodyValue"])))(e,t),function(){for(var e=arguments.length,t=new Array(e),r=0;r{const r=e.getSystem().specSelectors.specJson();let n=[...t][1]||[];return!r.getIn(["paths",...n,"requestBody","required"])||j(...t)}});var j;const I=(e,t)=>{var r;let{oas3RequiredRequestBodyContentType:n,oas3RequestContentType:o,oas3RequestBodyValue:a}=t,s=[];if(!p.Map.isMap(a))return s;let u=[];return i()(r=l()(n.requestContentType)).call(r,(e=>{if(e===o){let t=n.requestContentType[e];i()(t).call(t,(e=>{c()(u).call(u,e)<0&&u.push(e)}))}})),i()(u).call(u,(e=>{a.getIn([e,"value"])||s.push(e)})),s}},91741:(e,t,r)=>{"use strict";r.r(t),r.d(t,{servers:()=>u,isSwagger2:()=>p});var n=r(20573),o=r(43393),a=r(7779);const i=e=>e||(0,o.Map)(),s=(0,n.P1)(i,(e=>e.get("json",(0,o.Map)()))),l=(0,n.P1)(i,(e=>e.get("resolved",(0,o.Map)()))),u=(c=(0,n.P1)((e=>{let t=l(e);return t.count()<1&&(t=s(e)),t}),(e=>e.getIn(["servers"])||(0,o.Map)())),()=>function(e){const t=e.getSystem().specSelectors.specJson();if((0,a.isOAS3)(t)){for(var r=arguments.length,n=new Array(r>1?r-1:0),o=1;o()=>{const e=t.getSystem().specSelectors.specJson();return(0,a.isSwagger2)(e)}},92044:(e,t,r)=>{"use strict";r.r(t),r.d(t,{definitions:()=>h,hasHost:()=>d,securityDefinitions:()=>m,host:()=>g,basePath:()=>v,consumes:()=>y,produces:()=>b,schemes:()=>w,servers:()=>E,isOAS3:()=>x,isSwagger2:()=>_});var n=r(20573),o=r(33881),a=r(43393),i=r(7779);function s(e){return(t,r)=>function(){const n=r.getSystem().specSelectors.specJson();return(0,i.isOAS3)(n)?e(...arguments):t(...arguments)}}const l=e=>e||(0,a.Map)(),u=s((0,n.P1)((()=>null))),c=(0,n.P1)(l,(e=>e.get("json",(0,a.Map)()))),p=(0,n.P1)(l,(e=>e.get("resolved",(0,a.Map)()))),f=e=>{let t=p(e);return t.count()<1&&(t=c(e)),t},h=s((0,n.P1)(f,(e=>{const t=e.getIn(["components","schemas"]);return a.Map.isMap(t)?t:(0,a.Map)()}))),d=s((e=>f(e).hasIn(["servers",0]))),m=s((0,n.P1)(o.specJsonWithResolvedSubtrees,(e=>e.getIn(["components","securitySchemes"])||null))),g=u,v=u,y=u,b=u,w=u,E=s((0,n.P1)(f,(e=>e.getIn(["servers"])||(0,a.Map)()))),x=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isOAS3)(a.Map.isMap(e)?e:(0,a.Map)())},_=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isSwagger2)(a.Map.isMap(e)?e:(0,a.Map)())}},70356:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...r}=e;const{schema:o,getComponent:a,errSelectors:i,authorized:s,onAuthChange:l,name:u}=r,c=a("HttpAuth");return"http"===o.get("type")?n.createElement(c,{key:u,schema:o,name:u,errSelectors:i,authorized:s,getComponent:a,onChange:l}):n.createElement(t,r)}))},37761:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(22460),o=r(70356),a=r(69487),i=r(50058),s=r(53499),l=r(90287);const u={Markdown:n.default,AuthItem:o.default,JsonSchema_string:l.default,VersionStamp:a.default,model:s.default,onlineValidatorBadge:i.default}},90287:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...r}=e;const{schema:o,getComponent:a,errors:i,onChange:s}=r,l=o&&o.get?o.get("format"):null,u=o&&o.get?o.get("type"):null,c=a("Input");return u&&"string"===u&&l&&("binary"===l||"base64"===l)?n.createElement(c,{type:"file",className:i.length?"invalid":"",title:i.length?i:"",onChange:e=>{s(e.target.files[0])},disabled:t.isDisabled}):n.createElement(t,r)}))},22460:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Markdown:()=>f,default:()=>h});var n=r(81607),o=r.n(n),a=r(67294),i=r(94184),s=r.n(i),l=r(89927),u=r(7779),c=r(86019);const p=new l._("commonmark");p.block.ruler.enable(["table"]),p.set({linkTarget:"_blank"});const f=e=>{let{source:t,className:r="",getConfigs:n}=e;if("string"!=typeof t)return null;if(t){const{useUnsafeMarkdown:e}=n(),i=p.render(t),l=(0,c.s)(i,{useUnsafeMarkdown:e});let u;return"string"==typeof l&&(u=o()(l).call(l)),a.createElement("div",{dangerouslySetInnerHTML:{__html:u},className:s()(r,"renderedMarkdown")})}return null};f.defaultProps={getConfigs:()=>({useUnsafeMarkdown:!1})};const h=(0,u.OAS3ComponentWrapFactory)(f)},53499:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(23101),o=r.n(n),a=r(67294),i=r(7779),s=r(53795);class l extends a.Component{render(){let{getConfigs:e,schema:t}=this.props,r=["model-box"],n=null;return!0===t.get("deprecated")&&(r.push("deprecated"),n=a.createElement("span",{className:"model-deprecated-warning"},"Deprecated:")),a.createElement("div",{className:r.join(" ")},n,a.createElement(s.Z,o()({},this.props,{getConfigs:e,depth:1,expandDepth:this.props.expandDepth||0})))}}const u=(0,i.OAS3ComponentWrapFactory)(l)},50058:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(7779),o=r(5623);const a=(0,n.OAS3ComponentWrapFactory)(o.Z)},69487:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{const{Ori:t}=e;return n.createElement("span",null,n.createElement(t,e),n.createElement("small",{className:"version-stamp"},n.createElement("pre",{className:"version"},"OAS3")))}))},28560:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(87198),o=r.n(n);let a=!1;function i(){return{statePlugins:{spec:{wrapActions:{updateSpec:e=>function(){return a=!0,e(...arguments)},updateJsonSpec:(e,t)=>function(){const r=t.getConfigs().onComplete;return a&&"function"==typeof r&&(o()(r,0),a=!1),e(...arguments)}}}}}}},92135:(e,t,r)=>{"use strict";r.r(t),r.d(t,{requestSnippetGenerator_curl_powershell:()=>A,requestSnippetGenerator_curl_bash:()=>k,requestSnippetGenerator_curl_cmd:()=>C});var n=r(11882),o=r.n(n),a=r(81607),i=r.n(a),s=r(35627),l=r.n(s),u=r(97606),c=r.n(u),p=r(12196),f=r.n(p),h=r(74386),d=r.n(h),m=r(58118),g=r.n(m),v=r(27504),y=r(43393);const b=e=>{var t;const r="_**[]";return o()(e).call(e,r)<0?e:i()(t=e.split(r)[0]).call(t)},w=e=>"-d "===e||/^[_\/-]/g.test(e)?e:"'"+e.replace(/'/g,"'\\''")+"'",E=e=>"-d "===(e=e.replace(/\^/g,"^^").replace(/\\"/g,'\\\\"').replace(/"/g,'""').replace(/\n/g,"^\n"))?e.replace(/-d /g,"-d ^\n"):/^[_\/-]/g.test(e)?e:'"'+e+'"',x=e=>"-d "===e?e:/\n/.test(e)?'@"\n'+e.replace(/"/g,'\\"').replace(/`/g,"``").replace(/\$/,"`$")+'\n"@':/^[_\/-]/g.test(e)?e:"'"+e.replace(/"/g,'""').replace(/'/g,"''")+"'";function _(e){let t=[];for(let[r,n]of e.get("body").entrySeq()){let e=b(r);n instanceof v.Z.File?t.push(` "${e}": {\n "name": "${n.name}"${n.type?`,\n "type": "${n.type}"`:""}\n }`):t.push(` "${e}": ${l()(n,null,2).replace(/(\r\n|\r|\n)/g,"\n ")}`)}return`{\n${t.join(",\n")}\n}`}const S=function(e,t,r){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=!1,a="";const i=function(){for(var e=arguments.length,r=new Array(e),n=0;na+=` ${r}`,p=function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return a+=f()(e=" ").call(e,t)};let h=e.get("headers");if(a+="curl"+n,e.has("curlOptions")&&i(...e.get("curlOptions")),i("-X",e.get("method")),u(),p(),s(`${e.get("url")}`),h&&h.size)for(let t of d()(m=e.get("headers")).call(m)){var m;u(),p();let[e,r]=t;s("-H",`${e}: ${r}`),o=o||/^content-type$/i.test(e)&&/^multipart\/form-data$/i.test(r)}const w=e.get("body");var E;if(w)if(o&&g()(E=["POST","PUT","PATCH"]).call(E,e.get("method")))for(let[e,t]of w.entrySeq()){let r=b(e);u(),p(),s("-F"),t instanceof v.Z.File?i(`${r}=@${t.name}${t.type?`;type=${t.type}`:""}`):i(`${r}=${t}`)}else if(w instanceof v.Z.File)u(),p(),s(`--data-binary '@${w.name}'`);else{u(),p(),s("-d ");let t=w;y.Map.isMap(t)?s(_(e)):("string"!=typeof t&&(t=l()(t)),s(t))}else w||"POST"!==e.get("method")||(u(),p(),s("-d ''"));return a},A=e=>S(e,x,"`\n",".exe"),k=e=>S(e,w,"\\\n"),C=e=>S(e,E,"^\n")},86575:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(92135),o=r(4669),a=r(84206);const i=()=>({components:{RequestSnippets:a.default},fn:n,statePlugins:{requestSnippets:{selectors:o}}})},84206:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>w});var n=r(14418),o=r.n(n),a=r(25110),i=r.n(a),s=r(86),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294),f=r(27361),h=r.n(f),d=r(23560),m=r.n(d),g=r(74855),v=r(36581);const y={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(250, 250, 250)",paddingBottom:"0",paddingTop:"0",border:"1px solid rgb(51, 51, 51)",borderRadius:"4px 4px 0 0",boxShadow:"none",borderBottom:"none"},b={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(51, 51, 51)",boxShadow:"none",border:"1px solid rgb(51, 51, 51)",paddingBottom:"0",paddingTop:"0",borderRadius:"4px 4px 0 0",marginTop:"-5px",marginRight:"-5px",marginLeft:"-5px",zIndex:"9999",borderBottom:"none"},w=e=>{var t,r;let{request:n,requestSnippetsSelectors:a,getConfigs:s}=e;const u=m()(s)?s():null,f=!1!==h()(u,"syntaxHighlight")&&h()(u,"syntaxHighlight.activated",!0),d=(0,p.useRef)(null),[w,E]=(0,p.useState)(null===(t=a.getSnippetGenerators())||void 0===t?void 0:t.keySeq().first()),[x,_]=(0,p.useState)(null==a?void 0:a.getDefaultExpanded());(0,p.useEffect)((()=>{}),[]),(0,p.useEffect)((()=>{var e;const t=o()(e=i()(d.current.childNodes)).call(e,(e=>{var t;return!!e.nodeType&&(null===(t=e.classList)||void 0===t?void 0:t.contains("curl-command"))}));return l()(t).call(t,(e=>e.addEventListener("mousewheel",j,{passive:!1}))),()=>{l()(t).call(t,(e=>e.removeEventListener("mousewheel",j)))}}),[n]);const S=a.getSnippetGenerators(),A=S.get(w),k=A.get("fn")(n),C=()=>{_(!x)},O=e=>e===w?b:y,j=e=>{const{target:t,deltaY:r}=e,{scrollHeight:n,offsetHeight:o,scrollTop:a}=t;n>o&&(0===a&&r<0||o+a>=n&&r>0)&&e.preventDefault()},I=f?p.createElement(v.d3,{language:A.get("syntax"),className:"curl microlight",style:(0,v.C2)(h()(u,"syntaxHighlight.theme"))},k):p.createElement("textarea",{readOnly:!0,className:"curl",value:k});return p.createElement("div",{className:"request-snippets",ref:d},p.createElement("div",{style:{width:"100%",display:"flex",justifyContent:"flex-start",alignItems:"center",marginBottom:"15px"}},p.createElement("h4",{onClick:()=>C(),style:{cursor:"pointer"}},"Snippets"),p.createElement("button",{onClick:()=>C(),style:{border:"none",background:"none"},title:x?"Collapse operation":"Expand operation"},p.createElement("svg",{className:"arrow",width:"10",height:"10"},p.createElement("use",{href:x?"#large-arrow-down":"#large-arrow",xlinkHref:x?"#large-arrow-down":"#large-arrow"})))),x&&p.createElement("div",{className:"curl-command"},p.createElement("div",{style:{paddingLeft:"15px",paddingRight:"10px",width:"100%",display:"flex"}},c()(r=S.entrySeq()).call(r,(e=>{let[t,r]=e;return p.createElement("div",{style:O(t),className:"btn",key:t,onClick:()=>(e=>{w!==e&&E(e)})(t)},p.createElement("h4",{style:t===w?{color:"white"}:{}},r.get("title")))}))),p.createElement("div",{className:"copy-to-clipboard"},p.createElement(g.CopyToClipboard,{text:k},p.createElement("button",null))),p.createElement("div",null,I)))}},4669:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getGenerators:()=>f,getSnippetGenerators:()=>h,getActiveLanguage:()=>d,getDefaultExpanded:()=>m});var n=r(14418),o=r.n(n),a=r(58118),i=r.n(a),s=r(97606),l=r.n(s),u=r(20573),c=r(43393);const p=e=>e||(0,c.Map)(),f=(0,u.P1)(p,(e=>{const t=e.get("languages"),r=e.get("generators",(0,c.Map)());return!t||t.isEmpty()?r:o()(r).call(r,((e,r)=>i()(t).call(t,r)))})),h=e=>t=>{var r,n;let{fn:a}=t;return o()(r=l()(n=f(e)).call(n,((e,t)=>{const r=(e=>a[`requestSnippetGenerator_${e}`])(t);return"function"!=typeof r?null:e.set("fn",r)}))).call(r,(e=>e))},d=(0,u.P1)(p,(e=>e.get("activeLanguage"))),m=(0,u.P1)(p,(e=>e.get("defaultExpanded")))},36195:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ErrorBoundary:()=>i,default:()=>s});var n=r(67294),o=r(56189),a=r(29403);class i extends n.Component{static getDerivedStateFromError(e){return{hasError:!0,error:e}}constructor(){super(...arguments),this.state={hasError:!1,error:null}}componentDidCatch(e,t){this.props.fn.componentDidCatch(e,t)}render(){const{getComponent:e,targetName:t,children:r}=this.props;if(this.state.hasError){const r=e("Fallback");return n.createElement(r,{name:t})}return r}}i.defaultProps={targetName:"this component",getComponent:()=>a.default,fn:{componentDidCatch:o.componentDidCatch},children:null};const s=i},29403:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=e=>{let{name:t}=e;return n.createElement("div",{className:"fallback"},"😱 ",n.createElement("i",null,"Could not render ","t"===t?"this component":t,", see the console."))}},56189:(e,t,r)=>{"use strict";r.r(t),r.d(t,{componentDidCatch:()=>i,withErrorBoundary:()=>s});var n=r(23101),o=r.n(n),a=r(67294);const i=console.error,s=e=>t=>{const{getComponent:r,fn:n}=e(),i=r("ErrorBoundary"),s=n.getDisplayName(t);class l extends a.Component{render(){return a.createElement(i,{targetName:s,getComponent:r,fn:n},a.createElement(t,o()({},this.props,this.context)))}}var u;return l.displayName=`WithErrorBoundary(${s})`,(u=t).prototype&&u.prototype.isReactComponent&&(l.prototype.mapStateToProps=t.prototype.mapStateToProps),l}},27621:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(47475),o=r.n(n),a=r(7287),i=r.n(a),s=r(36195),l=r(29403),u=r(56189);const c=function(){let{componentList:e=[],fullOverride:t=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return r=>{var n;let{getSystem:a}=r;const c=t?e:["App","BaseLayout","VersionPragmaFilter","InfoContainer","ServersContainer","SchemesContainer","AuthorizeBtnContainer","FilterContainer","Operations","OperationContainer","parameters","responses","OperationServers","Models","ModelWrapper",...e],p=i()(c,o()(n=Array(c.length)).call(n,((e,t)=>{let{fn:r}=t;return r.withErrorBoundary(e)})));return{fn:{componentDidCatch:u.componentDidCatch,withErrorBoundary:(0,u.withErrorBoundary)(a)},components:{ErrorBoundary:s.default,Fallback:l.default},wrapComponents:p}}}},57050:(e,t,r)=>{"use strict";r.r(t),r.d(t,{sampleFromSchemaGeneric:()=>F,inferSchema:()=>z,createXMLExample:()=>U,sampleFromSchema:()=>q,memoizedCreateXMLExample:()=>$,memoizedSampleFromSchema:()=>W});var n=r(11882),o=r.n(n),a=r(86),i=r.n(a),s=r(58309),l=r.n(s),u=r(58118),c=r.n(u),p=r(92039),f=r.n(p),h=r(24278),d=r.n(h),m=r(51679),g=r.n(m),v=r(39022),y=r.n(v),b=r(97606),w=r.n(b),E=r(35627),x=r.n(E),_=r(53479),S=r.n(_),A=r(14419),k=r.n(A),C=r(41609),O=r.n(C),j=r(90242),I=r(60314);const N={string:e=>e.pattern?(e=>{try{return new(k())(e).gen()}catch(e){return"string"}})(e.pattern):"string",string_email:()=>"user@example.com","string_date-time":()=>(new Date).toISOString(),string_date:()=>(new Date).toISOString().substring(0,10),string_uuid:()=>"3fa85f64-5717-4562-b3fc-2c963f66afa6",string_hostname:()=>"example.com",string_ipv4:()=>"198.51.100.42",string_ipv6:()=>"2001:0db8:5b96:0000:0000:426f:8e17:642a",number:()=>0,number_float:()=>0,integer:()=>0,boolean:e=>"boolean"!=typeof e.default||e.default},T=e=>{e=(0,j.mz)(e);let{type:t,format:r}=e,n=N[`${t}_${r}`]||N[t];return(0,j.Wl)(n)?n(e):"Unknown Type: "+e.type},P=e=>(0,j.XV)(e,"$$ref",(e=>"string"==typeof e&&o()(e).call(e,"#")>-1)),R=["maxProperties","minProperties"],M=["minItems","maxItems"],D=["minimum","maximum","exclusiveMinimum","exclusiveMaximum"],L=["minLength","maxLength"],B=function(e,t){var r;let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=r=>{void 0===t[r]&&void 0!==e[r]&&(t[r]=e[r])};var s;(i()(r=["example","default","enum","xml","type",...R,...M,...D,...L]).call(r,(e=>a(e))),void 0!==e.required&&l()(e.required))&&(void 0!==t.required&&t.required.length||(t.required=[]),i()(s=e.required).call(s,(e=>{var r;c()(r=t.required).call(r,e)||t.required.push(e)})));if(e.properties){t.properties||(t.properties={});let r=(0,j.mz)(e.properties);for(let a in r){var u;if(Object.prototype.hasOwnProperty.call(r,a))if(!r[a]||!r[a].deprecated)if(!r[a]||!r[a].readOnly||n.includeReadOnly)if(!r[a]||!r[a].writeOnly||n.includeWriteOnly)if(!t.properties[a])t.properties[a]=r[a],!e.required&&l()(e.required)&&-1!==o()(u=e.required).call(u,a)&&(t.required?t.required.push(a):t.required=[a])}}return e.items&&(t.items||(t.items={}),t.items=B(e.items,t.items,n)),t},F=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e&&(0,j.Wl)(e.toJS)&&(e=e.toJS());let a=void 0!==r||e&&void 0!==e.example||e&&void 0!==e.default;const s=!a&&e&&e.oneOf&&e.oneOf.length>0,u=!a&&e&&e.anyOf&&e.anyOf.length>0;if(!a&&(s||u)){const r=(0,j.mz)(s?e.oneOf[0]:e.anyOf[0]);if(B(r,e,t),!e.xml&&r.xml&&(e.xml=r.xml),void 0!==e.example&&void 0!==r.example)a=!0;else if(r.properties){e.properties||(e.properties={});let n=(0,j.mz)(r.properties);for(let a in n){var p;if(Object.prototype.hasOwnProperty.call(n,a))if(!n[a]||!n[a].deprecated)if(!n[a]||!n[a].readOnly||t.includeReadOnly)if(!n[a]||!n[a].writeOnly||t.includeWriteOnly)if(!e.properties[a])e.properties[a]=n[a],!r.required&&l()(r.required)&&-1!==o()(p=r.required).call(p,a)&&(e.required?e.required.push(a):e.required=[a])}}}const h={};let{xml:m,type:v,example:b,properties:E,additionalProperties:x,items:_}=e||{},{includeReadOnly:S,includeWriteOnly:A}=t;m=m||{};let k,{name:C,prefix:I,namespace:N}=m,L={};if(n&&(C=C||"notagname",k=(I?I+":":"")+C,N)){h[I?"xmlns:"+I:"xmlns"]=N}n&&(L[k]=[]);const z=t=>f()(t).call(t,(t=>Object.prototype.hasOwnProperty.call(e,t)));e&&!v&&(E||x||z(R)?v="object":_||z(M)?v="array":z(D)?(v="number",e.type="number"):a||e.enum||(v="string",e.type="string"));const U=t=>{var r,n,o,a,i;null!==(null===(r=e)||void 0===r?void 0:r.maxItems)&&void 0!==(null===(n=e)||void 0===n?void 0:n.maxItems)&&(t=d()(t).call(t,0,null===(i=e)||void 0===i?void 0:i.maxItems));if(null!==(null===(o=e)||void 0===o?void 0:o.minItems)&&void 0!==(null===(a=e)||void 0===a?void 0:a.minItems)){let r=0;for(;t.length<(null===(s=e)||void 0===s?void 0:s.minItems);){var s;t.push(t[r++%t.length])}}return t},q=(0,j.mz)(E);let V,$=0;const W=()=>e&&null!==e.maxProperties&&void 0!==e.maxProperties&&$>=e.maxProperties,H=()=>{if(!e||!e.required)return 0;let t=0;var r,o;n?i()(r=e.required).call(r,(e=>t+=void 0===L[e]?0:1)):i()(o=e.required).call(o,(e=>{var r;return t+=void 0===(null===(r=L[k])||void 0===r?void 0:g()(r).call(r,(t=>void 0!==t[e])))?0:1}));return e.required.length-t},J=t=>{var r;return!(e&&e.required&&e.required.length)||!c()(r=e.required).call(r,t)},K=t=>!e||null===e.maxProperties||void 0===e.maxProperties||!W()&&(!J(t)||e.maxProperties-$-H()>0);if(V=n?function(r){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;if(e&&q[r]){if(q[r].xml=q[r].xml||{},q[r].xml.attribute){const e=l()(q[r].enum)?q[r].enum[0]:void 0,t=q[r].example,n=q[r].default;return void(h[q[r].xml.name||r]=void 0!==t?t:void 0!==n?n:void 0!==e?e:T(q[r]))}q[r].xml.name=q[r].xml.name||r}else q[r]||!1===x||(q[r]={xml:{name:r}});let a=F(e&&q[r]||void 0,t,o,n);var i;K(r)&&($++,l()(a)?L[k]=y()(i=L[k]).call(i,a):L[k].push(a))}:(r,o)=>{if(K(r)){if(Object.prototype.hasOwnProperty.call(e,"discriminator")&&e.discriminator&&Object.prototype.hasOwnProperty.call(e.discriminator,"mapping")&&e.discriminator.mapping&&Object.prototype.hasOwnProperty.call(e,"$$ref")&&e.$$ref&&e.discriminator.propertyName===r){for(let t in e.discriminator.mapping)if(-1!==e.$$ref.search(e.discriminator.mapping[t])){L[r]=t;break}}else L[r]=F(q[r],t,o,n);$++}},a){let o;if(o=P(void 0!==r?r:void 0!==b?b:e.default),!n){if("number"==typeof o&&"string"===v)return`${o}`;if("string"!=typeof o||"string"===v)return o;try{return JSON.parse(o)}catch(e){return o}}if(e||(v=l()(o)?"array":typeof o),"array"===v){if(!l()(o)){if("string"==typeof o)return o;o=[o]}const r=e?e.items:void 0;r&&(r.xml=r.xml||m||{},r.xml.name=r.xml.name||m.name);let a=w()(o).call(o,(e=>F(r,t,e,n)));return a=U(a),m.wrapped?(L[k]=a,O()(h)||L[k].push({_attr:h})):L=a,L}if("object"===v){if("string"==typeof o)return o;for(let t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e&&q[t]&&q[t].readOnly&&!S||e&&q[t]&&q[t].writeOnly&&!A||(e&&q[t]&&q[t].xml&&q[t].xml.attribute?h[q[t].xml.name||t]=o[t]:V(t,o[t])));return O()(h)||L[k].push({_attr:h}),L}return L[k]=O()(h)?o:[{_attr:h},o],L}if("object"===v){for(let e in q)Object.prototype.hasOwnProperty.call(q,e)&&(q[e]&&q[e].deprecated||q[e]&&q[e].readOnly&&!S||q[e]&&q[e].writeOnly&&!A||V(e));if(n&&h&&L[k].push({_attr:h}),W())return L;if(!0===x)n?L[k].push({additionalProp:"Anything can be here"}):L.additionalProp1={},$++;else if(x){const r=(0,j.mz)(x),o=F(r,t,void 0,n);if(n&&r.xml&&r.xml.name&&"notagname"!==r.xml.name)L[k].push(o);else{const t=null!==e.minProperties&&void 0!==e.minProperties&&$F(B(_,e,t),t,void 0,n)));else if(l()(_.oneOf)){var Y;r=w()(Y=_.oneOf).call(Y,(e=>F(B(_,e,t),t,void 0,n)))}else{if(!(!n||n&&m.wrapped))return F(_,t,void 0,n);r=[F(_,t,void 0,n)]}return r=U(r),n&&m.wrapped?(L[k]=r,O()(h)||L[k].push({_attr:h}),L):r}let Q;if(e&&l()(e.enum))Q=(0,j.AF)(e.enum)[0];else{if(!e)return;if(Q=T(e),"number"==typeof Q){let t=e.minimum;null!=t&&(e.exclusiveMinimum&&t++,Q=t);let r=e.maximum;null!=r&&(e.exclusiveMaximum&&r--,Q=r)}if("string"==typeof Q&&(null!==e.maxLength&&void 0!==e.maxLength&&(Q=d()(Q).call(Q,0,e.maxLength)),null!==e.minLength&&void 0!==e.minLength)){let t=0;for(;Q.length(e.schema&&(e=e.schema),e.properties&&(e.type="object"),e),U=(e,t,r)=>{const n=F(e,t,r,!0);if(n)return"string"==typeof n?n:S()(n,{declaration:!0,indent:"\t"})},q=(e,t,r)=>F(e,t,r,!1),V=(e,t,r)=>[e,x()(t),x()(r)],$=(0,I.Z)(U,V),W=(0,I.Z)(q,V)},8883:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(57050);function o(){return{fn:n}}},51228:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_SPEC:()=>U,UPDATE_URL:()=>q,UPDATE_JSON:()=>V,UPDATE_PARAM:()=>$,UPDATE_EMPTY_PARAM_INCLUSION:()=>W,VALIDATE_PARAMS:()=>H,SET_RESPONSE:()=>J,SET_REQUEST:()=>K,SET_MUTATED_REQUEST:()=>G,LOG_REQUEST:()=>Z,CLEAR_RESPONSE:()=>Y,CLEAR_REQUEST:()=>Q,CLEAR_VALIDATE_PARAMS:()=>X,UPDATE_OPERATION_META_VALUE:()=>ee,UPDATE_RESOLVED:()=>te,UPDATE_RESOLVED_SUBTREE:()=>re,SET_SCHEME:()=>ne,updateSpec:()=>oe,updateResolved:()=>ae,updateUrl:()=>ie,updateJsonSpec:()=>se,parseToJson:()=>le,resolveSpec:()=>ce,requestResolvedSubtree:()=>he,changeParam:()=>de,changeParamByIdentity:()=>me,updateResolvedSubtree:()=>ge,invalidateResolvedSubtreeCache:()=>ve,validateParams:()=>ye,updateEmptyParamInclusion:()=>be,clearValidateParams:()=>we,changeConsumesValue:()=>Ee,changeProducesValue:()=>xe,setResponse:()=>_e,setRequest:()=>Se,setMutatedRequest:()=>Ae,logRequest:()=>ke,executeRequest:()=>Ce,execute:()=>Oe,clearResponse:()=>je,clearRequest:()=>Ie,setScheme:()=>Ne});var n=r(58309),o=r.n(n),a=r(97606),i=r.n(a),s=r(96718),l=r.n(s),u=r(24282),c=r.n(u),p=r(2250),f=r.n(p),h=r(6226),d=r.n(h),m=r(14418),g=r.n(m),v=r(3665),y=r.n(v),b=r(11882),w=r.n(b),E=r(86),x=r.n(E),_=r(28222),S=r.n(_),A=r(76986),k=r.n(A),C=r(70586),O=r.n(C),j=r(1272),I=r(43393),N=r(84564),T=r.n(N),P=r(7710),R=r(47037),M=r.n(R),D=r(23279),L=r.n(D),B=r(36968),F=r.n(B),z=r(90242);const U="spec_update_spec",q="spec_update_url",V="spec_update_json",$="spec_update_param",W="spec_update_empty_param_inclusion",H="spec_validate_param",J="spec_set_response",K="spec_set_request",G="spec_set_mutated_request",Z="spec_log_request",Y="spec_clear_response",Q="spec_clear_request",X="spec_clear_validate_param",ee="spec_update_operation_meta_value",te="spec_update_resolved",re="spec_update_resolved_subtree",ne="set_scheme";function oe(e){const t=(r=e,M()(r)?r:"").replace(/\t/g," ");var r;if("string"==typeof e)return{type:U,payload:t}}function ae(e){return{type:te,payload:e}}function ie(e){return{type:q,payload:e}}function se(e){return{type:V,payload:e}}const le=e=>t=>{let{specActions:r,specSelectors:n,errActions:o}=t,{specStr:a}=n,i=null;try{e=e||a(),o.clear({source:"parser"}),i=j.ZP.load(e,{schema:j.A8})}catch(e){return console.error(e),o.newSpecErr({source:"parser",level:"error",message:e.reason,line:e.mark&&e.mark.line?e.mark.line+1:void 0})}return i&&"object"==typeof i?r.updateJsonSpec(i):{}};let ue=!1;const ce=(e,t)=>r=>{let{specActions:n,specSelectors:a,errActions:s,fn:{fetch:u,resolve:c,AST:p={}},getConfigs:f}=r;ue||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),ue=!0);const{modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}=f();void 0===e&&(e=a.specJson()),void 0===t&&(t=a.url());let v=p.getLineNumberForPath?p.getLineNumberForPath:()=>{},y=a.specStr();return c({fetch:u,spec:e,baseDoc:t,modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}).then((e=>{let{spec:t,errors:r}=e;if(s.clear({type:"thrown"}),o()(r)&&r.length>0){let e=i()(r).call(r,(e=>(console.error(e),e.line=e.fullPath?v(y,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));s.newThrownErrBatch(e)}return n.updateResolved(t)}))};let pe=[];const fe=L()((async()=>{const e=pe.system;if(!e)return void console.error("debResolveSubtrees: don't have a system to operate on, aborting.");const{errActions:t,errSelectors:r,fn:{resolveSubtree:n,fetch:a,AST:s={}},specSelectors:u,specActions:p}=e;if(!n)return void console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.");let h=s.getLineNumberForPath?s.getLineNumberForPath:()=>{};const m=u.specStr(),{modelPropertyMacro:v,parameterMacro:b,requestInterceptor:w,responseInterceptor:E}=e.getConfigs();try{var x=await c()(pe).call(pe,(async(e,s)=>{const{resultMap:c,specWithCurrentSubtrees:p}=await e,{errors:x,spec:_}=await n(p,s,{baseDoc:u.url(),modelPropertyMacro:v,parameterMacro:b,requestInterceptor:w,responseInterceptor:E});if(r.allErrors().size&&t.clearBy((e=>{var t;return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!f()(t=e.get("fullPath")).call(t,((e,t)=>e===s[t]||void 0===s[t]))})),o()(x)&&x.length>0){let e=i()(x).call(x,(e=>(e.line=e.fullPath?h(m,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));t.newThrownErrBatch(e)}var S,A;_&&u.isOAS3()&&"components"===s[0]&&"securitySchemes"===s[1]&&await d().all(i()(S=g()(A=y()(_)).call(A,(e=>"openIdConnect"===e.type))).call(S,(async e=>{const t={url:e.openIdConnectUrl,requestInterceptor:w,responseInterceptor:E};try{const r=await a(t);r instanceof Error||r.status>=400?console.error(r.statusText+" "+t.url):e.openIdConnectData=JSON.parse(r.text)}catch(e){console.error(e)}})));return F()(c,s,_),F()(p,s,_),{resultMap:c,specWithCurrentSubtrees:p}}),d().resolve({resultMap:(u.specResolvedSubtree([])||(0,I.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));delete pe.system,pe=[]}catch(e){console.error(e)}p.updateResolvedSubtree([],x.resultMap)}),35),he=e=>t=>{var r;w()(r=i()(pe).call(pe,(e=>e.join("@@")))).call(r,e.join("@@"))>-1||(pe.push(e),pe.system=t,fe())};function de(e,t,r,n,o){return{type:$,payload:{path:e,value:n,paramName:t,paramIn:r,isXml:o}}}function me(e,t,r,n){return{type:$,payload:{path:e,param:t,value:r,isXml:n}}}const ge=(e,t)=>({type:re,payload:{path:e,value:t}}),ve=()=>({type:re,payload:{path:[],value:(0,I.Map)()}}),ye=(e,t)=>({type:H,payload:{pathMethod:e,isOAS3:t}}),be=(e,t,r,n)=>({type:W,payload:{pathMethod:e,paramName:t,paramIn:r,includeEmptyValue:n}});function we(e){return{type:X,payload:{pathMethod:e}}}function Ee(e,t){return{type:ee,payload:{path:e,value:t,key:"consumes_value"}}}function xe(e,t){return{type:ee,payload:{path:e,value:t,key:"produces_value"}}}const _e=(e,t,r)=>({payload:{path:e,method:t,res:r},type:J}),Se=(e,t,r)=>({payload:{path:e,method:t,req:r},type:K}),Ae=(e,t,r)=>({payload:{path:e,method:t,req:r},type:G}),ke=e=>({payload:e,type:Z}),Ce=e=>t=>{let{fn:r,specActions:n,specSelectors:a,getConfigs:s,oas3Selectors:l}=t,{pathName:u,method:c,operation:p}=e,{requestInterceptor:f,responseInterceptor:h}=s(),d=p.toJS();var m,v;p&&p.get("parameters")&&x()(m=g()(v=p.get("parameters")).call(v,(e=>e&&!0===e.get("allowEmptyValue")))).call(m,(t=>{if(a.parameterInclusionSettingFor([u,c],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};const r=(0,z.cz)(t,e.parameters);(!r||r&&0===r.size)&&(e.parameters[t.get("name")]="")}}));if(e.contextUrl=T()(a.url()).toString(),d&&d.operationId?e.operationId=d.operationId:d&&u&&c&&(e.operationId=r.opId(d,u,c)),a.isOAS3()){const t=`${u}:${c}`;e.server=l.selectedServer(t)||l.selectedServer();const r=l.serverVariables({server:e.server,namespace:t}).toJS(),n=l.serverVariables({server:e.server}).toJS();e.serverVariables=S()(r).length?r:n,e.requestContentType=l.requestContentType(u,c),e.responseContentType=l.responseContentType(u,c)||"*/*";const a=l.requestBodyValue(u,c),s=l.requestBodyInclusionSetting(u,c);var y;if(a&&a.toJS)e.requestBody=g()(y=i()(a).call(a,(e=>I.Map.isMap(e)?e.get("value"):e))).call(y,((e,t)=>(o()(e)?0!==e.length:!(0,z.O2)(e))||s.get(t))).toJS();else e.requestBody=a}let b=k()({},e);b=r.buildRequest(b),n.setRequest(e.pathName,e.method,b);e.requestInterceptor=async t=>{let r=await f.apply(void 0,[t]),o=k()({},r);return n.setMutatedRequest(e.pathName,e.method,o),r},e.responseInterceptor=h;const w=O()();return r.execute(e).then((t=>{t.duration=O()()-w,n.setResponse(e.pathName,e.method,t)})).catch((t=>{"Failed to fetch"===t.message&&(t.name="",t.message='**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.'),n.setResponse(e.pathName,e.method,{error:!0,err:(0,P.serializeError)(t)})}))},Oe=function(){let{path:e,method:t,...r}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return n=>{let{fn:{fetch:o},specSelectors:a,specActions:i}=n,s=a.specJsonWithResolvedSubtrees().toJS(),l=a.operationScheme(e,t),{requestContentType:u,responseContentType:c}=a.contentTypeValues([e,t]).toJS(),p=/xml/i.test(u),f=a.parameterValues([e,t],p).toJS();return i.executeRequest({...r,fetch:o,spec:s,pathName:e,method:t,parameters:f,requestContentType:u,scheme:l,responseContentType:c})}};function je(e,t){return{type:Y,payload:{path:e,method:t}}}function Ie(e,t){return{type:Q,payload:{path:e,method:t}}}function Ne(e,t,r){return{type:ne,payload:{scheme:e,path:t,method:r}}}},37038:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(20032),o=r(51228),a=r(33881),i=r(77508);function s(){return{statePlugins:{spec:{wrapActions:i,reducers:n.default,actions:o,selectors:a}}}}},20032:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>d});var n=r(24282),o=r.n(n),a=r(97606),i=r.n(a),s=r(76986),l=r.n(s),u=r(43393),c=r(90242),p=r(27504),f=r(33881),h=r(51228);const d={[h.UPDATE_SPEC]:(e,t)=>"string"==typeof t.payload?e.set("spec",t.payload):e,[h.UPDATE_URL]:(e,t)=>e.set("url",t.payload+""),[h.UPDATE_JSON]:(e,t)=>e.set("json",(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED]:(e,t)=>e.setIn(["resolved"],(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED_SUBTREE]:(e,t)=>{const{value:r,path:n}=t.payload;return e.setIn(["resolvedSubtrees",...n],(0,c.oG)(r))},[h.UPDATE_PARAM]:(e,t)=>{let{payload:r}=t,{path:n,paramName:o,paramIn:a,param:i,value:s,isXml:l}=r,u=i?(0,c.V9)(i):`${a}.${o}`;const p=l?"value_xml":"value";return e.setIn(["meta","paths",...n,"parameters",u,p],s)},[h.UPDATE_EMPTY_PARAM_INCLUSION]:(e,t)=>{let{payload:r}=t,{pathMethod:n,paramName:o,paramIn:a,includeEmptyValue:i}=r;if(!o||!a)return console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey."),e;const s=`${a}.${o}`;return e.setIn(["meta","paths",...n,"parameter_inclusions",s],i)},[h.VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:r,isOAS3:n}}=t;const a=(0,f.specJsonWithResolvedSubtrees)(e).getIn(["paths",...r]),i=(0,f.parameterValues)(e,r).toJS();return e.updateIn(["meta","paths",...r,"parameters"],(0,u.fromJS)({}),(t=>{var s;return o()(s=a.get("parameters",(0,u.List)())).call(s,((t,o)=>{const a=(0,c.cz)(o,i),s=(0,f.parameterInclusionSettingFor)(e,r,o.get("name"),o.get("in")),l=(0,c.Ik)(o,a,{bypassRequiredCheck:s,isOAS3:n});return t.setIn([(0,c.V9)(o),"errors"],(0,u.fromJS)(l))}),t)}))},[h.CLEAR_VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:r}}=t;return e.updateIn(["meta","paths",...r,"parameters"],(0,u.fromJS)([]),(e=>i()(e).call(e,(e=>e.set("errors",(0,u.fromJS)([]))))))},[h.SET_RESPONSE]:(e,t)=>{let r,{payload:{res:n,path:o,method:a}}=t;r=n.error?l()({error:!0,name:n.err.name,message:n.err.message,statusCode:n.err.statusCode},n.err.response):n,r.headers=r.headers||{};let i=e.setIn(["responses",o,a],(0,c.oG)(r));return p.Z.Blob&&n.data instanceof p.Z.Blob&&(i=i.setIn(["responses",o,a,"text"],n.data)),i},[h.SET_REQUEST]:(e,t)=>{let{payload:{req:r,path:n,method:o}}=t;return e.setIn(["requests",n,o],(0,c.oG)(r))},[h.SET_MUTATED_REQUEST]:(e,t)=>{let{payload:{req:r,path:n,method:o}}=t;return e.setIn(["mutatedRequests",n,o],(0,c.oG)(r))},[h.UPDATE_OPERATION_META_VALUE]:(e,t)=>{let{payload:{path:r,value:n,key:o}}=t,a=["paths",...r],i=["meta","paths",...r];return e.getIn(["json",...a])||e.getIn(["resolved",...a])||e.getIn(["resolvedSubtrees",...a])?e.setIn([...i,o],(0,u.fromJS)(n)):e},[h.CLEAR_RESPONSE]:(e,t)=>{let{payload:{path:r,method:n}}=t;return e.deleteIn(["responses",r,n])},[h.CLEAR_REQUEST]:(e,t)=>{let{payload:{path:r,method:n}}=t;return e.deleteIn(["requests",r,n])},[h.SET_SCHEME]:(e,t)=>{let{payload:{scheme:r,path:n,method:o}}=t;return n&&o?e.setIn(["scheme",n,o],r):n||o?void 0:e.setIn(["scheme","_defaultScheme"],r)}}},33881:(e,t,r)=>{"use strict";r.r(t),r.d(t,{lastError:()=>O,url:()=>j,specStr:()=>I,specSource:()=>N,specJson:()=>T,specResolved:()=>P,specResolvedSubtree:()=>R,specJsonWithResolvedSubtrees:()=>D,spec:()=>L,isOAS3:()=>B,info:()=>F,externalDocs:()=>z,version:()=>U,semver:()=>q,paths:()=>V,operations:()=>$,consumes:()=>W,produces:()=>H,security:()=>J,securityDefinitions:()=>K,findDefinition:()=>G,definitions:()=>Z,basePath:()=>Y,host:()=>Q,schemes:()=>X,operationsWithRootInherited:()=>ee,tags:()=>te,tagDetails:()=>re,operationsWithTags:()=>ne,taggedOperations:()=>oe,responses:()=>ae,requests:()=>ie,mutatedRequests:()=>se,responseFor:()=>le,requestFor:()=>ue,mutatedRequestFor:()=>ce,allowTryItOutFor:()=>pe,parameterWithMetaByIdentity:()=>fe,parameterInclusionSettingFor:()=>he,parameterWithMeta:()=>de,operationWithMeta:()=>me,getParameter:()=>ge,hasHost:()=>ve,parameterValues:()=>ye,parametersIncludeIn:()=>be,parametersIncludeType:()=>we,contentTypeValues:()=>Ee,currentProducesFor:()=>xe,producesOptionsFor:()=>_e,consumesOptionsFor:()=>Se,operationScheme:()=>Ae,canExecuteScheme:()=>ke,validationErrors:()=>Ce,validateBeforeExecute:()=>Oe,getOAS3RequiredRequestBodyContentType:()=>je,isMediaTypeSchemaPropertiesEqual:()=>Ie});var n=r(24278),o=r.n(n),a=r(86),i=r.n(a),s=r(11882),l=r.n(s),u=r(97606),c=r.n(u),p=r(14418),f=r.n(p),h=r(51679),d=r.n(h),m=r(24282),g=r.n(m),v=r(2578),y=r.n(v),b=r(92039),w=r.n(b),E=r(58309),x=r.n(E),_=r(20573),S=r(90242),A=r(43393);const k=["get","put","post","delete","options","head","patch","trace"],C=e=>e||(0,A.Map)(),O=(0,_.P1)(C,(e=>e.get("lastError"))),j=(0,_.P1)(C,(e=>e.get("url"))),I=(0,_.P1)(C,(e=>e.get("spec")||"")),N=(0,_.P1)(C,(e=>e.get("specSource")||"not-editor")),T=(0,_.P1)(C,(e=>e.get("json",(0,A.Map)()))),P=(0,_.P1)(C,(e=>e.get("resolved",(0,A.Map)()))),R=(e,t)=>e.getIn(["resolvedSubtrees",...t],void 0),M=(e,t)=>A.Map.isMap(e)&&A.Map.isMap(t)?t.get("$$ref")?t:(0,A.OrderedMap)().mergeWith(M,e,t):t,D=(0,_.P1)(C,(e=>(0,A.OrderedMap)().mergeWith(M,e.get("json"),e.get("resolvedSubtrees")))),L=e=>T(e),B=(0,_.P1)(L,(()=>!1)),F=(0,_.P1)(L,(e=>Ne(e&&e.get("info")))),z=(0,_.P1)(L,(e=>Ne(e&&e.get("externalDocs")))),U=(0,_.P1)(F,(e=>e&&e.get("version"))),q=(0,_.P1)(U,(e=>{var t;return o()(t=/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(e)).call(t,1)})),V=(0,_.P1)(D,(e=>e.get("paths"))),$=(0,_.P1)(V,(e=>{if(!e||e.size<1)return(0,A.List)();let t=(0,A.List)();return e&&i()(e)?(i()(e).call(e,((e,r)=>{if(!e||!i()(e))return{};i()(e).call(e,((e,n)=>{l()(k).call(k,n)<0||(t=t.push((0,A.fromJS)({path:r,method:n,operation:e,id:`${n}-${r}`})))}))})),t):(0,A.List)()})),W=(0,_.P1)(L,(e=>(0,A.Set)(e.get("consumes")))),H=(0,_.P1)(L,(e=>(0,A.Set)(e.get("produces")))),J=(0,_.P1)(L,(e=>e.get("security",(0,A.List)()))),K=(0,_.P1)(L,(e=>e.get("securityDefinitions"))),G=(e,t)=>{const r=e.getIn(["resolvedSubtrees","definitions",t],null),n=e.getIn(["json","definitions",t],null);return r||n||null},Z=(0,_.P1)(L,(e=>{const t=e.get("definitions");return A.Map.isMap(t)?t:(0,A.Map)()})),Y=(0,_.P1)(L,(e=>e.get("basePath"))),Q=(0,_.P1)(L,(e=>e.get("host"))),X=(0,_.P1)(L,(e=>e.get("schemes",(0,A.Map)()))),ee=(0,_.P1)($,W,H,((e,t,r)=>c()(e).call(e,(e=>e.update("operation",(e=>{if(e){if(!A.Map.isMap(e))return;return e.withMutations((e=>(e.get("consumes")||e.update("consumes",(e=>(0,A.Set)(e).merge(t))),e.get("produces")||e.update("produces",(e=>(0,A.Set)(e).merge(r))),e)))}return(0,A.Map)()})))))),te=(0,_.P1)(L,(e=>{const t=e.get("tags",(0,A.List)());return A.List.isList(t)?f()(t).call(t,(e=>A.Map.isMap(e))):(0,A.List)()})),re=(e,t)=>{var r;let n=te(e)||(0,A.List)();return d()(r=f()(n).call(n,A.Map.isMap)).call(r,(e=>e.get("name")===t),(0,A.Map)())},ne=(0,_.P1)(ee,te,((e,t)=>g()(e).call(e,((e,t)=>{let r=(0,A.Set)(t.getIn(["operation","tags"]));return r.count()<1?e.update("default",(0,A.List)(),(e=>e.push(t))):g()(r).call(r,((e,r)=>e.update(r,(0,A.List)(),(e=>e.push(t)))),e)}),g()(t).call(t,((e,t)=>e.set(t.get("name"),(0,A.List)())),(0,A.OrderedMap)())))),oe=e=>t=>{var r;let{getConfigs:n}=t,{tagsSorter:o,operationsSorter:a}=n();return c()(r=ne(e).sortBy(((e,t)=>t),((e,t)=>{let r="function"==typeof o?o:S.wh.tagsSorter[o];return r?r(e,t):null}))).call(r,((t,r)=>{let n="function"==typeof a?a:S.wh.operationsSorter[a],o=n?y()(t).call(t,n):t;return(0,A.Map)({tagDetails:re(e,r),operations:o})}))},ae=(0,_.P1)(C,(e=>e.get("responses",(0,A.Map)()))),ie=(0,_.P1)(C,(e=>e.get("requests",(0,A.Map)()))),se=(0,_.P1)(C,(e=>e.get("mutatedRequests",(0,A.Map)()))),le=(e,t,r)=>ae(e).getIn([t,r],null),ue=(e,t,r)=>ie(e).getIn([t,r],null),ce=(e,t,r)=>se(e).getIn([t,r],null),pe=()=>!0,fe=(e,t,r)=>{const n=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),o=e.getIn(["meta","paths",...t,"parameters"],(0,A.OrderedMap)()),a=c()(n).call(n,(e=>{const t=o.get(`${r.get("in")}.${r.get("name")}`),n=o.get(`${r.get("in")}.${r.get("name")}.hash-${r.hashCode()}`);return(0,A.OrderedMap)().merge(e,t,n)}));return d()(a).call(a,(e=>e.get("in")===r.get("in")&&e.get("name")===r.get("name")),(0,A.OrderedMap)())},he=(e,t,r,n)=>{const o=`${n}.${r}`;return e.getIn(["meta","paths",...t,"parameter_inclusions",o],!1)},de=(e,t,r,n)=>{const o=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),a=d()(o).call(o,(e=>e.get("in")===n&&e.get("name")===r),(0,A.OrderedMap)());return fe(e,t,a)},me=(e,t,r)=>{var n;const o=D(e).getIn(["paths",t,r],(0,A.OrderedMap)()),a=e.getIn(["meta","paths",t,r],(0,A.OrderedMap)()),i=c()(n=o.get("parameters",(0,A.List)())).call(n,(n=>fe(e,[t,r],n)));return(0,A.OrderedMap)().merge(o,a).set("parameters",i)};function ge(e,t,r,n){t=t||[];let o=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([]));return d()(o).call(o,(e=>A.Map.isMap(e)&&e.get("name")===r&&e.get("in")===n))||(0,A.Map)()}const ve=(0,_.P1)(L,(e=>{const t=e.get("host");return"string"==typeof t&&t.length>0&&"/"!==t[0]}));function ye(e,t,r){t=t||[];let n=me(e,...t).get("parameters",(0,A.List)());return g()(n).call(n,((e,t)=>{let n=r&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set((0,S.V9)(t,{allowHashes:!1}),n)}),(0,A.fromJS)({}))}function be(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("in")===t))}function we(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("type")===t))}function Ee(e,t){t=t||[];let r=D(e).getIn(["paths",...t],(0,A.fromJS)({})),n=e.getIn(["meta","paths",...t],(0,A.fromJS)({})),o=xe(e,t);const a=r.get("parameters")||new A.List,i=n.get("consumes_value")?n.get("consumes_value"):we(a,"file")?"multipart/form-data":we(a,"formData")?"application/x-www-form-urlencoded":void 0;return(0,A.fromJS)({requestContentType:i,responseContentType:o})}function xe(e,t){t=t||[];const r=D(e).getIn(["paths",...t],null);if(null===r)return;const n=e.getIn(["meta","paths",...t,"produces_value"],null),o=r.getIn(["produces",0],null);return n||o||"application/json"}function _e(e,t){t=t||[];const r=D(e),n=r.getIn(["paths",...t],null);if(null===n)return;const[o]=t,a=n.get("produces",null),i=r.getIn(["paths",o,"produces"],null),s=r.getIn(["produces"],null);return a||i||s}function Se(e,t){t=t||[];const r=D(e),n=r.getIn(["paths",...t],null);if(null===n)return;const[o]=t,a=n.get("consumes",null),i=r.getIn(["paths",o,"consumes"],null),s=r.getIn(["consumes"],null);return a||i||s}const Ae=(e,t,r)=>{let n=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),o=x()(n)?n[1]:null;return e.getIn(["scheme",t,r])||e.getIn(["scheme","_defaultScheme"])||o||""},ke=(e,t,r)=>{var n;return l()(n=["http","https"]).call(n,Ae(e,t,r))>-1},Ce=(e,t)=>{t=t||[];let r=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([]));const n=[];return i()(r).call(r,(e=>{let t=e.get("errors");t&&t.count()&&i()(t).call(t,(e=>n.push(e)))})),n},Oe=(e,t)=>0===Ce(e,t).length,je=(e,t)=>{var r;let n={requestBody:!1,requestContentType:{}},o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody"],(0,A.fromJS)([]));return o.size<1||(o.getIn(["required"])&&(n.requestBody=o.getIn(["required"])),i()(r=o.getIn(["content"]).entrySeq()).call(r,(e=>{const t=e[0];if(e[1].getIn(["schema","required"])){const r=e[1].getIn(["schema","required"]).toJS();n.requestContentType[t]=r}}))),n},Ie=(e,t,r,n)=>{if((r||n)&&r===n)return!0;let o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody","content"],(0,A.fromJS)([]));if(o.size<2||!r||!n)return!1;let a=o.getIn([r,"schema","properties"],(0,A.fromJS)([])),i=o.getIn([n,"schema","properties"],(0,A.fromJS)([]));return!!a.equals(i)};function Ne(e){return A.Map.isMap(e)?e:new A.Map}},77508:(e,t,r)=>{"use strict";r.r(t),r.d(t,{updateSpec:()=>u,updateJsonSpec:()=>c,executeRequest:()=>p,validateParams:()=>f});var n=r(28222),o=r.n(n),a=r(86),i=r.n(a),s=r(27361),l=r.n(s);const u=(e,t)=>{let{specActions:r}=t;return function(){e(...arguments),r.parseToJson(...arguments)}},c=(e,t)=>{let{specActions:r}=t;return function(){for(var t=arguments.length,n=new Array(t),a=0;a{l()(u,[e]).$ref&&r.requestResolvedSubtree(["paths",e])})),r.requestResolvedSubtree(["components","securitySchemes"])}},p=(e,t)=>{let{specActions:r}=t;return t=>(r.logRequest(t),e(t))},f=(e,t)=>{let{specSelectors:r}=t;return t=>e(t,r.isOAS3())}},34852:(e,t,r)=>{"use strict";r.r(t),r.d(t,{loaded:()=>n});const n=(e,t)=>function(){e(...arguments);const r=t.getConfigs().withCredentials;void 0!==r&&(t.fn.fetch.withCredentials="string"==typeof r?"true"===r:!!r)}},48792:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>qr});var n={};r.r(n),r.d(n,{JsonPatchError:()=>Fe,_areEquals:()=>Ge,applyOperation:()=>$e,applyPatch:()=>We,applyReducer:()=>He,deepClone:()=>ze,getValueByPointer:()=>Ve,validate:()=>Ke,validator:()=>Je});var o={};r.r(o),r.d(o,{compare:()=>nt,generate:()=>tt,observe:()=>et,unobserve:()=>Xe});var a={};r.r(a),r.d(a,{cookie:()=>kr,header:()=>Ar,path:()=>xr,query:()=>_r});var i=r(80093),s=r.n(i),l=r(30222),u=r.n(l),c=r(36594),p=r.n(c),f=r(20474),h=r.n(f),d=r(67375),m=r.n(d),g=r(58118),v=r.n(g),y=r(74386),b=r.n(y),w=r(25110),E=r.n(w),x=r(35627),_=r.n(x),S=r(97606),A=r.n(S),k=r(28222),C=r.n(k),O=r(39022),j=r.n(O),I=r(2018),N=r.n(I),T=r(14418),P=r.n(T),R=(r(31905),r(80129)),M=r.n(R),D=r(1272);const L="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window,{FormData:B,Blob:F,File:z}=L;var U=r(15687),q=r.n(U),V=r(24278),$=r.n(V),W=function(e){return":/?#[]@!$&'()*+,;=".indexOf(e)>-1},H=function(e){return/^[a-z0-9\-._~]+$/i.test(e)};function J(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=r.escape,o=arguments.length>2?arguments[2]:void 0;return"number"==typeof e&&(e=e.toString()),"string"==typeof e&&e.length&&n?o?JSON.parse(e):A()(t=q()(e)).call(t,(function(e){var t,r;if(H(e))return e;if(W(e)&&"unsafe"===n)return e;var o=new TextEncoder;return A()(t=A()(r=E()(o.encode(e))).call(r,(function(e){var t;return $()(t="0".concat(e.toString(16).toUpperCase())).call(t,-2)}))).call(t,(function(e){return"%".concat(e)})).join("")})).join(""):e}function K(e){var t=e.value;return Array.isArray(t)?function(e){var t=e.key,r=e.value,n=e.style,o=e.explode,a=e.escape,i=function(e){return J(e,{escape:a})};if("simple"===n)return A()(r).call(r,(function(e){return i(e)})).join(",");if("label"===n)return".".concat(A()(r).call(r,(function(e){return i(e)})).join("."));if("matrix"===n)return A()(r).call(r,(function(e){return i(e)})).reduce((function(e,r){var n,a,i;return!e||o?j()(a=j()(i="".concat(e||"",";")).call(i,t,"=")).call(a,r):j()(n="".concat(e,",")).call(n,r)}),"");if("form"===n){var s=o?"&".concat(t,"="):",";return A()(r).call(r,(function(e){return i(e)})).join(s)}if("spaceDelimited"===n){var l=o?"".concat(t,"="):"";return A()(r).call(r,(function(e){return i(e)})).join(" ".concat(l))}if("pipeDelimited"===n){var u=o?"".concat(t,"="):"";return A()(r).call(r,(function(e){return i(e)})).join("|".concat(u))}return}(e):"object"===h()(t)?function(e){var t=e.key,r=e.value,n=e.style,o=e.explode,a=e.escape,i=function(e){return J(e,{escape:a})},s=C()(r);if("simple"===n)return s.reduce((function(e,t){var n,a,s,l=i(r[t]),u=o?"=":",",c=e?"".concat(e,","):"";return j()(n=j()(a=j()(s="".concat(c)).call(s,t)).call(a,u)).call(n,l)}),"");if("label"===n)return s.reduce((function(e,t){var n,a,s,l=i(r[t]),u=o?"=":".",c=e?"".concat(e,"."):".";return j()(n=j()(a=j()(s="".concat(c)).call(s,t)).call(a,u)).call(n,l)}),"");if("matrix"===n&&o)return s.reduce((function(e,t){var n,o,a=i(r[t]),s=e?"".concat(e,";"):";";return j()(n=j()(o="".concat(s)).call(o,t,"=")).call(n,a)}),"");if("matrix"===n)return s.reduce((function(e,n){var o,a,s=i(r[n]),l=e?"".concat(e,","):";".concat(t,"=");return j()(o=j()(a="".concat(l)).call(a,n,",")).call(o,s)}),"");if("form"===n)return s.reduce((function(e,t){var n,a,s,l,u=i(r[t]),c=e?j()(n="".concat(e)).call(n,o?"&":","):"",p=o?"=":",";return j()(a=j()(s=j()(l="".concat(c)).call(l,t)).call(s,p)).call(a,u)}),"");return}(e):function(e){var t,r=e.key,n=e.value,o=e.style,a=e.escape,i=function(e){return J(e,{escape:a})};if("simple"===o)return i(n);if("label"===o)return".".concat(i(n));if("matrix"===o)return j()(t=";".concat(r,"=")).call(t,i(n));if("form"===o)return i(n);if("deepObject"===o)return i(n,{},!0);return}(e)}const G=function(e,t){t.body=e};var Z={serializeRes:te,mergeInQueryOrForm:fe};function Y(e){return Q.apply(this,arguments)}function Q(){return Q=s()(u().mark((function e(t){var r,n,o,a,i,s=arguments;return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=s.length>1&&void 0!==s[1]?s[1]:{},"object"===h()(t)&&(t=(r=t).url),r.headers=r.headers||{},Z.mergeInQueryOrForm(r),r.headers&&C()(r.headers).forEach((function(e){var t=r.headers[e];"string"==typeof t&&(r.headers[e]=t.replace(/\n+/g," "))})),!r.requestInterceptor){e.next=12;break}return e.next=8,r.requestInterceptor(r);case 8:if(e.t0=e.sent,e.t0){e.next=11;break}e.t0=r;case 11:r=e.t0;case 12:return n=r.headers["content-type"]||r.headers["Content-Type"],/multipart\/form-data/i.test(n)&&r.body instanceof B&&(delete r.headers["content-type"],delete r.headers["Content-Type"]),e.prev=14,e.next=17,(r.userFetch||fetch)(r.url,r);case 17:return o=e.sent,e.next=20,Z.serializeRes(o,t,r);case 20:if(o=e.sent,!r.responseInterceptor){e.next=28;break}return e.next=24,r.responseInterceptor(o);case 24:if(e.t1=e.sent,e.t1){e.next=27;break}e.t1=o;case 27:o=e.t1;case 28:e.next=39;break;case 30:if(e.prev=30,e.t2=e.catch(14),o){e.next=34;break}throw e.t2;case 34:throw(a=new Error(o.statusText||"response status is ".concat(o.status))).status=o.status,a.statusCode=o.status,a.responseError=e.t2,a;case 39:if(o.ok){e.next=45;break}throw(i=new Error(o.statusText||"response status is ".concat(o.status))).status=o.status,i.statusCode=o.status,i.response=o,i;case 45:return e.abrupt("return",o);case 46:case"end":return e.stop()}}),e,null,[[14,30]])}))),Q.apply(this,arguments)}var X=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return/(json|xml|yaml|text)\b/.test(e)};function ee(e,t){return t&&(0===t.indexOf("application/json")||t.indexOf("+json")>0)?JSON.parse(e):D.ZP.load(e)}function te(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=r.loadSpec,o=void 0!==n&&n,a={ok:e.ok,url:e.url||t,status:e.status,statusText:e.statusText,headers:ne(e.headers)},i=a.headers["content-type"],s=o||X(i),l=s?e.text:e.blob||e.buffer;return l.call(e).then((function(e){if(a.text=e,a.data=e,s)try{var t=ee(e,i);a.body=t,a.obj=t}catch(e){a.parseError=e}return a}))}function re(e){return v()(e).call(e,", ")?e.split(", "):e}function ne(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return"function"!=typeof b()(e)?{}:E()(b()(e).call(e)).reduce((function(e,t){var r=m()(t,2),n=r[0],o=r[1];return e[n]=re(o),e}),{})}function oe(e,t){return t||"undefined"==typeof navigator||(t=navigator),t&&"ReactNative"===t.product?!(!e||"object"!==h()(e)||"string"!=typeof e.uri):void 0!==z&&e instanceof z||(void 0!==F&&e instanceof F||(!!ArrayBuffer.isView(e)||null!==e&&"object"===h()(e)&&"function"==typeof e.pipe))}function ae(e,t){return Array.isArray(e)&&e.some((function(e){return oe(e,t)}))}var ie={form:",",spaceDelimited:"%20",pipeDelimited:"|"},se={csv:",",ssv:"%20",tsv:"%09",pipes:"|"};function le(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=t.collectionFormat,o=t.allowEmptyValue,a=t.serializationOption,i=t.encoding,s="object"!==h()(t)||Array.isArray(t)?t:t.value,l=r?function(e){return e.toString()}:function(e){return encodeURIComponent(e)},u=l(e);if(void 0===s&&o)return[[u,""]];if(oe(s)||ae(s))return[[u,s]];if(a)return ue(e,s,r,a);if(i){if([h()(i.style),h()(i.explode),h()(i.allowReserved)].some((function(e){return"undefined"!==e}))){var c=i.style,p=i.explode,f=i.allowReserved;return ue(e,s,r,{style:c,explode:p,allowReserved:f})}if(i.contentType){if("application/json"===i.contentType){var d="string"==typeof s?s:_()(s);return[[u,l(d)]]}return[[u,l(s.toString())]]}return"object"!==h()(s)?[[u,l(s)]]:Array.isArray(s)&&s.every((function(e){return"object"!==h()(e)}))?[[u,A()(s).call(s,l).join(",")]]:[[u,l(_()(s))]]}return"object"!==h()(s)?[[u,l(s)]]:Array.isArray(s)?"multi"===n?[[u,A()(s).call(s,l)]]:[[u,A()(s).call(s,l).join(se[n||"csv"])]]:[[u,""]]}function ue(e,t,r,n){var o,a,i,s=n.style||"form",l=void 0===n.explode?"form"===s:n.explode,u=!r&&(n&&n.allowReserved?"unsafe":"reserved"),c=function(e){return J(e,{escape:u})},p=r?function(e){return e}:function(e){return J(e,{escape:u})};return"object"!==h()(t)?[[p(e),c(t)]]:Array.isArray(t)?l?[[p(e),A()(t).call(t,c)]]:[[p(e),A()(t).call(t,c).join(ie[s])]]:"deepObject"===s?A()(a=C()(t)).call(a,(function(r){var n;return[p(j()(n="".concat(e,"[")).call(n,r,"]")),c(t[r])]})):l?A()(i=C()(t)).call(i,(function(e){return[p(e),c(t[e])]})):[[p(e),A()(o=C()(t)).call(o,(function(e){var r;return[j()(r="".concat(p(e),",")).call(r,c(t[e]))]})).join(",")]]}function ce(e){return N()(e).reduce((function(e,t){var r,n=m()(t,2),o=n[0],a=n[1],i=p()(le(o,a,!0));try{for(i.s();!(r=i.n()).done;){var s=m()(r.value,2),l=s[0],u=s[1];if(Array.isArray(u)){var c,f=p()(u);try{for(f.s();!(c=f.n()).done;){var h=c.value;if(ArrayBuffer.isView(h)){var d=new F([h]);e.append(l,d)}else e.append(l,h)}}catch(e){f.e(e)}finally{f.f()}}else if(ArrayBuffer.isView(u)){var g=new F([u]);e.append(l,g)}else e.append(l,u)}}catch(e){i.e(e)}finally{i.f()}return e}),new B)}function pe(e){var t=C()(e).reduce((function(t,r){var n,o=p()(le(r,e[r]));try{for(o.s();!(n=o.n()).done;){var a=m()(n.value,2),i=a[0],s=a[1];t[i]=s}}catch(e){o.e(e)}finally{o.f()}return t}),{});return M().stringify(t,{encode:!1,indices:!1})||""}function fe(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.url,r=void 0===t?"":t,n=e.query,o=e.form,a=function(){for(var e=arguments.length,t=new Array(e),r=0;r=48&&t<=57))return!1;r++}return!0}function Re(e){return-1===e.indexOf("/")&&-1===e.indexOf("~")?e:e.replace(/~/g,"~0").replace(/\//g,"~1")}function Me(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}function De(e){if(void 0===e)return!0;if(e)if(Array.isArray(e)){for(var t=0,r=e.length;t0&&"constructor"==s[u-1]))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(r&&void 0===p&&(void 0===l[f]?p=s.slice(0,u).join("/"):u==c-1&&(p=t.path),void 0!==p&&h(t,0,e,p)),u++,Array.isArray(l)){if("-"===f)f=l.length;else{if(r&&!Pe(f))throw new Fe("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",a,t,e);Pe(f)&&(f=~~f)}if(u>=c){if(r&&"add"===t.op&&f>l.length)throw new Fe("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",a,t,e);if(!1===(i=qe[t.op].call(t,l,f,e)).test)throw new Fe("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}}else if(u>=c){if(!1===(i=Ue[t.op].call(t,l,f,e)).test)throw new Fe("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}if(l=l[f],r&&u0)throw new Fe('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",t,e,r);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new Fe("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",t,e,r);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new Fe("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",t,e,r);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&De(e.value))throw new Fe("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",t,e,r);if(r)if("add"==e.op){var o=e.path.split("/").length,a=n.split("/").length;if(o!==a+1&&o!==a)throw new Fe("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",t,e,r)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==n)throw new Fe("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",t,e,r)}else if("move"===e.op||"copy"===e.op){var i=Ke([{op:"_get",path:e.from,value:void 0}],r);if(i&&"OPERATION_PATH_UNRESOLVABLE"===i.name)throw new Fe("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",t,e,r)}}function Ke(e,t,r){try{if(!Array.isArray(e))throw new Fe("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(t)We(Te(t),Te(e),r||!0);else{r=r||Je;for(var n=0;n0&&(e.patches=[],e.callback&&e.callback(n)),n}function rt(e,t,r,n,o){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var a=Ne(t),i=Ne(e),s=!1,l=i.length-1;l>=0;l--){var u=e[p=i[l]];if(!Ie(t,p)||void 0===t[p]&&void 0!==u&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(o&&r.push({op:"test",path:n+"/"+Re(p),value:Te(u)}),r.push({op:"remove",path:n+"/"+Re(p)}),s=!0):(o&&r.push({op:"test",path:n,value:e}),r.push({op:"replace",path:n,value:t}),!0);else{var c=t[p];"object"==typeof u&&null!=u&&"object"==typeof c&&null!=c&&Array.isArray(u)===Array.isArray(c)?rt(u,c,r,n+"/"+Re(p),o):u!==c&&(!0,o&&r.push({op:"test",path:n+"/"+Re(p),value:Te(u)}),r.push({op:"replace",path:n+"/"+Re(p),value:Te(c)}))}}if(s||a.length!=i.length)for(l=0;l0){var o=t(e,r[r.length-1],r);o&&(n=j()(n).call(n,o))}if(Array.isArray(e)){var a=A()(e).call(e,(function(e,n){return pt(e,t,j()(r).call(r,n))}));a&&(n=j()(n).call(n,a))}else if(mt(e)){var i,s=A()(i=C()(e)).call(i,(function(n){return pt(e[n],t,j()(r).call(r,n))}));s&&(n=j()(n).call(n,s))}return n=ht(n)}function ft(e){return Array.isArray(e)?e:[e]}function ht(e){var t;return j()(t=[]).apply(t,q()(A()(e).call(e,(function(e){return Array.isArray(e)?ht(e):e}))))}function dt(e){return P()(e).call(e,(function(e){return void 0!==e}))}function mt(e){return e&&"object"===h()(e)}function gt(e){return e&&"function"==typeof e}function vt(e){if(wt(e)){var t=e.op;return"add"===t||"remove"===t||"replace"===t}return!1}function yt(e){return vt(e)||wt(e)&&"mutation"===e.type}function bt(e){return yt(e)&&("add"===e.op||"replace"===e.op||"merge"===e.op||"mergeDeep"===e.op)}function wt(e){return e&&"object"===h()(e)}function Et(e,t){try{return Ve(e,t)}catch(e){return console.error(e),{}}}var xt=r(28886),_t=r.n(xt),St=r(37659),At=r.n(St),kt=r(8575);function Ct(e,t){function r(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var e=arguments.length,r=new Array(e),n=0;n-1&&-1===Nt.indexOf(r)||Tt.indexOf(n)>-1||Pt.some((function(e){return n.indexOf(e)>-1}))}function Mt(e,t){var r,n=e.split("#"),o=m()(n,2),a=o[0],i=o[1],s=kt.resolve(a||"",t||"");return i?j()(r="".concat(s,"#")).call(r,i):s}var Dt="application/json, application/yaml",Lt=/^([a-z]+:\/\/|\/\/)/i,Bt=Ct("JSONRefError",(function(e,t,r){this.originalError=r,Ee()(this,t||{})})),Ft={},zt=new(_t()),Ut=[function(e){return"paths"===e[0]&&"responses"===e[3]&&"examples"===e[5]},function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"example"===e[7]},function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"example"===e[6]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"example"===e[4]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"example"===e[5]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"examples"===e[4]&&"value"===e[6]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"examples"===e[5]&&"value"===e[7]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"example"===e[6]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"content"===e[4]&&"example"===e[7]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9]}],qt={key:"$ref",plugin:function(e,t,r,n){var o=n.getInstance(),a=$()(r).call(r,0,-1);if(!Rt(a)&&!function(e){return Ut.some((function(t){return t(e)}))}(a)){var i=n.getContext(r).baseDoc;if("string"!=typeof e)return new Bt("$ref: must be a string (JSON-Ref)",{$ref:e,baseDoc:i,fullPath:r});var s,l,u,c=Jt(e),p=c[0],f=c[1]||"";try{s=i||p?Wt(p,i):null}catch(t){return Ht(t,{pointer:f,$ref:e,basePath:s,fullPath:r})}if(function(e,t,r,n){var o,a,i=zt.get(n);i||(i={},zt.set(n,i));var s=function(e){if(0===e.length)return"";return"/".concat(A()(e).call(e,Xt).join("/"))}(r),l=j()(o="".concat(t||"","#")).call(o,e),u=s.replace(/allOf\/\d+\/?/g,""),c=n.contextTree.get([]).baseDoc;if(t===c&&er(u,e))return!0;var p="",f=r.some((function(e){var t;return p=j()(t="".concat(p,"/")).call(t,Xt(e)),i[p]&&i[p].some((function(e){return er(e,l)||er(l,e)}))}));if(f)return!0;return void(i[u]=j()(a=i[u]||[]).call(a,l))}(f,s,a,n)&&!o.useCircularStructures){var h=Mt(e,s);return e===h?null:it.replace(r,h)}if(null==s?(u=Yt(f),void 0===(l=n.get(u))&&(l=new Bt("Could not resolve reference: ".concat(e),{pointer:f,$ref:e,baseDoc:i,fullPath:r}))):l=null!=(l=Kt(s,f)).__value?l.__value:l.catch((function(t){throw Ht(t,{pointer:f,$ref:e,baseDoc:i,fullPath:r})})),l instanceof Error)return[it.remove(r),l];var d=Mt(e,s),m=it.replace(a,l,{$$ref:d});if(s&&s!==i)return[m,it.context(a,{baseDoc:s})];try{if(!function(e,t){var r=[e];return t.path.reduce((function(e,t){return r.push(e[t]),e[t]}),e),n(t.value);function n(e){return it.isObject(e)&&(r.indexOf(e)>=0||C()(e).some((function(t){return n(e[t])})))}}(n.state,m)||o.useCircularStructures)return m}catch(e){return null}}}},Vt=Ee()(qt,{docCache:Ft,absoluteify:Wt,clearCache:function(e){void 0!==e?delete Ft[e]:C()(Ft).forEach((function(e){delete Ft[e]}))},JSONRefError:Bt,wrapError:Ht,getDoc:Gt,split:Jt,extractFromDoc:Kt,fetchJSON:function(e){return fetch(e,{headers:{Accept:Dt},loadSpec:!0}).then((function(e){return e.text()})).then((function(e){return D.ZP.load(e)}))},extract:Zt,jsonPointerToArray:Yt,unescapeJsonPointerToken:Qt});const $t=Vt;function Wt(e,t){if(!Lt.test(e)){var r;if(!t)throw new Bt(j()(r="Tried to resolve a relative URL, without having a basePath. path: '".concat(e,"' basePath: '")).call(r,t,"'"));return kt.resolve(t,e)}return e}function Ht(e,t){var r,n;e&&e.response&&e.response.body?r=j()(n="".concat(e.response.body.code," ")).call(n,e.response.body.message):r=e.message;return new Bt("Could not resolve reference: ".concat(r),t,e)}function Jt(e){return(e+"").split("#")}function Kt(e,t){var r=Ft[e];if(r&&!it.isPromise(r))try{var n=Zt(t,r);return Ee()(Ae().resolve(n),{__value:n})}catch(e){return Ae().reject(e)}return Gt(e).then((function(e){return Zt(t,e)}))}function Gt(e){var t=Ft[e];return t?it.isPromise(t)?t:Ae().resolve(t):(Ft[e]=Vt.fetchJSON(e).then((function(t){return Ft[e]=t,t})),Ft[e])}function Zt(e,t){var r=Yt(e);if(r.length<1)return t;var n=it.getIn(t,r);if(void 0===n)throw new Bt("Could not resolve pointer: ".concat(e," does not exist in document"),{pointer:e});return n}function Yt(e){var t;if("string"!=typeof e)throw new TypeError("Expected a string, got a ".concat(h()(e)));return"/"===e[0]&&(e=e.substr(1)),""===e?[]:A()(t=e.split("/")).call(t,Qt)}function Qt(e){return"string"!=typeof e?e:new(At())("=".concat(e.replace(/~1/g,"/").replace(/~0/g,"~"))).get("")}function Xt(e){var t,r=new(At())([["",e.replace(/~/g,"~0").replace(/\//g,"~1")]]);return $()(t=r.toString()).call(t,1)}function er(e,t){if(!(r=t)||"/"===r||"#"===r)return!0;var r,n=e.charAt(t.length),o=$()(t).call(t,-1);return 0===e.indexOf(t)&&(!n||"/"===n||"#"===n)&&"#"!==o}const tr={key:"allOf",plugin:function(e,t,r,n,o){if(!o.meta||!o.meta.$$ref){var a=$()(r).call(r,0,-1);if(!Rt(a)){if(!Array.isArray(e)){var i=new TypeError("allOf must be an array");return i.fullPath=r,i}var s=!1,l=o.value;if(a.forEach((function(e){l&&(l=l[e])})),l=me()({},l),0!==C()(l).length){delete l.allOf;var u,c,p=[];if(p.push(n.replace(a,{})),e.forEach((function(e,t){if(!n.isObject(e)){if(s)return null;s=!0;var o=new TypeError("Elements in allOf must be objects");return o.fullPath=r,p.push(o)}p.push(n.mergeDeep(a,e));var i=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=r.specmap,o=r.getBaseUrlForNodePath,a=void 0===o?function(e){var r;return n.getContext(j()(r=[]).call(r,q()(t),q()(e))).baseDoc}:o,i=r.targetKeys,s=void 0===i?["$ref","$$ref"]:i,l=[];return jt()(e).forEach((function(){if(v()(s).call(s,this.key)&&"string"==typeof this.node){var e=this.path,r=j()(t).call(t,this.path),o=Mt(this.node,a(e));l.push(n.replace(r,o))}})),l}(e,$()(r).call(r,0,-1),{getBaseUrlForNodePath:function(e){var o;return n.getContext(j()(o=[]).call(o,q()(r),[t],q()(e))).baseDoc},specmap:n});p.push.apply(p,q()(i))})),l.example)p.push(n.remove(j()(u=[]).call(u,a,"example")));if(p.push(n.mergeDeep(a,l)),!l.$$ref)p.push(n.remove(j()(c=[]).call(c,a,"$$ref")));return p}}}}},rr={key:"parameters",plugin:function(e,t,r,n){if(Array.isArray(e)&&e.length){var o=Ee()([],e),a=$()(r).call(r,0,-1),i=me()({},it.getIn(n.spec,a));return e.forEach((function(e,t){try{o[t].default=n.parameterMacro(i,e)}catch(e){var a=new Error(e);return a.fullPath=r,a}})),it.replace(r,o)}return it.replace(r,e)}},nr={key:"properties",plugin:function(e,t,r,n){var o=me()({},e);for(var a in e)try{o[a].default=n.modelPropertyMacro(o[a])}catch(e){var i=new Error(e);return i.fullPath=r,i}return it.replace(r,o)}};var or=function(){function e(t){ve()(this,e),this.root=ar(t||{})}return be()(e,[{key:"set",value:function(e,t){var r=this.getParent(e,!0);if(r){var n=e[e.length-1],o=r.children;o[n]?ir(o[n],t,r):o[n]=ar(t,r)}else ir(this.root,t,null)}},{key:"get",value:function(e){if((e=e||[]).length<1)return this.root.value;for(var t,r,n=this.root,o=0;o1?r-1:0),o=1;o1?n-1:0),a=1;a0}))}},{key:"nextPromisedPatch",value:function(){var e;if(this.promisedPatches.length>0)return Ae().race(A()(e=this.promisedPatches).call(e,(function(e){return e.value})))}},{key:"getPluginHistory",value:function(e){var t=this.constructor.getPluginName(e);return this.pluginHistory[t]||[]}},{key:"getPluginRunCount",value:function(e){return this.getPluginHistory(e).length}},{key:"getPluginHistoryTip",value:function(e){var t=this.getPluginHistory(e);return t&&t[t.length-1]||{}}},{key:"getPluginMutationIndex",value:function(e){var t=this.getPluginHistoryTip(e).mutationIndex;return"number"!=typeof t?-1:t}},{key:"updatePluginHistory",value:function(e,t){var r=this.constructor.getPluginName(e);this.pluginHistory[r]=this.pluginHistory[r]||[],this.pluginHistory[r].push(t)}},{key:"updatePatches",value:function(e){var t=this;it.normalizeArray(e).forEach((function(e){if(e instanceof Error)t.errors.push(e);else try{if(!it.isObject(e))return void t.debug("updatePatches","Got a non-object patch",e);if(t.showDebug&&t.allPatches.push(e),it.isPromise(e.value))return t.promisedPatches.push(e),void t.promisedPatchThen(e);if(it.isContextPatch(e))return void t.setContext(e.path,e.value);if(it.isMutation(e))return void t.updateMutations(e)}catch(e){console.error(e),t.errors.push(e)}}))}},{key:"updateMutations",value:function(e){"object"===h()(e.value)&&!Array.isArray(e.value)&&this.allowMetaPatches&&(e.value=me()({},e.value));var t=it.applyPatch(this.state,e,{allowMetaPatches:this.allowMetaPatches});t&&(this.mutations.push(e),this.state=t)}},{key:"removePromisedPatch",value:function(e){var t,r=this.promisedPatches.indexOf(e);r<0?this.debug("Tried to remove a promisedPatch that isn't there!"):Ce()(t=this.promisedPatches).call(t,r,1)}},{key:"promisedPatchThen",value:function(e){var t=this;return e.value=e.value.then((function(r){var n=me()(me()({},e),{},{value:r});t.removePromisedPatch(e),t.updatePatches(n)})).catch((function(r){t.removePromisedPatch(e),t.updatePatches(r)})),e.value}},{key:"getMutations",value:function(e,t){var r;return e=e||0,"number"!=typeof t&&(t=this.mutations.length),$()(r=this.mutations).call(r,e,t)}},{key:"getCurrentMutations",value:function(){return this.getMutationsForPlugin(this.getCurrentPlugin())}},{key:"getMutationsForPlugin",value:function(e){var t=this.getPluginMutationIndex(e);return this.getMutations(t+1)}},{key:"getCurrentPlugin",value:function(){return this.currentPlugin}},{key:"getLib",value:function(){return this.libMethods}},{key:"_get",value:function(e){return it.getIn(this.state,e)}},{key:"_getContext",value:function(e){return this.contextTree.get(e)}},{key:"setContext",value:function(e,t){return this.contextTree.set(e,t)}},{key:"_hasRun",value:function(e){return this.getPluginRunCount(this.getCurrentPlugin())>(e||0)}},{key:"dispatch",value:function(){var e,t=this,r=this,n=this.nextPlugin();if(!n){var o=this.nextPromisedPatch();if(o)return o.then((function(){return t.dispatch()})).catch((function(){return t.dispatch()}));var a={spec:this.state,errors:this.errors};return this.showDebug&&(a.patches=this.allPatches),Ae().resolve(a)}if(r.pluginCount=r.pluginCount||{},r.pluginCount[n]=(r.pluginCount[n]||0)+1,r.pluginCount[n]>100)return Ae().resolve({spec:r.state,errors:j()(e=r.errors).call(e,new Error("We've reached a hard limit of ".concat(100," plugin runs")))});if(n!==this.currentPlugin&&this.promisedPatches.length){var i,s=A()(i=this.promisedPatches).call(i,(function(e){return e.value}));return Ae().all(A()(s).call(s,(function(e){return e.then(sr,sr)}))).then((function(){return t.dispatch()}))}return function(){r.currentPlugin=n;var e=r.getCurrentMutations(),t=r.mutations.length-1;try{if(n.isGenerator){var o,a=p()(n(e,r.getLib()));try{for(a.s();!(o=a.n()).done;){l(o.value)}}catch(e){a.e(e)}finally{a.f()}}else{l(n(e,r.getLib()))}}catch(e){console.error(e),l([Ee()(Object.create(e),{plugin:n})])}finally{r.updatePluginHistory(n,{mutationIndex:t})}return r.dispatch()}();function l(e){e&&(e=it.fullyNormalizeArray(e),r.updatePatches(e,n))}}}],[{key:"getPluginName",value:function(e){return e.pluginName}},{key:"getPatchesOfType",value:function(e,t){return P()(e).call(e,t)}}]),e}();var ur={refs:$t,allOf:tr,parameters:rr,properties:nr},cr=r(23159);function pr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.requestInterceptor,n=t.responseInterceptor,o=e.withCredentials?"include":"same-origin";return function(t){return e({url:t,loadSpec:!0,requestInterceptor:r,responseInterceptor:n,headers:{Accept:Dt},credentials:o}).then((function(e){return e.body}))}}function fr(e){var t=e.fetch,r=e.spec,n=e.url,o=e.mode,a=e.allowMetaPatches,i=void 0===a||a,l=e.pathDiscriminator,c=e.modelPropertyMacro,p=e.parameterMacro,f=e.requestInterceptor,h=e.responseInterceptor,d=e.skipNormalization,m=e.useCircularStructures,g=e.http,v=e.baseDoc;return v=v||n,g=t||g||Y,r?y(r):pr(g,{requestInterceptor:f,responseInterceptor:h})(v).then(y);function y(e){v&&(ur.refs.docCache[v]=e),ur.refs.fetchJSON=pr(g,{requestInterceptor:f,responseInterceptor:h});var t,r=[ur.refs];return"function"==typeof p&&r.push(ur.parameters),"function"==typeof c&&r.push(ur.properties),"strict"!==o&&r.push(ur.allOf),(t={spec:e,context:{baseDoc:v},plugins:r,allowMetaPatches:i,pathDiscriminator:l,parameterMacro:p,modelPropertyMacro:c,useCircularStructures:m},new lr(t).dispatch()).then(d?function(){var e=s()(u().mark((function e(t){return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",t);case 1:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}():cr.K1)}}var hr=r(88436),dr=r.n(hr),mr=r(27361),gr=r.n(mr),vr=r(76489);function yr(e){return"[object Object]"===Object.prototype.toString.call(e)}function br(e){var t,r;return!1!==yr(e)&&(void 0===(t=e.constructor)||!1!==yr(r=t.prototype)&&!1!==r.hasOwnProperty("isPrototypeOf"))}const wr={body:function(e){var t=e.req,r=e.value;t.body=r},header:function(e){var t=e.req,r=e.parameter,n=e.value;t.headers=t.headers||{},void 0!==n&&(t.headers[r.name]=n)},query:function(e){var t=e.req,r=e.value,n=e.parameter;t.query=t.query||{},!1===r&&"boolean"===n.type&&(r="false");0===r&&["number","integer"].indexOf(n.type)>-1&&(r="0");if(r)t.query[n.name]={collectionFormat:n.collectionFormat,value:r};else if(n.allowEmptyValue&&void 0!==r){var o=n.name;t.query[o]=t.query[o]||{},t.query[o].allowEmptyValue=!0}},path:function(e){var t=e.req,r=e.value,n=e.parameter;t.url=t.url.split("{".concat(n.name,"}")).join(encodeURIComponent(r))},formData:function(e){var t=e.req,r=e.value,n=e.parameter;(r||n.allowEmptyValue)&&(t.form=t.form||{},t.form[n.name]={value:r,allowEmptyValue:n.allowEmptyValue,collectionFormat:n.collectionFormat})}};function Er(e,t){return v()(t).call(t,"application/json")?"string"==typeof e?e:_()(e):e.toString()}function xr(e){var t=e.req,r=e.value,n=e.parameter,o=n.name,a=n.style,i=n.explode,s=n.content;if(s){var l=C()(s)[0];t.url=t.url.split("{".concat(o,"}")).join(J(Er(r,l),{escape:!0}))}else{var u=K({key:n.name,value:r,style:a||"simple",explode:i||!1,escape:!0});t.url=t.url.split("{".concat(o,"}")).join(u)}}function _r(e){var t=e.req,r=e.value,n=e.parameter;if(t.query=t.query||{},n.content){var o=C()(n.content)[0];t.query[n.name]=Er(r,o)}else if(!1===r&&(r="false"),0===r&&(r="0"),r){var a=n.style,i=n.explode,s=n.allowReserved;t.query[n.name]={value:r,serializationOption:{style:a,explode:i,allowReserved:s}}}else if(n.allowEmptyValue&&void 0!==r){var l=n.name;t.query[l]=t.query[l]||{},t.query[l].allowEmptyValue=!0}}var Sr=["accept","authorization","content-type"];function Ar(e){var t=e.req,r=e.parameter,n=e.value;if(t.headers=t.headers||{},!(Sr.indexOf(r.name.toLowerCase())>-1))if(r.content){var o=C()(r.content)[0];t.headers[r.name]=Er(n,o)}else void 0!==n&&(t.headers[r.name]=K({key:r.name,value:n,style:r.style||"simple",explode:void 0!==r.explode&&r.explode,escape:!1}))}function kr(e){var t=e.req,r=e.parameter,n=e.value;t.headers=t.headers||{};var o=h()(n);if(r.content){var a,i=C()(r.content)[0];t.headers.Cookie=j()(a="".concat(r.name,"=")).call(a,Er(n,i))}else if("undefined"!==o){var s="object"===o&&!Array.isArray(n)&&r.explode?"":"".concat(r.name,"=");t.headers.Cookie=s+K({key:r.name,value:n,escape:!1,style:r.style||"form",explode:void 0!==r.explode&&r.explode})}}var Cr=r(92381),Or=r.n(Cr);const jr=(void 0!==Or()?Or():"undefined"!=typeof self?self:window).btoa;function Ir(e,t){var r=e.operation,n=e.requestBody,o=e.securities,a=e.spec,i=e.attachContentTypeForEmptyPayload,s=e.requestContentType;t=function(e){var t=e.request,r=e.securities,n=void 0===r?{}:r,o=e.operation,a=void 0===o?{}:o,i=e.spec,s=me()({},t),l=n.authorized,u=void 0===l?{}:l,c=a.security||i.security||[],p=u&&!!C()(u).length,f=gr()(i,["components","securitySchemes"])||{};if(s.headers=s.headers||{},s.query=s.query||{},!C()(n).length||!p||!c||Array.isArray(a.security)&&!a.security.length)return t;return c.forEach((function(e){C()(e).forEach((function(e){var t=u[e],r=f[e];if(t){var n=t.value||t,o=r.type;if(t)if("apiKey"===o)"query"===r.in&&(s.query[r.name]=n),"header"===r.in&&(s.headers[r.name]=n),"cookie"===r.in&&(s.cookies[r.name]=n);else if("http"===o){if(/^basic$/i.test(r.scheme)){var a,i=n.username||"",l=n.password||"",c=jr(j()(a="".concat(i,":")).call(a,l));s.headers.Authorization="Basic ".concat(c)}/^bearer$/i.test(r.scheme)&&(s.headers.Authorization="Bearer ".concat(n))}else if("oauth2"===o||"openIdConnect"===o){var p,h=t.token||{},d=h[r["x-tokenName"]||"access_token"],m=h.token_type;m&&"bearer"!==m.toLowerCase()||(m="Bearer"),s.headers.Authorization=j()(p="".concat(m," ")).call(p,d)}}}))})),s}({request:t,securities:o,operation:r,spec:a});var l=r.requestBody||{},u=C()(l.content||{}),c=s&&u.indexOf(s)>-1;if(n||i){if(s&&c)t.headers["Content-Type"]=s;else if(!s){var p=u[0];p&&(t.headers["Content-Type"]=p,s=p)}}else s&&c&&(t.headers["Content-Type"]=s);if(!e.responseContentType&&r.responses){var f,d=P()(f=N()(r.responses)).call(f,(function(e){var t=m()(e,2),r=t[0],n=t[1],o=parseInt(r,10);return o>=200&&o<300&&br(n.content)})).reduce((function(e,t){var r=m()(t,2)[1];return j()(e).call(e,C()(r.content))}),[]);d.length>0&&(t.headers.accept=d.join(", "))}if(n)if(s){if(u.indexOf(s)>-1)if("application/x-www-form-urlencoded"===s||"multipart/form-data"===s)if("object"===h()(n)){var g=(l.content[s]||{}).encoding||{};t.form={},C()(n).forEach((function(e){t.form[e]={value:n[e],encoding:g[e]||{}}}))}else t.form=n;else t.body=n}else t.body=n;return t}function Nr(e,t){var r,n,o=e.spec,a=e.operation,i=e.securities,s=e.requestContentType,l=e.responseContentType,u=e.attachContentTypeForEmptyPayload;if(t=function(e){var t=e.request,r=e.securities,n=void 0===r?{}:r,o=e.operation,a=void 0===o?{}:o,i=e.spec,s=me()({},t),l=n.authorized,u=void 0===l?{}:l,c=n.specSecurity,p=void 0===c?[]:c,f=a.security||p,h=u&&!!C()(u).length,d=i.securityDefinitions;if(s.headers=s.headers||{},s.query=s.query||{},!C()(n).length||!h||!f||Array.isArray(a.security)&&!a.security.length)return t;return f.forEach((function(e){C()(e).forEach((function(e){var t=u[e];if(t){var r=t.token,n=t.value||t,o=d[e],a=o.type,i=o["x-tokenName"]||"access_token",l=r&&r[i],c=r&&r.token_type;if(t)if("apiKey"===a){var p="query"===o.in?"query":"headers";s[p]=s[p]||{},s[p][o.name]=n}else if("basic"===a)if(n.header)s.headers.authorization=n.header;else{var f,h=n.username||"",m=n.password||"";n.base64=jr(j()(f="".concat(h,":")).call(f,m)),s.headers.authorization="Basic ".concat(n.base64)}else if("oauth2"===a&&l){var g;c=c&&"bearer"!==c.toLowerCase()?c:"Bearer",s.headers.authorization=j()(g="".concat(c," ")).call(g,l)}}}))})),s}({request:t,securities:i,operation:a,spec:o}),t.body||t.form||u)if(s)t.headers["Content-Type"]=s;else if(Array.isArray(a.consumes)){var c=m()(a.consumes,1);t.headers["Content-Type"]=c[0]}else if(Array.isArray(o.consumes)){var p=m()(o.consumes,1);t.headers["Content-Type"]=p[0]}else a.parameters&&P()(r=a.parameters).call(r,(function(e){return"file"===e.type})).length?t.headers["Content-Type"]="multipart/form-data":a.parameters&&P()(n=a.parameters).call(n,(function(e){return"formData"===e.in})).length&&(t.headers["Content-Type"]="application/x-www-form-urlencoded");else if(s){var f,h,d=a.parameters&&P()(f=a.parameters).call(f,(function(e){return"body"===e.in})).length>0,g=a.parameters&&P()(h=a.parameters).call(h,(function(e){return"formData"===e.in})).length>0;(d||g)&&(t.headers["Content-Type"]=s)}return!l&&Array.isArray(a.produces)&&a.produces.length>0&&(t.headers.accept=a.produces.join(", ")),t}var Tr=["http","fetch","spec","operationId","pathName","method","parameters","securities"],Pr=function(e){return Array.isArray(e)?e:[]},Rr=Ct("OperationNotFoundError",(function(e,t,r){this.originalError=r,Ee()(this,t||{})})),Mr={buildRequest:Lr};function Dr(e){var t=e.http,r=e.fetch,n=e.spec,o=e.operationId,a=e.pathName,i=e.method,s=e.parameters,l=e.securities,u=dr()(e,Tr),c=t||r||Y;a&&i&&!o&&(o=(0,cr.nc)(a,i));var p=Mr.buildRequest(me()({spec:n,operationId:o,parameters:s,securities:l,http:c},u));return p.body&&(br(p.body)||Array.isArray(p.body))&&(p.body=_()(p.body)),c(p)}function Lr(e){var t,r,n=e.spec,o=e.operationId,i=e.responseContentType,s=e.scheme,l=e.requestInterceptor,u=e.responseInterceptor,c=e.contextUrl,p=e.userFetch,f=e.server,h=e.serverVariables,d=e.http,g=e.signal,v=e.parameters,y=e.parameterBuilders,b=(0,cr.z6)(n);y||(y=b?a:wr);var w={url:"",credentials:d&&d.withCredentials?"include":"same-origin",headers:{},cookies:{}};g&&(w.signal=g),l&&(w.requestInterceptor=l),u&&(w.responseInterceptor=u),p&&(w.userFetch=p);var E=(0,cr.$r)(n,o);if(!E)throw new Rr("Operation ".concat(o," not found"));var x,_=E.operation,S=void 0===_?{}:_,k=E.method,O=E.pathName;if(w.url+=(x={spec:n,scheme:s,contextUrl:c,server:f,serverVariables:h,pathName:O,method:k},(0,cr.z6)(x.spec)?function(e){var t=e.spec,r=e.pathName,n=e.method,o=e.server,a=e.contextUrl,i=e.serverVariables,s=void 0===i?{}:i,l=gr()(t,["paths",r,(n||"").toLowerCase(),"servers"])||gr()(t,["paths",r,"servers"])||gr()(t,["servers"]),u="",c=null;if(o&&l&&l.length){var p=A()(l).call(l,(function(e){return e.url}));p.indexOf(o)>-1&&(u=o,c=l[p.indexOf(o)])}if(!u&&l&&l.length){u=l[0].url;var f=m()(l,1);c=f[0]}return u.indexOf("{")>-1&&function(e){for(var t,r=[],n=/{([^}]+)}/g;t=n.exec(e);)r.push(t[1]);return r}(u).forEach((function(e){if(c.variables&&c.variables[e]){var t=c.variables[e],r=s[e]||t.default,n=new RegExp("{".concat(e,"}"),"g");u=u.replace(n,r)}})),function(){var e,t,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=r&&n?kt.parse(kt.resolve(n,r)):kt.parse(r),a=kt.parse(n),i=Br(o.protocol)||Br(a.protocol)||"",s=o.host||a.host,l=o.pathname||"";return"/"===(e=i&&s?j()(t="".concat(i,"://")).call(t,s+l):l)[e.length-1]?$()(e).call(e,0,-1):e}(u,a)}(x):function(e){var t,r,n=e.spec,o=e.scheme,a=e.contextUrl,i=void 0===a?"":a,s=kt.parse(i),l=Array.isArray(n.schemes)?n.schemes[0]:null,u=o||l||Br(s.protocol)||"http",c=n.host||s.host||"",p=n.basePath||"";return"/"===(t=u&&c?j()(r="".concat(u,"://")).call(r,c+p):p)[t.length-1]?$()(t).call(t,0,-1):t}(x)),!o)return delete w.cookies,w;w.url+=O,w.method="".concat(k).toUpperCase(),v=v||{};var I=n.paths[O]||{};i&&(w.headers.accept=i);var N=function(e){var t={};e.forEach((function(e){t[e.in]||(t[e.in]={}),t[e.in][e.name]=e}));var r=[];return C()(t).forEach((function(e){C()(t[e]).forEach((function(n){r.push(t[e][n])}))})),r}(j()(t=j()(r=[]).call(r,Pr(S.parameters))).call(t,Pr(I.parameters)));N.forEach((function(e){var t,r,o=y[e.in];if("body"===e.in&&e.schema&&e.schema.properties&&(t=v),void 0===(t=e&&e.name&&v[e.name]))t=e&&e.name&&v[j()(r="".concat(e.in,".")).call(r,e.name)];else if(function(e,t){return P()(t).call(t,(function(t){return t.name===e}))}(e.name,N).length>1){var a;console.warn(j()(a="Parameter '".concat(e.name,"' is ambiguous because the defined spec has more than one parameter with the name: '")).call(a,e.name,"' and the passed-in parameter values did not define an 'in' value."))}if(null!==t){if(void 0!==e.default&&void 0===t&&(t=e.default),void 0===t&&e.required&&!e.allowEmptyValue)throw new Error("Required parameter ".concat(e.name," is not provided"));if(b&&e.schema&&"object"===e.schema.type&&"string"==typeof t)try{t=JSON.parse(t)}catch(e){throw new Error("Could not parse object parameter value string as JSON")}o&&o({req:w,parameter:e,value:t,operation:S,spec:n})}}));var T=me()(me()({},e),{},{operation:S});if((w=b?Ir(T,w):Nr(T,w)).cookies&&C()(w.cookies).length){var R=C()(w.cookies).reduce((function(e,t){var r=w.cookies[t];return e+(e?"&":"")+vr.serialize(t,r)}),"");w.headers.Cookie=R}return w.cookies&&delete w.cookies,fe(w),w}var Br=function(e){return e?e.replace(/\W/g,""):null};function Fr(e,t){return zr.apply(this,arguments)}function zr(){return zr=s()(u().mark((function e(t,r){var n,o,a,i,s,l,c,p,f,h,d,m,g=arguments;return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=g.length>2&&void 0!==g[2]?g[2]:{},o=n.returnEntireTree,a=n.baseDoc,i=n.requestInterceptor,s=n.responseInterceptor,l=n.parameterMacro,c=n.modelPropertyMacro,p=n.useCircularStructures,f={pathDiscriminator:r,baseDoc:a,requestInterceptor:i,responseInterceptor:s,parameterMacro:l,modelPropertyMacro:c,useCircularStructures:p},h=(0,cr.K1)({spec:t}),d=h.spec,e.next=6,fr(me()(me()({},f),{},{spec:d,allowMetaPatches:!0,skipNormalization:!0}));case 6:return m=e.sent,!o&&Array.isArray(r)&&r.length&&(m.spec=gr()(m.spec,r)||null),e.abrupt("return",m);case 9:case"end":return e.stop()}}),e)}))),zr.apply(this,arguments)}var Ur=r(34852);function qr(e){let{configs:t,getConfigs:r}=e;return{fn:{fetch:(n=Y,o=t.preFetch,a=t.postFetch,a=a||function(e){return e},o=o||function(e){return e},function(e){return"string"==typeof e&&(e={url:e}),Z.mergeInQueryOrForm(e),e=o(e),a(n(e))}),buildRequest:Lr,execute:Dr,resolve:fr,resolveSubtree:function(e,t,n){if(void 0===n){const e=r();n={modelPropertyMacro:e.modelPropertyMacro,parameterMacro:e.parameterMacro,requestInterceptor:e.requestInterceptor,responseInterceptor:e.responseInterceptor}}for(var o=arguments.length,a=new Array(o>3?o-3:0),i=3;i{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(90242);function o(){return{fn:{shallowEqualKeys:n.be}}}},48347:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getDisplayName:()=>n});const n=e=>e.displayName||e.name||"Component"},73420:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(35627),o=r.n(n),a=r(90242),i=r(55776),s=r(48347),l=r(60314);const u=e=>{let{getComponents:t,getStore:r,getSystem:n}=e;const u=(c=(0,i.getComponent)(n,r,t),(0,a.HP)(c,(function(){for(var e=arguments.length,t=new Array(e),r=0;r(0,l.Z)(e,(function(){for(var e=arguments.length,t=new Array(e),r=0;r{"use strict";r.r(t),r.d(t,{getComponent:()=>ne,render:()=>re,withMappedContainer:()=>te});var n=r(23101),o=r.n(n),a=r(28222),i=r.n(a),s=r(67294),l=r(73935),u=r(97779),c=s.createContext(null);var p=function(e){e()},f=function(){return p},h={notify:function(){}};var d=function(){function e(e,t){this.store=e,this.parentSub=t,this.unsubscribe=null,this.listeners=h,this.handleChangeWrapper=this.handleChangeWrapper.bind(this)}var t=e.prototype;return t.addNestedSub=function(e){return this.trySubscribe(),this.listeners.subscribe(e)},t.notifyNestedSubs=function(){this.listeners.notify()},t.handleChangeWrapper=function(){this.onStateChange&&this.onStateChange()},t.isSubscribed=function(){return Boolean(this.unsubscribe)},t.trySubscribe=function(){this.unsubscribe||(this.unsubscribe=this.parentSub?this.parentSub.addNestedSub(this.handleChangeWrapper):this.store.subscribe(this.handleChangeWrapper),this.listeners=function(){var e=f(),t=null,r=null;return{clear:function(){t=null,r=null},notify:function(){e((function(){for(var e=t;e;)e.callback(),e=e.next}))},get:function(){for(var e=[],r=t;r;)e.push(r),r=r.next;return e},subscribe:function(e){var n=!0,o=r={callback:e,next:null,prev:r};return o.prev?o.prev.next=o:t=o,function(){n&&null!==t&&(n=!1,o.next?o.next.prev=o.prev:r=o.prev,o.prev?o.prev.next=o.next:t=o.next)}}}}())},t.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null,this.listeners.clear(),this.listeners=h)},e}(),m="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?s.useLayoutEffect:s.useEffect;const g=function(e){var t=e.store,r=e.context,n=e.children,o=(0,s.useMemo)((function(){var e=new d(t);return e.onStateChange=e.notifyNestedSubs,{store:t,subscription:e}}),[t]),a=(0,s.useMemo)((function(){return t.getState()}),[t]);m((function(){var e=o.subscription;return e.trySubscribe(),a!==t.getState()&&e.notifyNestedSubs(),function(){e.tryUnsubscribe(),e.onStateChange=null}}),[o,a]);var i=r||c;return s.createElement(i.Provider,{value:o},n)};var v=r(87462),y=r(63366),b=r(8679),w=r.n(b),E=r(72973),x=[],_=[null,null];function S(e,t){var r=e[1];return[t.payload,r+1]}function A(e,t,r){m((function(){return e.apply(void 0,t)}),r)}function k(e,t,r,n,o,a,i){e.current=n,t.current=o,r.current=!1,a.current&&(a.current=null,i())}function C(e,t,r,n,o,a,i,s,l,u){if(e){var c=!1,p=null,f=function(){if(!c){var e,r,f=t.getState();try{e=n(f,o.current)}catch(e){r=e,p=e}r||(p=null),e===a.current?i.current||l():(a.current=e,s.current=e,i.current=!0,u({type:"STORE_UPDATED",payload:{error:r}}))}};r.onStateChange=f,r.trySubscribe(),f();return function(){if(c=!0,r.tryUnsubscribe(),r.onStateChange=null,p)throw p}}}var O=function(){return[null,0]};function j(e,t){void 0===t&&(t={});var r=t,n=r.getDisplayName,o=void 0===n?function(e){return"ConnectAdvanced("+e+")"}:n,a=r.methodName,i=void 0===a?"connectAdvanced":a,l=r.renderCountProp,u=void 0===l?void 0:l,p=r.shouldHandleStateChanges,f=void 0===p||p,h=r.storeKey,m=void 0===h?"store":h,g=(r.withRef,r.forwardRef),b=void 0!==g&&g,j=r.context,I=void 0===j?c:j,N=(0,y.Z)(r,["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef","forwardRef","context"]),T=I;return function(t){var r=t.displayName||t.name||"Component",n=o(r),a=(0,v.Z)({},N,{getDisplayName:o,methodName:i,renderCountProp:u,shouldHandleStateChanges:f,storeKey:m,displayName:n,wrappedComponentName:r,WrappedComponent:t}),l=N.pure;var c=l?s.useMemo:function(e){return e()};function p(r){var n=(0,s.useMemo)((function(){var e=r.reactReduxForwardedRef,t=(0,y.Z)(r,["reactReduxForwardedRef"]);return[r.context,e,t]}),[r]),o=n[0],i=n[1],l=n[2],u=(0,s.useMemo)((function(){return o&&o.Consumer&&(0,E.isContextConsumer)(s.createElement(o.Consumer,null))?o:T}),[o,T]),p=(0,s.useContext)(u),h=Boolean(r.store)&&Boolean(r.store.getState)&&Boolean(r.store.dispatch);Boolean(p)&&Boolean(p.store);var m=h?r.store:p.store,g=(0,s.useMemo)((function(){return function(t){return e(t.dispatch,a)}(m)}),[m]),b=(0,s.useMemo)((function(){if(!f)return _;var e=new d(m,h?null:p.subscription),t=e.notifyNestedSubs.bind(e);return[e,t]}),[m,h,p]),w=b[0],j=b[1],I=(0,s.useMemo)((function(){return h?p:(0,v.Z)({},p,{subscription:w})}),[h,p,w]),N=(0,s.useReducer)(S,x,O),P=N[0][0],R=N[1];if(P&&P.error)throw P.error;var M=(0,s.useRef)(),D=(0,s.useRef)(l),L=(0,s.useRef)(),B=(0,s.useRef)(!1),F=c((function(){return L.current&&l===D.current?L.current:g(m.getState(),l)}),[m,P,l]);A(k,[D,M,B,l,F,L,j]),A(C,[f,m,w,g,D,M,B,L,j,R],[m,w,g]);var z=(0,s.useMemo)((function(){return s.createElement(t,(0,v.Z)({},F,{ref:i}))}),[i,t,F]);return(0,s.useMemo)((function(){return f?s.createElement(u.Provider,{value:I},z):z}),[u,z,I])}var h=l?s.memo(p):p;if(h.WrappedComponent=t,h.displayName=p.displayName=n,b){var g=s.forwardRef((function(e,t){return s.createElement(h,(0,v.Z)({},e,{reactReduxForwardedRef:t}))}));return g.displayName=n,g.WrappedComponent=t,w()(g,t)}return w()(h,t)}}function I(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function N(e,t){if(I(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(var o=0;o=0;n--){var o=t[n](e);if(o)return o}return function(t,n){throw new Error("Invalid value of type "+typeof e+" for "+r+" argument when connecting component "+n.wrappedComponentName+".")}}function V(e,t){return e===t}function $(e){var t=void 0===e?{}:e,r=t.connectHOC,n=void 0===r?j:r,o=t.mapStateToPropsFactories,a=void 0===o?D:o,i=t.mapDispatchToPropsFactories,s=void 0===i?M:i,l=t.mergePropsFactories,u=void 0===l?B:l,c=t.selectorFactory,p=void 0===c?U:c;return function(e,t,r,o){void 0===o&&(o={});var i=o,l=i.pure,c=void 0===l||l,f=i.areStatesEqual,h=void 0===f?V:f,d=i.areOwnPropsEqual,m=void 0===d?N:d,g=i.areStatePropsEqual,b=void 0===g?N:g,w=i.areMergedPropsEqual,E=void 0===w?N:w,x=(0,y.Z)(i,["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"]),_=q(e,a,"mapStateToProps"),S=q(t,s,"mapDispatchToProps"),A=q(r,u,"mergeProps");return n(p,(0,v.Z)({methodName:"connect",getDisplayName:function(e){return"Connect("+e+")"},shouldHandleStateChanges:Boolean(e),initMapStateToProps:_,initMapDispatchToProps:S,initMergeProps:A,pure:c,areStatesEqual:h,areOwnPropsEqual:m,areStatePropsEqual:b,areMergedPropsEqual:E},x))}}const W=$();var H;H=l.unstable_batchedUpdates,p=H;var J=r(57557),K=r.n(J),G=r(6557),Z=r.n(G);const Y=e=>t=>{const{fn:r}=e();class n extends s.Component{render(){return s.createElement(t,o()({},e(),this.props,this.context))}}return n.displayName=`WithSystem(${r.getDisplayName(t)})`,n},Q=(e,t)=>r=>{const{fn:n}=e();class a extends s.Component{render(){return s.createElement(g,{store:t},s.createElement(r,o()({},this.props,this.context)))}}return a.displayName=`WithRoot(${n.getDisplayName(r)})`,a},X=(e,t,r)=>(0,u.qC)(r?Q(e,r):Z(),W(((r,n)=>{var o;const a={...n,...e()},i=(null===(o=t.prototype)||void 0===o?void 0:o.mapStateToProps)||(e=>({state:e}));return i(r,a)})),Y(e))(t),ee=(e,t,r,n)=>{for(const o in t){const a=t[o];"function"==typeof a&&a(r[o],n[o],e())}},te=(e,t,r)=>(t,n)=>{const{fn:o}=e(),a=r(t,"root");class l extends s.Component{constructor(t,r){super(t,r),ee(e,n,t,{})}UNSAFE_componentWillReceiveProps(t){ee(e,n,t,this.props)}render(){const e=K()(this.props,n?i()(n):[]);return s.createElement(a,e)}}return l.displayName=`WithMappedContainer(${o.getDisplayName(a)})`,l},re=(e,t,r,n)=>o=>{const a=r(e,t,n)("App","root");l.render(s.createElement(a,null),o)},ne=(e,t,r)=>function(n,o){let a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"!=typeof n)throw new TypeError("Need a string, to fetch a component. Was given a "+typeof n);const i=r(n);return i?o?"root"===o?X(e,i,t()):X(e,i):i:(a.failSilently||e().log.warn("Could not find component:",n),null)}},36581:(e,t,r)=>{"use strict";r.d(t,{d3:()=>T,C2:()=>Z});var n=r(28222),o=r.n(n),a=r(58118),i=r.n(a),s=r(63366);function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=4?[t[0],t[1],t[2],t[3],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[2],".").concat(t[3]),"".concat(t[3],".").concat(t[0]),"".concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[0]),"".concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[3],".").concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[2],".").concat(t[1],".").concat(t[0])]:void 0),d[n]}function g(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0,n=e.filter((function(e){return"token"!==e})),o=m(n);return o.reduce((function(e,t){return p({},e,r[t])}),t)}function v(e){return e.join(" ")}function y(e){var t=e.node,r=e.stylesheet,n=e.style,o=void 0===n?{}:n,a=e.useInlineStyles,i=e.key,s=t.properties,l=t.type,u=t.tagName,c=t.value;if("text"===l)return c;if(u){var d,m=function(e,t){var r=0;return function(n){return r+=1,n.map((function(n,o){return y({node:n,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(r,"-").concat(o)})}))}}(r,a);if(a){var b=Object.keys(r).reduce((function(e,t){return t.split(".").forEach((function(t){e.includes(t)||e.push(t)})),e}),[]),w=s.className&&s.className.includes("token")?["token"]:[],E=s.className&&w.concat(s.className.filter((function(e){return!b.includes(e)})));d=p({},s,{className:v(E)||void 0,style:g(s.className,Object.assign({},s.style,o),r)})}else d=p({},s,{className:v(s.className)});var x=m(t.children);return f.createElement(u,(0,h.Z)({key:i},d),x)}}var b=/\n/g;function w(e){var t=e.codeString,r=e.codeStyle,n=e.containerStyle,o=void 0===n?{float:"left",paddingRight:"10px"}:n,a=e.numberStyle,i=void 0===a?{}:a,s=e.startingLineNumber;return f.createElement("code",{style:Object.assign({},r,o)},function(e){var t=e.lines,r=e.startingLineNumber,n=e.style;return t.map((function(e,t){var o=t+r;return f.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof n?n(o):n},"".concat(o,"\n"))}))}({lines:t.replace(/\n$/,"").split("\n"),style:i,startingLineNumber:s}))}function E(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function x(e,t,r){var n;return p({},{display:"inline-block",minWidth:(n=r,"".concat(n.toString().length,".25em")),paddingRight:"1em",textAlign:"right",userSelect:"none"},"function"==typeof e?e(t):e)}function _(e){var t=e.children,r=e.lineNumber,n=e.lineNumberStyle,o=e.largestLineNumber,a=e.showInlineLineNumbers,i=e.lineProps,s=void 0===i?{}:i,l=e.className,u=void 0===l?[]:l,c=e.showLineNumbers,f=e.wrapLongLines,h="function"==typeof s?s(r):s;if(h.className=u,r&&a){var d=x(n,r,o);t.unshift(E(r,d))}return f&c&&(h.style=p({},h.style,{display:"flex"})),{type:"element",tagName:"span",properties:h,children:t}}function S(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],n=0;n2&&void 0!==arguments[2]?arguments[2]:[];return _({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:i,showInlineLineNumbers:o,lineProps:r,className:a,showLineNumbers:n,wrapLongLines:l})}function m(e,t){if(n&&t&&o){var r=x(s,t,i);e.unshift(E(t,r))}return e}function g(e,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||n.length>0?d(e,r,n):m(e,r)}for(var v=function(){var e=c[h],t=e.children[0].value;if(t.match(b)){var r=t.split("\n");r.forEach((function(t,o){var i=n&&p.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===o){var l=g(c.slice(f+1,h).concat(_({children:[s],className:e.properties.className})),i);p.push(l)}else if(o===r.length-1){if(c[h+1]&&c[h+1].children&&c[h+1].children[0]){var u=_({children:[{type:"text",value:"".concat(t)}],className:e.properties.className});c.splice(h+1,0,u)}else{var d=g([s],i,e.properties.className);p.push(d)}}else{var m=g([s],i,e.properties.className);p.push(m)}})),f=h}h++};h=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}(e,["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"]);U=U||O;var V=m?f.createElement(w,{containerStyle:E,codeStyle:u.style||{},numberStyle:_,startingLineNumber:b,codeString:z}):null,$=o.hljs||o['pre[class*="language-"]']||{backgroundColor:"#fff"},W=C(U)?"hljs":"prismjs",H=h?Object.assign({},q,{style:Object.assign({},$,i)}):Object.assign({},q,{className:q.className?"".concat(W," ").concat(q.className):W,style:Object.assign({},i)});if(!U)return f.createElement(D,H,V,f.createElement(B,u,z));(void 0===S&&R||N)&&(S=!0),R=R||k;var J=[{type:"text",value:z}],K=function(e){var t=e.astGenerator,r=e.language,n=e.code,o=e.defaultCodeValue;if(C(t)){var a=function(e,t){return-1!==e.listLanguages().indexOf(t)}(t,r);return"text"===r?{value:o,language:"text"}:a?t.highlight(r,n):t.highlightAuto(n)}try{return r&&"text"!==r?{value:t.highlight(n,r)}:{value:o}}catch(e){return{value:o}}}({astGenerator:U,language:t,code:z,defaultCodeValue:J});null===K.language&&(K.value=J);var G=A(K,S,P,m,v,b,K.value.length+b,_,N);return u.style=p({},u.style,N?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),f.createElement(D,H,f.createElement(B,u,!v&&V,R({rows:G,stylesheet:o,useInlineStyles:h})))});N.registerLanguage=I.registerLanguage;const T=N;var P=r(96344);const R=r.n(P)();var M=r(82026);const D=r.n(M)();var L=r(42157);const B=r.n(L)();var F=r(61519);const z=r.n(F)();var U=r(54587);const q=r.n(U)();var V=r(30786);const $=r.n(V)();var W=r(66336);const H=r.n(W)(),J={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#333",color:"white"},"hljs-name":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-code":{fontStyle:"italic",color:"#888"},"hljs-emphasis":{fontStyle:"italic"},"hljs-tag":{color:"#62c8f3"},"hljs-variable":{color:"#ade5fc"},"hljs-template-variable":{color:"#ade5fc"},"hljs-selector-id":{color:"#ade5fc"},"hljs-selector-class":{color:"#ade5fc"},"hljs-string":{color:"#a2fca2"},"hljs-bullet":{color:"#d36363"},"hljs-type":{color:"#ffa"},"hljs-title":{color:"#ffa"},"hljs-section":{color:"#ffa"},"hljs-attribute":{color:"#ffa"},"hljs-quote":{color:"#ffa"},"hljs-built_in":{color:"#ffa"},"hljs-builtin-name":{color:"#ffa"},"hljs-number":{color:"#d36363"},"hljs-symbol":{color:"#d36363"},"hljs-keyword":{color:"#fcc28c"},"hljs-selector-tag":{color:"#fcc28c"},"hljs-literal":{color:"#fcc28c"},"hljs-comment":{color:"#888"},"hljs-deletion":{color:"#333",backgroundColor:"#fc9b9b"},"hljs-regexp":{color:"#c6b4f0"},"hljs-link":{color:"#c6b4f0"},"hljs-meta":{color:"#fc9b9b"},"hljs-addition":{backgroundColor:"#a2fca2",color:"#333"}};T.registerLanguage("json",D),T.registerLanguage("js",R),T.registerLanguage("xml",B),T.registerLanguage("yaml",q),T.registerLanguage("http",$),T.registerLanguage("bash",z),T.registerLanguage("powershell",H),T.registerLanguage("javascript",R);const K={agate:J,arta:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#222",color:"#aaa"},"hljs-subst":{color:"#aaa"},"hljs-section":{color:"#fff",fontWeight:"bold"},"hljs-comment":{color:"#444"},"hljs-quote":{color:"#444"},"hljs-meta":{color:"#444"},"hljs-string":{color:"#ffcc33"},"hljs-symbol":{color:"#ffcc33"},"hljs-bullet":{color:"#ffcc33"},"hljs-regexp":{color:"#ffcc33"},"hljs-number":{color:"#00cc66"},"hljs-addition":{color:"#00cc66"},"hljs-built_in":{color:"#32aaee"},"hljs-builtin-name":{color:"#32aaee"},"hljs-literal":{color:"#32aaee"},"hljs-type":{color:"#32aaee"},"hljs-template-variable":{color:"#32aaee"},"hljs-attribute":{color:"#32aaee"},"hljs-link":{color:"#32aaee"},"hljs-keyword":{color:"#6644aa"},"hljs-selector-tag":{color:"#6644aa"},"hljs-name":{color:"#6644aa"},"hljs-selector-id":{color:"#6644aa"},"hljs-selector-class":{color:"#6644aa"},"hljs-title":{color:"#bb1166"},"hljs-variable":{color:"#bb1166"},"hljs-deletion":{color:"#bb1166"},"hljs-template-tag":{color:"#bb1166"},"hljs-doctag":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-emphasis":{fontStyle:"italic"}},monokai:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#272822",color:"#ddd"},"hljs-tag":{color:"#f92672"},"hljs-keyword":{color:"#f92672",fontWeight:"bold"},"hljs-selector-tag":{color:"#f92672",fontWeight:"bold"},"hljs-literal":{color:"#f92672",fontWeight:"bold"},"hljs-strong":{color:"#f92672"},"hljs-name":{color:"#f92672"},"hljs-code":{color:"#66d9ef"},"hljs-class .hljs-title":{color:"white"},"hljs-attribute":{color:"#bf79db"},"hljs-symbol":{color:"#bf79db"},"hljs-regexp":{color:"#bf79db"},"hljs-link":{color:"#bf79db"},"hljs-string":{color:"#a6e22e"},"hljs-bullet":{color:"#a6e22e"},"hljs-subst":{color:"#a6e22e"},"hljs-title":{color:"#a6e22e",fontWeight:"bold"},"hljs-section":{color:"#a6e22e",fontWeight:"bold"},"hljs-emphasis":{color:"#a6e22e"},"hljs-type":{color:"#a6e22e",fontWeight:"bold"},"hljs-built_in":{color:"#a6e22e"},"hljs-builtin-name":{color:"#a6e22e"},"hljs-selector-attr":{color:"#a6e22e"},"hljs-selector-pseudo":{color:"#a6e22e"},"hljs-addition":{color:"#a6e22e"},"hljs-variable":{color:"#a6e22e"},"hljs-template-tag":{color:"#a6e22e"},"hljs-template-variable":{color:"#a6e22e"},"hljs-comment":{color:"#75715e"},"hljs-quote":{color:"#75715e"},"hljs-deletion":{color:"#75715e"},"hljs-meta":{color:"#75715e"},"hljs-doctag":{fontWeight:"bold"},"hljs-selector-id":{fontWeight:"bold"}},nord:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#2E3440",color:"#D8DEE9"},"hljs-subst":{color:"#D8DEE9"},"hljs-selector-tag":{color:"#81A1C1"},"hljs-selector-id":{color:"#8FBCBB",fontWeight:"bold"},"hljs-selector-class":{color:"#8FBCBB"},"hljs-selector-attr":{color:"#8FBCBB"},"hljs-selector-pseudo":{color:"#88C0D0"},"hljs-addition":{backgroundColor:"rgba(163, 190, 140, 0.5)"},"hljs-deletion":{backgroundColor:"rgba(191, 97, 106, 0.5)"},"hljs-built_in":{color:"#8FBCBB"},"hljs-type":{color:"#8FBCBB"},"hljs-class":{color:"#8FBCBB"},"hljs-function":{color:"#88C0D0"},"hljs-function > .hljs-title":{color:"#88C0D0"},"hljs-keyword":{color:"#81A1C1"},"hljs-literal":{color:"#81A1C1"},"hljs-symbol":{color:"#81A1C1"},"hljs-number":{color:"#B48EAD"},"hljs-regexp":{color:"#EBCB8B"},"hljs-string":{color:"#A3BE8C"},"hljs-title":{color:"#8FBCBB"},"hljs-params":{color:"#D8DEE9"},"hljs-bullet":{color:"#81A1C1"},"hljs-code":{color:"#8FBCBB"},"hljs-emphasis":{fontStyle:"italic"},"hljs-formula":{color:"#8FBCBB"},"hljs-strong":{fontWeight:"bold"},"hljs-link:hover":{textDecoration:"underline"},"hljs-quote":{color:"#4C566A"},"hljs-comment":{color:"#4C566A"},"hljs-doctag":{color:"#8FBCBB"},"hljs-meta":{color:"#5E81AC"},"hljs-meta-keyword":{color:"#5E81AC"},"hljs-meta-string":{color:"#A3BE8C"},"hljs-attr":{color:"#8FBCBB"},"hljs-attribute":{color:"#D8DEE9"},"hljs-builtin-name":{color:"#81A1C1"},"hljs-name":{color:"#81A1C1"},"hljs-section":{color:"#88C0D0"},"hljs-tag":{color:"#81A1C1"},"hljs-variable":{color:"#D8DEE9"},"hljs-template-variable":{color:"#D8DEE9"},"hljs-template-tag":{color:"#5E81AC"},"abnf .hljs-attribute":{color:"#88C0D0"},"abnf .hljs-symbol":{color:"#EBCB8B"},"apache .hljs-attribute":{color:"#88C0D0"},"apache .hljs-section":{color:"#81A1C1"},"arduino .hljs-built_in":{color:"#88C0D0"},"aspectj .hljs-meta":{color:"#D08770"},"aspectj > .hljs-title":{color:"#88C0D0"},"bnf .hljs-attribute":{color:"#8FBCBB"},"clojure .hljs-name":{color:"#88C0D0"},"clojure .hljs-symbol":{color:"#EBCB8B"},"coq .hljs-built_in":{color:"#88C0D0"},"cpp .hljs-meta-string":{color:"#8FBCBB"},"css .hljs-built_in":{color:"#88C0D0"},"css .hljs-keyword":{color:"#D08770"},"diff .hljs-meta":{color:"#8FBCBB"},"ebnf .hljs-attribute":{color:"#8FBCBB"},"glsl .hljs-built_in":{color:"#88C0D0"},"groovy .hljs-meta:not(:first-child)":{color:"#D08770"},"haxe .hljs-meta":{color:"#D08770"},"java .hljs-meta":{color:"#D08770"},"ldif .hljs-attribute":{color:"#8FBCBB"},"lisp .hljs-name":{color:"#88C0D0"},"lua .hljs-built_in":{color:"#88C0D0"},"moonscript .hljs-built_in":{color:"#88C0D0"},"nginx .hljs-attribute":{color:"#88C0D0"},"nginx .hljs-section":{color:"#5E81AC"},"pf .hljs-built_in":{color:"#88C0D0"},"processing .hljs-built_in":{color:"#88C0D0"},"scss .hljs-keyword":{color:"#81A1C1"},"stylus .hljs-keyword":{color:"#81A1C1"},"swift .hljs-meta":{color:"#D08770"},"vim .hljs-built_in":{color:"#88C0D0",fontStyle:"italic"},"yaml .hljs-meta":{color:"#D08770"}},obsidian:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#282b2e",color:"#e0e2e4"},"hljs-keyword":{color:"#93c763",fontWeight:"bold"},"hljs-selector-tag":{color:"#93c763",fontWeight:"bold"},"hljs-literal":{color:"#93c763",fontWeight:"bold"},"hljs-selector-id":{color:"#93c763"},"hljs-number":{color:"#ffcd22"},"hljs-attribute":{color:"#668bb0"},"hljs-code":{color:"white"},"hljs-class .hljs-title":{color:"white"},"hljs-section":{color:"white",fontWeight:"bold"},"hljs-regexp":{color:"#d39745"},"hljs-link":{color:"#d39745"},"hljs-meta":{color:"#557182"},"hljs-tag":{color:"#8cbbad"},"hljs-name":{color:"#8cbbad",fontWeight:"bold"},"hljs-bullet":{color:"#8cbbad"},"hljs-subst":{color:"#8cbbad"},"hljs-emphasis":{color:"#8cbbad"},"hljs-type":{color:"#8cbbad",fontWeight:"bold"},"hljs-built_in":{color:"#8cbbad"},"hljs-selector-attr":{color:"#8cbbad"},"hljs-selector-pseudo":{color:"#8cbbad"},"hljs-addition":{color:"#8cbbad"},"hljs-variable":{color:"#8cbbad"},"hljs-template-tag":{color:"#8cbbad"},"hljs-template-variable":{color:"#8cbbad"},"hljs-string":{color:"#ec7600"},"hljs-symbol":{color:"#ec7600"},"hljs-comment":{color:"#818e96"},"hljs-quote":{color:"#818e96"},"hljs-deletion":{color:"#818e96"},"hljs-selector-class":{color:"#A082BD"},"hljs-doctag":{fontWeight:"bold"},"hljs-title":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"}},"tomorrow-night":{"hljs-comment":{color:"#969896"},"hljs-quote":{color:"#969896"},"hljs-variable":{color:"#cc6666"},"hljs-template-variable":{color:"#cc6666"},"hljs-tag":{color:"#cc6666"},"hljs-name":{color:"#cc6666"},"hljs-selector-id":{color:"#cc6666"},"hljs-selector-class":{color:"#cc6666"},"hljs-regexp":{color:"#cc6666"},"hljs-deletion":{color:"#cc6666"},"hljs-number":{color:"#de935f"},"hljs-built_in":{color:"#de935f"},"hljs-builtin-name":{color:"#de935f"},"hljs-literal":{color:"#de935f"},"hljs-type":{color:"#de935f"},"hljs-params":{color:"#de935f"},"hljs-meta":{color:"#de935f"},"hljs-link":{color:"#de935f"},"hljs-attribute":{color:"#f0c674"},"hljs-string":{color:"#b5bd68"},"hljs-symbol":{color:"#b5bd68"},"hljs-bullet":{color:"#b5bd68"},"hljs-addition":{color:"#b5bd68"},"hljs-title":{color:"#81a2be"},"hljs-section":{color:"#81a2be"},"hljs-keyword":{color:"#b294bb"},"hljs-selector-tag":{color:"#b294bb"},hljs:{display:"block",overflowX:"auto",background:"#1d1f21",color:"#c5c8c6",padding:"0.5em"},"hljs-emphasis":{fontStyle:"italic"},"hljs-strong":{fontWeight:"bold"}}},G=o()(K),Z=e=>i()(G).call(G,e)?K[e]:(console.warn(`Request style '${e}' is not available, returning default instead`),J)},90242:(e,t,r)=>{"use strict";r.d(t,{mz:()=>pe,oG:()=>fe,AF:()=>he,LQ:()=>de,Kn:()=>me,Wl:()=>ge,kJ:()=>ve,HP:()=>ye,Ay:()=>be,Q2:()=>we,_5:()=>Ee,iQ:()=>xe,gp:()=>_e,DR:()=>Se,Zl:()=>Ae,Ik:()=>Ce,xi:()=>Pe,UG:()=>Re,r3:()=>Me,wh:()=>De,GZ:()=>Le,be:()=>Be,Nm:()=>Fe,hW:()=>ze,QG:()=>Ue,oJ:()=>qe,J6:()=>Ve,nX:()=>$e,po:()=>We,XV:()=>He,Pz:()=>Je,D$:()=>Ke,V9:()=>Ge,cz:()=>Ze,Uj:()=>Ye,Xb:()=>Qe,O2:()=>et});var n=r(58309),o=r.n(n),a=r(97606),i=r.n(a),s=r(74386),l=r.n(s),u=r(86),c=r.n(u),p=r(14418),f=r.n(p),h=r(28222),d=r.n(h),m=(r(11189),r(24282)),g=r.n(m),v=r(76986),y=r.n(v),b=r(2578),w=r.n(b),E=r(24278),x=r.n(E),_=(r(39022),r(92039)),S=r.n(_),A=(r(58118),r(35627)),k=r.n(A),C=r(11882),O=r.n(C),j=r(51679),I=r.n(j),N=r(27043),T=r.n(N),P=r(81607),R=r.n(P),M=r(43393),D=r.n(M),L=r(17967),B=r(68929),F=r.n(B),z=r(11700),U=r.n(z),q=r(88306),V=r.n(q),$=r(13311),W=r.n($),H=r(59704),J=r.n(H),K=r(77813),G=r.n(K),Z=r(23560),Y=r.n(Z),Q=r(57050),X=r(27504),ee=r(8269),te=r.n(ee),re=r(19069),ne=r(92282),oe=r.n(ne),ae=r(89072),ie=r.n(ae),se=r(1272),le=r(48764).Buffer;const ue="default",ce=e=>D().Iterable.isIterable(e);function pe(e){return me(e)?ce(e)?e.toJS():e:{}}function fe(e){var t,r;if(ce(e))return e;if(e instanceof X.Z.File)return e;if(!me(e))return e;if(o()(e))return i()(r=D().Seq(e)).call(r,fe).toList();if(Y()(l()(e))){var n;const t=function(e){if(!Y()(l()(e)))return e;const t={},r="_**[]",n={};for(let o of l()(e).call(e))if(t[o[0]]||n[o[0]]&&n[o[0]].containsMultiple){if(!n[o[0]]){n[o[0]]={containsMultiple:!0,length:1},t[`${o[0]}${r}${n[o[0]].length}`]=t[o[0]],delete t[o[0]]}n[o[0]].length+=1,t[`${o[0]}${r}${n[o[0]].length}`]=o[1]}else t[o[0]]=o[1];return t}(e);return i()(n=D().OrderedMap(t)).call(n,fe)}return i()(t=D().OrderedMap(e)).call(t,fe)}function he(e){return o()(e)?e:[e]}function de(e){return"function"==typeof e}function me(e){return!!e&&"object"==typeof e}function ge(e){return"function"==typeof e}function ve(e){return o()(e)}const ye=V();function be(e,t){var r;return g()(r=d()(e)).call(r,((r,n)=>(r[n]=t(e[n],n),r)),{})}function we(e,t){var r;return g()(r=d()(e)).call(r,((r,n)=>{let o=t(e[n],n);return o&&"object"==typeof o&&y()(r,o),r}),{})}function Ee(e){return t=>{let{dispatch:r,getState:n}=t;return t=>r=>"function"==typeof r?r(e()):t(r)}}function xe(e){var t;let r=e.keySeq();return r.contains(ue)?ue:w()(t=f()(r).call(r,(e=>"2"===(e+"")[0]))).call(t).first()}function _e(e,t){if(!D().Iterable.isIterable(e))return D().List();let r=e.getIn(o()(t)?t:[t]);return D().List.isList(r)?r:D().List()}function Se(e){let t,r=[/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i];if(S()(r).call(r,(r=>(t=r.exec(e),null!==t))),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function Ae(e){return t=e.replace(/\.[^./]*$/,""),U()(F()(t));var t}function ke(e,t,r,n,a){if(!t)return[];let s=[],l=t.get("nullable"),u=t.get("required"),p=t.get("maximum"),h=t.get("minimum"),d=t.get("type"),m=t.get("format"),g=t.get("maxLength"),v=t.get("minLength"),y=t.get("uniqueItems"),b=t.get("maxItems"),w=t.get("minItems"),E=t.get("pattern");const x=r||!0===u,_=null!=e;if(l&&null===e||!d||!(x||_&&"array"===d||!(!x&&!_)))return[];let A="string"===d&&e,k="array"===d&&o()(e)&&e.length,C="array"===d&&D().List.isList(e)&&e.count();const O=[A,k,C,"array"===d&&"string"==typeof e&&e,"file"===d&&e instanceof X.Z.File,"boolean"===d&&(e||!1===e),"number"===d&&(e||0===e),"integer"===d&&(e||0===e),"object"===d&&"object"==typeof e&&null!==e,"object"===d&&"string"==typeof e&&e],j=S()(O).call(O,(e=>!!e));if(x&&!j&&!n)return s.push("Required field is not provided"),s;if("object"===d&&(null===a||"application/json"===a)){let r=e;if("string"==typeof e)try{r=JSON.parse(e)}catch(e){return s.push("Parameter string value must be valid JSON"),s}var I;if(t&&t.has("required")&&ge(u.isList)&&u.isList()&&c()(u).call(u,(e=>{void 0===r[e]&&s.push({propKey:e,error:"Required property not found"})})),t&&t.has("properties"))c()(I=t.get("properties")).call(I,((e,t)=>{const o=ke(r[t],e,!1,n,a);s.push(...i()(o).call(o,(e=>({propKey:t,error:e}))))}))}if(E){let t=((e,t)=>{if(!new RegExp(t).test(e))return"Value must follow pattern "+t})(e,E);t&&s.push(t)}if(w&&"array"===d){let t=((e,t)=>{if(!e&&t>=1||e&&e.length{if(e&&e.length>t)return`Array must not contain more then ${t} item${1===t?"":"s"}`})(e,b);t&&s.push({needRemove:!0,error:t})}if(y&&"array"===d){let t=((e,t)=>{if(e&&("true"===t||!0===t)){const t=(0,M.fromJS)(e),r=t.toSet();if(e.length>r.size){let e=(0,M.Set)();if(c()(t).call(t,((r,n)=>{f()(t).call(t,(e=>ge(e.equals)?e.equals(r):e===r)).size>1&&(e=e.add(n))})),0!==e.size)return i()(e).call(e,(e=>({index:e,error:"No duplicates allowed."}))).toArray()}}})(e,y);t&&s.push(...t)}if(g||0===g){let t=((e,t)=>{if(e.length>t)return`Value must be no longer than ${t} character${1!==t?"s":""}`})(e,g);t&&s.push(t)}if(v){let t=((e,t)=>{if(e.length{if(e>t)return`Value must be less than ${t}`})(e,p);t&&s.push(t)}if(h||0===h){let t=((e,t)=>{if(e{if(isNaN(Date.parse(e)))return"Value must be a DateTime"})(e):"uuid"===m?(e=>{if(e=e.toString().toLowerCase(),!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[)}]?$/.test(e))return"Value must be a Guid"})(e):(e=>{if(e&&"string"!=typeof e)return"Value must be a string"})(e),!t)return s;s.push(t)}else if("boolean"===d){let t=(e=>{if("true"!==e&&"false"!==e&&!0!==e&&!1!==e)return"Value must be a boolean"})(e);if(!t)return s;s.push(t)}else if("number"===d){let t=(e=>{if(!/^-?\d+(\.?\d+)?$/.test(e))return"Value must be a number"})(e);if(!t)return s;s.push(t)}else if("integer"===d){let t=(e=>{if(!/^-?\d+$/.test(e))return"Value must be an integer"})(e);if(!t)return s;s.push(t)}else if("array"===d){if(!k&&!C)return s;e&&c()(e).call(e,((e,r)=>{const o=ke(e,t.get("items"),!1,n,a);s.push(...i()(o).call(o,(e=>({index:r,error:e}))))}))}else if("file"===d){let t=(e=>{if(e&&!(e instanceof X.Z.File))return"Value must be a file"})(e);if(!t)return s;s.push(t)}return s}const Ce=function(e,t){let{isOAS3:r=!1,bypassRequiredCheck:n=!1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=e.get("required"),{schema:a,parameterContentMediaType:i}=(0,re.Z)(e,{isOAS3:r});return ke(t,a,o,n,i)},Oe=(e,t,r)=>{if(e&&!e.xml&&(e.xml={}),e&&!e.xml.name){if(!e.$$ref&&(e.type||e.items||e.properties||e.additionalProperties))return'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e';if(e.$$ref){let t=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=t[1]}}return(0,Q.memoizedCreateXMLExample)(e,t,r)},je=[{when:/json/,shouldStringifyTypes:["string"]}],Ie=["object"],Ne=(e,t,r,n)=>{const o=(0,Q.memoizedSampleFromSchema)(e,t,n),a=typeof o,i=g()(je).call(je,((e,t)=>t.when.test(r)?[...e,...t.shouldStringifyTypes]:e),Ie);return J()(i,(e=>e===a))?k()(o,null,2):o},Te=(e,t,r,n)=>{const o=Ne(e,t,r,n);let a;try{a=se.ZP.dump(se.ZP.load(o),{lineWidth:-1},{schema:se.A8}),"\n"===a[a.length-1]&&(a=x()(a).call(a,0,a.length-1))}catch(e){return console.error(e),"error: could not generate yaml example"}return a.replace(/\t/g," ")},Pe=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return e&&ge(e.toJS)&&(e=e.toJS()),n&&ge(n.toJS)&&(n=n.toJS()),/xml/.test(t)?Oe(e,r,n):/(yaml|yml)/.test(t)?Te(e,r,t,n):Ne(e,r,t,n)},Re=()=>{let e={},t=X.Z.location.search;if(!t)return{};if(""!=t){let r=t.substr(1).split("&");for(let t in r)Object.prototype.hasOwnProperty.call(r,t)&&(t=r[t].split("="),e[decodeURIComponent(t[0])]=t[1]&&decodeURIComponent(t[1])||"")}return e},Me=e=>{let t;return t=e instanceof le?e:le.from(e.toString(),"utf-8"),t.toString("base64")},De={operationsSorter:{alpha:(e,t)=>e.get("path").localeCompare(t.get("path")),method:(e,t)=>e.get("method").localeCompare(t.get("method"))},tagsSorter:{alpha:(e,t)=>e.localeCompare(t)}},Le=e=>{let t=[];for(let r in e){let n=e[r];void 0!==n&&""!==n&&t.push([r,"=",encodeURIComponent(n).replace(/%20/g,"+")].join(""))}return t.join("&")},Be=(e,t,r)=>!!W()(r,(r=>G()(e[r],t[r])));function Fe(e){return"string"!=typeof e||""===e?"":(0,L.N)(e)}function ze(e){return!(!e||O()(e).call(e,"localhost")>=0||O()(e).call(e,"127.0.0.1")>=0||"none"===e)}function Ue(e){if(!D().OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;const t=I()(e).call(e,((e,t)=>T()(t).call(t,"2")&&d()(e.get("content")||{}).length>0)),r=e.get("default")||D().OrderedMap(),n=(r.get("content")||D().OrderedMap()).keySeq().toJS().length?r:null;return t||n}const qe=e=>"string"==typeof e||e instanceof String?R()(e).call(e).replace(/\s/g,"%20"):"",Ve=e=>te()(qe(e).replace(/%20/g,"_")),$e=e=>f()(e).call(e,((e,t)=>/^x-/.test(t))),We=e=>f()(e).call(e,((e,t)=>/^pattern|maxLength|minLength|maximum|minimum/.test(t)));function He(e,t){var r;let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>!0;if("object"!=typeof e||o()(e)||null===e||!t)return e;const a=y()({},e);return c()(r=d()(a)).call(r,(e=>{e===t&&n(a[e],e)?delete a[e]:a[e]=He(a[e],t,n)})),a}function Je(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"==typeof e&&null!==e)try{return k()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function Ke(e){return"number"==typeof e?e.toString():e}function Ge(e){let{returnAll:t=!1,allowHashes:r=!0}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!D().Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");const n=e.get("name"),o=e.get("in");let a=[];return e&&e.hashCode&&o&&n&&r&&a.push(`${o}.${n}.hash-${e.hashCode()}`),o&&n&&a.push(`${o}.${n}`),a.push(n),t?a:a[0]||""}function Ze(e,t){var r;const n=Ge(e,{returnAll:!0});return f()(r=i()(n).call(n,(e=>t[e]))).call(r,(e=>void 0!==e))[0]}function Ye(){return Xe(oe()(32).toString("base64"))}function Qe(e){return Xe(ie()("sha256").update(e).digest("base64"))}function Xe(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}const et=e=>!e||!(!ce(e)||!e.isEmpty())},2518:(e,t,r)=>{"use strict";function n(e){return function(e){try{return!!JSON.parse(e)}catch(e){return null}}(e)?"json":null}r.d(t,{O:()=>n})},27504:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});const n=function(){var e={location:{},history:{},open:()=>{},close:()=>{},File:function(){}};if("undefined"==typeof window)return e;try{e=window;for(var t of["File","Blob","FormData"])t in window&&(e[t]=window[t])}catch(e){console.error(e)}return e}()},19069:(e,t,r)=>{"use strict";r.d(t,{Z:()=>c});var n=r(14418),o=r.n(n),a=r(58118),i=r.n(a),s=r(43393),l=r.n(s);const u=l().Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function c(e){let{isOAS3:t}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!l().Map.isMap(e))return{schema:l().Map(),parameterContentMediaType:null};if(!t)return"body"===e.get("in")?{schema:e.get("schema",l().Map()),parameterContentMediaType:null}:{schema:o()(e).call(e,((e,t)=>i()(u).call(u,t))),parameterContentMediaType:null};if(e.get("content")){const t=e.get("content",l().Map({})).keySeq().first();return{schema:e.getIn(["content",t,"schema"],l().Map()),parameterContentMediaType:t}}return{schema:e.get("schema")?e.get("schema",l().Map()):l().Map(),parameterContentMediaType:null}}},60314:(e,t,r)=>{"use strict";r.d(t,{Z:()=>x});var n=r(58309),o=r.n(n),a=r(2250),i=r.n(a),s=r(25110),l=r.n(s),u=r(8712),c=r.n(u),p=r(51679),f=r.n(p),h=r(12373),d=r.n(h),m=r(18492),g=r.n(m),v=r(88306),y=r.n(v);const b=e=>t=>o()(e)&&o()(t)&&e.length===t.length&&i()(e).call(e,((e,r)=>e===t[r])),w=function(){for(var e=arguments.length,t=new Array(e),r=0;r1&&void 0!==arguments[1]?arguments[1]:w;const{Cache:r}=y();y().Cache=E;const n=y()(e,t);return y().Cache=r,n}},79742:(e,t)=>{"use strict";t.byteLength=function(e){var t=l(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,a=l(e),i=a[0],s=a[1],u=new o(function(e,t,r){return 3*(t+r)/4-r}(0,i,s)),c=0,p=s>0?i-4:i;for(r=0;r>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===s&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,u[c++]=255&t);1===s&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,a=[],i=16383,s=0,l=n-o;sl?l:s+i));1===o?(t=e[n-1],a.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],a.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return a.join("")};for(var r=[],n=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,s=a.length;i0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function u(e,t,n){for(var o,a,i=[],s=t;s>18&63]+r[a>>12&63]+r[a>>6&63]+r[63&a]);return i.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63},48764:(e,t,r)=>{"use strict";const n=r(79742),o=r(80645),a="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=l,t.SlowBuffer=function(e){+e!=e&&(e=0);return l.alloc(+e)},t.INSPECT_MAX_BYTES=50;const i=2147483647;function s(e){if(e>i)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,l.prototype),t}function l(e,t,r){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return p(e)}return u(e,t,r)}function u(e,t,r){if("string"==typeof e)return function(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!l.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const r=0|m(e,t);let n=s(r);const o=n.write(e,t);o!==r&&(n=n.slice(0,o));return n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(G(e,Uint8Array)){const t=new Uint8Array(e);return h(t.buffer,t.byteOffset,t.byteLength)}return f(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(G(e,ArrayBuffer)||e&&G(e.buffer,ArrayBuffer))return h(e,t,r);if("undefined"!=typeof SharedArrayBuffer&&(G(e,SharedArrayBuffer)||e&&G(e.buffer,SharedArrayBuffer)))return h(e,t,r);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return l.from(n,t,r);const o=function(e){if(l.isBuffer(e)){const t=0|d(e.length),r=s(t);return 0===r.length||e.copy(r,0,0,t),r}if(void 0!==e.length)return"number"!=typeof e.length||Z(e.length)?s(0):f(e);if("Buffer"===e.type&&Array.isArray(e.data))return f(e.data)}(e);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return l.from(e[Symbol.toPrimitive]("string"),t,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function c(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function p(e){return c(e),s(e<0?0:0|d(e))}function f(e){const t=e.length<0?0:0|d(e.length),r=s(t);for(let n=0;n=i)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i.toString(16)+" bytes");return 0|e}function m(e,t){if(l.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||G(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let o=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return J(e).length;default:if(o)return n?-1:H(e).length;t=(""+t).toLowerCase(),o=!0}}function g(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,r);case"utf8":case"utf-8":return k(this,t,r);case"ascii":return O(this,t,r);case"latin1":case"binary":return j(this,t,r);case"base64":return A(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function v(e,t,r){const n=e[t];e[t]=e[r],e[r]=n}function y(e,t,r,n,o){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),Z(r=+r)&&(r=o?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(o)return-1;r=e.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof t&&(t=l.from(t,n)),l.isBuffer(t))return 0===t.length?-1:b(e,t,r,n,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):b(e,[t],r,n,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,r,n,o){let a,i=1,s=e.length,l=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;i=2,s/=2,l/=2,r/=2}function u(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o){let n=-1;for(a=r;as&&(r=s-l),a=r;a>=0;a--){let r=!0;for(let n=0;no&&(n=o):n=o;const a=t.length;let i;for(n>a/2&&(n=a/2),i=0;i>8,o=r%256,a.push(o),a.push(n);return a}(t,e.length-r),e,r,n)}function A(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function k(e,t,r){r=Math.min(e.length,r);const n=[];let o=t;for(;o239?4:t>223?3:t>191?2:1;if(o+i<=r){let r,n,s,l;switch(i){case 1:t<128&&(a=t);break;case 2:r=e[o+1],128==(192&r)&&(l=(31&t)<<6|63&r,l>127&&(a=l));break;case 3:r=e[o+1],n=e[o+2],128==(192&r)&&128==(192&n)&&(l=(15&t)<<12|(63&r)<<6|63&n,l>2047&&(l<55296||l>57343)&&(a=l));break;case 4:r=e[o+1],n=e[o+2],s=e[o+3],128==(192&r)&&128==(192&n)&&128==(192&s)&&(l=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&s,l>65535&&l<1114112&&(a=l))}}null===a?(a=65533,i=1):a>65535&&(a-=65536,n.push(a>>>10&1023|55296),a=56320|1023&a),n.push(a),o+=i}return function(e){const t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);let r="",n=0;for(;nn.length?(l.isBuffer(t)||(t=l.from(t)),t.copy(n,o)):Uint8Array.prototype.set.call(n,t,o);else{if(!l.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(n,o)}o+=t.length}return n},l.byteLength=m,l.prototype._isBuffer=!0,l.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tr&&(e+=" ... "),""},a&&(l.prototype[a]=l.prototype.inspect),l.prototype.compare=function(e,t,r,n,o){if(G(e,Uint8Array)&&(e=l.from(e,e.offset,e.byteLength)),!l.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||r>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&t>=r)return 0;if(n>=o)return-1;if(t>=r)return 1;if(this===e)return 0;let a=(o>>>=0)-(n>>>=0),i=(r>>>=0)-(t>>>=0);const s=Math.min(a,i),u=this.slice(n,o),c=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}const o=this.length-t;if((void 0===r||r>o)&&(r=o),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let a=!1;for(;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return E(this,e,t,r);case"ascii":case"latin1":case"binary":return x(this,e,t,r);case"base64":return _(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,r);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const C=4096;function O(e,t,r){let n="";r=Math.min(e.length,r);for(let o=t;on)&&(r=n);let o="";for(let n=t;nr)throw new RangeError("Trying to access beyond buffer length")}function P(e,t,r,n,o,a){if(!l.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function R(e,t,r,n,o){q(t,n,o,e,r,7);let a=Number(t&BigInt(4294967295));e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=i,i>>=8,e[r++]=i,i>>=8,e[r++]=i,i>>=8,e[r++]=i,r}function M(e,t,r,n,o){q(t,n,o,e,r,7);let a=Number(t&BigInt(4294967295));e[r+7]=a,a>>=8,e[r+6]=a,a>>=8,e[r+5]=a,a>>=8,e[r+4]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=i,i>>=8,e[r+2]=i,i>>=8,e[r+1]=i,i>>=8,e[r]=i,r+8}function D(e,t,r,n,o,a){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(e,t,r,n,a){return t=+t,r>>>=0,a||D(e,0,r,4),o.write(e,t,r,n,23,4),r+4}function B(e,t,r,n,a){return t=+t,r>>>=0,a||D(e,0,r,8),o.write(e,t,r,n,52,8),r+8}l.prototype.slice=function(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e],o=1,a=0;for(;++a>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e+--t],o=1;for(;t>0&&(o*=256);)n+=this[e+--t]*o;return n},l.prototype.readUint8=l.prototype.readUInt8=function(e,t){return e>>>=0,t||T(e,1,this.length),this[e]},l.prototype.readUint16LE=l.prototype.readUInt16LE=function(e,t){return e>>>=0,t||T(e,2,this.length),this[e]|this[e+1]<<8},l.prototype.readUint16BE=l.prototype.readUInt16BE=function(e,t){return e>>>=0,t||T(e,2,this.length),this[e]<<8|this[e+1]},l.prototype.readUint32LE=l.prototype.readUInt32LE=function(e,t){return e>>>=0,t||T(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},l.prototype.readUint32BE=l.prototype.readUInt32BE=function(e,t){return e>>>=0,t||T(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},l.prototype.readBigUInt64LE=Q((function(e){V(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,o=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(o)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],o=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return(BigInt(n)<>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e],o=1,a=0;for(;++a=o&&(n-=Math.pow(2,8*t)),n},l.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||T(e,t,this.length);let n=t,o=1,a=this[e+--n];for(;n>0&&(o*=256);)a+=this[e+--n]*o;return o*=128,a>=o&&(a-=Math.pow(2,8*t)),a},l.prototype.readInt8=function(e,t){return e>>>=0,t||T(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},l.prototype.readInt16LE=function(e,t){e>>>=0,t||T(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},l.prototype.readInt16BE=function(e,t){e>>>=0,t||T(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},l.prototype.readInt32LE=function(e,t){return e>>>=0,t||T(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},l.prototype.readInt32BE=function(e,t){return e>>>=0,t||T(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},l.prototype.readBigInt64LE=Q((function(e){V(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return(BigInt(n)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(n)<>>=0,t||T(e,4,this.length),o.read(this,e,!0,23,4)},l.prototype.readFloatBE=function(e,t){return e>>>=0,t||T(e,4,this.length),o.read(this,e,!1,23,4)},l.prototype.readDoubleLE=function(e,t){return e>>>=0,t||T(e,8,this.length),o.read(this,e,!0,52,8)},l.prototype.readDoubleBE=function(e,t){return e>>>=0,t||T(e,8,this.length),o.read(this,e,!1,52,8)},l.prototype.writeUintLE=l.prototype.writeUIntLE=function(e,t,r,n){if(e=+e,t>>>=0,r>>>=0,!n){P(this,e,t,r,Math.pow(2,8*r)-1,0)}let o=1,a=0;for(this[t]=255&e;++a>>=0,r>>>=0,!n){P(this,e,t,r,Math.pow(2,8*r)-1,0)}let o=r-1,a=1;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=e/a&255;return t+r},l.prototype.writeUint8=l.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,1,255,0),this[t]=255&e,t+1},l.prototype.writeUint16LE=l.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeUint16BE=l.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeUint32LE=l.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},l.prototype.writeUint32BE=l.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigUInt64LE=Q((function(e,t=0){return R(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeBigUInt64BE=Q((function(e,t=0){return M(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);P(this,e,t,r,n-1,-n)}let o=0,a=1,i=0;for(this[t]=255&e;++o>0)-i&255;return t+r},l.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);P(this,e,t,r,n-1,-n)}let o=r-1,a=1,i=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===i&&0!==this[t+o+1]&&(i=1),this[t+o]=(e/a>>0)-i&255;return t+r},l.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},l.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigInt64LE=Q((function(e,t=0){return R(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeBigInt64BE=Q((function(e,t=0){return M(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeFloatLE=function(e,t,r){return L(this,e,t,!0,r)},l.prototype.writeFloatBE=function(e,t,r){return L(this,e,t,!1,r)},l.prototype.writeDoubleLE=function(e,t,r){return B(this,e,t,!0,r)},l.prototype.writeDoubleBE=function(e,t,r){return B(this,e,t,!1,r)},l.prototype.copy=function(e,t,r,n){if(!l.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return`${e.slice(0,r)}${t}`}function q(e,t,r,n,o,a){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(a+1)}${n}`:`>= -(2${n} ** ${8*(a+1)-1}${n}) and < 2 ** ${8*(a+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new F.ERR_OUT_OF_RANGE("value",o,e)}!function(e,t,r){V(t,"offset"),void 0!==e[t]&&void 0!==e[t+r]||$(t,e.length-(r+1))}(n,o,a)}function V(e,t){if("number"!=typeof e)throw new F.ERR_INVALID_ARG_TYPE(t,"number",e)}function $(e,t,r){if(Math.floor(e)!==e)throw V(e,r),new F.ERR_OUT_OF_RANGE(r||"offset","an integer",e);if(t<0)throw new F.ERR_BUFFER_OUT_OF_BOUNDS;throw new F.ERR_OUT_OF_RANGE(r||"offset",`>= ${r?1:0} and <= ${t}`,e)}z("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),z("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),z("ERR_OUT_OF_RANGE",(function(e,t,r){let n=`The value of "${e}" is out of range.`,o=r;return Number.isInteger(r)&&Math.abs(r)>2**32?o=U(String(r)):"bigint"==typeof r&&(o=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(o=U(o)),o+="n"),n+=` It must be ${t}. Received ${o}`,n}),RangeError);const W=/[^+/0-9A-Za-z-_]/g;function H(e,t){let r;t=t||1/0;const n=e.length;let o=null;const a=[];for(let i=0;i55295&&r<57344){if(!o){if(r>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===n){(t-=3)>-1&&a.push(239,191,189);continue}o=r;continue}if(r<56320){(t-=3)>-1&&a.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,r<128){if((t-=1)<0)break;a.push(r)}else if(r<2048){if((t-=2)<0)break;a.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;a.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return a}function J(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(W,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function K(e,t,r,n){let o;for(o=0;o=t.length||o>=e.length);++o)t[o+r]=e[o];return o}function G(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Z(e){return e!=e}const Y=function(){const e="0123456789abcdef",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let o=0;o<16;++o)t[n+o]=e[r]+e[o]}return t}();function Q(e){return"undefined"==typeof BigInt?X:e}function X(){throw new Error("BigInt not supported")}},21924:(e,t,r)=>{"use strict";var n=r(40210),o=r(55559),a=o(n("String.prototype.indexOf"));e.exports=function(e,t){var r=n(e,!!t);return"function"==typeof r&&a(e,".prototype.")>-1?o(r):r}},55559:(e,t,r)=>{"use strict";var n=r(58612),o=r(40210),a=o("%Function.prototype.apply%"),i=o("%Function.prototype.call%"),s=o("%Reflect.apply%",!0)||n.call(i,a),l=o("%Object.getOwnPropertyDescriptor%",!0),u=o("%Object.defineProperty%",!0),c=o("%Math.max%");if(u)try{u({},"a",{value:1})}catch(e){u=null}e.exports=function(e){var t=s(n,i,arguments);if(l&&u){var r=l(t,"length");r.configurable&&u(t,"length",{value:1+c(0,e.length-(arguments.length-1))})}return t};var p=function(){return s(n,a,arguments)};u?u(e.exports,"apply",{value:p}):e.exports.apply=p},94184:(e,t)=>{var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t{"use strict";t.parse=function(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");var r={},n=(t||{}).decode||o,a=0;for(;a{"use strict";var n=r(11742),o={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var r,a,i,s,l,u,c=!1;t||(t={}),r=t.debug||!1;try{if(i=n(),s=document.createRange(),l=document.getSelection(),(u=document.createElement("span")).textContent=e,u.style.all="unset",u.style.position="fixed",u.style.top=0,u.style.clip="rect(0, 0, 0, 0)",u.style.whiteSpace="pre",u.style.webkitUserSelect="text",u.style.MozUserSelect="text",u.style.msUserSelect="text",u.style.userSelect="text",u.addEventListener("copy",(function(n){if(n.stopPropagation(),t.format)if(n.preventDefault(),void 0===n.clipboardData){r&&console.warn("unable to use e.clipboardData"),r&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var a=o[t.format]||o.default;window.clipboardData.setData(a,e)}else n.clipboardData.clearData(),n.clipboardData.setData(t.format,e);t.onCopy&&(n.preventDefault(),t.onCopy(n.clipboardData))})),document.body.appendChild(u),s.selectNodeContents(u),l.addRange(s),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(n){r&&console.error("unable to copy using execCommand: ",n),r&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),c=!0}catch(n){r&&console.error("unable to copy using clipboardData: ",n),r&&console.error("falling back to prompt"),a=function(e){var t=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C";return e.replace(/#{\s*key\s*}/g,t)}("message"in t?t.message:"Copy to clipboard: #{key}, Enter"),window.prompt(a,e)}}finally{l&&("function"==typeof l.removeRange?l.removeRange(s):l.removeAllRanges()),u&&document.body.removeChild(u),i()}return c}},95299:(e,t,r)=>{var n=r(24848);e.exports=n},83450:(e,t,r)=>{var n=r(83363);e.exports=n},66820:(e,t,r)=>{var n=r(56243);e.exports=n},5023:(e,t,r)=>{var n=r(72369);e.exports=n},90093:(e,t,r)=>{var n=r(28196);e.exports=n},3688:(e,t,r)=>{var n=r(11955);e.exports=n},83838:(e,t,r)=>{var n=r(46279);e.exports=n},15684:(e,t,r)=>{var n=r(19373);e.exports=n},99826:(e,t,r)=>{var n=r(28427);e.exports=n},84234:(e,t,r)=>{var n=r(82073);e.exports=n},65362:(e,t,r)=>{var n=r(63383);e.exports=n},32271:(e,t,r)=>{var n=r(14471);e.exports=n},91254:(e,t,r)=>{var n=r(57396);e.exports=n},43536:(e,t,r)=>{var n=r(41910);e.exports=n},37331:(e,t,r)=>{var n=r(79427);e.exports=n},68522:(e,t,r)=>{var n=r(62857);e.exports=n},73151:(e,t,r)=>{var n=r(9534);e.exports=n},99565:(e,t,r)=>{var n=r(96507);e.exports=n},45012:(e,t,r)=>{var n=r(23059);e.exports=n},78690:(e,t,r)=>{var n=r(16670);e.exports=n},25626:(e,t,r)=>{var n=r(27460);e.exports=n},80281:(e,t,r)=>{var n=r(92547);e.exports=n},40031:(e,t,r)=>{var n=r(46509);e.exports=n},54493:(e,t,r)=>{r(77971),r(53242);var n=r(54058);e.exports=n.Array.from},24034:(e,t,r)=>{r(92737);var n=r(54058);e.exports=n.Array.isArray},15367:(e,t,r)=>{r(85906);var n=r(35703);e.exports=n("Array").concat},12710:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").entries},51459:(e,t,r)=>{r(48851);var n=r(35703);e.exports=n("Array").every},6172:(e,t,r)=>{r(80290);var n=r(35703);e.exports=n("Array").fill},62383:(e,t,r)=>{r(21501);var n=r(35703);e.exports=n("Array").filter},60009:(e,t,r)=>{r(44929);var n=r(35703);e.exports=n("Array").findIndex},17671:(e,t,r)=>{r(80833);var n=r(35703);e.exports=n("Array").find},99324:(e,t,r)=>{r(2437);var n=r(35703);e.exports=n("Array").forEach},80991:(e,t,r)=>{r(97690);var n=r(35703);e.exports=n("Array").includes},8700:(e,t,r)=>{r(99076);var n=r(35703);e.exports=n("Array").indexOf},95909:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").keys},6442:(e,t,r)=>{r(75915);var n=r(35703);e.exports=n("Array").lastIndexOf},23866:(e,t,r)=>{r(68787);var n=r(35703);e.exports=n("Array").map},52999:(e,t,r)=>{r(81876);var n=r(35703);e.exports=n("Array").reduce},91876:(e,t,r)=>{r(11490);var n=r(35703);e.exports=n("Array").reverse},24900:(e,t,r)=>{r(60186);var n=r(35703);e.exports=n("Array").slice},3824:(e,t,r)=>{r(36026);var n=r(35703);e.exports=n("Array").some},2948:(e,t,r)=>{r(4115);var n=r(35703);e.exports=n("Array").sort},78209:(e,t,r)=>{r(98611);var n=r(35703);e.exports=n("Array").splice},14423:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").values},81103:(e,t,r)=>{r(95160);var n=r(54058);e.exports=n.Date.now},27700:(e,t,r)=>{r(73381);var n=r(35703);e.exports=n("Function").bind},13830:(e,t,r)=>{r(66274),r(77971);var n=r(22902);e.exports=n},91031:(e,t,r)=>{r(52595),e.exports=r(21899)},16246:(e,t,r)=>{var n=r(7046),o=r(27700),a=Function.prototype;e.exports=function(e){var t=e.bind;return e===a||n(a,e)&&t===a.bind?o:t}},56043:(e,t,r)=>{var n=r(7046),o=r(15367),a=Array.prototype;e.exports=function(e){var t=e.concat;return e===a||n(a,e)&&t===a.concat?o:t}},13160:(e,t,r)=>{var n=r(7046),o=r(51459),a=Array.prototype;e.exports=function(e){var t=e.every;return e===a||n(a,e)&&t===a.every?o:t}},80446:(e,t,r)=>{var n=r(7046),o=r(6172),a=Array.prototype;e.exports=function(e){var t=e.fill;return e===a||n(a,e)&&t===a.fill?o:t}},2480:(e,t,r)=>{var n=r(7046),o=r(62383),a=Array.prototype;e.exports=function(e){var t=e.filter;return e===a||n(a,e)&&t===a.filter?o:t}},7147:(e,t,r)=>{var n=r(7046),o=r(60009),a=Array.prototype;e.exports=function(e){var t=e.findIndex;return e===a||n(a,e)&&t===a.findIndex?o:t}},32236:(e,t,r)=>{var n=r(7046),o=r(17671),a=Array.prototype;e.exports=function(e){var t=e.find;return e===a||n(a,e)&&t===a.find?o:t}},58557:(e,t,r)=>{var n=r(7046),o=r(80991),a=r(21631),i=Array.prototype,s=String.prototype;e.exports=function(e){var t=e.includes;return e===i||n(i,e)&&t===i.includes?o:"string"==typeof e||e===s||n(s,e)&&t===s.includes?a:t}},34570:(e,t,r)=>{var n=r(7046),o=r(8700),a=Array.prototype;e.exports=function(e){var t=e.indexOf;return e===a||n(a,e)&&t===a.indexOf?o:t}},57564:(e,t,r)=>{var n=r(7046),o=r(6442),a=Array.prototype;e.exports=function(e){var t=e.lastIndexOf;return e===a||n(a,e)&&t===a.lastIndexOf?o:t}},88287:(e,t,r)=>{var n=r(7046),o=r(23866),a=Array.prototype;e.exports=function(e){var t=e.map;return e===a||n(a,e)&&t===a.map?o:t}},68025:(e,t,r)=>{var n=r(7046),o=r(52999),a=Array.prototype;e.exports=function(e){var t=e.reduce;return e===a||n(a,e)&&t===a.reduce?o:t}},59257:(e,t,r)=>{var n=r(7046),o=r(80454),a=String.prototype;e.exports=function(e){var t=e.repeat;return"string"==typeof e||e===a||n(a,e)&&t===a.repeat?o:t}},91060:(e,t,r)=>{var n=r(7046),o=r(91876),a=Array.prototype;e.exports=function(e){var t=e.reverse;return e===a||n(a,e)&&t===a.reverse?o:t}},69601:(e,t,r)=>{var n=r(7046),o=r(24900),a=Array.prototype;e.exports=function(e){var t=e.slice;return e===a||n(a,e)&&t===a.slice?o:t}},28299:(e,t,r)=>{var n=r(7046),o=r(3824),a=Array.prototype;e.exports=function(e){var t=e.some;return e===a||n(a,e)&&t===a.some?o:t}},69355:(e,t,r)=>{var n=r(7046),o=r(2948),a=Array.prototype;e.exports=function(e){var t=e.sort;return e===a||n(a,e)&&t===a.sort?o:t}},18339:(e,t,r)=>{var n=r(7046),o=r(78209),a=Array.prototype;e.exports=function(e){var t=e.splice;return e===a||n(a,e)&&t===a.splice?o:t}},71611:(e,t,r)=>{var n=r(7046),o=r(3269),a=String.prototype;e.exports=function(e){var t=e.startsWith;return"string"==typeof e||e===a||n(a,e)&&t===a.startsWith?o:t}},62774:(e,t,r)=>{var n=r(7046),o=r(13348),a=String.prototype;e.exports=function(e){var t=e.trim;return"string"==typeof e||e===a||n(a,e)&&t===a.trim?o:t}},84426:(e,t,r)=>{r(32619);var n=r(54058),o=r(79730);n.JSON||(n.JSON={stringify:JSON.stringify}),e.exports=function(e,t,r){return o(n.JSON.stringify,null,arguments)}},91018:(e,t,r)=>{r(66274),r(37501),r(55967),r(77971);var n=r(54058);e.exports=n.Map},45999:(e,t,r)=>{r(49221);var n=r(54058);e.exports=n.Object.assign},35254:(e,t,r)=>{r(53882);var n=r(54058).Object;e.exports=function(e,t){return n.create(e,t)}},7702:(e,t,r)=>{r(74979);var n=r(54058).Object,o=e.exports=function(e,t){return n.defineProperties(e,t)};n.defineProperties.sham&&(o.sham=!0)},48171:(e,t,r)=>{r(86450);var n=r(54058).Object,o=e.exports=function(e,t,r){return n.defineProperty(e,t,r)};n.defineProperty.sham&&(o.sham=!0)},73081:(e,t,r)=>{r(94366);var n=r(54058);e.exports=n.Object.entries},286:(e,t,r)=>{r(46924);var n=r(54058).Object,o=e.exports=function(e,t){return n.getOwnPropertyDescriptor(e,t)};n.getOwnPropertyDescriptor.sham&&(o.sham=!0)},92766:(e,t,r)=>{r(88482);var n=r(54058);e.exports=n.Object.getOwnPropertyDescriptors},30498:(e,t,r)=>{r(35824);var n=r(54058);e.exports=n.Object.getOwnPropertySymbols},13966:(e,t,r)=>{r(17405);var n=r(54058);e.exports=n.Object.getPrototypeOf},48494:(e,t,r)=>{r(21724);var n=r(54058);e.exports=n.Object.keys},3065:(e,t,r)=>{r(90108);var n=r(54058);e.exports=n.Object.setPrototypeOf},98430:(e,t,r)=>{r(26614);var n=r(54058);e.exports=n.Object.values},52956:(e,t,r)=>{r(47627),r(66274),r(55967),r(98881),r(4560),r(91302),r(44349),r(77971);var n=r(54058);e.exports=n.Promise},21631:(e,t,r)=>{r(11035);var n=r(35703);e.exports=n("String").includes},80454:(e,t,r)=>{r(60986);var n=r(35703);e.exports=n("String").repeat},3269:(e,t,r)=>{r(94761);var n=r(35703);e.exports=n("String").startsWith},13348:(e,t,r)=>{r(57398);var n=r(35703);e.exports=n("String").trim},57473:(e,t,r)=>{r(85906),r(55967),r(35824),r(8555),r(52615),r(21732),r(35903),r(1825),r(28394),r(45915),r(61766),r(62737),r(89911),r(74315),r(63131),r(64714),r(70659),r(69120),r(79413),r(1502);var n=r(54058);e.exports=n.Symbol},24227:(e,t,r)=>{r(66274),r(55967),r(77971),r(1825);var n=r(11477);e.exports=n.f("iterator")},32304:(e,t,r)=>{r(66274),r(55967),r(54334);var n=r(54058);e.exports=n.WeakMap},27385:(e,t,r)=>{var n=r(95299);e.exports=n},81522:(e,t,r)=>{var n=r(83450);e.exports=n},32209:(e,t,r)=>{var n=r(66820);e.exports=n},30888:(e,t,r)=>{r(9668);var n=r(5023);e.exports=n},14122:(e,t,r)=>{var n=r(90093);e.exports=n},44442:(e,t,r)=>{var n=r(3688);e.exports=n},57152:(e,t,r)=>{var n=r(83838);e.exports=n},69447:(e,t,r)=>{var n=r(15684);e.exports=n},17579:(e,t,r)=>{var n=r(99826);e.exports=n},81493:(e,t,r)=>{var n=r(84234);e.exports=n},60269:(e,t,r)=>{var n=r(65362);e.exports=n},76094:(e,t,r)=>{var n=r(32271);e.exports=n},70573:(e,t,r)=>{var n=r(91254);e.exports=n},73685:(e,t,r)=>{var n=r(43536);e.exports=n},27533:(e,t,r)=>{var n=r(37331);e.exports=n},39057:(e,t,r)=>{var n=r(68522);e.exports=n},84710:(e,t,r)=>{var n=r(73151);e.exports=n},74303:(e,t,r)=>{var n=r(99565);e.exports=n},93799:(e,t,r)=>{var n=r(45012);e.exports=n},55122:(e,t,r)=>{var n=r(78690);e.exports=n},29531:(e,t,r)=>{var n=r(25626);r(89731),r(55708),r(30014),r(88731),e.exports=n},86600:(e,t,r)=>{var n=r(80281);r(28783),r(43975),r(65799),r(45414),r(46774),r(80620),r(36172),e.exports=n},9759:(e,t,r)=>{var n=r(40031);e.exports=n},24883:(e,t,r)=>{var n=r(21899),o=r(57475),a=r(69826),i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not a function")}},174:(e,t,r)=>{var n=r(21899),o=r(24284),a=r(69826),i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not a constructor")}},11851:(e,t,r)=>{var n=r(21899),o=r(57475),a=n.String,i=n.TypeError;e.exports=function(e){if("object"==typeof e||o(e))return e;throw i("Can't set "+a(e)+" as a prototype")}},18479:e=>{e.exports=function(){}},5743:(e,t,r)=>{var n=r(21899),o=r(7046),a=n.TypeError;e.exports=function(e,t){if(o(t,e))return e;throw a("Incorrect invocation")}},96059:(e,t,r)=>{var n=r(21899),o=r(10941),a=n.String,i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not an object")}},97135:(e,t,r)=>{var n=r(95981);e.exports=n((function(){if("function"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,"a",{value:8})}}))},91860:(e,t,r)=>{"use strict";var n=r(89678),o=r(59413),a=r(10623);e.exports=function(e){for(var t=n(this),r=a(t),i=arguments.length,s=o(i>1?arguments[1]:void 0,r),l=i>2?arguments[2]:void 0,u=void 0===l?r:o(l,r);u>s;)t[s++]=e;return t}},56837:(e,t,r)=>{"use strict";var n=r(3610).forEach,o=r(34194)("forEach");e.exports=o?[].forEach:function(e){return n(this,e,arguments.length>1?arguments[1]:void 0)}},11354:(e,t,r)=>{"use strict";var n=r(21899),o=r(86843),a=r(78834),i=r(89678),s=r(75196),l=r(6782),u=r(24284),c=r(10623),p=r(55449),f=r(53476),h=r(22902),d=n.Array;e.exports=function(e){var t=i(e),r=u(this),n=arguments.length,m=n>1?arguments[1]:void 0,g=void 0!==m;g&&(m=o(m,n>2?arguments[2]:void 0));var v,y,b,w,E,x,_=h(t),S=0;if(!_||this==d&&l(_))for(v=c(t),y=r?new this(v):d(v);v>S;S++)x=g?m(t[S],S):t[S],p(y,S,x);else for(E=(w=f(t,_)).next,y=r?new this:[];!(b=a(E,w)).done;S++)x=g?s(w,m,[b.value,S],!0):b.value,p(y,S,x);return y.length=S,y}},31692:(e,t,r)=>{var n=r(74529),o=r(59413),a=r(10623),i=function(e){return function(t,r,i){var s,l=n(t),u=a(l),c=o(i,u);if(e&&r!=r){for(;u>c;)if((s=l[c++])!=s)return!0}else for(;u>c;c++)if((e||c in l)&&l[c]===r)return e||c||0;return!e&&-1}};e.exports={includes:i(!0),indexOf:i(!1)}},3610:(e,t,r)=>{var n=r(86843),o=r(95329),a=r(37026),i=r(89678),s=r(10623),l=r(64692),u=o([].push),c=function(e){var t=1==e,r=2==e,o=3==e,c=4==e,p=6==e,f=7==e,h=5==e||p;return function(d,m,g,v){for(var y,b,w=i(d),E=a(w),x=n(m,g),_=s(E),S=0,A=v||l,k=t?A(d,_):r||f?A(d,0):void 0;_>S;S++)if((h||S in E)&&(b=x(y=E[S],S,w),e))if(t)k[S]=b;else if(b)switch(e){case 3:return!0;case 5:return y;case 6:return S;case 2:u(k,y)}else switch(e){case 4:return!1;case 7:u(k,y)}return p?-1:o||c?c:k}};e.exports={forEach:c(0),map:c(1),filter:c(2),some:c(3),every:c(4),find:c(5),findIndex:c(6),filterReject:c(7)}},67145:(e,t,r)=>{"use strict";var n=r(79730),o=r(74529),a=r(62435),i=r(10623),s=r(34194),l=Math.min,u=[].lastIndexOf,c=!!u&&1/[1].lastIndexOf(1,-0)<0,p=s("lastIndexOf"),f=c||!p;e.exports=f?function(e){if(c)return n(u,this,arguments)||0;var t=o(this),r=i(t),s=r-1;for(arguments.length>1&&(s=l(s,a(arguments[1]))),s<0&&(s=r+s);s>=0;s--)if(s in t&&t[s]===e)return s||0;return-1}:u},50568:(e,t,r)=>{var n=r(95981),o=r(99813),a=r(53385),i=o("species");e.exports=function(e){return a>=51||!n((function(){var t=[];return(t.constructor={})[i]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},34194:(e,t,r)=>{"use strict";var n=r(95981);e.exports=function(e,t){var r=[][e];return!!r&&n((function(){r.call(null,t||function(){throw 1},1)}))}},46499:(e,t,r)=>{var n=r(21899),o=r(24883),a=r(89678),i=r(37026),s=r(10623),l=n.TypeError,u=function(e){return function(t,r,n,u){o(r);var c=a(t),p=i(c),f=s(c),h=e?f-1:0,d=e?-1:1;if(n<2)for(;;){if(h in p){u=p[h],h+=d;break}if(h+=d,e?h<0:f<=h)throw l("Reduce of empty array with no initial value")}for(;e?h>=0:f>h;h+=d)h in p&&(u=r(u,p[h],h,c));return u}};e.exports={left:u(!1),right:u(!0)}},15790:(e,t,r)=>{var n=r(21899),o=r(59413),a=r(10623),i=r(55449),s=n.Array,l=Math.max;e.exports=function(e,t,r){for(var n=a(e),u=o(t,n),c=o(void 0===r?n:r,n),p=s(l(c-u,0)),f=0;u{var n=r(95329);e.exports=n([].slice)},61388:(e,t,r)=>{var n=r(15790),o=Math.floor,a=function(e,t){var r=e.length,l=o(r/2);return r<8?i(e,t):s(e,a(n(e,0,l),t),a(n(e,l),t),t)},i=function(e,t){for(var r,n,o=e.length,a=1;a0;)e[n]=e[--n];n!==a++&&(e[n]=r)}return e},s=function(e,t,r,n){for(var o=t.length,a=r.length,i=0,s=0;i{var n=r(21899),o=r(1052),a=r(24284),i=r(10941),s=r(99813)("species"),l=n.Array;e.exports=function(e){var t;return o(e)&&(t=e.constructor,(a(t)&&(t===l||o(t.prototype))||i(t)&&null===(t=t[s]))&&(t=void 0)),void 0===t?l:t}},64692:(e,t,r)=>{var n=r(5693);e.exports=function(e,t){return new(n(e))(0===t?0:t)}},75196:(e,t,r)=>{var n=r(96059),o=r(7609);e.exports=function(e,t,r,a){try{return a?t(n(r)[0],r[1]):t(r)}catch(t){o(e,"throw",t)}}},21385:(e,t,r)=>{var n=r(99813)("iterator"),o=!1;try{var a=0,i={next:function(){return{done:!!a++}},return:function(){o=!0}};i[n]=function(){return this},Array.from(i,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!o)return!1;var r=!1;try{var a={};a[n]=function(){return{next:function(){return{done:r=!0}}}},e(a)}catch(e){}return r}},82532:(e,t,r)=>{var n=r(95329),o=n({}.toString),a=n("".slice);e.exports=function(e){return a(o(e),8,-1)}},9697:(e,t,r)=>{var n=r(21899),o=r(22885),a=r(57475),i=r(82532),s=r(99813)("toStringTag"),l=n.Object,u="Arguments"==i(function(){return arguments}());e.exports=o?i:function(e){var t,r,n;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(r=function(e,t){try{return e[t]}catch(e){}}(t=l(e),s))?r:u?i(t):"Object"==(n=i(t))&&a(t.callee)?"Arguments":n}},38694:(e,t,r)=>{var n=r(95329)("".replace),o=String(Error("zxcasd").stack),a=/\n\s*at [^:]*:[^\n]*/,i=a.test(o);e.exports=function(e,t){if(i&&"string"==typeof e)for(;t--;)e=n(e,a,"");return e}},85616:(e,t,r)=>{"use strict";var n=r(65988).f,o=r(29290),a=r(87524),i=r(86843),s=r(5743),l=r(93091),u=r(47771),c=r(94431),p=r(55746),f=r(21647).fastKey,h=r(45402),d=h.set,m=h.getterFor;e.exports={getConstructor:function(e,t,r,u){var c=e((function(e,n){s(e,h),d(e,{type:t,index:o(null),first:void 0,last:void 0,size:0}),p||(e.size=0),null!=n&&l(n,e[u],{that:e,AS_ENTRIES:r})})),h=c.prototype,g=m(t),v=function(e,t,r){var n,o,a=g(e),i=y(e,t);return i?i.value=r:(a.last=i={index:o=f(t,!0),key:t,value:r,previous:n=a.last,next:void 0,removed:!1},a.first||(a.first=i),n&&(n.next=i),p?a.size++:e.size++,"F"!==o&&(a.index[o]=i)),e},y=function(e,t){var r,n=g(e),o=f(t);if("F"!==o)return n.index[o];for(r=n.first;r;r=r.next)if(r.key==t)return r};return a(h,{clear:function(){for(var e=g(this),t=e.index,r=e.first;r;)r.removed=!0,r.previous&&(r.previous=r.previous.next=void 0),delete t[r.index],r=r.next;e.first=e.last=void 0,p?e.size=0:this.size=0},delete:function(e){var t=this,r=g(t),n=y(t,e);if(n){var o=n.next,a=n.previous;delete r.index[n.index],n.removed=!0,a&&(a.next=o),o&&(o.previous=a),r.first==n&&(r.first=o),r.last==n&&(r.last=a),p?r.size--:t.size--}return!!n},forEach:function(e){for(var t,r=g(this),n=i(e,arguments.length>1?arguments[1]:void 0);t=t?t.next:r.first;)for(n(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!y(this,e)}}),a(h,r?{get:function(e){var t=y(this,e);return t&&t.value},set:function(e,t){return v(this,0===e?0:e,t)}}:{add:function(e){return v(this,e=0===e?0:e,e)}}),p&&n(h,"size",{get:function(){return g(this).size}}),c},setStrong:function(e,t,r){var n=t+" Iterator",o=m(t),a=m(n);u(e,t,(function(e,t){d(this,{type:n,target:e,state:o(e),kind:t,last:void 0})}),(function(){for(var e=a(this),t=e.kind,r=e.last;r&&r.removed;)r=r.previous;return e.target&&(e.last=r=r?r.next:e.state.first)?"keys"==t?{value:r.key,done:!1}:"values"==t?{value:r.value,done:!1}:{value:[r.key,r.value],done:!1}:(e.target=void 0,{value:void 0,done:!0})}),r?"entries":"values",!r,!0),c(t)}}},8850:(e,t,r)=>{"use strict";var n=r(95329),o=r(87524),a=r(21647).getWeakData,i=r(96059),s=r(10941),l=r(5743),u=r(93091),c=r(3610),p=r(90953),f=r(45402),h=f.set,d=f.getterFor,m=c.find,g=c.findIndex,v=n([].splice),y=0,b=function(e){return e.frozen||(e.frozen=new w)},w=function(){this.entries=[]},E=function(e,t){return m(e.entries,(function(e){return e[0]===t}))};w.prototype={get:function(e){var t=E(this,e);if(t)return t[1]},has:function(e){return!!E(this,e)},set:function(e,t){var r=E(this,e);r?r[1]=t:this.entries.push([e,t])},delete:function(e){var t=g(this.entries,(function(t){return t[0]===e}));return~t&&v(this.entries,t,1),!!~t}},e.exports={getConstructor:function(e,t,r,n){var c=e((function(e,o){l(e,f),h(e,{type:t,id:y++,frozen:void 0}),null!=o&&u(o,e[n],{that:e,AS_ENTRIES:r})})),f=c.prototype,m=d(t),g=function(e,t,r){var n=m(e),o=a(i(t),!0);return!0===o?b(n).set(t,r):o[n.id]=r,e};return o(f,{delete:function(e){var t=m(this);if(!s(e))return!1;var r=a(e);return!0===r?b(t).delete(e):r&&p(r,t.id)&&delete r[t.id]},has:function(e){var t=m(this);if(!s(e))return!1;var r=a(e);return!0===r?b(t).has(e):r&&p(r,t.id)}}),o(f,r?{get:function(e){var t=m(this);if(s(e)){var r=a(e);return!0===r?b(t).get(e):r?r[t.id]:void 0}},set:function(e,t){return g(this,e,t)}}:{add:function(e){return g(this,e,!0)}}),c}}},24683:(e,t,r)=>{"use strict";var n=r(76887),o=r(21899),a=r(21647),i=r(95981),s=r(32029),l=r(93091),u=r(5743),c=r(57475),p=r(10941),f=r(90904),h=r(65988).f,d=r(3610).forEach,m=r(55746),g=r(45402),v=g.set,y=g.getterFor;e.exports=function(e,t,r){var g,b=-1!==e.indexOf("Map"),w=-1!==e.indexOf("Weak"),E=b?"set":"add",x=o[e],_=x&&x.prototype,S={};if(m&&c(x)&&(w||_.forEach&&!i((function(){(new x).entries().next()})))){var A=(g=t((function(t,r){v(u(t,A),{type:e,collection:new x}),null!=r&&l(r,t[E],{that:t,AS_ENTRIES:b})}))).prototype,k=y(e);d(["add","clear","delete","forEach","get","has","set","keys","values","entries"],(function(e){var t="add"==e||"set"==e;!(e in _)||w&&"clear"==e||s(A,e,(function(r,n){var o=k(this).collection;if(!t&&w&&!p(r))return"get"==e&&void 0;var a=o[e](0===r?0:r,n);return t?this:a}))})),w||h(A,"size",{configurable:!0,get:function(){return k(this).collection.size}})}else g=r.getConstructor(t,e,b,E),a.enable();return f(g,e,!1,!0),S[e]=g,n({global:!0,forced:!0},S),w||r.setStrong(g,e,b),g}},23489:(e,t,r)=>{var n=r(90953),o=r(31136),a=r(49677),i=r(65988);e.exports=function(e,t,r){for(var s=o(t),l=i.f,u=a.f,c=0;c{var n=r(99813)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(r){try{return t[n]=!1,"/./"[e](t)}catch(e){}}return!1}},64160:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},31046:(e,t,r)=>{"use strict";var n=r(35143).IteratorPrototype,o=r(29290),a=r(31887),i=r(90904),s=r(12077),l=function(){return this};e.exports=function(e,t,r,u){var c=t+" Iterator";return e.prototype=o(n,{next:a(+!u,r)}),i(e,c,!1,!0),s[c]=l,e}},32029:(e,t,r)=>{var n=r(55746),o=r(65988),a=r(31887);e.exports=n?function(e,t,r){return o.f(e,t,a(1,r))}:function(e,t,r){return e[t]=r,e}},31887:e=>{e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},55449:(e,t,r)=>{"use strict";var n=r(83894),o=r(65988),a=r(31887);e.exports=function(e,t,r){var i=n(t);i in e?o.f(e,i,a(0,r)):e[i]=r}},47771:(e,t,r)=>{"use strict";var n=r(76887),o=r(78834),a=r(82529),i=r(79417),s=r(57475),l=r(31046),u=r(249),c=r(88929),p=r(90904),f=r(32029),h=r(99754),d=r(99813),m=r(12077),g=r(35143),v=i.PROPER,y=i.CONFIGURABLE,b=g.IteratorPrototype,w=g.BUGGY_SAFARI_ITERATORS,E=d("iterator"),x="keys",_="values",S="entries",A=function(){return this};e.exports=function(e,t,r,i,d,g,k){l(r,t,i);var C,O,j,I=function(e){if(e===d&&M)return M;if(!w&&e in P)return P[e];switch(e){case x:case _:case S:return function(){return new r(this,e)}}return function(){return new r(this)}},N=t+" Iterator",T=!1,P=e.prototype,R=P[E]||P["@@iterator"]||d&&P[d],M=!w&&R||I(d),D="Array"==t&&P.entries||R;if(D&&(C=u(D.call(new e)))!==Object.prototype&&C.next&&(a||u(C)===b||(c?c(C,b):s(C[E])||h(C,E,A)),p(C,N,!0,!0),a&&(m[N]=A)),v&&d==_&&R&&R.name!==_&&(!a&&y?f(P,"name",_):(T=!0,M=function(){return o(R,this)})),d)if(O={values:I(_),keys:g?M:I(x),entries:I(S)},k)for(j in O)(w||T||!(j in P))&&h(P,j,O[j]);else n({target:t,proto:!0,forced:w||T},O);return a&&!k||P[E]===M||h(P,E,M,{name:d}),m[t]=M,O}},66349:(e,t,r)=>{var n=r(54058),o=r(90953),a=r(11477),i=r(65988).f;e.exports=function(e){var t=n.Symbol||(n.Symbol={});o(t,e)||i(t,e,{value:a.f(e)})}},55746:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},61333:(e,t,r)=>{var n=r(21899),o=r(10941),a=n.document,i=o(a)&&o(a.createElement);e.exports=function(e){return i?a.createElement(e):{}}},63281:e=>{e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},34342:(e,t,r)=>{var n=r(2861).match(/firefox\/(\d+)/i);e.exports=!!n&&+n[1]},23321:e=>{e.exports="object"==typeof window},81046:(e,t,r)=>{var n=r(2861);e.exports=/MSIE|Trident/.test(n)},4470:(e,t,r)=>{var n=r(2861),o=r(21899);e.exports=/ipad|iphone|ipod/i.test(n)&&void 0!==o.Pebble},22749:(e,t,r)=>{var n=r(2861);e.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(n)},6049:(e,t,r)=>{var n=r(82532),o=r(21899);e.exports="process"==n(o.process)},58045:(e,t,r)=>{var n=r(2861);e.exports=/web0s(?!.*chrome)/i.test(n)},2861:(e,t,r)=>{var n=r(626);e.exports=n("navigator","userAgent")||""},53385:(e,t,r)=>{var n,o,a=r(21899),i=r(2861),s=a.process,l=a.Deno,u=s&&s.versions||l&&l.version,c=u&&u.v8;c&&(o=(n=c.split("."))[0]>0&&n[0]<4?1:+(n[0]+n[1])),!o&&i&&(!(n=i.match(/Edge\/(\d+)/))||n[1]>=74)&&(n=i.match(/Chrome\/(\d+)/))&&(o=+n[1]),e.exports=o},18938:(e,t,r)=>{var n=r(2861).match(/AppleWebKit\/(\d+)\./);e.exports=!!n&&+n[1]},35703:(e,t,r)=>{var n=r(54058);e.exports=function(e){return n[e+"Prototype"]}},56759:e=>{e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},18780:(e,t,r)=>{var n=r(95981),o=r(31887);e.exports=!n((function(){var e=Error("a");return!("stack"in e)||(Object.defineProperty(e,"stack",o(1,7)),7!==e.stack)}))},76887:(e,t,r)=>{"use strict";var n=r(21899),o=r(79730),a=r(95329),i=r(57475),s=r(49677).f,l=r(37252),u=r(54058),c=r(86843),p=r(32029),f=r(90953),h=function(e){var t=function(r,n,a){if(this instanceof t){switch(arguments.length){case 0:return new e;case 1:return new e(r);case 2:return new e(r,n)}return new e(r,n,a)}return o(e,this,arguments)};return t.prototype=e.prototype,t};e.exports=function(e,t){var r,o,d,m,g,v,y,b,w=e.target,E=e.global,x=e.stat,_=e.proto,S=E?n:x?n[w]:(n[w]||{}).prototype,A=E?u:u[w]||p(u,w,{})[w],k=A.prototype;for(d in t)r=!l(E?d:w+(x?".":"#")+d,e.forced)&&S&&f(S,d),g=A[d],r&&(v=e.noTargetGet?(b=s(S,d))&&b.value:S[d]),m=r&&v?v:t[d],r&&typeof g==typeof m||(y=e.bind&&r?c(m,n):e.wrap&&r?h(m):_&&i(m)?a(m):m,(e.sham||m&&m.sham||g&&g.sham)&&p(y,"sham",!0),p(A,d,y),_&&(f(u,o=w+"Prototype")||p(u,o,{}),p(u[o],d,m),e.real&&k&&!k[d]&&p(k,d,m)))}},95981:e=>{e.exports=function(e){try{return!!e()}catch(e){return!0}}},45602:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){return Object.isExtensible(Object.preventExtensions({}))}))},79730:(e,t,r)=>{var n=r(18285),o=Function.prototype,a=o.apply,i=o.call;e.exports="object"==typeof Reflect&&Reflect.apply||(n?i.bind(a):function(){return i.apply(a,arguments)})},86843:(e,t,r)=>{var n=r(95329),o=r(24883),a=r(18285),i=n(n.bind);e.exports=function(e,t){return o(e),void 0===t?e:a?i(e,t):function(){return e.apply(t,arguments)}}},18285:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},98308:(e,t,r)=>{"use strict";var n=r(21899),o=r(95329),a=r(24883),i=r(10941),s=r(90953),l=r(93765),u=r(18285),c=n.Function,p=o([].concat),f=o([].join),h={},d=function(e,t,r){if(!s(h,t)){for(var n=[],o=0;o{var n=r(18285),o=Function.prototype.call;e.exports=n?o.bind(o):function(){return o.apply(o,arguments)}},79417:(e,t,r)=>{var n=r(55746),o=r(90953),a=Function.prototype,i=n&&Object.getOwnPropertyDescriptor,s=o(a,"name"),l=s&&"something"===function(){}.name,u=s&&(!n||n&&i(a,"name").configurable);e.exports={EXISTS:s,PROPER:l,CONFIGURABLE:u}},95329:(e,t,r)=>{var n=r(18285),o=Function.prototype,a=o.bind,i=o.call,s=n&&a.bind(i,i);e.exports=n?function(e){return e&&s(e)}:function(e){return e&&function(){return i.apply(e,arguments)}}},626:(e,t,r)=>{var n=r(54058),o=r(21899),a=r(57475),i=function(e){return a(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?i(n[e])||i(o[e]):n[e]&&n[e][t]||o[e]&&o[e][t]}},22902:(e,t,r)=>{var n=r(9697),o=r(14229),a=r(12077),i=r(99813)("iterator");e.exports=function(e){if(null!=e)return o(e,i)||o(e,"@@iterator")||a[n(e)]}},53476:(e,t,r)=>{var n=r(21899),o=r(78834),a=r(24883),i=r(96059),s=r(69826),l=r(22902),u=n.TypeError;e.exports=function(e,t){var r=arguments.length<2?l(e):t;if(a(r))return i(o(r,e));throw u(s(e)+" is not iterable")}},14229:(e,t,r)=>{var n=r(24883);e.exports=function(e,t){var r=e[t];return null==r?void 0:n(r)}},21899:(e,t,r)=>{var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof r.g&&r.g)||function(){return this}()||Function("return this")()},90953:(e,t,r)=>{var n=r(95329),o=r(89678),a=n({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,t){return a(o(e),t)}},27748:e=>{e.exports={}},34845:(e,t,r)=>{var n=r(21899);e.exports=function(e,t){var r=n.console;r&&r.error&&(1==arguments.length?r.error(e):r.error(e,t))}},15463:(e,t,r)=>{var n=r(626);e.exports=n("document","documentElement")},2840:(e,t,r)=>{var n=r(55746),o=r(95981),a=r(61333);e.exports=!n&&!o((function(){return 7!=Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},37026:(e,t,r)=>{var n=r(21899),o=r(95329),a=r(95981),i=r(82532),s=n.Object,l=o("".split);e.exports=a((function(){return!s("z").propertyIsEnumerable(0)}))?function(e){return"String"==i(e)?l(e,""):s(e)}:s},81302:(e,t,r)=>{var n=r(95329),o=r(57475),a=r(63030),i=n(Function.toString);o(a.inspectSource)||(a.inspectSource=function(e){return i(e)}),e.exports=a.inspectSource},53794:(e,t,r)=>{var n=r(10941),o=r(32029);e.exports=function(e,t){n(t)&&"cause"in t&&o(e,"cause",t.cause)}},21647:(e,t,r)=>{var n=r(76887),o=r(95329),a=r(27748),i=r(10941),s=r(90953),l=r(65988).f,u=r(10946),c=r(684),p=r(91584),f=r(99418),h=r(45602),d=!1,m=f("meta"),g=0,v=function(e){l(e,m,{value:{objectID:"O"+g++,weakData:{}}})},y=e.exports={enable:function(){y.enable=function(){},d=!0;var e=u.f,t=o([].splice),r={};r[m]=1,e(r).length&&(u.f=function(r){for(var n=e(r),o=0,a=n.length;o{var n,o,a,i=r(38019),s=r(21899),l=r(95329),u=r(10941),c=r(32029),p=r(90953),f=r(63030),h=r(44262),d=r(27748),m="Object already initialized",g=s.TypeError,v=s.WeakMap;if(i||f.state){var y=f.state||(f.state=new v),b=l(y.get),w=l(y.has),E=l(y.set);n=function(e,t){if(w(y,e))throw new g(m);return t.facade=e,E(y,e,t),t},o=function(e){return b(y,e)||{}},a=function(e){return w(y,e)}}else{var x=h("state");d[x]=!0,n=function(e,t){if(p(e,x))throw new g(m);return t.facade=e,c(e,x,t),t},o=function(e){return p(e,x)?e[x]:{}},a=function(e){return p(e,x)}}e.exports={set:n,get:o,has:a,enforce:function(e){return a(e)?o(e):n(e,{})},getterFor:function(e){return function(t){var r;if(!u(t)||(r=o(t)).type!==e)throw g("Incompatible receiver, "+e+" required");return r}}}},6782:(e,t,r)=>{var n=r(99813),o=r(12077),a=n("iterator"),i=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||i[a]===e)}},1052:(e,t,r)=>{var n=r(82532);e.exports=Array.isArray||function(e){return"Array"==n(e)}},57475:e=>{e.exports=function(e){return"function"==typeof e}},24284:(e,t,r)=>{var n=r(95329),o=r(95981),a=r(57475),i=r(9697),s=r(626),l=r(81302),u=function(){},c=[],p=s("Reflect","construct"),f=/^\s*(?:class|function)\b/,h=n(f.exec),d=!f.exec(u),m=function(e){if(!a(e))return!1;try{return p(u,c,e),!0}catch(e){return!1}},g=function(e){if(!a(e))return!1;switch(i(e)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return d||!!h(f,l(e))}catch(e){return!0}};g.sham=!0,e.exports=!p||o((function(){var e;return m(m.call)||!m(Object)||!m((function(){e=!0}))||e}))?g:m},37252:(e,t,r)=>{var n=r(95981),o=r(57475),a=/#|\.prototype\./,i=function(e,t){var r=l[s(e)];return r==c||r!=u&&(o(t)?n(t):!!t)},s=i.normalize=function(e){return String(e).replace(a,".").toLowerCase()},l=i.data={},u=i.NATIVE="N",c=i.POLYFILL="P";e.exports=i},10941:(e,t,r)=>{var n=r(57475);e.exports=function(e){return"object"==typeof e?null!==e:n(e)}},82529:e=>{e.exports=!0},60685:(e,t,r)=>{var n=r(10941),o=r(82532),a=r(99813)("match");e.exports=function(e){var t;return n(e)&&(void 0!==(t=e[a])?!!t:"RegExp"==o(e))}},56664:(e,t,r)=>{var n=r(21899),o=r(626),a=r(57475),i=r(7046),s=r(32302),l=n.Object;e.exports=s?function(e){return"symbol"==typeof e}:function(e){var t=o("Symbol");return a(t)&&i(t.prototype,l(e))}},93091:(e,t,r)=>{var n=r(21899),o=r(86843),a=r(78834),i=r(96059),s=r(69826),l=r(6782),u=r(10623),c=r(7046),p=r(53476),f=r(22902),h=r(7609),d=n.TypeError,m=function(e,t){this.stopped=e,this.result=t},g=m.prototype;e.exports=function(e,t,r){var n,v,y,b,w,E,x,_=r&&r.that,S=!(!r||!r.AS_ENTRIES),A=!(!r||!r.IS_ITERATOR),k=!(!r||!r.INTERRUPTED),C=o(t,_),O=function(e){return n&&h(n,"normal",e),new m(!0,e)},j=function(e){return S?(i(e),k?C(e[0],e[1],O):C(e[0],e[1])):k?C(e,O):C(e)};if(A)n=e;else{if(!(v=f(e)))throw d(s(e)+" is not iterable");if(l(v)){for(y=0,b=u(e);b>y;y++)if((w=j(e[y]))&&c(g,w))return w;return new m(!1)}n=p(e,v)}for(E=n.next;!(x=a(E,n)).done;){try{w=j(x.value)}catch(e){h(n,"throw",e)}if("object"==typeof w&&w&&c(g,w))return w}return new m(!1)}},7609:(e,t,r)=>{var n=r(78834),o=r(96059),a=r(14229);e.exports=function(e,t,r){var i,s;o(e);try{if(!(i=a(e,"return"))){if("throw"===t)throw r;return r}i=n(i,e)}catch(e){s=!0,i=e}if("throw"===t)throw r;if(s)throw i;return o(i),r}},35143:(e,t,r)=>{"use strict";var n,o,a,i=r(95981),s=r(57475),l=r(29290),u=r(249),c=r(99754),p=r(99813),f=r(82529),h=p("iterator"),d=!1;[].keys&&("next"in(a=[].keys())?(o=u(u(a)))!==Object.prototype&&(n=o):d=!0),null==n||i((function(){var e={};return n[h].call(e)!==e}))?n={}:f&&(n=l(n)),s(n[h])||c(n,h,(function(){return this})),e.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:d}},12077:e=>{e.exports={}},10623:(e,t,r)=>{var n=r(43057);e.exports=function(e){return n(e.length)}},66132:(e,t,r)=>{var n,o,a,i,s,l,u,c,p=r(21899),f=r(86843),h=r(49677).f,d=r(42941).set,m=r(22749),g=r(4470),v=r(58045),y=r(6049),b=p.MutationObserver||p.WebKitMutationObserver,w=p.document,E=p.process,x=p.Promise,_=h(p,"queueMicrotask"),S=_&&_.value;S||(n=function(){var e,t;for(y&&(e=E.domain)&&e.exit();o;){t=o.fn,o=o.next;try{t()}catch(e){throw o?i():a=void 0,e}}a=void 0,e&&e.enter()},m||y||v||!b||!w?!g&&x&&x.resolve?((u=x.resolve(void 0)).constructor=x,c=f(u.then,u),i=function(){c(n)}):y?i=function(){E.nextTick(n)}:(d=f(d,p),i=function(){d(n)}):(s=!0,l=w.createTextNode(""),new b(n).observe(l,{characterData:!0}),i=function(){l.data=s=!s})),e.exports=S||function(e){var t={fn:e,next:void 0};a&&(a.next=t),o||(o=t,i()),a=t}},19297:(e,t,r)=>{var n=r(21899);e.exports=n.Promise},72497:(e,t,r)=>{var n=r(53385),o=r(95981);e.exports=!!Object.getOwnPropertySymbols&&!o((function(){var e=Symbol();return!String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&n&&n<41}))},28468:(e,t,r)=>{var n=r(95981),o=r(99813),a=r(82529),i=o("iterator");e.exports=!n((function(){var e=new URL("b?a=1&b=2&c=3","http://a"),t=e.searchParams,r="";return e.pathname="c%20d",t.forEach((function(e,n){t.delete("b"),r+=n+e})),a&&!e.toJSON||!t.sort||"http://a/c%20d?a=1&c=3"!==e.href||"3"!==t.get("c")||"a=1"!==String(new URLSearchParams("?a=1"))||!t[i]||"a"!==new URL("https://a@b").username||"b"!==new URLSearchParams(new URLSearchParams("a=b")).get("a")||"xn--e1aybc"!==new URL("http://тест").host||"#%D0%B1"!==new URL("http://a#б").hash||"a1c3"!==r||"x"!==new URL("http://x",void 0).host}))},38019:(e,t,r)=>{var n=r(21899),o=r(57475),a=r(81302),i=n.WeakMap;e.exports=o(i)&&/native code/.test(a(i))},69520:(e,t,r)=>{"use strict";var n=r(24883),o=function(e){var t,r;this.promise=new e((function(e,n){if(void 0!==t||void 0!==r)throw TypeError("Bad Promise constructor");t=e,r=n})),this.resolve=n(t),this.reject=n(r)};e.exports.f=function(e){return new o(e)}},14649:(e,t,r)=>{var n=r(85803);e.exports=function(e,t){return void 0===e?arguments.length<2?"":t:n(e)}},70344:(e,t,r)=>{var n=r(21899),o=r(60685),a=n.TypeError;e.exports=function(e){if(o(e))throw a("The method doesn't accept regular expressions");return e}},24420:(e,t,r)=>{"use strict";var n=r(55746),o=r(95329),a=r(78834),i=r(95981),s=r(14771),l=r(87857),u=r(36760),c=r(89678),p=r(37026),f=Object.assign,h=Object.defineProperty,d=o([].concat);e.exports=!f||i((function(){if(n&&1!==f({b:1},f(h({},"a",{enumerable:!0,get:function(){h(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},r=Symbol(),o="abcdefghijklmnopqrst";return e[r]=7,o.split("").forEach((function(e){t[e]=e})),7!=f({},e)[r]||s(f({},t)).join("")!=o}))?function(e,t){for(var r=c(e),o=arguments.length,i=1,f=l.f,h=u.f;o>i;)for(var m,g=p(arguments[i++]),v=f?d(s(g),f(g)):s(g),y=v.length,b=0;y>b;)m=v[b++],n&&!a(h,g,m)||(r[m]=g[m]);return r}:f},29290:(e,t,r)=>{var n,o=r(96059),a=r(59938),i=r(56759),s=r(27748),l=r(15463),u=r(61333),c=r(44262),p=c("IE_PROTO"),f=function(){},h=function(e){return"") + 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/ +- Chat: https://discord.gg/pallets diff --git a/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/RECORD new file mode 100644 index 0000000..8bf8583 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.3.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.3.dist-info/METADATA,sha256=Wvvh4Tz-YtW24YagYdqrrrBdm9m-DjTdqJWhxlbU6-0,3003 +MarkupSafe-2.1.3.dist-info/RECORD,, +MarkupSafe-2.1.3.dist-info/WHEEL,sha256=gREe7-l-MJWbGZG46A7WHnwwUSxA3XJYHQvGGLzmBNU,148 +MarkupSafe-2.1.3.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xIItqrn1Bwi7FxPJO9rCVQBG0Evewue1Tl4BV0l9xEs,10338 +markupsafe/__pycache__/__init__.cpython-39.pyc,, +markupsafe/__pycache__/_native.cpython-39.pyc,, +markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 +markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 +markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so,sha256=3wRXXXyXLhwOEl2dgZ0BOIOvNcp0sPJ5_LpKz7X20HI,44024 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL new file mode 100644 index 0000000..0ceab8b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: false +Tag: cp39-cp39-manylinux_2_17_x86_64 +Tag: cp39-cp39-manylinux2014_x86_64 + diff --git a/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/testclient/.venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..129399360956af58dababe96c46df27119aa05b1 GIT binary patch literal 334 zcmYk0u}Z{15QcY?s6o6Z5HwtuBH6-95V5havCuBfvbQ^!aJxGpyE%x3jZfpV_y(y2 zD__CNiCWyi{KF4F-#==#I%YKQA8UA_`?;9?NyyyLhBb*{4FhiYHW|)LVp5y9v`IOG z^p$aDvPV`PJfA*{zKAUpw<=6`K15}0q0u?z&74c=ROhAqA{;CEoGtdg%;qC04QeTu zh*u7zY|aD3v5$y0)c=4Q2r9cj>W~uSjSYu%e&riPiw?wq5TM!xjb +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Homepage, https://blinker.readthedocs.io +Project-URL: Issue Tracker, https://github.com/pallets-eco/blinker/issues/ +Project-URL: Source Code, https://github.com/pallets-eco/blinker/ + +Blinker +======= + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +.. code-block:: pycon + + >>> from blinker import signal + >>> started = signal('round-started') + >>> def each(round): + ... print(f"Round {round}") + ... + >>> started.connect(each) + + >>> def round_two(round): + ... print("This is round two.") + ... + >>> started.connect(round_two, sender=2) + + >>> for round in range(1, 4): + ... started.send(round) + ... + Round 1! + Round 2! + This is round two. + Round 3! + + +Links +----- + +- Documentation: https://blinker.readthedocs.io/ +- Changes: https://blinker.readthedocs.io/#changes +- PyPI Releases: https://pypi.org/project/blinker/ +- Source Code: https://github.com/pallets-eco/blinker/ +- Issue Tracker: https://github.com/pallets-eco/blinker/issues/ + diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/RECORD new file mode 100644 index 0000000..c1fb2d9 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/RECORD @@ -0,0 +1,14 @@ +blinker-1.6.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.6.3.dist-info/LICENSE.rst,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.6.3.dist-info/METADATA,sha256=yDLuXpi6nLMwYYWJlGDIBvbZxFZH23JHbdxPGzIU4vg,1918 +blinker-1.6.3.dist-info/RECORD,, +blinker-1.6.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +blinker/__init__.py,sha256=E7dbyl7JyaK4RbWHlGrWY3mQ8d3BEnxRCeKQnqMa0bw,408 +blinker/__pycache__/__init__.cpython-39.pyc,, +blinker/__pycache__/_saferef.cpython-39.pyc,, +blinker/__pycache__/_utilities.cpython-39.pyc,, +blinker/__pycache__/base.cpython-39.pyc,, +blinker/_saferef.py,sha256=kWOTIWnCY3kOb8lZP74Rbx7bR_BLVg4TjwzNCRLhKHs,9096 +blinker/_utilities.py,sha256=GPXtJzykzVotoxHC79mgFQMPJtICwpVDCCpus4_JtsA,4110 +blinker/base.py,sha256=ZfN6L36P0BzPaQAcAF0tSNAicxiG4f7xLPug6iLsjjE,20293 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker-1.6.3.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/__init__.py b/testclient/.venv/lib/python3.9/site-packages/blinker/__init__.py new file mode 100644 index 0000000..0d7a6bc --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker/__init__.py @@ -0,0 +1,19 @@ +from blinker.base import ANY +from blinker.base import NamedSignal +from blinker.base import Namespace +from blinker.base import receiver_connected +from blinker.base import Signal +from blinker.base import signal +from blinker.base import WeakNamespace + +__all__ = [ + "ANY", + "NamedSignal", + "Namespace", + "Signal", + "WeakNamespace", + "receiver_connected", + "signal", +] + +__version__ = "1.6.3" diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5cd92a875af7c0bbf13e5628c575375486e06e1 GIT binary patch literal 519 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 Mt<+$RQsc${0edtU7XSbN literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/_utilities.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/blinker/__pycache__/_utilities.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f92cbdfe5a318355d80f10f55353b47f7b75e31f GIT binary patch literal 4211 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 ycoi3WVhZ{7Q~GPg|7ji3cx=?xm literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/_saferef.py b/testclient/.venv/lib/python3.9/site-packages/blinker/_saferef.py new file mode 100644 index 0000000..dcb70c1 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker/_saferef.py @@ -0,0 +1,230 @@ +# extracted from Louie, http://pylouie.org/ +# updated for Python 3 +# +# Copyright (c) 2006 Patrick K. O'Brien, Mike C. Fletcher, +# Matthew R. Scott +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * 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. +# +# * Neither the name of the 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 +# OWNER 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. +# +"""Refactored 'safe reference from dispatcher.py""" +import operator +import sys +import traceback +import weakref + + +get_self = operator.attrgetter("__self__") +get_func = operator.attrgetter("__func__") + + +def safe_ref(target, on_delete=None): + """Return a *safe* weak reference to a callable target. + + - ``target``: The object to be weakly referenced, if it's a bound + method reference, will create a BoundMethodWeakref, otherwise + creates a simple weakref. + + - ``on_delete``: If provided, will have a hard reference stored to + the callable to be called after the safe reference goes out of + scope with the reference object, (either a weakref or a + BoundMethodWeakref) as argument. + """ + try: + im_self = get_self(target) + except AttributeError: + if callable(on_delete): + return weakref.ref(target, on_delete) + else: + return weakref.ref(target) + else: + if im_self is not None: + # Turn a bound method into a BoundMethodWeakref instance. + # Keep track of these instances for lookup by disconnect(). + assert hasattr(target, "im_func") or hasattr(target, "__func__"), ( + f"safe_ref target {target!r} has im_self, but no im_func, " + "don't know how to create reference" + ) + reference = BoundMethodWeakref(target=target, on_delete=on_delete) + return reference + + +class BoundMethodWeakref: + """'Safe' and reusable weak references to instance methods. + + BoundMethodWeakref objects provide a mechanism for referencing a + bound method without requiring that the method object itself + (which is normally a transient object) is kept alive. Instead, + the BoundMethodWeakref object keeps weak references to both the + object and the function which together define the instance method. + + Attributes: + + - ``key``: The identity key for the reference, calculated by the + class's calculate_key method applied to the target instance method. + + - ``deletion_methods``: Sequence of callable objects taking single + argument, a reference to this object which will be called when + *either* the target object or target function is garbage + collected (i.e. when this object becomes invalid). These are + specified as the on_delete parameters of safe_ref calls. + + - ``weak_self``: Weak reference to the target object. + + - ``weak_func``: Weak reference to the target function. + + Class Attributes: + + - ``_all_instances``: Class attribute pointing to all live + BoundMethodWeakref objects indexed by the class's + calculate_key(target) method applied to the target objects. + This weak value dictionary is used to short-circuit creation so + that multiple references to the same (object, function) pair + produce the same BoundMethodWeakref instance. + """ + + _all_instances = weakref.WeakValueDictionary() # type: ignore[var-annotated] + + def __new__(cls, target, on_delete=None, *arguments, **named): + """Create new instance or return current instance. + + Basically this method of construction allows us to + short-circuit creation of references to already-referenced + instance methods. The key corresponding to the target is + calculated, and if there is already an existing reference, + that is returned, with its deletion_methods attribute updated. + Otherwise the new instance is created and registered in the + table of already-referenced methods. + """ + key = cls.calculate_key(target) + current = cls._all_instances.get(key) + if current is not None: + current.deletion_methods.append(on_delete) + return current + else: + base = super().__new__(cls) + cls._all_instances[key] = base + base.__init__(target, on_delete, *arguments, **named) + return base + + def __init__(self, target, on_delete=None): + """Return a weak-reference-like instance for a bound method. + + - ``target``: The instance-method target for the weak reference, + must have im_self and im_func attributes and be + reconstructable via the following, which is true of built-in + instance methods:: + + target.im_func.__get__( target.im_self ) + + - ``on_delete``: Optional callback which will be called when + this weak reference ceases to be valid (i.e. either the + object or the function is garbage collected). Should take a + single argument, which will be passed a pointer to this + object. + """ + + def remove(weak, self=self): + """Set self.isDead to True when method or instance is destroyed.""" + methods = self.deletion_methods[:] + del self.deletion_methods[:] + try: + del self.__class__._all_instances[self.key] + except KeyError: + pass + for function in methods: + try: + if callable(function): + function(self) + except Exception: + try: + traceback.print_exc() + except AttributeError: + e = sys.exc_info()[1] + print( + f"Exception during saferef {self} " + f"cleanup function {function}: {e}" + ) + + self.deletion_methods = [on_delete] + self.key = self.calculate_key(target) + im_self = get_self(target) + im_func = get_func(target) + self.weak_self = weakref.ref(im_self, remove) + self.weak_func = weakref.ref(im_func, remove) + self.self_name = str(im_self) + self.func_name = str(im_func.__name__) + + @classmethod + def calculate_key(cls, target): + """Calculate the reference key for this reference. + + Currently this is a two-tuple of the id()'s of the target + object and the target function respectively. + """ + return (id(get_self(target)), id(get_func(target))) + + def __str__(self): + """Give a friendly representation of the object.""" + return "{}({}.{})".format( + self.__class__.__name__, + self.self_name, + self.func_name, + ) + + __repr__ = __str__ + + def __hash__(self): + return hash((self.self_name, self.key)) + + def __nonzero__(self): + """Whether we are still a valid reference.""" + return self() is not None + + def __eq__(self, other): + """Compare with another reference.""" + if not isinstance(other, self.__class__): + return operator.eq(self.__class__, type(other)) + return operator.eq(self.key, other.key) + + def __call__(self): + """Return a strong reference to the bound method. + + If the target cannot be retrieved, then will return None, + otherwise returns a bound instance method for our object and + function. + + Note: You may call this method any number of times, as it does + not invalidate the reference. + """ + target = self.weak_self() + if target is not None: + function = self.weak_func() + if function is not None: + return function.__get__(target) + return None diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/_utilities.py b/testclient/.venv/lib/python3.9/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..068d94c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker/_utilities.py @@ -0,0 +1,142 @@ +from __future__ import annotations + +import asyncio +import inspect +import sys +import typing as t +from functools import partial +from weakref import ref + +from blinker._saferef import BoundMethodWeakref + +IdentityType = t.Union[t.Tuple[int, int], str, int] + + +class _symbol: + def __init__(self, name): + """Construct a new named symbol.""" + self.__name__ = self.name = name + + def __reduce__(self): + return symbol, (self.name,) + + def __repr__(self): + return self.name + + +_symbol.__name__ = "symbol" + + +class symbol: + """A constant symbol. + + >>> symbol('foo') is symbol('foo') + True + >>> symbol('foo') + foo + + A slight refinement of the MAGICCOOKIE=object() pattern. The primary + advantage of symbol() is its repr(). They are also singletons. + + Repeated calls of symbol('name') will all return the same instance. + + """ + + symbols = {} # type: ignore[var-annotated] + + def __new__(cls, name): + try: + return cls.symbols[name] + except KeyError: + return cls.symbols.setdefault(name, _symbol(name)) + + +def hashable_identity(obj: object) -> IdentityType: + if hasattr(obj, "__func__"): + return (id(obj.__func__), id(obj.__self__)) # type: ignore[attr-defined] + elif hasattr(obj, "im_func"): + return (id(obj.im_func), id(obj.im_self)) # type: ignore[attr-defined] + elif isinstance(obj, (int, str)): + return obj + else: + return id(obj) + + +WeakTypes = (ref, BoundMethodWeakref) + + +class annotatable_weakref(ref): + """A weakref.ref that supports custom instance attributes.""" + + receiver_id: t.Optional[IdentityType] + sender_id: t.Optional[IdentityType] + + +def reference( # type: ignore[no-untyped-def] + object, callback=None, **annotations +) -> annotatable_weakref: + """Return an annotated weak ref.""" + if callable(object): + weak = callable_reference(object, callback) + else: + weak = annotatable_weakref(object, callback) + for key, value in annotations.items(): + setattr(weak, key, value) + return weak # type: ignore[no-any-return] + + +def callable_reference(object, callback=None): + """Return an annotated weak ref, supporting bound instance methods.""" + if hasattr(object, "im_self") and object.im_self is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + elif hasattr(object, "__self__") and object.__self__ is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + return annotatable_weakref(object, callback) + + +class lazy_property: + """A @property that is only evaluated once.""" + + def __init__(self, deferred): + self._deferred = deferred + self.__doc__ = deferred.__doc__ + + def __get__(self, obj, cls): + if obj is None: + return self + value = self._deferred(obj) + setattr(obj, self._deferred.__name__, value) + return value + + +def is_coroutine_function(func: t.Any) -> bool: + # Python < 3.8 does not correctly determine partially wrapped + # coroutine functions are coroutine functions, hence the need for + # this to exist. Code taken from CPython. + if sys.version_info >= (3, 8): + return asyncio.iscoroutinefunction(func) + else: + # Note that there is something special about the AsyncMock + # such that it isn't determined as a coroutine function + # without an explicit check. + try: + from unittest.mock import AsyncMock # type: ignore[attr-defined] + + if isinstance(func, AsyncMock): + return True + except ImportError: + # Not testing, no asynctest to import + pass + + while inspect.ismethod(func): + func = func.__func__ + while isinstance(func, partial): + func = func.func + if not inspect.isfunction(func): + return False + + if func.__code__.co_flags & inspect.CO_COROUTINE: + return True + + acic = asyncio.coroutines._is_coroutine # type: ignore[attr-defined] + return getattr(func, "_is_coroutine", None) is acic diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/base.py b/testclient/.venv/lib/python3.9/site-packages/blinker/base.py new file mode 100644 index 0000000..337ebc2 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/blinker/base.py @@ -0,0 +1,548 @@ +"""Signals and events. + +A small implementation of signals, inspired by a snippet of Django signal +API client code seen in a blog post. Signals are first-class objects and +each manages its own receivers and message emission. + +The :func:`signal` function provides singleton behavior for named signals. + +""" +from __future__ import annotations + +import typing as t +from collections import defaultdict +from contextlib import contextmanager +from warnings import warn +from weakref import WeakValueDictionary + +from blinker._utilities import annotatable_weakref +from blinker._utilities import hashable_identity +from blinker._utilities import IdentityType +from blinker._utilities import is_coroutine_function +from blinker._utilities import lazy_property +from blinker._utilities import reference +from blinker._utilities import symbol +from blinker._utilities import WeakTypes + +if t.TYPE_CHECKING: + import typing_extensions as te + + T_callable = t.TypeVar("T_callable", bound=t.Callable[..., t.Any]) + + T = t.TypeVar("T") + P = te.ParamSpec("P") + + AsyncWrapperType = t.Callable[[t.Callable[P, t.Awaitable[T]]], t.Callable[P, T]] + SyncWrapperType = t.Callable[[t.Callable[P, T]], t.Callable[P, t.Awaitable[T]]] + +ANY = symbol("ANY") +ANY.__doc__ = 'Token for "any sender".' +ANY_ID = 0 + + +class Signal: + """A notification emitter.""" + + #: An :obj:`ANY` convenience synonym, allows ``Signal.ANY`` + #: without an additional import. + ANY = ANY + + @lazy_property + def receiver_connected(self) -> Signal: + """Emitted after each :meth:`connect`. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: *receiver*, *sender*, and *weak*. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver connects.") + + @lazy_property + def receiver_disconnected(self) -> Signal: + """Emitted after :meth:`disconnect`. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: *receiver* and *sender*. + + Note, this signal is emitted **only** when :meth:`disconnect` is + called explicitly. + + The disconnect signal can not be emitted by an automatic disconnect + (due to a weakly referenced receiver or sender going out of scope), + as the receiver and/or sender instances are no longer available for + use at the time this signal would be emitted. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + """ + :param doc: optional. If provided, will be assigned to the signal's + __doc__ attribute. + + """ + if doc: + self.__doc__ = doc + #: A mapping of connected receivers. + #: + #: The values of this mapping are not meaningful outside of the + #: internal :class:`Signal` implementation, however the boolean value + #: of the mapping is useful as an extremely efficient check to see if + #: any receivers are connected to the signal. + self.receivers: dict[IdentityType, t.Callable | annotatable_weakref] = {} + self.is_muted = False + self._by_receiver: dict[IdentityType, set[IdentityType]] = defaultdict(set) + self._by_sender: dict[IdentityType, set[IdentityType]] = defaultdict(set) + self._weak_senders: dict[IdentityType, annotatable_weakref] = {} + + def connect( + self, receiver: T_callable, sender: t.Any = ANY, weak: bool = True + ) -> T_callable: + """Connect *receiver* to signal events sent by *sender*. + + :param receiver: A callable. Will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to a call to :meth:`send`. + + :param sender: Any object or :obj:`ANY`, defaults to ``ANY``. + Restricts notifications delivered to *receiver* to only those + :meth:`send` emissions sent by *sender*. If ``ANY``, the receiver + will always be notified. A *receiver* may be connected to + multiple *sender* values on the same Signal through multiple calls + to :meth:`connect`. + + :param weak: If true, the Signal will hold a weakref to *receiver* + and automatically disconnect when *receiver* goes out of scope or + is garbage collected. Defaults to True. + + """ + receiver_id = hashable_identity(receiver) + receiver_ref: T_callable | annotatable_weakref + + if weak: + receiver_ref = reference(receiver, self._cleanup_receiver) + receiver_ref.receiver_id = receiver_id + else: + receiver_ref = receiver + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + + self.receivers.setdefault(receiver_id, receiver_ref) + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + del receiver_ref + + if sender is not ANY and sender_id not in self._weak_senders: + # wire together a cleanup for weakref-able senders + try: + sender_ref = reference(sender, self._cleanup_sender) + sender_ref.sender_id = sender_id + except TypeError: + pass + else: + self._weak_senders.setdefault(sender_id, sender_ref) + del sender_ref + + # broadcast this connection. if receivers raise, disconnect. + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + if receiver_connected.receivers and self is not receiver_connected: + try: + receiver_connected.send( + self, receiver_arg=receiver, sender_arg=sender, weak_arg=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + return receiver + + def connect_via( + self, sender: t.Any, weak: bool = False + ) -> t.Callable[[T_callable], T_callable]: + """Connect the decorated function as a receiver for *sender*. + + :param sender: Any object or :obj:`ANY`. The decorated function + will only receive :meth:`send` emissions sent by *sender*. If + ``ANY``, the receiver will always be notified. A function may be + decorated multiple times with differing *sender* values. + + :param weak: If true, the Signal will hold a weakref to the + decorated function and automatically disconnect when *receiver* + goes out of scope or is garbage collected. Unlike + :meth:`connect`, this defaults to False. + + The decorated function will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to the call to :meth:`send`. + + + .. versionadded:: 1.1 + + """ + + def decorator(fn: T_callable) -> T_callable: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.Generator[None, None, None]: + """Execute a block with the signal temporarily connected to *receiver*. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + This is a context manager for use in the ``with`` statement. It can + be useful in unit tests. *receiver* is connected to the signal for + the duration of the ``with`` block, and will be disconnected + automatically when exiting the block: + + .. code-block:: python + + with on_ready.connected_to(receiver): + # do stuff + on_ready.send(123) + + .. versionadded:: 1.1 + + """ + self.connect(receiver, sender=sender, weak=False) + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> t.Generator[None, None, None]: + """Context manager for temporarily disabling signal. + Useful for test purposes. + """ + self.is_muted = True + try: + yield None + except Exception as e: + raise e + finally: + self.is_muted = False + + def temporarily_connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.ContextManager[None]: + """An alias for :meth:`connected_to`. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + .. versionadded:: 0.9 + + .. versionchanged:: 1.1 + Renamed to :meth:`connected_to`. ``temporarily_connected_to`` was + deprecated in 1.2 and will be removed in a subsequent version. + + """ + warn( + "temporarily_connected_to is deprecated; use connected_to instead.", + DeprecationWarning, + ) + return self.connected_to(receiver, sender) + + def send( + self, + *sender: t.Any, + _async_wrapper: AsyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _async_wrapper: A callable that should wrap a coroutine + receiver and run it when called synchronously. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if is_coroutine_function(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function") + receiver = _async_wrapper(receiver) + result = receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + async def send_async( + self, + *sender: t.Any, + _sync_wrapper: SyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _sync_wrapper: A callable that should wrap a synchronous + receiver and run it when awaited. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if not is_coroutine_function(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function") + receiver = _sync_wrapper(receiver) + result = await receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + def _extract_sender(self, sender: t.Any) -> t.Any: + if not self.receivers: + # Ensure correct signature even on no-op sends, disable with -O + # for lowest possible cost. + if __debug__ and sender and len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + return [] + + # Using '*sender' rather than 'sender=None' allows 'sender' to be + # used as a keyword argument- i.e. it's an invisible name in the + # function signature. + if len(sender) == 0: + sender = None + elif len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + else: + sender = sender[0] + return sender + + def has_receivers_for(self, sender: t.Any) -> bool: + """True if there is probably a receiver for *sender*. + + Performs an optimistic check only. Does not guarantee that all + weakly referenced receivers are still alive. See + :meth:`receivers_for` for a stronger search. + + """ + if not self.receivers: + return False + if self._by_sender[ANY_ID]: + return True + if sender is ANY: + return False + return hashable_identity(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> t.Generator[t.Callable[[t.Any], t.Any], None, None]: + """Iterate all live receivers listening for *sender*.""" + # TODO: test receivers_for(ANY) + if self.receivers: + sender_id = hashable_identity(sender) + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + if receiver is None: + continue + if isinstance(receiver, WeakTypes): + strong = receiver() + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + receiver = strong + yield receiver # type: ignore[misc] + + def disconnect(self, receiver: t.Callable, sender: t.Any = ANY) -> None: + """Disconnect *receiver* from this signal's events. + + :param receiver: a previously :meth:`connected` callable + + :param sender: a specific sender to disconnect from, or :obj:`ANY` + to disconnect from all senders. Defaults to ``ANY``. + + """ + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + receiver_id = hashable_identity(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: IdentityType, sender_id: IdentityType) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, False): + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_receiver(self, receiver_ref: annotatable_weakref) -> None: + """Disconnect a receiver from all senders.""" + self._disconnect(t.cast(IdentityType, receiver_ref.receiver_id), ANY_ID) + + def _cleanup_sender(self, sender_ref: annotatable_weakref) -> None: + """Disconnect all receivers from a sender.""" + sender_id = t.cast(IdentityType, sender_ref.sender_id) + assert sender_id != ANY_ID + self._weak_senders.pop(sender_id, None) + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leave behind a small amount of bookkeeping + for the receiver and sender values. Typical workloads using Blinker, + for example in most web apps, Flask, CLI scripts, etc., are not + adversely affected by this bookkeeping. + + With a long-running Python process performing dynamic signal routing + with high volume- e.g. connecting to function closures, "senders" are + all unique object instances, and doing all of this over and over- you + may see memory usage will grow due to extraneous bookkeeping. (An empty + set() for each stale sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that + failure mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for _id, bucket in list(mapping.items()): + if not bucket: + mapping.pop(_id, None) + + def _clear_state(self) -> None: + """Throw away all signal state. Useful for unit tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +receiver_connected = Signal( + """\ +Sent by a :class:`Signal` after a receiver connects. + +:argument: the Signal that was connected to +:keyword receiver_arg: the connected receiver +:keyword sender_arg: the sender to connect to +:keyword weak_arg: true if the connection to receiver_arg is a weak reference + +.. deprecated:: 1.2 + +As of 1.2, individual signals have their own private +:attr:`~Signal.receiver_connected` and +:attr:`~Signal.receiver_disconnected` signals with a slightly simplified +call signature. This global signal is planned to be removed in 1.6. + +""" +) + + +class NamedSignal(Signal): + """A named generic notification emitter.""" + + def __init__(self, name: str, doc: str | None = None) -> None: + Signal.__init__(self, doc) + + #: The name of this signal. + self.name = name + + def __repr__(self) -> str: + base = Signal.__repr__(self) + return f"{base[:-1]}; {self.name!r}>" + + +class Namespace(dict): + """A mapping of signal names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +class WeakNamespace(WeakValueDictionary): + """A weak mapping of signal names to signals. + + Automatically cleans up unused Signals when the last reference goes out + of scope. This namespace implementation exists for a measure of legacy + compatibility with Blinker <= 1.2, and may be dropped in the future. + + .. versionadded:: 1.3 + + """ + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +signal = Namespace().signal diff --git a/testclient/.venv/lib/python3.9/site-packages/blinker/py.typed b/testclient/.venv/lib/python3.9/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/LICENSE b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/LICENSE new file mode 100644 index 0000000..0a64774 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/LICENSE @@ -0,0 +1,21 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/METADATA new file mode 100644 index 0000000..07f4991 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/METADATA @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: certifi +Version: 2023.7.22 +Summary: Python package for providing Mozilla's CA Bundle. +Home-page: https://github.com/certifi/python-certifi +Author: Kenneth Reitz +Author-email: me@kennethreitz.com +License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +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 +Requires-Python: >=3.6 +License-File: LICENSE + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> 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! + +.. _`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/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/RECORD new file mode 100644 index 0000000..faf1a9a --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2023.7.22.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2023.7.22.dist-info/LICENSE,sha256=oC9sY4-fuE0G93ZMOrCF2K9-2luTwWbaVDEkeQd8b7A,1052 +certifi-2023.7.22.dist-info/METADATA,sha256=oyc8gd32SOVo0IGolt8-bR7FnZ9Z99GoHoGE6ACcvFA,2191 +certifi-2023.7.22.dist-info/RECORD,, +certifi-2023.7.22.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +certifi-2023.7.22.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=L_j-d0kYuA_MzA2_2hraF1ovf6KT6DTquRdV3paQwOk,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-39.pyc,, +certifi/__pycache__/__main__.cpython-39.pyc,, +certifi/__pycache__/core.cpython-39.pyc,, +certifi/cacert.pem,sha256=eU0Dn_3yd8BH4m8sfVj4Glhl2KDrcCSg-sEWT-pNJ88,281617 +certifi/core.py,sha256=lhewz0zFb2b4ULsQurElmloYwQoecjWzPqY67P8T7iM,4219 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/WHEEL new file mode 100644 index 0000000..5bad85f --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/top_level.txt new file mode 100644 index 0000000..963eac5 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi-2023.7.22.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/__init__.py b/testclient/.venv/lib/python3.9/site-packages/certifi/__init__.py new file mode 100644 index 0000000..8ce89ce --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2023.07.22" diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/__main__.py b/testclient/.venv/lib/python3.9/site-packages/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi/__main__.py @@ -0,0 +1,12 @@ +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/testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d74127e46640ce55122be82d2a46fd4a5991c00 GIT binary patch literal 309 zcmYjMK~BRk5R9FKMn#o)0^*iK;wn8LB!v0`F5GfpmD=0J!m%UU1eG80CEpMyzQ76l z){%BrqaDre4x7z7i`akP;cM(aNnCIr zd}Vf(0uud6Hkt{UHR!Ne95*6~gYivTYK>~9K@TUi%%k&M$#@5A7t{+=^1$Y^AC2C% q56nrA%{=h8Xm*UF_3|hgfYj0hwDUPskCPGa3ZK$ju84F)EAkH;X;J?G literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__main__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/certifi/__pycache__/__main__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f394403f69a7f6d41e539d69b440ce36d8179e8 GIT binary patch literal 445 zcmYjLu};G<5Vf5q4N;5u2DT2V2PPzh%F2L{SWuV9jgQtPv7@tF)UM3@1C0EVH^juu z#)KUZ;v~Pj_wM}e#CTkg5VN;q_zd|ylK+tgG7Hb%29QM3hRkDT4Q<(+waGl81jzH? zh0Ie(*O^S@K&CQ#ihBAy40;avn&BlJ0DB~lloDNpI{B$3y&;p~M{p-s6Xx^UXb0L^ zpFXSrVb98XUzFvaTv%riDu)}GP@jp~DWfNa&jl_!ffoF*26XC9Aq$?E1n`F!xZJeC z_Bu|W&-zL9BOzrKKK4Cd^lIeR4|+^HRNB1~Jd9Qmz7$`X7C0KPP;PB)WF!mY`V-MK zWh=B;0&)k|)r|^U`E(0<%Nw=e-OjCyKAE0!s~nV_sPDtD<-a%cs%nMORWv5bkc- z31rD~$sSqp2lkLThM&|o#3_FvaGyo7pVz<&^55HY&7M=NUCc_CVWxixH$7NbQ< z#G+U@SQ37pt&?aOET1n}eTCl@%VI_N`0%Bd9$)4w&%LNQjc)aov+k5yA%?U#>?G>K~LSW z7mWjAs)>sG*-#h{r3$I3ln14_`sQ%K*o0So z0765-j);6;Q_VO%qvsB16POcMd)hs(ObF<(YL{F%+on2A?<$zb7gkLp-h8zA<>S40 z=h5C*68%dLgz*oGEFUL&VCu6Kn|t3GM`>wlaSYiA8OIkyF5ngvSE4s4MxrMRp~S|q zN(+w0lR|G`{<0WujFLRr7qX{?(&;b*C%x{m$d7x&>`8BYq6bC(p!;c0Wm;^Elk^Z4 ztKKy3URp>2wK3k010lsCoTz*d#P{n&s3+SH@+0AIFdksRq$deLdrraSpg$Orp^Y& zh!wPPeg=vrnx2tU=!zHYx3y>Pse8^QE=(AFHPXX=;-cAq{k`u6Dg_7%_nkvs^o{WU?V|#bRv2n3w0c6_$cR1J@ zeR#`o{!f|Zo3Q^UegoC|Gd2DzrgA!q>@|loq)BOOI_AlYtQxdw(Ci_@% literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/cacert.pem b/testclient/.venv/lib/python3.9/site-packages/certifi/cacert.pem new file mode 100644 index 0000000..0212369 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi/cacert.pem @@ -0,0 +1,4635 @@ + +# 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=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=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=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: 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=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=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=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 - 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=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=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=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----- +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 +-----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----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +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+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----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: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----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: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----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: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----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: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----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: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication RootCA3" +# Serial: 16247922307909811815 +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad +TdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/core.py b/testclient/.venv/lib/python3.9/site-packages/certifi/core.py new file mode 100644 index 0000000..de02898 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/certifi/core.py @@ -0,0 +1,108 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # 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 = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +elif sys.version_info >= (3, 7): + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # 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 + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") + +else: + import os + import types + from typing import Union + + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # 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( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), 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() -> str: + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/testclient/.venv/lib/python3.9/site-packages/certifi/py.typed b/testclient/.venv/lib/python3.9/site-packages/certifi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE new file mode 100644 index 0000000..ad82355 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +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/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/METADATA new file mode 100644 index 0000000..ad5158c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/METADATA @@ -0,0 +1,668 @@ +Metadata-Version: 2.1 +Name: charset-normalizer +Version: 3.3.0 +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 +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,charset,charset-detector,detector,normalization,unicode,chardet,detect +Classifier: Development Status :: 5 - Production/Stable +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.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Text Processing :: Linguistic +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.7.0 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: unicode_backport + +

Charset Detection, for Everyone 👋

+ +

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

+

+ Featured Packages
+ + Static Badge + + + Static Badge + +

+

+ In other language (unofficial port - by the community)
+ + Static Badge + +

+ +> 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 | ✅ | ✅ | ✅ | +| `License` | LGPL-2.1
_restrictive_ | MIT | MPL-1.1
_restrictive_ | +| `Native Python` | ✅ | ✅ | ❌ | +| `Detect spoken language` | ❌ | ✅ | N/A | +| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ | +| `Whl Size (min)` | 193.6 kB | 42 kB | ~200 kB | +| `Supported Encoding` | 33 | 🎉 [99](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) + +## ⚡ 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) | 86 % | 200 ms | 5 file/sec | +| charset-normalizer | **98 %** | **10 ms** | 100 file/sec | + +| Package | 99th percentile | 95th percentile | 50th percentile | +|-----------------------------------------------|:---------------:|:---------------:|:---------------:| +| [chardet](https://github.com/chardet/chardet) | 1200 ms | 287 ms | 23 ms | +| charset-normalizer | 100 ms | 50 ms | 5 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. +> Keep in mind that the stats are generous and that Chardet accuracy vs our is measured using Chardet initial capability +> (eg. Supported Encoding) Challenge-them if you want. + +## ✨ Installation + +Using pip: + +```sh +pip install charset-normalizer -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 +``` + +or + +```bash +python -m charset_normalizer ./data/sample.1.fr.srt +``` + +🎉 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())) +``` + +*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 noise, 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 noise/mess and coherence according to **YOU ?** + +*Noise :* 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 noise is probably incomplete, 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. + +## ⚠️ About Python EOLs + +**If you are running:** + +- Python >=2.7,<3.5: Unsupported +- Python 3.5: charset-normalizer < 2.1 +- Python 3.6: charset-normalizer < 3.1 +- Python 3.7: charset-normalizer < 4.0 + +Upgrade your Python interpreter as soon as possible. + +## 👤 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 © [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/) + +## 💼 For Enterprise + +Professional support for charset-normalizer is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme + +# Changelog +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.3.0](https://github.com/Ousret/charset_normalizer/compare/3.2.0...3.3.0) (2023-09-30) + +### Added +- Allow to execute the CLI (e.g. normalizer) through `python -m charset_normalizer.cli` or `python -m charset_normalizer` +- Support for 9 forgotten encoding that are supported by Python but unlisted in `encoding.aliases` as they have no alias (#323) + +### Removed +- (internal) Redundant utils.is_ascii function and unused function is_private_use_only +- (internal) charset_normalizer.assets is moved inside charset_normalizer.constant + +### Changed +- (internal) Unicode code blocks in constants are updated using the latest v15.0.0 definition to improve detection +- Optional mypyc compilation upgraded to version 1.5.1 for Python >= 3.7 + +### Fixed +- Unable to properly sort CharsetMatch when both chaos/noise and coherence were close due to an unreachable condition in \_\_lt\_\_ (#350) + +## [3.2.0](https://github.com/Ousret/charset_normalizer/compare/3.1.0...3.2.0) (2023-06-07) + +### Changed +- Typehint for function `from_path` no longer enforce `PathLike` as its first argument +- Minor improvement over the global detection reliability + +### Added +- Introduce function `is_binary` that relies on main capabilities, and optimized to detect binaries +- Propagate `enable_fallback` argument throughout `from_bytes`, `from_path`, and `from_fp` that allow a deeper control over the detection (default True) +- Explicit support for Python 3.12 + +### Fixed +- Edge case detection failure where a file would contain 'very-long' camel cased word (Issue #289) + +## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) + +### Added +- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) + +### Removed +- Support for Python 3.6 (PR #260) + +### Changed +- Optional speedup provided by mypy/c 1.0.1 + +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) + +### Fixed +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) + +### Changed +- Speedup provided by mypy/c 0.990 on Python >= 3.7 + +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it +- Sphinx warnings when generating the documentation + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' + +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) + +### Added +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Removed +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) + +### Fixed +- Sphinx warnings when generating the documentation + +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) + +### Changed +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Removed +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) + +### Deprecated +- Function `normalize` scheduled for removal in 3.0 + +### Changed +- Removed useless call to decode in fn is_unprintable (#206) + +### Fixed +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) + +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) + +### Added +- Output the Unicode table version when running the CLI with `--version` (PR #194) + +### Changed +- Re-use decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) + +### Fixed +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) + +### Removed +- Support for Python 3.5 (PR #192) + +### Deprecated +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) + +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) + +### Fixed +- ASCII miss-detection on rare cases (PR #170) + +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) + +### Added +- Explicit support for Python 3.11 (PR #164) + +### Changed +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) + +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) + +### Fixed +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) + +### Changed +- Skipping the language-detection (CD) on ASCII (PR #155) + +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) + +### Changed +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) + +### Fixed +- Wrong logging level applied when setting kwarg `explain` to True (PR #146) + +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) +### Changed +- Improvement over Vietnamese detection (PR #126) +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) +- Code style as refactored by Sourcery-AI (PR #131) +- Minor adjustment on the MD around european words (PR #133) +- Remove and replace SRTs from assets / tests (PR #139) +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) + +### Fixed +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) +- Avoid using too insignificant chunk (PR #137) + +### Added +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) + +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) +### Added +- Add support for Kazakh (Cyrillic) language detection (PR #109) + +### Changed +- Further, improve inferring the language from a given single-byte code page (PR #112) +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) +- Various detection improvement (MD+CD) (PR #117) + +### Removed +- Remove redundant logging entry about detected language(s) (PR #115) + +### Fixed +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) + +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) +### Fixed +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) +- Fix CLI crash when using --minimal output in certain cases (PR #103) + +### Changed +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) + +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) +### Changed +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) +- The Unicode detection is slightly improved (PR #93) +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) + +### Removed +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) + +### Fixed +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) +- The MANIFEST.in was not exhaustive (PR #78) + +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) +### Fixed +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) +- Submatch factoring could be wrong in rare edge cases (PR #72) +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) +- Fix line endings from CRLF to LF for certain project files (PR #67) + +### Changed +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) +- Allow fallback on specified encoding if any (PR #71) + +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) +### Changed +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) + +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) +### Fixed +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) + +### Changed +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) + +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) +### Fixed +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) +- Using explain=False permanently disable the verbose output in the current runtime (PR #47) +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) + +### Changed +- Public function normalize default args values were not aligned with from_bytes (PR #53) + +### Added +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) + +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) +### Changed +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. +- Accent has been made on UTF-8 detection, should perform rather instantaneous. +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ +- utf_7 detection has been reinstated. + +### Removed +- This package no longer require anything when used with Python 3.5 (Dropped cached_property) +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. +- The exception hook on UnicodeDecodeError has been removed. + +### Deprecated +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 + +### Fixed +- The CLI output used the relative path of the file(s). Should be absolute. + +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) +### Fixed +- Logger configuration/usage no longer conflict with others (PR #44) + +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) +### Removed +- Using standard logging instead of using the package loguru. +- Dropping nose test framework in favor of the maintained pytest. +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. +- Stop support for UTF-7 that does not contain a SIG. +- Dropping PrettyTable, replaced with pure JSON output in CLI. + +### Fixed +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. +- Not searching properly for the BOM when trying utf32/16 parent codec. + +### Changed +- Improving the package final size by compressing frequencies.json. +- Huge improvement over the larges payload. + +### Added +- CLI now produces JSON consumable output. +- Return ASCII if given sequences fit. Given reasonable confidence. + +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) + +### Fixed +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) + +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) + +### Fixed +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) + +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) + +### Fixed +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) + +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) + +### Changed +- Amend the previous release to allow prettytable 2.0 (PR #35) + +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) + +### Fixed +- Fix error while using the package with a python pre-release interpreter (PR #33) + +### Changed +- Dependencies refactoring, constraints revised. + +### Added +- Add python 3.9 and 3.10 to the supported interpreters + +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. diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/RECORD new file mode 100644 index 0000000..17b1ba3 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/RECORD @@ -0,0 +1,35 @@ +../../../bin/normalizer,sha256=r_BxSdf6HbZLT2UVL_Sy6ExhND5LyvZb5WVwXXLCXIE,286 +charset_normalizer-3.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +charset_normalizer-3.3.0.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 +charset_normalizer-3.3.0.dist-info/METADATA,sha256=dIp-XpvvXQKv1zMQcdlRqMsROXvtJ8Yw55TIaXGegNg,32868 +charset_normalizer-3.3.0.dist-info/RECORD,, +charset_normalizer-3.3.0.dist-info/WHEEL,sha256=_BMdtp3IQ4NF7VFMKD4lD9Cik0H3WhEP1vtG22VwXhU,148 +charset_normalizer-3.3.0.dist-info/entry_points.txt,sha256=ADSTKrkXZ3hhdOVFi6DcUEHQRS0xfxDIE_pEz4wLIXA,65 +charset_normalizer-3.3.0.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 +charset_normalizer/__init__.py,sha256=UzI3xC8PhmcLRMzSgPb6minTmRq0kWznnCBJ8ZCc2XI,1577 +charset_normalizer/__main__.py,sha256=JxY8bleaENOFlLRb9HfoeZCzAMnn2A1oGR5Xm2eyqg0,73 +charset_normalizer/__pycache__/__init__.cpython-39.pyc,, +charset_normalizer/__pycache__/__main__.cpython-39.pyc,, +charset_normalizer/__pycache__/api.cpython-39.pyc,, +charset_normalizer/__pycache__/cd.cpython-39.pyc,, +charset_normalizer/__pycache__/constant.cpython-39.pyc,, +charset_normalizer/__pycache__/legacy.cpython-39.pyc,, +charset_normalizer/__pycache__/md.cpython-39.pyc,, +charset_normalizer/__pycache__/models.cpython-39.pyc,, +charset_normalizer/__pycache__/utils.cpython-39.pyc,, +charset_normalizer/__pycache__/version.cpython-39.pyc,, +charset_normalizer/api.py,sha256=WOlWjy6wT8SeMYFpaGbXZFN1TMXa-s8vZYfkL4G29iQ,21097 +charset_normalizer/cd.py,sha256=xwZliZcTQFA3jU0c00PRiu9MNxXTFxQkFLWmMW24ZzI,12560 +charset_normalizer/cli/__init__.py,sha256=D5ERp8P62llm2FuoMzydZ7d9rs8cvvLXqE-1_6oViPc,100 +charset_normalizer/cli/__main__.py,sha256=2F-xURZJzo063Ye-2RLJ2wcmURpbKeAzKwpiws65dAs,9744 +charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc,, +charset_normalizer/cli/__pycache__/__main__.cpython-39.pyc,, +charset_normalizer/constant.py,sha256=p0IsOVcEbPWYPOdWhnhRbjK1YVBy6fs05C5vKC-zoxU,40481 +charset_normalizer/legacy.py,sha256=T-QuVMsMeDiQEk8WSszMrzVJg_14AMeSkmHdRYhdl1k,2071 +charset_normalizer/md.cpython-39-x86_64-linux-gnu.so,sha256=Y7QSLD5QLoSFAWys0-tL7R6QB7oi5864zM6zr7RWek4,16064 +charset_normalizer/md.py,sha256=N7pMe_84czujAOG_3U5Zv42JkpIO40DHCzD0bf47Caw,18668 +charset_normalizer/md__mypyc.cpython-39-x86_64-linux-gnu.so,sha256=4c9PCRMEGasvZ-n-BIL_AD7dyYtYdbAg4CrpixfCyS8,257368 +charset_normalizer/models.py,sha256=tA2tf9rfRyFW9sfoMXWSjoW0-y6EdfdMogHuQBfbOHM,11487 +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/utils.py,sha256=welXEWvrzpBaZY0yfzPeaqsZVAZQ7mDcfMu4noiCTTU,11231 +charset_normalizer/version.py,sha256=cadHi_iqsnEErna9xaToqabie92T0nTPMTCUQ3u7yLw,79 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL new file mode 100644 index 0000000..ca2752b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp39-cp39-manylinux_2_17_x86_64 +Tag: cp39-cp39-manylinux2014_x86_64 + diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt new file mode 100644 index 0000000..65619e7 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +normalizer = charset_normalizer.cli:cli_detect diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt new file mode 100644 index 0000000..66958f0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt @@ -0,0 +1 @@ +charset_normalizer diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__init__.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__init__.py new file mode 100644 index 0000000..55991fc --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__init__.py @@ -0,0 +1,46 @@ +# -*- 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, is_binary +from .legacy import detect +from .models import CharsetMatch, CharsetMatches +from .utils import set_logging_handler +from .version import VERSION, __version__ + +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "is_binary", + "detect", + "CharsetMatch", + "CharsetMatches", + "__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/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__main__.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__main__.py new file mode 100644 index 0000000..beae2ef --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__main__.py @@ -0,0 +1,4 @@ +from .cli import cli_detect + +if __name__ == "__main__": + cli_detect() diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa09e87b4418987e36e1d7f20d8cde8e665b5815 GIT binary patch literal 1605 zcmcIkPjB2r6t_2<{o_sA&=#r3flIPd*M@R|Rf(FGphjvoCVv1aX;^(ZqQYi7LZ zazM}vU!ys43rH0ag76ibt8a)?zXB)Tc(+MWd&QEU=Dm6I-tYaTtE--a-^0H?gnr9$ z{fPH7^vAw1wgA+pYTuB?{typQXyR5^Bz&n zVp3?tIP?f1o12^SfEQ6l*;SSa6ZTns9gSxO^y>#0Pr;2QpTBXpvHs}thw^3lTX{|{ ze=IM`Uo1n)^YZudjFf*~eqWxU?1GekSpK5?xt9D|Yo4L-ynN}Cy?2Q(pO+UOtowET zVPm~8N71M2{r+n-W6&m=6re4j1vK9ZH?CB)Q5)B4wfO&r>v?-vZl#F;tWtuN$dY;9 z=S87Y$~YZ!AOkG$yf=;tEPf*6LO^DyVKVcuM<1ld3hRi<}<}6sTq=uxKHkXbpK=9a9gRsjy>FZvcKaEIg26FFeJM>hxcj#Pj?<~j}Er$ z9uu~uu&EKE_PtlQ1f0<;7iqs)d3HYL{ZO^*^HE-P>qAaWT6LL@#w^1T>$_D8jo{?< z8`a8U7I&$M)9S{X9B9X z)UqYGA{>QF%u#JiI+k=TS+S&NiCuQ#t+$iaf4^!+5hgr}s`kQnwM26^H+t>Eny*?M zCN!SaZmO2R`QrN8UA0^o%vSBIYA>M9-CH2m5#<~mbthn+Vw|8Vk0!~Jd8k!ygvDPl zKRN2I#cjzyCP<}#KuORrm})!M$c&{K#4Vmvp z5}){=1)3QcEcTOrN9zPp#4={0$j@h0=K%&-aM)}h2EB%)d8gC3>#n$K_HQ)T{sr&L BI;8*r literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__main__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/__main__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e9167e1d02bd1017648cbb193ea6e9611972b7f GIT binary patch literal 283 zcmYjLJxc^J5KXd&EQj|8uCTD%VmF1AAadgH@h@#BR{jMm zCxYO>yy4Bfc|5(@tQpnr;}-TbKP&lPg2;}#+z?o1xo3gDaLzzjaTIwA{EcyDn`hRo zzBq|GzO0RR$^wGHrBy0u7nOSInx&ybu9kHjbpWN_S-zshFMOjMQvjJ06zJz-lC9*B zus11UPQDL1>Q~4Tp&*$-L^;e5XX)KRPG=lbyc_OiaR~jS&5^`Kno;KhsA9@Ndv~G# Xzf{9?UfPF{?8(DpjbBy-*P`V=H9Jmr literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/api.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/api.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4dda55f18fc1438474359cb141806bee1cdb3f35 GIT binary patch literal 11446 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 R*91QUd-z4LT^-&F`+w^ChKm3I literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/cd.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/cd.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bcc6c175938303cf591efd3dc3db2853d18cac3 GIT binary patch literal 9678 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 W!{}uYH&D}Wq9*pvd=#OTfBpr>79|S+ literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/md.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/md.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..261839bbbc98e3cc3ebe9381d98a9eb23d83ac97 GIT binary patch literal 15432 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/models.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..504fd64e529235f1fefc6bfcfb02df136e705b04 GIT binary patch literal 11457 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 NJ>&M=O4Tgc{|Cg$X{7)F literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/utils.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dce98db0795987c9e577afca6876c1f896f7ba5e GIT binary patch literal 8712 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 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 blocks 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: int = logger.level + logger.addHandler(explain_handler) + logger.setLevel(TRACE) + + length: int = len(sequences) + + 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: bool = len(sequences) < TOO_SMALL_SEQUENCE + is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE + + 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: List[str] = [] + + specified_encoding: Optional[str] = ( + any_specified_encoding(sequences) if preemptive_behaviour else None + ) + + 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[str] = set() + tested_but_hard_failure: List[str] = [] + tested_but_soft_failure: List[str] = [] + + fallback_ascii: Optional[CharsetMatch] = None + fallback_u8: Optional[CharsetMatch] = None + fallback_specified: Optional[CharsetMatch] = None + + results: CharsetMatches = 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: Optional[str] = None + bom_or_sig_available: bool = sig_encoding == encoding_iana + strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) + + if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) + continue + if encoding_iana in {"utf_7"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", + encoding_iana, + ) + continue + + try: + is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) + 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: bool = False + + 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: bool = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) + + 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 = int(len(r_) / 4) + + max_chunk_gave_up = max(max_chunk_gave_up, 2) + early_stop_count: int = 0 + lazy_str_hard_failure = False + + md_chunks: List[str] = [] + md_ratios = [] + + try: + for chunk in cut_sequence_chunks( + sequences, + encoding_iana, + r_, + chunk_size, + bom_or_sig_available, + strip_sig_or_bom, + sig_payload, + is_multi_byte_decoder, + decoded_payload, + ): + md_chunks.append(chunk) + + md_ratios.append( + mess_ratio( + chunk, + threshold, + explain is True and 1 <= len(cp_isolation) <= 2, + ) + ) + + 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 + 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 + + # 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: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 + 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 ( + enable_fallback + and 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: List[str] = encoding_languages(encoding_iana) + 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, + language_threshold, + ",".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: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> 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, + language_threshold, + enable_fallback, + ) + + +def from_path( + path: Union[str, bytes, PathLike], # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> 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, + language_threshold, + enable_fallback, + ) + + +def is_binary( + fp_or_path_or_payload: Union[PathLike, str, BinaryIO, bytes], # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = False, +) -> bool: + """ + Detect if the given input (file, bytes, or path) points to a binary file. aka. not a string. + Based on the same main heuristic algorithms and default kwargs at the sole exception that fallbacks match + are disabled to be stricter around ASCII-compatible but unlikely to be a string. + """ + if isinstance(fp_or_path_or_payload, (str, PathLike)): + guesses = from_path( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + elif isinstance( + fp_or_path_or_payload, + ( + bytes, + bytearray, + ), + ): + guesses = from_bytes( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + else: + guesses = from_fp( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + + return not guesses diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cd.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cd.py new file mode 100644 index 0000000..4ea6760 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cd.py @@ -0,0 +1,395 @@ +import importlib +from codecs import IncrementalDecoder +from collections import Counter +from functools import lru_cache +from typing import Counter as TypeCounter, Dict, List, Optional, Tuple + +from .constant import ( + FREQUENCIES, + 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 + + p: IncrementalDecoder = decoder(errors="ignore") + seen_ranges: Dict[str, int] = {} + character_count: int = 0 + + for i in range(0x40, 0xFF): + chunk: str = p.decode(bytes([i])) + + if chunk: + character_range: Optional[str] = unicode_range(chunk) + + 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: 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: List[str] = encoding_unicode_range(iana_name) + primary_range: Optional[str] = None + + 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"] + 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: bool = False + target_pure_latin: bool = True + + 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: 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: int = len(language_characters) + + character_match_count: int = len( + [c for c in language_characters if c in characters] + ) + + ratio: float = character_match_count / character_count + + 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: int = 0 + FREQUENCIES_language_set = set(FREQUENCIES[language]) + + ordered_characters_count: int = len(ordered_characters) + target_language_characters_count: int = len(FREQUENCIES[language]) + + large_alphabet: bool = target_language_characters_count > 26 + + for character, character_rank in zip( + ordered_characters, range(0, ordered_characters_count) + ): + if character not in FREQUENCIES_language_set: + continue + + character_rank_in_language: int = FREQUENCIES[language].index(character) + expected_projection_ratio: float = ( + target_language_characters_count / ordered_characters_count + ) + character_rank_projection: int = int(character_rank * expected_projection_ratio) + + if ( + large_alphabet is False + and abs(character_rank_projection - character_rank_in_language) > 4 + ): + continue + + if ( + large_alphabet is True + and abs(character_rank_projection - character_rank_in_language) + < target_language_characters_count / 3 + ): + character_approved_count += 1 + continue + + characters_before_source: List[str] = FREQUENCIES[language][ + 0:character_rank_in_language + ] + characters_after_source: List[str] = FREQUENCIES[language][ + character_rank_in_language: + ] + characters_before: List[str] = ordered_characters[0:character_rank] + characters_after: List[str] = ordered_characters[character_rank:] + + before_match_count: int = len( + set(characters_before) & set(characters_before_source) + ) + + after_match_count: int = len( + set(characters_after) & set(characters_after_source) + ) + + 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: Dict[str, str] = {} + + for character in decoded_sequence: + if character.isalpha() is False: + continue + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + layer_target_range: Optional[str] = None + + 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: 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) + + +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: + """ + We shall NOT return "English—" in CoherenceMatches because it is an alternative + of "English". This function only keeps the best match and remove the em-dash in it. + """ + index_results: Dict[str, List[float]] = dict() + + for result in results: + language, ratio = result + no_em_name: str = language.replace("—", "") + + if no_em_name not in index_results: + index_results[no_em_name] = [] + + index_results[no_em_name].append(ratio) + + if any(len(index_results[e]) > 1 for e in index_results): + filtered_results: CoherenceMatches = [] + + for language in index_results: + filtered_results.append((language, max(index_results[language]))) + + return filtered_results + + return results + + +@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: List[Tuple[str, float]] = [] + ignore_non_latin: bool = False + + sufficient_match_count: int = 0 + + 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: TypeCounter[str] = Counter(layer) + most_common = sequence_frequencies.most_common() + + character_count: int = sum(o for c, o in most_common) + + if character_count <= TOO_SMALL_SEQUENCE: + continue + + popular_character_ordered: List[str] = [c for c, o in most_common] + + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered, ignore_non_latin + ): + ratio: float = characters_popularity_compare( + language, popular_character_ordered + ) + + 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( + filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True + ) diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__init__.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__init__.py new file mode 100644 index 0000000..d95fedf --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__init__.py @@ -0,0 +1,6 @@ +from .__main__ import cli_detect, query_yes_no + +__all__ = ( + "cli_detect", + "query_yes_no", +) diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__main__.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__main__.py new file mode 100644 index 0000000..f4bcbaa --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__main__.py @@ -0,0 +1,296 @@ +import argparse +import sys +from json import dumps +from os.path import abspath, basename, dirname, join, realpath +from platform import python_version +from typing import List, Optional +from unicodedata import unidata_version + +import charset_normalizer.md as md_module +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: Optional[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.2, + 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 {} - Unicode {} - SpeedUp {}".format( + __version__, + python_version(), + unidata_version, + "OFF" if md_module.__file__.lower().endswith(".py") else "ON", + ), + 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 + + dir_path = dirname(realpath(my_file.name)) + file_name = basename(realpath(my_file.name)) + + o_: List[str] = file_name.split(".") + + 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 = join(dir_path, ".".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/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ca9ef31383fba2c15931e2e28039e8816b96947 GIT binary patch literal 292 zcmYjMy-vh13~o~drxPbJGP8APGccWm&^-YQTNf*rSl5XB^b%i1c_Ut_8)D)Wm~b{M z`LjOTpMTVDx2@O?Uk_+Fei!oJ1d{`MzGpC%sa@skq4r`BHM5~H;bpzm)4FIW3O%20(1E8D(_^i@(Nf!8hmt*uOQ^btjoOLvX z93yo)21?O&UIlf+BndO|N(?0X8N)1{J<4gJF^0!}FS8}=CZ*rFIZHjNl#%$F_+0+U<;*+r2f`gv+5i9m literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a7d256e5d410cfedda120b73fc295759053b32b GIT binary patch literal 6508 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 G{l5WrCL3J< literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/constant.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/constant.py new file mode 100644 index 0000000..8634904 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/constant.py @@ -0,0 +1,1995 @@ +# -*- coding: utf-8 -*- +from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE +from encodings.aliases import aliases +from re import IGNORECASE, compile as re_compile +from typing import Dict, List, Set, Union + +# Contain for each eligible encoding a list of/item bytes SIG/BOM +ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = { + "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], +} + +TOO_SMALL_SEQUENCE: int = 32 +TOO_BIG_SEQUENCE: int = int(10e6) + +UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 + +# Up-to-date Unicode ucd/15.0.0 +UNICODE_RANGES_COMBINED: Dict[str, range] = { + "Control character": range(32), + "Basic Latin": range(32, 128), + "Latin-1 Supplement": range(128, 256), + "Latin Extended-A": range(256, 384), + "Latin Extended-B": range(384, 592), + "IPA Extensions": range(592, 688), + "Spacing Modifier Letters": range(688, 768), + "Combining Diacritical Marks": range(768, 880), + "Greek and Coptic": range(880, 1024), + "Cyrillic": range(1024, 1280), + "Cyrillic Supplement": range(1280, 1328), + "Armenian": range(1328, 1424), + "Hebrew": range(1424, 1536), + "Arabic": range(1536, 1792), + "Syriac": range(1792, 1872), + "Arabic Supplement": range(1872, 1920), + "Thaana": range(1920, 1984), + "NKo": range(1984, 2048), + "Samaritan": range(2048, 2112), + "Mandaic": range(2112, 2144), + "Syriac Supplement": range(2144, 2160), + "Arabic Extended-B": range(2160, 2208), + "Arabic Extended-A": range(2208, 2304), + "Devanagari": range(2304, 2432), + "Bengali": range(2432, 2560), + "Gurmukhi": range(2560, 2688), + "Gujarati": range(2688, 2816), + "Oriya": range(2816, 2944), + "Tamil": range(2944, 3072), + "Telugu": range(3072, 3200), + "Kannada": range(3200, 3328), + "Malayalam": range(3328, 3456), + "Sinhala": range(3456, 3584), + "Thai": range(3584, 3712), + "Lao": range(3712, 3840), + "Tibetan": range(3840, 4096), + "Myanmar": range(4096, 4256), + "Georgian": range(4256, 4352), + "Hangul Jamo": range(4352, 4608), + "Ethiopic": range(4608, 4992), + "Ethiopic Supplement": range(4992, 5024), + "Cherokee": range(5024, 5120), + "Unified Canadian Aboriginal Syllabics": range(5120, 5760), + "Ogham": range(5760, 5792), + "Runic": range(5792, 5888), + "Tagalog": range(5888, 5920), + "Hanunoo": range(5920, 5952), + "Buhid": range(5952, 5984), + "Tagbanwa": range(5984, 6016), + "Khmer": range(6016, 6144), + "Mongolian": range(6144, 6320), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6400), + "Limbu": range(6400, 6480), + "Tai Le": range(6480, 6528), + "New Tai Lue": range(6528, 6624), + "Khmer Symbols": range(6624, 6656), + "Buginese": range(6656, 6688), + "Tai Tham": range(6688, 6832), + "Combining Diacritical Marks Extended": range(6832, 6912), + "Balinese": range(6912, 7040), + "Sundanese": range(7040, 7104), + "Batak": range(7104, 7168), + "Lepcha": range(7168, 7248), + "Ol Chiki": range(7248, 7296), + "Cyrillic Extended-C": range(7296, 7312), + "Georgian Extended": range(7312, 7360), + "Sundanese Supplement": range(7360, 7376), + "Vedic Extensions": range(7376, 7424), + "Phonetic Extensions": range(7424, 7552), + "Phonetic Extensions Supplement": range(7552, 7616), + "Combining Diacritical Marks Supplement": range(7616, 7680), + "Latin Extended Additional": range(7680, 7936), + "Greek Extended": range(7936, 8192), + "General Punctuation": range(8192, 8304), + "Superscripts and Subscripts": range(8304, 8352), + "Currency Symbols": range(8352, 8400), + "Combining Diacritical Marks for Symbols": range(8400, 8448), + "Letterlike Symbols": range(8448, 8528), + "Number Forms": range(8528, 8592), + "Arrows": range(8592, 8704), + "Mathematical Operators": range(8704, 8960), + "Miscellaneous Technical": range(8960, 9216), + "Control Pictures": range(9216, 9280), + "Optical Character Recognition": range(9280, 9312), + "Enclosed Alphanumerics": range(9312, 9472), + "Box Drawing": range(9472, 9600), + "Block Elements": range(9600, 9632), + "Geometric Shapes": range(9632, 9728), + "Miscellaneous Symbols": range(9728, 9984), + "Dingbats": range(9984, 10176), + "Miscellaneous Mathematical Symbols-A": range(10176, 10224), + "Supplemental Arrows-A": range(10224, 10240), + "Braille Patterns": range(10240, 10496), + "Supplemental Arrows-B": range(10496, 10624), + "Miscellaneous Mathematical Symbols-B": range(10624, 10752), + "Supplemental Mathematical Operators": range(10752, 11008), + "Miscellaneous Symbols and Arrows": range(11008, 11264), + "Glagolitic": range(11264, 11360), + "Latin Extended-C": range(11360, 11392), + "Coptic": range(11392, 11520), + "Georgian Supplement": range(11520, 11568), + "Tifinagh": range(11568, 11648), + "Ethiopic Extended": range(11648, 11744), + "Cyrillic Extended-A": range(11744, 11776), + "Supplemental Punctuation": range(11776, 11904), + "CJK Radicals Supplement": range(11904, 12032), + "Kangxi Radicals": range(12032, 12256), + "Ideographic Description Characters": range(12272, 12288), + "CJK Symbols and Punctuation": range(12288, 12352), + "Hiragana": range(12352, 12448), + "Katakana": range(12448, 12544), + "Bopomofo": range(12544, 12592), + "Hangul Compatibility Jamo": range(12592, 12688), + "Kanbun": range(12688, 12704), + "Bopomofo Extended": range(12704, 12736), + "CJK Strokes": range(12736, 12784), + "Katakana Phonetic Extensions": range(12784, 12800), + "Enclosed CJK Letters and Months": range(12800, 13056), + "CJK Compatibility": range(13056, 13312), + "CJK Unified Ideographs Extension A": range(13312, 19904), + "Yijing Hexagram Symbols": range(19904, 19968), + "CJK Unified Ideographs": range(19968, 40960), + "Yi Syllables": range(40960, 42128), + "Yi Radicals": range(42128, 42192), + "Lisu": range(42192, 42240), + "Vai": range(42240, 42560), + "Cyrillic Extended-B": range(42560, 42656), + "Bamum": range(42656, 42752), + "Modifier Tone Letters": range(42752, 42784), + "Latin Extended-D": range(42784, 43008), + "Syloti Nagri": range(43008, 43056), + "Common Indic Number Forms": range(43056, 43072), + "Phags-pa": range(43072, 43136), + "Saurashtra": range(43136, 43232), + "Devanagari Extended": range(43232, 43264), + "Kayah Li": range(43264, 43312), + "Rejang": range(43312, 43360), + "Hangul Jamo Extended-A": range(43360, 43392), + "Javanese": range(43392, 43488), + "Myanmar Extended-B": range(43488, 43520), + "Cham": range(43520, 43616), + "Myanmar Extended-A": range(43616, 43648), + "Tai Viet": range(43648, 43744), + "Meetei Mayek Extensions": range(43744, 43776), + "Ethiopic Extended-A": range(43776, 43824), + "Latin Extended-E": range(43824, 43888), + "Cherokee Supplement": range(43888, 43968), + "Meetei Mayek": range(43968, 44032), + "Hangul Syllables": range(44032, 55216), + "Hangul Jamo Extended-B": range(55216, 55296), + "High Surrogates": range(55296, 56192), + "High Private Use Surrogates": range(56192, 56320), + "Low Surrogates": range(56320, 57344), + "Private Use Area": range(57344, 63744), + "CJK Compatibility Ideographs": range(63744, 64256), + "Alphabetic Presentation Forms": range(64256, 64336), + "Arabic Presentation Forms-A": range(64336, 65024), + "Variation Selectors": range(65024, 65040), + "Vertical Forms": range(65040, 65056), + "Combining Half Marks": range(65056, 65072), + "CJK Compatibility Forms": range(65072, 65104), + "Small Form Variants": range(65104, 65136), + "Arabic Presentation Forms-B": range(65136, 65280), + "Halfwidth and Fullwidth Forms": range(65280, 65520), + "Specials": range(65520, 65536), + "Linear B Syllabary": range(65536, 65664), + "Linear B Ideograms": range(65664, 65792), + "Aegean Numbers": range(65792, 65856), + "Ancient Greek Numbers": range(65856, 65936), + "Ancient Symbols": range(65936, 66000), + "Phaistos Disc": range(66000, 66048), + "Lycian": range(66176, 66208), + "Carian": range(66208, 66272), + "Coptic Epact Numbers": range(66272, 66304), + "Old Italic": range(66304, 66352), + "Gothic": range(66352, 66384), + "Old Permic": range(66384, 66432), + "Ugaritic": range(66432, 66464), + "Old Persian": range(66464, 66528), + "Deseret": range(66560, 66640), + "Shavian": range(66640, 66688), + "Osmanya": range(66688, 66736), + "Osage": range(66736, 66816), + "Elbasan": range(66816, 66864), + "Caucasian Albanian": range(66864, 66928), + "Vithkuqi": range(66928, 67008), + "Linear A": range(67072, 67456), + "Latin Extended-F": range(67456, 67520), + "Cypriot Syllabary": range(67584, 67648), + "Imperial Aramaic": range(67648, 67680), + "Palmyrene": range(67680, 67712), + "Nabataean": range(67712, 67760), + "Hatran": range(67808, 67840), + "Phoenician": range(67840, 67872), + "Lydian": range(67872, 67904), + "Meroitic Hieroglyphs": range(67968, 68000), + "Meroitic Cursive": range(68000, 68096), + "Kharoshthi": range(68096, 68192), + "Old South Arabian": range(68192, 68224), + "Old North Arabian": range(68224, 68256), + "Manichaean": range(68288, 68352), + "Avestan": range(68352, 68416), + "Inscriptional Parthian": range(68416, 68448), + "Inscriptional Pahlavi": range(68448, 68480), + "Psalter Pahlavi": range(68480, 68528), + "Old Turkic": range(68608, 68688), + "Old Hungarian": range(68736, 68864), + "Hanifi Rohingya": range(68864, 68928), + "Rumi Numeral Symbols": range(69216, 69248), + "Yezidi": range(69248, 69312), + "Arabic Extended-C": range(69312, 69376), + "Old Sogdian": range(69376, 69424), + "Sogdian": range(69424, 69488), + "Old Uyghur": range(69488, 69552), + "Chorasmian": range(69552, 69600), + "Elymaic": range(69600, 69632), + "Brahmi": range(69632, 69760), + "Kaithi": range(69760, 69840), + "Sora Sompeng": range(69840, 69888), + "Chakma": range(69888, 69968), + "Mahajani": range(69968, 70016), + "Sharada": range(70016, 70112), + "Sinhala Archaic Numbers": range(70112, 70144), + "Khojki": range(70144, 70224), + "Multani": range(70272, 70320), + "Khudawadi": range(70320, 70400), + "Grantha": range(70400, 70528), + "Newa": range(70656, 70784), + "Tirhuta": range(70784, 70880), + "Siddham": range(71040, 71168), + "Modi": range(71168, 71264), + "Mongolian Supplement": range(71264, 71296), + "Takri": range(71296, 71376), + "Ahom": range(71424, 71504), + "Dogra": range(71680, 71760), + "Warang Citi": range(71840, 71936), + "Dives Akuru": range(71936, 72032), + "Nandinagari": range(72096, 72192), + "Zanabazar Square": range(72192, 72272), + "Soyombo": range(72272, 72368), + "Unified Canadian Aboriginal Syllabics Extended-A": range(72368, 72384), + "Pau Cin Hau": range(72384, 72448), + "Devanagari Extended-A": range(72448, 72544), + "Bhaiksuki": range(72704, 72816), + "Marchen": range(72816, 72896), + "Masaram Gondi": range(72960, 73056), + "Gunjala Gondi": range(73056, 73136), + "Makasar": range(73440, 73472), + "Kawi": range(73472, 73568), + "Lisu Supplement": range(73648, 73664), + "Tamil Supplement": range(73664, 73728), + "Cuneiform": range(73728, 74752), + "Cuneiform Numbers and Punctuation": range(74752, 74880), + "Early Dynastic Cuneiform": range(74880, 75088), + "Cypro-Minoan": range(77712, 77824), + "Egyptian Hieroglyphs": range(77824, 78896), + "Egyptian Hieroglyph Format Controls": range(78896, 78944), + "Anatolian Hieroglyphs": range(82944, 83584), + "Bamum Supplement": range(92160, 92736), + "Mro": range(92736, 92784), + "Tangsa": range(92784, 92880), + "Bassa Vah": range(92880, 92928), + "Pahawh Hmong": range(92928, 93072), + "Medefaidrin": range(93760, 93856), + "Miao": range(93952, 94112), + "Ideographic Symbols and Punctuation": range(94176, 94208), + "Tangut": range(94208, 100352), + "Tangut Components": range(100352, 101120), + "Khitan Small Script": range(101120, 101632), + "Tangut Supplement": range(101632, 101760), + "Kana Extended-B": range(110576, 110592), + "Kana Supplement": range(110592, 110848), + "Kana Extended-A": range(110848, 110896), + "Small Kana Extension": range(110896, 110960), + "Nushu": range(110960, 111360), + "Duployan": range(113664, 113824), + "Shorthand Format Controls": range(113824, 113840), + "Znamenny Musical Notation": range(118528, 118736), + "Byzantine Musical Symbols": range(118784, 119040), + "Musical Symbols": range(119040, 119296), + "Ancient Greek Musical Notation": range(119296, 119376), + "Kaktovik Numerals": range(119488, 119520), + "Mayan Numerals": range(119520, 119552), + "Tai Xuan Jing Symbols": range(119552, 119648), + "Counting Rod Numerals": range(119648, 119680), + "Mathematical Alphanumeric Symbols": range(119808, 120832), + "Sutton SignWriting": range(120832, 121520), + "Latin Extended-G": range(122624, 122880), + "Glagolitic Supplement": range(122880, 122928), + "Cyrillic Extended-D": range(122928, 123024), + "Nyiakeng Puachue Hmong": range(123136, 123216), + "Toto": range(123536, 123584), + "Wancho": range(123584, 123648), + "Nag Mundari": range(124112, 124160), + "Ethiopic Extended-B": range(124896, 124928), + "Mende Kikakui": range(124928, 125152), + "Adlam": range(125184, 125280), + "Indic Siyaq Numbers": range(126064, 126144), + "Ottoman Siyaq Numbers": range(126208, 126288), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126720), + "Mahjong Tiles": range(126976, 127024), + "Domino Tiles": range(127024, 127136), + "Playing Cards": range(127136, 127232), + "Enclosed Alphanumeric Supplement": range(127232, 127488), + "Enclosed Ideographic Supplement": range(127488, 127744), + "Miscellaneous Symbols and Pictographs": range(127744, 128512), + "Emoticons range(Emoji)": range(128512, 128592), + "Ornamental Dingbats": range(128592, 128640), + "Transport and Map Symbols": range(128640, 128768), + "Alchemical Symbols": range(128768, 128896), + "Geometric Shapes Extended": range(128896, 129024), + "Supplemental Arrows-C": range(129024, 129280), + "Supplemental Symbols and Pictographs": range(129280, 129536), + "Chess Symbols": range(129536, 129648), + "Symbols and Pictographs Extended-A": range(129648, 129792), + "Symbols for Legacy Computing": range(129792, 130048), + "CJK Unified Ideographs Extension B": range(131072, 173792), + "CJK Unified Ideographs Extension C": range(173824, 177984), + "CJK Unified Ideographs Extension D": range(177984, 178208), + "CJK Unified Ideographs Extension E": range(178208, 183984), + "CJK Unified Ideographs Extension F": range(183984, 191472), + "CJK Compatibility Ideographs Supplement": range(194560, 195104), + "CJK Unified Ideographs Extension G": range(196608, 201552), + "CJK Unified Ideographs Extension H": range(201552, 205744), + "Tags": range(917504, 917632), + "Variation Selectors Supplement": range(917760, 918000), + "Supplementary Private Use Area-A": range(983040, 1048576), + "Supplementary Private Use Area-B": range(1048576, 1114112), +} + + +UNICODE_SECONDARY_RANGE_KEYWORD: List[str] = [ + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", +] + +RE_POSSIBLE_ENCODING_INDICATION = re_compile( + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + IGNORECASE, +) + +IANA_NO_ALIASES = [ + "cp720", + "cp737", + "cp856", + "cp874", + "cp875", + "cp1006", + "koi8_r", + "koi8_t", + "koi8_u", +] + +IANA_SUPPORTED: List[str] = sorted( + filter( + lambda x: x.endswith("_codec") is False + and x not in {"rot_13", "tactis", "mbcs"}, + list(set(aliases.values())) + IANA_NO_ALIASES, + ) +) + +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) + +# pre-computed code page that are similar using the function cp_similarity. +IANA_SUPPORTED_SIMILAR: Dict[str, List[str]] = { + "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"], +} + + +CHARDET_CORRESPONDENCE: Dict[str, str] = { + "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", +} + + +COMMON_SAFE_ASCII_CHARACTERS: Set[str] = { + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", +} + + +KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"} +ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"} + +# Logging LEVEL below DEBUG +TRACE: int = 5 + + +# Language label that contain the em dash "—" +# character are to be considered alternative seq to origin +FREQUENCIES: Dict[str, List[str]] = { + "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", + ], + "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", + ], + "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": [ + "о", + "а", + "е", + "и", + "н", + "с", + "т", + "р", + "в", + "л", + "к", + "м", + "д", + "п", + "у", + "г", + "я", + "ы", + "з", + "б", + "й", + "ь", + "ч", + "х", + "ж", + "ц", + ], + # Jap-Kanji + "Japanese": [ + "人", + "一", + "大", + "亅", + "丁", + "丨", + "竹", + "笑", + "口", + "日", + "今", + "二", + "彳", + "行", + "十", + "土", + "丶", + "寸", + "寺", + "時", + "乙", + "丿", + "乂", + "气", + "気", + "冂", + "巾", + "亠", + "市", + "目", + "儿", + "見", + "八", + "小", + "凵", + "県", + "月", + "彐", + "門", + "間", + "木", + "東", + "山", + "出", + "本", + "中", + "刀", + "分", + "耳", + "又", + "取", + "最", + "言", + "田", + "心", + "思", + "刂", + "前", + "京", + "尹", + "事", + "生", + "厶", + "云", + "会", + "未", + "来", + "白", + "冫", + "楽", + "灬", + "馬", + "尸", + "尺", + "駅", + "明", + "耂", + "者", + "了", + "阝", + "都", + "高", + "卜", + "占", + "厂", + "广", + "店", + "子", + "申", + "奄", + "亻", + "俺", + "上", + "方", + "冖", + "学", + "衣", + "艮", + "食", + "自", + ], + # Jap-Katakana + "Japanese—": [ + "ー", + "ン", + "ス", + "・", + "ル", + "ト", + "リ", + "イ", + "ア", + "ラ", + "ッ", + "ク", + "ド", + "シ", + "レ", + "ジ", + "タ", + "フ", + "ロ", + "カ", + "テ", + "マ", + "ィ", + "グ", + "バ", + "ム", + "プ", + "オ", + "コ", + "デ", + "ニ", + "ウ", + "メ", + "サ", + "ビ", + "ナ", + "ブ", + "ャ", + "エ", + "ュ", + "チ", + "キ", + "ズ", + "ダ", + "パ", + "ミ", + "ェ", + "ョ", + "ハ", + "セ", + "ベ", + "ガ", + "モ", + "ツ", + "ネ", + "ボ", + "ソ", + "ノ", + "ァ", + "ヴ", + "ワ", + "ポ", + "ペ", + "ピ", + "ケ", + "ゴ", + "ギ", + "ザ", + "ホ", + "ゲ", + "ォ", + "ヤ", + "ヒ", + "ユ", + "ヨ", + "ヘ", + "ゼ", + "ヌ", + "ゥ", + "ゾ", + "ヶ", + "ヂ", + "ヲ", + "ヅ", + "ヵ", + "ヱ", + "ヰ", + "ヮ", + "ヽ", + "゠", + "ヾ", + "ヷ", + "ヿ", + "ヸ", + "ヹ", + "ヺ", + ], + # Jap-Hiragana + "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", + ], + "Thai": [ + "า", + "น", + "ร", + "อ", + "ก", + "เ", + "ง", + "ม", + "ย", + "ล", + "ว", + "ด", + "ท", + "ส", + "ต", + "ะ", + "ป", + "บ", + "ค", + "ห", + "แ", + "จ", + "พ", + "ช", + "ข", + "ใ", + ], + "Greek": [ + "α", + "τ", + "ο", + "ι", + "ε", + "ν", + "ρ", + "σ", + "κ", + "η", + "π", + "ς", + "υ", + "μ", + "λ", + "ί", + "ό", + "ά", + "γ", + "έ", + "δ", + "ή", + "ω", + "χ", + "θ", + "ύ", + ], + "Tamil": [ + "க", + "த", + "ப", + "ட", + "ர", + "ம", + "ல", + "ன", + "வ", + "ற", + "ய", + "ள", + "ச", + "ந", + "இ", + "ண", + "அ", + "ஆ", + "ழ", + "ங", + "எ", + "உ", + "ஒ", + "ஸ", + ], + "Kazakh": [ + "а", + "ы", + "е", + "н", + "т", + "р", + "л", + "і", + "д", + "с", + "м", + "қ", + "к", + "о", + "б", + "и", + "у", + "ғ", + "ж", + "ң", + "з", + "ш", + "й", + "п", + "г", + "ө", + ], +} + +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/legacy.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/legacy.py new file mode 100644 index 0000000..43aad21 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/legacy.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Optional, Union +from warnings import warn + +from .api import from_bytes +from .constant import CHARDET_CORRESPONDENCE + + +def detect( + byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any +) -> 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. + :param should_rename_legacy: Should we rename legacy encodings + to their more modern equivalents? + """ + if len(kwargs): + warn( + f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" + ) + + 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" + + if should_rename_legacy is False and encoding in CHARDET_CORRESPONDENCE: + encoding = CHARDET_CORRESPONDENCE[encoding] + + return { + "encoding": encoding, + "language": language, + "confidence": confidence, + } diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.cpython-39-x86_64-linux-gnu.so b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.cpython-39-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..3824a428ffd621958e1f1f22dfd105c58417ffd0 GIT binary patch literal 16064 zcmeHOZ)_Y_5r3D9n`<3x6Ph-Sk-Uu(DM937yCkFpH|O}@8tl{?%Bt)gEUl64ds70bGAW+gqCE^P$Ab~1XvVc@}i%3F4Wxn{Bd2fE} z-Ss&jA@QaAEbq+xX6C)w*?oI+x9@$uZ>WD$BB9Wd>ORHNLW@B%P#gxMR7M?Ex6-jy z?bNoL*Hr7dTLc1?etC=rR*4*?7bPT6=o!}IS?o;B(np`JhzJ_=;}BN%8-tauFdf-s z;Rw->O~~ zdofqfXuMIqAh@10taO}{#d681dTzyY9OX=vraa|L5K+$H*szn!SMn#Ps$RY_Hr!Jv zm-1uocp-0e^)*g**5wY|!ql0(8krlU9-U&2x#D!0Mloc#oSUJJM&^3l=_+voD`#ZR z>CL-^LOBa(M@L1`6{g0gy~#@6&84g5bUVvg<_@WWp}}K4PG`C^eGsQCbQ9e(=8pm9 zenk}5W@hIUC2^CwEY_IMn131MQRXXfC3q@=LtZ>;I^=tm?-8`60FF7wx@!SEIR91x z_!e|RbVtSrjLFo}fEB=b&Y@0O~{Z&>D%cKHP@zrr$?vdhnE`R6Qi3A?;N zvVFemMFQ;e4bL;Vcg5RI;T>Y0!n?J$*xWWxw(3=(WdE49KX``8zE%6&HT&YDC^6hh1ysgyjJ0DkS>0t_K zX_5}FHQYsZiH9*R=<-)dIgxH|dz_^PW>GSBm<@UnO14IZknIdM?X8H`Ay2oujkf z!Xf`0`6gPEM=YZJ<^R&vTJ6(BZ(OU@ST}aPR^xBD{0^C0;>@T@%(f(2w{A%-(60%* z3FCLY^W-81Z~Qos5gYj0D_qqjAsKHK;} z6TkoB_k}#(Wzq-VlMxiRI0JD8;ta$Yh%*ppAkILXfj9$k2I35SATr>ukBqE`#G1z+ zOBNvW+DmR*4e=LZen@1jTfIwUtjBB>8EX-D!e7>3^7l7x(EoF_R%ZDTeuGR6-`QT~ zFOk%+#`3$O=k>$f{$L2LxHWBuP;sLLkOmMpwIF(Y|HPWeI|ZMXfq`G%Y!ry|IkBTf zsJdZ1dONG*e@^V_6|k0(NBSD7<)=jdFOmH?rN93d!Fu-Sc!y-6ZNJb5giZ)OE%X~g z2YPxwW$mSv;QOqOc3REbVRg25cC>fg({Ak@&F3uJ^+d71qhnumw6L6{mA6oApUr?QTiF!uE~+ zev2@^em%J9hi07>v^0EDHTnAng4(2NR`Yf3TNLJL*q$B=GC#xkHidQ4Vf-Vi-hGs$ zUw5#cI&8n)pO0bu4rOP8h~bk8vvN(x^J%lX&PyRejh|1O=qZ5xD^Sv!3yoih&Z(ny^-Vz+oRT6c3kB*jML&s)1u}JE* zzLoH8^r?c+4>;Yufqf_87K{S4djtCi39q*g!xcQbui{a{>-GO6;kyFkf&GE*r_OxO zR=lb=Gcl3Qs)%f;zJ-pl7`lSEw$ zy~D$CD;0On$(Ov!oSLY(#k`Z7DHi9*B_Ns27eUivj-qj#{?YE?KBw<^FYg<1a@Ddk z>6UW5Ii&Xs$Ge9IdkCc`xzlHhsogtD5bYy@)4Lb)&=z#ZS zam@#R)B&It%};JTF0=4Qy_O-2`-VU21yIzLWTKmN2T|F?ag7Im)D@r@2l2xW^aS~H z%?KIw2dE_@MdKG(zuRCP{86WX^5+0Ij2}J!66x6g7#mSTJp;O6VC}!1_^AIZVVo1x z<^Drn9`=5{Fa7XX!B!<9=x>Q1=ycGScv1WGYY~5Z?t|`$Trl{f+s7mR_#6U7eGmI+ z{NED)P8e9i2>l{(p~xS?;(d$ECuL!Cy|p$KfBOxc7V`VrHeoMM)fgujj9AhzHL#o*#&vSie1V(6B$kK%$9= Uy6mp!-@pYpwHt=`$Eg3m0k}Z)kN^Mx literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.py new file mode 100644 index 0000000..a6d9350 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md.py @@ -0,0 +1,581 @@ +from functools import lru_cache +from logging import getLogger +from typing import List, Optional + +from .constant import ( + COMMON_SAFE_ASCII_CHARACTERS, + TRACE, + UNICODE_SECONDARY_RANGE_KEYWORD, +) +from .utils import ( + is_accentuated, + is_case_variable, + is_cjk, + is_emoticon, + is_hangul, + is_hiragana, + is_katakana, + is_latin, + is_punctuation, + is_separator, + is_symbol, + is_thai, + is_unprintable, + 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: int = 0 + self._symbol_count: int = 0 + self._character_count: int = 0 + + self._last_printable_char: Optional[str] = None + self._frenzy_symbol_in_word: bool = False + + 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: float = ( + self._punctuation_count + self._symbol_count + ) / self._character_count + + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 + + +class TooManyAccentuatedPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._accentuated_count: int = 0 + + 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 or self._character_count < 8: + return 0.0 + ratio_of_accentuation: float = self._accentuated_count / self._character_count + return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 + + +class UnprintablePlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._unprintable_count: int = 0 + self._character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if is_unprintable(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: int = 0 + self._character_count: int = 0 + + self._last_latin_character: Optional[str] = None + + 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: int = 0 + self._character_count: int = 0 + self._last_printable_seen: Optional[str] = None + + 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: Optional[str] = unicode_range(self._last_printable_seen) + unicode_range_b: Optional[str] = unicode_range(character) + + 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: float = ( + self._suspicious_successive_range_count * 2 + ) / self._character_count + + 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: int = 0 + self._bad_word_count: int = 0 + self._foreign_long_count: int = 0 + + self._is_current_word_bad: bool = False + self._foreign_long_watch: bool = False + + self._character_count: int = 0 + self._bad_character_count: int = 0 + + self._buffer: str = "" + self._buffer_accent_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character.isalpha(): + 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: int = len(self._buffer) + + 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 an 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: + camel_case_dst = [ + i + for c, i in zip(self._buffer, range(0, buffer_length)) + if c.isupper() + ] + probable_camel_cased: bool = False + + if camel_case_dst and (len(camel_case_dst) / buffer_length <= 0.3): + probable_camel_cased = True + + if not probable_camel_cased: + 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: int = 0 + self._cjk_character_count: int = 0 + + 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: bool = False + + self._character_count_since_last_sep: int = 0 + + self._successive_upper_lower_count: int = 0 + self._successive_upper_lower_count_final: int = 0 + + self._character_count: int = 0 + + self._last_alpha_seen: Optional[str] = None + self._current_ascii_only: bool = True + + 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 character.isascii() 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 + + +@lru_cache(maxsize=1024) +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: List[MessDetectorPlugin] = [ + md_class() for md_class in MessDetectorPlugin.__subclasses__() + ] + + length: int = len(decoded_sequence) + 1 + + mean_mess_ratio: float = 0.0 + + if length < 512: + intermediary_mean_mess_ratio_calc: int = 32 + 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: + logger = getLogger("charset_normalizer") + + logger.log( + TRACE, + "Mess-detector extended-analysis start. " + f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} " + f"maximum_threshold={maximum_threshold}", + ) + + if len(decoded_sequence) > 16: + logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") + logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") + + for dt in detectors: # pragma: nocover + logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") + + return round(mean_mess_ratio, 3) diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md__mypyc.cpython-39-x86_64-linux-gnu.so b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/md__mypyc.cpython-39-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..aaceebaa6823ca85bcdb7a4782a0ed0e3c91f4dd GIT binary patch literal 257368 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 z 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 J>8aGUki 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

(yp4W$>WJUIoAWza{N5_A9!^-&7T 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 Jjot?Se*gsNT4ewL literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/models.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/models.py new file mode 100644 index 0000000..f3f7bcc --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/models.py @@ -0,0 +1,337 @@ +from encodings.aliases import aliases +from hashlib import sha256 +from json import dumps +from typing import Any, Dict, Iterator, List, Optional, Tuple, Union + +from .constant import TOO_BIG_SEQUENCE +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: bytes = payload + + self._encoding: str = guessed_encoding + self._mean_mess_ratio: float = mean_mess_ratio + self._languages: CoherenceMatches = languages + self._has_sig_or_bom: bool = has_sig_or_bom + self._unicode_ranges: Optional[List[str]] = None + + self._leaves: List[CharsetMatch] = [] + self._mean_coherence_ratio: float = 0.0 + + self._output_payload: Optional[bytes] = None + self._output_encoding: Optional[str] = None + + self._string: Optional[str] = decoded_payload + + 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: float = abs(self.chaos - other.chaos) + coherence_difference: float = abs(self.coherence - other.coherence) + + # Below 1% difference --> Use Coherence + if chaos_difference < 0.01 and coherence_difference > 0.02: + return self.coherence > other.coherence + elif chaos_difference < 0.01 and coherence_difference <= 0.02: + # When having a difficult decision, use the result that decoded as many multi-byte as possible. + return self.multi_byte_usage > other.multi_byte_usage + + return self.chaos < other.chaos + + @property + def multi_byte_usage(self) -> float: + return 1.0 - (len(str(self)) / len(self.raw)) + + 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: 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: List[Optional[str]] = [ + unicode_range(char) for char in str(self) + ] + # 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 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: Optional[List[CharsetMatch]] = None): + self._results: List[CharsetMatch] = sorted(results) if results else [] + + 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: str = path + self.unicode_path: Optional[str] = unicode_path + self.encoding: Optional[str] = encoding + self.encoding_aliases: List[str] = encoding_aliases + self.alternative_encodings: List[str] = alternative_encodings + self.language: str = language + self.alphabets: List[str] = alphabets + self.has_sig_or_bom: bool = has_sig_or_bom + self.chaos: float = chaos + self.coherence: float = coherence + self.is_preferred: bool = is_preferred + + @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/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/py.typed b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/utils.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/utils.py new file mode 100644 index 0000000..45a402e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/utils.py @@ -0,0 +1,399 @@ +import importlib +import logging +import unicodedata +from codecs import IncrementalDecoder +from encodings.aliases import aliases +from functools import lru_cache +from re import findall +from typing import Generator, List, Optional, Set, Tuple, Union + +from _multibytecodec import MultibyteIncrementalDecoder + +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: str = unicodedata.name(character) + 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: str = unicodedata.decomposition(character) + if not decomposed: + return character + + codes: List[str] = decomposed.split(" ") + + 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: int = ord(character) + + 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: str = unicodedata.name(character) + except ValueError: + return False + return "LATIN" in description + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_punctuation(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "P" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + 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: str = unicodedata.category(character) + + if "S" in character_category or "N" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + 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: Optional[str] = unicode_range(character) + + 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: str = unicodedata.category(character) + + return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_case_variable(character: str) -> bool: + return character.islower() != character.isupper() + + +@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) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_unprintable(character: str) -> bool: + return ( + character.isspace() is False # includes \n \t \r \v + and character.isprintable() is False + and character != "\x1A" # Why? Its the ASCII substitute character. + and character != "\ufeff" # bug discovered in Python, + # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. + ) + + +def any_specified_encoding(sequence: bytes, search_zone: int = 8192) -> Optional[str]: + """ + Extract using ASCII-only decoder any specified encoding in the first n-bytes. + """ + if not isinstance(sequence, bytes): + raise TypeError + + seq_len: int = len(sequence) + + results: List[str] = findall( + RE_POSSIBLE_ENCODING_INDICATION, + sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"), + ) + + if len(results) == 0: + return None + + for specified_encoding in results: + specified_encoding = specified_encoding.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + 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, + 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: Union[bytes, List[bytes]] = ENCODING_MARKS[iana_encoding] + + 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("-", "_") + + encoding_alias: str + encoding_iana: str + + 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[str] = set() + + for character in decoded_sequence: + character_range: Optional[str] = unicode_range(character) + + 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 + decoder_b = importlib.import_module( + "encodings.{}".format(iana_name_b) + ).IncrementalDecoder + + id_a: IncrementalDecoder = decoder_a(errors="ignore") + id_b: IncrementalDecoder = decoder_b(errors="ignore") + + character_match_count: int = 0 + + for i in range(255): + to_be_decoded: bytes = bytes([i]) + 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) + + +def cut_sequence_chunks( + sequences: bytes, + encoding_iana: str, + offsets: range, + chunk_size: int, + bom_or_sig_available: bool, + strip_sig_or_bom: bool, + sig_payload: bytes, + is_multi_byte_decoder: bool, + decoded_payload: Optional[str] = None, +) -> Generator[str, None, None]: + if decoded_payload and is_multi_byte_decoder is False: + for i in offsets: + chunk = decoded_payload[i : i + chunk_size] + if not chunk: + break + yield chunk + else: + for i in offsets: + chunk_end = i + chunk_size + if chunk_end > len(sequences) + 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 + + chunk = cut_sequence.decode( + encoding_iana, + errors="ignore" if is_multi_byte_decoder else "strict", + ) + + # 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: + chunk_partial_size_chk: int = min(chunk_size, 16) + + 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:chunk_end] + + 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 + + yield chunk diff --git a/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/version.py b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/version.py new file mode 100644 index 0000000..db1ff57 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/charset_normalizer/version.py @@ -0,0 +1,6 @@ +""" +Expose version +""" + +__version__ = "3.3.0" +VERSION = __version__.split(".") diff --git a/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +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/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +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: Chat, https://discord.gg/pallets +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.7 +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 +- Chat: https://discord.gg/pallets diff --git a/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..05f2645 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/__pycache__/__init__.cpython-39.pyc,, +click/__pycache__/_compat.cpython-39.pyc,, +click/__pycache__/_termui_impl.cpython-39.pyc,, +click/__pycache__/_textwrap.cpython-39.pyc,, +click/__pycache__/_winconsole.cpython-39.pyc,, +click/__pycache__/core.cpython-39.pyc,, +click/__pycache__/decorators.cpython-39.pyc,, +click/__pycache__/exceptions.cpython-39.pyc,, +click/__pycache__/formatting.cpython-39.pyc,, +click/__pycache__/globals.cpython-39.pyc,, +click/__pycache__/parser.cpython-39.pyc,, +click/__pycache__/shell_completion.cpython-39.pyc,, +click/__pycache__/termui.cpython-39.pyc,, +click/__pycache__/testing.cpython-39.pyc,, +click/__pycache__/types.cpython-39.pyc,, +click/__pycache__/utils.cpython-39.pyc,, +click/_compat.py,sha256=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__init__.py b/testclient/.venv/lib/python3.9/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +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 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_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.7" diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e595255e05f2edaf4464f5adffbec778cd2453d GIT binary patch literal 2638 zcmc)M$yVD)6b4`eo-y+fW)uh^47QoVJee_M08W6--RQ_tVOOK+RLKys?w9FT@~%&> z`W1TB_g*ukpPmvDjbK`1Pk58~gZQ546N$P7GpB zlhf=rdCkz=L~cR1KnpvLjzgTCKqnx#2!Qs!!UaYJpv=_Ve}}BvPaNkFvcE5kHa{73~hkH z9(Uh*6EMLx(33F9e(S#TreKOa;lB5#VVXVZe(+{shW!pb3$yGg^c>8w-=pVYo;{7u zL!SKsU4R0623>?AdltO_3+y@cA}q4!(Mzzz&ZC!MnO#7yzzVzQe)LvhmA!yogEjUd zdL7o;OXv;QU@xOLVUxXr-hwUmNAxyqvsckOu)|(M@4_y79lZy8><#oj?6Wt~B`C4C z&7_D-1x4%6GniusHfTWydk4$ZImr7oUEmS z8lL%bA*IVRT+)gRClK23gNP;<#)FKixGb()v#YpxMcM|fD0LQ(hk>@rt|(;xZo=n( zrm3DTsY=ZgeuQp4z=aMQSBTBjE4!X}7`U#mBN_OO<9;N5(3y!-ytojN`&M%!`FdjV zB77R1xwMq!iAX3MmbPA3P1!Fi_Sk`cE0t%_IVKjdu~4G&G<$1RxZ!Jm50%yoEv-#Q z*nzU5fF@7AoS5TdIO)@6rnw!If5TB7qmY>gWrgO`?e$bdWZE^Q@Z&UJ?>g6*3|G-y{DkcaiwcF6=W^4%2)i1X z_tL_0R(MogIFjx>g_GJ<9-nlrnr~OJGZ9)fO*Lo@RZvkv>vCfRHocH{gr*s3sE!_8 z8k(y4&x{{jTzti@iYZH`6*3wUBf3A(Ry=!`TgSX`0DET2%GVnn=}6Xbg3P; zTv_uL*Y|O+(iv1zD-2CXQpLKcS(d(~9!(u7VR_iuL7nswymn=RQ20F0&%}CRv9NYN z^R=EbO((ETvmVF2Dipnh6~2FCDo&B0NK&LI(i9mAdX+==WrJ(gO1=16kEu3_c8U&) zPKqvyZi*g?UWz`9dR9E|L#_I$_YK7W#URBH#W2MP#VExX24ov$q3PQ3;O?h7|4 zTdr1bsg(?Qcc}?%Koa++SCeWI8|od!6vcarX^IaNGZeEFa}@Iwd5Qu?JrUujsa26W z7AO`emME4fRwzDFtWvB|tW#`IY*K7dY-7|DwMgQX?oh`r#U8~zMTz17quy$o&(FX4 zM@)U80~G&MidFn#Eh_w)75RH@2M#sLL6oOwOa*QpztZWcDMms^wkz@RD;DmBe_zCR zK{4bP#&Th!sAVMbp=ICUU|qz4_Fd65r7t7XEQF8s^mgN|f-ge++w6CYcrw@YKmTj~ E7yPNZga7~l literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdcbe70149e86067e7c1e1a0582aa22e1d894413 GIT binary patch literal 16013 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 {aE%6?`8b2T@`I3w$YO zY0Ryl|B4QO=LwpeWtRywNAr`h|IWjP-*4D!$*@4~3LDBI*d;D>Bg{r+g>Y5$|8OUi zdu_0o@t+slyI%{q@78@i{m(GSf_?`n+MpDF>@cq*WaH##Q}$=vzvkd;R6B7Z*w{5>1J2?Ck70s51sFg;L@@@M1L( z#}ro`{_G*n@J|CGuYrjN17WhPgc zNZj*ve!aout4w(9!Njt!^J|$2nc29-B7QNnWE^B|e8njV0q9p*`gJK-Y~gCUcwEHf z7fCAiqbSPKC}UvV@Ry0!P-htJT6nc3f2j7Vu|7no8d*rXFYUu0QOMr`4aB}mlRFAw zJ?~NqD^Y)&3(O>={}t!mg=*vM8934K_YKdJvBF8Dyx*4m%R3YaN9~? zdd4Q{97`Q?IbI$k7alKolXmXIe46bhVO30iFMp_j--5YO@x7xXauwlw-iK-X$VdMV Da-)|z literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_termui_impl.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_termui_impl.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cae6a5e7dfd206d305ece0f11ff4c2cb9b472402 GIT binary patch literal 16258 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 Z#Wb6*OrM<|r-$A#r|rp8n2)&w{|D*d%n1Mh literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_textwrap.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_textwrap.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35da2d4e77d6641fb03f9b4d1278a8e40f362a7e GIT binary patch literal 1554 zcmZWp&2HO95Z*shlq@TW>m+u8UUDcPAeM^uP!tG?04>m_D0FCxrXbo9G@^3O=AW+EBH*rf|75Djcl8qO7YJHR~Oj6`p z`BuGB+6QO3bYmYHcQE?G^I3ZC z?;jhLPLrb4C&^i9r1c>lPfO3|<-Fha!m8qx!7>fjZV+qJ0^vJ$o@Od3)GOyjky;n? zY~egN%Kk;n2jKE{JRFxZH8iEN>S$@RQlfHPx+CnUDT||RONUNbmle6vZa7#fy&M+# z@o;|O#-;vj@Ws&PP8~tIDfHhC!7-Z-6Qsl$bYn2T@DGx4s$~J?{C5(p(e8mDtsV<$ zM7!{G;1TrlqedeKcOv`Dhq;zei-{mSWB8HnKp<)(yzLJlpi5-MuvaTyK|3d;qMs8+ z64(KaZZ&%ONRpokB`-+@-mnYa3Dv!(_Q|GCbOaUja-F+8Es{+o{()T_TXnjCs}%G(z~^h4k{E z30pG^>J`|HyLcg8kT*5Qzk|gIpandqYkEVj=-1@8!LMw^R{{`3&T~np!aN0ygT~gP z3SPslcuoFf$m7%dlC8mhgFgs9GRS97JN?kNm0rx0Nu5Gs7P-S~Xw74AFb61h(N#>! zT=&Bba37+DnWg8sJO>IxKn>>q5!%_bASrcm@iD~M9tc7O+ovImVD7Wa$4zJ&{{60x zl0>I7l_b8CB(qX3fTfA=Cdug{Ew(!puF&_nh1+ADfqH;?4iOt}!-JK^V0+9H z6nMQF0$XM{2*kT)eZ(W+Jj3U0caPD7ZoLmkMc664H$HS1^IV@8Je2Qjf3k4#>a?|c XBSoFDW=!;KbBZq!eTx|}RhRz@_o#zI literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_winconsole.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/_winconsole.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03a6f0764afe8bcbf614c195a721c1f8a5d63929 GIT binary patch literal 7805 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b119e7eb3836d938235e42d6c82436715533893c GIT binary patch literal 90639 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�e?Ob z;m&T=r8k0G2wJz7oVN!1xW9*cw^%4Z^>VN3wA!Lp*mrOn&$c20-+r|e><`{yfdm!o z@Rr~nuGe|9zE5x3+j{rT=-uGn8@`vkdEn|ma8Pf~+#1}+d#SOoKDjm)g9$?RO$K+7 z&)OT;{7!m%C^$@SD?t&a`TowZ*7R|wt*E`mLKd5$=;{&kmc(;$)QDhF4Z`VFjy

D35w*JFQ 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⁢LJwzhIl0=<~ zigax}-E_m)EdXI<;>qCEF=~ADr_RKxQ5*EkH3r_gkrSHJ;$&H({(KFKzdNL9t@Ys$ z-_`zOF0vMb+fyEm^l5Kl*Jip4hb^W_a=4ReF%t*O81O0YOWR|Cs;0ApIM9m<8lDat zJ2QMiO>*}v0Bra-=vo(41p$s7v@o;10KJ!I|3Ls1KnN*pA!6MuNYAsb1=9t)2Y5{r zfny@Mp3OFMxEadt1sDpYz2G7Sqb7Dp&KwB$8ZyhSoqN_I8p1evcL>)=*f4mCvl6OU zOag3bfu)vI%(tKzHgAc@2T?154QL6g2|Nt@8_xL(O%DG$mo6xoREO zU~YhWj0CgFtx<(&8qkfyJA>kTO`2nWyvO8#dpx^# z*CxPD2zUJI>62@>oT3~j`b6T37MbiVsD(QNh>Y`#wX@-jTK3Dj{Io72-BA7a3%?py zWg6md=+Ps(_h~&(xkh$IQi#13KB_$3Jqq8=y;Vsl?j7?{YcyM?Qm$?fLI%$~#`Yxzp^TGEu2oi>LAabKxLc$3iJhNp>{)aHca%UO7G+w#WU+_my+TFr&E*~b+{+hj7QesYr|5l5LT z8Z&W$Qq)+^dK8L2repZ&o=vOJ5&{0^U?Gum1x`D~cCnZ~6l1sG`Skolsuw0uu z?4Ix;cE$_4+8vYq4hk?%+!ki1@D^_$(HM-8$P_qC7v@WG z$4ZL!v?rRE8V&24(}7WTUxaCcAm46>(Y;8S7B4}bv8ZX{k;`MIhhYG{DbLS$<7AS9<2PndZB-5E z^)fk3)Vf|4uLz3g7A#~aZm%!(hYw`n>^hk`KMn)j=gl3QN zQ>u!t2_R}2lk`v71n?&d>`zuAQWkE%K^}MOJnIi)&U!3_4?)Ip!(AvLXOuo~@+?tm05Y~J!w-=RpX7qm zh{?0ly74p@9P`7maSwA4fO$Ox5h5^a1J?IA{5()gIOk@Gq19^3^ zz8R&9ZiP=x$&EU{ z&e3TT4|)jGDW0B*ks{6l?&x8;4d61s32R+~l!wLIII1~?Std4!Cg zrsUz4u325LjkLD}`Jm7ql}vUyPwb)MwXycLHk{*S;Vf!#65M*Wx}CRnT)PQLZil-E zr%;*>j|qHPbK+P#@VK<%+Qr0t#6Sk>32U+8r84nJY%r}$lWPaBn-BjRpV4#$lRKS? zbThdkd|abwt`>8^)Gd|m&MfTMRh?7D_9f@pA-IRwr8Av8=LZ||G8IE7&lwNS(c`kR ze7`PI>_u)lrhTzTCsm=A(#){%-BOjc81cU*S@p~twe5oD%>;=IYl%I)ATga_vjb-w z95L))>5mG9(QmV-w=8xf(E%CvY}T#~yfKA34lrJ8huT@ikx+mG1v7xInYqwruReMeP3(tR+alDeVL#*z) zl3OUXbRB4YgjHN7HTYV#J+v^4H{?fNx(gCEq8+cF$<4F5D=55LKAR!WmM>?yj(*uR z^QMiloZ3EhZA{x8U$gB=wi~usgZIcd%|hi*b~kK90VR~*aA&MHPU0TQ;VJ*W+)z3P zoZ>%;Xj+u_@o634g8gEjvtIySzn7FjAOcc)Cu#U?vSQ4TI?X8}ykSFTAT+-Rb^mT% zw9wt`G`)A8%D<|KDORUI*g*D+PDYcl%ipk`C`*#PqT9j(1z7RYi_{jIt4q$1@u=!C zy@%P>%25<+7v<2bQ-QK9=wcd3<1HRmab_49P^zel**FBH(3-3VSJh<0hJ)HEigR$T z{8o80X@(LnLh-brc&t#2griu7f&>vFUAuTFb8;rHrVx;U&mgD$$yZ>pS|1^S zgWn+pg^mCIqjL(}0S$4EfH>(z|NdaCQW+T=+&MU2-Z{Lpyz{29fw95yvGHyE8yO$m zw`+WhXlU1;F+1F8U8R{_etfwZysT%6!2u!w4%EwdkPTXD&>|bA@09Qt!{cvZ*!%dA zLa|x8S~l-7#dmbxd5Sq$j`At0qCHoPNAI1tFs6FqC(durdE^y>QSXhWsE;Ev+k=DF zo}v1Vv)TF%)f{ZYe{MY3PUJ%Q;f>P<-myrJ&IhmL%BKac9wI$j3*@^uLM%u{b{vjt zSH#B==c^aLx0@WU=lb4bkg&4mk^d}m9wN@b>X|u5;{0(E?D?{z@s^g@@Zryj7Imf;dp&aAdOTcSjgQXq z$lMW04u7@-tfO-PdtG>(61U#lk+u#lu`19-T#Vt%|5naN%;XiR}o@WUK0R zN`s}TrGTKG#$H0Mzs3pTKk}#HmK3=dp^1xj_%*H%quKsrV7o(OCnuDAQTn<7H+~PG z`exuZ^~5G_PuDG`zf072?!9F$QI5Ox6E2y(kxz;DuQR(Eb5<@t{>)C#rlMzD)#6n37-M;Gu}U^8M_UAS%-^hIiA+5|pPU_$l$h)# zNv11pPhf8bS|lF&#^Ep49;p~oF1A`2*6BX|qWN(MPK&7NxHUqDCH`|hN-7!+LJ{;S zBjObzq+%FEyR6T#T?$E|y^LNJ56>>JI2kQI>d5i`?q(ud0B9#~IE@zlwz}drcpRl; z)_I19sXPh=UZ%3&+E!V_#Vw57QWHl&uh#5o#%$V~O91yXidKa9y;{tasGBJW1$FJC zJwsoCbc6~$Tjp)yr%z5#AzF%)>g?>l8cpu)j3;9s&0Y)G(b?M5Rt|YntDLPs5^nUT z=*-g04D)Hd%0+%VIyls1z5z*m=o#hhfZ=XEHzFmO^M^u;tg?^Fo;*f?2zE_fDxky6 z*%2D@kdmJiM<#LQvrr5_%~i)M?Y%^to%M2ikRzJTtd|#tT4&nBL0%CKUpiwp!@@Ln zy{Dgg>e%#S_f$T1?Agapy};pDm5=#*_a^srpX1V8-sJY$Lry0d0rolc&ZF5W?U&l!1?TJfUJ1ko=Dj4+U`CN_ zTA4_D=KP2Xu7C2%2tTfiCJQ28(icrzRo zp+XJT;C&>b2FEt6*lv}$IObiGCCYTRdIfwuXlC*3X{~bZQEOFIM#`;Qy4vc?@QMNC zVB1G`guELxUU6ghSYs76RZ@aQ_d>_@>WJ)^vSHS~N}q6El^1g#G9ohV+YG<*Xqs_K zof6#pB1EOONQk@OV!XjY^i0IYJi8tGq3k7v5|7D}W$@G};;3Q@RFT`SxP-Jbt^BOC zLs5FmxR_YOMs=RGO-c#P^~mkwkNo-*$`O|_VOD+)qrx{*+0w7!eiJS)ne$TeCRMRF zN0b|$Brb*)c#dOIu1a=H8sCDdF~ZuV4y^1B@eY!ZX0f}vh$-Y;Z)g{FOyg6A$rCTv zwDa+3$^fai9&zEV&PuYFNc4-TM{Xib96a1Oc&Kvl@Zm-icXyJWIey>0_jSLgF@iK|^UD0xd#B5nRO}fL zKWB`O?B*X8yWY=HGZl-K?3qYveEKh*ST>1anZo)K0m{=Gi~G5WKRA^*v8%XenG#E^ z2OprtRT`DO$rfJRO4x94w36PfGa{=$$%%Hm@Apfxq{{MSR&u;e=Ovp&uyy4v@N(jaT-|G zp9W@ITM0S{v($Sxeb)9QoByh51Xp#ZswF#Ji5aTX$q5DbQ&crGvb-21Y(~rvbjnev zjz<&Zxih*1-WJlwQi1iqnQn#2$YrIAAyt~P~jJs0Vr zk%o?qAhmQ?yh>*v=$&|=GN0poTEE1l$0B^hcppZbvqBy3lZ7dscxjXqKy%>{zUB7` z7c_6G@|QSe)J_`zMYx(`klU5PsYVKSW{BM1FK2gUE|sVQuRS=c3Z}S%I4VU^gO4J> zfR)D9S5wC?t`CHibPcvyt^u*VdB_DKfV0X*oRvkP?m9=*8~{pd9HAqln!pK>w<+18E4WVz&WWBGD+FIM&uG4_1JaCT4Wo}Px^qKvM2 z9bqmZ%2u1p+czyMvLEx&Ho`~_SSVu@#OzcZ#PK~_9cu2!3!*9UFvuxpAgNrCQ7WhB zn4PPbniqx`*1R(ZyPyceH!#~8TmMa(YJ9$h&ol(tWsASebD%11Mh{P^H_r;7ZmWbd zs*Xxpvc2#7a%(qtVTDbss6q(Ra2w$6XAUboqCOk>$}5D8Z=EM7Xg)l5CG&+T0_PO~ zUGa*%?egn6o|MAJ&Jx~FD8T|AvLKuwWXJw~A}t7A0qE^=P|z}0EL)Y1eJ-;w_+?~l z{nh|*wQ>ns_!xEma5i%#du<2;1bV{$Pk4I}RtYMYZT+1Oaya}tt*H(t?Lxfb+#sa% z!WCknd_J!r_i8ylq5}(Ct`&t?dfU3O<-S)JI*BrlxK#;AY>F2ccpHYVb7oHAE zO{Pn4t3ZhahUEFzHtP>%e$jfAv>!VGPS3<qR) zo7KFa<-rHSJd}kXAL?2VPJ&2~X3xuOV^6UQRLo-}CWSvkNuBInr%%EotdLGZWlU~$ zT!h)uUezO0e%KPX#vjwYuj%q>U2IuPf3>`Lo^xj%jt>949=)N9ARekyJEdOw##YAz!}rieo}lChlrrByxd^ zUXyYqYgk5pzJuuTINHLr55@4$ujjQc!3>IuZRmVnQLu~CMw-`lPs`|&+TR_yU^u4> zhvJ9AJLr$o$gC@6K014qGQ@7f^fmqbv@XvuBwapf@i5M8TgES>!7ec!A#A%Y`f>x8 zDdBHvD0fm`CXcEnKT;THc8`>yrwkO_aX01cnPVtcY~|S8v9+34N&Zi1YH&j(Hn9y# zbqvc|Zya`ah)1+IZ2O82&F-W{_^OzZ>eT@Iof(p>V<$DKsG~RCnUg7Q%fiohDTS;9 zJv@dqW4|Woh!x8e)^>GGP5CnWmDZ(IQRcYQ!c=GF1D;(w{cN!ULDYbf0_@k&K^}c#kftr$bx@FHoo5CE7SxH z4=5E=yAUoW^ZS}GHtxC7TRqZ2x1&fx=aOx~;G)?5#Uh`FUr`nP+*hn_qb73J_#IU{ zLf*{K2s+~Oo23FSD&0EG?&|TB+0CZp0^<_>`=;DZ+%cs&Vp2gd|MS>^%J`n*&ceRK<9qjS-FadtTX}Qj zmR+Ttr8&yz`jdS^f30s*f8=EH94nY`QMj4Ziwh+_=2#&&lOWGAqPdwNe}7odBxG8i zk=^i97AT5iM#;C=a_NXsSBi4$XiEz?MS81TO8gr|Tr6;syjn1Pfr})LDcgcuan;bf zl)=+7&Ke3RRpi*w;=*=5I|7wCrZPCiOVsj=gO&1k{ibqYele? zGRIQyMEODsMv#B+5c~NV2QkvQumA;|mz~Er5*^zoD%HOv&{+;B_ zoAf4i$z4WJlfzE>$kdy;yW3#7o3^%QEm=%qOwA&@vZe%IR7?hLuKhl<`to_6@7++JBx@os-B?cRhLNbT-DZYo?(_c&8eQJ&uS4iU$s0fS~b zTOu39M8h9vblkOMN)^uvVEzO#0Yok9vc7)@_Uxn{9|ku~sAmst=$}!x4KJnQ4@R*a zZ=_;AO~YqrJ$15AUW1*y3k8he4~ZK=FPM{FQ0iwH&P{mi zQ9_F!Q#GgfwDxhqFIztS;_02>h%Q^P7JtZv!}uUs%n=%?5ZM+9Z7zktg}XaL4{5;Z z{K~@zz_d=6w%?Xnd}3ybK*pINkVXuR<~*u;)VS~t(Fke5B2`Tf=CbY4N@Pb^p1JgH(o z4~d7h(+329YzE z#dftEkqypIxyZjL#ni{KJV0eC#a^4z@$8S#yJ$lG66x@9T@2#hFr2_Cq186j!`i3o z>wKqxF6CB+a4+%&MX$KcfjpIK3Y+^#)oxd-G7xOsY^qUbxSd?2xf$DnZKg5tzR1n+ z^O_gk?J-IIU22EQ$mG_xxcYqy!`pdfPDMw58fE=f;2`7dx~mG&=k%@PJ#ig{uJR;# z>$6qm{V11MC}6Dwc^Pxq2@4MzaQgSJ@`TNW|~u1G9O0<4@#ev z?WqvXUddf6258SXeJaB*?p?_R0}o*UfE6ioHNuV}-@I7mi~pJYe8J8uA3^5FFCXdt zM=&LzW#T9l0^3ZE)V2bpV{SL?oTAT1M;_beY^XR%PLaaX826w^0bS&CBn$kRFq@ z(`?>1Y`2QkUld_jDlxB{dG~X~F+Av@GjZ2lFLGew+1BKQz^vfTlLtlaJxWT3ddk*j zCqK8?n%Zb$)%w)ZjzzR9OnJ1DrjuM3&B|WMUjvnzgv^vR_Z1Y9pJPRW0e*^i4Sl~} zaCT19;r*iS8gekaV3LGvdY{m8MT%mvOMSCe=|T$$EsDota!B#Lq7%TKg79yv@L3^* z&*<`5{k%t)-`2&XCCNFj7hMZ3>#iC^w0EJo#J2b)y>4w&qu;N#?I)4hW}6doLmaiJ z?LN6T3+M@n;6Rw31H>3A=dQ0v=|NpTpjx`oW2b0qm+qmD_0Z%}*ck%6av8 ztT`Nv;Mo&l&7bMQnpj z)CR^>e*%r$u4bCMO_g?0BGcej;L;oYI$(FUODd(HY75%DGWSa8gkYf2APv_?EYx_>bVY+`$g~lxFf+=13mT7JDb}^kY&8wi z7;N-dCyM-c+(npUS8?q{AaN|_RlRd84moGcmR9%#?N{p?;F75^F?|iwA80WRvVK6z3`B zI3EimJ(gn7#cnu<;drlIIHi+ht@(0KB5j@eQT3;Xa~zTs z<$(LMF}_OT_@(-jWZa0RBk|ZeA)BH)f%C+@W*L*YIfq%AC@E%)))o)M;x?ve)GLL{ zc{zFHkk?OTUcw0_8k>Uafg!15lxgYF%1DBz{hP8s(vU7vw30 zX&!PD$K6Zy@45s*117Nc}U88VC}Z!PHIkdVlX*C~jcB=9$N0kfPRoWLj|w~nEz_nwrJvuczI2aOXShlvi@6u8YS6C; z8b;Vqo)vQ8Rdt&eyZ$6BKfasHX8uUbR?hr1SSL;cPdLujNTD;56c+|{ zkI(2?8LI4QY?PAmYqY*KuqS8p(Q|Lo8sj@QwUA0ml-bIRW_?O3TREzATcFcF_>K%= zE;riKfva2Oa}}GqRGzgA`79eqD$_Y9W&33&FEc{9{m*KJ3{GYMib{{ZZ8x+tdTpbO zo9nxLDUqpaxBtB(xQXX`c<+|reL%pKNGl-zH^UO_3U9e@j&beCdrKXJaXG`d5Q!%;V%PtyHo0oeNs?BIu z#VM7AI#WjwfZ=FHSEXk#OGJLx#+pUeu1M$T4UV?mrYhaA15OH@x=DN@wIYhF3$}H> z+(5`c7YWbl@Bgp4^N+6ktnd5%r7P*`N|vu>S$2$blR#|che$$4LkMZWiAhE)d=ei@ z1w~SPWm~c>oA13!$mNQsWW;FgS2J zx&htRGj{Mwyx05ldA`3S*$JHfF(-QN_s8>netw?M^Lai$6k zn8Y(DWfT&3%WGXZosD}%6ow?~6oZ#4@Av30Y24()^09P;4^sDlNo$$s#pYq+sX)oA zOlvaMO%S7UsAdsC6it?iG$LIzmz1fOw&?xh8oXylOKjA~rJI$^N3IjG!RK8-YKR+5 zUSs4Wql>vTEd!8pUk39dAAxWa47Ml%zBi552-q1yyk`qLZ9?FfwVMW|NQQt57KzJ( z6$#iK93=K(7PgaK$Mw-hMZOL}L$amlI%aV%u4<9Fcr{3-V*xj#;~|4ynnu`V;T~Iy z7~Ckfc2fV@gqK^04vf;Z9XWxOU|Jw3U=)M@h?(YtW{0oNGGVN@g@t1W&~YM;qF~?_ zAFSz2SQ$w|P9rpkO|&$>zW3+L(qV{FS-^IDN{4ZI_2{WJ3q-|9>NMxD+>EU<24Pv@ z8RrqY$Kp@MMfeJUIeLOQdr&cEIyCt91%&Oi!gcwQ4yOZc>btXH6$d1@yzDP(=%c z@FesAKuG6}9&AyVHBg0l#Roi=vO5=G+%>+ugnUv>A@HOeU~Ey88jX0V^LUKl?3-yO z)|^heAO0h(I;wtT}XAtyL5h zWGf(0GoM$x%pAF@o(qP9J7c+0yzziq1(zTZNzQB;#LHSs6!lZn9|2upuxTrG3(%k^ zuHp%Zh6Vws`MFqq)Mhg#-BozJWylqU_BdyE(1)#}h;BI>_C>lw7NMw9P6E+bAbL1Nw; zgRxHwV39Oj!yOQxZGfyf>3rEDi`O6PGH#y$F~!$fYit&4_|6Idnsmr8O4gk9na4zw zKswnBij^UH#^U@fEaavpo?O%7Sb8k!P#Y8p33yZz<=7p_;v*bUrJx2G3Du(_Rd^b? z$VOO8GAV|o8_aRF&)+$7J8{z~_LN3OM_*sSG&?b6Vf(OAD`DX$mD^78Y^!|ONn$pwxL^hd?HD-| zX9G^4Qn)ODp0_0oMN(`0IY6`E8ube^8#}|?rp4IyX2ZF483&*|uClJOF}UsrG;!p+ z`si|WX4TXT!H&yfayVM&JOMH%n9d?2D3%4(9x58Fhuo|!Suwt(bBiN!zRnKVUZz+> z?Se9~lIgLWrKbc#TDk3#?&4>^e6;yUK1i2Bvd2;&M3qA|Q3|0o9y=4AyhRQbVrWmM2M#-%)*|ji&1tAQE_B>{ z{LC6pVXhJ(#MZ+yPN@SSs&MM;pzY<@0nwbiTC)&2G0Yx1V#Wp2qy6C8)ectCeeigq z({O($R)(9njM&D8P(8+T2na&OZtJ@vH z)fHHv`djEr_p01g&kvgN-2|NBV*5+IiVTd_M|-2<9b@YE{@x(zRJYOD*_rH(qGW|R z{`%<87FPFF3Y}f=C_X;v%H-5RNv*=0OFxG(khY=6m(G-L^*+lrwDRgh&AHXU7 zI_&5cqi}zWc=v0QAbR@JO!pO6`~(U@h!<}h+88!}YgynUv7^A!v8GD6Qh z^9XFw(@mTvAMc##SN*qJOH1fBdJEcHlE@D#fvt&Ly@0-E;3hWbka&`C@xYw_0)01zlYv=}*o(#Yg-GdDM&v zvFO#xCh>T`f}`q=@pU6(3or25^tekY&a0ec)kjvr2lQoHvsGo`W2|OXY6~4LV`C!6 zh~m?#OTLFzaEiTw<80O(2S5VtQ{*a4R1nJQzoEdGSG|#k7gx_61mA4e@CNe9Be z8GOR%83Ntaa=je;P=rmTdK@;8nWGx)_@Ay5NZed!^m_vPE$aDXT2HP#6`?5n(O8%lBugK{ytFgayU!^($H|HeYnqn{*h>TDdqG8OdaFsQ)kYc zTss^0d!c!3nHZpfX{mC}i&0#91}(>&Y59mh=%SpMFPAQjI1{V{Jjt6%Ok9+RD^3f% z(Xze8t~hGUH1ESDy3SS^9Z_3l?rKdTSkik5f-dEITk;Qsx~OMXRDHU;n*Tv1b7N?TbEIA#}&fyic6X&{M5;eY(7qU% z8ELVpE!yLSTnrJkxWEsUk$Q4H(J8ISQAOEsIU#HC1B#lHJs(J(%TL{Se=x z-w>^aFR*Y+@=8;q{zP&0zNGwL&*dsunNp+le0#Tii+_8SqLxNq>I~vpv)GcK{UPl1 z(Tj4oW)I`W#Caokn^m&+>=@cKw zL#+PmSfo`<66g>c9uOXL9qgoEp6%{=mE=pw=^nf(^&ssFGnl;?$Q`Bv5QS8P{3tob zgXo-+U(mC2N^I4>m}mW3s%7-F0C1d#1x{@!x>ZQc(xiK9x{5VAxCg`ohAoLy_d6}e zD5p&$pfznHpc>?Ns7H#aTk%OLVU(n6sHR&dK!f+`daDKx0{WWZ5xix^^!rWErhWd| zrgmv*SiAOe(eXevED$+t1jv}B7|5Urb03TJ6#4xE{@VH&%h(AFlZv1!Qao{$gO|DF zOzW-bi|*^d3Dl_hQ^I!*=#AgWw=x5Q zbDt;6=-|a;O!%j_4)qGj_zuo?pXZV*{QJPwU-w1ZHg4)?+$hta=KY5A38(|1EWebFD2gM-7LD5KSFt+2I-GN1b& za`^sJWl0vK&Bsp7hd>H%%6NT-hhqOJC|B)oDg)g8pjzA15g~X3MxC+&#xZ~qP)wX1 zCSYilsSB9*YWg#^m$|($?nL*NX90sL$l-omg;_^UG4!jnBl@NiTg|_%w;GU`iZF0Y zNEnco0jaepg;Zgw=nEwON9f5I2$iAYRH-@ADD5rRO8W-(j#rC&O5NR8Y^-^*I2zWq|3NmuPB>X^?-cb8X8j z=~Ozj{c)!uU?!e+XJ$8PmPKh5;H_2QhE-4jPdl+Od+w;DxlTAC8eOOw=Gru*#R*Zf z0e2qHXEbXK-F`sHztXJ% zPy(|3(VUp`1?ra3o&Yb7%Q)GN;Q%r1ST6Twvl$^|{n^~iabfczM+Rfs28B{q*eX%! zy+iH{5I=AaIY(zB;tD=oSbeUZpixci_mD$A%k=)vUMZ-E-I*q1CGrZ~)b74?P`3I! zXVIw{*Pji`EnN7Fd&i99!Hnyu3^vx40^KwFKC{t3-~$%ezg4GffeK~_=YTPBCs4HB zo+C z9Yj$8)4%^Z37^cv94i08QLRUlF82m5;!Cazdq;%7xyG#ovCY8ab3y2W$GP@HZ-xi5 zUU9Ka&dcIBfdF#xY8kG<=vNUy5p$61^4*vc^q_d1Few^gg7?3NXk_$<8lNxg%FYP? zn%n;H{cn)n47_CbI%llDH7s;X6O)+m|WJ=Tf=({N|=DTYYHjZ;$msK8o>!D0X(?d`vy6?WIe_{Xx#B zeS72j)UN#)!|2XbZcf*w2GJTae*%@$t?0zEbN4@@Qa?r`I7=oFJ2$Ma<|WA6P-A~A zUvi{5w8dQ^pu*IZ8W7z|4Y_?x-^8c=_KFPxo3COY&pCbz`xC6c=mAha9=LWp@_#@R ze5!o9@&o{$Sndt=%9?Nx|GAgR z*FOCbuL+}Hyz|T`y=6<&tPiPLBg6Y@ikb9UlmDx3P1Ze}0FK*hE$YqJmE5f4Yf8+d z>z%s#hLU$H`D-N$O5UeRzNITeAit~IztHU$m0Y9bexCIQf5ttJIZMs9P@^!7xYQQv zl!@pJ+XEx*L6LTc=<~X=flP@KyRw0NC0V{I>!{!00xJ5!oF71^29#C{-z#yFn&ceS zEbfKgmUlp%s-U|0j|0VJ-!O|^fdNNIJ{I}kwH=%_)@vCfKKud z5(|sxhT&3KJ&$7DY#s^YZ*U(}w6`7vQ=a(Tyh=4}=Px#|YFN1gEB0&VRrU9l-4Eg1 zj-`pEoz#>XTum;?Gof0HAx~oD)4<4QM{5Ez9r@^+B7o-3R-BKXC0_hwaJAcV9H5-E zuk@3rd(42%dK?VN;h;G7>dQ3g&tYXYj#mZ3tp832S0O+g;6v zV;%fha%Y_h@;kOn@1$t6kSSp_q5r+`f2h)u(RF9y;vLq3ktfic^h{x6~ zC)&*u%gCn~(NvS1!A<+Quy6$`EqiNbB%11u9{k@^lr@(BdDsI=|WbcmC3Q?l9b6{D>NhE zjvk#C2Wc-&2#c0v;IOf1$rU_nQcPSzDspg5>!XWjmpic$9wLO;7KLSktXZ~SXI7;@ zP8;uP9=2bdT{w3khUhG_aHU!6nYGfA3IlYSJ8u!6*{07l4>CFQCp4S_%^o5HlSw(r zc&VP8FSKwR+G4yp7rLH)e&7T2IP7J|HK{DyNFQGhi)-TM%+RSr?Xycq{q)8S(PaSZ zq@2WN%z-!8M1Xv0-sUa{-F=0n{ftd?EKiI*y=9pS93aAqvG7uApL&(9+RQ=~T107B z)*Qsx$~6d9pc;RdfJ%NeOgASiS_U12AiFc~VK63)7w#3zY-B8eCP4@7KENkenQC$t z&t1Vl&jBS_lkjEGEdn)w&Pu4S}{61a+y&PGGVWFRxe=rS|M0VIL# zj-+*hdhBCQ2;NUGMkmb%*GDODAQvmB=FG3+6>4i=wfLSGZ*Zn=VNOpnMkKkW#iiPs zqcN;LXMS*UOI@tAmrpN)qt(X51ZC^4vKeTHlYs!LjBzp{@E)N3P4$ZLVQ2Ty(Ha`rVkqu0mL6hjB$P-9Lav!j#%p2WUhmUFF7&Xy z-&&(6+k_*g?4lh$ChjOE1p&Foh#0$+5L;L{xD^fd>^rR*V+09Ef;Z3sLS-sUOpKBo zv$?NaCqO`R*?z}mBy?Ve{<%u$Z<|SVoE8>Ljlg4=8$OP~9Lul-6Eh%G?Se`xxL@_Q zV*4@Oh|cTi`zFqb(LR#?jQ< zZhy46-avXIeQmTkFz&$l)_Y66?MdWk`LKN*oLq^i;2(De6qm{cR~M=+gvJ+37Y0$? z+_Bn#9XLpyQ}FqBtirKh-_hHF5ed}Umcu1m>Gf#0gNEPO{uj0aAzxEYzs-hdowVeppybWJJ(5tI8ynCS2xUd6W@Q@kSOqij} zPStQ`0b`TG%0#EJvg<7}x|uR#ncZeMv!_?%+xH};{5^7AqW}RG>>C4CMCJcapvy=|n|_K>X1H>u&e*2u{crG1VWsD~LC;{H3l+ZleR=;L>IkKu~V z&=e7=WQeov9i^zkb4*?0=O&aI;rRjH+gR(GJdCX6*~9%|-d)e{y*wWe&v)uM_uF-E ziZG2?GlD?aYFsu6UXOHd#G2&vk{PGOL@3ldek=C-3Nd@Z{WH-yKr{Lf$suRT@iB66 zLhdcEMt{Uj_eN7b!2V9?(oT?x{|yoUzChcuSMh?aO63DxEIR?k;o{aTwwdYP{;(15 z+S#+{=W3t4C@J5&k*@14YRuR6JRI^u32eyc#l-Z?{+aG`uaYg$ru%26Z-{0YmgtpA zQV;AV{QA7c@>fYvBT9}lhODA5Df@p=@@GnfPNF?Z7M0wiXR={)YZjr4=>5922^HEh z9_!rb%Q(B*_9ynXS>mXtMm9(PQQ5vsGB@<#YUd&8wMPF*&kTVX-u!dj{%0j7^c18_ zPq=_1k6bsl*P37z=o_oW%eDq47&1yLke~j!M%X&$Qz`%4NWjqAjW-4k6l3)Z;sc-K zLMAr^a6y+rx_?8s_Lb&l#^k0VclARu!6{YI5gbGNK@NZkG6>&NUl6UatgwTV3eC=Q z_{yXfwq3tGt&?ktzj6NdiUE4Lf;NRp9V&LWz0w#+SFynXqnj#QncwzpBp#yM6zPc) z#_BaI9DXI0PpoiIJ*a}=Op-N=Ow`72AD`O}l}@CA34&GwGh;P>Ntv#mJ*ZruLs!^1 zyei@l8WwG1xJm|}{qItBsJkO{IcstfeVC$hQYyh`mA`}hwL833U_buYqSgoat@h9o z`}xl*$lry+MZnwQ)EA>W2?9VEL|LbtM@=0xH@H6VdXRYwI~7H(Y*kP!d8jpjm0yKz zfEcWg7NXBkN{LMZsTHE{;q_W?_(GW>9_|fC@9I@AfLMFO5^6G}STSIesjJ$BDtT(X zTJ+&wg{O9JZ-#p{YWZ3RSy*on3&}xm3+?c-1~X;hM4rH?6V`s;qNBelgIx8df{oQT*6B@ts7{rMiYZRY=hKN~tljo0K$LC)B zFY4+XN%w|>#y(R|bi|L?u{;2TF{Qk>-J6J&=a=a*NY={uebmqyLkNxp)aZfk12|N< zk1b0U%BMAA#ypUpCh>_ACUAUA_^C~q#oJI!^KNPXPfd>qJwwoAzJ_Q$GUe0$fN7XS zKcT^StrBUqMZc@$)g=8&8_!n0g$!`=T#7I}Gx>9BGG!_xwqa<`nH!6(%*|}5-LJ?> zYp&*+ELb;0{QiBSvZC7M z>VN{}j`LO?hby35q1YkxdXOez<0#w51fyi_x1!&t>p6^4p>F8`8b*0P7of{Rg!nw_!=(awyy;*zdauq+M6RNDtea z?bD#1bx0qWo{g273JXn6ct3A{Nwa=0ZN&4X|7V+Pjrn7)FIRyDN%@qP{_oIGdRN(S z*PRH9IA_wZS(9xWRY_w?Sft%&@08keRMSwlicf$9QIG|Nc2H_?5A*2QD=c7LN?YXR z+=DhtnX3VXLB^m#PeF@9(p(LmJ<`JDfemPYyP@c7q{D1RZiN37ceUs#rgTJSo=EpP zU2vsm08>>@E{t9*{1)0K;kzOm#aOS}DWhNa@m_Vc(Hgw4%~5}^>bf*+b5gDtZ`Fw8 zxt+~yBt-Hot~AyOIYtoXMt6#`cc3|0Y>i^MHT<)jWb}Mhn;gHlF#_vY<*tvAZ$hnN zo4L0$raRTm-JPv^rLaD-URzZ=C-`m9?l|v5x@Nl@Ve2@-sizd(!bwu)=!&P&n_5;H z{oF?H>Z|XfU&Au@KZfog@854d8`q}R8xB3Iub%4cx-g|Jl^lOaA31gK?W<_PZk~LH z-vRx0_HcC#SABjfs}((OH59d_wPSaIFP_Vj-Lz#$Z#WeVaS|kDzUr$(C}gsMuh)BZ zYpsvwgpFpswbMt_#$s>hIV<~UZ7J$f&b9n5@Vj@V*=le$i|?+Z---pSJbN!(&qj=+ z1AU`;(#hMPWz`^K3`d_wf2N- z%x>OJJ<;b{yC7Ju;Vbki-FRkt@2nJI4OfdU% zFShR>Ew%3eZh&+VJwRsGDD#M&+)yr@q!dRKhBBmhfaa1_{}iw0MsON8Z*1eG_6JLI zJ9O*(L6PS6!uOd(l>mpUk73!rG!Lq2e_W`-bXdz$)s*Tcni)5TWiQ<)G5CTOT)KT{ zN{IfkT6m76Tf&Nu_9g#BL>o%r*R(@jS6k|jn{>4yEWSdv55`6Vt&Q7RnUepU);e`D z{Y))Pw6(iqFmjr3QSWNLk#t>0V1AE8AE&@e#RHd$(?52jqrakz=zl2LfQHrD? zE-B$)l!u)n>@0XuEwhtiTVL3I@+-P}nUaqwIj7{X@;#=jFDiMHl2<7C6TQ%>xL;dt z$2wM#ZCOU&Jf-(`Qq;*|ZhU^$xcPQORj@hV=laUkC7Ig>ht$0?%|~{ORZodyZIqDh zY2Q;`LAD=;zOO5FV{VX1n}@MeHq=|M0kffw{t1oG5n@`1JiDTT?3HYo_b{`rAY17+GBt(~ z{o65=Zl;yw8ZBg+XibWag@yxqNsDdl*jF&z<2-sm2Gc8||8&Zn;CdjM=u{PiTN;ro z!$B3EEtL~l4VLT(+L0yM3Hb3ws9?IDp~rrLs-ib5u{C30Zj0^?J(F&VpXKfRt~CRu zPGR_y%5+%Ct;(5TURzx^s;h=^2kXp!qc{OnZPNJ_hA`B5gbVfxsED;Y7dESB6gaL%-HMcoaJ?zil?HML{kj@5~fJdT+$RC!Z>M=ZVz<77pq?A2y}{b z7S5&Q$LSd76ONB)$H-n88M>(3NAcv8c!reAw?ug2!UK3e@@OYpWH|k?8Di@U(q5h8 zmfnDVA!5V_gO4d^73G8x5-bNNYxX(kH80w}b%7*@T3JrxAp~)$PPn1kj7-zNL7WVl zAdrKLvYPzM8?|XEBwMwnL*{I<`H}{$M=dEvrm**4G>7N%6Zv&+e};+7Z$^Rt#aVl! z&0u^yh9#7u%s*3^##j3iS93LMxp~r?9&+BIVPnI#&!L5mX!BoXwV1tVgEnifoy^BK zHtL0fzdaOJsKQsPNY7q}0Y4DvP*DFtcUM^F8^6tgsYXwK2Br&KIE&0Ijv?!f0H2bX z3hS~Iy_VHlwrAKS2g@9L2Jr>UUgj-3la-IomcdrR!@r-sW@mL(B!1n7%HrTBc zqDl3FzH(SNiQzF<@XB_XI|t0LD$)ekI0S1JoqhGhaz}F=4n?}ddl#b%jJ}5|rUx^Y zE{iBFB*3Va~qV;jR|Fl_Ni=q3Erh5t(Ij#$ij4;b!z!Q%|(;^ZqRP@-Bte z0LInHte!8~1F;#vWFnYlV&GvAY?DgwlO< z;|z#)d|QHC_J{EnYaubAPbu+)&fU}+4Z0mf_Hki41x;t3eHNa`OkOrls4}r0Nx2iAmBg zbC@w#11>=^A5(qrXpYuhH$zO2pc6eeqQD{OfvQqiEPri#Pg$5*t(-@?*NSS+vB)&W7z? zUc6H>nYU30tNiXOsFbJ5<$opBa#(}>CzWzZZ}bcG%C%pylYDpl(S4&esg?ho#{TB1 zSdsinO6B7O!rHTAYC9!AZKTyvnv?q{{-OT0KTonri(FdM)ulnx1|M1)w%?lAOCipc ztglBct`#Ef_ZE%C1H)-HE7WU8reHrljN8*P3K*ZVN=m5reU!_^3vF~6bxx78+qY_sfea* zqDunJlL^)UId$X&UPaw&8%m@`lCft$DoveZOE8&9Q*Gy1P~fUqqU}sK8V7N*)RDs$ z_x9i(|E2$>b|f<9RI@mvAf0KNHQG7u!PU1~D zu$#k0Cz$_kL@@}36uUas(?Elvw2b*x(9(!Wm9uQU1Fd0>7iakfeqfN$kGO>Xkc(YK zwfhNQ_^bP(d9*MwJDoo;-8>Ev%!sey{t&HB(b6ZE9yfK#xYHTuku%3d{(%O%P`b#KQ`%+sJC^b%(w)a}mZ7VUQ0ynvvMMDOOeWFYo3!Rf z@}Cx;BsaGS`rrJgweh!;^_DzHM@XaQA=deTuBD!N*$k2$HBSK?9l1{E5S{7XEF>q zXKEkj!`zyQX)z;FwL|oZ?LECxyU~I`I9@P;C2Pl41l@(lD}On-7?J=K9<|YGSez0% z5J9L!wdK``4*Yct7Re1MA4IMaWgahjiPJ;4ySS=EFJ1vYW;D7G{i2d{B;6OreFOR7 z?VXb($5GjUAQMcm4|2jJ>dGy)*38u_Xv9{-0%e-)E&3K$h-d7q{yTd5?^Tf|1ZpEX zzH#Wa1AkUSFDP~yng-ks?i`y+#j5;(;zTZPXC?C?9zRlka6Cj1!dQhy`_ z1c9PxM}i47nOq6=)bb;d<|(S^>9BEmQ7mXjnz%^F)|tej!urE5%}& zJ-KQ5IVG&~`dn2?0c*>VaYgJjaV?Mg18aCLZ%0jKzD~*YN^Vf1p^ctL(jPtYbBFJr zKls4?2Ve2v?91o2`ykE31zuW}g*@_0N^fc?_bdOP6tZ5m7`eTuLBRnPc9W8?DEX$6 z1toVYSyb|JlK#+xlq8>384J@{y)~%PCghNIRGBOHqY3Y1yMfTR_4*biFHrI}HRv~# zyjRI9_3U0<33@V1!4`$K4RkVaD7bcN=^io^+8-xz(Z8ocVVVDs`}_$1i5!3*u%}q7 zREiDEKV=}w3E=7a)Bz&4>kc&e^wxcD;#-6cXD8&Emx9bPSb$^$oKS_G~_^o?t MA=jPuRPXEm58zN!Q2+n{ literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/decorators.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/decorators.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cda7124e7dcf620b5c91174cb81a65cd7e80c27 GIT binary patch literal 17060 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4af95cb0f8b3a15103b6d307f8a168720d6a3250 GIT binary patch literal 10217 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 N_2&8J(Pj;|^S|d`D&PPB literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7350446cb57bc1185968778a4c722df11907389f GIT binary patch literal 9433 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 DNo_dV literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bd68f7944e66ccba8c780f04e7b6b7fc5a8ae0a GIT binary patch literal 2445 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a8213777bef65c302589419585cfe8d9e780273 GIT binary patch literal 17019 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 DbkreY literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f360d0c1a544ed048df215cf8b40e8f7155aab27 GIT binary patch literal 15169 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%0D0+oeDMoux>FqFpqkme{_yykWLEgA;${LxR9ZdHE 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 d%=%gF^kdJX-%klr*3WCRQvOqh)1|E*{$E;+r= 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[t.Any]) -> 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[t.Any], 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[t.Any], 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.Any]) -> 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.Any]) -> 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[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], 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[t.Any], + 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[t.Any], + 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[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """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: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # 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[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], 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: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + 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[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = 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( # noqa: F811 + 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 sys.getfilesystemencoding() + + 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[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + 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/testclient/.venv/lib/python3.9/site-packages/click/_termui_impl.py b/testclient/.venv/lib/python3.9/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +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 io import StringIO +from types import TracebackType + +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: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = 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: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + 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() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + 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/testclient/.venv/lib/python3.9/site-packages/click/_textwrap.py b/testclient/.venv/lib/python3.9/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +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/testclient/.venv/lib/python3.9/site-packages/click/_winconsole.py b/testclient/.venv/lib/python3.9/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# 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/testclient/.venv/lib/python3.9/site-packages/click/core.py b/testclient/.venv/lib/python3.9/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/core.py @@ -0,0 +1,3042 @@ +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 update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +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 the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. 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.MutableMapping[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] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + 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.MutableMapping[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: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + 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) + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """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 = t.cast("t.Callable[..., V]", 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.MutableMapping[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.MutableMapping[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'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 invocable 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. + """ + 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) as e: + echo(file=sys.stderr) + raise Abort() from e + 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.MutableMapping[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``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".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. + + :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. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[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 [] + 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. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + 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.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + 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: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(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 + ctx._opt_prefixes.update(parser._opt_prefixes) + 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. + :param attrs: Other command arguments described in :class:`Command`. + """ + + 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) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + 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 the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + 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 ``commands`` 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.MutableMapping[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.MutableMapping[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 + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], 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.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "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.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + 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 = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + 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. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + 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 latter 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, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = 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 + 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[t.Any]: + 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: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + 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: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :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. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. 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, None] = None, + 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: + if help: + help = inspect.cleandoc(help) + + 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 + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + 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: bool = 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 = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + 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] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + 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 t.cast(Option, param).flag_value + + 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) + + 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 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 constructor of :class:`Parameter`. + """ + + 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/testclient/.venv/lib/python3.9/site-packages/click/decorators.py b/testclient/.venv/lib/python3.9/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +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 + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """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: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """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: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + 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(new_func, f) + + return decorator # type: ignore[return-value] + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """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: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(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 # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + 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. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + 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`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """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`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], 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, cls: t.Optional[t.Type[Argument]] = None, **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. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **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. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **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( + 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/testclient/.venv/lib/python3.9/site-packages/click/exceptions.py b/testclient/.venv/lib/python3.9/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + 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[t.Any]] = 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: t.Optional["Command"] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = 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: str = format_filename(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: int = code diff --git a/testclient/.venv/lib/python3.9/site-packages/click/formatting.py b/testclient/.venv/lib/python3.9/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +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/testclient/.venv/lib/python3.9/site-packages/click/globals.py b/testclient/.venv/lib/python3.9/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/globals.py @@ -0,0 +1,68 @@ +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/testclient/.venv/lib/python3.9/site-packages/click/parser.py b/testclient/.venv/lib/python3.9/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +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: t.Set[str] = 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: t.Any, 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: bool = 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: bool = 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 recombine 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/testclient/.venv/lib/python3.9/site-packages/click/py.typed b/testclient/.venv/lib/python3.9/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/click/shell_completion.py b/testclient/.venv/lib/python3.9/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +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.MutableMapping[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: t.Any = value + self.type: str = type + self.help: t.Optional[str] = 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 +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + 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.MutableMapping[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("-", "_"), flags=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 + + @staticmethod + def _check_version() -> 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": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + 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}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """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 + + return 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 + # Will be None if expose_value is False. + value = ctx.params.get(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(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, 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 or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[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: + sub_ctx = ctx + + 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(ctx, 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(ctx, 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(ctx, 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/testclient/.venv/lib/python3.9/site-packages/click/termui.py b/testclient/.venv/lib/python3.9/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +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 + + 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) + is_empty = not value and not value2 + if value2 or is_empty: + 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 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 + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +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/testclient/.venv/lib/python3.9/site-packages/click/testing.py b/testclient/.venv/lib/python3.9/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/testing.py @@ -0,0 +1,479 @@ +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[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], 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(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: t.Mapping[str, t.Optional[str]] = 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[t.Any]]] = 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[t.Any]] = 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[t.Any]]] = 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[str]"]] = 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) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/testclient/.venv/lib/python3.9/site-packages/click/types.py b/testclient/.venv/lib/python3.9/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/types.py @@ -0,0 +1,1089 @@ +import os +import stat +import sys +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 open_stream +from .exceptions import BadParameter +from .utils import format_filename +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] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": 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: str = 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 = sys.getfilesystemencoding() + 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: t.Sequence[str] = 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[t.Any]] + + 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: t.ClassVar[str] = 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.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + 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"'{format_filename(value)}': {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")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +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 readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :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.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = 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[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + 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: str = _("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, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + 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=format_filename(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=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(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=format_filename(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=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(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[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [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/testclient/.venv/lib/python3.9/site-packages/click/utils.py b/testclient/.venv/lib/python3.9/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +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 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 + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + 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: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + 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[t.Any]: + """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: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + 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[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + 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() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # 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[t.Any]: + """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[t.Any], 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[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :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) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return 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 effect 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[t.Any]) -> 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: t.Optional[ModuleType] = None +) -> 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 _main is None: + _main = sys.modules["__main__"] + + 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. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {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 is 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. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. 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) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/testclient/.venv/lib/python3.9/site-packages/easy_install.py b/testclient/.venv/lib/python3.9/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/easy_install.py @@ -0,0 +1,5 @@ +"""Run the EasyInstall command""" + +if __name__ == '__main__': + from setuptools.command.easy_install import main + main() diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/LICENSE.rst b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +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/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/METADATA new file mode 100644 index 0000000..b802e93 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 3.0.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +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-Dist: Werkzeug>=3.0.0 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.1.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.6.2 +Requires-Dist: importlib-metadata>=3.6.0; python_version < '3.10' +Requires-Dist: asgiref>=3.2 ; extra == "async" +Requires-Dist: python-dotenv ; extra == "dotenv" +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/ +Project-URL: Source Code, https://github.com/pallets/flask/ +Provides-Extra: async +Provides-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/ +- Chat: https://discord.gg/pallets + diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/RECORD new file mode 100644 index 0000000..3caab25 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=tZZhGd53yZU2v1UkxJ3O8_b98JB1ntNzHr7tJIUnGwE,261 +flask-3.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.0.0.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.0.0.dist-info/METADATA,sha256=02XP69VTiwn5blcRgHcyuSQ2cLTuJFV8FXw2x4QnxKo,3588 +flask-3.0.0.dist-info/RECORD,, +flask-3.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.0.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +flask-3.0.0.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40 +flask/__init__.py,sha256=6xMqdVA0FIQ2U1KVaGX3lzNCdXPzoHPaa0hvQCNcfSk,2625 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-39.pyc,, +flask/__pycache__/__main__.cpython-39.pyc,, +flask/__pycache__/app.cpython-39.pyc,, +flask/__pycache__/blueprints.cpython-39.pyc,, +flask/__pycache__/cli.cpython-39.pyc,, +flask/__pycache__/config.cpython-39.pyc,, +flask/__pycache__/ctx.cpython-39.pyc,, +flask/__pycache__/debughelpers.cpython-39.pyc,, +flask/__pycache__/globals.cpython-39.pyc,, +flask/__pycache__/helpers.cpython-39.pyc,, +flask/__pycache__/logging.cpython-39.pyc,, +flask/__pycache__/sessions.cpython-39.pyc,, +flask/__pycache__/signals.cpython-39.pyc,, +flask/__pycache__/templating.cpython-39.pyc,, +flask/__pycache__/testing.cpython-39.pyc,, +flask/__pycache__/typing.cpython-39.pyc,, +flask/__pycache__/views.cpython-39.pyc,, +flask/__pycache__/wrappers.cpython-39.pyc,, +flask/app.py,sha256=voUkc9xk9B039AhVrU21GDpsQ6wqrr-NobqLx8fURfQ,59201 +flask/blueprints.py,sha256=zO8bLO9Xy1aVD92bDmzihutjVEXf8xdDaVfiy7c--Ck,3129 +flask/cli.py,sha256=PDwZCfPagi5GUzb-D6dEN7y20gWiVAg3ejRnxBKNHPA,33821 +flask/config.py,sha256=YZSZ-xpFj1iW1B1Kj1iDhpc5s7pHncloiRLqXhsU7Hs,12856 +flask/ctx.py,sha256=x2kGzUXtPzVyi2YSKrU_PV1AvtxTmh2iRdriJRTSPGM,14841 +flask/debughelpers.py,sha256=WKzD2FNTSimNSwCJVLr9_fFo1f2VlTWB5EZ6lmR5bwE,5548 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=ynEoMB7fdF5Y1P-ngxMjZDZWfrJ4St-9OGZZsTcUwx8,22992 +flask/json/__init__.py,sha256=pdtpoK2b0b1u7Sxbx3feM7VWhsI20l1yGAvbYWxaxvc,5572 +flask/json/__pycache__/__init__.cpython-39.pyc,, +flask/json/__pycache__/provider.cpython-39.pyc,, +flask/json/__pycache__/tag.cpython-39.pyc,, +flask/json/provider.py,sha256=VBKSK75t3OsTvZ3N10B3Fsu7-NdpfrGYcl41goQJ3q8,7640 +flask/json/tag.py,sha256=ihb7QWrNEr0YC3KD4TolZbftgSPCuLk7FAvK49huYC0,8871 +flask/logging.py,sha256=VcdJgW4Axm5l_-7vXLQjRTL0eckaMks7Ya_HaoDm0wg,2330 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-39.pyc,, +flask/sansio/__pycache__/blueprints.cpython-39.pyc,, +flask/sansio/__pycache__/scaffold.cpython-39.pyc,, +flask/sansio/app.py,sha256=nZWCFMOW8qK95Ck9UvDzxvswQr-coLJhIFaa_OVobCc,37977 +flask/sansio/blueprints.py,sha256=caskVI1Zf3mM5msevK5-tWy3VqX_A8mlB0KGNyRx5_0,24319 +flask/sansio/scaffold.py,sha256=-Cus0cVS4PmLof4qLvfjSQzk4AKsLqPR6LBpv6ALw3Y,30580 +flask/sessions.py,sha256=rFH2QKXG24dEazkKGxAHqUpAUh_30hDHrddhVYgAcY0,14169 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=EtL8CE5z2aefdR1I-TWYVNg0cSuXBqz_lvOGKeggktk,7538 +flask/testing.py,sha256=h7AinggrMgGzKlDN66VfB0JjWW4Z1U_OD6FyjqBNiYM,10017 +flask/typing.py,sha256=2pGlhSaZqJVJOoh-QdH-20QVzl2r-zLXyP8otXfCCs4,3156 +flask/views.py,sha256=V5hOGZLx0Bn99QGcM6mh5x_uM-MypVT0-RysEFU84jc,6789 +flask/wrappers.py,sha256=PhMp3teK3SnEmIdog59cO_DHiZ9Btn0qI1EifrTdwP8,5709 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/REQUESTED b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/entry_points.txt b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask-3.0.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__init__.py b/testclient/.venv/lib/python3.9/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from . import json as json +from .app import Flask as Flask +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 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 abort as abort +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 redirect as redirect +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 template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string +from .templating import stream_template as stream_template +from .templating import stream_template_string as stream_template_string +from .wrappers import Request as Request +from .wrappers import Response as Response + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.1. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") + + raise AttributeError(name) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__main__.py b/testclient/.venv/lib/python3.9/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab5f67f57dfca7d343806033bbb496c745fbdc2f GIT binary patch literal 2299 zcmb`IOLH4V6oqF-kCFV6pYq!tKV><#l*ECm07WGPSZ0wxQPrENk-8;K-1DHPWydLJ z18iBbWdTe6((EW!`3t~;b30Pva<<5oqpwf5x^LgU-3g|rCoFs_f9{IMpuebb^HV_M zk!9K0zqVy@i`&wQY-ZcUj&xXo7kE(?qY^8@EAWymM=o;>mt`fYvZ`TMPDGPz(r`si zMbm8Ba1}hmW(-e&YpiB?5eGAd4|_y zDcWH>hS%k8w8!=gZ-DpNzTr*q0Xs0f1wLelhPS~D)-ddWkJypn9dMI14ex@F*|Fh0 z@Evx?@ILs2oftllr%{Ww3?G8qtZldfzRT_!J_6rk_Y61X{pgIH89oL-U=P4|_z6G# z)!{AP{;9}5;?8rcdG`&~MbpkFgE&rfpu;52p1wg@kXd|@B{9BBU&|mn2UNe1Ly@X5 z)@YQUBylh7gXV*t7RuLyF!Po8ekd~P-{>akmERpIC1O4H{caL#@sj#$gCO&RG`(Rh zkTsg&hCMl+1f%goo7QySFXUz-%Mdu+QqV~hOUfhe*RxgevW1P_(y(!AA7#N6+Nk~$XNHdGS%ZwDmm%Gg?o zAo4FmJ-D$8cc`S_OB6=9l-RIGgXgfPQBM3cNmIdZo5O5i%;g&+wFqzueV-?nwC#FF zU}6e7=5!FFZJ}qWpS;h#c-a*x9Wgp;qg;%018a7i`Cb@@qeW|DFVlh2CXU6ibt{Ou z@v@^Z%wYWfc1ZPGmY*T_F`a1*M2Qt4(IHWOY?1lWtf4>jr$D|w0X8ex>8 z>SfqzMM4KW&_Qby$k8s9{`qdRfypu)7;n9C5E(K%ffMbXOK~A2Gq>fu>E`nvPL)?K z0~O8(U<-{gB;|DTRWiuGzs!O~iK90l9}H4U!`WN<(4m6kC(LV-iZ6 gInx{Ri5dJ^l<=VxpVQUIo#0B<0J(*OVf literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__main__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/__main__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cf6aa60d8601d5a8944d6beca1531cad12608b8 GIT binary patch literal 234 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb34be3dea8246a6b9ecdbddda59ef098edb7f89 GIT binary patch literal 3396 zcmcInO>Z2>5uKS`E{DsdMB1?u+X>R(A<_ckP*ISB7J*?(rW7F#Wr%W+jA6|7PWN($ znlE+tkRn0*5bBzL-~iGwe`#((PW}tIB(HjRXP2^kOGZ?)KdY*%UcGAajg78@&;RGP zyw`J_f6-w1Yh&=KpgdME4#Y(!G`Jr$7 zopdehhF#lVP1mztxMBM~`q#p1t|QyW*VQpjt)-jUR=DLlj~vkz>#rQKE;lY)VNZC6 zPQUj(S=M*!b)M&i;U+0^eSqwai5{Rz((xM9J6` z>Wt3aPb*ofBsa9D85~Mem4}coG3`H#|Vc4wS z_iBHfq%!B3tUC$@syy~^VE(nxq5luapgZUo=hzkQht4(C1a>>j@vf(h}FC%^= zheHxQ7j&DG_s^hY%&XMg zhK@wD=~Xow2yXabc({M?S@iJn=ljtg_x>F1J=%{x+kd$C<>$|ajH27fA^YMYA16nZ zvN&PIcrN4Hamw}cU~3(U*-w#t z2Ej9zyyZ+7G4~79HCOxfT{bBy^=>^}2&?5zaIeu4e)yvSJ?M87Wmw&r#tc zi9`qGS^dG0G%$%M2e^-BX|e??G&t6Awz{70w!N;~^Uiz0(*3J@;k@=P+&Atw$ad3yy<$38Uwwl)VuQc6Y`*V-EGfn(i9BVL z?}T2$vLH+Y+9yb2TtHvVtpPViff|T_<7ix@LMmj?9#cgHL=r$NQ)IMi0j=aw0*EMx z1tm1Gw`jJixnWmjRw|8%EQZ7uSC?k$prsL{rC9>@|1nb*2>$JYvCi+_yyA(QEUUC( zBjlts3qQ{HkUImEmDL$2`hK`I;X0bHTW{9Ar&UfYv9DC2)K3s+)j?Ccrf$a^fcOBT zaO29MeoJlAMuNV&K@Guv+Psfmy=f6SKLbN)KgE-&PfNnU%%L2KMZKo4p+X@*D zE$Lzoi*y|9iE1gJ#enZ~LPdewNYThSP0VDlKoe-0h-qh(7V&dX@|1NJ>qN_RgcJlM zDw@0H*7m~o?LOm3+Cig*j?o9E%LDmR#z<5htE4oy#sN9#R=>YcGAOy?S>x~l`vSR0 zjwUb6^`X;5;EJ9fL?dXHXMzbN17^cI_v^H1!DF-*uqQbR;Vf{=sZMv$Raq9wkXOO) ziJ%t6mT?4OTWzyji0-yBrNeMb^Bhl@U{QUop78pioo_Czd=k9z>@Q#JM-P6#|KJag4<6P2 nsX`KwEGn+=x=8K+Zt8?j=&uS*G~7es_EENbuKnkA++ORytZl`< literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..020e215023eb7e9ae669934f74a9b663dc233e6a GIT binary patch literal 26795 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/ctx.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/ctx.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9180c09f997ccd41eb061f2b1da0a1e61406d59e GIT binary patch literal 14536 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94de1536ac1b64ad0dd913e7d75d58d660994de5 GIT binary patch literal 21246 zcmd6P+ix6KnqO6Svw0D9m*vaYp0YI-*|yla*fX>4l{MDY)>x(#iN3W*=`MB^$)dWu zIH#&fkwY1qk&|_>I|=d-AV3sATI6Nkg8UhI%2N>3TacFwux|m9V6uSn`+et}>S~gb zJxG8oB{r+;@}1jv`F)pD{{H<_4t^&7%bVeU{K|3uE58(f_TkHij^idrN{$maf!lR@ zZqs#nTnLo8$Of?oRY3niFzwr90W1YEH@V7>@Tf_Zb?~&HcEy z+C9)a*gPcX#=FzK!_6Z&o(LwpM|;Pb$K-el$1gNrkmG$gKHfYo$J01|vH7AL@5k{= z&6ni(K=k@`<)QgAGyJi;OMuNrWbsT z?}vgH9+iUQ!HeIHHQxwc3SJIg!S^2pui}n3gV%!BgCFC&7rcS*CxVjs_vWKYa3c7L z{Cf*`od`}o8V_cI*>9`Op9H_c_qT(0f>Xg9?yCoZv}Vd-1|WT=l(o6k0(zC{}8?WMet#85$7%imvL?ePhAPFqG#8F zkMP`V&bCQ^@&t0Q?ml!e7v-&g z`B9j98!KVD5-KkU7YEB;FAhR4S&0YTz*`KxufF{hj`mqH{OsXDzE$9 z-#h9@IQhq=(<^Z=Jgwp|3Fp?64hD!Xi*Y*FiTkOFyK_Cij~Q2|Q!HDj8=+7I? zx*IK?UfWDp;{Ln!_fIEL8qTfxoqM=BInDLCcX}o4f+>>v+GchD-Dt@qa_yGcc2dEI zQ<-+vYxuiRD`n$m*y;#Qbhu{r2m0!n>*sE}$+2zcjI{$flk2PCR z11#Aok1Yrpc0lOXr!+^b`O5FvmK)v|D}L&wv8S2WiQ856aLA z<%h71+huUmr2kiF__kJF9z`R(pK3;e-opYxPxNKQlu<_%-6ZuD6+x^of&JD)rB`ra z1=sOEi2L9R=#Ow|De6GFI-6htKY>Q`{C+@===t|TFG@Y|Wa4$Bdtn!PC5H0o!~^t0 z2|M+|UaU58kAE-mHllRJTl53mxS^sHJnemP=cDUhFA9QgxZ$IZbx-S=c%z?0P-^H( zN)C*cgxqF4@NgSMhOD2Y=u!^@v4cyny5Q%0$-Isj4A1X$*h!>?-(PvKDqCu&*6Z{P%A? z{=QB39_&$E0<#A7x(8t(`0;}v3>ppZO#OXX;6ILu>aCTt3Ku`C-h)^#Ct6=ZE9O5$ z2-KNS-EKmI@SU^mM6i|r*8OMhgHq~1+Y#@$#Cb>e=oSpin|Mso8W2qYhbfOI#CnL~ zm<+;BEC%6MxS;L2d%)c~xd*xW`EJ|+8(pa94{hyB>mOO|uMUGm2fz6baRB|AcR7M@ zaF9BW-M}Go+lJ>dfH6yf`HPi2z}n`^o|Y7B(4N*|UH*u%pYb&?cVVIY0P;CpJ($%?VaJDh6e;C`(#Cu6rhq)x!veyymcxq|SK%cAZw|DM zHJTah;CBaj0%lo=foovApbrQsqCR@#=LXpjq04cN&>MYE!tN5hkrd3>!H{6zRn)o1 zQ3y4RBJVy(MX4YHv|;&AxEYKLVWp1~^^+8%_2MN13fMUPEKLp8n3j4Y>ULoTFiE?* zwy_d{)p-*Q31*0M0q%t-X**&N!Sy9A3Eeophn5L>FbfnK+lmi|iBDq;zSoD)=!Gbv z04jXAV&VOr#??$OTu&@rD-C;VU3hD=Gjel%CGB-*P61iOAG~+YXyLC+pZoC!*D@i4 ztPmIFJ^O(TYpCFTAdqed9ez+(hWLZ#-!f0#aNyT7U(VfvL(y3QXh~-7qKz3k82YQ$|sB4x9t3m8z0Q7PfX zjt_POXA76*0sxK!lL5GP$bX^XcO#a#dyj$cl1t6?phPgcH0Ww_yKpW!l7PHjK)`=xzDhOUsMLmO$SG$?P4wm|y2sJA+OqFjL5LWE+0hob(v zXbs^dXtiPk^g1vAsGnyw#bvf#0Bhz$$y)$J@SgAO(r^x8+|vOV-YB=dAl=V|yrNsH zXux1T33##tcDh;}DD@;Ocf)?Re`M?cV`2zLU3qmDkN+e5CK3>Sy8;V3O)JXtzprHD zEx+GcA%bXeZsPz42_kyEFq>?_ehW8bWq_QmDSW`WpT~@C?PG+^e5s9R6HuXRF)Wb+ zG;`E@{P-z9euj^%D(1@|QjUs0M53^<&NzNQp^2vLXDn_T{`a=KUD_^hR|5A@WqXYH z6lkmDKLV~W@DPjReRlf>#gePA3<%YSBdmL&MQeCow_o%!=`JB8Nkd`)7#LFGkscHi zoW3q2cQEZ1shtv&LkpP55}9Q$L@w(C)rFE#vo-I0kwMMr3y2Nf35DrWPfxWFqQ?(y z(1kteh$@w4O*k|?7vI!CQ1Cg)TG)eumGJr%K*aD<5t z_=qdk8KB~mW<1^^@Wz_Lg62e|u~~>Xoc5Zw?grax!7^Pn?9^aWvM881#6=jt5WCGN z<_XPm?Y3P#^mmkqo}VHSI|k_`$G3ajkzN@}zkXh#0vwf{vC&2}n-?3gb0^qEgEV$p z-$?Z)I53|QD;}d{?b#yXH5D$wz*zcVTFf10SES3Em9TCNoR^a}{K*FO&6cV+%Xng~ z?p-yq$;GCw>vRVQ-k^n?hUqq;QV{q2s9#5D5mG_~N+)9{=bzG~pz3lGd8S+8_*85p(HvQtL$!fysBZ;?AXZf~ry5WTa;5n5S^pjYRUg5fO|5A)$1tvt zco0g04M0|yoLnIzoC++MQ)st;;eW7rvhzW};JBO~YS#|b{Ia;r=j!M3M;M_bGwvb5 z6b4+?R*uuOhL}_A#ehAE5whYWFNWZgC`K&rnXR6wpFLxnUBI-o+eX7e07Sk+@PW61 zv5IT|TuR#I$DA2Lxg>FwL0B_>kuan@gz@?lNZXmguU#+VC45#<94C;Me*kQ05IQQ@In=pRuoT|VzEtTM)^56fi zR7-zUyyFjb7?P|E8QOX|h2Q!0B>=bECIrVAG|f~tT|5g%b%GHGs`acwFewhC4wRJH znEBx`J=n`MOCAnVM;+0oX&XM{?~ov)|41VhlzzvcaM{09!u^6{VVG>bYY1|*XJ?ic zs#@|@P! z))#FM)iv7Si+fw)V7Wd>qi#~qDVSawg>Gj|+a7IMh67CF5q%&CU3e1~CLPdCg}hjO zU|Se@#IBj9Z()unFo#lyPS>%RDGve(u3K3e6<+WpRJ9GJXt0e(DB@&fOIYKlJ+y=f z2*PULrz7kj*dC0bT`6eP+$;9G8~*0d80pCQ7iP9+5Ct$Py>@#@OwS20+%Ldy5F!52 z@r|;GlOj&ardu0Z0J}Pyig4To-j(0FQfk$`eUMM0&a5pI;1bGmVSG9;N1HJu?dz+EP5|NuL!m|5ppfTMq zAvm{vvMDreBfJmB{3hp2e1+2qc}?mcFD%@;YQMH~o)U~998uu7{|h-I!W#-2Lu$E{ zYC)5vcBr5MC0O&P$XQ`DLdBXYBWceUp8Vlc5CXXnmUFrU`g4 z5E=P`OFP(lhvgA5fmzY=a=7BYR8l;L(E5HG9cmE=XOm=%2w}QViw1Z&|KTx3L#zjF zSc*jCYDvcyS1a2{I5NoYe~BA!AjJx$g(y%*#ojD%lf_ImoV9HtP{QPu&eTE4F=}Sx z$|i=VecharL|^C*fD>*>VqP>cf-kT=47^b#+whA3T^+&5TjVGMufa5RquuHN^(YCQ zw1=+MFc2V#G{k^RC;;q`!~=v%grOTA18MK9M*US^VfSA zHzT(fvVA79rMo=yMXb63u0BHo&H!r4B_nfrdmL*+;4zOZD7Kf2kK{eueY@onKCWj6 zmQqiMP(bO&I7UedS{x>2{#z&_XigW0pH)%F0x%AXa|x`fz_dF7S$4emz;M1$nB^qG z_(#<>JeG}{lANqU>;-8<LzSn(mC$3^Q6So`(vc%5ez6j zfeG10dMa?wBYDHp9HivOR;vgQlvl@z!+^pnNXZb1Rs4U2K2cS#(7Oj3k}@Hy=9rQI zdJ#{b(t!An0&nxOLf)KVdE-G5nW3&ICm<|_iwOKn4U)tI@E9sc5H^;yD8BIqpbm9P zmVw{w%1XHj?hpfG5Ev)cv;*WW9ZjrJ7%J7F|8l1OuF!=9we7SPeTX8+H+*NvY8EO? z2K0w%c|_q`s``HWEw{FYfCO=g>#UQc{Xp9{bg%Hk&>4!q;vV9}%v{1W%@{f}08!LL ztOK}*sJpPUo(DaF1v2^&&x!|PpOi1CLBM$y7TD8;B7?mHy`el3;q9`@()QP+^ON0plovLNXiItDQ84LF$@3xOLDJ?y$ZGqrSWKMi@A(5M{JUM+|@6q=^F}Osa;!MXvYlpp=%@9SARs zYXCLTFD*N~nmR4_J4anfE9sb2^RV7$0@-ckw{hJ`K4+!Rw@@lq9A>%HuEIDsdn0v6m${t)EAvT}Uv2C>iJWj!73MiK$C;qTRNoX{2VXn@F;_ zi<%H%xvZ!dDh99fF+p&9pfPJ#@s#aQjjoaQh71tDChIGm-Zic02t)AD0uqxS@&_}R zYbsukq%IGkX_HAU+(Ddcn>S2^C@cI=dVfRl>qO1vog5=XYMNcqznz0(aU#S~r+acH3mBo3#gg0* zRs+Z*?MU_${A0SO7Ytn=4$1HUW8V$LxEt-$YrrLleCpaz63|w_;8DbqgxL2Pz+Id@ zjHMOr;NE2NINBb=-RVA}KL45wu~3&W=fMm`SIY4X2L8 zx={~7;G%SrM{lCG#7y}v8!0CWM2rriUKYWo?_kx1W`cS3ODNY4^nd=tV}iS*RK3$U zK$V31GD?QlS@=?#m+X|715}&1OTTy3E!?CHi&O$lobUR*#lXLifYg7-HD~MOUU+9% z1!Nx>=?D8joOp-*pmAD8Pwt|46R6L5+4&cxUsvc&>5LiuITVnV>Sr?d{!Sw|b)GW- z9I|#{fG(*8+`NTKtKAT+*d_Z2qL`co^(jASoU`&;yp~l+GplNe0pvwI#L+V$H;RLK zo9ARsj_uXjO>{<=y8M{sEyvv|Ozv^~9&pvycy#L!s>sEIbfZ~P}p_)~p9+#qJp_WY!iMe{vqdt4~atpZ?NGu=^ zx}j<7sKsVJub9axRxJylsr+5Fs@iC6>-9LP-$FNUu&QL6I0c_+{ZiCNiO=<$TT>>- zi3?k=*=-NFMF-E8P#(=7nxsSDT8AiXJR08*Ih(&CGN(X@78LQ*)(TKikvYe z*+dVuMvP@=`~8G|7HT$FTaoRj?v-k6x{TN^5o2S4t~<&q@bZ?k{lIT&3$7e$FT+6n zijyhaAvN3h#vdLNDqf~2y^RB+snyaFB6ZyNKz^`!*X^h?H7-IIClwS{WDJD6gz z;@0D*y7Hx%ovMm3LhlPODtrMamLdhcV{Igqo5U{6Lma;(T!qG*RMD7FIpS04iVmXE zCh82D32yabknAAfk5VaJW98ZKsx+WCDrmfcnI*^ zE+)CAU40T7CNoFt$TEEyA({Z_-m<%7Ci6c&;_B06u3tL(GU*$^A4|6npsk|@LG z__QhD7USQLIC!HS#q~>@sFAsT)B1<=QXI{~2tEJoJPIWQFrgO!Pri7fdPjmxG*MBK zAjvGnsYceQkszr^Y-d6ZU7S9F_|V-P8b0_;VQSpj2%H|pMJ zfCa|6)$$0?+|uD{ga9ProA^sCBbE|)d6xe2oB_w^njVNO3a0=Q;-e*Q9|8r#ScqbA z=B1Qf*V5At69~22qF&4{BtfD$hqwo~*D$d+OyQzk3|mTnBu!#j2oZX&N;-$84IM5o zZ?AhJwa^-DBMrdLFhH$GrBKVcCJ{R{{pB2`hMi*TTDJ`ZkY0n(-V=-`)6i~@YFPxT zG(OixJ4K{S+A-tBig1SI)G!Fn$+H1sG97D51y|cm1!P%>ATm_~t2rAsL}=#L02ETP zs!8W&EF}Vw*!yyW>)dU-{f|rcVHFg;#>^po+D5JYF4h>28_~=|? zaXE`cC9${2)xA$q6O?y?{;~YY$(&8m4InXtpoX$k5PIHAd%vYHZ7FWoYNtt1f7#=-# zo4k_frD>X#B;Za+i1s?s5{TvFA5P2_o%xbV0iM-$U0Q+d8g#+THN2~`!H)7{O`n8r z6jS?PBwbGl!G%%aE}Oh<>vWsy$hvpiR{pT~}i@mWiTy z@9KiToX5tva#r+mBViiJyHl`xb1IG)Q}bU|c_d7XdBGT97}1J@avBS)#p^Q&vheUTiREhW&0F4Hj8L0?U>i zpqimP5)$P^iyebHXH@Sp@1DD?9cE~A;WPLz?e^MW5j9%WsksKv2|=KSH}>N>X%kOl zZcQalk&k#4Gyfd7^ISbI;6TeGLIJA4pIsl7;WAj{-E!b2Xq0T-9@Zu1&ZSI0?k*y| z56u2fW2LNk&SwEe-g2;1>&6Y@yHZYCdsE>w*j3ZC%<^7J1#sKl%D()RHtLj!Wb0Q@F^xzhq++u@!3K_M&sV}1h0-gUrUbr=)LPji;R>pnAV^Fmr>OG$|i|M`rs9OLW zy?&F4c*EODr@~DpTvH%)v25B=}{5TRZVt{^vz=&eqT7 zlcI5(78V4SWaEtQZ8s)?aVA}4M$N`%*D3T$1e&-9>81EXC zKRXWy3berunMid&3BkR&c<1u<>sBnuYBzwD`g3Q+aKM0a-$*_U3{T+lV$_YWn(}-B z!VSD^E4WHAGMpOtq`4w4YQMj#xE!03DTl2p?q6d zJ+x-Re%hu=SJorz0r0E9*EJ}GLSf}I^z#oL_%j~o91J~F77D^naJcLSIzV{Hq2#02 z$Pb$PxeXVhlKHA<~WoknwPM zMU@8-=nspYbT$=!sPWHfl93J@^x-R*w;ND04XD?Aq)QVZKzTQ4OEAEKjko)R0G)&- zz&eWio1Qz5Kg|h}aj}L&gF%q7b85Bi8Zm7-f!qp?)Kx-J4&T&ZOG3#M1nAhBB-UwH z7p-1qtpJrN;$=RB9A)!2>225V~HQj{9uHqR?Q}CrBpU1MSR&LErQ?IPsKJVlpvU`1e06PvyR?!v#f+uouiNsxBvUzb~s0 zW*4HD4DZ^XG7ea>Cecd|2Rc5*1piWrF)Bu?bWNFwO1b{OLu~jC-CzT(pAj|yq^6l1 ziA;cf3(`P^Jtrw3)Bx&tS!i9zh51k_2xS-eo2QWkW7W>-^BhWpoO|KT;r1JdC917W zxQ-&Ci(5vwgqvu-UaOG^$!yMOY?nW58mx$j=+`r!-MVq};+595n>Vgpy*-0?B3nm< zX#_(uXfQ%0-{+)lIXsOJjyYU4SXuC=#1q6=m>egjGVa1C4Y#DSv@YrhQ4R^AE^L<4 z(;y+A#Ln!na!=ZT4XZQU(^|#e5W;UEp;Od?mc{9U&Ew+aVL0P22<(7!;{)bL@gRXY zk&qN&izXz#yoY6x_Z9#h6|7v&az^S*#ApeTxh_x(?6T}=690!AS42{wQ|=?4&)%S# z4sIT{W?;P9-Uu?I!s4d1=M*Z=$LTe0HN#6?2;5Bj)}gi$5aUeSuY_|cR1tdydtqw( zU{smM37|H)9{H;7h_~c%7VwJQw}K!RL+3Ko5g$#s)}y|XSpWlY;y6sr41L7J3iR_f z;rH0i+85B6G1(%)i}}Vc5EaXezt0glSV`_@AHud#$HYv<4)2N`HAXd8#m`i%MS}nT z0Pj%EYdeJW$qKZaitvGb_M)&ylz^yiB$Mv(t}Z`L@MARdp?Wx1f&SDRyG|l&^t9qm zKb7-Hg6-39ypVcDoeO{t&wp4|!M)^{nG5(^98lMy;EH?cnObuPuDXD%07|Q{Q~tuX zyNbP7at?)8kH=Yl^>~73pCG$*$Ju%{om`!IyicCD^%-BL)4z4`CYDz!PP#vxUMg*- z_H8T=%3nGCi8IjVs|OySj7#b{{yH6deDDc!Pki4>P)56dvt53CNN862KT8jD%eE^$ z-A3vU?{7K6{$am=`9Xzy#gOCr&*{;ivhDoqQZV*!%6t!i^wjp(^tM*r`rB(PHzMcf zQlfJi=DkHg96F$zKffFsMA9 z3zK19Xbs9A2vFHG)~wM#yQph2Y|56QeIr%SW&tv7@}?zg%ZLFHv{%tOG>0}j^C&yg znXy(T)qhrqw$9C??#-$RNuAgc2*hLKHaf&86AA^rt^Z)$LS}MSpmCVQFd&cjo7+0D zOj@PmHuLh873|{Hif*WTb-qIDAB_SFnHj8sB^{;EXxQNmvI#~^?Ipv;0=@iBnlwjM-^dPERt`i zD@Ob2N;atng;!r?6=JV!QdWb0RyH;C+p~Sw<;^qV#Aj7P2fQkw3UJ=p2-F&BPqkV` zR$J-{o1Mi6-u2Mu#WK2v+AdI4Tl_x3wPOc%sDo@j@qV5yJx#@M1`jw>)1_D4<7K|r zffZeckP5Ai;RtVem@ZG??GMxVCQ$Ba^=V~F{RN&uN}svkB-#qMCZ(PWKn`hVywU-4 zuv?oD#WC+J+Ju?KZD$#JBtZEl>a$MbZCp-@WBryj=9?cvYaq|e9RTI|%&qIauH~$X za0v8a_CgCql~LNtw;@VCIh#_@`Kd&_kOTiM8p_Hr|2w8a{bO8M;RHzbvsA^vQOV7- zH5V@zQ-6*lyyHZw<7y>c)K(jxzc#ElTzA+4YG*>Jay!47|jC~s_X4GVgi~+^OJe~eIh02>LMQ`8de|T z1J%6UcoDH;{Q{6Fo|lZd)FiMRp*fyJ%fL2?t_Iw{@YSuWt;-)@z5L1b`Hz~1^L9)O zCs7AU;{(#3$j|ZZYw~6<{f>>Z{K_%{sqd8vK&eR3t_A%9F*d?7GQEX`5MyNuL9}$? zRa{t-Ha;{bk{j`658+FG%CR|9<=^swi6aLO-8}T3aWww;`p=!G$6q@3;*sOWPB>4G Yy?yAQc_E87EC0*;=GZ%j-k)&)4=o?n<^TWy literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/logging.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/logging.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d74e1eadd7aecd61ab9f2942b9a5e52aecba424 GIT binary patch literal 2525 zcmZuzU2oh(6rJ&YZ+7$5Rw@Y42sN}TC0?YWB34mUNRzfA3Y8i_EUMNM&v@5~*WS#` zCfz9QODh3CfEQGuR(|Xh@cS}(k`Vqb|RqrUjW-hu)HF!g5?$AJSMGcesyJ>qem)v zI{A}kCKV+Q#!?%2Tljo5I<6XbM?N(Vzk-Fbl4h)8AERBo9GI+QEv~}A5H)Ma9u@Q* z@|YNBuK)-f{xihi3}eB}K(b+?4dbJcN=7Q=Mlz{XqL?;H@*xXgh*n?_g}z1WvWEfV zEXP)7aD|$2--L&9nMFyTnS^=Xk?x1Cjio(rnI#ZK9fex5G5kDFPqeFz00Yl+>oy96 zog`!CCvgz=$4cT%vE(Rb9Y5k)cRUE*597Z3*n)e&V-ZOO!O?BVC+vvF26ng6a2qoK zWYZL~j4XPz=di(8Lo^nIkz|mk2z_(DyG@nB4mOz2%F$eY~8+^^f*pUh*{d*ny5Pro6Q9DsO1PIUVX@vBG%<#=^3Q7B21n9+>MzgjTH5qEn>T;a;YWQ*{)+ zJHGS%(k-r`!b928PuS8e3qIyJ#RFWrHB7`ff>{U0QfpvrORF+CLwyRUXaCDItoAxq zy8{D5PU#8RbIvH#oa`0U4djuA`)LVevy38cDks1;eFxU6riLpg6wibI1|+^OQ4J*9 z#QsK&1cqc(LFG8t5+ERmN5En!g%r8k?SNlyi+N?_+eOWiOyfeXAsudv>Ua>`&Ge^d z%~vx`u{*oCf&{aS{dNF^&Apyqv=VZ6-1o2yjH22=d z7hm58@4zOb8GO9Z{f%}5@T}G1inm1mKhg?En*$hlC6_k0D`1d z$Z!kWH!a!xEj!aXfPRpvNjfKFz{io9HWoC)``~FiB5MSz)3y}A#X6wEZP zlV-zd(1uf`bw_;!^VZe0-s=Tp_`u6vPoYAp5AX*6{E)P4CL_o=rKUT3B-Q@09QWbd z0^O{T-D#yCCA-kt+1I1F^WCG3-ui=$^)DZ8-|yBnk9C;1*dW*}RDodbiOfvtxk)y`cJX+FVZH~ AXaE2J literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcab39a14c82217c8188502412f869f7e0f9ecd4 GIT binary patch literal 13119 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 GfByhVgAUsO literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/templating.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/templating.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b642563223d409a628ad1142850ccc3d4da2d5d2 GIT binary patch literal 7014 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 ZRw}B$#`whK*yP>mYHgxcojz2X`VSSK-=F{h literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d058a186403545815d64e8f6bbef406dfd12d0f GIT binary patch literal 9468 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 bDc2xdCR!mYSWzQeo{Q0%&gER}S;Odm@K5w9 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57b7a25f1112f9e9fd4a1fd80cbbc880826e244c GIT binary patch literal 5398 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 af0rtdlxl;v-L%{AkG5m8`gd;a^!UFVN8~#I literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0ee608b94d7607bbd5356315a5aac6e1503ac79 GIT binary patch literal 5171 zcmai2TW=f372a7cDUzZjO1|aNxZ5B_O4p*C6ewK52$C2|;wDyFTdA8Zg5_#wNUpRO zW_BorglrVCfdGB%bATp&3(&{@j{bmsEBX}l9|XO9XZE6t<#dG|&d$!BIrE(}-#JI# z(o);N)%^R*;_hX`_y;|lyevGtX&5a1BRbsREHonKFh+edG@TlLYoQg@ow^>g!bY^< zGd2-{1@3V$^Xuy59_!qGe}U_gmpg)OEVd5VgHk8ADn-T#GI^7nt#`!54Yw ziNQOf`MBmR;CYEJ<9S)M@!aC(eWSPXEos|h*`gQ6iSksC#OXGk+i!dPp7?YsQiZ35 z<8JewNGF&izGeBB)?S*#B*C9bDPrY%lL;O#x#=Vfl)D>F#Y6@epLlAF7uLOLD12J> z5N+D{ zmrQThdd!?fjI8L9E?<2@Bb{nwjbG3sOBlJR=Un2K^~f^6LeF0qL&l%u&p+unEBpm+ z@)y4}_1F*iOBm~ZVOWN<3Mj8i+JpBuz_K$Iw#>n^lifYxD|?y>Ztu=)E{5JTRCW;C z?}T2u-?#01A`;QAkg2W4qHW`fJmrruU&MTp06N=?xqT3bL)(+1X#|kdep}DH14*fU zIQA4xPVMQ$_ELM(hv;;3@Mx%)C{!6>tvf?|mQ3wK4?YoD?$v)n|p^*D?F&*^}CEN-a z^$SlNRH8@~t;R$q2LTuOJ`C+-NNC!mS+F}*7=2KPA`=8L1}5Q@)*1po@I;V=x&s7`0w_7k=)omvbQlYYffe8N({`e@W5BUOO?EC>#sg3 zr?kj^F6@`iyIY_6VnRo)e7P!Gnq=6Fa6VKnr0pwY;1VXOiQF}w)T%yP4 z(7b^=w@TlqJZyYq+(8{{$Vv{~A81j`P_7&si*NoS+ z+mmf9Z?B@^QIIMjp>#}pDO|sZRdyAf&Z2mpc?ghFQKDV4%fyq4gnAW(mB{M^8mvn2 zX{UI$Wsfadi8;rz97jqo8Vg^fsV4&*Xf0XWO7D+!tTX`6rLTTpNK56};xL zKDG0I?f{|_Tcn+&&-4pK)I(1qvZ^sSdNi)!#Qq3}O1Uy36C9@wI1ZYKCTeDr^5hRN zkrcWA*iZQ(8K7F@eCIjgs{OuwfS?GJJDR!yhZvK;izY3Ovo+-`sCK-MSZF^G`=68Ge@*1gpb(Q>;W*dfb;Af28v|H z+*UPtP1W`+dF^wIKL)y=n-7eSf$l^0h{f&v_l9vJ$D3{U>e7bP>@u<(o$3&9l$7Mr zND>w6$S+?;uf*k58vQXf6#b>9dgAKe<4!3o7|dkL_-ixMoL?z z+HR3-q2F=cPp4j3yjgHvp7=1q0>sNjG%&M!qJqIIT3RkqvrO-s$PQssHItMnkQSXk@{8ilPRWxm8b#Pf7*w|#<1>DQH*Kl{&R&+_= zW7?^!o|DzI^1+DUK4e0p^j-#t>ZLBiweM^5^3_*lMX7FwyrxCaZuWlq-htM4g59wc%<1wHKx;wDWVvMBOODMOh=#~CydYT_^C|CHG47y_1i zZ|5!oU2&jL>u5nmy@S%@*Hh$k;8~<=x(4A%{Hn@7hLAiuVSUIgN+v28D6vF*@;#`p zyGs3_$A^?0M(hLWuT{*l-#_jodSrAZA2{#Lj8R&NK336o@pbs3au{@Sde_wZK~xjY>rF+&kG1 zgqsF)F(|64mJ*+-jj@VCc?AxfbqiNAHuwZm&iO z`utDl*FBrGrOl%F`SATaTkick&eo~IC$Fvv`};za8+mkIHJTf^C@_vUi2}buqpUn% zO>NLtQB{&`XC*JMDjj-OPOwBTIT^21*QvQd%{ny|sX8xuQ-PJ1w%>KS p)k;NyE-3(?*lQK@vgWP)KLc-&d+J1>V>ZnW!(Y)hSf|#V{SOxxk%0gJ literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/app.py b/testclient/.venv/lib/python3.9/site-packages/flask/app.py new file mode 100644 index 0000000..d710cb9 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/app.py @@ -0,0 +1,1478 @@ +from __future__ import annotations + +import os +import sys +import typing as t +import weakref +from collections.abc import Iterator as _abc_Iterator +from datetime import timedelta +from inspect import iscoroutinefunction +from itertools import chain +from types import TracebackType +from urllib.parse import quote as _url_quote + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.serving import is_running_from_reloader +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import typing as ft +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import send_from_directory +from .sansio.app import App +from .sansio.scaffold import _sentinel +from .sessions import SecureCookieSessionInterface +from .sessions import SessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + from .testing import FlaskClient + from .testing import FlaskCliRunner + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(App): + """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. + """ + + default_config = ImmutableDict( + { + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": 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", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + } + ) + + #: 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 session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_url_path=static_url_path, + static_folder=static_folder, + static_host=static_host, + host_matching=host_matching, + subdomain_matching=subdomain_matching, + template_folder=template_folder, + instance_path=instance_path, + instance_relative_config=instance_relative_config, + root_path=root_path, + ) + + # 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 + ) + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) + + 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) + + 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: + auto_reload = self.config["TEMPLATES_AUTO_RELOAD"] + + if auto_reload is None: + auto_reload = self.debug + + options["auto_reload"] = auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=self.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"] = self.json.dumps + return rv + + def create_url_adapter(self, request: Request | None) -> MapAdapter | None: + """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 raise_routing_exception(self, request: Request) -> t.NoReturn: + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + 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[str | None] = (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(self.ensure_sync(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 + + def run( + self, + host: str | None = None, + port: int | None = None, + debug: bool | None = 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. + + The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Ignore this call so that it doesn't start another server if + # the 'flask run' command is used. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + if not is_running_from_reloader(): + click.secho( + " * Ignoring a call to 'app.run()' that would block" + " the current 'flask' CLI command.\n" + " Only call 'app.run()' in an 'if __name__ ==" + ' "__main__"\' guard.', + fg="red", + ) + + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, env var overrides existing value + if "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.debug, self.name) + + 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 + 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 + + return cls(self, **kwargs) # type: ignore + + def handle_http_exception( + self, e: HTTPException + ) -> HTTPException | ft.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, request.blueprints) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + def handle_user_exception( + self, e: Exception + ) -> HTTPException | ft.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, request.blueprints) + + 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 :data:`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, _async_wrapper=self.ensure_sync, exception=e) + propagate = self.config["PROPAGATE_EXCEPTIONS"] + + if propagate is None: + propagate = self.testing or self.debug + + if propagate: + # 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: InternalServerError | ft.ResponseReturnValue + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error, request.blueprints) + + 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: (tuple[type, BaseException, TracebackType] | 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 dispatch_request(self) -> ft.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.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule: Rule = req.url_rule # type: ignore[assignment] + # 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 + view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**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._got_first_request = True + + try: + request_started.send(self, _async_wrapper=self.ensure_sync) + 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: ft.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, _async_wrapper=self.ensure_sync, 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 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.url_adapter + methods = adapter.allowed_methods() # type: ignore[union-attr] + rv = self.response_class() + rv.allow.update(methods) + return rv + + 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 + + return asgiref_async_to_sync(func) + + def url_for( + self, + /, + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, + ) -> str: + """Generate a URL to the given endpoint with the given values. + + This is called by :func:`flask.url_for`, and can be called + directly as well. + + An *endpoint* is the name of a URL rule, usually added with + :meth:`@app.route() `, and usually the same name as the + view function. A route defined in a :class:`~flask.Blueprint` + will prepend the blueprint's name separated by a ``.`` to the + endpoint. + + In some cases, such as email messages, you want URLs to include + the scheme and domain, like ``https://example.com/hello``. When + not in an active request, URLs will be external by default, but + this requires setting :data:`SERVER_NAME` so Flask knows what + domain to use. :data:`APPLICATION_ROOT` and + :data:`PREFERRED_URL_SCHEME` should also be configured as + needed. This config is only used when not in an active request. + + Functions can be decorated with :meth:`url_defaults` to modify + keyword arguments before the URL is built. + + If building fails for some reason, such as an unknown endpoint + or incorrect values, the app's :meth:`handle_url_build_error` + method is called. If that returns a string, that is returned, + otherwise a :exc:`~werkzeug.routing.BuildError` is raised. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it + is external. + :param _external: If given, prefer the URL to be internal + (False) or require it to be external (True). External URLs + include the scheme and domain. When not in an active + request, URLs are external by default. + :param values: Values to use for the variable parts of the URL + rule. Unknown keys are appended as query string arguments, + like ``?a=b&c=d``. + + .. versionadded:: 2.2 + Moved from ``flask.url_for``, which calls this method. + """ + req_ctx = _cv_request.get(None) + + if req_ctx is not None: + url_adapter = req_ctx.url_adapter + blueprint_name = req_ctx.request.blueprint + + # If the endpoint starts with "." and the request matches a + # blueprint, the endpoint is relative to the blueprint. + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + # When in a request, generate a URL without scheme and + # domain by default, unless a scheme is given. + if _external is None: + _external = _scheme is not None + else: + app_ctx = _cv_app.get(None) + + # If called by helpers.url_for, an app context is active, + # use its url_adapter. Otherwise, app.url_for was called + # directly, build an adapter. + if app_ctx is not None: + url_adapter = app_ctx.url_adapter + else: + url_adapter = self.create_url_adapter(None) + + if url_adapter is None: + raise RuntimeError( + "Unable to build URLs outside an active request" + " without 'SERVER_NAME' configured. Also configure" + " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as" + " needed." + ) + + # When outside a request, generate a URL with scheme and + # domain by default. + if _external is None: + _external = True + + # It is an error to set _scheme when _external=False, in order + # to avoid accidental insecure URLs. + if _scheme is not None and not _external: + raise ValueError("When specifying '_scheme', '_external' must be True.") + + self.inject_url_defaults(endpoint, values) + + try: + rv = url_adapter.build( # type: ignore[union-attr] + endpoint, + values, + method=_method, + url_scheme=_scheme, + force_external=_external, + ) + except BuildError as error: + values.update( + _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external + ) + return self.handle_url_build_error(error, endpoint, values) + + if _anchor is not None: + _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@") + rv = f"{rv}#{_anchor}" + + return rv + + def make_response(self, rv: ft.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. + + ``list`` + A list that will be jsonify'd before being returned. + + ``generator`` or ``iterator`` + A generator that returns ``str`` or ``bytes`` to be + streamed as the response. + + ``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:: 2.2 + A generator will be converted to a streaming response. + A list will be converted to a JSON response. + + .. versionchanged:: 1.1 + A dict will be converted to a JSON response. + + .. 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 # type: ignore[misc] + # 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 # type: ignore[assignment,misc] + # 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)) or isinstance(rv, _abc_Iterator): + # 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, # type: ignore[arg-type] + ) + status = headers = None + elif isinstance(rv, (dict, list)): + rv = self.json.response(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[arg-type] + ) + 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, list, tuple with headers or status," + " Response instance, or WSGI callable, but it" + f" 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, list, tuple with headers or status," + " Response instance, or WSGI callable, but it was a" + f" {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 + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) # type: ignore[arg-type] + + return rv + + def preprocess_request(self) -> ft.ResponseReturnValue | None: + """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._get_current_object() # type: ignore[attr-defined] + + 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: BaseException | None = _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, _async_wrapper=self.ensure_sync, exc=exc) + + def do_teardown_appcontext( + self, exc: BaseException | None = _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, _async_wrapper=self.ensure_sync, 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 app.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: BaseException | None = 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 "werkzeug.debug.preserve_context" in environ: + environ["werkzeug.debug.preserve_context"](_cv_app.get()) + environ["werkzeug.debug.preserve_context"](_cv_request.get()) + + if error is not None and self.should_ignore_error(error): + error = None + + ctx.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/testclient/.venv/lib/python3.9/site-packages/flask/blueprints.py b/testclient/.venv/lib/python3.9/site-packages/flask/blueprints.py new file mode 100644 index 0000000..3a37a2c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/blueprints.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .globals import current_app +from .helpers import send_from_directory +from .sansio.blueprints import Blueprint as SansioBlueprint +from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/cli.py b/testclient/.venv/lib/python3.9/site-packages/flask/cli.py new file mode 100644 index 0000000..dda266b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/cli.py @@ -0,0 +1,1068 @@ +from __future__ import annotations + +import ast +import importlib.metadata +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import itemgetter + +import click +from click.core import ParameterSource +from werkzeug import run_simple +from werkzeug.serving import is_running_from_reloader +from werkzeug.utils import import_string + +from .globals import current_app +from .helpers import get_debug_flag +from .helpers import get_load_dotenv + +if t.TYPE_CHECKING: + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(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__}'. Use '{module.__name__}:name'" + " 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 = 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}' in module '{module.__name__}'," + " but could not call it without arguments. Use" + f" '{module.__name__}:{attr_name}(args)'" + " to specify arguments." + ) from e + + raise NoAppException( + "Failed to find Flask application or factory in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify one." + ) + + +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(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 = {} + 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 = 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(module_name, app_name, raise_if_not_found=True): + 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(module) + else: + return find_app_by_string(module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + flask_version = importlib.metadata.version("flask") + werkzeug_version = importlib.metadata.version("werkzeug") + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {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 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: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + ) -> None: + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path + #: 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: dict[t.Any, t.Any] = {} + self.set_debug_flag = set_debug_flag + self._loaded_app: Flask | None = None + + def load_app(self) -> Flask: + """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. + """ + if self._loaded_app is not None: + return self._loaded_app + + if self.create_app is not None: + app = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, maxsplit=1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + "Could not locate a Flask application. Use the" + " 'flask --app' option, 'FLASK_APP' environment" + " variable, or a 'wsgi.py' or 'app.py' file 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. + + Custom commands (and their options) registered under ``app.cli`` or + ``blueprint.cli`` will always have an app context available, this + decorator is not required in that case. + + .. versionchanged:: 2.2 + The app context is active for subcommands as well as the + decorated callback. The app context is always available to + ``app.cli`` command and parameter callbacks. + """ + + @click.pass_context + def decorator(__ctx, *args, **kwargs): + if not current_app: + app = __ctx.ensure_object(ScriptInfo).load_app() + __ctx.with_resource(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) + + +def _set_app(ctx: click.Context, param: click.Option, value: str | None) -> str | None: + if value is None: + return None + + info = ctx.ensure_object(ScriptInfo) + info.app_import_path = value + return value + + +# This option is eager so the app will be available if --help is given. +# --help is also eager, so --app must be before it in the param list. +# no_args_is_help bypasses eager processing, so this option must be +# processed manually in that case to ensure FLASK_APP gets picked up. +_app_option = click.Option( + ["-A", "--app"], + metavar="IMPORT", + help=( + "The Flask application or factory function to load, in the form 'module:name'." + " Module can be a dotted import or file path. Name is not required if it is" + " 'app', 'application', 'create_app', or 'make_app', and can be 'name(args)' to" + " pass arguments." + ), + is_eager=True, + expose_value=False, + callback=_set_app, +) + + +def _set_debug(ctx: click.Context, param: click.Option, value: bool) -> bool | None: + # If the flag isn't provided, it will default to False. Don't use + # that, let debug be set by env in that case. + source = ctx.get_parameter_source(param.name) # type: ignore[arg-type] + + if source is not None and source in ( + ParameterSource.DEFAULT, + ParameterSource.DEFAULT_MAP, + ): + return None + + # Set with env var instead of ScriptInfo.load so that it can be + # accessed early during a factory function. + os.environ["FLASK_DEBUG"] = "1" if value else "0" + return value + + +_debug_option = click.Option( + ["--debug/--no-debug"], + help="Set debug mode.", + expose_value=False, + callback=_set_debug, +) + + +def _env_file_callback( + ctx: click.Context, param: click.Option, value: str | None +) -> str | None: + if value is None: + return None + + import importlib + + try: + importlib.import_module("dotenv") + except ImportError: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Don't check FLASK_SKIP_DOTENV, that only disables automatically + # loading .env and .flaskenv files. + load_dotenv(value) + return value + + +# This option is eager so env vars are loaded as early as possible to be +# used by other options. +_env_file_option = click.Option( + ["-e", "--env-file"], + type=click.Path(exists=True, dir_okay=False), + help="Load environment variables from this file. python-dotenv must be installed.", + is_eager=True, + expose_value=False, + callback=_env_file_callback, +) + + +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. + + .. versionchanged:: 2.2 + Added the ``-A/--app``, ``--debug/--no-debug``, ``-e/--env-file`` options. + + .. versionchanged:: 2.2 + An app context is pushed when running ``app.cli`` commands, so + ``@with_appcontext`` is no longer required for those commands. + + .. 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: bool = True, + create_app: t.Callable[..., Flask] | None = None, + add_version_option: bool = True, + load_dotenv: bool = True, + set_debug_flag: bool = True, + **extra: t.Any, + ) -> None: + params = list(extra.pop("params", None) or ()) + # Processing is done with option callbacks instead of a group + # callback. This allows users to make a custom group callback + # without losing the behavior. --env-file must come first so + # that it is eagerly evaluated before --app. + params.extend((_env_file_option, _app_option, _debug_option)) + + if add_version_option: + params.append(version_option) + + if "context_settings" not in extra: + extra["context_settings"] = {} + + extra["context_settings"].setdefault("auto_envvar_prefix", "FLASK") + + super().__init__(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 + + if sys.version_info >= (3, 10): + from importlib import metadata + else: + # Use a backport on Python < 3.10. We technically have + # importlib.metadata on 3.8+, but the API changed in 3.10, + # so use the backport for consistency. + import importlib_metadata as metadata + + for ep in metadata.entry_points(group="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: + app = info.load_app() + except NoAppException as e: + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + return None + + # Push an app context for the loaded app unless it is already + # active somehow. This makes the context available to parameter + # and command callbacks without needing @with_appcontext. + if not current_app or current_app._get_current_object() is not app: + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + 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 make_context( + self, + info_name: str | None, + args: list[str], + parent: click.Context | None = None, + **extra: t.Any, + ) -> click.Context: + # Set a flag to tell app.run to become a no-op. If app.run was + # not in a __name__ == __main__ guard, it would start the server + # when importing, blocking whatever command is being called. + os.environ["FLASK_RUN_FROM_CLI"] = "true" + + # Attempt to load .env and .flask env files. The --env-file + # option can cause another file to be loaded. + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + if "obj" not in extra and "obj" not in self.context_settings: + extra["obj"] = ScriptInfo( + create_app=self.create_app, set_debug_flag=self.set_debug_flag + ) + + return super().make_context(info_name, args, parent=parent, **extra) + + def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: + if not args and self.no_args_is_help: + # Attempt to load --env-file and --app early in case they + # were given as env vars. Otherwise no_args_is_help will not + # see commands from app.cli. + _env_file_option.handle_parse_result(ctx, {}, []) + _app_option.handle_parse_result(ctx, {}, []) + + return super().parse_args(ctx, args) + + +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: str | os.PathLike | None = None) -> bool: + """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:: 2.0 + The current directory is not changed to the location of the + loaded file. + + .. versionchanged:: 2.0 + When loading the env files, set the default encoding to UTF-8. + + .. versionchanged:: 1.1.0 + Returns ``False`` when python-dotenv is not installed, or when + the given path isn't a file. + + .. versionadded:: 1.0 + """ + try: + import dotenv + except ImportError: + 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 + + # Always return after attempting to load a given path, don't load + # the default files. + if path is not None: + if os.path.isfile(path): + return dotenv.load_dotenv(path, encoding="utf-8") + + return False + + loaded = False + + for name in (".env", ".flaskenv"): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + dotenv.load_dotenv(path, encoding="utf-8") + loaded = True + + return loaded # True if at least one file was located and loaded. + + +def show_server_banner(debug, app_import_path): + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if is_running_from_reloader(): + return + + if app_import_path is not None: + click.echo(f" * Serving Flask app '{app_import_path}'") + + 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): + try: + import ssl + except ImportError: + raise click.BadParameter( + 'Using "--cert" requires Python to be compiled with SSL support.', + ctx, + param, + ) from None + + 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" + + try: + import ssl + except ImportError: + is_context = False + else: + is_context = 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.", + is_eager=True, +) +@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( + "--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}." + ), +) +@click.option( + "--exclude-patterns", + default=None, + type=SeparatedPathType(), + help=( + "Files matching these fnmatch patterns will not trigger a reload" + " on change. Multiple patterns are separated by" + f" {os.path.pathsep!r}." + ), +) +@pass_script_info +def run_command( + info, + host, + port, + reload, + debugger, + with_threads, + cert, + extra_files, + exclude_patterns, +): + """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 with the '--debug' + option. + """ + try: + app = info.load_app() + except Exception as e: + if is_running_from_reloader(): + # When reloading, print out the error immediately, but raise + # it later so the debugger or server can handle it. + traceback.print_exc() + err = e + + def app(environ, start_response): + raise err from None + + else: + # When not reloading, raise the error immediately so the + # command fails. + raise e from None + + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + show_server_banner(debug, info.app_import_path) + + run_simple( + host, + port, + app, + use_reloader=reload, + use_debugger=debugger, + threaded=with_threads, + ssl_context=cert, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + ) + + +run_command.params.insert(0, _debug_option) + + +@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 + + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {current_app.import_name}\n" + f"Instance: {current_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(current_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", "domain", "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"} + host_matching = current_app.url_map.host_matching + has_domain = any(rule.host if host_matching else rule.subdomain for rule in rules) + rows = [] + + for rule in rules: + row = [ + rule.endpoint, + ", ".join(sorted((rule.methods or set()) - ignored_methods)), + ] + + if has_domain: + row.append((rule.host if host_matching else rule.subdomain) or "") + + row.append(rule.rule) + rows.append(row) + + headers = ["Endpoint", "Methods"] + sorts = ["endpoint", "methods"] + + if has_domain: + headers.append("Host" if host_matching else "Subdomain") + sorts.append("domain") + + headers.append("Rule") + sorts.append("rule") + + try: + rows.sort(key=itemgetter(sorts.index(sort))) + except ValueError: + pass + + rows.insert(0, headers) + widths = [max(len(row[i]) for row in rows) for i in range(len(headers))] + rows.insert(1, ["-" * w for w in widths]) + template = " ".join(f"{{{i}:<{w}}}" for i, w in enumerate(widths)) + + for row in rows: + click.echo(template.format(*row)) + + +cli = FlaskGroup( + name="flask", + help="""\ +A general utility script for Flask applications. + +An application to load must be given with the '--app' option, +'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file +in the current directory. +""", +) + + +def main() -> None: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/config.py b/testclient/.venv/lib/python3.9/site-packages/flask/config.py new file mode 100644 index 0000000..5f921b4 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/config.py @@ -0,0 +1,347 @@ +from __future__ import annotations + +import errno +import json +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.Callable | None = 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 | os.PathLike, defaults: dict | None = None + ) -> None: + super().__init__(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_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + len_prefix = len(prefix) + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile(self, filename: str | os.PathLike, 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: 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 | os.PathLike, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + text: bool = True, + ) -> 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 json + app.config.from_file("config.json", load=json.load) + + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) + + :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. + :param text: Open the file in text or binary mode. + :return: ``True`` if the file was loaded successfully. + + .. versionchanged:: 2.3 + The ``text`` parameter was added. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename, "r" if text else "rb") 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_mapping( + self, mapping: t.Mapping[str, t.Any] | None = 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: 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 + ) -> 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/testclient/.venv/lib/python3.9/site-packages/flask/ctx.py b/testclient/.venv/lib/python3.9/site-packages/flask/ctx.py new file mode 100644 index 0000000..b37e4e0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/ctx.py @@ -0,0 +1,440 @@ +from __future__ import annotations + +import contextvars +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from . import typing as ft +from .globals import _cv_app +from .globals import _cv_request +from .signals import appcontext_popped +from .signals import appcontext_pushed + +if t.TYPE_CHECKING: # pragma: no cover + 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.Any | None = 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: + ctx = _cv_app.get(None) + if ctx is not None: + return f"" + return object.__repr__(self) + + +def after_this_request(f: ft.AfterRequestCallable) -> ft.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 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'after_this_request' can only be used when a request" + " context is active, such as in a view function." + ) + + ctx._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 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'copy_current_request_context' can only be used when a" + " request context is active, such as in a view function." + ) + + ctx = ctx.copy() + + def wrapper(*args, **kwargs): + with ctx: + return ctx.app.ensure_sync(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 _cv_request.get(None) 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 _cv_app.get(None) is not None + + +class AppContext: + """The app context contains application-specific information. An app + context is created and pushed at the beginning of each request if + one is not already active. An app context is also pushed when + running CLI commands. + """ + + def __init__(self, app: Flask) -> None: + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g: _AppCtxGlobals = app.app_ctx_globals_class() + self._cv_tokens: list[contextvars.Token] = [] + + def push(self) -> None: + """Binds the app context to the current context.""" + self._cv_tokens.append(_cv_app.set(self)) + appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync) + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + if len(self._cv_tokens) == 1: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + ctx = _cv_app.get() + _cv_app.reset(self._cv_tokens.pop()) + + if ctx is not self: + raise AssertionError( + f"Popped wrong app context. ({ctx!r} instead of {self!r})" + ) + + appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync) + + def __enter__(self) -> AppContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains per-request information. The Flask + app creates and pushes it at the beginning of the request, then pops + it at the end of the request. 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. When using the interactive debugger, the context will be + restored so ``request`` is still accessible. Similarly, the test + client can preserve the context after the request ends. However, + teardown functions may already have closed some resources such as + database connections. + """ + + def __init__( + self, + app: Flask, + environ: dict, + request: Request | None = None, + session: SessionMixin | None = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json + self.request: 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: list[tuple[str, str]] | None = None + self.session: SessionMixin | None = session + # 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: list[ft.AfterRequestCallable] = [] + + self._cv_tokens: list[tuple[contextvars.Token, AppContext | None]] = [] + + 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: + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _cv_app.get(None) + + if app_ctx is None or app_ctx.app is not self.app: + app_ctx = self.app.app_context() + app_ctx.push() + else: + app_ctx = None + + self._cv_tokens.append((_cv_request.set(self), app_ctx)) + + # 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: BaseException | None = _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. + """ + clear_request = len(self._cv_tokens) == 1 + + try: + if clear_request: + 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() + finally: + ctx = _cv_request.get() + token, app_ctx = self._cv_tokens.pop() + _cv_request.reset(token) + + # 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: + ctx.request.environ["werkzeug.request"] = None + + if app_ctx is not None: + app_ctx.pop(exc) + + if ctx is not self: + raise AssertionError( + f"Popped wrong request context. ({ctx!r} instead of {self!r})" + ) + + def __enter__(self) -> RequestContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.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/testclient/.venv/lib/python3.9/site-packages/flask/debughelpers.py b/testclient/.venv/lib/python3.9/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e836004 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/debughelpers.py @@ -0,0 +1,160 @@ +from __future__ import annotations + +import typing as t + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + + +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 in debug mode if a routing redirect + would cause the browser to drop the method or body. This happens + when method is not GET, HEAD or OPTIONS and the status code is not + 307 or 308. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = [ + f"A request was sent to '{request.url}', but routing issued" + f" a redirect to the canonical URL '{exc.new_url}'." + ] + + if f"{request.base_url}/" == exc.new_url.partition("?")[0]: + buf.append( + " The URL was defined with a trailing slash. Flask" + " will redirect to the URL with a trailing slash if it" + " was accessed without one." + ) + + buf.append( + " Send requests to the canonical URL, or use 307 or 308 for" + " routing redirects. Otherwise, browsers will drop form" + " data.\n\n" + "This exception is only raised in debug mode." + ) + super().__init__("".join(buf)) + + +def attach_enctype_error_multidict(request): + """Patch ``request.files.__getitem__`` to raise a descriptive error + about ``enctype=multipart/form-data``. + + :param request: The request to patch. + :meta private: + """ + oldcls = request.files.__class__ + + class newcls(oldcls): + def __getitem__(self, key): + try: + return super().__getitem__(key) + except KeyError as e: + if key not in request.form: + raise + + raise DebugFilesKeyError(request, key).with_traceback( + e.__traceback__ + ) from None + + 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: App, template, attempts) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + if request_ctx and request_ctx.request.blueprint is not None: + blueprint = request_ctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, App): + 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)) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/globals.py b/testclient/.venv/lib/python3.9/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/globals.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import typing as t +from contextvars import ContextVar + +from werkzeug.local import LocalProxy + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .ctx import _AppCtxGlobals + from .ctx import AppContext + from .ctx import RequestContext + from .sessions import SessionMixin + from .wrappers import Request + + +_no_app_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +the current application. To solve this, set up an application context +with app.app_context(). See the documentation for more information.\ +""" +_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx") +app_ctx: AppContext = LocalProxy( # type: ignore[assignment] + _cv_app, unbound_message=_no_app_msg +) +current_app: Flask = LocalProxy( # type: ignore[assignment] + _cv_app, "app", unbound_message=_no_app_msg +) +g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment] + _cv_app, "g", unbound_message=_no_app_msg +) + +_no_req_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.\ +""" +_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx") +request_ctx: RequestContext = LocalProxy( # type: ignore[assignment] + _cv_request, unbound_message=_no_req_msg +) +request: Request = LocalProxy( # type: ignore[assignment] + _cv_request, "request", unbound_message=_no_req_msg +) +session: SessionMixin = LocalProxy( # type: ignore[assignment] + _cv_request, "session", unbound_message=_no_req_msg +) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/helpers.py b/testclient/.venv/lib/python3.9/site-packages/flask/helpers.py new file mode 100644 index 0000000..13a5aa2 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/helpers.py @@ -0,0 +1,623 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import lru_cache +from functools import update_wrapper + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect + +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .globals import request_ctx +from .globals import session +from .signals import message_flashed + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + from .wrappers import Response + + +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 ``False``. + """ + val = os.environ.get("FLASK_DEBUG") + return bool(val and val.lower() not in {"0", "false", "no"}) + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading default 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.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 = _cv_request.get(None) + if ctx is None: + raise RuntimeError( + "'stream_with_context' can only be used when a request" + " context is active, such as in a view function." + ) + 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() + + # 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) # type: ignore + + +def url_for( + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, +) -> str: + """Generate a URL to the given endpoint with the given values. + + This requires an active request or application context, and calls + :meth:`current_app.url_for() `. See that method + for full documentation. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it is + external. + :param _external: If given, prefer the URL to be internal (False) or + require it to be external (True). External URLs include the + scheme and domain. When not in an active request, URLs are + external by default. + :param values: Values to use for the variable parts of the URL rule. + Unknown keys are appended as query string arguments, like + ``?a=b&c=d``. + + .. versionchanged:: 2.2 + Calls ``current_app.url_for``, allowing an app to override the + behavior. + + .. versionchanged:: 0.10 + The ``_scheme`` parameter was added. + + .. versionchanged:: 0.9 + The ``_anchor`` and ``_method`` parameters were added. + + .. versionchanged:: 0.9 + Calls ``app.handle_url_build_error`` on build errors. + """ + return current_app.url_for( + endpoint, + _anchor=_anchor, + _method=_method, + _scheme=_scheme, + _external=_external, + **values, + ) + + +def redirect( + location: str, code: int = 302, Response: type[BaseResponse] | None = None +) -> BaseResponse: + """Create a redirect response object. + + If :data:`~flask.current_app` is available, it will use its + :meth:`~flask.Flask.redirect` method, otherwise it will use + :func:`werkzeug.utils.redirect`. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + :param Response: The response class to use. Not used when + ``current_app`` is active, which uses ``app.response_class``. + + .. versionadded:: 2.2 + Calls ``current_app.redirect`` if available instead of always + using Werkzeug's default ``redirect``. + """ + if current_app: + return current_app.redirect(location, code=code) + + return _wz_redirect(location, code=code, Response=Response) + + +def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given + status code. + + If :data:`~flask.current_app` is available, it will call its + :attr:`~flask.Flask.aborter` object, otherwise it will use + :func:`werkzeug.exceptions.abort`. + + :param code: The status code for the exception, which must be + registered in ``app.aborter``. + :param args: Passed to the exception. + :param kwargs: Passed to the exception. + + .. versionadded:: 2.2 + Calls ``current_app.aborter`` if available instead of always + using Werkzeug's default ``abort``. + """ + if current_app: + current_app.aborter(code, *args, **kwargs) + + _wz_abort(code, *args, **kwargs) + + +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 + app = current_app._get_current_object() # type: ignore + message_flashed.send( + app, + _async_wrapper=app.ensure_sync, + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> list[str] | list[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.flashes + if flashes is None: + flashes = session.pop("_flashes") if "_flashes" in session else [] + request_ctx.flashes = flashes + 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(**kwargs: t.Any) -> dict[str, t.Any]: + if kwargs.get("max_age") is None: + kwargs["max_age"] = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + use_x_sendfile=current_app.config["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: os.PathLike | str | t.BinaryIO, + mimetype: str | None = None, + as_attachment: bool = False, + download_name: str | None = None, + conditional: bool = True, + etag: bool | str = True, + last_modified: datetime | int | float | None = None, + max_age: None | (int | t.Callable[[str | None], int | None]) = 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. 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 + removed 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( # type: ignore[return-value] + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + conditional=conditional, + etag=etag, + last_modified=last_modified, + max_age=max_age, + ) + ) + + +def send_from_directory( + directory: os.PathLike | str, + path: os.PathLike | str, + **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, + relative to the current application's root path. + :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 + """ + return werkzeug.utils.send_from_directory( # type: ignore[return-value] + 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. + try: + spec = importlib.util.find_spec(import_name) + + if spec is None: + raise ValueError + except (ImportError, ValueError): + loader = None + else: + loader = spec.loader + + # 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: + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) + 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)) + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> list[str]: + out: list[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/__init__.py b/testclient/.venv/lib/python3.9/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..f15296f --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/json/__init__.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..wrappers import Response + + +def dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dumps() ` + method, otherwise it will use :func:`json.dumps`. + + :param obj: The data to serialize. + :param kwargs: Arguments passed to the ``dumps`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dump() ` + method, otherwise it will use :func:`json.dump`. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: Arguments passed to the ``dump`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if current_app: + current_app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.loads() ` + method, otherwise it will use :func:`json.loads`. + + :param s: Text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``loads`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.loads``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + ``encoding`` 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. + """ + if current_app: + return current_app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.load() ` + method, otherwise it will use :func:`json.load`. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``load`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.load``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The file must be text + mode, or binary mode with UTF-8 bytes. + """ + if current_app: + return current_app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. A dict or list returned from a view will be converted to a + JSON response automatically without needing to call this. + + This requires an active request or application context, and calls + :meth:`app.json.response() `. + + In debug mode, the output is formatted with indentation to make it + easier to read. This may also be controlled by the provider. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + + .. versionchanged:: 2.2 + Calls ``current_app.json.response``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 0.11 + Added support for serializing top-level arrays. This was a + security risk in ancient browsers. See :ref:`security-json`. + + .. versionadded:: 0.2 + """ + return current_app.json.response(*args, **kwargs) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5fef1e83c5ce994a6ff7a049fef6c2fc951378a GIT binary patch literal 5988 zcmd5=OK%&=5uPC_iF(>rylZ*AaTKzKsMP;YNUCk zyGe$EkW)@MhbcyvhT@-qZRc6y-U$*ymqjL-a7u4#mYBTu`1U7Tsv6DJAF6Ajc;n=rnrT+ z4Y6s*eGj8eLweQ;MZ6W)77#U2e|4Ql%6XeN)37#gCysC|ARP$=uJ<1o4 z$6O6`zNn-bs-#Er%MZz~;rkV->&JL7p4u|rk$+S<_450i>l}CNfq)aJdsRr!x`7?7kjUEgOwGA&&xh*QFE*Fr+&osaWHqL4huEo zBOXS)8_8`J8a582hz+&Gv$peFu{4LR4m1!P=`;z%FwXQ38|-r@&9-GK9fd-wfY$xG ze6b^+bgUE-l8SAXnnS6^p_M;dtJNPSy;f%?zf)|!m2t&m26eXB{$X)GlQLbNIBpA|SvnD2-HX40S6Rrz0sYmGfvS=NXS84M}qsF{j#2XPaR_Iu4To;|arh zw13D~3Ob%jp#yd0As>aQx^&?O!EEVP4Pxlvpb*F^ zu2qCe_DnR{W{N`{3YUz2CI2uCX}5*;rrW}qjQpcv{Z!HU`r%-RdAM$8MEO$b*o%sM zGp~_7<_p$l@)a#j(XSS%ccD$)jfz^vn<8ZVm#1#w-~XcKVH(S(N~M-NBMnW^OE)z; zv;&n!J26lAK&qyZ+Vr9jcGwI?G8r|au-nWgaFyh7@YALajoit2?-+x1)B0PJ7HziM zVG^2lJIE$#152*stLymj?$!L;l{MeCo-CW-<*VP}>VBWscGE;QYId`ErJvait5wYC z5f+snfXNJ(zQ7A`>C+OIPW^rb$W$R@^1XzeR?cJ7*%20CtK5GpLg9i08!MdB8CgG! zWMLBD25MaywB8G|-Vd_+8Q_Z1!C9Kg1kOj+NjkBv2XhVB-eEe7gau`C`d{zA*!juS zs7p^H4Z<@e9 zUbahYn+hu8z&VVgdr)g|rrm}^7DfJ=*9chD4Ln*vQ8)3_s5&^gO|66}7E#>KCcT1p zc};wsx8JGxTjcH3da?>fXQu#fpb9vMujhRHt=!{BnE5vDVXANN4WDnoo4*9GeTR%A zO1Zci+E#SxD;?!oq7MA*K2-hik|biq0Gg4L??<%;^4+AnhBJLvc&zM80ncb9^;qPCL_ z8?tROv4^+~JeWa&jn>!a$)8-}$skc2p-81M5b;|K%cQL*EA8Z(Po4aO*pCuRj7w1QmP+rXcA78@%9|aGl81RlrV%b!QB*gfqf?`l{ zT!Bh8ggJ#$E6`*X2*3$GEr&Z)PoQ&XE-!Ve;HjmiOYK^d*n zPgxLnMFjzh^d;$@l>!<*&jB>EWS@x1AVl84N=AZY-sS#|xwyhZ0j6c@S5yJY%0-8g zYh+PQ4UX#|<&46fO^s~6(J6BH5Lx^rlK~j32r&hUj6wjmTZg!-1B_89$0au^Gf9_) zJ6xwK0VcW93FAYP##pR}taoC!kq!+@q;xKsGU@;e3w2>G`*aX`wft*wQL zC@T-d+GBo9)fQ`{lIxK2*c6B1B0ylo^q5aj5zv<37a3#(S;*39nQ86Cm3yAUnjs-e zkvt-`N5_5J^B+}M=wizm44EgDy<2T5?5-{Ou5rwP5&bGmWDUT$8)3X{( zS@$S%4YG1dYBUfPX$>-xq0R56oY8t4bE=JlDRW4Xk$9}LI$=! zn_%to>;xoh75h{O*iBLAv597>R~!7& zY$uW<8R6;`pXkE+sJ=Bv$0Vv&p_wohqJ)E54o`YizhGUJjv)=R_M~JjCHt+8E(Y&V z(W3N}*-dcT4r**=feK`2Mx^Sc;!$C_3p~7tM&(N+IP6dUf&rQ!)MM%%ejA(lO1s@3 zqV6i&ZACqno>>Ub7Xe~8aPFIYX%MAd_?9d9)JtD-6`u9|-+ukP{p{z@pMCXm_h)&1 ztN<%GqQ!GtVX=vqC2qLvDx@QV4l}M2QCaF`Gn}3CR(^wsrz;0ZfliAf33Rt M+3owAKiItge*;z5Qvd(} literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/provider.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/provider.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f6db1dda668aedb7d39bf4b21d34ab713ecf5e4 GIT binary patch literal 7576 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/tag.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/json/__pycache__/tag.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b31fac01f1d5d1ec12e5377984ecaf524cb5dec GIT binary patch literal 11438 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/provider.py b/testclient/.venv/lib/python3.9/site-packages/flask/json/provider.py new file mode 100644 index 0000000..3c22bc8 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/json/provider.py @@ -0,0 +1,216 @@ +from __future__ import annotations + +import dataclasses +import decimal +import json +import typing as t +import uuid +import weakref +from datetime import date + +from werkzeug.http import http_date + +if t.TYPE_CHECKING: # pragma: no cover + from ..sansio.app import App + from ..wrappers import Response + + +class JSONProvider: + """A standard set of JSON operations for an application. Subclasses + of this can be used to customize JSON behavior or use different + JSON libraries. + + To implement a provider for a specific library, subclass this base + class and implement at least :meth:`dumps` and :meth:`loads`. All + other methods have default implementations. + + To use a different provider, either subclass ``Flask`` and set + :attr:`~flask.Flask.json_provider_class` to a provider class, or set + :attr:`app.json ` to an instance of the class. + + :param app: An application instance. This will be stored as a + :class:`weakref.proxy` on the :attr:`_app` attribute. + + .. versionadded:: 2.2 + """ + + def __init__(self, app: App) -> None: + self._app = weakref.proxy(app) + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + :param obj: The data to serialize. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: May be passed to the underlying JSON library. + """ + fp.write(self.dumps(obj, **kwargs)) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + :param s: Text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + return self.loads(fp.read(), **kwargs) + + def _prepare_response_obj( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> t.Any: + if args and kwargs: + raise TypeError("app.json.response() takes either args or kwargs, not both") + + if not args and not kwargs: + return None + + if len(args) == 1: + return args[0] + + return args or kwargs + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. + + The :func:`~flask.json.jsonify` function calls this method for + the current application. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + return self._app.response_class(self.dumps(obj), mimetype="application/json") + + +def _default(o: t.Any) -> t.Any: + 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__()) + + raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") + + +class DefaultJSONProvider(JSONProvider): + """Provide JSON operations using Python's built-in :mod:`json` + library. Serializes the following additional data types: + + - :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. + """ + + default: t.Callable[[t.Any], t.Any] = staticmethod( + _default + ) # type: ignore[assignment] + """Apply this function to any object that :meth:`json.dumps` does + not know how to serialize. It should return a valid JSON type or + raise a ``TypeError``. + """ + + ensure_ascii = True + """Replace non-ASCII characters with escape sequences. This may be + more compatible with some clients, but can be disabled for better + performance and size. + """ + + sort_keys = True + """Sort the keys in any serialized dicts. This may be useful for + some caching situations, but can be disabled for better performance. + When enabled, keys must all be strings, they are not converted + before sorting. + """ + + compact: bool | None = None + """If ``True``, or ``None`` out of debug mode, the :meth:`response` + output will not add indentation, newlines, or spaces. If ``False``, + or ``None`` in debug mode, it will use a non-compact representation. + """ + + mimetype = "application/json" + """The mimetype set in :meth:`response`.""" + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON to a string. + + Keyword arguments are passed to :func:`json.dumps`. Sets some + parameter defaults from the :attr:`default`, + :attr:`ensure_ascii`, and :attr:`sort_keys` attributes. + + :param obj: The data to serialize. + :param kwargs: Passed to :func:`json.dumps`. + """ + kwargs.setdefault("default", self.default) + kwargs.setdefault("ensure_ascii", self.ensure_ascii) + kwargs.setdefault("sort_keys", self.sort_keys) + return json.dumps(obj, **kwargs) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON from a string or bytes. + + :param s: Text or UTF-8 bytes. + :param kwargs: Passed to :func:`json.loads`. + """ + return json.loads(s, **kwargs) + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with it. The response mimetype + will be "application/json" and can be changed with + :attr:`mimetype`. + + If :attr:`compact` is ``False`` or debug mode is enabled, the + output will be formatted to be easier to read. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + dump_args: dict[str, t.Any] = {} + + if (self.compact is None and self._app.debug) or self.compact is False: + dump_args.setdefault("indent", 2) + else: + dump_args.setdefault("separators", (",", ":")) + + return self._app.response_class( + f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype + ) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/json/tag.py b/testclient/.venv/lib/python3.9/site-packages/flask/json/tag.py new file mode 100644 index 0000000..91cc441 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/json/tag.py @@ -0,0 +1,314 @@ +""" +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON +types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this +to serialize the session data, but it may be useful in other places. It +can be extended to support other types. + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + +Let's see an example that adds support for +:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so +to handle this we will dump the items as a list of ``[key, value]`` +pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to +identify the type. The session serializer processes dicts first, so +insert the new tag at the front of the order since ``OrderedDict`` must +be processed before ``dict``. + +.. code-block:: python + + from flask.json.tag import JSONTag + + class TagOrderedDict(JSONTag): + __slots__ = ('serializer',) + key = ' od' + + def check(self, value): + return isinstance(value, OrderedDict) + + def to_json(self, value): + return [[k, self.serializer.tag(v)] for k, v in iteritems(value)] + + def to_python(self, value): + return OrderedDict(value) + + app.session_interface.serializer.register(TagOrderedDict, index=0) +""" +from __future__ import annotations + +import typing as t +from base64 import b64decode +from base64 import b64encode +from datetime import datetime +from uuid import UUID + +from markupsafe import Markup +from werkzeug.http import http_date +from werkzeug.http import parse_date + +from ..json import dumps +from ..json import loads + + +class JSONTag: + """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" + + __slots__ = ("serializer",) + + #: The tag to mark the serialized object with. If ``None``, this tag is + #: only used as an intermediate step during tagging. + key: str | None = None + + def __init__(self, serializer: TaggedJSONSerializer) -> None: + """Create a tagger for the given serializer.""" + self.serializer = serializer + + def check(self, value: t.Any) -> bool: + """Check if the given value should be tagged by this tag.""" + raise NotImplementedError + + def to_json(self, value: t.Any) -> t.Any: + """Convert the Python object to an object that is a valid JSON type. + The tag will be added later.""" + raise NotImplementedError + + def to_python(self, value: t.Any) -> t.Any: + """Convert the JSON representation back to the correct type. The tag + will already be removed.""" + raise NotImplementedError + + def tag(self, value: t.Any) -> t.Any: + """Convert the value to a valid JSON type and add the tag structure + around it.""" + return {self.key: self.to_json(value)} + + +class TagDict(JSONTag): + """Tag for 1-item dicts whose only key matches a registered tag. + + Internally, the dict key is suffixed with `__`, and the suffix is removed + when deserializing. + """ + + __slots__ = () + key = " di" + + def check(self, value: t.Any) -> bool: + return ( + isinstance(value, dict) + and len(value) == 1 + and next(iter(value)) in self.serializer.tags + ) + + def to_json(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {f"{key}__": self.serializer.tag(value[key])} + + def to_python(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {key[:-2]: value[key]} + + +class PassDict(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, dict) + + def to_json(self, value: t.Any) -> t.Any: + # JSON objects may only have string keys, so don't bother tagging the + # key here. + return {k: self.serializer.tag(v) for k, v in value.items()} + + tag = to_json + + +class TagTuple(JSONTag): + __slots__ = () + key = " t" + + def check(self, value: t.Any) -> bool: + return isinstance(value, tuple) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + def to_python(self, value: t.Any) -> t.Any: + return tuple(value) + + +class PassList(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, list) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + tag = to_json + + +class TagBytes(JSONTag): + __slots__ = () + key = " b" + + def check(self, value: t.Any) -> bool: + return isinstance(value, bytes) + + def to_json(self, value: t.Any) -> t.Any: + return b64encode(value).decode("ascii") + + def to_python(self, value: t.Any) -> t.Any: + return b64decode(value) + + +class TagMarkup(JSONTag): + """Serialize anything matching the :class:`~markupsafe.Markup` API by + having a ``__html__`` method to the result of that method. Always + deserializes to an instance of :class:`~markupsafe.Markup`.""" + + __slots__ = () + key = " m" + + def check(self, value: t.Any) -> bool: + return callable(getattr(value, "__html__", None)) + + def to_json(self, value: t.Any) -> t.Any: + return str(value.__html__()) + + def to_python(self, value: t.Any) -> t.Any: + return Markup(value) + + +class TagUUID(JSONTag): + __slots__ = () + key = " u" + + def check(self, value: t.Any) -> bool: + return isinstance(value, UUID) + + def to_json(self, value: t.Any) -> t.Any: + return value.hex + + def to_python(self, value: t.Any) -> t.Any: + return UUID(value) + + +class TagDateTime(JSONTag): + __slots__ = () + key = " d" + + def check(self, value: t.Any) -> bool: + return isinstance(value, datetime) + + def to_json(self, value: t.Any) -> t.Any: + return http_date(value) + + def to_python(self, value: t.Any) -> t.Any: + return parse_date(value) + + +class TaggedJSONSerializer: + """Serializer that uses a tag system to compactly represent objects that + are not JSON types. Passed as the intermediate serializer to + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~markupsafe.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ + + __slots__ = ("tags", "order") + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. + default_tags = [ + TagDict, + PassDict, + TagTuple, + PassList, + TagBytes, + TagMarkup, + TagUUID, + TagDateTime, + ] + + def __init__(self) -> None: + self.tags: dict[str, JSONTag] = {} + self.order: list[JSONTag] = [] + + for cls in self.default_tags: + self.register(cls) + + def register( + self, + tag_class: type[JSONTag], + force: bool = False, + index: int | None = None, + ) -> None: + """Register a new tag with this serializer. + + :param tag_class: tag class to register. Will be instantiated with this + serializer instance. + :param force: overwrite an existing tag. If false (default), a + :exc:`KeyError` is raised. + :param index: index to insert the new tag in the tag order. Useful when + the new tag is a special case of an existing tag. If ``None`` + (default), the tag is appended to the end of the order. + + :raise KeyError: if the tag key is already registered and ``force`` is + not true. + """ + tag = tag_class(self) + key = tag.key + + if key is not None: + if not force and key in self.tags: + raise KeyError(f"Tag '{key}' is already registered.") + + self.tags[key] = tag + + if index is None: + self.order.append(tag) + else: + self.order.insert(index, tag) + + def tag(self, value: t.Any) -> dict[str, t.Any]: + """Convert a value to a tagged representation if necessary.""" + for tag in self.order: + if tag.check(value): + return tag.tag(value) + + return value + + def untag(self, value: dict[str, t.Any]) -> t.Any: + """Convert a tagged representation back to the original type.""" + if len(value) != 1: + return value + + key = next(iter(value)) + + if key not in self.tags: + return value + + return self.tags[key].to_python(value[key]) + + def dumps(self, value: t.Any) -> str: + """Tag the value and dump it to a compact JSON string.""" + return dumps(self.tag(value), separators=(",", ":")) + + def loads(self, value: str) -> t.Any: + """Load data from a JSON string and deserialized any tagged objects.""" + return loads(value, object_hook=self.untag) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/logging.py b/testclient/.venv/lib/python3.9/site-packages/flask/logging.py new file mode 100644 index 0000000..b452f71 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/logging.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +import logging +import sys +import typing as t + +from werkzeug.local import LocalProxy + +from .globals import request + +if t.TYPE_CHECKING: # pragma: no cover + from .sansio.app import App + + +@LocalProxy +def wsgi_errors_stream() -> t.TextIO: + """Find the most appropriate error stream for the application. If a request + is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``. + + If you configure your own :class:`logging.StreamHandler`, you may want to + use this for the stream. If you are using file or dict configuration and + can't import this directly, you can refer to it as + ``ext://flask.logging.wsgi_errors_stream``. + """ + return request.environ["wsgi.errors"] if request else sys.stderr + + +def has_level_handler(logger: logging.Logger) -> bool: + """Check if there is a handler in the logging chain that will handle the + given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`. + """ + level = logger.getEffectiveLevel() + current = logger + + while current: + if any(handler.level <= level for handler in current.handlers): + return True + + if not current.propagate: + break + + current = current.parent # type: ignore + + return False + + +#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format +#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``. +default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore +default_handler.setFormatter( + logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s") +) + + +def create_logger(app: App) -> logging.Logger: + """Get the Flask app's logger and configure it if needed. + + The logger name will be the same as + :attr:`app.import_name `. + + When :attr:`~flask.Flask.debug` is enabled, set the logger level to + :data:`logging.DEBUG` if it is not set. + + If there is no handler for the logger's effective level, add a + :class:`~logging.StreamHandler` for + :func:`~flask.logging.wsgi_errors_stream` with a basic format. + """ + logger = logging.getLogger(app.name) + + if app.debug and not logger.level: + logger.setLevel(logging.DEBUG) + + if not has_level_handler(logger): + logger.addHandler(default_handler) + + return logger diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/py.typed b/testclient/.venv/lib/python3.9/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/README.md b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/README.md @@ -0,0 +1,6 @@ +# Sansio + +This folder contains code that can be used by alternative Flask +implementations, for example Quart. The code therefore cannot do any +IO, nor be part of a likely IO path. Finally this code cannot use the +Flask globals. diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/app.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff541fc5d57cb65f7e1a7589d9e672d76ad934b5 GIT binary patch literal 28184 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 vX}t!kDHV|11h&+?fGa9{jpCWihm?nd~= literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/blueprints.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/blueprints.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0743af53e784e5f2fb1a43e114a06de868cce48c GIT binary patch literal 22685 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/scaffold.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/__pycache__/scaffold.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eb1f91458923701c1038715cd1ad40e9446880b GIT binary patch literal 23763 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 Y0m timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class App(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 of the object assigned to :attr:`aborter`, created by + #: :meth:`create_aborter`. That object is called by + #: :func:`flask.abort` to raise HTTP errors, and can be + #: called directly as well. + #: + #: Defaults to :class:`werkzeug.exceptions.Aborter`. + #: + #: .. versionadded:: 2.2 + aborter_class = Aborter + + #: 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") + + #: 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 + ) + + json_provider_class: type[JSONProvider] = DefaultJSONProvider + """A subclass of :class:`~flask.json.provider.JSONProvider`. An + instance is created and assigned to :attr:`app.json` when creating + the app. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses + Python's built-in :mod:`json` library. A different provider can use + a different JSON library. + + .. versionadded:: 2.2 + """ + + #: 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 = {} + + #: 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: type[FlaskClient] | None = 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: type[FlaskCliRunner] | None = None + + default_config: dict + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = 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) + + #: An instance of :attr:`aborter_class` created by + #: :meth:`make_aborter`. This is called by :func:`flask.abort` + #: to raise HTTP errors, and can be called directly as well. + #: + #: .. versionadded:: 2.2 + #: Moved from ``flask.abort``, which calls this object. + self.aborter = self.make_aborter() + + self.json: JSONProvider = self.json_provider_class(self) + """Provides access to JSON methods. Functions in ``flask.json`` + will call methods on this provider when the application context + is active. Used for handling JSON requests and responses. + + An instance of :attr:`json_provider_class`. Can be customized by + changing that attribute on a subclass, or by assigning to this + attribute afterwards. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, + uses Python's built-in :mod:`json` library. A different provider + can use a different JSON library. + + .. versionadded:: 2.2 + """ + + #: A list of functions that are called by + #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function is called + #: with ``error``, ``endpoint`` and ``values``. If a function + #: returns ``None`` or raises a ``BuildError``, it is skipped. + #: Otherwise, its return value is returned by ``url_for``. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: list[ + t.Callable[[Exception, str, dict[str, t.Any]], str] + ] = [] + + #: 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: list[ft.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: list[ft.ShellContextProcessorCallable] = [] + + #: 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: 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(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 + + # 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 _check_setup_finished(self, f_name: str) -> None: + if self._got_first_request: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called" + " on the application. It has already handled its first" + " request, any changes will not be applied" + " consistently.\n" + "Make sure all imports, decorators, functions, etc." + " needed to set up the application are done before" + " running it." + ) + + @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 + + @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) + + @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() + + def create_jinja_environment(self) -> Environment: + raise NotImplementedError() + + 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["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def make_aborter(self) -> Aborter: + """Create the object to assign to :attr:`aborter`. That object + is called by :func:`flask.abort` to raise HTTP errors, and can + be called directly as well. + + By default, this creates an instance of :attr:`aborter_class`, + which defaults to :class:`werkzeug.exceptions.Aborter`. + + .. versionadded:: 2.2 + """ + return self.aborter_class() + + 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 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`. + + .. versionchanged:: 2.2 + Autoescaping is now enabled by default for ``.svg`` files. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg")) + + @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. It may not behave as expected if set late. + + **Do not enable debug mode when deploying in production.** + + Default: ``False`` + """ + return self.config["DEBUG"] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + + if self.config["TEMPLATES_AUTO_RELOAD"] is None: + self.jinja_env.auto_reload = value + + @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: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = 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: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """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: T_template_filter) -> T_template_filter: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = 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: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """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: T_template_test) -> T_template_test: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: ft.TemplateTestCallable, name: str | None = 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: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """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: T_template_global) -> T_template_global: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = 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 teardown_appcontext(self, f: T_teardown) -> T_teardown: + """Registers a function to be called when the application + context is popped. The application context is typically popped + after the request context for each request, at the end of CLI + commands, or after a manually pushed context ends. + + .. code-block:: python + + with app.app_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the app context is + made inactive. 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. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + 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_shell_context_processor + ) -> T_shell_context_processor: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler( + self, e: Exception, blueprints: list[str] + ) -> ft.ErrorHandlerCallable | None: + """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 = (*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 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 should_ignore_error(self, error: BaseException | None) -> 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 redirect(self, location: str, code: int = 302) -> BaseResponse: + """Create a redirect response object. + + This is called by :func:`flask.redirect`, and can be called + directly as well. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + + .. versionadded:: 2.2 + Moved from ``flask.redirect``, which calls this method. + """ + return _wz_redirect( + location, code=code, Response=self.response_class # type: ignore[arg-type] + ) + + 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[str | None] = (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: BuildError, endpoint: str, values: dict[str, t.Any] + ) -> str: + """Called by :meth:`.url_for` if a + :exc:`~werkzeug.routing.BuildError` was raised. If this returns + a value, it will be returned by ``url_for``, otherwise the error + will be re-raised. + + Each function in :attr:`url_build_error_handlers` is called with + ``error``, ``endpoint`` and ``values``. If a function returns + ``None`` or raises a ``BuildError``, it is skipped. Otherwise, + its return value is returned by ``url_for``. + + :param error: The active ``BuildError`` being handled. + :param endpoint: The endpoint being built. + :param values: The keyword arguments passed to ``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 diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/blueprints.py b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..38c92f4 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,626 @@ +from __future__ import annotations + +import os +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .. import typing as ft +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from .app import App + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) + + +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: App, + 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: str | None = None, + view_func: t.Callable | None = 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 + """ + + _got_registered_once = False + + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict | None = None, + root_path: str | None = None, + cli_group: str | None = _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 not name: + raise ValueError("'name' may not be empty.") + + 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: list[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: list[tuple[Blueprint, dict]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called on the blueprint" + f" '{self.name}'. It has already been registered at least once, any" + " changes will not be applied consistently.\n" + "Make sure all imports, decorators, functions, etc. needed to set up" + " the blueprint are done before registering it." + ) + + @setupmethod + 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. + """ + self.deferred_functions.append(func) + + @setupmethod + 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) + + self.record(update_wrapper(wrapper, func)) + + def make_setup_state( + self, app: App, 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) + + @setupmethod + 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: App, 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.3 + Nested blueprints now correctly apply subdomains. + + .. versionchanged:: 2.1 + Registering the same blueprint with the same name multiple + times is an error. + + .. 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``. + """ + 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: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + 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, # type: ignore[attr-defined] + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + self._merge_blueprint_funcs(app, name) + + 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") + bp_subdomain = bp_options.get("subdomain") + + if bp_subdomain is None: + bp_subdomain = blueprint.subdomain + + if state.subdomain is not None and bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + "." + state.subdomain + elif bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + elif state.subdomain is not None: + bp_options["subdomain"] = state.subdomain + + 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 _merge_blueprint_funcs(self, app: App, name: str) -> None: + 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) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for + full documentation. + + The URL rule is prefixed with the blueprint's URL prefix. The endpoint name, + used with :func:`url_for`, is prefixed with the blueprint's name. + """ + 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, + ) + ) + + @setupmethod + def app_template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a template filter, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a template filter, available in any template rendered by the + application. Works like the :meth:`app_template_filter` decorator. Equivalent to + :meth:`.Flask.add_template_filter`. + + :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) + + @setupmethod + def app_template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a template test, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_app_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a template test, available in any template rendered by the + application. Works like the :meth:`app_template_test` decorator. Equivalent to + :meth:`.Flask.add_template_test`. + + .. 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) + + @setupmethod + def app_template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a template global, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_app_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a template global, available in any template rendered by the + application. Works like the :meth:`app_template_global` decorator. Equivalent to + :meth:`.Flask.add_template_global`. + + .. 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) + + @setupmethod + def before_app_request(self, f: T_before_request) -> T_before_request: + """Like :meth:`before_request`, but before every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.before_request`. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`after_request`, but after every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.after_request`. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def teardown_app_request(self, f: T_teardown) -> T_teardown: + """Like :meth:`teardown_request`, but after every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_context_processor( + self, f: T_template_context_processor + ) -> T_template_context_processor: + """Like :meth:`context_processor`, but for templates rendered by every view, not + only by the blueprint. Equivalent to :meth:`.Flask.context_processor`. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`errorhandler`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.errorhandler`. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + + return decorator + + @setupmethod + def app_url_value_preprocessor( + self, f: T_url_value_preprocessor + ) -> T_url_value_preprocessor: + """Like :meth:`url_value_preprocessor`, but for every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`. + """ + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Like :meth:`url_defaults`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.url_defaults`. + """ + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sansio/scaffold.py b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..a43f6fd --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,802 @@ +from __future__ import annotations + +import importlib.util +import os +import pathlib +import sys +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from jinja2 import FileSystemLoader +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException +from werkzeug.utils import cached_property + +from .. import typing as ft +from ..cli import AppGroup +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +# a singleton sentinel value for parameter defaults +_sentinel = object() + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) +T_route = t.TypeVar("T_route", bound=ft.RouteCallable) + + +def setupmethod(f: F) -> F: + f_name = f.__name__ + + def wrapper_func(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + self._check_setup_finished(f_name) + return f(self, *args, **kwargs) + + return t.cast(F, update_wrapper(wrapper_func, f)) + + +class Scaffold: + """Common behavior shared between :class:`~flask.Flask` and + :class:`~flask.blueprints.Blueprint`. + + :param import_name: The import name of the module where this object + is defined. Usually :attr:`__name__` should be used. + :param static_folder: Path to a folder of static files to serve. + If this is set, a static route will be added. + :param static_url_path: URL prefix for the static route. + :param template_folder: Path to a folder containing template files. + for rendering. If this is set, a Jinja loader will be added. + :param root_path: The path that static, template, and resource files + are relative to. Typically not set, it is discovered based on + the ``import_name``. + + .. versionadded:: 2.0 + """ + + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + root_path: str | None = None, + ): + #: The name of the package or module that this object belongs + #: to. Do not change this once it is set by the constructor. + self.import_name = import_name + + self.static_folder = static_folder # type: ignore + self.static_url_path = static_url_path + + #: The path to the templates folder, relative to + #: :attr:`root_path`, to add to the template loader. ``None`` if + #: templates should not be added. + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + #: Absolute path to the package on the filesystem. Used to look + #: up resources contained in the package. + self.root_path = root_path + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + #: A dictionary mapping endpoint names to view functions. + #: + #: To register a view function, use the :meth:`route` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.view_functions: dict[str, t.Callable] = {} + + #: A data structure of registered error handlers, in the format + #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is + #: the name of a blueprint the handlers are active for, or + #: ``None`` for all requests. The ``code`` key is the HTTP + #: status code for ``HTTPException``, or ``None`` for + #: other exceptions. The innermost dictionary maps exception + #: classes to handler functions. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.error_handler_spec: dict[ + ft.AppOrBlueprintKey, + dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]], + ] = defaultdict(lambda: defaultdict(dict)) + + #: A data structure of functions to call at the beginning of + #: each request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`before_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.before_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`after_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.after_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.AfterRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request even if an exception is raised, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`teardown_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.teardown_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.TeardownCallable] + ] = defaultdict(list) + + #: A data structure of functions to call to pass extra context + #: values when rendering templates, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`context_processor` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.template_context_processors: dict[ + ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable] + ] = defaultdict(list, {None: [_default_template_ctx_processor]}) + + #: A data structure of functions to call to modify the keyword + #: arguments passed to the view function, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the + #: :meth:`url_value_preprocessor` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_value_preprocessors: dict[ + ft.AppOrBlueprintKey, + list[ft.URLValuePreprocessorCallable], + ] = defaultdict(list) + + #: A data structure of functions to call to modify the keyword + #: arguments when generating URLs, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`url_defaults` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_default_functions: dict[ + ft.AppOrBlueprintKey, list[ft.URLDefaultCallable] + ] = defaultdict(list) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.name!r}>" + + def _check_setup_finished(self, f_name: str) -> None: + raise NotImplementedError + + @property + def static_folder(self) -> str | None: + """The absolute path to the configured static folder. ``None`` + if no static folder is set. + """ + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + else: + return None + + @static_folder.setter + def static_folder(self, value: str | os.PathLike | None) -> None: + if value is not None: + value = os.fspath(value).rstrip(r"\/") + + self._static_folder = value + + @property + def has_static_folder(self) -> bool: + """``True`` if :attr:`static_folder` is set. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @property + def static_url_path(self) -> str | None: + """The URL prefix that the static route will be accessible from. + + If it was not configured during init, it is derived from + :attr:`static_folder`. + """ + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + basename = os.path.basename(self.static_folder) + return f"/{basename}".rstrip("/") + + return None + + @static_url_path.setter + def static_url_path(self, value: str | None) -> None: + if value is not None: + value = value.rstrip("/") + + self._static_url_path = value + + @cached_property + def jinja_loader(self) -> FileSystemLoader | None: + """The Jinja loader for this object's templates. By default this + is a class :class:`jinja2.loaders.FileSystemLoader` to + :attr:`template_folder` if it is set. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) + else: + return None + + def _method_route( + self, + method: str, + rule: str, + options: dict, + ) -> t.Callable[[T_route], T_route]: + if "methods" in options: + raise TypeError("Use the 'route' decorator to use the 'methods' argument.") + + return self.route(rule, methods=[method], **options) + + @setupmethod + def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["GET"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("GET", rule, options) + + @setupmethod + def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["POST"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("POST", rule, options) + + @setupmethod + def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PUT"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PUT", rule, options) + + @setupmethod + def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["DELETE"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("DELETE", rule, options) + + @setupmethod + def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PATCH"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PATCH", rule, options) + + @setupmethod + def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Decorate a view function to register it with the given URL + rule and options. Calls :meth:`add_url_rule`, which has more + details about the implementation. + + .. code-block:: python + + @app.route("/") + def index(): + return "Hello, World!" + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and + ``OPTIONS`` are added automatically. + + :param rule: The URL rule string. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + + def decorator(f: T_route) -> T_route: + endpoint = options.pop("endpoint", None) + self.add_url_rule(rule, endpoint, f, **options) + return f + + return decorator + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a rule for routing incoming requests and building + URLs. The :meth:`route` decorator is a shortcut to call this + with the ``view_func`` argument. These are equivalent: + + .. code-block:: python + + @app.route("/") + def index(): + ... + + .. code-block:: python + + def index(): + ... + + app.add_url_rule("/", view_func=index) + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. An error + will be raised if a function has already been registered for the + endpoint. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is + always added automatically, and ``OPTIONS`` is added + automatically by default. + + ``view_func`` does not necessarily need to be passed, but if the + rule should participate in routing an endpoint name must be + associated with a view function at some point with the + :meth:`endpoint` decorator. + + .. code-block:: python + + app.add_url_rule("/", endpoint="index") + + @app.endpoint("index") + def index(): + ... + + If ``view_func`` has a ``required_methods`` attribute, those + methods are added to the passed and automatic methods. If it + has a ``provide_automatic_methods`` attribute, it is used as the + default if the parameter is not passed. + + :param rule: The URL rule string. + :param endpoint: The endpoint name to associate with the rule + and view function. Used when routing and building URLs. + Defaults to ``view_func.__name__``. + :param view_func: The view function to associate with the + endpoint name. + :param provide_automatic_options: Add the ``OPTIONS`` method and + respond to ``OPTIONS`` requests automatically. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + raise NotImplementedError + + @setupmethod + def endpoint(self, endpoint: str) -> t.Callable[[F], F]: + """Decorate a view function to register it for the given + endpoint. Used if a rule is added without a ``view_func`` with + :meth:`add_url_rule`. + + .. code-block:: python + + app.add_url_rule("/ex", endpoint="example") + + @app.endpoint("example") + def example(): + ... + + :param endpoint: The endpoint name to associate with the view + function. + """ + + def decorator(f: F) -> F: + self.view_functions[endpoint] = f + return f + + return decorator + + @setupmethod + def before_request(self, f: T_before_request) -> T_before_request: + """Register a function to run before each request. + + For example, this can be used to open a database connection, or + to load the logged in user from the session. + + .. code-block:: python + + @app.before_request + def load_user(): + if "user_id" in session: + g.user = db.session.get(session["user_id"]) + + The function will be called without any arguments. If it 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. + + This is available on both app and blueprint objects. When used on an app, this + executes before every request. When used on a blueprint, this executes before + every request that the blueprint handles. To register with a blueprint and + execute before every request, use :meth:`.Blueprint.before_app_request`. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def after_request(self, f: T_after_request) -> T_after_request: + """Register a function to run after each request to this object. + + The function is called with the response object, and must return + a response object. This allows the functions to modify or + replace the response before it is sent. + + If a function raises an exception, any remaining + ``after_request`` functions will not be called. Therefore, this + should not be used for actions that must execute, such as to + close resources. Use :meth:`teardown_request` for that. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.after_app_request`. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f: T_teardown) -> T_teardown: + """Register a function to be called when the request context is + popped. Typically this happens at the end of each request, but + contexts may be pushed manually as well during testing. + + .. code-block:: python + + with app.test_request_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the request context is + made inactive. + + 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. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.teardown_app_request`. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def context_processor( + self, + f: T_template_context_processor, + ) -> T_template_context_processor: + """Registers a template context processor function. These functions run before + rendering a template. The keys of the returned dict are added as variables + available in the template. + + This is available on both app and blueprint objects. When used on an app, this + is called for every rendered template. When used on a blueprint, this is called + for templates rendered from the blueprint's views. To register with a blueprint + and affect every template, use :meth:`.Blueprint.app_context_processor`. + """ + self.template_context_processors[None].append(f) + return f + + @setupmethod + def url_value_preprocessor( + self, + f: T_url_value_preprocessor, + ) -> T_url_value_preprocessor: + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_value_preprocessor`. + """ + self.url_value_preprocessors[None].append(f) + return f + + @setupmethod + def url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_defaults`. + """ + self.url_default_functions[None].append(f) + return f + + @setupmethod + def errorhandler( + self, code_or_exception: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + This is available on both app and blueprint objects. When used on an app, this + can handle errors from every request. When used on a blueprint, this can handle + errors from requests that the blueprint handles. To register with a blueprint + and affect every request, use :meth:`.Blueprint.app_errorhandler`. + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.register_error_handler(code_or_exception, f) + return f + + return decorator + + @setupmethod + def register_error_handler( + self, + code_or_exception: type[Exception] | int, + f: ft.ErrorHandlerCallable, + ) -> None: + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + exc_class, code = self._get_exc_class_and_code(code_or_exception) + self.error_handler_spec[None][code][exc_class] = f + + @staticmethod + def _get_exc_class_and_code( + exc_class_or_code: type[Exception] | int, + ) -> tuple[type[Exception], int | None]: + """Get the exception class being handled. For HTTP status codes + or ``HTTPException`` subclasses, return both the exception and + status code. + + :param exc_class_or_code: Any exception class, or an HTTP status + code as an integer. + """ + exc_class: type[Exception] + + if isinstance(exc_class_or_code, int): + try: + exc_class = default_exceptions[exc_class_or_code] + except KeyError: + raise ValueError( + f"'{exc_class_or_code}' is not a recognized HTTP" + " error code. Use a subclass of HTTPException with" + " that code instead." + ) from None + else: + exc_class = exc_class_or_code + + if isinstance(exc_class, Exception): + raise TypeError( + f"{exc_class!r} is an instance, not a class. Handlers" + " can only be registered for Exception classes or HTTP" + " error codes." + ) + + if not issubclass(exc_class, Exception): + raise ValueError( + f"'{exc_class.__name__}' is not a subclass of Exception." + " Handlers can only be registered for Exception classes" + " or HTTP error codes." + ) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + +def _endpoint_from_view_func(view_func: t.Callable) -> str: + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, "expected view func if endpoint is not provided." + return view_func.__name__ + + +def _path_is_relative_to(path: pathlib.PurePath, base: str) -> bool: + # Path.is_relative_to doesn't exist until Python 3.9 + try: + path.relative_to(base) + return True + except ValueError: + return False + + +def _find_package_path(import_name): + """Find the path that contains the package or module.""" + root_mod_name, _, _ = import_name.partition(".") + + try: + root_spec = importlib.util.find_spec(root_mod_name) + + if root_spec is None: + raise ValueError("not found") + except (ImportError, ValueError): + # ImportError: the machinery told us it does not exist + # ValueError: + # - the module name was invalid + # - the module name is __main__ + # - we raised `ValueError` due to `root_spec` being `None` + return os.getcwd() + + if root_spec.origin in {"namespace", None}: + # namespace package + package_spec = importlib.util.find_spec(import_name) + + if package_spec is not None and package_spec.submodule_search_locations: + # Pick the path in the namespace that contains the submodule. + package_path = pathlib.Path( + os.path.commonpath(package_spec.submodule_search_locations) + ) + search_location = next( + location + for location in root_spec.submodule_search_locations + if _path_is_relative_to(package_path, location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + elif root_spec.submodule_search_locations: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) + + +def find_package(import_name: str): + """Find the prefix that a package is installed under, and the path + that it would be imported from. + + The prefix is the directory containing the standard directory + hierarchy (lib, bin, etc.). If the package is not installed to the + system (:attr:`sys.prefix`) or a virtualenv (``site-packages``), + ``None`` is returned. + + The path is the entry in :attr:`sys.path` that contains the package + for import. If the package is not installed, it's assumed that the + package was imported from the current working directory. + """ + package_path = _find_package_path(import_name) + py_prefix = os.path.abspath(sys.prefix) + + # installed to the system + if _path_is_relative_to(pathlib.PurePath(package_path), py_prefix): + return py_prefix, package_path + + site_parent, site_folder = os.path.split(package_path) + + # installed to a virtualenv + if site_folder.lower() == "site-packages": + parent, folder = os.path.split(site_parent) + + # Windows (prefix/lib/site-packages) + if folder.lower() == "lib": + return parent, package_path + + # Unix (prefix/lib/pythonX.Y/site-packages) + if os.path.basename(parent).lower() == "lib": + return os.path.dirname(parent), package_path + + # something else (prefix/site-packages) + return site_parent, package_path + + # not installed + return None, package_path diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/sessions.py b/testclient/.venv/lib/python3.9/site-packages/flask/sessions.py new file mode 100644 index 0000000..e5650d6 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/sessions.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import hashlib +import typing as t +from collections.abc import MutableMapping +from datetime import datetime +from datetime import timezone + +from itsdangerous import BadSignature +from itsdangerous import URLSafeTimedSerializer +from werkzeug.datastructures import CallbackDict + +from .json.tag import TaggedJSONSerializer + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .wrappers import Request, Response + + +class SessionMixin(MutableMapping): + """Expands a basic dictionary with session attributes.""" + + @property + def permanent(self) -> bool: + """This reflects the ``'_permanent'`` key in the dict.""" + return self.get("_permanent", False) + + @permanent.setter + def permanent(self, value: bool) -> None: + self["_permanent"] = bool(value) + + #: Some implementations can detect whether a session is newly + #: created, but that is not guaranteed. Use with caution. The mixin + # default is hard-coded ``False``. + new = False + + #: Some implementations can detect changes to the session and set + #: this when that happens. The mixin default is hard coded to + #: ``True``. + modified = True + + #: Some implementations can detect when session data is read or + #: written and set this when that happens. The mixin default is hard + #: coded to ``True``. + accessed = True + + +class SecureCookieSession(CallbackDict, SessionMixin): + """Base class for sessions based on signed cookies. + + This session backend will set the :attr:`modified` and + :attr:`accessed` attributes. It cannot reliably track whether a + session is new (vs. empty), so :attr:`new` remains hard coded to + ``False``. + """ + + #: When data is changed, this is set to ``True``. Only the session + #: dictionary itself is tracked; if the session contains mutable + #: data (for example a nested dict) then this must be set to + #: ``True`` manually when modifying that data. The session cookie + #: will only be written to the response if this is ``True``. + modified = False + + #: When data is read or written, this is set to ``True``. Used by + # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` + #: header, which allows caching proxies to cache different pages for + #: different users. + accessed = False + + def __init__(self, initial: t.Any = None) -> None: + def on_update(self) -> None: + self.modified = True + self.accessed = True + + super().__init__(initial, on_update) + + def __getitem__(self, key: str) -> t.Any: + self.accessed = True + return super().__getitem__(key) + + def get(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().get(key, default) + + def setdefault(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().setdefault(key, default) + + +class NullSession(SecureCookieSession): + """Class used to generate nicer error messages if sessions are not + available. Will still allow read-only access to the empty session + but fail on setting. + """ + + def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + raise RuntimeError( + "The session is unavailable because no secret " + "key was set. Set the secret_key on the " + "application to something unique and secret." + ) + + __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950 + del _fail + + +class SessionInterface: + """The basic interface you have to implement in order to replace the + default session interface which uses werkzeug's securecookie + implementation. The only methods you have to implement are + :meth:`open_session` and :meth:`save_session`, the others have + useful defaults which you don't need to change. + + The session object returned by the :meth:`open_session` method has to + provide a dictionary like interface plus the properties and methods + from the :class:`SessionMixin`. We recommend just subclassing a dict + and adding that mixin:: + + class Session(dict, SessionMixin): + pass + + If :meth:`open_session` returns ``None`` Flask will call into + :meth:`make_null_session` to create a session that acts as replacement + if the session support cannot work because some requirement is not + fulfilled. The default :class:`NullSession` class that is created + will complain that the secret key was not set. + + To replace the session interface on an application all you have to do + is to assign :attr:`flask.Flask.session_interface`:: + + app = Flask(__name__) + app.session_interface = MySessionInterface() + + Multiple requests with the same session may be sent and handled + concurrently. When implementing a new session interface, consider + whether reads or writes to the backing store must be synchronized. + There is no guarantee on the order in which the session for each + request is opened or saved, it will occur in the order that requests + begin and end processing. + + .. versionadded:: 0.8 + """ + + #: :meth:`make_null_session` will look here for the class that should + #: be created when a null session is requested. Likewise the + #: :meth:`is_null_session` method will perform a typecheck against + #: this type. + null_session_class = NullSession + + #: A flag that indicates if the session interface is pickle based. + #: This can be used by Flask extensions to make a decision in regards + #: to how to deal with the session object. + #: + #: .. versionadded:: 0.10 + pickle_based = False + + def make_null_session(self, app: Flask) -> NullSession: + """Creates a null session which acts as a replacement object if the + real session support could not be loaded due to a configuration + error. This mainly aids the user experience because the job of the + null session is to still support lookup without complaining but + modifications are answered with a helpful error message of what + failed. + + This creates an instance of :attr:`null_session_class` by default. + """ + return self.null_session_class() + + def is_null_session(self, obj: object) -> bool: + """Checks if a given object is a null session. Null sessions are + not asked to be saved. + + This checks if the object is an instance of :attr:`null_session_class` + by default. + """ + return isinstance(obj, self.null_session_class) + + def get_cookie_name(self, app: Flask) -> str: + """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``.""" + return app.config["SESSION_COOKIE_NAME"] + + def get_cookie_domain(self, app: Flask) -> str | None: + """The value of the ``Domain`` parameter on the session cookie. If not set, + browsers will only send the cookie to the exact domain it was set from. + Otherwise, they will send it to any subdomain of the given value as well. + + Uses the :data:`SESSION_COOKIE_DOMAIN` config. + + .. versionchanged:: 2.3 + Not set by default, does not fall back to ``SERVER_NAME``. + """ + rv = app.config["SESSION_COOKIE_DOMAIN"] + return rv if rv else None + + def get_cookie_path(self, app: Flask) -> str: + """Returns the path for which the cookie should be valid. The + default implementation uses the value from the ``SESSION_COOKIE_PATH`` + config var if it's set, and falls back to ``APPLICATION_ROOT`` or + uses ``/`` if it's ``None``. + """ + return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"] + + def get_cookie_httponly(self, app: Flask) -> bool: + """Returns True if the session cookie should be httponly. This + currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` + config var. + """ + return app.config["SESSION_COOKIE_HTTPONLY"] + + def get_cookie_secure(self, app: Flask) -> bool: + """Returns True if the cookie should be secure. This currently + just returns the value of the ``SESSION_COOKIE_SECURE`` setting. + """ + return app.config["SESSION_COOKIE_SECURE"] + + def get_cookie_samesite(self, app: Flask) -> str: + """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the + ``SameSite`` attribute. This currently just returns the value of + the :data:`SESSION_COOKIE_SAMESITE` setting. + """ + return app.config["SESSION_COOKIE_SAMESITE"] + + def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None: + """A helper method that returns an expiration date for the session + or ``None`` if the session is linked to the browser session. The + default implementation returns now + the permanent session + lifetime configured on the application. + """ + if session.permanent: + return datetime.now(timezone.utc) + app.permanent_session_lifetime + return None + + def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool: + """Used by session backends to determine if a ``Set-Cookie`` header + should be set for this session cookie for this response. If the session + has been modified, the cookie is set. If the session is permanent and + the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is + always set. + + This check is usually skipped if the session was deleted. + + .. versionadded:: 0.11 + """ + + return session.modified or ( + session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"] + ) + + def open_session(self, app: Flask, request: Request) -> SessionMixin | None: + """This is called at the beginning of each request, after + pushing the request context, before matching the URL. + + This must return an object which implements a dictionary-like + interface as well as the :class:`SessionMixin` interface. + + This will return ``None`` to indicate that loading failed in + some way that is not immediately an error. The request + context will fall back to using :meth:`make_null_session` + in this case. + """ + raise NotImplementedError() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + """This is called at the end of each request, after generating + a response, before removing the request context. It is skipped + if :meth:`is_null_session` returns ``True``. + """ + raise NotImplementedError() + + +session_json_serializer = TaggedJSONSerializer() + + +class SecureCookieSessionInterface(SessionInterface): + """The default session interface that stores sessions in signed cookies + through the :mod:`itsdangerous` module. + """ + + #: the salt that should be applied on top of the secret key for the + #: signing of cookie based sessions. + salt = "cookie-session" + #: the hash function to use for the signature. The default is sha1 + digest_method = staticmethod(hashlib.sha1) + #: the name of the itsdangerous supported key derivation. The default + #: is hmac. + key_derivation = "hmac" + #: A python serializer for the payload. The default is a compact + #: JSON derived serializer with support for some extra Python types + #: such as datetime objects or tuples. + serializer = session_json_serializer + session_class = SecureCookieSession + + def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: + if not app.secret_key: + return None + signer_kwargs = dict( + key_derivation=self.key_derivation, digest_method=self.digest_method + ) + return URLSafeTimedSerializer( + app.secret_key, + salt=self.salt, + serializer=self.serializer, + signer_kwargs=signer_kwargs, + ) + + def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: + s = self.get_signing_serializer(app) + if s is None: + return None + val = request.cookies.get(self.get_cookie_name(app)) + if not val: + return self.session_class() + max_age = int(app.permanent_session_lifetime.total_seconds()) + try: + data = s.loads(val, max_age=max_age) + return self.session_class(data) + except BadSignature: + return self.session_class() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + name = self.get_cookie_name(app) + domain = self.get_cookie_domain(app) + path = self.get_cookie_path(app) + secure = self.get_cookie_secure(app) + samesite = self.get_cookie_samesite(app) + httponly = self.get_cookie_httponly(app) + + # Add a "Vary: Cookie" header if the session was accessed at all. + if session.accessed: + response.vary.add("Cookie") + + # If the session is modified to be empty, remove the cookie. + # If the session is empty, return without setting the cookie. + if not session: + if session.modified: + response.delete_cookie( + name, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + httponly=httponly, + ) + response.vary.add("Cookie") + + return + + if not self.should_set_cookie(app, session): + return + + expires = self.get_expiration_time(app, session) + val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore + response.set_cookie( + name, + val, # type: ignore + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/signals.py b/testclient/.venv/lib/python3.9/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/signals.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from blinker import Namespace + +# This namespace is only for signals provided by Flask itself. +_signals = Namespace() + +template_rendered = _signals.signal("template-rendered") +before_render_template = _signals.signal("before-render-template") +request_started = _signals.signal("request-started") +request_finished = _signals.signal("request-finished") +request_tearing_down = _signals.signal("request-tearing-down") +got_request_exception = _signals.signal("got-request-exception") +appcontext_tearing_down = _signals.signal("appcontext-tearing-down") +appcontext_pushed = _signals.signal("appcontext-pushed") +appcontext_popped = _signals.signal("appcontext-popped") +message_flashed = _signals.signal("message-flashed") diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/templating.py b/testclient/.venv/lib/python3.9/site-packages/flask/templating.py new file mode 100644 index 0000000..8dff8ba --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/templating.py @@ -0,0 +1,221 @@ +from __future__ import annotations + +import typing as t + +from jinja2 import BaseLoader +from jinja2 import Environment as BaseEnvironment +from jinja2 import Template +from jinja2 import TemplateNotFound + +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .helpers import stream_with_context +from .signals import before_render_template +from .signals import template_rendered + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sansio.app import App + from .sansio.scaffold import Scaffold + + +def _default_template_ctx_processor() -> dict[str, t.Any]: + """Default template context processor. Injects `request`, + `session` and `g`. + """ + appctx = _cv_app.get(None) + reqctx = _cv_request.get(None) + rv: dict[str, t.Any] = {} + if appctx is not None: + rv["g"] = appctx.g + if reqctx is not None: + rv["request"] = reqctx.request + rv["session"] = reqctx.session + return rv + + +class Environment(BaseEnvironment): + """Works like a regular Jinja2 environment but has some additional + knowledge of how Flask's blueprint works so that it can prepend the + name of the blueprint to referenced templates if necessary. + """ + + def __init__(self, app: App, **options: t.Any) -> None: + if "loader" not in options: + options["loader"] = app.create_global_jinja_loader() + BaseEnvironment.__init__(self, **options) + self.app = app + + +class DispatchingJinjaLoader(BaseLoader): + """A loader that looks for templates in the application and all + the blueprint folders. + """ + + def __init__(self, app: App) -> None: + self.app = app + + def get_source( # type: ignore + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + if self.app.config["EXPLAIN_TEMPLATE_LOADING"]: + return self._get_source_explained(environment, template) + return self._get_source_fast(environment, template) + + def _get_source_explained( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + attempts = [] + rv: tuple[str, str | None, t.Callable[[], bool] | None] | None + trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None + + for srcobj, loader in self._iter_loaders(template): + try: + rv = loader.get_source(environment, template) + if trv is None: + trv = rv + except TemplateNotFound: + rv = None + attempts.append((loader, srcobj, rv)) + + from .debughelpers import explain_template_loading_attempts + + explain_template_loading_attempts(self.app, template, attempts) + + if trv is not None: + return trv + raise TemplateNotFound(template) + + def _get_source_fast( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + for _srcobj, loader in self._iter_loaders(template): + try: + return loader.get_source(environment, template) + except TemplateNotFound: + continue + raise TemplateNotFound(template) + + def _iter_loaders( + self, template: str + ) -> t.Generator[tuple[Scaffold, BaseLoader], None, None]: + loader = self.app.jinja_loader + if loader is not None: + yield self.app, loader + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + yield blueprint, loader + + def list_templates(self) -> list[str]: + result = set() + loader = self.app.jinja_loader + if loader is not None: + result.update(loader.list_templates()) + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + for template in loader.list_templates(): + result.add(template) + + return list(result) + + +def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + rv = template.render(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + return rv + + +def render_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> str: + """Render a template by name with the given context. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _render(app, template, context) + + +def render_template_string(source: str, **context: t.Any) -> str: + """Render a template from the given source string with the given + context. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _render(app, template, context) + + +def _stream( + app: Flask, template: Template, context: dict[str, t.Any] +) -> t.Iterator[str]: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + def generate() -> t.Iterator[str]: + yield from template.generate(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + rv = generate() + + # If a request context is active, keep it while generating. + if request: + rv = stream_with_context(rv) + + return rv + + +def stream_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> t.Iterator[str]: + """Render a template by name with the given context as a stream. + This returns an iterator of strings, which can be used as a + streaming response from a view. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _stream(app, template, context) + + +def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]: + """Render a template from the given source string with the given + context as a stream. This returns an iterator of strings, which can + be used as a streaming response from a view. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _stream(app, template, context) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/testing.py b/testclient/.venv/lib/python3.9/site-packages/flask/testing.py new file mode 100644 index 0000000..69aa785 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/testing.py @@ -0,0 +1,295 @@ +from __future__ import annotations + +import importlib.metadata +import typing as t +from contextlib import contextmanager +from contextlib import ExitStack +from copy import copy +from types import TracebackType +from urllib.parse import urlsplit + +import werkzeug.test +from click.testing import CliRunner +from werkzeug.test import Client +from werkzeug.wrappers import Request as BaseRequest + +from .cli import ScriptInfo +from .sessions import SessionMixin + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.test import TestResponse + + from .app import Flask + + +class EnvironBuilder(werkzeug.test.EnvironBuilder): + """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the + application. + + :param app: The Flask application to configure the environment from. + :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 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`. + """ + + def __init__( + self, + app: Flask, + path: str = "/", + base_url: str | None = None, + subdomain: str | None = None, + url_scheme: str | None = None, + *args: t.Any, + **kwargs: t.Any, + ) -> None: + assert not (base_url or subdomain or url_scheme) or ( + base_url is not None + ) != bool( + subdomain or url_scheme + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + + if base_url is None: + http_host = app.config.get("SERVER_NAME") or "localhost" + app_root = app.config["APPLICATION_ROOT"] + + if subdomain: + http_host = f"{subdomain}.{http_host}" + + if url_scheme is None: + url_scheme = app.config["PREFERRED_URL_SCHEME"] + + url = urlsplit(path) + base_url = ( + f"{url.scheme or url_scheme}://{url.netloc or http_host}" + f"/{app_root.lstrip('/')}" + ) + path = url.path + + if url.query: + sep = b"?" if isinstance(url.query, bytes) else "?" + path += sep + url.query + + self.app = app + super().__init__(path, base_url, *args, **kwargs) + + def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore + """Serialize ``obj`` to a JSON-formatted string. + + The serialization will be configured according to the config associated + with this EnvironBuilder's ``app``. + """ + return self.app.json.dumps(obj, **kwargs) + + +_werkzeug_version = "" + + +def _get_werkzeug_version() -> str: + global _werkzeug_version + + if not _werkzeug_version: + _werkzeug_version = importlib.metadata.version("werkzeug") + + return _werkzeug_version + + +class FlaskClient(Client): + """Works like a regular Werkzeug test client but has knowledge about + Flask's contexts to defer the cleanup of the request context until + the end of a ``with`` block. For general information about how to + use this class refer to :class:`werkzeug.test.Client`. + + .. versionchanged:: 0.12 + `app.test_client()` includes preset default environment, which can be + set after instantiation of the `app.test_client()` object in + `client.environ_base`. + + Basic usage is outlined in the :doc:`/testing` chapter. + """ + + application: Flask + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + super().__init__(*args, **kwargs) + self.preserve_context = False + self._new_contexts: list[t.ContextManager[t.Any]] = [] + self._context_stack = ExitStack() + self.environ_base = { + "REMOTE_ADDR": "127.0.0.1", + "HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}", + } + + @contextmanager + def session_transaction( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Generator[SessionMixin, None, None]: + """When used in combination with a ``with`` statement this opens a + session transaction. This can be used to modify the session that + the test client uses. Once the ``with`` block is left the session is + stored back. + + :: + + with client.session_transaction() as session: + session['value'] = 42 + + Internally this is implemented by going through a temporary test + request context and since session handling could depend on + request variables this function accepts the same arguments as + :meth:`~flask.Flask.test_request_context` which are directly + passed through. + """ + if self._cookies is None: + raise TypeError( + "Cookies are disabled. Create a client with 'use_cookies=True'." + ) + + app = self.application + ctx = app.test_request_context(*args, **kwargs) + self._add_cookies_to_wsgi(ctx.request.environ) + + with ctx: + sess = app.session_interface.open_session(app, ctx.request) + + if sess is None: + raise RuntimeError("Session backend did not open a session.") + + yield sess + resp = app.response_class() + + if app.session_interface.is_null_session(sess): + return + + with ctx: + app.session_interface.save_session(app, sess, resp) + + self._update_cookies_from_response( + ctx.request.host.partition(":")[0], + ctx.request.path, + resp.headers.getlist("Set-Cookie"), + ) + + def _copy_environ(self, other): + out = {**self.environ_base, **other} + + if self.preserve_context: + out["werkzeug.debug.preserve_context"] = self._new_contexts.append + + return out + + def _request_from_builder_args(self, args, kwargs): + kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {})) + builder = EnvironBuilder(self.application, *args, **kwargs) + + try: + return builder.get_request() + finally: + builder.close() + + def open( + self, + *args: t.Any, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> TestResponse: + if args and isinstance( + args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest) + ): + if isinstance(args[0], werkzeug.test.EnvironBuilder): + builder = copy(args[0]) + builder.environ_base = self._copy_environ(builder.environ_base or {}) + request = builder.get_request() + elif isinstance(args[0], dict): + request = EnvironBuilder.from_environ( + args[0], app=self.application, environ_base=self._copy_environ({}) + ).get_request() + else: + # isinstance(args[0], BaseRequest) + request = copy(args[0]) + request.environ = self._copy_environ(request.environ) + else: + # request is None + request = self._request_from_builder_args(args, kwargs) + + # Pop any previously preserved contexts. This prevents contexts + # from being preserved across redirects or multiple requests + # within a single block. + self._context_stack.close() + + response = super().open( + request, + buffered=buffered, + follow_redirects=follow_redirects, + ) + response.json_module = self.application.json # type: ignore[assignment] + + # Re-push contexts that were preserved during the request. + while self._new_contexts: + cm = self._new_contexts.pop() + self._context_stack.enter_context(cm) + + return response + + def __enter__(self) -> FlaskClient: + if self.preserve_context: + raise RuntimeError("Cannot nest client invocations") + self.preserve_context = True + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.preserve_context = False + self._context_stack.close() + + +class FlaskCliRunner(CliRunner): + """A :class:`~click.testing.CliRunner` for testing a Flask app's + CLI commands. Typically created using + :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`. + """ + + def __init__(self, app: Flask, **kwargs: t.Any) -> None: + self.app = app + super().__init__(**kwargs) + + def invoke( # type: ignore + self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any + ) -> t.Any: + """Invokes a CLI command in an isolated environment. See + :meth:`CliRunner.invoke ` for + full method documentation. See :ref:`testing-cli` for examples. + + If the ``obj`` argument is not given, passes an instance of + :class:`~flask.cli.ScriptInfo` that knows how to load the Flask + app being tested. + + :param cli: Command object to invoke. Default is the app's + :attr:`~flask.app.Flask.cli` group. + :param args: List of strings to invoke the command with. + + :return: a :class:`~click.testing.Result` object. + """ + if cli is None: + cli = self.app.cli # type: ignore + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/typing.py b/testclient/.venv/lib/python3.9/site-packages/flask/typing.py new file mode 100644 index 0000000..a8c9ba0 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/typing.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIApplication # noqa: F401 + from werkzeug.datastructures import Headers # noqa: F401 + from werkzeug.sansio.response import Response # noqa: F401 + +# The possible types that are directly convertible or are a Response object. +ResponseValue = t.Union[ + "Response", + str, + bytes, + t.List[t.Any], + # Only dict is actually accepted, but Mapping allows for TypedDict. + t.Mapping[str, t.Any], + t.Iterator[str], + t.Iterator[bytes], +] + +# the possible types for an individual HTTP header +# This should be a Union, but mypy doesn't pass unless it's a TypeVar. +HeaderValue = t.Union[str, t.List[str], t.Tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[t.Tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + t.Tuple[ResponseValue, HeadersValue], + t.Tuple[ResponseValue, int], + t.Tuple[ResponseValue, int, HeadersValue], + "WSGIApplication", +] + +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + +AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named +AfterRequestCallable = t.Union[ + t.Callable[[ResponseClass], ResponseClass], + t.Callable[[ResponseClass], t.Awaitable[ResponseClass]], +] +BeforeFirstRequestCallable = t.Union[ + t.Callable[[], None], t.Callable[[], t.Awaitable[None]] +] +BeforeRequestCallable = t.Union[ + t.Callable[[], t.Optional[ResponseReturnValue]], + t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]], +] +ShellContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]] +TeardownCallable = t.Union[ + t.Callable[[t.Optional[BaseException]], None], + t.Callable[[t.Optional[BaseException]], t.Awaitable[None]], +] +TemplateContextProcessorCallable = t.Union[ + t.Callable[[], t.Dict[str, t.Any]], + t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict], None] +URLValuePreprocessorCallable = t.Callable[[t.Optional[str], t.Optional[dict]], None] + +# This should take Exception, but that either breaks typing the argument +# with a specific exception, or decorating multiple times with different +# exceptions (and using a union type on the argument). +# https://github.com/pallets/flask/issues/4095 +# https://github.com/pallets/flask/issues/4295 +# https://github.com/pallets/flask/issues/4297 +ErrorHandlerCallable = t.Union[ + t.Callable[[t.Any], ResponseReturnValue], + t.Callable[[t.Any], t.Awaitable[ResponseReturnValue]], +] + +RouteCallable = t.Union[ + t.Callable[..., ResponseReturnValue], + t.Callable[..., t.Awaitable[ResponseReturnValue]], +] diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/views.py b/testclient/.venv/lib/python3.9/site-packages/flask/views.py new file mode 100644 index 0000000..c7a2b62 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/views.py @@ -0,0 +1,190 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + + +http_method_funcs = frozenset( + ["get", "post", "head", "options", "delete", "put", "trace", "patch"] +) + + +class View: + """Subclass this class and override :meth:`dispatch_request` to + create a generic class-based view. Call :meth:`as_view` to create a + view function that creates an instance of the class with the given + arguments and calls its ``dispatch_request`` method with any URL + variables. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class Hello(View): + init_every_request = False + + def dispatch_request(self, name): + return f"Hello, {name}!" + + app.add_url_rule( + "/hello/", view_func=Hello.as_view("hello") + ) + + Set :attr:`methods` on the class to change what methods the view + accepts. + + Set :attr:`decorators` on the class to apply a list of decorators to + the generated view function. Decorators applied to the class itself + will not be applied to the generated view function! + + Set :attr:`init_every_request` to ``False`` for efficiency, unless + you need to store request-global data on ``self``. + """ + + #: The methods this view is registered for. Uses the same default + #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and + #: ``add_url_rule`` by default. + methods: t.ClassVar[t.Collection[str] | None] = None + + #: Control whether the ``OPTIONS`` method is handled automatically. + #: Uses the same default (``True``) as ``route`` and + #: ``add_url_rule`` by default. + provide_automatic_options: t.ClassVar[bool | None] = None + + #: A list of decorators to apply, in order, to the generated view + #: function. Remember that ``@decorator`` syntax is applied bottom + #: to top, so the first decorator in the list would be the bottom + #: decorator. + #: + #: .. versionadded:: 0.8 + decorators: t.ClassVar[list[t.Callable]] = [] + + #: Create a new instance of this view class for every request by + #: default. If a view subclass sets this to ``False``, the same + #: instance is used for every request. + #: + #: A single instance is more efficient, especially if complex setup + #: is done during init. However, storing data on ``self`` is no + #: longer safe across requests, and :data:`~flask.g` should be used + #: instead. + #: + #: .. versionadded:: 2.2 + init_every_request: t.ClassVar[bool] = True + + def dispatch_request(self) -> ft.ResponseReturnValue: + """The actual view function behavior. Subclasses must override + this and return a valid response. Any variables from the URL + rule are passed as keyword arguments. + """ + raise NotImplementedError() + + @classmethod + def as_view( + cls, name: str, *class_args: t.Any, **class_kwargs: t.Any + ) -> ft.RouteCallable: + """Convert the class into a view function that can be registered + for a route. + + By default, the generated view will create a new instance of the + view class for every request and call its + :meth:`dispatch_request` method. If the view class sets + :attr:`init_every_request` to ``False``, the same instance will + be used for every request. + + Except for ``name``, all other arguments passed to this method + are forwarded to the view class ``__init__`` method. + + .. versionchanged:: 2.2 + Added the ``init_every_request`` class attribute. + """ + if cls.init_every_request: + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + self = view.view_class( # type: ignore[attr-defined] + *class_args, **class_kwargs + ) + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + else: + self = cls(*class_args, **class_kwargs) + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + if cls.decorators: + view.__name__ = name + view.__module__ = cls.__module__ + for decorator in cls.decorators: + view = decorator(view) + + # We attach the view class to the view function for two reasons: + # first of all it allows us to easily figure out what class-based + # view this thing came from, secondly it's also used for instantiating + # the view class so you can actually replace it with something else + # for testing purposes and debugging. + view.view_class = cls # type: ignore + view.__name__ = name + view.__doc__ = cls.__doc__ + view.__module__ = cls.__module__ + view.methods = cls.methods # type: ignore + view.provide_automatic_options = cls.provide_automatic_options # type: ignore + return view + + +class MethodView(View): + """Dispatches request methods to the corresponding instance methods. + For example, if you implement a ``get`` method, it will be used to + handle ``GET`` requests. + + This can be useful for defining a REST API. + + :attr:`methods` is automatically set based on the methods defined on + the class. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class CounterAPI(MethodView): + def get(self): + return str(session.get("counter", 0)) + + def post(self): + session["counter"] = session.get("counter", 0) + 1 + return redirect(url_for("counter")) + + app.add_url_rule( + "/counter", view_func=CounterAPI.as_view("counter") + ) + """ + + def __init_subclass__(cls, **kwargs: t.Any) -> None: + super().__init_subclass__(**kwargs) + + if "methods" not in cls.__dict__: + methods = set() + + for base in cls.__bases__: + if getattr(base, "methods", None): + methods.update(base.methods) # type: ignore[attr-defined] + + for key in http_method_funcs: + if hasattr(cls, key): + methods.add(key.upper()) + + if methods: + cls.methods = methods + + def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue: + meth = getattr(self, request.method.lower(), None) + + # If the request method is HEAD and we don't have a handler for it + # retry with GET. + if meth is None and request.method == "HEAD": + meth = getattr(self, "get", None) + + assert meth is not None, f"Unimplemented method {request.method!r}" + return current_app.ensure_sync(meth)(**kwargs) diff --git a/testclient/.venv/lib/python3.9/site-packages/flask/wrappers.py b/testclient/.venv/lib/python3.9/site-packages/flask/wrappers.py new file mode 100644 index 0000000..ef7aa38 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/flask/wrappers.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.wrappers import Request as RequestBase +from werkzeug.wrappers import Response as ResponseBase + +from . import json +from .globals import current_app +from .helpers import _split_blueprint_path + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.routing import Rule + + +class Request(RequestBase): + """The request object used by default in Flask. Remembers the + matched endpoint and view arguments. + + It is what ends up as :class:`~flask.request`. If you want to replace + the request object used you can subclass this and set + :attr:`~flask.Flask.request_class` to your subclass. + + The request object is a :class:`~werkzeug.wrappers.Request` subclass and + provides all of the attributes Werkzeug defines plus a few Flask + specific ones. + """ + + json_module: t.Any = json + + #: The internal URL rule that matched the request. This can be + #: useful to inspect which methods are allowed for the URL from + #: a before/after handler (``request.url_rule.methods``) etc. + #: Though if the request's method was invalid for the URL rule, + #: the valid list is available in ``routing_exception.valid_methods`` + #: instead (an attribute of the Werkzeug exception + #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) + #: because the request was never internally bound. + #: + #: .. versionadded:: 0.6 + url_rule: Rule | None = None + + #: A dict of view arguments that matched the request. If an exception + #: happened when matching, this will be ``None``. + view_args: dict[str, t.Any] | None = None + + #: If matching the URL failed, this is the exception that will be + #: raised / was raised as part of the request handling. This is + #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or + #: something similar. + routing_exception: Exception | None = None + + @property + def max_content_length(self) -> int | None: # type: ignore + """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" + if current_app: + return current_app.config["MAX_CONTENT_LENGTH"] + else: + return None + + @property + def endpoint(self) -> str | None: + """The endpoint that matched the request URL. + + This will be ``None`` if matching failed or has not been + performed yet. + + This in combination with :attr:`view_args` can be used to + reconstruct the same URL or a modified URL. + """ + if self.url_rule is not None: + return self.url_rule.endpoint + + return None + + @property + def blueprint(self) -> str | None: + """The registered name of the current blueprint. + + This will be ``None`` if the endpoint is not part of a + blueprint, or if URL matching failed or has not been performed + yet. + + This does not necessarily match the name the blueprint was + created with. It may have been nested, or registered with a + different name. + """ + endpoint = self.endpoint + + if endpoint is not None and "." in endpoint: + return endpoint.rpartition(".")[0] + + return None + + @property + def blueprints(self) -> list[str]: + """The registered names of the current blueprint upwards through + parent blueprints. + + This will be an empty list if there is no current blueprint, or + if URL matching failed. + + .. versionadded:: 2.0.1 + """ + name = self.blueprint + + if name is None: + return [] + + return _split_blueprint_path(name) + + def _load_form_data(self) -> None: + super()._load_form_data() + + # In debug mode we're replacing the files multidict with an ad-hoc + # subclass that raises a different error for key errors. + if ( + current_app + and current_app.debug + and self.mimetype != "multipart/form-data" + and not self.files + ): + from .debughelpers import attach_enctype_error_multidict + + attach_enctype_error_multidict(self) + + def on_json_loading_failed(self, e: ValueError | None) -> t.Any: + try: + return super().on_json_loading_failed(e) + except BadRequest as e: + if current_app and current_app.debug: + raise + + raise BadRequest() from e + + +class Response(ResponseBase): + """The response object that is used by default in Flask. Works like the + response object from Werkzeug but is set to have an HTML mimetype by + default. Quite often you don't have to create this object yourself because + :meth:`~flask.Flask.make_response` will take care of that for you. + + If you want to replace the response object used you can subclass this and + set :attr:`~flask.Flask.response_class` to your subclass. + + .. versionchanged:: 1.0 + JSON support is added to the response, like the request. This is useful + when testing to get the test client response data as JSON. + + .. versionchanged:: 1.0 + + Added :attr:`max_cookie_size`. + """ + + default_mimetype: str | None = "text/html" + + json_module = json + + autocorrect_location_header = False + + @property + def max_cookie_size(self) -> int: # type: ignore + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config["MAX_COOKIE_SIZE"] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/LICENSE.md b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/LICENSE.md new file mode 100644 index 0000000..b6f8732 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/LICENSE.md @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2013-2021, Kim Davies +All rights reserved. + +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/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/METADATA new file mode 100644 index 0000000..07f6193 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/METADATA @@ -0,0 +1,242 @@ +Metadata-Version: 2.1 +Name: idna +Version: 3.4 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.5 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +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: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna + +Internationalized Domain Names in Applications (IDNA) +===================================================== + +Support for the Internationalized Domain Names in +Applications (IDNA) protocol as specified in `RFC 5891 +`_. This is the latest version of +the protocol and is sometimes referred to as “IDNA 2008”. + +This library also provides support for Unicode Technical +Standard 46, `Unicode IDNA Compatibility Processing +`_. + +This acts as a suitable replacement for the “encodings.idna” +module that comes with the Python standard library, but which +only supports the older superseded IDNA specification (`RFC 3490 +`_). + +Basic functions are simply executed: + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + + +Installation +------------ + +This package is available for installation from PyPI: + +.. code-block:: bash + + $ python3 -m pip install idna + + +Usage +----- + +For typical usage, the ``encode`` and ``decode`` functions will take a +domain name argument and perform a conversion to A-labels or U-labels +respectively. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + +You may use the codec encoding and decoding methods using the +``idna.codec`` module: + +.. code-block:: pycon + + >>> import idna.codec + >>> print('домен.испытание'.encode('idna')) + b'xn--d1acufc.xn--80akhbyknj4f' + >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna')) + домен.испытание + +Conversions can be applied at a per-label basis using the ``ulabel`` or +``alabel`` functions if necessary: + +.. code-block:: pycon + + >>> idna.alabel('测试') + b'xn--0zwm56d' + +Compatibility Mapping (UTS #46) ++++++++++++++++++++++++++++++++ + +As described in `RFC 5895 `_, the +IDNA specification does not normalize input from different potential +ways a user may input a domain name. This functionality, known as +a “mapping”, is considered by the specification to be a local +user-interface issue distinct from IDNA conversion functionality. + +This library provides one such mapping, that was developed by the +Unicode Consortium. Known as `Unicode IDNA Compatibility Processing +`_, it provides for both a regular +mapping for typical applications, as well as a transitional mapping to +help migrate from older IDNA 2003 applications. + +For example, “Königsgäßchen” is not a permissible label as *LATIN +CAPITAL LETTER K* is not allowed (nor are capital letters in general). +UTS 46 will convert this into lower case prior to applying the IDNA +conversion. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('Königsgäßchen') + ... + idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed + >>> idna.encode('Königsgäßchen', uts46=True) + b'xn--knigsgchen-b4a3dun' + >>> print(idna.decode('xn--knigsgchen-b4a3dun')) + königsgäßchen + +Transitional processing provides conversions to help transition from +the older 2003 standard to the current standard. For example, in the +original IDNA specification, the *LATIN SMALL LETTER SHARP S* (ß) was +converted into two *LATIN SMALL LETTER S* (ss), whereas in the current +IDNA specification this conversion is not performed. + +.. code-block:: pycon + + >>> idna.encode('Königsgäßchen', uts46=True, transitional=True) + 'xn--knigsgsschen-lcb0w' + +Implementors should use transitional processing with caution, only in +rare cases where conversion from legacy labels to current labels must be +performed (i.e. IDNA implementations that pre-date 2008). For typical +applications that just need to convert labels, transitional processing +is unlikely to be beneficial and could produce unexpected incompatible +results. + +``encodings.idna`` Compatibility +++++++++++++++++++++++++++++++++ + +Function calls from the Python built-in ``encodings.idna`` module are +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module. +Simply substitute the ``import`` clause in your code to refer to the new +module name. + +Exceptions +---------- + +All errors raised during the conversion following the specification +should raise an exception derived from the ``idna.IDNAError`` base +class. + +More specific exceptions that may be generated as ``idna.IDNABidiError`` +when the error reflects an illegal combination of left-to-right and +right-to-left characters in a label; ``idna.InvalidCodepoint`` when +a specific codepoint is an illegal character in an IDN label (i.e. +INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is +illegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ +but the contextual requirements are not satisfied.) + +Building and Diagnostics +------------------------ + +The IDNA and UTS 46 functionality relies upon pre-calculated lookup +tables for performance. These tables are derived from computing against +eligibility criteria in the respective standards. These tables are +computed using the command-line script ``tools/idna-data``. + +This tool will fetch relevant codepoint data from the Unicode repository +and perform the required calculations to identify eligibility. There are +three main modes: + +* ``idna-data make-libdata``. Generates ``idnadata.py`` and + ``uts46data.py``, the pre-calculated lookup tables using for IDNA and + UTS 46 conversions. Implementors who wish to track this library against + a different Unicode version may use this tool to manually generate a + different version of the ``idnadata.py`` and ``uts46data.py`` files. + +* ``idna-data make-table``. Generate a table of the IDNA disposition + (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix + B.1 of RFC 5892 and the pre-computed tables published by `IANA + `_. + +* ``idna-data U+0061``. Prints debugging output on the various + properties associated with an individual Unicode codepoint (in this + case, U+0061), that are used to assess the IDNA and UTS 46 status of a + codepoint. This is helpful in debugging or analysis. + +The tool accepts a number of arguments, described using ``idna-data +-h``. Most notably, the ``--version`` argument allows the specification +of the version of Unicode to use in computing the table data. For +example, ``idna-data --version 9.0.0 make-libdata`` will generate +library data against Unicode 9.0.0. + + +Additional Notes +---------------- + +* **Packages**. The latest tagged release version is published in the + `Python Package Index `_. + +* **Version support**. This library supports Python 3.5 and higher. + As this library serves as a low-level toolkit for a variety of + applications, many of which strive for broad compatibility with older + Python versions, there is no rush to remove older intepreter support. + Removing support for older versions should be well justified in that the + maintenance burden has become too high. + +* **Python 2**. Python 2 is supported by version 2.x of this library. + While active development of the version 2.x series has ended, notable + issues being corrected may be backported to 2.x. Use "idna<3" in your + requirements file if you need this library for a Python 2 application. + +* **Testing**. The library has a test suite based on each rule of the + IDNA specification, as well as tests that are provided as part of the + Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing + `_. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the technical standard IDNA 2008 and emoji domains are broadly phased + out across the domain industry due to associated security risks. For + now, applications that wish need to support these non-compliant labels + may wish to consider trying the encode/decode operation in this library + first, and then falling back to using `encodings.idna`. See `the Github + project `_ for more discussion. + diff --git a/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/RECORD new file mode 100644 index 0000000..a11bdb5 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/RECORD @@ -0,0 +1,22 @@ +idna-3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-3.4.dist-info/LICENSE.md,sha256=otbk2UC9JNvnuWRc3hmpeSzFHbeuDVrNMBrIYMqj6DY,1523 +idna-3.4.dist-info/METADATA,sha256=8aLSf9MFS7oB26pZh2hprg7eJp0UJSc-3rpf_evp4DA,9830 +idna-3.4.dist-info/RECORD,, +idna-3.4.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81 +idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849 +idna/__pycache__/__init__.cpython-39.pyc,, +idna/__pycache__/codec.cpython-39.pyc,, +idna/__pycache__/compat.cpython-39.pyc,, +idna/__pycache__/core.cpython-39.pyc,, +idna/__pycache__/idnadata.cpython-39.pyc,, +idna/__pycache__/intranges.cpython-39.pyc,, +idna/__pycache__/package_data.cpython-39.pyc,, +idna/__pycache__/uts46data.cpython-39.pyc,, +idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374 +idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321 +idna/core.py,sha256=1JxchwKzkxBSn7R_oCE12oBu3eVux0VzdxolmIad24M,12950 +idna/idnadata.py,sha256=xUjqKqiJV8Ho_XzBpAtv5JFoVPSupK-SUXvtjygUHqw,44375 +idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881 +idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21 +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/WHEEL new file mode 100644 index 0000000..668ba4d --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna-3.4.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.7.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__init__.py b/testclient/.venv/lib/python3.9/site-packages/idna/__init__.py new file mode 100644 index 0000000..a40eeaf --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/__init__.py @@ -0,0 +1,44 @@ +from .package_data import __version__ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .intranges import intranges_contain + +__all__ = [ + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e1256495650f636548c982c7d8158d7c9ce851d GIT binary patch literal 852 zcmbu7y^qr{6u^^yq)pTG`+A6xtwWpP5E2qX2M5C~ClH$#%T0W(sh=G=ZbkncHvT1V zh>3rJ3BTlo&fF6lx8e8Nw($E4e~wD4|MC@xp5=!&*h#gst<127=#j5 zFiCR_TcNmdNn>w3#Eqiva~Bmn_n}?HRr5YJpCm_HJ%2$B2UfaKouYSEC-V7`uHCG; zum7ZytDW7ud1I@r5o-5f^o^PN5)D&3Ue)fHP^-D|!wgIZ(M3dv9-@zk5jc61Aclw( zF+yA*#)t`GikKnhh=s@9>WLecEI+Uvrv z1?DNHhWK@#?KSYsXkPL4slpL>WvlHPn{BjQ15-Y4lUZKbTnesiwmETi%B0w4<=O7F sy4t+VDq;Ehp~xx|g<=_{xCNAM%Cqag0$m&>e~tTDVS|U^hsCh<8zKGalK=n! literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/codec.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/codec.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b3f72ca7b433675cbe232467a6f687ad2259b28 GIT binary patch literal 3089 zcmds3OK%)S5T2g*u6J!`?Ia|G#J0p^k-Q58gpiWRkVGgKBM~0bps<>q?sdkQ$EKz? z$YCr+ajx(SaP9u_1du!0x1`IH8ovd^>kNPe^tFbU}58rm; zr?sG#)`L1TgttA#ogEf5J~g<@y+;Q3guC9{vVtZeKCdBCLu49}8AR%Q3Xv&9W)V4o zNP{;KX^JLdtt~rfAvVot5S!819Aa~5o9DBS89%{WkL=(iw{9Bkxu*=>Z#&8rS(J03 zTrR42n1p?iD0fu7Yd5Z~etaDuho|^~vD!A3^TlYG2<3k^lyRPg$*6&bZ#qvNJbd=c zkI#PHxfRjKgUv-{1)t&?3Sk6{8-dAvVd2jfj&KL&8I0Fsi(A}&Cp)=I=Pn01rjm2HL%H2RWpn1d|ji5!o(!T!>@<6g@zu8M_9Y#Mkqvdpl1>7jjXE z<$DDk3o89wE=PGLAy1amFbmfNbfqX{l*A&F-OfFc-RmZCzdPKJxAW{`=c8^BOR+o* zqdPdb=*Bz?yEIwU8E$Ali0Fl8JM-DJX*1ir-_T+0RIGRz(SsS-G=9~T-|J;zDtbLt@AcB0j}q!PdcC`&Fxj(MNFwlY zZsqhhFsRCkG0=2Wl}{5-bWgiOaidQPVw7*5s{tVqK8M;q_1{8xO#OZ0kLk@G+f*hn zJw0wC(;U^hkwqXawQ$b)esC#Xbej{k(6f8zKy@_UDE z+T7lBN*lf^ZSI`GOyw@=+_`LItK_hQp!AI8clLY^dqSbV;N1BYP#SY1Ux(7mt#lb9nC6whw1;W;jdYRTAe=D7&BMiKaB1 zC$LLm;^u_L7tlao6vTF)0qHM=#Mkuw0?gW*3VyWqY5$KMu*dWl o_eM0;P9D2U|5EjL;0lqopzGiq7GR&vnsu`^-&$-f&fD|$Uve~zyZ`_I literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/compat.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af0237b714707492aedc594dc50e1bce25428a51 GIT binary patch literal 771 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/idnadata.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/idnadata.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3231a60b62c1e3e9ebfa0a2aed1f3994aa72a25c GIT binary patch literal 23206 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/uts46data.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/idna/__pycache__/uts46data.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab872f1c241a7594ad3868a087e542db7e0b7545 GIT binary patch literal 153211 zcmb512Y6M*_V$w##7eby?11!ML{J0;6j4zyBJ~6~bPgRwLqbUCy|>VN?+}8OrUG`2 z4S_WEdcF2~{nk6PXUq)Zd~f6(ovS64B-@LMWP4HgVzRxsNVb=RFD2Vcie!6P zxCGf=S|r<&;ZkIKS&?i@hs%&{i6YsS4PQ>SC5vQxMfggxEmb7jtHM{4ZRsM}UK75S zY|9kM_PX%(WLvgKwl{=tB-_i2WP4NiX0pAaNVes|w~+0XMY6p$d>h$bRV3Tn!*`JF z)kU(sGkh1>UQ;C7^5F_(du@?yD~9hT+v|#CTPa+bY_BhpZIy6Uvb~{5w$;Mb$@az~ z+13cxB-@*cWLqm-n{00`l5L%EU9v4#B-?u7`eb`ck!%};8g zvaMJo+lRxCknPlMkiXE;K(^^0WNE8LrG8x+a5Pq;7HHY}2Dzi@xDy{AaF1HuEz zwo#F6qv1hhdvB3!2Zx7{ZQ~-@4h;_@+a^V_9UdM*w)Yjuc4YWDvc11Zw$F!0k!{l= z*}f2dk!&9*l5KK$G}$&Ql5I*jm28_A$#zUQjcgw*lI_@VI@vx{B-@PeII?X~B-`=f z31r){NVXHhlgPGJk!&Z2r;zQ#MY5e5o<_Eh6v=jacm~b~;)#mpa^LwrNz0UkzZ+>quzc-rSo6PUc=C_>ry~X_AYJP7s zzqgy;JIwE$=Jzi1Ti*OuFuxVe@7?CNlKHJ{eyf<@s^+(v`K@k#Ynb1f=C_vlt!;km znBThQx1RZ}Z+;t?--hP*9`oDC{N8JR8=K!I=J!7Hd%yW@YJMLuzs<~VbMyP4`F+Uz zwlKdf&2KC7`>^?a#Qe54zmJ;VHs<#+^ZU5@eZu^1xPJM-Hfzp3$wiQzR* z#8p^Zi1mXC2|2|cjtm-{b3xl71NtQ8T<~PSNdJB#i&w8*rCOD072

}|6CT?VP?McWg&?J^SM1(Mp|Vj2Lm{5@qTL&v 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 Tuple[bytes, int]: + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return b"", 0 + + return encode(data), len(data) + + def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]: + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return '', 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return "", 0 + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result_str = '.'.join(result) + trailing_dot # type: ignore + size += len(trailing_dot) + return result_str, size + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore + if errors != 'strict': + raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + + if not data: + return ('', 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = '.'.join(result) + trailing_dot + size += len(trailing_dot) + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def getregentry() -> codecs.CodecInfo: + # Compatibility as a search_function for codecs.register() + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, # type: ignore + decode=Codec().decode, # type: ignore + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/compat.py b/testclient/.venv/lib/python3.9/site-packages/idna/compat.py new file mode 100644 index 0000000..786e6bd --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/compat.py @@ -0,0 +1,13 @@ +from .core import * +from .codec import * +from typing import Any, Union + +def ToASCII(label: str) -> bytes: + return encode(label) + +def ToUnicode(label: Union[bytes, bytearray]) -> str: + return decode(label) + +def nameprep(s: Any) -> None: + raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol') + diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/core.py b/testclient/.venv/lib/python3.9/site-packages/idna/core.py new file mode 100644 index 0000000..4f30037 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/core.py @@ -0,0 +1,400 @@ +from . import idnadata +import bisect +import unicodedata +import re +from typing import Union, Optional +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0: + if not unicodedata.name(chr(cp)): + raise ValueError('Unknown character in unicodedata') + return v + +def _is_script(cp: str, script: str) -> bool: + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s: str) -> bytes: + return s.encode('punycode') + +def _unot(s: int) -> str: + return 'U+{:04X}'.format(s) + + +def valid_label_length(label: Union[bytes, str]) -> bool: + if len(label) > 63: + return False + return True + + +def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool: + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label: str, check_ltr: bool = False) -> bool: + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = None # type: Optional[str] + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label: str) -> bool: + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label: str) -> bool: + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label: str) -> None: + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label: str, pos: int) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == '\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + return False + + +def check_label(label: Union[str, bytes, bytearray]) -> None: + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format( + _unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label: str) -> bytes: + try: + label_bytes = label.encode('ascii') + ulabel(label_bytes) + if not valid_label_length(label_bytes): + raise IDNAError('Label too long') + return label_bytes + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = str(label) + check_label(label) + label_bytes = _punycode(label) + label_bytes = _alabel_prefix + label_bytes + + if not valid_label_length(label_bytes): + raise IDNAError('Label too long') + + return label_bytes + + +def ulabel(label: Union[str, bytes, bytearray]) -> str: + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = label + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix):] + if not label_bytes: + raise IDNAError('Malformed A-label, no Punycode eligible content found') + if label_bytes.decode('ascii')[-1] == '-': + raise IDNAError('A-label must not end with a hyphen') + else: + check_label(label_bytes) + return label_bytes.decode('ascii') + + try: + label = label_bytes.decode('punycode') + except UnicodeError: + raise IDNAError('Invalid A-label') + check_label(label) + return label + + +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = '' + + for pos, char in enumerate(domain): + code_point = ord(char) + try: + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, 'Z')) - 1] + status = uts46row[1] + replacement = None # type: Optional[str] + if len(uts46row) == 3: + replacement = uts46row[2] # type: ignore + if (status == 'V' or + (status == 'D' and not transitional) or + (status == '3' and not std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == 'M' or + (status == '3' and not std3_rules) or + (status == 'D' and transitional)): + output += replacement + elif status != 'I': + raise IndexError() + except IndexError: + raise InvalidCodepoint( + 'Codepoint {} not allowed at position {} in {}'.format( + _unot(code_point), pos + 1, repr(domain))) + + return unicodedata.normalize('NFC', output) + + +def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False, transitional: bool = False) -> bytes: + if isinstance(s, (bytes, bytearray)): + try: + s = s.decode('ascii') + except UnicodeDecodeError: + raise IDNAError('should pass a unicode string to the function rather than a byte string.') + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False) -> str: + try: + if isinstance(s, (bytes, bytearray)): + s = s.decode('ascii') + except UnicodeDecodeError: + raise IDNAError('Invalid ASCII in A-label') + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split('.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append('') + return '.'.join(result) diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/idnadata.py b/testclient/.venv/lib/python3.9/site-packages/idna/idnadata.py new file mode 100644 index 0000000..67db462 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/idnadata.py @@ -0,0 +1,2151 @@ +# This file is automatically generated by tools/idna-data + +__version__ = '15.0.0' +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004dc0, + 0x4e000000a000, + 0xf9000000fa6e, + 0xfa700000fada, + 0x16fe200016fe4, + 0x16ff000016ff2, + 0x200000002a6e0, + 0x2a7000002b73a, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + 0x300000003134b, + 0x31350000323b0, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5ef000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b120, + 0x1b1320001b133, + 0x1b1500001b153, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1aff00001aff4, + 0x1aff50001affc, + 0x1affd0001afff, + 0x1b0000001b001, + 0x1b1200001b123, + 0x1b1550001b156, + 0x1b1640001b168, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x605: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x70f: 84, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 82, + 0x857: 82, + 0x858: 82, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x870: 82, + 0x871: 82, + 0x872: 82, + 0x873: 82, + 0x874: 82, + 0x875: 82, + 0x876: 82, + 0x877: 82, + 0x878: 82, + 0x879: 82, + 0x87a: 82, + 0x87b: 82, + 0x87c: 82, + 0x87d: 82, + 0x87e: 82, + 0x87f: 82, + 0x880: 82, + 0x881: 82, + 0x882: 82, + 0x883: 67, + 0x884: 67, + 0x885: 67, + 0x886: 68, + 0x887: 85, + 0x888: 85, + 0x889: 68, + 0x88a: 68, + 0x88b: 68, + 0x88c: 68, + 0x88d: 68, + 0x88e: 82, + 0x890: 85, + 0x891: 85, + 0x8a0: 68, + 0x8a1: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x8ad: 85, + 0x8ae: 82, + 0x8af: 68, + 0x8b0: 68, + 0x8b1: 82, + 0x8b2: 82, + 0x8b3: 68, + 0x8b4: 68, + 0x8b5: 68, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 68, + 0x8be: 68, + 0x8bf: 68, + 0x8c0: 68, + 0x8c1: 68, + 0x8c2: 68, + 0x8c3: 68, + 0x8c4: 68, + 0x8c5: 68, + 0x8c6: 68, + 0x8c7: 68, + 0x8c8: 68, + 0x8e2: 85, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1878: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x10d00: 76, + 0x10d01: 68, + 0x10d02: 68, + 0x10d03: 68, + 0x10d04: 68, + 0x10d05: 68, + 0x10d06: 68, + 0x10d07: 68, + 0x10d08: 68, + 0x10d09: 68, + 0x10d0a: 68, + 0x10d0b: 68, + 0x10d0c: 68, + 0x10d0d: 68, + 0x10d0e: 68, + 0x10d0f: 68, + 0x10d10: 68, + 0x10d11: 68, + 0x10d12: 68, + 0x10d13: 68, + 0x10d14: 68, + 0x10d15: 68, + 0x10d16: 68, + 0x10d17: 68, + 0x10d18: 68, + 0x10d19: 68, + 0x10d1a: 68, + 0x10d1b: 68, + 0x10d1c: 68, + 0x10d1d: 68, + 0x10d1e: 68, + 0x10d1f: 68, + 0x10d20: 68, + 0x10d21: 68, + 0x10d22: 82, + 0x10d23: 68, + 0x10f30: 68, + 0x10f31: 68, + 0x10f32: 68, + 0x10f33: 82, + 0x10f34: 68, + 0x10f35: 68, + 0x10f36: 68, + 0x10f37: 68, + 0x10f38: 68, + 0x10f39: 68, + 0x10f3a: 68, + 0x10f3b: 68, + 0x10f3c: 68, + 0x10f3d: 68, + 0x10f3e: 68, + 0x10f3f: 68, + 0x10f40: 68, + 0x10f41: 68, + 0x10f42: 68, + 0x10f43: 68, + 0x10f44: 68, + 0x10f45: 85, + 0x10f51: 68, + 0x10f52: 68, + 0x10f53: 68, + 0x10f54: 82, + 0x10f70: 68, + 0x10f71: 68, + 0x10f72: 68, + 0x10f73: 68, + 0x10f74: 82, + 0x10f75: 82, + 0x10f76: 68, + 0x10f77: 68, + 0x10f78: 68, + 0x10f79: 68, + 0x10f7a: 68, + 0x10f7b: 68, + 0x10f7c: 68, + 0x10f7d: 68, + 0x10f7e: 68, + 0x10f7f: 68, + 0x10f80: 68, + 0x10f81: 68, + 0x10fb0: 68, + 0x10fb1: 85, + 0x10fb2: 68, + 0x10fb3: 68, + 0x10fb4: 82, + 0x10fb5: 82, + 0x10fb6: 82, + 0x10fb7: 85, + 0x10fb8: 68, + 0x10fb9: 82, + 0x10fba: 82, + 0x10fbb: 68, + 0x10fbc: 68, + 0x10fbd: 82, + 0x10fbe: 68, + 0x10fbf: 68, + 0x10fc0: 85, + 0x10fc1: 68, + 0x10fc2: 82, + 0x10fc3: 82, + 0x10fc4: 68, + 0x10fc5: 85, + 0x10fc6: 85, + 0x10fc7: 85, + 0x10fc8: 85, + 0x10fc9: 82, + 0x10fca: 68, + 0x10fcb: 76, + 0x110bd: 85, + 0x110cd: 85, + 0x1e900: 68, + 0x1e901: 68, + 0x1e902: 68, + 0x1e903: 68, + 0x1e904: 68, + 0x1e905: 68, + 0x1e906: 68, + 0x1e907: 68, + 0x1e908: 68, + 0x1e909: 68, + 0x1e90a: 68, + 0x1e90b: 68, + 0x1e90c: 68, + 0x1e90d: 68, + 0x1e90e: 68, + 0x1e90f: 68, + 0x1e910: 68, + 0x1e911: 68, + 0x1e912: 68, + 0x1e913: 68, + 0x1e914: 68, + 0x1e915: 68, + 0x1e916: 68, + 0x1e917: 68, + 0x1e918: 68, + 0x1e919: 68, + 0x1e91a: 68, + 0x1e91b: 68, + 0x1e91c: 68, + 0x1e91d: 68, + 0x1e91e: 68, + 0x1e91f: 68, + 0x1e920: 68, + 0x1e921: 68, + 0x1e922: 68, + 0x1e923: 68, + 0x1e924: 68, + 0x1e925: 68, + 0x1e926: 68, + 0x1e927: 68, + 0x1e928: 68, + 0x1e929: 68, + 0x1e92a: 68, + 0x1e92b: 68, + 0x1e92c: 68, + 0x1e92d: 68, + 0x1e92e: 68, + 0x1e92f: 68, + 0x1e930: 68, + 0x1e931: 68, + 0x1e932: 68, + 0x1e933: 68, + 0x1e934: 68, + 0x1e935: 68, + 0x1e936: 68, + 0x1e937: 68, + 0x1e938: 68, + 0x1e939: 68, + 0x1e93a: 68, + 0x1e93b: 68, + 0x1e93c: 68, + 0x1e93d: 68, + 0x1e93e: 68, + 0x1e93f: 68, + 0x1e940: 68, + 0x1e941: 68, + 0x1e942: 68, + 0x1e943: 68, + 0x1e94b: 84, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56000000587, + 0x58800000589, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5ef000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x7fd000007fe, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x87000000888, + 0x8890000088f, + 0x898000008e2, + 0x8e300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0x9fc000009fd, + 0x9fe000009ff, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xaf900000b00, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5500000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3c00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc5d00000c5e, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcdd00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf4, + 0xd0000000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8100000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8600000e8b, + 0xe8c00000ea4, + 0xea500000ea6, + 0xea700000eb3, + 0xeb400000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ecf, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x170000001716, + 0x171f00001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001879, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 0x1abf00001acf, + 0x1b0000001b4d, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfb, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c60, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x310500003130, + 0x31a0000031c0, + 0x31f000003200, + 0x340000004dc0, + 0x4e000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa6990000a69a, + 0xa69b0000a69c, + 0xa69e0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a790, + 0xa7910000a792, + 0xa7930000a796, + 0xa7970000a798, + 0xa7990000a79a, + 0xa79b0000a79c, + 0xa79d0000a79e, + 0xa79f0000a7a0, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7af0000a7b0, + 0xa7b50000a7b6, + 0xa7b70000a7b8, + 0xa7b90000a7ba, + 0xa7bb0000a7bc, + 0xa7bd0000a7be, + 0xa7bf0000a7c0, + 0xa7c10000a7c2, + 0xa7c30000a7c4, + 0xa7c80000a7c9, + 0xa7ca0000a7cb, + 0xa7d10000a7d2, + 0xa7d30000a7d4, + 0xa7d50000a7d6, + 0xa7d70000a7d8, + 0xa7d90000a7da, + 0xa7f20000a7f5, + 0xa7f60000a7f8, + 0xa7fa0000a828, + 0xa82c0000a82d, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab69, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe30, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x102e0000102e1, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x10597000105a2, + 0x105a3000105b2, + 0x105b3000105ba, + 0x105bb000105bd, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010786, + 0x10787000107b1, + 0x107b2000107bb, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a36, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x10d0000010d28, + 0x10d3000010d3a, + 0x10e8000010eaa, + 0x10eab00010ead, + 0x10eb000010eb2, + 0x10efd00010f1d, + 0x10f2700010f28, + 0x10f3000010f51, + 0x10f7000010f86, + 0x10fb000010fc5, + 0x10fe000010ff7, + 0x1100000011047, + 0x1106600011076, + 0x1107f000110bb, + 0x110c2000110c3, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111c9000111cd, + 0x111ce000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133b00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x1145e00011462, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b9, + 0x116c0000116ca, + 0x117000001171b, + 0x1171d0001172c, + 0x117300001173a, + 0x1174000011747, + 0x118000001183b, + 0x118c0000118ea, + 0x118ff00011907, + 0x119090001190a, + 0x1190c00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193b00011944, + 0x119500001195a, + 0x119a0000119a8, + 0x119aa000119d8, + 0x119da000119e2, + 0x119e3000119e5, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a9a, + 0x11a9d00011a9e, + 0x11ab000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x11d6000011d66, + 0x11d6700011d69, + 0x11d6a00011d8f, + 0x11d9000011d92, + 0x11d9300011d99, + 0x11da000011daa, + 0x11ee000011ef7, + 0x11f0000011f11, + 0x11f1200011f3b, + 0x11f3e00011f43, + 0x11f5000011f5a, + 0x11fb000011fb1, + 0x120000001239a, + 0x1248000012544, + 0x12f9000012ff1, + 0x1300000013430, + 0x1344000013456, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16a7000016abf, + 0x16ac000016aca, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16e6000016e80, + 0x16f0000016f4b, + 0x16f4f00016f88, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x16fe300016fe5, + 0x16ff000016ff2, + 0x17000000187f8, + 0x1880000018cd6, + 0x18d0000018d09, + 0x1aff00001aff4, + 0x1aff50001affc, + 0x1affd0001afff, + 0x1b0000001b123, + 0x1b1320001b133, + 0x1b1500001b153, + 0x1b1550001b156, + 0x1b1640001b168, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1cf000001cf2e, + 0x1cf300001cf47, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1df000001df1f, + 0x1df250001df2b, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e0300001e06e, + 0x1e08f0001e090, + 0x1e1000001e12d, + 0x1e1300001e13e, + 0x1e1400001e14a, + 0x1e14e0001e14f, + 0x1e2900001e2af, + 0x1e2c00001e2fa, + 0x1e4d00001e4fa, + 0x1e7e00001e7e7, + 0x1e7e80001e7ec, + 0x1e7ed0001e7ef, + 0x1e7f00001e7ff, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94c, + 0x1e9500001e95a, + 0x200000002a6e0, + 0x2a7000002b73a, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x300000003134b, + 0x31350000323b0, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/intranges.py b/testclient/.venv/lib/python3.9/site-packages/idna/intranges.py new file mode 100644 index 0000000..6a43b04 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/intranges.py @@ -0,0 +1,54 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect +from typing import List, Tuple + +def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + +def _decode_range(r: int) -> Tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/package_data.py b/testclient/.venv/lib/python3.9/site-packages/idna/package_data.py new file mode 100644 index 0000000..8501893 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '3.4' + diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/py.typed b/testclient/.venv/lib/python3.9/site-packages/idna/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/idna/uts46data.py b/testclient/.venv/lib/python3.9/site-packages/idna/uts46data.py new file mode 100644 index 0000000..186796c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/idna/uts46data.py @@ -0,0 +1,8600 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +from typing import List, Tuple, Union + + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = '15.0.0' +def _seg_0() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', 'a'), + (0x42, 'M', 'b'), + (0x43, 'M', 'c'), + (0x44, 'M', 'd'), + (0x45, 'M', 'e'), + (0x46, 'M', 'f'), + (0x47, 'M', 'g'), + (0x48, 'M', 'h'), + (0x49, 'M', 'i'), + (0x4A, 'M', 'j'), + (0x4B, 'M', 'k'), + (0x4C, 'M', 'l'), + (0x4D, 'M', 'm'), + (0x4E, 'M', 'n'), + (0x4F, 'M', 'o'), + (0x50, 'M', 'p'), + (0x51, 'M', 'q'), + (0x52, 'M', 'r'), + (0x53, 'M', 's'), + (0x54, 'M', 't'), + (0x55, 'M', 'u'), + (0x56, 'M', 'v'), + (0x57, 'M', 'w'), + (0x58, 'M', 'x'), + (0x59, 'M', 'y'), + (0x5A, 'M', 'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', ' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', ' ̈'), + (0xA9, 'V'), + (0xAA, 'M', 'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', ' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', '2'), + (0xB3, 'M', '3'), + (0xB4, '3', ' ́'), + (0xB5, 'M', 'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', ' ̧'), + (0xB9, 'M', '1'), + (0xBA, 'M', 'o'), + (0xBB, 'V'), + (0xBC, 'M', '1⁄4'), + (0xBD, 'M', '1⁄2'), + (0xBE, 'M', '3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', 'à'), + (0xC1, 'M', 'á'), + (0xC2, 'M', 'â'), + (0xC3, 'M', 'ã'), + (0xC4, 'M', 'ä'), + (0xC5, 'M', 'å'), + (0xC6, 'M', 'æ'), + (0xC7, 'M', 'ç'), + ] + +def _seg_2() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC8, 'M', 'è'), + (0xC9, 'M', 'é'), + (0xCA, 'M', 'ê'), + (0xCB, 'M', 'ë'), + (0xCC, 'M', 'ì'), + (0xCD, 'M', 'í'), + (0xCE, 'M', 'î'), + (0xCF, 'M', 'ï'), + (0xD0, 'M', 'ð'), + (0xD1, 'M', 'ñ'), + (0xD2, 'M', 'ò'), + (0xD3, 'M', 'ó'), + (0xD4, 'M', 'ô'), + (0xD5, 'M', 'õ'), + (0xD6, 'M', 'ö'), + (0xD7, 'V'), + (0xD8, 'M', 'ø'), + (0xD9, 'M', 'ù'), + (0xDA, 'M', 'ú'), + (0xDB, 'M', 'û'), + (0xDC, 'M', 'ü'), + (0xDD, 'M', 'ý'), + (0xDE, 'M', 'þ'), + (0xDF, 'D', 'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', 'ā'), + (0x101, 'V'), + (0x102, 'M', 'ă'), + (0x103, 'V'), + (0x104, 'M', 'ą'), + (0x105, 'V'), + (0x106, 'M', 'ć'), + (0x107, 'V'), + (0x108, 'M', 'ĉ'), + (0x109, 'V'), + (0x10A, 'M', 'ċ'), + (0x10B, 'V'), + (0x10C, 'M', 'č'), + (0x10D, 'V'), + (0x10E, 'M', 'ď'), + (0x10F, 'V'), + (0x110, 'M', 'đ'), + (0x111, 'V'), + (0x112, 'M', 'ē'), + (0x113, 'V'), + (0x114, 'M', 'ĕ'), + (0x115, 'V'), + (0x116, 'M', 'ė'), + (0x117, 'V'), + (0x118, 'M', 'ę'), + (0x119, 'V'), + (0x11A, 'M', 'ě'), + (0x11B, 'V'), + (0x11C, 'M', 'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', 'ğ'), + (0x11F, 'V'), + (0x120, 'M', 'ġ'), + (0x121, 'V'), + (0x122, 'M', 'ģ'), + (0x123, 'V'), + (0x124, 'M', 'ĥ'), + (0x125, 'V'), + (0x126, 'M', 'ħ'), + (0x127, 'V'), + (0x128, 'M', 'ĩ'), + (0x129, 'V'), + (0x12A, 'M', 'ī'), + (0x12B, 'V'), + ] + +def _seg_3() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x12C, 'M', 'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', 'į'), + (0x12F, 'V'), + (0x130, 'M', 'i̇'), + (0x131, 'V'), + (0x132, 'M', 'ij'), + (0x134, 'M', 'ĵ'), + (0x135, 'V'), + (0x136, 'M', 'ķ'), + (0x137, 'V'), + (0x139, 'M', 'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', 'ļ'), + (0x13C, 'V'), + (0x13D, 'M', 'ľ'), + (0x13E, 'V'), + (0x13F, 'M', 'l·'), + (0x141, 'M', 'ł'), + (0x142, 'V'), + (0x143, 'M', 'ń'), + (0x144, 'V'), + (0x145, 'M', 'ņ'), + (0x146, 'V'), + (0x147, 'M', 'ň'), + (0x148, 'V'), + (0x149, 'M', 'ʼn'), + (0x14A, 'M', 'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', 'ō'), + (0x14D, 'V'), + (0x14E, 'M', 'ŏ'), + (0x14F, 'V'), + (0x150, 'M', 'ő'), + (0x151, 'V'), + (0x152, 'M', 'œ'), + (0x153, 'V'), + (0x154, 'M', 'ŕ'), + (0x155, 'V'), + (0x156, 'M', 'ŗ'), + (0x157, 'V'), + (0x158, 'M', 'ř'), + (0x159, 'V'), + (0x15A, 'M', 'ś'), + (0x15B, 'V'), + (0x15C, 'M', 'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', 'ş'), + (0x15F, 'V'), + (0x160, 'M', 'š'), + (0x161, 'V'), + (0x162, 'M', 'ţ'), + (0x163, 'V'), + (0x164, 'M', 'ť'), + (0x165, 'V'), + (0x166, 'M', 'ŧ'), + (0x167, 'V'), + (0x168, 'M', 'ũ'), + (0x169, 'V'), + (0x16A, 'M', 'ū'), + (0x16B, 'V'), + (0x16C, 'M', 'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', 'ů'), + (0x16F, 'V'), + (0x170, 'M', 'ű'), + (0x171, 'V'), + (0x172, 'M', 'ų'), + (0x173, 'V'), + (0x174, 'M', 'ŵ'), + (0x175, 'V'), + (0x176, 'M', 'ŷ'), + (0x177, 'V'), + (0x178, 'M', 'ÿ'), + (0x179, 'M', 'ź'), + (0x17A, 'V'), + (0x17B, 'M', 'ż'), + (0x17C, 'V'), + (0x17D, 'M', 'ž'), + (0x17E, 'V'), + (0x17F, 'M', 's'), + (0x180, 'V'), + (0x181, 'M', 'ɓ'), + (0x182, 'M', 'ƃ'), + (0x183, 'V'), + (0x184, 'M', 'ƅ'), + (0x185, 'V'), + (0x186, 'M', 'ɔ'), + (0x187, 'M', 'ƈ'), + (0x188, 'V'), + (0x189, 'M', 'ɖ'), + (0x18A, 'M', 'ɗ'), + (0x18B, 'M', 'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', 'ǝ'), + (0x18F, 'M', 'ə'), + (0x190, 'M', 'ɛ'), + (0x191, 'M', 'ƒ'), + (0x192, 'V'), + (0x193, 'M', 'ɠ'), + ] + +def _seg_4() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x194, 'M', 'ɣ'), + (0x195, 'V'), + (0x196, 'M', 'ɩ'), + (0x197, 'M', 'ɨ'), + (0x198, 'M', 'ƙ'), + (0x199, 'V'), + (0x19C, 'M', 'ɯ'), + (0x19D, 'M', 'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', 'ɵ'), + (0x1A0, 'M', 'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', 'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', 'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', 'ʀ'), + (0x1A7, 'M', 'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', 'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', 'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', 'ʈ'), + (0x1AF, 'M', 'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', 'ʊ'), + (0x1B2, 'M', 'ʋ'), + (0x1B3, 'M', 'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', 'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', 'ʒ'), + (0x1B8, 'M', 'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', 'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', 'dž'), + (0x1C7, 'M', 'lj'), + (0x1CA, 'M', 'nj'), + (0x1CD, 'M', 'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', 'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', 'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', 'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', 'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', 'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', 'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', 'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', 'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', 'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', 'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', 'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', 'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', 'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', 'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', 'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', 'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', 'dz'), + (0x1F4, 'M', 'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', 'ƕ'), + (0x1F7, 'M', 'ƿ'), + (0x1F8, 'M', 'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', 'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', 'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', 'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', 'ȁ'), + (0x201, 'V'), + (0x202, 'M', 'ȃ'), + (0x203, 'V'), + (0x204, 'M', 'ȅ'), + (0x205, 'V'), + (0x206, 'M', 'ȇ'), + (0x207, 'V'), + (0x208, 'M', 'ȉ'), + (0x209, 'V'), + (0x20A, 'M', 'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', 'ȍ'), + ] + +def _seg_5() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x20D, 'V'), + (0x20E, 'M', 'ȏ'), + (0x20F, 'V'), + (0x210, 'M', 'ȑ'), + (0x211, 'V'), + (0x212, 'M', 'ȓ'), + (0x213, 'V'), + (0x214, 'M', 'ȕ'), + (0x215, 'V'), + (0x216, 'M', 'ȗ'), + (0x217, 'V'), + (0x218, 'M', 'ș'), + (0x219, 'V'), + (0x21A, 'M', 'ț'), + (0x21B, 'V'), + (0x21C, 'M', 'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', 'ȟ'), + (0x21F, 'V'), + (0x220, 'M', 'ƞ'), + (0x221, 'V'), + (0x222, 'M', 'ȣ'), + (0x223, 'V'), + (0x224, 'M', 'ȥ'), + (0x225, 'V'), + (0x226, 'M', 'ȧ'), + (0x227, 'V'), + (0x228, 'M', 'ȩ'), + (0x229, 'V'), + (0x22A, 'M', 'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', 'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', 'ȯ'), + (0x22F, 'V'), + (0x230, 'M', 'ȱ'), + (0x231, 'V'), + (0x232, 'M', 'ȳ'), + (0x233, 'V'), + (0x23A, 'M', 'ⱥ'), + (0x23B, 'M', 'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', 'ƚ'), + (0x23E, 'M', 'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', 'ɂ'), + (0x242, 'V'), + (0x243, 'M', 'ƀ'), + (0x244, 'M', 'ʉ'), + (0x245, 'M', 'ʌ'), + (0x246, 'M', 'ɇ'), + (0x247, 'V'), + (0x248, 'M', 'ɉ'), + (0x249, 'V'), + (0x24A, 'M', 'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', 'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', 'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', 'h'), + (0x2B1, 'M', 'ɦ'), + (0x2B2, 'M', 'j'), + (0x2B3, 'M', 'r'), + (0x2B4, 'M', 'ɹ'), + (0x2B5, 'M', 'ɻ'), + (0x2B6, 'M', 'ʁ'), + (0x2B7, 'M', 'w'), + (0x2B8, 'M', 'y'), + (0x2B9, 'V'), + (0x2D8, '3', ' ̆'), + (0x2D9, '3', ' ̇'), + (0x2DA, '3', ' ̊'), + (0x2DB, '3', ' ̨'), + (0x2DC, '3', ' ̃'), + (0x2DD, '3', ' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', 'ɣ'), + (0x2E1, 'M', 'l'), + (0x2E2, 'M', 's'), + (0x2E3, 'M', 'x'), + (0x2E4, 'M', 'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', '̀'), + (0x341, 'M', '́'), + (0x342, 'V'), + (0x343, 'M', '̓'), + (0x344, 'M', '̈́'), + (0x345, 'M', 'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', 'ͱ'), + (0x371, 'V'), + (0x372, 'M', 'ͳ'), + (0x373, 'V'), + (0x374, 'M', 'ʹ'), + (0x375, 'V'), + (0x376, 'M', 'ͷ'), + (0x377, 'V'), + ] + +def _seg_6() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x378, 'X'), + (0x37A, '3', ' ι'), + (0x37B, 'V'), + (0x37E, '3', ';'), + (0x37F, 'M', 'ϳ'), + (0x380, 'X'), + (0x384, '3', ' ́'), + (0x385, '3', ' ̈́'), + (0x386, 'M', 'ά'), + (0x387, 'M', '·'), + (0x388, 'M', 'έ'), + (0x389, 'M', 'ή'), + (0x38A, 'M', 'ί'), + (0x38B, 'X'), + (0x38C, 'M', 'ό'), + (0x38D, 'X'), + (0x38E, 'M', 'ύ'), + (0x38F, 'M', 'ώ'), + (0x390, 'V'), + (0x391, 'M', 'α'), + (0x392, 'M', 'β'), + (0x393, 'M', 'γ'), + (0x394, 'M', 'δ'), + (0x395, 'M', 'ε'), + (0x396, 'M', 'ζ'), + (0x397, 'M', 'η'), + (0x398, 'M', 'θ'), + (0x399, 'M', 'ι'), + (0x39A, 'M', 'κ'), + (0x39B, 'M', 'λ'), + (0x39C, 'M', 'μ'), + (0x39D, 'M', 'ν'), + (0x39E, 'M', 'ξ'), + (0x39F, 'M', 'ο'), + (0x3A0, 'M', 'π'), + (0x3A1, 'M', 'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', 'σ'), + (0x3A4, 'M', 'τ'), + (0x3A5, 'M', 'υ'), + (0x3A6, 'M', 'φ'), + (0x3A7, 'M', 'χ'), + (0x3A8, 'M', 'ψ'), + (0x3A9, 'M', 'ω'), + (0x3AA, 'M', 'ϊ'), + (0x3AB, 'M', 'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', 'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', 'ϗ'), + (0x3D0, 'M', 'β'), + (0x3D1, 'M', 'θ'), + (0x3D2, 'M', 'υ'), + (0x3D3, 'M', 'ύ'), + (0x3D4, 'M', 'ϋ'), + (0x3D5, 'M', 'φ'), + (0x3D6, 'M', 'π'), + (0x3D7, 'V'), + (0x3D8, 'M', 'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', 'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', 'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', 'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', 'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', 'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', 'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', 'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', 'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', 'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', 'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', 'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', 'κ'), + (0x3F1, 'M', 'ρ'), + (0x3F2, 'M', 'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', 'θ'), + (0x3F5, 'M', 'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', 'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', 'σ'), + (0x3FA, 'M', 'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', 'ͻ'), + (0x3FE, 'M', 'ͼ'), + (0x3FF, 'M', 'ͽ'), + (0x400, 'M', 'ѐ'), + (0x401, 'M', 'ё'), + (0x402, 'M', 'ђ'), + ] + +def _seg_7() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x403, 'M', 'ѓ'), + (0x404, 'M', 'є'), + (0x405, 'M', 'ѕ'), + (0x406, 'M', 'і'), + (0x407, 'M', 'ї'), + (0x408, 'M', 'ј'), + (0x409, 'M', 'љ'), + (0x40A, 'M', 'њ'), + (0x40B, 'M', 'ћ'), + (0x40C, 'M', 'ќ'), + (0x40D, 'M', 'ѝ'), + (0x40E, 'M', 'ў'), + (0x40F, 'M', 'џ'), + (0x410, 'M', 'а'), + (0x411, 'M', 'б'), + (0x412, 'M', 'в'), + (0x413, 'M', 'г'), + (0x414, 'M', 'д'), + (0x415, 'M', 'е'), + (0x416, 'M', 'ж'), + (0x417, 'M', 'з'), + (0x418, 'M', 'и'), + (0x419, 'M', 'й'), + (0x41A, 'M', 'к'), + (0x41B, 'M', 'л'), + (0x41C, 'M', 'м'), + (0x41D, 'M', 'н'), + (0x41E, 'M', 'о'), + (0x41F, 'M', 'п'), + (0x420, 'M', 'р'), + (0x421, 'M', 'с'), + (0x422, 'M', 'т'), + (0x423, 'M', 'у'), + (0x424, 'M', 'ф'), + (0x425, 'M', 'х'), + (0x426, 'M', 'ц'), + (0x427, 'M', 'ч'), + (0x428, 'M', 'ш'), + (0x429, 'M', 'щ'), + (0x42A, 'M', 'ъ'), + (0x42B, 'M', 'ы'), + (0x42C, 'M', 'ь'), + (0x42D, 'M', 'э'), + (0x42E, 'M', 'ю'), + (0x42F, 'M', 'я'), + (0x430, 'V'), + (0x460, 'M', 'ѡ'), + (0x461, 'V'), + (0x462, 'M', 'ѣ'), + (0x463, 'V'), + (0x464, 'M', 'ѥ'), + (0x465, 'V'), + (0x466, 'M', 'ѧ'), + (0x467, 'V'), + (0x468, 'M', 'ѩ'), + (0x469, 'V'), + (0x46A, 'M', 'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', 'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', 'ѯ'), + (0x46F, 'V'), + (0x470, 'M', 'ѱ'), + (0x471, 'V'), + (0x472, 'M', 'ѳ'), + (0x473, 'V'), + (0x474, 'M', 'ѵ'), + (0x475, 'V'), + (0x476, 'M', 'ѷ'), + (0x477, 'V'), + (0x478, 'M', 'ѹ'), + (0x479, 'V'), + (0x47A, 'M', 'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', 'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', 'ѿ'), + (0x47F, 'V'), + (0x480, 'M', 'ҁ'), + (0x481, 'V'), + (0x48A, 'M', 'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', 'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', 'ҏ'), + (0x48F, 'V'), + (0x490, 'M', 'ґ'), + (0x491, 'V'), + (0x492, 'M', 'ғ'), + (0x493, 'V'), + (0x494, 'M', 'ҕ'), + (0x495, 'V'), + (0x496, 'M', 'җ'), + (0x497, 'V'), + (0x498, 'M', 'ҙ'), + (0x499, 'V'), + (0x49A, 'M', 'қ'), + (0x49B, 'V'), + (0x49C, 'M', 'ҝ'), + (0x49D, 'V'), + ] + +def _seg_8() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x49E, 'M', 'ҟ'), + (0x49F, 'V'), + (0x4A0, 'M', 'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', 'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', 'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', 'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', 'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', 'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', 'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', 'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', 'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', 'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', 'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', 'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', 'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', 'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', 'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', 'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', 'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', 'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', 'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', 'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', 'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', 'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', 'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', 'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', 'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', 'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', 'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', 'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', 'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', 'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', 'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', 'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', 'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', 'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', 'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', 'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', 'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', 'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', 'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', 'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', 'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', 'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', 'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', 'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', 'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', 'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', 'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', 'ԁ'), + (0x501, 'V'), + (0x502, 'M', 'ԃ'), + ] + +def _seg_9() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x503, 'V'), + (0x504, 'M', 'ԅ'), + (0x505, 'V'), + (0x506, 'M', 'ԇ'), + (0x507, 'V'), + (0x508, 'M', 'ԉ'), + (0x509, 'V'), + (0x50A, 'M', 'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', 'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', 'ԏ'), + (0x50F, 'V'), + (0x510, 'M', 'ԑ'), + (0x511, 'V'), + (0x512, 'M', 'ԓ'), + (0x513, 'V'), + (0x514, 'M', 'ԕ'), + (0x515, 'V'), + (0x516, 'M', 'ԗ'), + (0x517, 'V'), + (0x518, 'M', 'ԙ'), + (0x519, 'V'), + (0x51A, 'M', 'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', 'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', 'ԟ'), + (0x51F, 'V'), + (0x520, 'M', 'ԡ'), + (0x521, 'V'), + (0x522, 'M', 'ԣ'), + (0x523, 'V'), + (0x524, 'M', 'ԥ'), + (0x525, 'V'), + (0x526, 'M', 'ԧ'), + (0x527, 'V'), + (0x528, 'M', 'ԩ'), + (0x529, 'V'), + (0x52A, 'M', 'ԫ'), + (0x52B, 'V'), + (0x52C, 'M', 'ԭ'), + (0x52D, 'V'), + (0x52E, 'M', 'ԯ'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', 'ա'), + (0x532, 'M', 'բ'), + (0x533, 'M', 'գ'), + (0x534, 'M', 'դ'), + (0x535, 'M', 'ե'), + (0x536, 'M', 'զ'), + (0x537, 'M', 'է'), + (0x538, 'M', 'ը'), + (0x539, 'M', 'թ'), + (0x53A, 'M', 'ժ'), + (0x53B, 'M', 'ի'), + (0x53C, 'M', 'լ'), + (0x53D, 'M', 'խ'), + (0x53E, 'M', 'ծ'), + (0x53F, 'M', 'կ'), + (0x540, 'M', 'հ'), + (0x541, 'M', 'ձ'), + (0x542, 'M', 'ղ'), + (0x543, 'M', 'ճ'), + (0x544, 'M', 'մ'), + (0x545, 'M', 'յ'), + (0x546, 'M', 'ն'), + (0x547, 'M', 'շ'), + (0x548, 'M', 'ո'), + (0x549, 'M', 'չ'), + (0x54A, 'M', 'պ'), + (0x54B, 'M', 'ջ'), + (0x54C, 'M', 'ռ'), + (0x54D, 'M', 'ս'), + (0x54E, 'M', 'վ'), + (0x54F, 'M', 'տ'), + (0x550, 'M', 'ր'), + (0x551, 'M', 'ց'), + (0x552, 'M', 'ւ'), + (0x553, 'M', 'փ'), + (0x554, 'M', 'ք'), + (0x555, 'M', 'օ'), + (0x556, 'M', 'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x587, 'M', 'եւ'), + (0x588, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5EF, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61D, 'V'), + ] + +def _seg_10() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x675, 'M', 'اٴ'), + (0x676, 'M', 'وٴ'), + (0x677, 'M', 'ۇٴ'), + (0x678, 'M', 'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x7FD, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x860, 'V'), + (0x86B, 'X'), + (0x870, 'V'), + (0x88F, 'X'), + (0x898, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', 'क़'), + (0x959, 'M', 'ख़'), + (0x95A, 'M', 'ग़'), + (0x95B, 'M', 'ज़'), + (0x95C, 'M', 'ड़'), + (0x95D, 'M', 'ढ़'), + (0x95E, 'M', 'फ़'), + (0x95F, 'M', 'य़'), + (0x960, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', 'ড়'), + (0x9DD, 'M', 'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', 'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FF, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', 'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', 'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + (0xA59, 'M', 'ਖ਼'), + (0xA5A, 'M', 'ਗ਼'), + (0xA5B, 'M', 'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + ] + +def _seg_11() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA5E, 'M', 'ਫ਼'), + (0xA5F, 'X'), + (0xA66, 'V'), + (0xA77, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xAF9, 'V'), + (0xB00, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB55, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', 'ଡ଼'), + (0xB5D, 'M', 'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC00, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + ] + +def _seg_12() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC3A, 'X'), + (0xC3C, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC5D, 'V'), + (0xC5E, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC77, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDD, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF4, 'X'), + (0xD00, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD50, 'X'), + (0xD54, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD80, 'X'), + (0xD81, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDE6, 'V'), + (0xDF0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', 'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE86, 'V'), + (0xE8B, 'X'), + (0xE8C, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEB3, 'M', 'ໍາ'), + (0xEB4, 'V'), + ] + +def _seg_13() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECF, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', 'ຫນ'), + (0xEDD, 'M', 'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', '་'), + (0xF0D, 'V'), + (0xF43, 'M', 'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', 'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', 'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', 'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', 'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', 'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', 'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', 'ཱུ'), + (0xF76, 'M', 'ྲྀ'), + (0xF77, 'M', 'ྲཱྀ'), + (0xF78, 'M', 'ླྀ'), + (0xF79, 'M', 'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', 'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', 'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', 'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', 'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', 'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', 'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', 'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', 'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', 'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', 'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + (0x1258, 'V'), + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + ] + +def _seg_14() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', 'Ᏸ'), + (0x13F9, 'M', 'Ᏹ'), + (0x13FA, 'M', 'Ᏺ'), + (0x13FB, 'M', 'Ᏻ'), + (0x13FC, 'M', 'Ᏼ'), + (0x13FD, 'M', 'Ᏽ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x1716, 'X'), + (0x171F, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x180F, 'I'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1879, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191F, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1ACF, 'X'), + (0x1B00, 'V'), + (0x1B4D, 'X'), + (0x1B50, 'V'), + (0x1B7F, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'M', 'в'), + ] + +def _seg_15() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1C81, 'M', 'д'), + (0x1C82, 'M', 'о'), + (0x1C83, 'M', 'с'), + (0x1C84, 'M', 'т'), + (0x1C86, 'M', 'ъ'), + (0x1C87, 'M', 'ѣ'), + (0x1C88, 'M', 'ꙋ'), + (0x1C89, 'X'), + (0x1C90, 'M', 'ა'), + (0x1C91, 'M', 'ბ'), + (0x1C92, 'M', 'გ'), + (0x1C93, 'M', 'დ'), + (0x1C94, 'M', 'ე'), + (0x1C95, 'M', 'ვ'), + (0x1C96, 'M', 'ზ'), + (0x1C97, 'M', 'თ'), + (0x1C98, 'M', 'ი'), + (0x1C99, 'M', 'კ'), + (0x1C9A, 'M', 'ლ'), + (0x1C9B, 'M', 'მ'), + (0x1C9C, 'M', 'ნ'), + (0x1C9D, 'M', 'ო'), + (0x1C9E, 'M', 'პ'), + (0x1C9F, 'M', 'ჟ'), + (0x1CA0, 'M', 'რ'), + (0x1CA1, 'M', 'ს'), + (0x1CA2, 'M', 'ტ'), + (0x1CA3, 'M', 'უ'), + (0x1CA4, 'M', 'ფ'), + (0x1CA5, 'M', 'ქ'), + (0x1CA6, 'M', 'ღ'), + (0x1CA7, 'M', 'ყ'), + (0x1CA8, 'M', 'შ'), + (0x1CA9, 'M', 'ჩ'), + (0x1CAA, 'M', 'ც'), + (0x1CAB, 'M', 'ძ'), + (0x1CAC, 'M', 'წ'), + (0x1CAD, 'M', 'ჭ'), + (0x1CAE, 'M', 'ხ'), + (0x1CAF, 'M', 'ჯ'), + (0x1CB0, 'M', 'ჰ'), + (0x1CB1, 'M', 'ჱ'), + (0x1CB2, 'M', 'ჲ'), + (0x1CB3, 'M', 'ჳ'), + (0x1CB4, 'M', 'ჴ'), + (0x1CB5, 'M', 'ჵ'), + (0x1CB6, 'M', 'ჶ'), + (0x1CB7, 'M', 'ჷ'), + (0x1CB8, 'M', 'ჸ'), + (0x1CB9, 'M', 'ჹ'), + (0x1CBA, 'M', 'ჺ'), + (0x1CBB, 'X'), + (0x1CBD, 'M', 'ჽ'), + (0x1CBE, 'M', 'ჾ'), + (0x1CBF, 'M', 'ჿ'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFB, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', 'a'), + (0x1D2D, 'M', 'æ'), + (0x1D2E, 'M', 'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', 'd'), + (0x1D31, 'M', 'e'), + (0x1D32, 'M', 'ǝ'), + (0x1D33, 'M', 'g'), + (0x1D34, 'M', 'h'), + (0x1D35, 'M', 'i'), + (0x1D36, 'M', 'j'), + (0x1D37, 'M', 'k'), + (0x1D38, 'M', 'l'), + (0x1D39, 'M', 'm'), + (0x1D3A, 'M', 'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', 'o'), + (0x1D3D, 'M', 'ȣ'), + (0x1D3E, 'M', 'p'), + (0x1D3F, 'M', 'r'), + (0x1D40, 'M', 't'), + (0x1D41, 'M', 'u'), + (0x1D42, 'M', 'w'), + (0x1D43, 'M', 'a'), + (0x1D44, 'M', 'ɐ'), + (0x1D45, 'M', 'ɑ'), + (0x1D46, 'M', 'ᴂ'), + (0x1D47, 'M', 'b'), + (0x1D48, 'M', 'd'), + (0x1D49, 'M', 'e'), + (0x1D4A, 'M', 'ə'), + (0x1D4B, 'M', 'ɛ'), + (0x1D4C, 'M', 'ɜ'), + (0x1D4D, 'M', 'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', 'k'), + (0x1D50, 'M', 'm'), + (0x1D51, 'M', 'ŋ'), + (0x1D52, 'M', 'o'), + (0x1D53, 'M', 'ɔ'), + ] + +def _seg_16() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D54, 'M', 'ᴖ'), + (0x1D55, 'M', 'ᴗ'), + (0x1D56, 'M', 'p'), + (0x1D57, 'M', 't'), + (0x1D58, 'M', 'u'), + (0x1D59, 'M', 'ᴝ'), + (0x1D5A, 'M', 'ɯ'), + (0x1D5B, 'M', 'v'), + (0x1D5C, 'M', 'ᴥ'), + (0x1D5D, 'M', 'β'), + (0x1D5E, 'M', 'γ'), + (0x1D5F, 'M', 'δ'), + (0x1D60, 'M', 'φ'), + (0x1D61, 'M', 'χ'), + (0x1D62, 'M', 'i'), + (0x1D63, 'M', 'r'), + (0x1D64, 'M', 'u'), + (0x1D65, 'M', 'v'), + (0x1D66, 'M', 'β'), + (0x1D67, 'M', 'γ'), + (0x1D68, 'M', 'ρ'), + (0x1D69, 'M', 'φ'), + (0x1D6A, 'M', 'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', 'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', 'ɒ'), + (0x1D9C, 'M', 'c'), + (0x1D9D, 'M', 'ɕ'), + (0x1D9E, 'M', 'ð'), + (0x1D9F, 'M', 'ɜ'), + (0x1DA0, 'M', 'f'), + (0x1DA1, 'M', 'ɟ'), + (0x1DA2, 'M', 'ɡ'), + (0x1DA3, 'M', 'ɥ'), + (0x1DA4, 'M', 'ɨ'), + (0x1DA5, 'M', 'ɩ'), + (0x1DA6, 'M', 'ɪ'), + (0x1DA7, 'M', 'ᵻ'), + (0x1DA8, 'M', 'ʝ'), + (0x1DA9, 'M', 'ɭ'), + (0x1DAA, 'M', 'ᶅ'), + (0x1DAB, 'M', 'ʟ'), + (0x1DAC, 'M', 'ɱ'), + (0x1DAD, 'M', 'ɰ'), + (0x1DAE, 'M', 'ɲ'), + (0x1DAF, 'M', 'ɳ'), + (0x1DB0, 'M', 'ɴ'), + (0x1DB1, 'M', 'ɵ'), + (0x1DB2, 'M', 'ɸ'), + (0x1DB3, 'M', 'ʂ'), + (0x1DB4, 'M', 'ʃ'), + (0x1DB5, 'M', 'ƫ'), + (0x1DB6, 'M', 'ʉ'), + (0x1DB7, 'M', 'ʊ'), + (0x1DB8, 'M', 'ᴜ'), + (0x1DB9, 'M', 'ʋ'), + (0x1DBA, 'M', 'ʌ'), + (0x1DBB, 'M', 'z'), + (0x1DBC, 'M', 'ʐ'), + (0x1DBD, 'M', 'ʑ'), + (0x1DBE, 'M', 'ʒ'), + (0x1DBF, 'M', 'θ'), + (0x1DC0, 'V'), + (0x1E00, 'M', 'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', 'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', 'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', 'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', 'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', 'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', 'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', 'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', 'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', 'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', 'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', 'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', 'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', 'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', 'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', 'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', 'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', 'ḣ'), + (0x1E23, 'V'), + ] + +def _seg_17() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E24, 'M', 'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', 'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', 'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', 'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', 'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', 'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', 'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', 'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', 'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', 'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', 'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', 'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', 'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', 'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', 'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', 'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', 'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', 'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', 'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', 'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', 'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', 'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', 'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', 'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', 'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', 'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', 'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', 'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', 'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', 'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', 'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', 'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', 'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', 'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', 'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', 'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', 'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', 'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', 'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', 'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', 'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', 'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', 'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', 'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', 'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', 'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', 'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', 'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', 'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', 'ẇ'), + (0x1E87, 'V'), + ] + +def _seg_18() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E88, 'M', 'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', 'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', 'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', 'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', 'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', 'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', 'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', 'aʾ'), + (0x1E9B, 'M', 'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', 'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', 'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', 'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', 'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', 'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', 'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', 'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', 'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', 'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', 'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', 'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', 'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', 'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', 'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', 'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', 'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', 'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', 'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', 'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', 'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', 'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', 'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', 'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', 'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', 'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', 'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', 'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', 'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', 'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', 'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', 'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', 'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', 'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', 'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', 'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', 'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', 'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', 'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', 'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', 'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', 'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', 'ự'), + ] + +def _seg_19() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EF1, 'V'), + (0x1EF2, 'M', 'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', 'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', 'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', 'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', 'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', 'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', 'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', 'ἀ'), + (0x1F09, 'M', 'ἁ'), + (0x1F0A, 'M', 'ἂ'), + (0x1F0B, 'M', 'ἃ'), + (0x1F0C, 'M', 'ἄ'), + (0x1F0D, 'M', 'ἅ'), + (0x1F0E, 'M', 'ἆ'), + (0x1F0F, 'M', 'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', 'ἐ'), + (0x1F19, 'M', 'ἑ'), + (0x1F1A, 'M', 'ἒ'), + (0x1F1B, 'M', 'ἓ'), + (0x1F1C, 'M', 'ἔ'), + (0x1F1D, 'M', 'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', 'ἠ'), + (0x1F29, 'M', 'ἡ'), + (0x1F2A, 'M', 'ἢ'), + (0x1F2B, 'M', 'ἣ'), + (0x1F2C, 'M', 'ἤ'), + (0x1F2D, 'M', 'ἥ'), + (0x1F2E, 'M', 'ἦ'), + (0x1F2F, 'M', 'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', 'ἰ'), + (0x1F39, 'M', 'ἱ'), + (0x1F3A, 'M', 'ἲ'), + (0x1F3B, 'M', 'ἳ'), + (0x1F3C, 'M', 'ἴ'), + (0x1F3D, 'M', 'ἵ'), + (0x1F3E, 'M', 'ἶ'), + (0x1F3F, 'M', 'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', 'ὀ'), + (0x1F49, 'M', 'ὁ'), + (0x1F4A, 'M', 'ὂ'), + (0x1F4B, 'M', 'ὃ'), + (0x1F4C, 'M', 'ὄ'), + (0x1F4D, 'M', 'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', 'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', 'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', 'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', 'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', 'ὠ'), + (0x1F69, 'M', 'ὡ'), + (0x1F6A, 'M', 'ὢ'), + (0x1F6B, 'M', 'ὣ'), + (0x1F6C, 'M', 'ὤ'), + (0x1F6D, 'M', 'ὥ'), + (0x1F6E, 'M', 'ὦ'), + (0x1F6F, 'M', 'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', 'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', 'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', 'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', 'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', 'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', 'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', 'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', 'ἀι'), + (0x1F81, 'M', 'ἁι'), + (0x1F82, 'M', 'ἂι'), + (0x1F83, 'M', 'ἃι'), + (0x1F84, 'M', 'ἄι'), + (0x1F85, 'M', 'ἅι'), + (0x1F86, 'M', 'ἆι'), + (0x1F87, 'M', 'ἇι'), + ] + +def _seg_20() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F88, 'M', 'ἀι'), + (0x1F89, 'M', 'ἁι'), + (0x1F8A, 'M', 'ἂι'), + (0x1F8B, 'M', 'ἃι'), + (0x1F8C, 'M', 'ἄι'), + (0x1F8D, 'M', 'ἅι'), + (0x1F8E, 'M', 'ἆι'), + (0x1F8F, 'M', 'ἇι'), + (0x1F90, 'M', 'ἠι'), + (0x1F91, 'M', 'ἡι'), + (0x1F92, 'M', 'ἢι'), + (0x1F93, 'M', 'ἣι'), + (0x1F94, 'M', 'ἤι'), + (0x1F95, 'M', 'ἥι'), + (0x1F96, 'M', 'ἦι'), + (0x1F97, 'M', 'ἧι'), + (0x1F98, 'M', 'ἠι'), + (0x1F99, 'M', 'ἡι'), + (0x1F9A, 'M', 'ἢι'), + (0x1F9B, 'M', 'ἣι'), + (0x1F9C, 'M', 'ἤι'), + (0x1F9D, 'M', 'ἥι'), + (0x1F9E, 'M', 'ἦι'), + (0x1F9F, 'M', 'ἧι'), + (0x1FA0, 'M', 'ὠι'), + (0x1FA1, 'M', 'ὡι'), + (0x1FA2, 'M', 'ὢι'), + (0x1FA3, 'M', 'ὣι'), + (0x1FA4, 'M', 'ὤι'), + (0x1FA5, 'M', 'ὥι'), + (0x1FA6, 'M', 'ὦι'), + (0x1FA7, 'M', 'ὧι'), + (0x1FA8, 'M', 'ὠι'), + (0x1FA9, 'M', 'ὡι'), + (0x1FAA, 'M', 'ὢι'), + (0x1FAB, 'M', 'ὣι'), + (0x1FAC, 'M', 'ὤι'), + (0x1FAD, 'M', 'ὥι'), + (0x1FAE, 'M', 'ὦι'), + (0x1FAF, 'M', 'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', 'ὰι'), + (0x1FB3, 'M', 'αι'), + (0x1FB4, 'M', 'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', 'ᾶι'), + (0x1FB8, 'M', 'ᾰ'), + (0x1FB9, 'M', 'ᾱ'), + (0x1FBA, 'M', 'ὰ'), + (0x1FBB, 'M', 'ά'), + (0x1FBC, 'M', 'αι'), + (0x1FBD, '3', ' ̓'), + (0x1FBE, 'M', 'ι'), + (0x1FBF, '3', ' ̓'), + (0x1FC0, '3', ' ͂'), + (0x1FC1, '3', ' ̈͂'), + (0x1FC2, 'M', 'ὴι'), + (0x1FC3, 'M', 'ηι'), + (0x1FC4, 'M', 'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', 'ῆι'), + (0x1FC8, 'M', 'ὲ'), + (0x1FC9, 'M', 'έ'), + (0x1FCA, 'M', 'ὴ'), + (0x1FCB, 'M', 'ή'), + (0x1FCC, 'M', 'ηι'), + (0x1FCD, '3', ' ̓̀'), + (0x1FCE, '3', ' ̓́'), + (0x1FCF, '3', ' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', 'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', 'ῐ'), + (0x1FD9, 'M', 'ῑ'), + (0x1FDA, 'M', 'ὶ'), + (0x1FDB, 'M', 'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', ' ̔̀'), + (0x1FDE, '3', ' ̔́'), + (0x1FDF, '3', ' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', 'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', 'ῠ'), + (0x1FE9, 'M', 'ῡ'), + (0x1FEA, 'M', 'ὺ'), + (0x1FEB, 'M', 'ύ'), + (0x1FEC, 'M', 'ῥ'), + (0x1FED, '3', ' ̈̀'), + (0x1FEE, '3', ' ̈́'), + (0x1FEF, '3', '`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', 'ὼι'), + (0x1FF3, 'M', 'ωι'), + (0x1FF4, 'M', 'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + ] + +def _seg_21() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FF7, 'M', 'ῶι'), + (0x1FF8, 'M', 'ὸ'), + (0x1FF9, 'M', 'ό'), + (0x1FFA, 'M', 'ὼ'), + (0x1FFB, 'M', 'ώ'), + (0x1FFC, 'M', 'ωι'), + (0x1FFD, '3', ' ́'), + (0x1FFE, '3', ' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', ' '), + (0x200B, 'I'), + (0x200C, 'D', ''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', '‐'), + (0x2012, 'V'), + (0x2017, '3', ' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', ' '), + (0x2030, 'V'), + (0x2033, 'M', '′′'), + (0x2034, 'M', '′′′'), + (0x2035, 'V'), + (0x2036, 'M', '‵‵'), + (0x2037, 'M', '‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', '!!'), + (0x203D, 'V'), + (0x203E, '3', ' ̅'), + (0x203F, 'V'), + (0x2047, '3', '??'), + (0x2048, '3', '?!'), + (0x2049, '3', '!?'), + (0x204A, 'V'), + (0x2057, 'M', '′′′′'), + (0x2058, 'V'), + (0x205F, '3', ' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', '0'), + (0x2071, 'M', 'i'), + (0x2072, 'X'), + (0x2074, 'M', '4'), + (0x2075, 'M', '5'), + (0x2076, 'M', '6'), + (0x2077, 'M', '7'), + (0x2078, 'M', '8'), + (0x2079, 'M', '9'), + (0x207A, '3', '+'), + (0x207B, 'M', '−'), + (0x207C, '3', '='), + (0x207D, '3', '('), + (0x207E, '3', ')'), + (0x207F, 'M', 'n'), + (0x2080, 'M', '0'), + (0x2081, 'M', '1'), + (0x2082, 'M', '2'), + (0x2083, 'M', '3'), + (0x2084, 'M', '4'), + (0x2085, 'M', '5'), + (0x2086, 'M', '6'), + (0x2087, 'M', '7'), + (0x2088, 'M', '8'), + (0x2089, 'M', '9'), + (0x208A, '3', '+'), + (0x208B, 'M', '−'), + (0x208C, '3', '='), + (0x208D, '3', '('), + (0x208E, '3', ')'), + (0x208F, 'X'), + (0x2090, 'M', 'a'), + (0x2091, 'M', 'e'), + (0x2092, 'M', 'o'), + (0x2093, 'M', 'x'), + (0x2094, 'M', 'ə'), + (0x2095, 'M', 'h'), + (0x2096, 'M', 'k'), + (0x2097, 'M', 'l'), + (0x2098, 'M', 'm'), + (0x2099, 'M', 'n'), + (0x209A, 'M', 'p'), + (0x209B, 'M', 's'), + (0x209C, 'M', 't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', 'rs'), + (0x20A9, 'V'), + (0x20C1, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', 'a/c'), + (0x2101, '3', 'a/s'), + (0x2102, 'M', 'c'), + (0x2103, 'M', '°c'), + (0x2104, 'V'), + ] + +def _seg_22() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2105, '3', 'c/o'), + (0x2106, '3', 'c/u'), + (0x2107, 'M', 'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', '°f'), + (0x210A, 'M', 'g'), + (0x210B, 'M', 'h'), + (0x210F, 'M', 'ħ'), + (0x2110, 'M', 'i'), + (0x2112, 'M', 'l'), + (0x2114, 'V'), + (0x2115, 'M', 'n'), + (0x2116, 'M', 'no'), + (0x2117, 'V'), + (0x2119, 'M', 'p'), + (0x211A, 'M', 'q'), + (0x211B, 'M', 'r'), + (0x211E, 'V'), + (0x2120, 'M', 'sm'), + (0x2121, 'M', 'tel'), + (0x2122, 'M', 'tm'), + (0x2123, 'V'), + (0x2124, 'M', 'z'), + (0x2125, 'V'), + (0x2126, 'M', 'ω'), + (0x2127, 'V'), + (0x2128, 'M', 'z'), + (0x2129, 'V'), + (0x212A, 'M', 'k'), + (0x212B, 'M', 'å'), + (0x212C, 'M', 'b'), + (0x212D, 'M', 'c'), + (0x212E, 'V'), + (0x212F, 'M', 'e'), + (0x2131, 'M', 'f'), + (0x2132, 'X'), + (0x2133, 'M', 'm'), + (0x2134, 'M', 'o'), + (0x2135, 'M', 'א'), + (0x2136, 'M', 'ב'), + (0x2137, 'M', 'ג'), + (0x2138, 'M', 'ד'), + (0x2139, 'M', 'i'), + (0x213A, 'V'), + (0x213B, 'M', 'fax'), + (0x213C, 'M', 'π'), + (0x213D, 'M', 'γ'), + (0x213F, 'M', 'π'), + (0x2140, 'M', '∑'), + (0x2141, 'V'), + (0x2145, 'M', 'd'), + (0x2147, 'M', 'e'), + (0x2148, 'M', 'i'), + (0x2149, 'M', 'j'), + (0x214A, 'V'), + (0x2150, 'M', '1⁄7'), + (0x2151, 'M', '1⁄9'), + (0x2152, 'M', '1⁄10'), + (0x2153, 'M', '1⁄3'), + (0x2154, 'M', '2⁄3'), + (0x2155, 'M', '1⁄5'), + (0x2156, 'M', '2⁄5'), + (0x2157, 'M', '3⁄5'), + (0x2158, 'M', '4⁄5'), + (0x2159, 'M', '1⁄6'), + (0x215A, 'M', '5⁄6'), + (0x215B, 'M', '1⁄8'), + (0x215C, 'M', '3⁄8'), + (0x215D, 'M', '5⁄8'), + (0x215E, 'M', '7⁄8'), + (0x215F, 'M', '1⁄'), + (0x2160, 'M', 'i'), + (0x2161, 'M', 'ii'), + (0x2162, 'M', 'iii'), + (0x2163, 'M', 'iv'), + (0x2164, 'M', 'v'), + (0x2165, 'M', 'vi'), + (0x2166, 'M', 'vii'), + (0x2167, 'M', 'viii'), + (0x2168, 'M', 'ix'), + (0x2169, 'M', 'x'), + (0x216A, 'M', 'xi'), + (0x216B, 'M', 'xii'), + (0x216C, 'M', 'l'), + (0x216D, 'M', 'c'), + (0x216E, 'M', 'd'), + (0x216F, 'M', 'm'), + (0x2170, 'M', 'i'), + (0x2171, 'M', 'ii'), + (0x2172, 'M', 'iii'), + (0x2173, 'M', 'iv'), + (0x2174, 'M', 'v'), + (0x2175, 'M', 'vi'), + (0x2176, 'M', 'vii'), + (0x2177, 'M', 'viii'), + (0x2178, 'M', 'ix'), + (0x2179, 'M', 'x'), + (0x217A, 'M', 'xi'), + (0x217B, 'M', 'xii'), + (0x217C, 'M', 'l'), + ] + +def _seg_23() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x217D, 'M', 'c'), + (0x217E, 'M', 'd'), + (0x217F, 'M', 'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', '0⁄3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', '∫∫'), + (0x222D, 'M', '∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', '∮∮'), + (0x2230, 'M', '∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', '〈'), + (0x232A, 'M', '〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', '1'), + (0x2461, 'M', '2'), + (0x2462, 'M', '3'), + (0x2463, 'M', '4'), + (0x2464, 'M', '5'), + (0x2465, 'M', '6'), + (0x2466, 'M', '7'), + (0x2467, 'M', '8'), + (0x2468, 'M', '9'), + (0x2469, 'M', '10'), + (0x246A, 'M', '11'), + (0x246B, 'M', '12'), + (0x246C, 'M', '13'), + (0x246D, 'M', '14'), + (0x246E, 'M', '15'), + (0x246F, 'M', '16'), + (0x2470, 'M', '17'), + (0x2471, 'M', '18'), + (0x2472, 'M', '19'), + (0x2473, 'M', '20'), + (0x2474, '3', '(1)'), + (0x2475, '3', '(2)'), + (0x2476, '3', '(3)'), + (0x2477, '3', '(4)'), + (0x2478, '3', '(5)'), + (0x2479, '3', '(6)'), + (0x247A, '3', '(7)'), + (0x247B, '3', '(8)'), + (0x247C, '3', '(9)'), + (0x247D, '3', '(10)'), + (0x247E, '3', '(11)'), + (0x247F, '3', '(12)'), + (0x2480, '3', '(13)'), + (0x2481, '3', '(14)'), + (0x2482, '3', '(15)'), + (0x2483, '3', '(16)'), + (0x2484, '3', '(17)'), + (0x2485, '3', '(18)'), + (0x2486, '3', '(19)'), + (0x2487, '3', '(20)'), + (0x2488, 'X'), + (0x249C, '3', '(a)'), + (0x249D, '3', '(b)'), + (0x249E, '3', '(c)'), + (0x249F, '3', '(d)'), + (0x24A0, '3', '(e)'), + (0x24A1, '3', '(f)'), + (0x24A2, '3', '(g)'), + (0x24A3, '3', '(h)'), + (0x24A4, '3', '(i)'), + (0x24A5, '3', '(j)'), + (0x24A6, '3', '(k)'), + (0x24A7, '3', '(l)'), + (0x24A8, '3', '(m)'), + (0x24A9, '3', '(n)'), + (0x24AA, '3', '(o)'), + (0x24AB, '3', '(p)'), + (0x24AC, '3', '(q)'), + (0x24AD, '3', '(r)'), + (0x24AE, '3', '(s)'), + (0x24AF, '3', '(t)'), + (0x24B0, '3', '(u)'), + (0x24B1, '3', '(v)'), + (0x24B2, '3', '(w)'), + (0x24B3, '3', '(x)'), + (0x24B4, '3', '(y)'), + (0x24B5, '3', '(z)'), + (0x24B6, 'M', 'a'), + (0x24B7, 'M', 'b'), + (0x24B8, 'M', 'c'), + (0x24B9, 'M', 'd'), + (0x24BA, 'M', 'e'), + (0x24BB, 'M', 'f'), + (0x24BC, 'M', 'g'), + ] + +def _seg_24() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x24BD, 'M', 'h'), + (0x24BE, 'M', 'i'), + (0x24BF, 'M', 'j'), + (0x24C0, 'M', 'k'), + (0x24C1, 'M', 'l'), + (0x24C2, 'M', 'm'), + (0x24C3, 'M', 'n'), + (0x24C4, 'M', 'o'), + (0x24C5, 'M', 'p'), + (0x24C6, 'M', 'q'), + (0x24C7, 'M', 'r'), + (0x24C8, 'M', 's'), + (0x24C9, 'M', 't'), + (0x24CA, 'M', 'u'), + (0x24CB, 'M', 'v'), + (0x24CC, 'M', 'w'), + (0x24CD, 'M', 'x'), + (0x24CE, 'M', 'y'), + (0x24CF, 'M', 'z'), + (0x24D0, 'M', 'a'), + (0x24D1, 'M', 'b'), + (0x24D2, 'M', 'c'), + (0x24D3, 'M', 'd'), + (0x24D4, 'M', 'e'), + (0x24D5, 'M', 'f'), + (0x24D6, 'M', 'g'), + (0x24D7, 'M', 'h'), + (0x24D8, 'M', 'i'), + (0x24D9, 'M', 'j'), + (0x24DA, 'M', 'k'), + (0x24DB, 'M', 'l'), + (0x24DC, 'M', 'm'), + (0x24DD, 'M', 'n'), + (0x24DE, 'M', 'o'), + (0x24DF, 'M', 'p'), + (0x24E0, 'M', 'q'), + (0x24E1, 'M', 'r'), + (0x24E2, 'M', 's'), + (0x24E3, 'M', 't'), + (0x24E4, 'M', 'u'), + (0x24E5, 'M', 'v'), + (0x24E6, 'M', 'w'), + (0x24E7, 'M', 'x'), + (0x24E8, 'M', 'y'), + (0x24E9, 'M', 'z'), + (0x24EA, 'M', '0'), + (0x24EB, 'V'), + (0x2A0C, 'M', '∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', '::='), + (0x2A75, '3', '=='), + (0x2A76, '3', '==='), + (0x2A77, 'V'), + (0x2ADC, 'M', '⫝̸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B97, 'V'), + (0x2C00, 'M', 'ⰰ'), + (0x2C01, 'M', 'ⰱ'), + (0x2C02, 'M', 'ⰲ'), + (0x2C03, 'M', 'ⰳ'), + (0x2C04, 'M', 'ⰴ'), + (0x2C05, 'M', 'ⰵ'), + (0x2C06, 'M', 'ⰶ'), + (0x2C07, 'M', 'ⰷ'), + (0x2C08, 'M', 'ⰸ'), + (0x2C09, 'M', 'ⰹ'), + (0x2C0A, 'M', 'ⰺ'), + (0x2C0B, 'M', 'ⰻ'), + (0x2C0C, 'M', 'ⰼ'), + (0x2C0D, 'M', 'ⰽ'), + (0x2C0E, 'M', 'ⰾ'), + (0x2C0F, 'M', 'ⰿ'), + (0x2C10, 'M', 'ⱀ'), + (0x2C11, 'M', 'ⱁ'), + (0x2C12, 'M', 'ⱂ'), + (0x2C13, 'M', 'ⱃ'), + (0x2C14, 'M', 'ⱄ'), + (0x2C15, 'M', 'ⱅ'), + (0x2C16, 'M', 'ⱆ'), + (0x2C17, 'M', 'ⱇ'), + (0x2C18, 'M', 'ⱈ'), + (0x2C19, 'M', 'ⱉ'), + (0x2C1A, 'M', 'ⱊ'), + (0x2C1B, 'M', 'ⱋ'), + (0x2C1C, 'M', 'ⱌ'), + (0x2C1D, 'M', 'ⱍ'), + (0x2C1E, 'M', 'ⱎ'), + (0x2C1F, 'M', 'ⱏ'), + (0x2C20, 'M', 'ⱐ'), + (0x2C21, 'M', 'ⱑ'), + (0x2C22, 'M', 'ⱒ'), + (0x2C23, 'M', 'ⱓ'), + (0x2C24, 'M', 'ⱔ'), + (0x2C25, 'M', 'ⱕ'), + (0x2C26, 'M', 'ⱖ'), + (0x2C27, 'M', 'ⱗ'), + (0x2C28, 'M', 'ⱘ'), + ] + +def _seg_25() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2C29, 'M', 'ⱙ'), + (0x2C2A, 'M', 'ⱚ'), + (0x2C2B, 'M', 'ⱛ'), + (0x2C2C, 'M', 'ⱜ'), + (0x2C2D, 'M', 'ⱝ'), + (0x2C2E, 'M', 'ⱞ'), + (0x2C2F, 'M', 'ⱟ'), + (0x2C30, 'V'), + (0x2C60, 'M', 'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', 'ɫ'), + (0x2C63, 'M', 'ᵽ'), + (0x2C64, 'M', 'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', 'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', 'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', 'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', 'ɑ'), + (0x2C6E, 'M', 'ɱ'), + (0x2C6F, 'M', 'ɐ'), + (0x2C70, 'M', 'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', 'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', 'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', 'j'), + (0x2C7D, 'M', 'v'), + (0x2C7E, 'M', 'ȿ'), + (0x2C7F, 'M', 'ɀ'), + (0x2C80, 'M', 'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', 'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', 'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', 'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', 'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', 'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', 'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', 'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', 'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', 'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', 'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', 'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', 'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', 'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', 'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', 'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', 'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', 'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', 'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', 'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', 'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', 'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', 'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', 'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', 'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', 'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', 'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', 'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', 'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', 'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', 'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', 'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', 'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', 'ⳃ'), + ] + +def _seg_26() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2CC3, 'V'), + (0x2CC4, 'M', 'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', 'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', 'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', 'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', 'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', 'ⳏ'), + (0x2CCF, 'V'), + (0x2CD0, 'M', 'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', 'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', 'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', 'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', 'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', 'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', 'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', 'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', 'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', 'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', 'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', 'ⳮ'), + (0x2CEE, 'V'), + (0x2CF2, 'M', 'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', 'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E5E, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', '母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', '龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', '一'), + (0x2F01, 'M', '丨'), + (0x2F02, 'M', '丶'), + (0x2F03, 'M', '丿'), + (0x2F04, 'M', '乙'), + (0x2F05, 'M', '亅'), + (0x2F06, 'M', '二'), + (0x2F07, 'M', '亠'), + (0x2F08, 'M', '人'), + (0x2F09, 'M', '儿'), + (0x2F0A, 'M', '入'), + (0x2F0B, 'M', '八'), + (0x2F0C, 'M', '冂'), + (0x2F0D, 'M', '冖'), + (0x2F0E, 'M', '冫'), + (0x2F0F, 'M', '几'), + (0x2F10, 'M', '凵'), + (0x2F11, 'M', '刀'), + (0x2F12, 'M', '力'), + (0x2F13, 'M', '勹'), + (0x2F14, 'M', '匕'), + (0x2F15, 'M', '匚'), + ] + +def _seg_27() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F16, 'M', '匸'), + (0x2F17, 'M', '十'), + (0x2F18, 'M', '卜'), + (0x2F19, 'M', '卩'), + (0x2F1A, 'M', '厂'), + (0x2F1B, 'M', '厶'), + (0x2F1C, 'M', '又'), + (0x2F1D, 'M', '口'), + (0x2F1E, 'M', '囗'), + (0x2F1F, 'M', '土'), + (0x2F20, 'M', '士'), + (0x2F21, 'M', '夂'), + (0x2F22, 'M', '夊'), + (0x2F23, 'M', '夕'), + (0x2F24, 'M', '大'), + (0x2F25, 'M', '女'), + (0x2F26, 'M', '子'), + (0x2F27, 'M', '宀'), + (0x2F28, 'M', '寸'), + (0x2F29, 'M', '小'), + (0x2F2A, 'M', '尢'), + (0x2F2B, 'M', '尸'), + (0x2F2C, 'M', '屮'), + (0x2F2D, 'M', '山'), + (0x2F2E, 'M', '巛'), + (0x2F2F, 'M', '工'), + (0x2F30, 'M', '己'), + (0x2F31, 'M', '巾'), + (0x2F32, 'M', '干'), + (0x2F33, 'M', '幺'), + (0x2F34, 'M', '广'), + (0x2F35, 'M', '廴'), + (0x2F36, 'M', '廾'), + (0x2F37, 'M', '弋'), + (0x2F38, 'M', '弓'), + (0x2F39, 'M', '彐'), + (0x2F3A, 'M', '彡'), + (0x2F3B, 'M', '彳'), + (0x2F3C, 'M', '心'), + (0x2F3D, 'M', '戈'), + (0x2F3E, 'M', '戶'), + (0x2F3F, 'M', '手'), + (0x2F40, 'M', '支'), + (0x2F41, 'M', '攴'), + (0x2F42, 'M', '文'), + (0x2F43, 'M', '斗'), + (0x2F44, 'M', '斤'), + (0x2F45, 'M', '方'), + (0x2F46, 'M', '无'), + (0x2F47, 'M', '日'), + (0x2F48, 'M', '曰'), + (0x2F49, 'M', '月'), + (0x2F4A, 'M', '木'), + (0x2F4B, 'M', '欠'), + (0x2F4C, 'M', '止'), + (0x2F4D, 'M', '歹'), + (0x2F4E, 'M', '殳'), + (0x2F4F, 'M', '毋'), + (0x2F50, 'M', '比'), + (0x2F51, 'M', '毛'), + (0x2F52, 'M', '氏'), + (0x2F53, 'M', '气'), + (0x2F54, 'M', '水'), + (0x2F55, 'M', '火'), + (0x2F56, 'M', '爪'), + (0x2F57, 'M', '父'), + (0x2F58, 'M', '爻'), + (0x2F59, 'M', '爿'), + (0x2F5A, 'M', '片'), + (0x2F5B, 'M', '牙'), + (0x2F5C, 'M', '牛'), + (0x2F5D, 'M', '犬'), + (0x2F5E, 'M', '玄'), + (0x2F5F, 'M', '玉'), + (0x2F60, 'M', '瓜'), + (0x2F61, 'M', '瓦'), + (0x2F62, 'M', '甘'), + (0x2F63, 'M', '生'), + (0x2F64, 'M', '用'), + (0x2F65, 'M', '田'), + (0x2F66, 'M', '疋'), + (0x2F67, 'M', '疒'), + (0x2F68, 'M', '癶'), + (0x2F69, 'M', '白'), + (0x2F6A, 'M', '皮'), + (0x2F6B, 'M', '皿'), + (0x2F6C, 'M', '目'), + (0x2F6D, 'M', '矛'), + (0x2F6E, 'M', '矢'), + (0x2F6F, 'M', '石'), + (0x2F70, 'M', '示'), + (0x2F71, 'M', '禸'), + (0x2F72, 'M', '禾'), + (0x2F73, 'M', '穴'), + (0x2F74, 'M', '立'), + (0x2F75, 'M', '竹'), + (0x2F76, 'M', '米'), + (0x2F77, 'M', '糸'), + (0x2F78, 'M', '缶'), + (0x2F79, 'M', '网'), + ] + +def _seg_28() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F7A, 'M', '羊'), + (0x2F7B, 'M', '羽'), + (0x2F7C, 'M', '老'), + (0x2F7D, 'M', '而'), + (0x2F7E, 'M', '耒'), + (0x2F7F, 'M', '耳'), + (0x2F80, 'M', '聿'), + (0x2F81, 'M', '肉'), + (0x2F82, 'M', '臣'), + (0x2F83, 'M', '自'), + (0x2F84, 'M', '至'), + (0x2F85, 'M', '臼'), + (0x2F86, 'M', '舌'), + (0x2F87, 'M', '舛'), + (0x2F88, 'M', '舟'), + (0x2F89, 'M', '艮'), + (0x2F8A, 'M', '色'), + (0x2F8B, 'M', '艸'), + (0x2F8C, 'M', '虍'), + (0x2F8D, 'M', '虫'), + (0x2F8E, 'M', '血'), + (0x2F8F, 'M', '行'), + (0x2F90, 'M', '衣'), + (0x2F91, 'M', '襾'), + (0x2F92, 'M', '見'), + (0x2F93, 'M', '角'), + (0x2F94, 'M', '言'), + (0x2F95, 'M', '谷'), + (0x2F96, 'M', '豆'), + (0x2F97, 'M', '豕'), + (0x2F98, 'M', '豸'), + (0x2F99, 'M', '貝'), + (0x2F9A, 'M', '赤'), + (0x2F9B, 'M', '走'), + (0x2F9C, 'M', '足'), + (0x2F9D, 'M', '身'), + (0x2F9E, 'M', '車'), + (0x2F9F, 'M', '辛'), + (0x2FA0, 'M', '辰'), + (0x2FA1, 'M', '辵'), + (0x2FA2, 'M', '邑'), + (0x2FA3, 'M', '酉'), + (0x2FA4, 'M', '釆'), + (0x2FA5, 'M', '里'), + (0x2FA6, 'M', '金'), + (0x2FA7, 'M', '長'), + (0x2FA8, 'M', '門'), + (0x2FA9, 'M', '阜'), + (0x2FAA, 'M', '隶'), + (0x2FAB, 'M', '隹'), + (0x2FAC, 'M', '雨'), + (0x2FAD, 'M', '靑'), + (0x2FAE, 'M', '非'), + (0x2FAF, 'M', '面'), + (0x2FB0, 'M', '革'), + (0x2FB1, 'M', '韋'), + (0x2FB2, 'M', '韭'), + (0x2FB3, 'M', '音'), + (0x2FB4, 'M', '頁'), + (0x2FB5, 'M', '風'), + (0x2FB6, 'M', '飛'), + (0x2FB7, 'M', '食'), + (0x2FB8, 'M', '首'), + (0x2FB9, 'M', '香'), + (0x2FBA, 'M', '馬'), + (0x2FBB, 'M', '骨'), + (0x2FBC, 'M', '高'), + (0x2FBD, 'M', '髟'), + (0x2FBE, 'M', '鬥'), + (0x2FBF, 'M', '鬯'), + (0x2FC0, 'M', '鬲'), + (0x2FC1, 'M', '鬼'), + (0x2FC2, 'M', '魚'), + (0x2FC3, 'M', '鳥'), + (0x2FC4, 'M', '鹵'), + (0x2FC5, 'M', '鹿'), + (0x2FC6, 'M', '麥'), + (0x2FC7, 'M', '麻'), + (0x2FC8, 'M', '黃'), + (0x2FC9, 'M', '黍'), + (0x2FCA, 'M', '黑'), + (0x2FCB, 'M', '黹'), + (0x2FCC, 'M', '黽'), + (0x2FCD, 'M', '鼎'), + (0x2FCE, 'M', '鼓'), + (0x2FCF, 'M', '鼠'), + (0x2FD0, 'M', '鼻'), + (0x2FD1, 'M', '齊'), + (0x2FD2, 'M', '齒'), + (0x2FD3, 'M', '龍'), + (0x2FD4, 'M', '龜'), + (0x2FD5, 'M', '龠'), + (0x2FD6, 'X'), + (0x3000, '3', ' '), + (0x3001, 'V'), + (0x3002, 'M', '.'), + (0x3003, 'V'), + (0x3036, 'M', '〒'), + (0x3037, 'V'), + (0x3038, 'M', '十'), + ] + +def _seg_29() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3039, 'M', '卄'), + (0x303A, 'M', '卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', ' ゙'), + (0x309C, '3', ' ゚'), + (0x309D, 'V'), + (0x309F, 'M', 'より'), + (0x30A0, 'V'), + (0x30FF, 'M', 'コト'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x3130, 'X'), + (0x3131, 'M', 'ᄀ'), + (0x3132, 'M', 'ᄁ'), + (0x3133, 'M', 'ᆪ'), + (0x3134, 'M', 'ᄂ'), + (0x3135, 'M', 'ᆬ'), + (0x3136, 'M', 'ᆭ'), + (0x3137, 'M', 'ᄃ'), + (0x3138, 'M', 'ᄄ'), + (0x3139, 'M', 'ᄅ'), + (0x313A, 'M', 'ᆰ'), + (0x313B, 'M', 'ᆱ'), + (0x313C, 'M', 'ᆲ'), + (0x313D, 'M', 'ᆳ'), + (0x313E, 'M', 'ᆴ'), + (0x313F, 'M', 'ᆵ'), + (0x3140, 'M', 'ᄚ'), + (0x3141, 'M', 'ᄆ'), + (0x3142, 'M', 'ᄇ'), + (0x3143, 'M', 'ᄈ'), + (0x3144, 'M', 'ᄡ'), + (0x3145, 'M', 'ᄉ'), + (0x3146, 'M', 'ᄊ'), + (0x3147, 'M', 'ᄋ'), + (0x3148, 'M', 'ᄌ'), + (0x3149, 'M', 'ᄍ'), + (0x314A, 'M', 'ᄎ'), + (0x314B, 'M', 'ᄏ'), + (0x314C, 'M', 'ᄐ'), + (0x314D, 'M', 'ᄑ'), + (0x314E, 'M', 'ᄒ'), + (0x314F, 'M', 'ᅡ'), + (0x3150, 'M', 'ᅢ'), + (0x3151, 'M', 'ᅣ'), + (0x3152, 'M', 'ᅤ'), + (0x3153, 'M', 'ᅥ'), + (0x3154, 'M', 'ᅦ'), + (0x3155, 'M', 'ᅧ'), + (0x3156, 'M', 'ᅨ'), + (0x3157, 'M', 'ᅩ'), + (0x3158, 'M', 'ᅪ'), + (0x3159, 'M', 'ᅫ'), + (0x315A, 'M', 'ᅬ'), + (0x315B, 'M', 'ᅭ'), + (0x315C, 'M', 'ᅮ'), + (0x315D, 'M', 'ᅯ'), + (0x315E, 'M', 'ᅰ'), + (0x315F, 'M', 'ᅱ'), + (0x3160, 'M', 'ᅲ'), + (0x3161, 'M', 'ᅳ'), + (0x3162, 'M', 'ᅴ'), + (0x3163, 'M', 'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', 'ᄔ'), + (0x3166, 'M', 'ᄕ'), + (0x3167, 'M', 'ᇇ'), + (0x3168, 'M', 'ᇈ'), + (0x3169, 'M', 'ᇌ'), + (0x316A, 'M', 'ᇎ'), + (0x316B, 'M', 'ᇓ'), + (0x316C, 'M', 'ᇗ'), + (0x316D, 'M', 'ᇙ'), + (0x316E, 'M', 'ᄜ'), + (0x316F, 'M', 'ᇝ'), + (0x3170, 'M', 'ᇟ'), + (0x3171, 'M', 'ᄝ'), + (0x3172, 'M', 'ᄞ'), + (0x3173, 'M', 'ᄠ'), + (0x3174, 'M', 'ᄢ'), + (0x3175, 'M', 'ᄣ'), + (0x3176, 'M', 'ᄧ'), + (0x3177, 'M', 'ᄩ'), + (0x3178, 'M', 'ᄫ'), + (0x3179, 'M', 'ᄬ'), + (0x317A, 'M', 'ᄭ'), + (0x317B, 'M', 'ᄮ'), + (0x317C, 'M', 'ᄯ'), + (0x317D, 'M', 'ᄲ'), + (0x317E, 'M', 'ᄶ'), + (0x317F, 'M', 'ᅀ'), + (0x3180, 'M', 'ᅇ'), + (0x3181, 'M', 'ᅌ'), + (0x3182, 'M', 'ᇱ'), + (0x3183, 'M', 'ᇲ'), + (0x3184, 'M', 'ᅗ'), + ] + +def _seg_30() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3185, 'M', 'ᅘ'), + (0x3186, 'M', 'ᅙ'), + (0x3187, 'M', 'ᆄ'), + (0x3188, 'M', 'ᆅ'), + (0x3189, 'M', 'ᆈ'), + (0x318A, 'M', 'ᆑ'), + (0x318B, 'M', 'ᆒ'), + (0x318C, 'M', 'ᆔ'), + (0x318D, 'M', 'ᆞ'), + (0x318E, 'M', 'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', '一'), + (0x3193, 'M', '二'), + (0x3194, 'M', '三'), + (0x3195, 'M', '四'), + (0x3196, 'M', '上'), + (0x3197, 'M', '中'), + (0x3198, 'M', '下'), + (0x3199, 'M', '甲'), + (0x319A, 'M', '乙'), + (0x319B, 'M', '丙'), + (0x319C, 'M', '丁'), + (0x319D, 'M', '天'), + (0x319E, 'M', '地'), + (0x319F, 'M', '人'), + (0x31A0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', '(ᄀ)'), + (0x3201, '3', '(ᄂ)'), + (0x3202, '3', '(ᄃ)'), + (0x3203, '3', '(ᄅ)'), + (0x3204, '3', '(ᄆ)'), + (0x3205, '3', '(ᄇ)'), + (0x3206, '3', '(ᄉ)'), + (0x3207, '3', '(ᄋ)'), + (0x3208, '3', '(ᄌ)'), + (0x3209, '3', '(ᄎ)'), + (0x320A, '3', '(ᄏ)'), + (0x320B, '3', '(ᄐ)'), + (0x320C, '3', '(ᄑ)'), + (0x320D, '3', '(ᄒ)'), + (0x320E, '3', '(가)'), + (0x320F, '3', '(나)'), + (0x3210, '3', '(다)'), + (0x3211, '3', '(라)'), + (0x3212, '3', '(마)'), + (0x3213, '3', '(바)'), + (0x3214, '3', '(사)'), + (0x3215, '3', '(아)'), + (0x3216, '3', '(자)'), + (0x3217, '3', '(차)'), + (0x3218, '3', '(카)'), + (0x3219, '3', '(타)'), + (0x321A, '3', '(파)'), + (0x321B, '3', '(하)'), + (0x321C, '3', '(주)'), + (0x321D, '3', '(오전)'), + (0x321E, '3', '(오후)'), + (0x321F, 'X'), + (0x3220, '3', '(一)'), + (0x3221, '3', '(二)'), + (0x3222, '3', '(三)'), + (0x3223, '3', '(四)'), + (0x3224, '3', '(五)'), + (0x3225, '3', '(六)'), + (0x3226, '3', '(七)'), + (0x3227, '3', '(八)'), + (0x3228, '3', '(九)'), + (0x3229, '3', '(十)'), + (0x322A, '3', '(月)'), + (0x322B, '3', '(火)'), + (0x322C, '3', '(水)'), + (0x322D, '3', '(木)'), + (0x322E, '3', '(金)'), + (0x322F, '3', '(土)'), + (0x3230, '3', '(日)'), + (0x3231, '3', '(株)'), + (0x3232, '3', '(有)'), + (0x3233, '3', '(社)'), + (0x3234, '3', '(名)'), + (0x3235, '3', '(特)'), + (0x3236, '3', '(財)'), + (0x3237, '3', '(祝)'), + (0x3238, '3', '(労)'), + (0x3239, '3', '(代)'), + (0x323A, '3', '(呼)'), + (0x323B, '3', '(学)'), + (0x323C, '3', '(監)'), + (0x323D, '3', '(企)'), + (0x323E, '3', '(資)'), + (0x323F, '3', '(協)'), + (0x3240, '3', '(祭)'), + (0x3241, '3', '(休)'), + (0x3242, '3', '(自)'), + (0x3243, '3', '(至)'), + (0x3244, 'M', '問'), + (0x3245, 'M', '幼'), + (0x3246, 'M', '文'), + ] + +def _seg_31() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3247, 'M', '箏'), + (0x3248, 'V'), + (0x3250, 'M', 'pte'), + (0x3251, 'M', '21'), + (0x3252, 'M', '22'), + (0x3253, 'M', '23'), + (0x3254, 'M', '24'), + (0x3255, 'M', '25'), + (0x3256, 'M', '26'), + (0x3257, 'M', '27'), + (0x3258, 'M', '28'), + (0x3259, 'M', '29'), + (0x325A, 'M', '30'), + (0x325B, 'M', '31'), + (0x325C, 'M', '32'), + (0x325D, 'M', '33'), + (0x325E, 'M', '34'), + (0x325F, 'M', '35'), + (0x3260, 'M', 'ᄀ'), + (0x3261, 'M', 'ᄂ'), + (0x3262, 'M', 'ᄃ'), + (0x3263, 'M', 'ᄅ'), + (0x3264, 'M', 'ᄆ'), + (0x3265, 'M', 'ᄇ'), + (0x3266, 'M', 'ᄉ'), + (0x3267, 'M', 'ᄋ'), + (0x3268, 'M', 'ᄌ'), + (0x3269, 'M', 'ᄎ'), + (0x326A, 'M', 'ᄏ'), + (0x326B, 'M', 'ᄐ'), + (0x326C, 'M', 'ᄑ'), + (0x326D, 'M', 'ᄒ'), + (0x326E, 'M', '가'), + (0x326F, 'M', '나'), + (0x3270, 'M', '다'), + (0x3271, 'M', '라'), + (0x3272, 'M', '마'), + (0x3273, 'M', '바'), + (0x3274, 'M', '사'), + (0x3275, 'M', '아'), + (0x3276, 'M', '자'), + (0x3277, 'M', '차'), + (0x3278, 'M', '카'), + (0x3279, 'M', '타'), + (0x327A, 'M', '파'), + (0x327B, 'M', '하'), + (0x327C, 'M', '참고'), + (0x327D, 'M', '주의'), + (0x327E, 'M', '우'), + (0x327F, 'V'), + (0x3280, 'M', '一'), + (0x3281, 'M', '二'), + (0x3282, 'M', '三'), + (0x3283, 'M', '四'), + (0x3284, 'M', '五'), + (0x3285, 'M', '六'), + (0x3286, 'M', '七'), + (0x3287, 'M', '八'), + (0x3288, 'M', '九'), + (0x3289, 'M', '十'), + (0x328A, 'M', '月'), + (0x328B, 'M', '火'), + (0x328C, 'M', '水'), + (0x328D, 'M', '木'), + (0x328E, 'M', '金'), + (0x328F, 'M', '土'), + (0x3290, 'M', '日'), + (0x3291, 'M', '株'), + (0x3292, 'M', '有'), + (0x3293, 'M', '社'), + (0x3294, 'M', '名'), + (0x3295, 'M', '特'), + (0x3296, 'M', '財'), + (0x3297, 'M', '祝'), + (0x3298, 'M', '労'), + (0x3299, 'M', '秘'), + (0x329A, 'M', '男'), + (0x329B, 'M', '女'), + (0x329C, 'M', '適'), + (0x329D, 'M', '優'), + (0x329E, 'M', '印'), + (0x329F, 'M', '注'), + (0x32A0, 'M', '項'), + (0x32A1, 'M', '休'), + (0x32A2, 'M', '写'), + (0x32A3, 'M', '正'), + (0x32A4, 'M', '上'), + (0x32A5, 'M', '中'), + (0x32A6, 'M', '下'), + (0x32A7, 'M', '左'), + (0x32A8, 'M', '右'), + (0x32A9, 'M', '医'), + (0x32AA, 'M', '宗'), + (0x32AB, 'M', '学'), + (0x32AC, 'M', '監'), + (0x32AD, 'M', '企'), + (0x32AE, 'M', '資'), + (0x32AF, 'M', '協'), + (0x32B0, 'M', '夜'), + (0x32B1, 'M', '36'), + ] + +def _seg_32() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x32B2, 'M', '37'), + (0x32B3, 'M', '38'), + (0x32B4, 'M', '39'), + (0x32B5, 'M', '40'), + (0x32B6, 'M', '41'), + (0x32B7, 'M', '42'), + (0x32B8, 'M', '43'), + (0x32B9, 'M', '44'), + (0x32BA, 'M', '45'), + (0x32BB, 'M', '46'), + (0x32BC, 'M', '47'), + (0x32BD, 'M', '48'), + (0x32BE, 'M', '49'), + (0x32BF, 'M', '50'), + (0x32C0, 'M', '1月'), + (0x32C1, 'M', '2月'), + (0x32C2, 'M', '3月'), + (0x32C3, 'M', '4月'), + (0x32C4, 'M', '5月'), + (0x32C5, 'M', '6月'), + (0x32C6, 'M', '7月'), + (0x32C7, 'M', '8月'), + (0x32C8, 'M', '9月'), + (0x32C9, 'M', '10月'), + (0x32CA, 'M', '11月'), + (0x32CB, 'M', '12月'), + (0x32CC, 'M', 'hg'), + (0x32CD, 'M', 'erg'), + (0x32CE, 'M', 'ev'), + (0x32CF, 'M', 'ltd'), + (0x32D0, 'M', 'ア'), + (0x32D1, 'M', 'イ'), + (0x32D2, 'M', 'ウ'), + (0x32D3, 'M', 'エ'), + (0x32D4, 'M', 'オ'), + (0x32D5, 'M', 'カ'), + (0x32D6, 'M', 'キ'), + (0x32D7, 'M', 'ク'), + (0x32D8, 'M', 'ケ'), + (0x32D9, 'M', 'コ'), + (0x32DA, 'M', 'サ'), + (0x32DB, 'M', 'シ'), + (0x32DC, 'M', 'ス'), + (0x32DD, 'M', 'セ'), + (0x32DE, 'M', 'ソ'), + (0x32DF, 'M', 'タ'), + (0x32E0, 'M', 'チ'), + (0x32E1, 'M', 'ツ'), + (0x32E2, 'M', 'テ'), + (0x32E3, 'M', 'ト'), + (0x32E4, 'M', 'ナ'), + (0x32E5, 'M', 'ニ'), + (0x32E6, 'M', 'ヌ'), + (0x32E7, 'M', 'ネ'), + (0x32E8, 'M', 'ノ'), + (0x32E9, 'M', 'ハ'), + (0x32EA, 'M', 'ヒ'), + (0x32EB, 'M', 'フ'), + (0x32EC, 'M', 'ヘ'), + (0x32ED, 'M', 'ホ'), + (0x32EE, 'M', 'マ'), + (0x32EF, 'M', 'ミ'), + (0x32F0, 'M', 'ム'), + (0x32F1, 'M', 'メ'), + (0x32F2, 'M', 'モ'), + (0x32F3, 'M', 'ヤ'), + (0x32F4, 'M', 'ユ'), + (0x32F5, 'M', 'ヨ'), + (0x32F6, 'M', 'ラ'), + (0x32F7, 'M', 'リ'), + (0x32F8, 'M', 'ル'), + (0x32F9, 'M', 'レ'), + (0x32FA, 'M', 'ロ'), + (0x32FB, 'M', 'ワ'), + (0x32FC, 'M', 'ヰ'), + (0x32FD, 'M', 'ヱ'), + (0x32FE, 'M', 'ヲ'), + (0x32FF, 'M', '令和'), + (0x3300, 'M', 'アパート'), + (0x3301, 'M', 'アルファ'), + (0x3302, 'M', 'アンペア'), + (0x3303, 'M', 'アール'), + (0x3304, 'M', 'イニング'), + (0x3305, 'M', 'インチ'), + (0x3306, 'M', 'ウォン'), + (0x3307, 'M', 'エスクード'), + (0x3308, 'M', 'エーカー'), + (0x3309, 'M', 'オンス'), + (0x330A, 'M', 'オーム'), + (0x330B, 'M', 'カイリ'), + (0x330C, 'M', 'カラット'), + (0x330D, 'M', 'カロリー'), + (0x330E, 'M', 'ガロン'), + (0x330F, 'M', 'ガンマ'), + (0x3310, 'M', 'ギガ'), + (0x3311, 'M', 'ギニー'), + (0x3312, 'M', 'キュリー'), + (0x3313, 'M', 'ギルダー'), + (0x3314, 'M', 'キロ'), + (0x3315, 'M', 'キログラム'), + ] + +def _seg_33() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3316, 'M', 'キロメートル'), + (0x3317, 'M', 'キロワット'), + (0x3318, 'M', 'グラム'), + (0x3319, 'M', 'グラムトン'), + (0x331A, 'M', 'クルゼイロ'), + (0x331B, 'M', 'クローネ'), + (0x331C, 'M', 'ケース'), + (0x331D, 'M', 'コルナ'), + (0x331E, 'M', 'コーポ'), + (0x331F, 'M', 'サイクル'), + (0x3320, 'M', 'サンチーム'), + (0x3321, 'M', 'シリング'), + (0x3322, 'M', 'センチ'), + (0x3323, 'M', 'セント'), + (0x3324, 'M', 'ダース'), + (0x3325, 'M', 'デシ'), + (0x3326, 'M', 'ドル'), + (0x3327, 'M', 'トン'), + (0x3328, 'M', 'ナノ'), + (0x3329, 'M', 'ノット'), + (0x332A, 'M', 'ハイツ'), + (0x332B, 'M', 'パーセント'), + (0x332C, 'M', 'パーツ'), + (0x332D, 'M', 'バーレル'), + (0x332E, 'M', 'ピアストル'), + (0x332F, 'M', 'ピクル'), + (0x3330, 'M', 'ピコ'), + (0x3331, 'M', 'ビル'), + (0x3332, 'M', 'ファラッド'), + (0x3333, 'M', 'フィート'), + (0x3334, 'M', 'ブッシェル'), + (0x3335, 'M', 'フラン'), + (0x3336, 'M', 'ヘクタール'), + (0x3337, 'M', 'ペソ'), + (0x3338, 'M', 'ペニヒ'), + (0x3339, 'M', 'ヘルツ'), + (0x333A, 'M', 'ペンス'), + (0x333B, 'M', 'ページ'), + (0x333C, 'M', 'ベータ'), + (0x333D, 'M', 'ポイント'), + (0x333E, 'M', 'ボルト'), + (0x333F, 'M', 'ホン'), + (0x3340, 'M', 'ポンド'), + (0x3341, 'M', 'ホール'), + (0x3342, 'M', 'ホーン'), + (0x3343, 'M', 'マイクロ'), + (0x3344, 'M', 'マイル'), + (0x3345, 'M', 'マッハ'), + (0x3346, 'M', 'マルク'), + (0x3347, 'M', 'マンション'), + (0x3348, 'M', 'ミクロン'), + (0x3349, 'M', 'ミリ'), + (0x334A, 'M', 'ミリバール'), + (0x334B, 'M', 'メガ'), + (0x334C, 'M', 'メガトン'), + (0x334D, 'M', 'メートル'), + (0x334E, 'M', 'ヤード'), + (0x334F, 'M', 'ヤール'), + (0x3350, 'M', 'ユアン'), + (0x3351, 'M', 'リットル'), + (0x3352, 'M', 'リラ'), + (0x3353, 'M', 'ルピー'), + (0x3354, 'M', 'ルーブル'), + (0x3355, 'M', 'レム'), + (0x3356, 'M', 'レントゲン'), + (0x3357, 'M', 'ワット'), + (0x3358, 'M', '0点'), + (0x3359, 'M', '1点'), + (0x335A, 'M', '2点'), + (0x335B, 'M', '3点'), + (0x335C, 'M', '4点'), + (0x335D, 'M', '5点'), + (0x335E, 'M', '6点'), + (0x335F, 'M', '7点'), + (0x3360, 'M', '8点'), + (0x3361, 'M', '9点'), + (0x3362, 'M', '10点'), + (0x3363, 'M', '11点'), + (0x3364, 'M', '12点'), + (0x3365, 'M', '13点'), + (0x3366, 'M', '14点'), + (0x3367, 'M', '15点'), + (0x3368, 'M', '16点'), + (0x3369, 'M', '17点'), + (0x336A, 'M', '18点'), + (0x336B, 'M', '19点'), + (0x336C, 'M', '20点'), + (0x336D, 'M', '21点'), + (0x336E, 'M', '22点'), + (0x336F, 'M', '23点'), + (0x3370, 'M', '24点'), + (0x3371, 'M', 'hpa'), + (0x3372, 'M', 'da'), + (0x3373, 'M', 'au'), + (0x3374, 'M', 'bar'), + (0x3375, 'M', 'ov'), + (0x3376, 'M', 'pc'), + (0x3377, 'M', 'dm'), + (0x3378, 'M', 'dm2'), + (0x3379, 'M', 'dm3'), + ] + +def _seg_34() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x337A, 'M', 'iu'), + (0x337B, 'M', '平成'), + (0x337C, 'M', '昭和'), + (0x337D, 'M', '大正'), + (0x337E, 'M', '明治'), + (0x337F, 'M', '株式会社'), + (0x3380, 'M', 'pa'), + (0x3381, 'M', 'na'), + (0x3382, 'M', 'μa'), + (0x3383, 'M', 'ma'), + (0x3384, 'M', 'ka'), + (0x3385, 'M', 'kb'), + (0x3386, 'M', 'mb'), + (0x3387, 'M', 'gb'), + (0x3388, 'M', 'cal'), + (0x3389, 'M', 'kcal'), + (0x338A, 'M', 'pf'), + (0x338B, 'M', 'nf'), + (0x338C, 'M', 'μf'), + (0x338D, 'M', 'μg'), + (0x338E, 'M', 'mg'), + (0x338F, 'M', 'kg'), + (0x3390, 'M', 'hz'), + (0x3391, 'M', 'khz'), + (0x3392, 'M', 'mhz'), + (0x3393, 'M', 'ghz'), + (0x3394, 'M', 'thz'), + (0x3395, 'M', 'μl'), + (0x3396, 'M', 'ml'), + (0x3397, 'M', 'dl'), + (0x3398, 'M', 'kl'), + (0x3399, 'M', 'fm'), + (0x339A, 'M', 'nm'), + (0x339B, 'M', 'μm'), + (0x339C, 'M', 'mm'), + (0x339D, 'M', 'cm'), + (0x339E, 'M', 'km'), + (0x339F, 'M', 'mm2'), + (0x33A0, 'M', 'cm2'), + (0x33A1, 'M', 'm2'), + (0x33A2, 'M', 'km2'), + (0x33A3, 'M', 'mm3'), + (0x33A4, 'M', 'cm3'), + (0x33A5, 'M', 'm3'), + (0x33A6, 'M', 'km3'), + (0x33A7, 'M', 'm∕s'), + (0x33A8, 'M', 'm∕s2'), + (0x33A9, 'M', 'pa'), + (0x33AA, 'M', 'kpa'), + (0x33AB, 'M', 'mpa'), + (0x33AC, 'M', 'gpa'), + (0x33AD, 'M', 'rad'), + (0x33AE, 'M', 'rad∕s'), + (0x33AF, 'M', 'rad∕s2'), + (0x33B0, 'M', 'ps'), + (0x33B1, 'M', 'ns'), + (0x33B2, 'M', 'μs'), + (0x33B3, 'M', 'ms'), + (0x33B4, 'M', 'pv'), + (0x33B5, 'M', 'nv'), + (0x33B6, 'M', 'μv'), + (0x33B7, 'M', 'mv'), + (0x33B8, 'M', 'kv'), + (0x33B9, 'M', 'mv'), + (0x33BA, 'M', 'pw'), + (0x33BB, 'M', 'nw'), + (0x33BC, 'M', 'μw'), + (0x33BD, 'M', 'mw'), + (0x33BE, 'M', 'kw'), + (0x33BF, 'M', 'mw'), + (0x33C0, 'M', 'kω'), + (0x33C1, 'M', 'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', 'bq'), + (0x33C4, 'M', 'cc'), + (0x33C5, 'M', 'cd'), + (0x33C6, 'M', 'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', 'db'), + (0x33C9, 'M', 'gy'), + (0x33CA, 'M', 'ha'), + (0x33CB, 'M', 'hp'), + (0x33CC, 'M', 'in'), + (0x33CD, 'M', 'kk'), + (0x33CE, 'M', 'km'), + (0x33CF, 'M', 'kt'), + (0x33D0, 'M', 'lm'), + (0x33D1, 'M', 'ln'), + (0x33D2, 'M', 'log'), + (0x33D3, 'M', 'lx'), + (0x33D4, 'M', 'mb'), + (0x33D5, 'M', 'mil'), + (0x33D6, 'M', 'mol'), + (0x33D7, 'M', 'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', 'ppm'), + (0x33DA, 'M', 'pr'), + (0x33DB, 'M', 'sr'), + (0x33DC, 'M', 'sv'), + (0x33DD, 'M', 'wb'), + ] + +def _seg_35() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x33DE, 'M', 'v∕m'), + (0x33DF, 'M', 'a∕m'), + (0x33E0, 'M', '1日'), + (0x33E1, 'M', '2日'), + (0x33E2, 'M', '3日'), + (0x33E3, 'M', '4日'), + (0x33E4, 'M', '5日'), + (0x33E5, 'M', '6日'), + (0x33E6, 'M', '7日'), + (0x33E7, 'M', '8日'), + (0x33E8, 'M', '9日'), + (0x33E9, 'M', '10日'), + (0x33EA, 'M', '11日'), + (0x33EB, 'M', '12日'), + (0x33EC, 'M', '13日'), + (0x33ED, 'M', '14日'), + (0x33EE, 'M', '15日'), + (0x33EF, 'M', '16日'), + (0x33F0, 'M', '17日'), + (0x33F1, 'M', '18日'), + (0x33F2, 'M', '19日'), + (0x33F3, 'M', '20日'), + (0x33F4, 'M', '21日'), + (0x33F5, 'M', '22日'), + (0x33F6, 'M', '23日'), + (0x33F7, 'M', '24日'), + (0x33F8, 'M', '25日'), + (0x33F9, 'M', '26日'), + (0x33FA, 'M', '27日'), + (0x33FB, 'M', '28日'), + (0x33FC, 'M', '29日'), + (0x33FD, 'M', '30日'), + (0x33FE, 'M', '31日'), + (0x33FF, 'M', 'gal'), + (0x3400, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', 'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', 'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', 'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', 'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', 'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', 'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', 'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', 'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', 'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', 'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', 'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', 'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', 'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', 'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', 'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', 'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', 'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', 'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', 'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', 'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', 'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', 'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', 'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', 'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', 'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', 'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', 'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', 'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', 'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', 'ꚍ'), + (0xA68D, 'V'), + ] + +def _seg_36() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA68E, 'M', 'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', 'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', 'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', 'ꚕ'), + (0xA695, 'V'), + (0xA696, 'M', 'ꚗ'), + (0xA697, 'V'), + (0xA698, 'M', 'ꚙ'), + (0xA699, 'V'), + (0xA69A, 'M', 'ꚛ'), + (0xA69B, 'V'), + (0xA69C, 'M', 'ъ'), + (0xA69D, 'M', 'ь'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', 'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', 'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', 'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', 'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', 'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', 'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', 'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', 'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', 'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', 'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', 'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', 'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', 'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', 'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', 'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', 'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', 'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', 'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', 'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', 'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', 'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', 'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', 'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', 'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', 'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', 'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', 'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', 'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', 'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', 'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', 'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', 'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', 'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', 'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', 'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', 'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', 'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', 'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', 'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', 'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', 'ꝼ'), + ] + +def _seg_37() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA77C, 'V'), + (0xA77D, 'M', 'ᵹ'), + (0xA77E, 'M', 'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', 'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', 'ꞃ'), + (0xA783, 'V'), + (0xA784, 'M', 'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', 'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', 'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', 'ɥ'), + (0xA78E, 'V'), + (0xA790, 'M', 'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', 'ꞓ'), + (0xA793, 'V'), + (0xA796, 'M', 'ꞗ'), + (0xA797, 'V'), + (0xA798, 'M', 'ꞙ'), + (0xA799, 'V'), + (0xA79A, 'M', 'ꞛ'), + (0xA79B, 'V'), + (0xA79C, 'M', 'ꞝ'), + (0xA79D, 'V'), + (0xA79E, 'M', 'ꞟ'), + (0xA79F, 'V'), + (0xA7A0, 'M', 'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', 'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', 'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', 'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', 'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', 'ɦ'), + (0xA7AB, 'M', 'ɜ'), + (0xA7AC, 'M', 'ɡ'), + (0xA7AD, 'M', 'ɬ'), + (0xA7AE, 'M', 'ɪ'), + (0xA7AF, 'V'), + (0xA7B0, 'M', 'ʞ'), + (0xA7B1, 'M', 'ʇ'), + (0xA7B2, 'M', 'ʝ'), + (0xA7B3, 'M', 'ꭓ'), + (0xA7B4, 'M', 'ꞵ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', 'ꞷ'), + (0xA7B7, 'V'), + (0xA7B8, 'M', 'ꞹ'), + (0xA7B9, 'V'), + (0xA7BA, 'M', 'ꞻ'), + (0xA7BB, 'V'), + (0xA7BC, 'M', 'ꞽ'), + (0xA7BD, 'V'), + (0xA7BE, 'M', 'ꞿ'), + (0xA7BF, 'V'), + (0xA7C0, 'M', 'ꟁ'), + (0xA7C1, 'V'), + (0xA7C2, 'M', 'ꟃ'), + (0xA7C3, 'V'), + (0xA7C4, 'M', 'ꞔ'), + (0xA7C5, 'M', 'ʂ'), + (0xA7C6, 'M', 'ᶎ'), + (0xA7C7, 'M', 'ꟈ'), + (0xA7C8, 'V'), + (0xA7C9, 'M', 'ꟊ'), + (0xA7CA, 'V'), + (0xA7CB, 'X'), + (0xA7D0, 'M', 'ꟑ'), + (0xA7D1, 'V'), + (0xA7D2, 'X'), + (0xA7D3, 'V'), + (0xA7D4, 'X'), + (0xA7D5, 'V'), + (0xA7D6, 'M', 'ꟗ'), + (0xA7D7, 'V'), + (0xA7D8, 'M', 'ꟙ'), + (0xA7D9, 'V'), + (0xA7DA, 'X'), + (0xA7F2, 'M', 'c'), + (0xA7F3, 'M', 'f'), + (0xA7F4, 'M', 'q'), + (0xA7F5, 'M', 'ꟶ'), + (0xA7F6, 'V'), + (0xA7F8, 'M', 'ħ'), + (0xA7F9, 'M', 'œ'), + (0xA7FA, 'V'), + (0xA82D, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + ] + +def _seg_38() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9FF, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xAB30, 'V'), + (0xAB5C, 'M', 'ꜧ'), + (0xAB5D, 'M', 'ꬷ'), + (0xAB5E, 'M', 'ɫ'), + (0xAB5F, 'M', 'ꭒ'), + (0xAB60, 'V'), + (0xAB69, 'M', 'ʍ'), + (0xAB6A, 'V'), + (0xAB6C, 'X'), + (0xAB70, 'M', 'Ꭰ'), + (0xAB71, 'M', 'Ꭱ'), + (0xAB72, 'M', 'Ꭲ'), + (0xAB73, 'M', 'Ꭳ'), + (0xAB74, 'M', 'Ꭴ'), + (0xAB75, 'M', 'Ꭵ'), + (0xAB76, 'M', 'Ꭶ'), + (0xAB77, 'M', 'Ꭷ'), + (0xAB78, 'M', 'Ꭸ'), + (0xAB79, 'M', 'Ꭹ'), + (0xAB7A, 'M', 'Ꭺ'), + (0xAB7B, 'M', 'Ꭻ'), + (0xAB7C, 'M', 'Ꭼ'), + (0xAB7D, 'M', 'Ꭽ'), + (0xAB7E, 'M', 'Ꭾ'), + (0xAB7F, 'M', 'Ꭿ'), + (0xAB80, 'M', 'Ꮀ'), + (0xAB81, 'M', 'Ꮁ'), + (0xAB82, 'M', 'Ꮂ'), + (0xAB83, 'M', 'Ꮃ'), + (0xAB84, 'M', 'Ꮄ'), + (0xAB85, 'M', 'Ꮅ'), + (0xAB86, 'M', 'Ꮆ'), + (0xAB87, 'M', 'Ꮇ'), + (0xAB88, 'M', 'Ꮈ'), + (0xAB89, 'M', 'Ꮉ'), + (0xAB8A, 'M', 'Ꮊ'), + (0xAB8B, 'M', 'Ꮋ'), + (0xAB8C, 'M', 'Ꮌ'), + (0xAB8D, 'M', 'Ꮍ'), + (0xAB8E, 'M', 'Ꮎ'), + (0xAB8F, 'M', 'Ꮏ'), + (0xAB90, 'M', 'Ꮐ'), + (0xAB91, 'M', 'Ꮑ'), + (0xAB92, 'M', 'Ꮒ'), + (0xAB93, 'M', 'Ꮓ'), + (0xAB94, 'M', 'Ꮔ'), + (0xAB95, 'M', 'Ꮕ'), + (0xAB96, 'M', 'Ꮖ'), + (0xAB97, 'M', 'Ꮗ'), + (0xAB98, 'M', 'Ꮘ'), + (0xAB99, 'M', 'Ꮙ'), + (0xAB9A, 'M', 'Ꮚ'), + (0xAB9B, 'M', 'Ꮛ'), + (0xAB9C, 'M', 'Ꮜ'), + (0xAB9D, 'M', 'Ꮝ'), + (0xAB9E, 'M', 'Ꮞ'), + (0xAB9F, 'M', 'Ꮟ'), + (0xABA0, 'M', 'Ꮠ'), + (0xABA1, 'M', 'Ꮡ'), + (0xABA2, 'M', 'Ꮢ'), + (0xABA3, 'M', 'Ꮣ'), + (0xABA4, 'M', 'Ꮤ'), + (0xABA5, 'M', 'Ꮥ'), + (0xABA6, 'M', 'Ꮦ'), + (0xABA7, 'M', 'Ꮧ'), + (0xABA8, 'M', 'Ꮨ'), + (0xABA9, 'M', 'Ꮩ'), + (0xABAA, 'M', 'Ꮪ'), + ] + +def _seg_39() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xABAB, 'M', 'Ꮫ'), + (0xABAC, 'M', 'Ꮬ'), + (0xABAD, 'M', 'Ꮭ'), + (0xABAE, 'M', 'Ꮮ'), + (0xABAF, 'M', 'Ꮯ'), + (0xABB0, 'M', 'Ꮰ'), + (0xABB1, 'M', 'Ꮱ'), + (0xABB2, 'M', 'Ꮲ'), + (0xABB3, 'M', 'Ꮳ'), + (0xABB4, 'M', 'Ꮴ'), + (0xABB5, 'M', 'Ꮵ'), + (0xABB6, 'M', 'Ꮶ'), + (0xABB7, 'M', 'Ꮷ'), + (0xABB8, 'M', 'Ꮸ'), + (0xABB9, 'M', 'Ꮹ'), + (0xABBA, 'M', 'Ꮺ'), + (0xABBB, 'M', 'Ꮻ'), + (0xABBC, 'M', 'Ꮼ'), + (0xABBD, 'M', 'Ꮽ'), + (0xABBE, 'M', 'Ꮾ'), + (0xABBF, 'M', 'Ꮿ'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', '豈'), + (0xF901, 'M', '更'), + (0xF902, 'M', '車'), + (0xF903, 'M', '賈'), + (0xF904, 'M', '滑'), + (0xF905, 'M', '串'), + (0xF906, 'M', '句'), + (0xF907, 'M', '龜'), + (0xF909, 'M', '契'), + (0xF90A, 'M', '金'), + (0xF90B, 'M', '喇'), + (0xF90C, 'M', '奈'), + (0xF90D, 'M', '懶'), + (0xF90E, 'M', '癩'), + (0xF90F, 'M', '羅'), + (0xF910, 'M', '蘿'), + (0xF911, 'M', '螺'), + (0xF912, 'M', '裸'), + (0xF913, 'M', '邏'), + (0xF914, 'M', '樂'), + (0xF915, 'M', '洛'), + (0xF916, 'M', '烙'), + (0xF917, 'M', '珞'), + (0xF918, 'M', '落'), + (0xF919, 'M', '酪'), + (0xF91A, 'M', '駱'), + (0xF91B, 'M', '亂'), + (0xF91C, 'M', '卵'), + (0xF91D, 'M', '欄'), + (0xF91E, 'M', '爛'), + (0xF91F, 'M', '蘭'), + (0xF920, 'M', '鸞'), + (0xF921, 'M', '嵐'), + (0xF922, 'M', '濫'), + (0xF923, 'M', '藍'), + (0xF924, 'M', '襤'), + (0xF925, 'M', '拉'), + (0xF926, 'M', '臘'), + (0xF927, 'M', '蠟'), + (0xF928, 'M', '廊'), + (0xF929, 'M', '朗'), + (0xF92A, 'M', '浪'), + (0xF92B, 'M', '狼'), + (0xF92C, 'M', '郎'), + (0xF92D, 'M', '來'), + (0xF92E, 'M', '冷'), + (0xF92F, 'M', '勞'), + (0xF930, 'M', '擄'), + (0xF931, 'M', '櫓'), + (0xF932, 'M', '爐'), + (0xF933, 'M', '盧'), + (0xF934, 'M', '老'), + (0xF935, 'M', '蘆'), + (0xF936, 'M', '虜'), + (0xF937, 'M', '路'), + (0xF938, 'M', '露'), + (0xF939, 'M', '魯'), + (0xF93A, 'M', '鷺'), + (0xF93B, 'M', '碌'), + (0xF93C, 'M', '祿'), + (0xF93D, 'M', '綠'), + (0xF93E, 'M', '菉'), + (0xF93F, 'M', '錄'), + (0xF940, 'M', '鹿'), + (0xF941, 'M', '論'), + (0xF942, 'M', '壟'), + (0xF943, 'M', '弄'), + (0xF944, 'M', '籠'), + (0xF945, 'M', '聾'), + ] + +def _seg_40() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF946, 'M', '牢'), + (0xF947, 'M', '磊'), + (0xF948, 'M', '賂'), + (0xF949, 'M', '雷'), + (0xF94A, 'M', '壘'), + (0xF94B, 'M', '屢'), + (0xF94C, 'M', '樓'), + (0xF94D, 'M', '淚'), + (0xF94E, 'M', '漏'), + (0xF94F, 'M', '累'), + (0xF950, 'M', '縷'), + (0xF951, 'M', '陋'), + (0xF952, 'M', '勒'), + (0xF953, 'M', '肋'), + (0xF954, 'M', '凜'), + (0xF955, 'M', '凌'), + (0xF956, 'M', '稜'), + (0xF957, 'M', '綾'), + (0xF958, 'M', '菱'), + (0xF959, 'M', '陵'), + (0xF95A, 'M', '讀'), + (0xF95B, 'M', '拏'), + (0xF95C, 'M', '樂'), + (0xF95D, 'M', '諾'), + (0xF95E, 'M', '丹'), + (0xF95F, 'M', '寧'), + (0xF960, 'M', '怒'), + (0xF961, 'M', '率'), + (0xF962, 'M', '異'), + (0xF963, 'M', '北'), + (0xF964, 'M', '磻'), + (0xF965, 'M', '便'), + (0xF966, 'M', '復'), + (0xF967, 'M', '不'), + (0xF968, 'M', '泌'), + (0xF969, 'M', '數'), + (0xF96A, 'M', '索'), + (0xF96B, 'M', '參'), + (0xF96C, 'M', '塞'), + (0xF96D, 'M', '省'), + (0xF96E, 'M', '葉'), + (0xF96F, 'M', '說'), + (0xF970, 'M', '殺'), + (0xF971, 'M', '辰'), + (0xF972, 'M', '沈'), + (0xF973, 'M', '拾'), + (0xF974, 'M', '若'), + (0xF975, 'M', '掠'), + (0xF976, 'M', '略'), + (0xF977, 'M', '亮'), + (0xF978, 'M', '兩'), + (0xF979, 'M', '凉'), + (0xF97A, 'M', '梁'), + (0xF97B, 'M', '糧'), + (0xF97C, 'M', '良'), + (0xF97D, 'M', '諒'), + (0xF97E, 'M', '量'), + (0xF97F, 'M', '勵'), + (0xF980, 'M', '呂'), + (0xF981, 'M', '女'), + (0xF982, 'M', '廬'), + (0xF983, 'M', '旅'), + (0xF984, 'M', '濾'), + (0xF985, 'M', '礪'), + (0xF986, 'M', '閭'), + (0xF987, 'M', '驪'), + (0xF988, 'M', '麗'), + (0xF989, 'M', '黎'), + (0xF98A, 'M', '力'), + (0xF98B, 'M', '曆'), + (0xF98C, 'M', '歷'), + (0xF98D, 'M', '轢'), + (0xF98E, 'M', '年'), + (0xF98F, 'M', '憐'), + (0xF990, 'M', '戀'), + (0xF991, 'M', '撚'), + (0xF992, 'M', '漣'), + (0xF993, 'M', '煉'), + (0xF994, 'M', '璉'), + (0xF995, 'M', '秊'), + (0xF996, 'M', '練'), + (0xF997, 'M', '聯'), + (0xF998, 'M', '輦'), + (0xF999, 'M', '蓮'), + (0xF99A, 'M', '連'), + (0xF99B, 'M', '鍊'), + (0xF99C, 'M', '列'), + (0xF99D, 'M', '劣'), + (0xF99E, 'M', '咽'), + (0xF99F, 'M', '烈'), + (0xF9A0, 'M', '裂'), + (0xF9A1, 'M', '說'), + (0xF9A2, 'M', '廉'), + (0xF9A3, 'M', '念'), + (0xF9A4, 'M', '捻'), + (0xF9A5, 'M', '殮'), + (0xF9A6, 'M', '簾'), + (0xF9A7, 'M', '獵'), + (0xF9A8, 'M', '令'), + (0xF9A9, 'M', '囹'), + ] + +def _seg_41() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF9AA, 'M', '寧'), + (0xF9AB, 'M', '嶺'), + (0xF9AC, 'M', '怜'), + (0xF9AD, 'M', '玲'), + (0xF9AE, 'M', '瑩'), + (0xF9AF, 'M', '羚'), + (0xF9B0, 'M', '聆'), + (0xF9B1, 'M', '鈴'), + (0xF9B2, 'M', '零'), + (0xF9B3, 'M', '靈'), + (0xF9B4, 'M', '領'), + (0xF9B5, 'M', '例'), + (0xF9B6, 'M', '禮'), + (0xF9B7, 'M', '醴'), + (0xF9B8, 'M', '隸'), + (0xF9B9, 'M', '惡'), + (0xF9BA, 'M', '了'), + (0xF9BB, 'M', '僚'), + (0xF9BC, 'M', '寮'), + (0xF9BD, 'M', '尿'), + (0xF9BE, 'M', '料'), + (0xF9BF, 'M', '樂'), + (0xF9C0, 'M', '燎'), + (0xF9C1, 'M', '療'), + (0xF9C2, 'M', '蓼'), + (0xF9C3, 'M', '遼'), + (0xF9C4, 'M', '龍'), + (0xF9C5, 'M', '暈'), + (0xF9C6, 'M', '阮'), + (0xF9C7, 'M', '劉'), + (0xF9C8, 'M', '杻'), + (0xF9C9, 'M', '柳'), + (0xF9CA, 'M', '流'), + (0xF9CB, 'M', '溜'), + (0xF9CC, 'M', '琉'), + (0xF9CD, 'M', '留'), + (0xF9CE, 'M', '硫'), + (0xF9CF, 'M', '紐'), + (0xF9D0, 'M', '類'), + (0xF9D1, 'M', '六'), + (0xF9D2, 'M', '戮'), + (0xF9D3, 'M', '陸'), + (0xF9D4, 'M', '倫'), + (0xF9D5, 'M', '崙'), + (0xF9D6, 'M', '淪'), + (0xF9D7, 'M', '輪'), + (0xF9D8, 'M', '律'), + (0xF9D9, 'M', '慄'), + (0xF9DA, 'M', '栗'), + (0xF9DB, 'M', '率'), + (0xF9DC, 'M', '隆'), + (0xF9DD, 'M', '利'), + (0xF9DE, 'M', '吏'), + (0xF9DF, 'M', '履'), + (0xF9E0, 'M', '易'), + (0xF9E1, 'M', '李'), + (0xF9E2, 'M', '梨'), + (0xF9E3, 'M', '泥'), + (0xF9E4, 'M', '理'), + (0xF9E5, 'M', '痢'), + (0xF9E6, 'M', '罹'), + (0xF9E7, 'M', '裏'), + (0xF9E8, 'M', '裡'), + (0xF9E9, 'M', '里'), + (0xF9EA, 'M', '離'), + (0xF9EB, 'M', '匿'), + (0xF9EC, 'M', '溺'), + (0xF9ED, 'M', '吝'), + (0xF9EE, 'M', '燐'), + (0xF9EF, 'M', '璘'), + (0xF9F0, 'M', '藺'), + (0xF9F1, 'M', '隣'), + (0xF9F2, 'M', '鱗'), + (0xF9F3, 'M', '麟'), + (0xF9F4, 'M', '林'), + (0xF9F5, 'M', '淋'), + (0xF9F6, 'M', '臨'), + (0xF9F7, 'M', '立'), + (0xF9F8, 'M', '笠'), + (0xF9F9, 'M', '粒'), + (0xF9FA, 'M', '狀'), + (0xF9FB, 'M', '炙'), + (0xF9FC, 'M', '識'), + (0xF9FD, 'M', '什'), + (0xF9FE, 'M', '茶'), + (0xF9FF, 'M', '刺'), + (0xFA00, 'M', '切'), + (0xFA01, 'M', '度'), + (0xFA02, 'M', '拓'), + (0xFA03, 'M', '糖'), + (0xFA04, 'M', '宅'), + (0xFA05, 'M', '洞'), + (0xFA06, 'M', '暴'), + (0xFA07, 'M', '輻'), + (0xFA08, 'M', '行'), + (0xFA09, 'M', '降'), + (0xFA0A, 'M', '見'), + (0xFA0B, 'M', '廓'), + (0xFA0C, 'M', '兀'), + (0xFA0D, 'M', '嗀'), + ] + +def _seg_42() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA0E, 'V'), + (0xFA10, 'M', '塚'), + (0xFA11, 'V'), + (0xFA12, 'M', '晴'), + (0xFA13, 'V'), + (0xFA15, 'M', '凞'), + (0xFA16, 'M', '猪'), + (0xFA17, 'M', '益'), + (0xFA18, 'M', '礼'), + (0xFA19, 'M', '神'), + (0xFA1A, 'M', '祥'), + (0xFA1B, 'M', '福'), + (0xFA1C, 'M', '靖'), + (0xFA1D, 'M', '精'), + (0xFA1E, 'M', '羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', '蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', '諸'), + (0xFA23, 'V'), + (0xFA25, 'M', '逸'), + (0xFA26, 'M', '都'), + (0xFA27, 'V'), + (0xFA2A, 'M', '飯'), + (0xFA2B, 'M', '飼'), + (0xFA2C, 'M', '館'), + (0xFA2D, 'M', '鶴'), + (0xFA2E, 'M', '郞'), + (0xFA2F, 'M', '隷'), + (0xFA30, 'M', '侮'), + (0xFA31, 'M', '僧'), + (0xFA32, 'M', '免'), + (0xFA33, 'M', '勉'), + (0xFA34, 'M', '勤'), + (0xFA35, 'M', '卑'), + (0xFA36, 'M', '喝'), + (0xFA37, 'M', '嘆'), + (0xFA38, 'M', '器'), + (0xFA39, 'M', '塀'), + (0xFA3A, 'M', '墨'), + (0xFA3B, 'M', '層'), + (0xFA3C, 'M', '屮'), + (0xFA3D, 'M', '悔'), + (0xFA3E, 'M', '慨'), + (0xFA3F, 'M', '憎'), + (0xFA40, 'M', '懲'), + (0xFA41, 'M', '敏'), + (0xFA42, 'M', '既'), + (0xFA43, 'M', '暑'), + (0xFA44, 'M', '梅'), + (0xFA45, 'M', '海'), + (0xFA46, 'M', '渚'), + (0xFA47, 'M', '漢'), + (0xFA48, 'M', '煮'), + (0xFA49, 'M', '爫'), + (0xFA4A, 'M', '琢'), + (0xFA4B, 'M', '碑'), + (0xFA4C, 'M', '社'), + (0xFA4D, 'M', '祉'), + (0xFA4E, 'M', '祈'), + (0xFA4F, 'M', '祐'), + (0xFA50, 'M', '祖'), + (0xFA51, 'M', '祝'), + (0xFA52, 'M', '禍'), + (0xFA53, 'M', '禎'), + (0xFA54, 'M', '穀'), + (0xFA55, 'M', '突'), + (0xFA56, 'M', '節'), + (0xFA57, 'M', '練'), + (0xFA58, 'M', '縉'), + (0xFA59, 'M', '繁'), + (0xFA5A, 'M', '署'), + (0xFA5B, 'M', '者'), + (0xFA5C, 'M', '臭'), + (0xFA5D, 'M', '艹'), + (0xFA5F, 'M', '著'), + (0xFA60, 'M', '褐'), + (0xFA61, 'M', '視'), + (0xFA62, 'M', '謁'), + (0xFA63, 'M', '謹'), + (0xFA64, 'M', '賓'), + (0xFA65, 'M', '贈'), + (0xFA66, 'M', '辶'), + (0xFA67, 'M', '逸'), + (0xFA68, 'M', '難'), + (0xFA69, 'M', '響'), + (0xFA6A, 'M', '頻'), + (0xFA6B, 'M', '恵'), + (0xFA6C, 'M', '𤋮'), + (0xFA6D, 'M', '舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', '並'), + (0xFA71, 'M', '况'), + (0xFA72, 'M', '全'), + (0xFA73, 'M', '侀'), + (0xFA74, 'M', '充'), + (0xFA75, 'M', '冀'), + (0xFA76, 'M', '勇'), + (0xFA77, 'M', '勺'), + (0xFA78, 'M', '喝'), + ] + +def _seg_43() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA79, 'M', '啕'), + (0xFA7A, 'M', '喙'), + (0xFA7B, 'M', '嗢'), + (0xFA7C, 'M', '塚'), + (0xFA7D, 'M', '墳'), + (0xFA7E, 'M', '奄'), + (0xFA7F, 'M', '奔'), + (0xFA80, 'M', '婢'), + (0xFA81, 'M', '嬨'), + (0xFA82, 'M', '廒'), + (0xFA83, 'M', '廙'), + (0xFA84, 'M', '彩'), + (0xFA85, 'M', '徭'), + (0xFA86, 'M', '惘'), + (0xFA87, 'M', '慎'), + (0xFA88, 'M', '愈'), + (0xFA89, 'M', '憎'), + (0xFA8A, 'M', '慠'), + (0xFA8B, 'M', '懲'), + (0xFA8C, 'M', '戴'), + (0xFA8D, 'M', '揄'), + (0xFA8E, 'M', '搜'), + (0xFA8F, 'M', '摒'), + (0xFA90, 'M', '敖'), + (0xFA91, 'M', '晴'), + (0xFA92, 'M', '朗'), + (0xFA93, 'M', '望'), + (0xFA94, 'M', '杖'), + (0xFA95, 'M', '歹'), + (0xFA96, 'M', '殺'), + (0xFA97, 'M', '流'), + (0xFA98, 'M', '滛'), + (0xFA99, 'M', '滋'), + (0xFA9A, 'M', '漢'), + (0xFA9B, 'M', '瀞'), + (0xFA9C, 'M', '煮'), + (0xFA9D, 'M', '瞧'), + (0xFA9E, 'M', '爵'), + (0xFA9F, 'M', '犯'), + (0xFAA0, 'M', '猪'), + (0xFAA1, 'M', '瑱'), + (0xFAA2, 'M', '甆'), + (0xFAA3, 'M', '画'), + (0xFAA4, 'M', '瘝'), + (0xFAA5, 'M', '瘟'), + (0xFAA6, 'M', '益'), + (0xFAA7, 'M', '盛'), + (0xFAA8, 'M', '直'), + (0xFAA9, 'M', '睊'), + (0xFAAA, 'M', '着'), + (0xFAAB, 'M', '磌'), + (0xFAAC, 'M', '窱'), + (0xFAAD, 'M', '節'), + (0xFAAE, 'M', '类'), + (0xFAAF, 'M', '絛'), + (0xFAB0, 'M', '練'), + (0xFAB1, 'M', '缾'), + (0xFAB2, 'M', '者'), + (0xFAB3, 'M', '荒'), + (0xFAB4, 'M', '華'), + (0xFAB5, 'M', '蝹'), + (0xFAB6, 'M', '襁'), + (0xFAB7, 'M', '覆'), + (0xFAB8, 'M', '視'), + (0xFAB9, 'M', '調'), + (0xFABA, 'M', '諸'), + (0xFABB, 'M', '請'), + (0xFABC, 'M', '謁'), + (0xFABD, 'M', '諾'), + (0xFABE, 'M', '諭'), + (0xFABF, 'M', '謹'), + (0xFAC0, 'M', '變'), + (0xFAC1, 'M', '贈'), + (0xFAC2, 'M', '輸'), + (0xFAC3, 'M', '遲'), + (0xFAC4, 'M', '醙'), + (0xFAC5, 'M', '鉶'), + (0xFAC6, 'M', '陼'), + (0xFAC7, 'M', '難'), + (0xFAC8, 'M', '靖'), + (0xFAC9, 'M', '韛'), + (0xFACA, 'M', '響'), + (0xFACB, 'M', '頋'), + (0xFACC, 'M', '頻'), + (0xFACD, 'M', '鬒'), + (0xFACE, 'M', '龜'), + (0xFACF, 'M', '𢡊'), + (0xFAD0, 'M', '𢡄'), + (0xFAD1, 'M', '𣏕'), + (0xFAD2, 'M', '㮝'), + (0xFAD3, 'M', '䀘'), + (0xFAD4, 'M', '䀹'), + (0xFAD5, 'M', '𥉉'), + (0xFAD6, 'M', '𥳐'), + (0xFAD7, 'M', '𧻓'), + (0xFAD8, 'M', '齃'), + (0xFAD9, 'M', '龎'), + (0xFADA, 'X'), + (0xFB00, 'M', 'ff'), + (0xFB01, 'M', 'fi'), + ] + +def _seg_44() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFB02, 'M', 'fl'), + (0xFB03, 'M', 'ffi'), + (0xFB04, 'M', 'ffl'), + (0xFB05, 'M', 'st'), + (0xFB07, 'X'), + (0xFB13, 'M', 'մն'), + (0xFB14, 'M', 'մե'), + (0xFB15, 'M', 'մի'), + (0xFB16, 'M', 'վն'), + (0xFB17, 'M', 'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', 'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', 'ײַ'), + (0xFB20, 'M', 'ע'), + (0xFB21, 'M', 'א'), + (0xFB22, 'M', 'ד'), + (0xFB23, 'M', 'ה'), + (0xFB24, 'M', 'כ'), + (0xFB25, 'M', 'ל'), + (0xFB26, 'M', 'ם'), + (0xFB27, 'M', 'ר'), + (0xFB28, 'M', 'ת'), + (0xFB29, '3', '+'), + (0xFB2A, 'M', 'שׁ'), + (0xFB2B, 'M', 'שׂ'), + (0xFB2C, 'M', 'שּׁ'), + (0xFB2D, 'M', 'שּׂ'), + (0xFB2E, 'M', 'אַ'), + (0xFB2F, 'M', 'אָ'), + (0xFB30, 'M', 'אּ'), + (0xFB31, 'M', 'בּ'), + (0xFB32, 'M', 'גּ'), + (0xFB33, 'M', 'דּ'), + (0xFB34, 'M', 'הּ'), + (0xFB35, 'M', 'וּ'), + (0xFB36, 'M', 'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', 'טּ'), + (0xFB39, 'M', 'יּ'), + (0xFB3A, 'M', 'ךּ'), + (0xFB3B, 'M', 'כּ'), + (0xFB3C, 'M', 'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', 'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', 'נּ'), + (0xFB41, 'M', 'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', 'ףּ'), + (0xFB44, 'M', 'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', 'צּ'), + (0xFB47, 'M', 'קּ'), + (0xFB48, 'M', 'רּ'), + (0xFB49, 'M', 'שּ'), + (0xFB4A, 'M', 'תּ'), + (0xFB4B, 'M', 'וֹ'), + (0xFB4C, 'M', 'בֿ'), + (0xFB4D, 'M', 'כֿ'), + (0xFB4E, 'M', 'פֿ'), + (0xFB4F, 'M', 'אל'), + (0xFB50, 'M', 'ٱ'), + (0xFB52, 'M', 'ٻ'), + (0xFB56, 'M', 'پ'), + (0xFB5A, 'M', 'ڀ'), + (0xFB5E, 'M', 'ٺ'), + (0xFB62, 'M', 'ٿ'), + (0xFB66, 'M', 'ٹ'), + (0xFB6A, 'M', 'ڤ'), + (0xFB6E, 'M', 'ڦ'), + (0xFB72, 'M', 'ڄ'), + (0xFB76, 'M', 'ڃ'), + (0xFB7A, 'M', 'چ'), + (0xFB7E, 'M', 'ڇ'), + (0xFB82, 'M', 'ڍ'), + (0xFB84, 'M', 'ڌ'), + (0xFB86, 'M', 'ڎ'), + (0xFB88, 'M', 'ڈ'), + (0xFB8A, 'M', 'ژ'), + (0xFB8C, 'M', 'ڑ'), + (0xFB8E, 'M', 'ک'), + (0xFB92, 'M', 'گ'), + (0xFB96, 'M', 'ڳ'), + (0xFB9A, 'M', 'ڱ'), + (0xFB9E, 'M', 'ں'), + (0xFBA0, 'M', 'ڻ'), + (0xFBA4, 'M', 'ۀ'), + (0xFBA6, 'M', 'ہ'), + (0xFBAA, 'M', 'ھ'), + (0xFBAE, 'M', 'ے'), + (0xFBB0, 'M', 'ۓ'), + (0xFBB2, 'V'), + (0xFBC3, 'X'), + (0xFBD3, 'M', 'ڭ'), + (0xFBD7, 'M', 'ۇ'), + (0xFBD9, 'M', 'ۆ'), + (0xFBDB, 'M', 'ۈ'), + (0xFBDD, 'M', 'ۇٴ'), + (0xFBDE, 'M', 'ۋ'), + ] + +def _seg_45() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFBE0, 'M', 'ۅ'), + (0xFBE2, 'M', 'ۉ'), + (0xFBE4, 'M', 'ې'), + (0xFBE8, 'M', 'ى'), + (0xFBEA, 'M', 'ئا'), + (0xFBEC, 'M', 'ئە'), + (0xFBEE, 'M', 'ئو'), + (0xFBF0, 'M', 'ئۇ'), + (0xFBF2, 'M', 'ئۆ'), + (0xFBF4, 'M', 'ئۈ'), + (0xFBF6, 'M', 'ئې'), + (0xFBF9, 'M', 'ئى'), + (0xFBFC, 'M', 'ی'), + (0xFC00, 'M', 'ئج'), + (0xFC01, 'M', 'ئح'), + (0xFC02, 'M', 'ئم'), + (0xFC03, 'M', 'ئى'), + (0xFC04, 'M', 'ئي'), + (0xFC05, 'M', 'بج'), + (0xFC06, 'M', 'بح'), + (0xFC07, 'M', 'بخ'), + (0xFC08, 'M', 'بم'), + (0xFC09, 'M', 'بى'), + (0xFC0A, 'M', 'بي'), + (0xFC0B, 'M', 'تج'), + (0xFC0C, 'M', 'تح'), + (0xFC0D, 'M', 'تخ'), + (0xFC0E, 'M', 'تم'), + (0xFC0F, 'M', 'تى'), + (0xFC10, 'M', 'تي'), + (0xFC11, 'M', 'ثج'), + (0xFC12, 'M', 'ثم'), + (0xFC13, 'M', 'ثى'), + (0xFC14, 'M', 'ثي'), + (0xFC15, 'M', 'جح'), + (0xFC16, 'M', 'جم'), + (0xFC17, 'M', 'حج'), + (0xFC18, 'M', 'حم'), + (0xFC19, 'M', 'خج'), + (0xFC1A, 'M', 'خح'), + (0xFC1B, 'M', 'خم'), + (0xFC1C, 'M', 'سج'), + (0xFC1D, 'M', 'سح'), + (0xFC1E, 'M', 'سخ'), + (0xFC1F, 'M', 'سم'), + (0xFC20, 'M', 'صح'), + (0xFC21, 'M', 'صم'), + (0xFC22, 'M', 'ضج'), + (0xFC23, 'M', 'ضح'), + (0xFC24, 'M', 'ضخ'), + (0xFC25, 'M', 'ضم'), + (0xFC26, 'M', 'طح'), + (0xFC27, 'M', 'طم'), + (0xFC28, 'M', 'ظم'), + (0xFC29, 'M', 'عج'), + (0xFC2A, 'M', 'عم'), + (0xFC2B, 'M', 'غج'), + (0xFC2C, 'M', 'غم'), + (0xFC2D, 'M', 'فج'), + (0xFC2E, 'M', 'فح'), + (0xFC2F, 'M', 'فخ'), + (0xFC30, 'M', 'فم'), + (0xFC31, 'M', 'فى'), + (0xFC32, 'M', 'في'), + (0xFC33, 'M', 'قح'), + (0xFC34, 'M', 'قم'), + (0xFC35, 'M', 'قى'), + (0xFC36, 'M', 'قي'), + (0xFC37, 'M', 'كا'), + (0xFC38, 'M', 'كج'), + (0xFC39, 'M', 'كح'), + (0xFC3A, 'M', 'كخ'), + (0xFC3B, 'M', 'كل'), + (0xFC3C, 'M', 'كم'), + (0xFC3D, 'M', 'كى'), + (0xFC3E, 'M', 'كي'), + (0xFC3F, 'M', 'لج'), + (0xFC40, 'M', 'لح'), + (0xFC41, 'M', 'لخ'), + (0xFC42, 'M', 'لم'), + (0xFC43, 'M', 'لى'), + (0xFC44, 'M', 'لي'), + (0xFC45, 'M', 'مج'), + (0xFC46, 'M', 'مح'), + (0xFC47, 'M', 'مخ'), + (0xFC48, 'M', 'مم'), + (0xFC49, 'M', 'مى'), + (0xFC4A, 'M', 'مي'), + (0xFC4B, 'M', 'نج'), + (0xFC4C, 'M', 'نح'), + (0xFC4D, 'M', 'نخ'), + (0xFC4E, 'M', 'نم'), + (0xFC4F, 'M', 'نى'), + (0xFC50, 'M', 'ني'), + (0xFC51, 'M', 'هج'), + (0xFC52, 'M', 'هم'), + (0xFC53, 'M', 'هى'), + (0xFC54, 'M', 'هي'), + (0xFC55, 'M', 'يج'), + (0xFC56, 'M', 'يح'), + ] + +def _seg_46() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFC57, 'M', 'يخ'), + (0xFC58, 'M', 'يم'), + (0xFC59, 'M', 'يى'), + (0xFC5A, 'M', 'يي'), + (0xFC5B, 'M', 'ذٰ'), + (0xFC5C, 'M', 'رٰ'), + (0xFC5D, 'M', 'ىٰ'), + (0xFC5E, '3', ' ٌّ'), + (0xFC5F, '3', ' ٍّ'), + (0xFC60, '3', ' َّ'), + (0xFC61, '3', ' ُّ'), + (0xFC62, '3', ' ِّ'), + (0xFC63, '3', ' ّٰ'), + (0xFC64, 'M', 'ئر'), + (0xFC65, 'M', 'ئز'), + (0xFC66, 'M', 'ئم'), + (0xFC67, 'M', 'ئن'), + (0xFC68, 'M', 'ئى'), + (0xFC69, 'M', 'ئي'), + (0xFC6A, 'M', 'بر'), + (0xFC6B, 'M', 'بز'), + (0xFC6C, 'M', 'بم'), + (0xFC6D, 'M', 'بن'), + (0xFC6E, 'M', 'بى'), + (0xFC6F, 'M', 'بي'), + (0xFC70, 'M', 'تر'), + (0xFC71, 'M', 'تز'), + (0xFC72, 'M', 'تم'), + (0xFC73, 'M', 'تن'), + (0xFC74, 'M', 'تى'), + (0xFC75, 'M', 'تي'), + (0xFC76, 'M', 'ثر'), + (0xFC77, 'M', 'ثز'), + (0xFC78, 'M', 'ثم'), + (0xFC79, 'M', 'ثن'), + (0xFC7A, 'M', 'ثى'), + (0xFC7B, 'M', 'ثي'), + (0xFC7C, 'M', 'فى'), + (0xFC7D, 'M', 'في'), + (0xFC7E, 'M', 'قى'), + (0xFC7F, 'M', 'قي'), + (0xFC80, 'M', 'كا'), + (0xFC81, 'M', 'كل'), + (0xFC82, 'M', 'كم'), + (0xFC83, 'M', 'كى'), + (0xFC84, 'M', 'كي'), + (0xFC85, 'M', 'لم'), + (0xFC86, 'M', 'لى'), + (0xFC87, 'M', 'لي'), + (0xFC88, 'M', 'ما'), + (0xFC89, 'M', 'مم'), + (0xFC8A, 'M', 'نر'), + (0xFC8B, 'M', 'نز'), + (0xFC8C, 'M', 'نم'), + (0xFC8D, 'M', 'نن'), + (0xFC8E, 'M', 'نى'), + (0xFC8F, 'M', 'ني'), + (0xFC90, 'M', 'ىٰ'), + (0xFC91, 'M', 'ير'), + (0xFC92, 'M', 'يز'), + (0xFC93, 'M', 'يم'), + (0xFC94, 'M', 'ين'), + (0xFC95, 'M', 'يى'), + (0xFC96, 'M', 'يي'), + (0xFC97, 'M', 'ئج'), + (0xFC98, 'M', 'ئح'), + (0xFC99, 'M', 'ئخ'), + (0xFC9A, 'M', 'ئم'), + (0xFC9B, 'M', 'ئه'), + (0xFC9C, 'M', 'بج'), + (0xFC9D, 'M', 'بح'), + (0xFC9E, 'M', 'بخ'), + (0xFC9F, 'M', 'بم'), + (0xFCA0, 'M', 'به'), + (0xFCA1, 'M', 'تج'), + (0xFCA2, 'M', 'تح'), + (0xFCA3, 'M', 'تخ'), + (0xFCA4, 'M', 'تم'), + (0xFCA5, 'M', 'ته'), + (0xFCA6, 'M', 'ثم'), + (0xFCA7, 'M', 'جح'), + (0xFCA8, 'M', 'جم'), + (0xFCA9, 'M', 'حج'), + (0xFCAA, 'M', 'حم'), + (0xFCAB, 'M', 'خج'), + (0xFCAC, 'M', 'خم'), + (0xFCAD, 'M', 'سج'), + (0xFCAE, 'M', 'سح'), + (0xFCAF, 'M', 'سخ'), + (0xFCB0, 'M', 'سم'), + (0xFCB1, 'M', 'صح'), + (0xFCB2, 'M', 'صخ'), + (0xFCB3, 'M', 'صم'), + (0xFCB4, 'M', 'ضج'), + (0xFCB5, 'M', 'ضح'), + (0xFCB6, 'M', 'ضخ'), + (0xFCB7, 'M', 'ضم'), + (0xFCB8, 'M', 'طح'), + (0xFCB9, 'M', 'ظم'), + (0xFCBA, 'M', 'عج'), + ] + +def _seg_47() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFCBB, 'M', 'عم'), + (0xFCBC, 'M', 'غج'), + (0xFCBD, 'M', 'غم'), + (0xFCBE, 'M', 'فج'), + (0xFCBF, 'M', 'فح'), + (0xFCC0, 'M', 'فخ'), + (0xFCC1, 'M', 'فم'), + (0xFCC2, 'M', 'قح'), + (0xFCC3, 'M', 'قم'), + (0xFCC4, 'M', 'كج'), + (0xFCC5, 'M', 'كح'), + (0xFCC6, 'M', 'كخ'), + (0xFCC7, 'M', 'كل'), + (0xFCC8, 'M', 'كم'), + (0xFCC9, 'M', 'لج'), + (0xFCCA, 'M', 'لح'), + (0xFCCB, 'M', 'لخ'), + (0xFCCC, 'M', 'لم'), + (0xFCCD, 'M', 'له'), + (0xFCCE, 'M', 'مج'), + (0xFCCF, 'M', 'مح'), + (0xFCD0, 'M', 'مخ'), + (0xFCD1, 'M', 'مم'), + (0xFCD2, 'M', 'نج'), + (0xFCD3, 'M', 'نح'), + (0xFCD4, 'M', 'نخ'), + (0xFCD5, 'M', 'نم'), + (0xFCD6, 'M', 'نه'), + (0xFCD7, 'M', 'هج'), + (0xFCD8, 'M', 'هم'), + (0xFCD9, 'M', 'هٰ'), + (0xFCDA, 'M', 'يج'), + (0xFCDB, 'M', 'يح'), + (0xFCDC, 'M', 'يخ'), + (0xFCDD, 'M', 'يم'), + (0xFCDE, 'M', 'يه'), + (0xFCDF, 'M', 'ئم'), + (0xFCE0, 'M', 'ئه'), + (0xFCE1, 'M', 'بم'), + (0xFCE2, 'M', 'به'), + (0xFCE3, 'M', 'تم'), + (0xFCE4, 'M', 'ته'), + (0xFCE5, 'M', 'ثم'), + (0xFCE6, 'M', 'ثه'), + (0xFCE7, 'M', 'سم'), + (0xFCE8, 'M', 'سه'), + (0xFCE9, 'M', 'شم'), + (0xFCEA, 'M', 'شه'), + (0xFCEB, 'M', 'كل'), + (0xFCEC, 'M', 'كم'), + (0xFCED, 'M', 'لم'), + (0xFCEE, 'M', 'نم'), + (0xFCEF, 'M', 'نه'), + (0xFCF0, 'M', 'يم'), + (0xFCF1, 'M', 'يه'), + (0xFCF2, 'M', 'ـَّ'), + (0xFCF3, 'M', 'ـُّ'), + (0xFCF4, 'M', 'ـِّ'), + (0xFCF5, 'M', 'طى'), + (0xFCF6, 'M', 'طي'), + (0xFCF7, 'M', 'عى'), + (0xFCF8, 'M', 'عي'), + (0xFCF9, 'M', 'غى'), + (0xFCFA, 'M', 'غي'), + (0xFCFB, 'M', 'سى'), + (0xFCFC, 'M', 'سي'), + (0xFCFD, 'M', 'شى'), + (0xFCFE, 'M', 'شي'), + (0xFCFF, 'M', 'حى'), + (0xFD00, 'M', 'حي'), + (0xFD01, 'M', 'جى'), + (0xFD02, 'M', 'جي'), + (0xFD03, 'M', 'خى'), + (0xFD04, 'M', 'خي'), + (0xFD05, 'M', 'صى'), + (0xFD06, 'M', 'صي'), + (0xFD07, 'M', 'ضى'), + (0xFD08, 'M', 'ضي'), + (0xFD09, 'M', 'شج'), + (0xFD0A, 'M', 'شح'), + (0xFD0B, 'M', 'شخ'), + (0xFD0C, 'M', 'شم'), + (0xFD0D, 'M', 'شر'), + (0xFD0E, 'M', 'سر'), + (0xFD0F, 'M', 'صر'), + (0xFD10, 'M', 'ضر'), + (0xFD11, 'M', 'طى'), + (0xFD12, 'M', 'طي'), + (0xFD13, 'M', 'عى'), + (0xFD14, 'M', 'عي'), + (0xFD15, 'M', 'غى'), + (0xFD16, 'M', 'غي'), + (0xFD17, 'M', 'سى'), + (0xFD18, 'M', 'سي'), + (0xFD19, 'M', 'شى'), + (0xFD1A, 'M', 'شي'), + (0xFD1B, 'M', 'حى'), + (0xFD1C, 'M', 'حي'), + (0xFD1D, 'M', 'جى'), + (0xFD1E, 'M', 'جي'), + ] + +def _seg_48() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFD1F, 'M', 'خى'), + (0xFD20, 'M', 'خي'), + (0xFD21, 'M', 'صى'), + (0xFD22, 'M', 'صي'), + (0xFD23, 'M', 'ضى'), + (0xFD24, 'M', 'ضي'), + (0xFD25, 'M', 'شج'), + (0xFD26, 'M', 'شح'), + (0xFD27, 'M', 'شخ'), + (0xFD28, 'M', 'شم'), + (0xFD29, 'M', 'شر'), + (0xFD2A, 'M', 'سر'), + (0xFD2B, 'M', 'صر'), + (0xFD2C, 'M', 'ضر'), + (0xFD2D, 'M', 'شج'), + (0xFD2E, 'M', 'شح'), + (0xFD2F, 'M', 'شخ'), + (0xFD30, 'M', 'شم'), + (0xFD31, 'M', 'سه'), + (0xFD32, 'M', 'شه'), + (0xFD33, 'M', 'طم'), + (0xFD34, 'M', 'سج'), + (0xFD35, 'M', 'سح'), + (0xFD36, 'M', 'سخ'), + (0xFD37, 'M', 'شج'), + (0xFD38, 'M', 'شح'), + (0xFD39, 'M', 'شخ'), + (0xFD3A, 'M', 'طم'), + (0xFD3B, 'M', 'ظم'), + (0xFD3C, 'M', 'اً'), + (0xFD3E, 'V'), + (0xFD50, 'M', 'تجم'), + (0xFD51, 'M', 'تحج'), + (0xFD53, 'M', 'تحم'), + (0xFD54, 'M', 'تخم'), + (0xFD55, 'M', 'تمج'), + (0xFD56, 'M', 'تمح'), + (0xFD57, 'M', 'تمخ'), + (0xFD58, 'M', 'جمح'), + (0xFD5A, 'M', 'حمي'), + (0xFD5B, 'M', 'حمى'), + (0xFD5C, 'M', 'سحج'), + (0xFD5D, 'M', 'سجح'), + (0xFD5E, 'M', 'سجى'), + (0xFD5F, 'M', 'سمح'), + (0xFD61, 'M', 'سمج'), + (0xFD62, 'M', 'سمم'), + (0xFD64, 'M', 'صحح'), + (0xFD66, 'M', 'صمم'), + (0xFD67, 'M', 'شحم'), + (0xFD69, 'M', 'شجي'), + (0xFD6A, 'M', 'شمخ'), + (0xFD6C, 'M', 'شمم'), + (0xFD6E, 'M', 'ضحى'), + (0xFD6F, 'M', 'ضخم'), + (0xFD71, 'M', 'طمح'), + (0xFD73, 'M', 'طمم'), + (0xFD74, 'M', 'طمي'), + (0xFD75, 'M', 'عجم'), + (0xFD76, 'M', 'عمم'), + (0xFD78, 'M', 'عمى'), + (0xFD79, 'M', 'غمم'), + (0xFD7A, 'M', 'غمي'), + (0xFD7B, 'M', 'غمى'), + (0xFD7C, 'M', 'فخم'), + (0xFD7E, 'M', 'قمح'), + (0xFD7F, 'M', 'قمم'), + (0xFD80, 'M', 'لحم'), + (0xFD81, 'M', 'لحي'), + (0xFD82, 'M', 'لحى'), + (0xFD83, 'M', 'لجج'), + (0xFD85, 'M', 'لخم'), + (0xFD87, 'M', 'لمح'), + (0xFD89, 'M', 'محج'), + (0xFD8A, 'M', 'محم'), + (0xFD8B, 'M', 'محي'), + (0xFD8C, 'M', 'مجح'), + (0xFD8D, 'M', 'مجم'), + (0xFD8E, 'M', 'مخج'), + (0xFD8F, 'M', 'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', 'مجخ'), + (0xFD93, 'M', 'همج'), + (0xFD94, 'M', 'همم'), + (0xFD95, 'M', 'نحم'), + (0xFD96, 'M', 'نحى'), + (0xFD97, 'M', 'نجم'), + (0xFD99, 'M', 'نجى'), + (0xFD9A, 'M', 'نمي'), + (0xFD9B, 'M', 'نمى'), + (0xFD9C, 'M', 'يمم'), + (0xFD9E, 'M', 'بخي'), + (0xFD9F, 'M', 'تجي'), + (0xFDA0, 'M', 'تجى'), + (0xFDA1, 'M', 'تخي'), + (0xFDA2, 'M', 'تخى'), + (0xFDA3, 'M', 'تمي'), + (0xFDA4, 'M', 'تمى'), + (0xFDA5, 'M', 'جمي'), + (0xFDA6, 'M', 'جحى'), + ] + +def _seg_49() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFDA7, 'M', 'جمى'), + (0xFDA8, 'M', 'سخى'), + (0xFDA9, 'M', 'صحي'), + (0xFDAA, 'M', 'شحي'), + (0xFDAB, 'M', 'ضحي'), + (0xFDAC, 'M', 'لجي'), + (0xFDAD, 'M', 'لمي'), + (0xFDAE, 'M', 'يحي'), + (0xFDAF, 'M', 'يجي'), + (0xFDB0, 'M', 'يمي'), + (0xFDB1, 'M', 'ممي'), + (0xFDB2, 'M', 'قمي'), + (0xFDB3, 'M', 'نحي'), + (0xFDB4, 'M', 'قمح'), + (0xFDB5, 'M', 'لحم'), + (0xFDB6, 'M', 'عمي'), + (0xFDB7, 'M', 'كمي'), + (0xFDB8, 'M', 'نجح'), + (0xFDB9, 'M', 'مخي'), + (0xFDBA, 'M', 'لجم'), + (0xFDBB, 'M', 'كمم'), + (0xFDBC, 'M', 'لجم'), + (0xFDBD, 'M', 'نجح'), + (0xFDBE, 'M', 'جحي'), + (0xFDBF, 'M', 'حجي'), + (0xFDC0, 'M', 'مجي'), + (0xFDC1, 'M', 'فمي'), + (0xFDC2, 'M', 'بحي'), + (0xFDC3, 'M', 'كمم'), + (0xFDC4, 'M', 'عجم'), + (0xFDC5, 'M', 'صمم'), + (0xFDC6, 'M', 'سخي'), + (0xFDC7, 'M', 'نجي'), + (0xFDC8, 'X'), + (0xFDCF, 'V'), + (0xFDD0, 'X'), + (0xFDF0, 'M', 'صلے'), + (0xFDF1, 'M', 'قلے'), + (0xFDF2, 'M', 'الله'), + (0xFDF3, 'M', 'اكبر'), + (0xFDF4, 'M', 'محمد'), + (0xFDF5, 'M', 'صلعم'), + (0xFDF6, 'M', 'رسول'), + (0xFDF7, 'M', 'عليه'), + (0xFDF8, 'M', 'وسلم'), + (0xFDF9, 'M', 'صلى'), + (0xFDFA, '3', 'صلى الله عليه وسلم'), + (0xFDFB, '3', 'جل جلاله'), + (0xFDFC, 'M', 'ریال'), + (0xFDFD, 'V'), + (0xFE00, 'I'), + (0xFE10, '3', ','), + (0xFE11, 'M', '、'), + (0xFE12, 'X'), + (0xFE13, '3', ':'), + (0xFE14, '3', ';'), + (0xFE15, '3', '!'), + (0xFE16, '3', '?'), + (0xFE17, 'M', '〖'), + (0xFE18, 'M', '〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', '—'), + (0xFE32, 'M', '–'), + (0xFE33, '3', '_'), + (0xFE35, '3', '('), + (0xFE36, '3', ')'), + (0xFE37, '3', '{'), + (0xFE38, '3', '}'), + (0xFE39, 'M', '〔'), + (0xFE3A, 'M', '〕'), + (0xFE3B, 'M', '【'), + (0xFE3C, 'M', '】'), + (0xFE3D, 'M', '《'), + (0xFE3E, 'M', '》'), + (0xFE3F, 'M', '〈'), + (0xFE40, 'M', '〉'), + (0xFE41, 'M', '「'), + (0xFE42, 'M', '」'), + (0xFE43, 'M', '『'), + (0xFE44, 'M', '』'), + (0xFE45, 'V'), + (0xFE47, '3', '['), + (0xFE48, '3', ']'), + (0xFE49, '3', ' ̅'), + (0xFE4D, '3', '_'), + (0xFE50, '3', ','), + (0xFE51, 'M', '、'), + (0xFE52, 'X'), + (0xFE54, '3', ';'), + (0xFE55, '3', ':'), + (0xFE56, '3', '?'), + (0xFE57, '3', '!'), + (0xFE58, 'M', '—'), + (0xFE59, '3', '('), + (0xFE5A, '3', ')'), + (0xFE5B, '3', '{'), + (0xFE5C, '3', '}'), + (0xFE5D, 'M', '〔'), + ] + +def _seg_50() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFE5E, 'M', '〕'), + (0xFE5F, '3', '#'), + (0xFE60, '3', '&'), + (0xFE61, '3', '*'), + (0xFE62, '3', '+'), + (0xFE63, 'M', '-'), + (0xFE64, '3', '<'), + (0xFE65, '3', '>'), + (0xFE66, '3', '='), + (0xFE67, 'X'), + (0xFE68, '3', '\\'), + (0xFE69, '3', '$'), + (0xFE6A, '3', '%'), + (0xFE6B, '3', '@'), + (0xFE6C, 'X'), + (0xFE70, '3', ' ً'), + (0xFE71, 'M', 'ـً'), + (0xFE72, '3', ' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', ' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', ' َ'), + (0xFE77, 'M', 'ـَ'), + (0xFE78, '3', ' ُ'), + (0xFE79, 'M', 'ـُ'), + (0xFE7A, '3', ' ِ'), + (0xFE7B, 'M', 'ـِ'), + (0xFE7C, '3', ' ّ'), + (0xFE7D, 'M', 'ـّ'), + (0xFE7E, '3', ' ْ'), + (0xFE7F, 'M', 'ـْ'), + (0xFE80, 'M', 'ء'), + (0xFE81, 'M', 'آ'), + (0xFE83, 'M', 'أ'), + (0xFE85, 'M', 'ؤ'), + (0xFE87, 'M', 'إ'), + (0xFE89, 'M', 'ئ'), + (0xFE8D, 'M', 'ا'), + (0xFE8F, 'M', 'ب'), + (0xFE93, 'M', 'ة'), + (0xFE95, 'M', 'ت'), + (0xFE99, 'M', 'ث'), + (0xFE9D, 'M', 'ج'), + (0xFEA1, 'M', 'ح'), + (0xFEA5, 'M', 'خ'), + (0xFEA9, 'M', 'د'), + (0xFEAB, 'M', 'ذ'), + (0xFEAD, 'M', 'ر'), + (0xFEAF, 'M', 'ز'), + (0xFEB1, 'M', 'س'), + (0xFEB5, 'M', 'ش'), + (0xFEB9, 'M', 'ص'), + (0xFEBD, 'M', 'ض'), + (0xFEC1, 'M', 'ط'), + (0xFEC5, 'M', 'ظ'), + (0xFEC9, 'M', 'ع'), + (0xFECD, 'M', 'غ'), + (0xFED1, 'M', 'ف'), + (0xFED5, 'M', 'ق'), + (0xFED9, 'M', 'ك'), + (0xFEDD, 'M', 'ل'), + (0xFEE1, 'M', 'م'), + (0xFEE5, 'M', 'ن'), + (0xFEE9, 'M', 'ه'), + (0xFEED, 'M', 'و'), + (0xFEEF, 'M', 'ى'), + (0xFEF1, 'M', 'ي'), + (0xFEF5, 'M', 'لآ'), + (0xFEF7, 'M', 'لأ'), + (0xFEF9, 'M', 'لإ'), + (0xFEFB, 'M', 'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', '!'), + (0xFF02, '3', '"'), + (0xFF03, '3', '#'), + (0xFF04, '3', '$'), + (0xFF05, '3', '%'), + (0xFF06, '3', '&'), + (0xFF07, '3', '\''), + (0xFF08, '3', '('), + (0xFF09, '3', ')'), + (0xFF0A, '3', '*'), + (0xFF0B, '3', '+'), + (0xFF0C, '3', ','), + (0xFF0D, 'M', '-'), + (0xFF0E, 'M', '.'), + (0xFF0F, '3', '/'), + (0xFF10, 'M', '0'), + (0xFF11, 'M', '1'), + (0xFF12, 'M', '2'), + (0xFF13, 'M', '3'), + (0xFF14, 'M', '4'), + (0xFF15, 'M', '5'), + (0xFF16, 'M', '6'), + (0xFF17, 'M', '7'), + (0xFF18, 'M', '8'), + (0xFF19, 'M', '9'), + (0xFF1A, '3', ':'), + ] + +def _seg_51() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF1B, '3', ';'), + (0xFF1C, '3', '<'), + (0xFF1D, '3', '='), + (0xFF1E, '3', '>'), + (0xFF1F, '3', '?'), + (0xFF20, '3', '@'), + (0xFF21, 'M', 'a'), + (0xFF22, 'M', 'b'), + (0xFF23, 'M', 'c'), + (0xFF24, 'M', 'd'), + (0xFF25, 'M', 'e'), + (0xFF26, 'M', 'f'), + (0xFF27, 'M', 'g'), + (0xFF28, 'M', 'h'), + (0xFF29, 'M', 'i'), + (0xFF2A, 'M', 'j'), + (0xFF2B, 'M', 'k'), + (0xFF2C, 'M', 'l'), + (0xFF2D, 'M', 'm'), + (0xFF2E, 'M', 'n'), + (0xFF2F, 'M', 'o'), + (0xFF30, 'M', 'p'), + (0xFF31, 'M', 'q'), + (0xFF32, 'M', 'r'), + (0xFF33, 'M', 's'), + (0xFF34, 'M', 't'), + (0xFF35, 'M', 'u'), + (0xFF36, 'M', 'v'), + (0xFF37, 'M', 'w'), + (0xFF38, 'M', 'x'), + (0xFF39, 'M', 'y'), + (0xFF3A, 'M', 'z'), + (0xFF3B, '3', '['), + (0xFF3C, '3', '\\'), + (0xFF3D, '3', ']'), + (0xFF3E, '3', '^'), + (0xFF3F, '3', '_'), + (0xFF40, '3', '`'), + (0xFF41, 'M', 'a'), + (0xFF42, 'M', 'b'), + (0xFF43, 'M', 'c'), + (0xFF44, 'M', 'd'), + (0xFF45, 'M', 'e'), + (0xFF46, 'M', 'f'), + (0xFF47, 'M', 'g'), + (0xFF48, 'M', 'h'), + (0xFF49, 'M', 'i'), + (0xFF4A, 'M', 'j'), + (0xFF4B, 'M', 'k'), + (0xFF4C, 'M', 'l'), + (0xFF4D, 'M', 'm'), + (0xFF4E, 'M', 'n'), + (0xFF4F, 'M', 'o'), + (0xFF50, 'M', 'p'), + (0xFF51, 'M', 'q'), + (0xFF52, 'M', 'r'), + (0xFF53, 'M', 's'), + (0xFF54, 'M', 't'), + (0xFF55, 'M', 'u'), + (0xFF56, 'M', 'v'), + (0xFF57, 'M', 'w'), + (0xFF58, 'M', 'x'), + (0xFF59, 'M', 'y'), + (0xFF5A, 'M', 'z'), + (0xFF5B, '3', '{'), + (0xFF5C, '3', '|'), + (0xFF5D, '3', '}'), + (0xFF5E, '3', '~'), + (0xFF5F, 'M', '⦅'), + (0xFF60, 'M', '⦆'), + (0xFF61, 'M', '.'), + (0xFF62, 'M', '「'), + (0xFF63, 'M', '」'), + (0xFF64, 'M', '、'), + (0xFF65, 'M', '・'), + (0xFF66, 'M', 'ヲ'), + (0xFF67, 'M', 'ァ'), + (0xFF68, 'M', 'ィ'), + (0xFF69, 'M', 'ゥ'), + (0xFF6A, 'M', 'ェ'), + (0xFF6B, 'M', 'ォ'), + (0xFF6C, 'M', 'ャ'), + (0xFF6D, 'M', 'ュ'), + (0xFF6E, 'M', 'ョ'), + (0xFF6F, 'M', 'ッ'), + (0xFF70, 'M', 'ー'), + (0xFF71, 'M', 'ア'), + (0xFF72, 'M', 'イ'), + (0xFF73, 'M', 'ウ'), + (0xFF74, 'M', 'エ'), + (0xFF75, 'M', 'オ'), + (0xFF76, 'M', 'カ'), + (0xFF77, 'M', 'キ'), + (0xFF78, 'M', 'ク'), + (0xFF79, 'M', 'ケ'), + (0xFF7A, 'M', 'コ'), + (0xFF7B, 'M', 'サ'), + (0xFF7C, 'M', 'シ'), + (0xFF7D, 'M', 'ス'), + (0xFF7E, 'M', 'セ'), + ] + +def _seg_52() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF7F, 'M', 'ソ'), + (0xFF80, 'M', 'タ'), + (0xFF81, 'M', 'チ'), + (0xFF82, 'M', 'ツ'), + (0xFF83, 'M', 'テ'), + (0xFF84, 'M', 'ト'), + (0xFF85, 'M', 'ナ'), + (0xFF86, 'M', 'ニ'), + (0xFF87, 'M', 'ヌ'), + (0xFF88, 'M', 'ネ'), + (0xFF89, 'M', 'ノ'), + (0xFF8A, 'M', 'ハ'), + (0xFF8B, 'M', 'ヒ'), + (0xFF8C, 'M', 'フ'), + (0xFF8D, 'M', 'ヘ'), + (0xFF8E, 'M', 'ホ'), + (0xFF8F, 'M', 'マ'), + (0xFF90, 'M', 'ミ'), + (0xFF91, 'M', 'ム'), + (0xFF92, 'M', 'メ'), + (0xFF93, 'M', 'モ'), + (0xFF94, 'M', 'ヤ'), + (0xFF95, 'M', 'ユ'), + (0xFF96, 'M', 'ヨ'), + (0xFF97, 'M', 'ラ'), + (0xFF98, 'M', 'リ'), + (0xFF99, 'M', 'ル'), + (0xFF9A, 'M', 'レ'), + (0xFF9B, 'M', 'ロ'), + (0xFF9C, 'M', 'ワ'), + (0xFF9D, 'M', 'ン'), + (0xFF9E, 'M', '゙'), + (0xFF9F, 'M', '゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', 'ᄀ'), + (0xFFA2, 'M', 'ᄁ'), + (0xFFA3, 'M', 'ᆪ'), + (0xFFA4, 'M', 'ᄂ'), + (0xFFA5, 'M', 'ᆬ'), + (0xFFA6, 'M', 'ᆭ'), + (0xFFA7, 'M', 'ᄃ'), + (0xFFA8, 'M', 'ᄄ'), + (0xFFA9, 'M', 'ᄅ'), + (0xFFAA, 'M', 'ᆰ'), + (0xFFAB, 'M', 'ᆱ'), + (0xFFAC, 'M', 'ᆲ'), + (0xFFAD, 'M', 'ᆳ'), + (0xFFAE, 'M', 'ᆴ'), + (0xFFAF, 'M', 'ᆵ'), + (0xFFB0, 'M', 'ᄚ'), + (0xFFB1, 'M', 'ᄆ'), + (0xFFB2, 'M', 'ᄇ'), + (0xFFB3, 'M', 'ᄈ'), + (0xFFB4, 'M', 'ᄡ'), + (0xFFB5, 'M', 'ᄉ'), + (0xFFB6, 'M', 'ᄊ'), + (0xFFB7, 'M', 'ᄋ'), + (0xFFB8, 'M', 'ᄌ'), + (0xFFB9, 'M', 'ᄍ'), + (0xFFBA, 'M', 'ᄎ'), + (0xFFBB, 'M', 'ᄏ'), + (0xFFBC, 'M', 'ᄐ'), + (0xFFBD, 'M', 'ᄑ'), + (0xFFBE, 'M', 'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', 'ᅡ'), + (0xFFC3, 'M', 'ᅢ'), + (0xFFC4, 'M', 'ᅣ'), + (0xFFC5, 'M', 'ᅤ'), + (0xFFC6, 'M', 'ᅥ'), + (0xFFC7, 'M', 'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', 'ᅧ'), + (0xFFCB, 'M', 'ᅨ'), + (0xFFCC, 'M', 'ᅩ'), + (0xFFCD, 'M', 'ᅪ'), + (0xFFCE, 'M', 'ᅫ'), + (0xFFCF, 'M', 'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', 'ᅭ'), + (0xFFD3, 'M', 'ᅮ'), + (0xFFD4, 'M', 'ᅯ'), + (0xFFD5, 'M', 'ᅰ'), + (0xFFD6, 'M', 'ᅱ'), + (0xFFD7, 'M', 'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', 'ᅳ'), + (0xFFDB, 'M', 'ᅴ'), + (0xFFDC, 'M', 'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', '¢'), + (0xFFE1, 'M', '£'), + (0xFFE2, 'M', '¬'), + (0xFFE3, '3', ' ̄'), + (0xFFE4, 'M', '¦'), + (0xFFE5, 'M', '¥'), + (0xFFE6, 'M', '₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', '│'), + (0xFFE9, 'M', '←'), + ] + +def _seg_53() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFFEA, 'M', '↑'), + (0xFFEB, 'M', '→'), + (0xFFEC, 'M', '↓'), + (0xFFED, 'M', '■'), + (0xFFEE, 'M', '○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018F, 'X'), + (0x10190, 'V'), + (0x1019D, 'X'), + (0x101A0, 'V'), + (0x101A1, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x102E0, 'V'), + (0x102FC, 'X'), + (0x10300, 'V'), + (0x10324, 'X'), + (0x1032D, 'V'), + (0x1034B, 'X'), + (0x10350, 'V'), + (0x1037B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', '𐐨'), + (0x10401, 'M', '𐐩'), + (0x10402, 'M', '𐐪'), + (0x10403, 'M', '𐐫'), + (0x10404, 'M', '𐐬'), + (0x10405, 'M', '𐐭'), + (0x10406, 'M', '𐐮'), + (0x10407, 'M', '𐐯'), + (0x10408, 'M', '𐐰'), + (0x10409, 'M', '𐐱'), + (0x1040A, 'M', '𐐲'), + (0x1040B, 'M', '𐐳'), + (0x1040C, 'M', '𐐴'), + (0x1040D, 'M', '𐐵'), + (0x1040E, 'M', '𐐶'), + (0x1040F, 'M', '𐐷'), + (0x10410, 'M', '𐐸'), + (0x10411, 'M', '𐐹'), + (0x10412, 'M', '𐐺'), + (0x10413, 'M', '𐐻'), + (0x10414, 'M', '𐐼'), + (0x10415, 'M', '𐐽'), + (0x10416, 'M', '𐐾'), + (0x10417, 'M', '𐐿'), + (0x10418, 'M', '𐑀'), + (0x10419, 'M', '𐑁'), + (0x1041A, 'M', '𐑂'), + (0x1041B, 'M', '𐑃'), + (0x1041C, 'M', '𐑄'), + (0x1041D, 'M', '𐑅'), + (0x1041E, 'M', '𐑆'), + (0x1041F, 'M', '𐑇'), + (0x10420, 'M', '𐑈'), + (0x10421, 'M', '𐑉'), + (0x10422, 'M', '𐑊'), + (0x10423, 'M', '𐑋'), + (0x10424, 'M', '𐑌'), + (0x10425, 'M', '𐑍'), + (0x10426, 'M', '𐑎'), + (0x10427, 'M', '𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', '𐓘'), + (0x104B1, 'M', '𐓙'), + (0x104B2, 'M', '𐓚'), + (0x104B3, 'M', '𐓛'), + (0x104B4, 'M', '𐓜'), + (0x104B5, 'M', '𐓝'), + ] + +def _seg_54() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x104B6, 'M', '𐓞'), + (0x104B7, 'M', '𐓟'), + (0x104B8, 'M', '𐓠'), + (0x104B9, 'M', '𐓡'), + (0x104BA, 'M', '𐓢'), + (0x104BB, 'M', '𐓣'), + (0x104BC, 'M', '𐓤'), + (0x104BD, 'M', '𐓥'), + (0x104BE, 'M', '𐓦'), + (0x104BF, 'M', '𐓧'), + (0x104C0, 'M', '𐓨'), + (0x104C1, 'M', '𐓩'), + (0x104C2, 'M', '𐓪'), + (0x104C3, 'M', '𐓫'), + (0x104C4, 'M', '𐓬'), + (0x104C5, 'M', '𐓭'), + (0x104C6, 'M', '𐓮'), + (0x104C7, 'M', '𐓯'), + (0x104C8, 'M', '𐓰'), + (0x104C9, 'M', '𐓱'), + (0x104CA, 'M', '𐓲'), + (0x104CB, 'M', '𐓳'), + (0x104CC, 'M', '𐓴'), + (0x104CD, 'M', '𐓵'), + (0x104CE, 'M', '𐓶'), + (0x104CF, 'M', '𐓷'), + (0x104D0, 'M', '𐓸'), + (0x104D1, 'M', '𐓹'), + (0x104D2, 'M', '𐓺'), + (0x104D3, 'M', '𐓻'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'M', '𐖗'), + (0x10571, 'M', '𐖘'), + (0x10572, 'M', '𐖙'), + (0x10573, 'M', '𐖚'), + (0x10574, 'M', '𐖛'), + (0x10575, 'M', '𐖜'), + (0x10576, 'M', '𐖝'), + (0x10577, 'M', '𐖞'), + (0x10578, 'M', '𐖟'), + (0x10579, 'M', '𐖠'), + (0x1057A, 'M', '𐖡'), + (0x1057B, 'X'), + (0x1057C, 'M', '𐖣'), + (0x1057D, 'M', '𐖤'), + (0x1057E, 'M', '𐖥'), + (0x1057F, 'M', '𐖦'), + (0x10580, 'M', '𐖧'), + (0x10581, 'M', '𐖨'), + (0x10582, 'M', '𐖩'), + (0x10583, 'M', '𐖪'), + (0x10584, 'M', '𐖫'), + (0x10585, 'M', '𐖬'), + (0x10586, 'M', '𐖭'), + (0x10587, 'M', '𐖮'), + (0x10588, 'M', '𐖯'), + (0x10589, 'M', '𐖰'), + (0x1058A, 'M', '𐖱'), + (0x1058B, 'X'), + (0x1058C, 'M', '𐖳'), + (0x1058D, 'M', '𐖴'), + (0x1058E, 'M', '𐖵'), + (0x1058F, 'M', '𐖶'), + (0x10590, 'M', '𐖷'), + (0x10591, 'M', '𐖸'), + (0x10592, 'M', '𐖹'), + (0x10593, 'X'), + (0x10594, 'M', '𐖻'), + (0x10595, 'M', '𐖼'), + (0x10596, 'X'), + (0x10597, 'V'), + (0x105A2, 'X'), + (0x105A3, 'V'), + (0x105B2, 'X'), + (0x105B3, 'V'), + (0x105BA, 'X'), + (0x105BB, 'V'), + (0x105BD, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10780, 'V'), + (0x10781, 'M', 'ː'), + (0x10782, 'M', 'ˑ'), + (0x10783, 'M', 'æ'), + (0x10784, 'M', 'ʙ'), + (0x10785, 'M', 'ɓ'), + (0x10786, 'X'), + (0x10787, 'M', 'ʣ'), + (0x10788, 'M', 'ꭦ'), + ] + +def _seg_55() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x10789, 'M', 'ʥ'), + (0x1078A, 'M', 'ʤ'), + (0x1078B, 'M', 'ɖ'), + (0x1078C, 'M', 'ɗ'), + (0x1078D, 'M', 'ᶑ'), + (0x1078E, 'M', 'ɘ'), + (0x1078F, 'M', 'ɞ'), + (0x10790, 'M', 'ʩ'), + (0x10791, 'M', 'ɤ'), + (0x10792, 'M', 'ɢ'), + (0x10793, 'M', 'ɠ'), + (0x10794, 'M', 'ʛ'), + (0x10795, 'M', 'ħ'), + (0x10796, 'M', 'ʜ'), + (0x10797, 'M', 'ɧ'), + (0x10798, 'M', 'ʄ'), + (0x10799, 'M', 'ʪ'), + (0x1079A, 'M', 'ʫ'), + (0x1079B, 'M', 'ɬ'), + (0x1079C, 'M', '𝼄'), + (0x1079D, 'M', 'ꞎ'), + (0x1079E, 'M', 'ɮ'), + (0x1079F, 'M', '𝼅'), + (0x107A0, 'M', 'ʎ'), + (0x107A1, 'M', '𝼆'), + (0x107A2, 'M', 'ø'), + (0x107A3, 'M', 'ɶ'), + (0x107A4, 'M', 'ɷ'), + (0x107A5, 'M', 'q'), + (0x107A6, 'M', 'ɺ'), + (0x107A7, 'M', '𝼈'), + (0x107A8, 'M', 'ɽ'), + (0x107A9, 'M', 'ɾ'), + (0x107AA, 'M', 'ʀ'), + (0x107AB, 'M', 'ʨ'), + (0x107AC, 'M', 'ʦ'), + (0x107AD, 'M', 'ꭧ'), + (0x107AE, 'M', 'ʧ'), + (0x107AF, 'M', 'ʈ'), + (0x107B0, 'M', 'ⱱ'), + (0x107B1, 'X'), + (0x107B2, 'M', 'ʏ'), + (0x107B3, 'M', 'ʡ'), + (0x107B4, 'M', 'ʢ'), + (0x107B5, 'M', 'ʘ'), + (0x107B6, 'M', 'ǀ'), + (0x107B7, 'M', 'ǁ'), + (0x107B8, 'M', 'ǂ'), + (0x107B9, 'M', '𝼊'), + (0x107BA, 'M', '𝼞'), + (0x107BB, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x1089F, 'X'), + (0x108A7, 'V'), + (0x108B0, 'X'), + (0x108E0, 'V'), + (0x108F3, 'X'), + (0x108F4, 'V'), + (0x108F6, 'X'), + (0x108FB, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BC, 'V'), + (0x109D0, 'X'), + (0x109D2, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A36, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A49, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10AA0, 'X'), + (0x10AC0, 'V'), + ] + +def _seg_56() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x10AE7, 'X'), + (0x10AEB, 'V'), + (0x10AF7, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B92, 'X'), + (0x10B99, 'V'), + (0x10B9D, 'X'), + (0x10BA9, 'V'), + (0x10BB0, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10C80, 'M', '𐳀'), + (0x10C81, 'M', '𐳁'), + (0x10C82, 'M', '𐳂'), + (0x10C83, 'M', '𐳃'), + (0x10C84, 'M', '𐳄'), + (0x10C85, 'M', '𐳅'), + (0x10C86, 'M', '𐳆'), + (0x10C87, 'M', '𐳇'), + (0x10C88, 'M', '𐳈'), + (0x10C89, 'M', '𐳉'), + (0x10C8A, 'M', '𐳊'), + (0x10C8B, 'M', '𐳋'), + (0x10C8C, 'M', '𐳌'), + (0x10C8D, 'M', '𐳍'), + (0x10C8E, 'M', '𐳎'), + (0x10C8F, 'M', '𐳏'), + (0x10C90, 'M', '𐳐'), + (0x10C91, 'M', '𐳑'), + (0x10C92, 'M', '𐳒'), + (0x10C93, 'M', '𐳓'), + (0x10C94, 'M', '𐳔'), + (0x10C95, 'M', '𐳕'), + (0x10C96, 'M', '𐳖'), + (0x10C97, 'M', '𐳗'), + (0x10C98, 'M', '𐳘'), + (0x10C99, 'M', '𐳙'), + (0x10C9A, 'M', '𐳚'), + (0x10C9B, 'M', '𐳛'), + (0x10C9C, 'M', '𐳜'), + (0x10C9D, 'M', '𐳝'), + (0x10C9E, 'M', '𐳞'), + (0x10C9F, 'M', '𐳟'), + (0x10CA0, 'M', '𐳠'), + (0x10CA1, 'M', '𐳡'), + (0x10CA2, 'M', '𐳢'), + (0x10CA3, 'M', '𐳣'), + (0x10CA4, 'M', '𐳤'), + (0x10CA5, 'M', '𐳥'), + (0x10CA6, 'M', '𐳦'), + (0x10CA7, 'M', '𐳧'), + (0x10CA8, 'M', '𐳨'), + (0x10CA9, 'M', '𐳩'), + (0x10CAA, 'M', '𐳪'), + (0x10CAB, 'M', '𐳫'), + (0x10CAC, 'M', '𐳬'), + (0x10CAD, 'M', '𐳭'), + (0x10CAE, 'M', '𐳮'), + (0x10CAF, 'M', '𐳯'), + (0x10CB0, 'M', '𐳰'), + (0x10CB1, 'M', '𐳱'), + (0x10CB2, 'M', '𐳲'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D28, 'X'), + (0x10D30, 'V'), + (0x10D3A, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x10E80, 'V'), + (0x10EAA, 'X'), + (0x10EAB, 'V'), + (0x10EAE, 'X'), + (0x10EB0, 'V'), + (0x10EB2, 'X'), + (0x10EFD, 'V'), + (0x10F28, 'X'), + (0x10F30, 'V'), + (0x10F5A, 'X'), + (0x10F70, 'V'), + (0x10F8A, 'X'), + (0x10FB0, 'V'), + (0x10FCC, 'X'), + (0x10FE0, 'V'), + (0x10FF7, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11076, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + ] + +def _seg_57() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x110C3, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11148, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + (0x11213, 'V'), + (0x11242, 'X'), + (0x11280, 'V'), + (0x11287, 'X'), + (0x11288, 'V'), + (0x11289, 'X'), + (0x1128A, 'V'), + (0x1128E, 'X'), + (0x1128F, 'V'), + (0x1129E, 'X'), + (0x1129F, 'V'), + (0x112AA, 'X'), + (0x112B0, 'V'), + (0x112EB, 'X'), + (0x112F0, 'V'), + (0x112FA, 'X'), + (0x11300, 'V'), + (0x11304, 'X'), + (0x11305, 'V'), + (0x1130D, 'X'), + (0x1130F, 'V'), + (0x11311, 'X'), + (0x11313, 'V'), + (0x11329, 'X'), + (0x1132A, 'V'), + (0x11331, 'X'), + (0x11332, 'V'), + (0x11334, 'X'), + (0x11335, 'V'), + (0x1133A, 'X'), + (0x1133B, 'V'), + (0x11345, 'X'), + (0x11347, 'V'), + (0x11349, 'X'), + (0x1134B, 'V'), + (0x1134E, 'X'), + (0x11350, 'V'), + (0x11351, 'X'), + (0x11357, 'V'), + (0x11358, 'X'), + (0x1135D, 'V'), + (0x11364, 'X'), + (0x11366, 'V'), + (0x1136D, 'X'), + (0x11370, 'V'), + (0x11375, 'X'), + (0x11400, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + (0x11462, 'X'), + (0x11480, 'V'), + (0x114C8, 'X'), + (0x114D0, 'V'), + (0x114DA, 'X'), + (0x11580, 'V'), + (0x115B6, 'X'), + (0x115B8, 'V'), + (0x115DE, 'X'), + (0x11600, 'V'), + (0x11645, 'X'), + (0x11650, 'V'), + (0x1165A, 'X'), + (0x11660, 'V'), + (0x1166D, 'X'), + (0x11680, 'V'), + (0x116BA, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171B, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11747, 'X'), + (0x11800, 'V'), + (0x1183C, 'X'), + (0x118A0, 'M', '𑣀'), + (0x118A1, 'M', '𑣁'), + (0x118A2, 'M', '𑣂'), + (0x118A3, 'M', '𑣃'), + (0x118A4, 'M', '𑣄'), + (0x118A5, 'M', '𑣅'), + (0x118A6, 'M', '𑣆'), + ] + +def _seg_58() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x118A7, 'M', '𑣇'), + (0x118A8, 'M', '𑣈'), + (0x118A9, 'M', '𑣉'), + (0x118AA, 'M', '𑣊'), + (0x118AB, 'M', '𑣋'), + (0x118AC, 'M', '𑣌'), + (0x118AD, 'M', '𑣍'), + (0x118AE, 'M', '𑣎'), + (0x118AF, 'M', '𑣏'), + (0x118B0, 'M', '𑣐'), + (0x118B1, 'M', '𑣑'), + (0x118B2, 'M', '𑣒'), + (0x118B3, 'M', '𑣓'), + (0x118B4, 'M', '𑣔'), + (0x118B5, 'M', '𑣕'), + (0x118B6, 'M', '𑣖'), + (0x118B7, 'M', '𑣗'), + (0x118B8, 'M', '𑣘'), + (0x118B9, 'M', '𑣙'), + (0x118BA, 'M', '𑣚'), + (0x118BB, 'M', '𑣛'), + (0x118BC, 'M', '𑣜'), + (0x118BD, 'M', '𑣝'), + (0x118BE, 'M', '𑣞'), + (0x118BF, 'M', '𑣟'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11907, 'X'), + (0x11909, 'V'), + (0x1190A, 'X'), + (0x1190C, 'V'), + (0x11914, 'X'), + (0x11915, 'V'), + (0x11917, 'X'), + (0x11918, 'V'), + (0x11936, 'X'), + (0x11937, 'V'), + (0x11939, 'X'), + (0x1193B, 'V'), + (0x11947, 'X'), + (0x11950, 'V'), + (0x1195A, 'X'), + (0x119A0, 'V'), + (0x119A8, 'X'), + (0x119AA, 'V'), + (0x119D8, 'X'), + (0x119DA, 'V'), + (0x119E5, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11AA3, 'X'), + (0x11AB0, 'V'), + (0x11AF9, 'X'), + (0x11B00, 'V'), + (0x11B0A, 'X'), + (0x11C00, 'V'), + (0x11C09, 'X'), + (0x11C0A, 'V'), + (0x11C37, 'X'), + (0x11C38, 'V'), + (0x11C46, 'X'), + (0x11C50, 'V'), + (0x11C6D, 'X'), + (0x11C70, 'V'), + (0x11C90, 'X'), + (0x11C92, 'V'), + (0x11CA8, 'X'), + (0x11CA9, 'V'), + (0x11CB7, 'X'), + (0x11D00, 'V'), + (0x11D07, 'X'), + (0x11D08, 'V'), + (0x11D0A, 'X'), + (0x11D0B, 'V'), + (0x11D37, 'X'), + (0x11D3A, 'V'), + (0x11D3B, 'X'), + (0x11D3C, 'V'), + (0x11D3E, 'X'), + (0x11D3F, 'V'), + (0x11D48, 'X'), + (0x11D50, 'V'), + (0x11D5A, 'X'), + (0x11D60, 'V'), + (0x11D66, 'X'), + (0x11D67, 'V'), + (0x11D69, 'X'), + (0x11D6A, 'V'), + (0x11D8F, 'X'), + (0x11D90, 'V'), + (0x11D92, 'X'), + (0x11D93, 'V'), + (0x11D99, 'X'), + (0x11DA0, 'V'), + (0x11DAA, 'X'), + (0x11EE0, 'V'), + (0x11EF9, 'X'), + (0x11F00, 'V'), + ] + +def _seg_59() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x11F11, 'X'), + (0x11F12, 'V'), + (0x11F3B, 'X'), + (0x11F3E, 'V'), + (0x11F5A, 'X'), + (0x11FB0, 'V'), + (0x11FB1, 'X'), + (0x11FC0, 'V'), + (0x11FF2, 'X'), + (0x11FFF, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x12F90, 'V'), + (0x12FF3, 'X'), + (0x13000, 'V'), + (0x13430, 'X'), + (0x13440, 'V'), + (0x13456, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16ABF, 'X'), + (0x16AC0, 'V'), + (0x16ACA, 'X'), + (0x16AD0, 'V'), + (0x16AEE, 'X'), + (0x16AF0, 'V'), + (0x16AF6, 'X'), + (0x16B00, 'V'), + (0x16B46, 'X'), + (0x16B50, 'V'), + (0x16B5A, 'X'), + (0x16B5B, 'V'), + (0x16B62, 'X'), + (0x16B63, 'V'), + (0x16B78, 'X'), + (0x16B7D, 'V'), + (0x16B90, 'X'), + (0x16E40, 'M', '𖹠'), + (0x16E41, 'M', '𖹡'), + (0x16E42, 'M', '𖹢'), + (0x16E43, 'M', '𖹣'), + (0x16E44, 'M', '𖹤'), + (0x16E45, 'M', '𖹥'), + (0x16E46, 'M', '𖹦'), + (0x16E47, 'M', '𖹧'), + (0x16E48, 'M', '𖹨'), + (0x16E49, 'M', '𖹩'), + (0x16E4A, 'M', '𖹪'), + (0x16E4B, 'M', '𖹫'), + (0x16E4C, 'M', '𖹬'), + (0x16E4D, 'M', '𖹭'), + (0x16E4E, 'M', '𖹮'), + (0x16E4F, 'M', '𖹯'), + (0x16E50, 'M', '𖹰'), + (0x16E51, 'M', '𖹱'), + (0x16E52, 'M', '𖹲'), + (0x16E53, 'M', '𖹳'), + (0x16E54, 'M', '𖹴'), + (0x16E55, 'M', '𖹵'), + (0x16E56, 'M', '𖹶'), + (0x16E57, 'M', '𖹷'), + (0x16E58, 'M', '𖹸'), + (0x16E59, 'M', '𖹹'), + (0x16E5A, 'M', '𖹺'), + (0x16E5B, 'M', '𖹻'), + (0x16E5C, 'M', '𖹼'), + (0x16E5D, 'M', '𖹽'), + (0x16E5E, 'M', '𖹾'), + (0x16E5F, 'M', '𖹿'), + (0x16E60, 'V'), + (0x16E9B, 'X'), + (0x16F00, 'V'), + (0x16F4B, 'X'), + (0x16F4F, 'V'), + (0x16F88, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE5, 'X'), + (0x16FF0, 'V'), + (0x16FF2, 'X'), + (0x17000, 'V'), + (0x187F8, 'X'), + (0x18800, 'V'), + (0x18CD6, 'X'), + (0x18D00, 'V'), + (0x18D09, 'X'), + (0x1AFF0, 'V'), + ] + +def _seg_60() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1AFF4, 'X'), + (0x1AFF5, 'V'), + (0x1AFFC, 'X'), + (0x1AFFD, 'V'), + (0x1AFFF, 'X'), + (0x1B000, 'V'), + (0x1B123, 'X'), + (0x1B132, 'V'), + (0x1B133, 'X'), + (0x1B150, 'V'), + (0x1B153, 'X'), + (0x1B155, 'V'), + (0x1B156, 'X'), + (0x1B164, 'V'), + (0x1B168, 'X'), + (0x1B170, 'V'), + (0x1B2FC, 'X'), + (0x1BC00, 'V'), + (0x1BC6B, 'X'), + (0x1BC70, 'V'), + (0x1BC7D, 'X'), + (0x1BC80, 'V'), + (0x1BC89, 'X'), + (0x1BC90, 'V'), + (0x1BC9A, 'X'), + (0x1BC9C, 'V'), + (0x1BCA0, 'I'), + (0x1BCA4, 'X'), + (0x1CF00, 'V'), + (0x1CF2E, 'X'), + (0x1CF30, 'V'), + (0x1CF47, 'X'), + (0x1CF50, 'V'), + (0x1CFC4, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', '𝅗𝅥'), + (0x1D15F, 'M', '𝅘𝅥'), + (0x1D160, 'M', '𝅘𝅥𝅮'), + (0x1D161, 'M', '𝅘𝅥𝅯'), + (0x1D162, 'M', '𝅘𝅥𝅰'), + (0x1D163, 'M', '𝅘𝅥𝅱'), + (0x1D164, 'M', '𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', '𝆹𝅥'), + (0x1D1BC, 'M', '𝆺𝅥'), + (0x1D1BD, 'M', '𝆹𝅥𝅮'), + (0x1D1BE, 'M', '𝆺𝅥𝅮'), + (0x1D1BF, 'M', '𝆹𝅥𝅯'), + (0x1D1C0, 'M', '𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1EB, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D2C0, 'V'), + (0x1D2D4, 'X'), + (0x1D2E0, 'V'), + (0x1D2F4, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D379, 'X'), + (0x1D400, 'M', 'a'), + (0x1D401, 'M', 'b'), + (0x1D402, 'M', 'c'), + (0x1D403, 'M', 'd'), + (0x1D404, 'M', 'e'), + (0x1D405, 'M', 'f'), + (0x1D406, 'M', 'g'), + (0x1D407, 'M', 'h'), + (0x1D408, 'M', 'i'), + (0x1D409, 'M', 'j'), + (0x1D40A, 'M', 'k'), + (0x1D40B, 'M', 'l'), + (0x1D40C, 'M', 'm'), + (0x1D40D, 'M', 'n'), + (0x1D40E, 'M', 'o'), + (0x1D40F, 'M', 'p'), + (0x1D410, 'M', 'q'), + (0x1D411, 'M', 'r'), + (0x1D412, 'M', 's'), + (0x1D413, 'M', 't'), + (0x1D414, 'M', 'u'), + (0x1D415, 'M', 'v'), + (0x1D416, 'M', 'w'), + (0x1D417, 'M', 'x'), + (0x1D418, 'M', 'y'), + (0x1D419, 'M', 'z'), + (0x1D41A, 'M', 'a'), + (0x1D41B, 'M', 'b'), + (0x1D41C, 'M', 'c'), + (0x1D41D, 'M', 'd'), + (0x1D41E, 'M', 'e'), + (0x1D41F, 'M', 'f'), + (0x1D420, 'M', 'g'), + ] + +def _seg_61() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D421, 'M', 'h'), + (0x1D422, 'M', 'i'), + (0x1D423, 'M', 'j'), + (0x1D424, 'M', 'k'), + (0x1D425, 'M', 'l'), + (0x1D426, 'M', 'm'), + (0x1D427, 'M', 'n'), + (0x1D428, 'M', 'o'), + (0x1D429, 'M', 'p'), + (0x1D42A, 'M', 'q'), + (0x1D42B, 'M', 'r'), + (0x1D42C, 'M', 's'), + (0x1D42D, 'M', 't'), + (0x1D42E, 'M', 'u'), + (0x1D42F, 'M', 'v'), + (0x1D430, 'M', 'w'), + (0x1D431, 'M', 'x'), + (0x1D432, 'M', 'y'), + (0x1D433, 'M', 'z'), + (0x1D434, 'M', 'a'), + (0x1D435, 'M', 'b'), + (0x1D436, 'M', 'c'), + (0x1D437, 'M', 'd'), + (0x1D438, 'M', 'e'), + (0x1D439, 'M', 'f'), + (0x1D43A, 'M', 'g'), + (0x1D43B, 'M', 'h'), + (0x1D43C, 'M', 'i'), + (0x1D43D, 'M', 'j'), + (0x1D43E, 'M', 'k'), + (0x1D43F, 'M', 'l'), + (0x1D440, 'M', 'm'), + (0x1D441, 'M', 'n'), + (0x1D442, 'M', 'o'), + (0x1D443, 'M', 'p'), + (0x1D444, 'M', 'q'), + (0x1D445, 'M', 'r'), + (0x1D446, 'M', 's'), + (0x1D447, 'M', 't'), + (0x1D448, 'M', 'u'), + (0x1D449, 'M', 'v'), + (0x1D44A, 'M', 'w'), + (0x1D44B, 'M', 'x'), + (0x1D44C, 'M', 'y'), + (0x1D44D, 'M', 'z'), + (0x1D44E, 'M', 'a'), + (0x1D44F, 'M', 'b'), + (0x1D450, 'M', 'c'), + (0x1D451, 'M', 'd'), + (0x1D452, 'M', 'e'), + (0x1D453, 'M', 'f'), + (0x1D454, 'M', 'g'), + (0x1D455, 'X'), + (0x1D456, 'M', 'i'), + (0x1D457, 'M', 'j'), + (0x1D458, 'M', 'k'), + (0x1D459, 'M', 'l'), + (0x1D45A, 'M', 'm'), + (0x1D45B, 'M', 'n'), + (0x1D45C, 'M', 'o'), + (0x1D45D, 'M', 'p'), + (0x1D45E, 'M', 'q'), + (0x1D45F, 'M', 'r'), + (0x1D460, 'M', 's'), + (0x1D461, 'M', 't'), + (0x1D462, 'M', 'u'), + (0x1D463, 'M', 'v'), + (0x1D464, 'M', 'w'), + (0x1D465, 'M', 'x'), + (0x1D466, 'M', 'y'), + (0x1D467, 'M', 'z'), + (0x1D468, 'M', 'a'), + (0x1D469, 'M', 'b'), + (0x1D46A, 'M', 'c'), + (0x1D46B, 'M', 'd'), + (0x1D46C, 'M', 'e'), + (0x1D46D, 'M', 'f'), + (0x1D46E, 'M', 'g'), + (0x1D46F, 'M', 'h'), + (0x1D470, 'M', 'i'), + (0x1D471, 'M', 'j'), + (0x1D472, 'M', 'k'), + (0x1D473, 'M', 'l'), + (0x1D474, 'M', 'm'), + (0x1D475, 'M', 'n'), + (0x1D476, 'M', 'o'), + (0x1D477, 'M', 'p'), + (0x1D478, 'M', 'q'), + (0x1D479, 'M', 'r'), + (0x1D47A, 'M', 's'), + (0x1D47B, 'M', 't'), + (0x1D47C, 'M', 'u'), + (0x1D47D, 'M', 'v'), + (0x1D47E, 'M', 'w'), + (0x1D47F, 'M', 'x'), + (0x1D480, 'M', 'y'), + (0x1D481, 'M', 'z'), + (0x1D482, 'M', 'a'), + (0x1D483, 'M', 'b'), + (0x1D484, 'M', 'c'), + ] + +def _seg_62() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D485, 'M', 'd'), + (0x1D486, 'M', 'e'), + (0x1D487, 'M', 'f'), + (0x1D488, 'M', 'g'), + (0x1D489, 'M', 'h'), + (0x1D48A, 'M', 'i'), + (0x1D48B, 'M', 'j'), + (0x1D48C, 'M', 'k'), + (0x1D48D, 'M', 'l'), + (0x1D48E, 'M', 'm'), + (0x1D48F, 'M', 'n'), + (0x1D490, 'M', 'o'), + (0x1D491, 'M', 'p'), + (0x1D492, 'M', 'q'), + (0x1D493, 'M', 'r'), + (0x1D494, 'M', 's'), + (0x1D495, 'M', 't'), + (0x1D496, 'M', 'u'), + (0x1D497, 'M', 'v'), + (0x1D498, 'M', 'w'), + (0x1D499, 'M', 'x'), + (0x1D49A, 'M', 'y'), + (0x1D49B, 'M', 'z'), + (0x1D49C, 'M', 'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', 'c'), + (0x1D49F, 'M', 'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', 'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', 'j'), + (0x1D4A6, 'M', 'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', 'n'), + (0x1D4AA, 'M', 'o'), + (0x1D4AB, 'M', 'p'), + (0x1D4AC, 'M', 'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', 's'), + (0x1D4AF, 'M', 't'), + (0x1D4B0, 'M', 'u'), + (0x1D4B1, 'M', 'v'), + (0x1D4B2, 'M', 'w'), + (0x1D4B3, 'M', 'x'), + (0x1D4B4, 'M', 'y'), + (0x1D4B5, 'M', 'z'), + (0x1D4B6, 'M', 'a'), + (0x1D4B7, 'M', 'b'), + (0x1D4B8, 'M', 'c'), + (0x1D4B9, 'M', 'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', 'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', 'h'), + (0x1D4BE, 'M', 'i'), + (0x1D4BF, 'M', 'j'), + (0x1D4C0, 'M', 'k'), + (0x1D4C1, 'M', 'l'), + (0x1D4C2, 'M', 'm'), + (0x1D4C3, 'M', 'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', 'p'), + (0x1D4C6, 'M', 'q'), + (0x1D4C7, 'M', 'r'), + (0x1D4C8, 'M', 's'), + (0x1D4C9, 'M', 't'), + (0x1D4CA, 'M', 'u'), + (0x1D4CB, 'M', 'v'), + (0x1D4CC, 'M', 'w'), + (0x1D4CD, 'M', 'x'), + (0x1D4CE, 'M', 'y'), + (0x1D4CF, 'M', 'z'), + (0x1D4D0, 'M', 'a'), + (0x1D4D1, 'M', 'b'), + (0x1D4D2, 'M', 'c'), + (0x1D4D3, 'M', 'd'), + (0x1D4D4, 'M', 'e'), + (0x1D4D5, 'M', 'f'), + (0x1D4D6, 'M', 'g'), + (0x1D4D7, 'M', 'h'), + (0x1D4D8, 'M', 'i'), + (0x1D4D9, 'M', 'j'), + (0x1D4DA, 'M', 'k'), + (0x1D4DB, 'M', 'l'), + (0x1D4DC, 'M', 'm'), + (0x1D4DD, 'M', 'n'), + (0x1D4DE, 'M', 'o'), + (0x1D4DF, 'M', 'p'), + (0x1D4E0, 'M', 'q'), + (0x1D4E1, 'M', 'r'), + (0x1D4E2, 'M', 's'), + (0x1D4E3, 'M', 't'), + (0x1D4E4, 'M', 'u'), + (0x1D4E5, 'M', 'v'), + (0x1D4E6, 'M', 'w'), + (0x1D4E7, 'M', 'x'), + (0x1D4E8, 'M', 'y'), + (0x1D4E9, 'M', 'z'), + (0x1D4EA, 'M', 'a'), + (0x1D4EB, 'M', 'b'), + ] + +def _seg_63() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D4EC, 'M', 'c'), + (0x1D4ED, 'M', 'd'), + (0x1D4EE, 'M', 'e'), + (0x1D4EF, 'M', 'f'), + (0x1D4F0, 'M', 'g'), + (0x1D4F1, 'M', 'h'), + (0x1D4F2, 'M', 'i'), + (0x1D4F3, 'M', 'j'), + (0x1D4F4, 'M', 'k'), + (0x1D4F5, 'M', 'l'), + (0x1D4F6, 'M', 'm'), + (0x1D4F7, 'M', 'n'), + (0x1D4F8, 'M', 'o'), + (0x1D4F9, 'M', 'p'), + (0x1D4FA, 'M', 'q'), + (0x1D4FB, 'M', 'r'), + (0x1D4FC, 'M', 's'), + (0x1D4FD, 'M', 't'), + (0x1D4FE, 'M', 'u'), + (0x1D4FF, 'M', 'v'), + (0x1D500, 'M', 'w'), + (0x1D501, 'M', 'x'), + (0x1D502, 'M', 'y'), + (0x1D503, 'M', 'z'), + (0x1D504, 'M', 'a'), + (0x1D505, 'M', 'b'), + (0x1D506, 'X'), + (0x1D507, 'M', 'd'), + (0x1D508, 'M', 'e'), + (0x1D509, 'M', 'f'), + (0x1D50A, 'M', 'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', 'j'), + (0x1D50E, 'M', 'k'), + (0x1D50F, 'M', 'l'), + (0x1D510, 'M', 'm'), + (0x1D511, 'M', 'n'), + (0x1D512, 'M', 'o'), + (0x1D513, 'M', 'p'), + (0x1D514, 'M', 'q'), + (0x1D515, 'X'), + (0x1D516, 'M', 's'), + (0x1D517, 'M', 't'), + (0x1D518, 'M', 'u'), + (0x1D519, 'M', 'v'), + (0x1D51A, 'M', 'w'), + (0x1D51B, 'M', 'x'), + (0x1D51C, 'M', 'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', 'a'), + (0x1D51F, 'M', 'b'), + (0x1D520, 'M', 'c'), + (0x1D521, 'M', 'd'), + (0x1D522, 'M', 'e'), + (0x1D523, 'M', 'f'), + (0x1D524, 'M', 'g'), + (0x1D525, 'M', 'h'), + (0x1D526, 'M', 'i'), + (0x1D527, 'M', 'j'), + (0x1D528, 'M', 'k'), + (0x1D529, 'M', 'l'), + (0x1D52A, 'M', 'm'), + (0x1D52B, 'M', 'n'), + (0x1D52C, 'M', 'o'), + (0x1D52D, 'M', 'p'), + (0x1D52E, 'M', 'q'), + (0x1D52F, 'M', 'r'), + (0x1D530, 'M', 's'), + (0x1D531, 'M', 't'), + (0x1D532, 'M', 'u'), + (0x1D533, 'M', 'v'), + (0x1D534, 'M', 'w'), + (0x1D535, 'M', 'x'), + (0x1D536, 'M', 'y'), + (0x1D537, 'M', 'z'), + (0x1D538, 'M', 'a'), + (0x1D539, 'M', 'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', 'd'), + (0x1D53C, 'M', 'e'), + (0x1D53D, 'M', 'f'), + (0x1D53E, 'M', 'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', 'i'), + (0x1D541, 'M', 'j'), + (0x1D542, 'M', 'k'), + (0x1D543, 'M', 'l'), + (0x1D544, 'M', 'm'), + (0x1D545, 'X'), + (0x1D546, 'M', 'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', 's'), + (0x1D54B, 'M', 't'), + (0x1D54C, 'M', 'u'), + (0x1D54D, 'M', 'v'), + (0x1D54E, 'M', 'w'), + (0x1D54F, 'M', 'x'), + (0x1D550, 'M', 'y'), + (0x1D551, 'X'), + (0x1D552, 'M', 'a'), + ] + +def _seg_64() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D553, 'M', 'b'), + (0x1D554, 'M', 'c'), + (0x1D555, 'M', 'd'), + (0x1D556, 'M', 'e'), + (0x1D557, 'M', 'f'), + (0x1D558, 'M', 'g'), + (0x1D559, 'M', 'h'), + (0x1D55A, 'M', 'i'), + (0x1D55B, 'M', 'j'), + (0x1D55C, 'M', 'k'), + (0x1D55D, 'M', 'l'), + (0x1D55E, 'M', 'm'), + (0x1D55F, 'M', 'n'), + (0x1D560, 'M', 'o'), + (0x1D561, 'M', 'p'), + (0x1D562, 'M', 'q'), + (0x1D563, 'M', 'r'), + (0x1D564, 'M', 's'), + (0x1D565, 'M', 't'), + (0x1D566, 'M', 'u'), + (0x1D567, 'M', 'v'), + (0x1D568, 'M', 'w'), + (0x1D569, 'M', 'x'), + (0x1D56A, 'M', 'y'), + (0x1D56B, 'M', 'z'), + (0x1D56C, 'M', 'a'), + (0x1D56D, 'M', 'b'), + (0x1D56E, 'M', 'c'), + (0x1D56F, 'M', 'd'), + (0x1D570, 'M', 'e'), + (0x1D571, 'M', 'f'), + (0x1D572, 'M', 'g'), + (0x1D573, 'M', 'h'), + (0x1D574, 'M', 'i'), + (0x1D575, 'M', 'j'), + (0x1D576, 'M', 'k'), + (0x1D577, 'M', 'l'), + (0x1D578, 'M', 'm'), + (0x1D579, 'M', 'n'), + (0x1D57A, 'M', 'o'), + (0x1D57B, 'M', 'p'), + (0x1D57C, 'M', 'q'), + (0x1D57D, 'M', 'r'), + (0x1D57E, 'M', 's'), + (0x1D57F, 'M', 't'), + (0x1D580, 'M', 'u'), + (0x1D581, 'M', 'v'), + (0x1D582, 'M', 'w'), + (0x1D583, 'M', 'x'), + (0x1D584, 'M', 'y'), + (0x1D585, 'M', 'z'), + (0x1D586, 'M', 'a'), + (0x1D587, 'M', 'b'), + (0x1D588, 'M', 'c'), + (0x1D589, 'M', 'd'), + (0x1D58A, 'M', 'e'), + (0x1D58B, 'M', 'f'), + (0x1D58C, 'M', 'g'), + (0x1D58D, 'M', 'h'), + (0x1D58E, 'M', 'i'), + (0x1D58F, 'M', 'j'), + (0x1D590, 'M', 'k'), + (0x1D591, 'M', 'l'), + (0x1D592, 'M', 'm'), + (0x1D593, 'M', 'n'), + (0x1D594, 'M', 'o'), + (0x1D595, 'M', 'p'), + (0x1D596, 'M', 'q'), + (0x1D597, 'M', 'r'), + (0x1D598, 'M', 's'), + (0x1D599, 'M', 't'), + (0x1D59A, 'M', 'u'), + (0x1D59B, 'M', 'v'), + (0x1D59C, 'M', 'w'), + (0x1D59D, 'M', 'x'), + (0x1D59E, 'M', 'y'), + (0x1D59F, 'M', 'z'), + (0x1D5A0, 'M', 'a'), + (0x1D5A1, 'M', 'b'), + (0x1D5A2, 'M', 'c'), + (0x1D5A3, 'M', 'd'), + (0x1D5A4, 'M', 'e'), + (0x1D5A5, 'M', 'f'), + (0x1D5A6, 'M', 'g'), + (0x1D5A7, 'M', 'h'), + (0x1D5A8, 'M', 'i'), + (0x1D5A9, 'M', 'j'), + (0x1D5AA, 'M', 'k'), + (0x1D5AB, 'M', 'l'), + (0x1D5AC, 'M', 'm'), + (0x1D5AD, 'M', 'n'), + (0x1D5AE, 'M', 'o'), + (0x1D5AF, 'M', 'p'), + (0x1D5B0, 'M', 'q'), + (0x1D5B1, 'M', 'r'), + (0x1D5B2, 'M', 's'), + (0x1D5B3, 'M', 't'), + (0x1D5B4, 'M', 'u'), + (0x1D5B5, 'M', 'v'), + (0x1D5B6, 'M', 'w'), + ] + +def _seg_65() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D5B7, 'M', 'x'), + (0x1D5B8, 'M', 'y'), + (0x1D5B9, 'M', 'z'), + (0x1D5BA, 'M', 'a'), + (0x1D5BB, 'M', 'b'), + (0x1D5BC, 'M', 'c'), + (0x1D5BD, 'M', 'd'), + (0x1D5BE, 'M', 'e'), + (0x1D5BF, 'M', 'f'), + (0x1D5C0, 'M', 'g'), + (0x1D5C1, 'M', 'h'), + (0x1D5C2, 'M', 'i'), + (0x1D5C3, 'M', 'j'), + (0x1D5C4, 'M', 'k'), + (0x1D5C5, 'M', 'l'), + (0x1D5C6, 'M', 'm'), + (0x1D5C7, 'M', 'n'), + (0x1D5C8, 'M', 'o'), + (0x1D5C9, 'M', 'p'), + (0x1D5CA, 'M', 'q'), + (0x1D5CB, 'M', 'r'), + (0x1D5CC, 'M', 's'), + (0x1D5CD, 'M', 't'), + (0x1D5CE, 'M', 'u'), + (0x1D5CF, 'M', 'v'), + (0x1D5D0, 'M', 'w'), + (0x1D5D1, 'M', 'x'), + (0x1D5D2, 'M', 'y'), + (0x1D5D3, 'M', 'z'), + (0x1D5D4, 'M', 'a'), + (0x1D5D5, 'M', 'b'), + (0x1D5D6, 'M', 'c'), + (0x1D5D7, 'M', 'd'), + (0x1D5D8, 'M', 'e'), + (0x1D5D9, 'M', 'f'), + (0x1D5DA, 'M', 'g'), + (0x1D5DB, 'M', 'h'), + (0x1D5DC, 'M', 'i'), + (0x1D5DD, 'M', 'j'), + (0x1D5DE, 'M', 'k'), + (0x1D5DF, 'M', 'l'), + (0x1D5E0, 'M', 'm'), + (0x1D5E1, 'M', 'n'), + (0x1D5E2, 'M', 'o'), + (0x1D5E3, 'M', 'p'), + (0x1D5E4, 'M', 'q'), + (0x1D5E5, 'M', 'r'), + (0x1D5E6, 'M', 's'), + (0x1D5E7, 'M', 't'), + (0x1D5E8, 'M', 'u'), + (0x1D5E9, 'M', 'v'), + (0x1D5EA, 'M', 'w'), + (0x1D5EB, 'M', 'x'), + (0x1D5EC, 'M', 'y'), + (0x1D5ED, 'M', 'z'), + (0x1D5EE, 'M', 'a'), + (0x1D5EF, 'M', 'b'), + (0x1D5F0, 'M', 'c'), + (0x1D5F1, 'M', 'd'), + (0x1D5F2, 'M', 'e'), + (0x1D5F3, 'M', 'f'), + (0x1D5F4, 'M', 'g'), + (0x1D5F5, 'M', 'h'), + (0x1D5F6, 'M', 'i'), + (0x1D5F7, 'M', 'j'), + (0x1D5F8, 'M', 'k'), + (0x1D5F9, 'M', 'l'), + (0x1D5FA, 'M', 'm'), + (0x1D5FB, 'M', 'n'), + (0x1D5FC, 'M', 'o'), + (0x1D5FD, 'M', 'p'), + (0x1D5FE, 'M', 'q'), + (0x1D5FF, 'M', 'r'), + (0x1D600, 'M', 's'), + (0x1D601, 'M', 't'), + (0x1D602, 'M', 'u'), + (0x1D603, 'M', 'v'), + (0x1D604, 'M', 'w'), + (0x1D605, 'M', 'x'), + (0x1D606, 'M', 'y'), + (0x1D607, 'M', 'z'), + (0x1D608, 'M', 'a'), + (0x1D609, 'M', 'b'), + (0x1D60A, 'M', 'c'), + (0x1D60B, 'M', 'd'), + (0x1D60C, 'M', 'e'), + (0x1D60D, 'M', 'f'), + (0x1D60E, 'M', 'g'), + (0x1D60F, 'M', 'h'), + (0x1D610, 'M', 'i'), + (0x1D611, 'M', 'j'), + (0x1D612, 'M', 'k'), + (0x1D613, 'M', 'l'), + (0x1D614, 'M', 'm'), + (0x1D615, 'M', 'n'), + (0x1D616, 'M', 'o'), + (0x1D617, 'M', 'p'), + (0x1D618, 'M', 'q'), + (0x1D619, 'M', 'r'), + (0x1D61A, 'M', 's'), + ] + +def _seg_66() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D61B, 'M', 't'), + (0x1D61C, 'M', 'u'), + (0x1D61D, 'M', 'v'), + (0x1D61E, 'M', 'w'), + (0x1D61F, 'M', 'x'), + (0x1D620, 'M', 'y'), + (0x1D621, 'M', 'z'), + (0x1D622, 'M', 'a'), + (0x1D623, 'M', 'b'), + (0x1D624, 'M', 'c'), + (0x1D625, 'M', 'd'), + (0x1D626, 'M', 'e'), + (0x1D627, 'M', 'f'), + (0x1D628, 'M', 'g'), + (0x1D629, 'M', 'h'), + (0x1D62A, 'M', 'i'), + (0x1D62B, 'M', 'j'), + (0x1D62C, 'M', 'k'), + (0x1D62D, 'M', 'l'), + (0x1D62E, 'M', 'm'), + (0x1D62F, 'M', 'n'), + (0x1D630, 'M', 'o'), + (0x1D631, 'M', 'p'), + (0x1D632, 'M', 'q'), + (0x1D633, 'M', 'r'), + (0x1D634, 'M', 's'), + (0x1D635, 'M', 't'), + (0x1D636, 'M', 'u'), + (0x1D637, 'M', 'v'), + (0x1D638, 'M', 'w'), + (0x1D639, 'M', 'x'), + (0x1D63A, 'M', 'y'), + (0x1D63B, 'M', 'z'), + (0x1D63C, 'M', 'a'), + (0x1D63D, 'M', 'b'), + (0x1D63E, 'M', 'c'), + (0x1D63F, 'M', 'd'), + (0x1D640, 'M', 'e'), + (0x1D641, 'M', 'f'), + (0x1D642, 'M', 'g'), + (0x1D643, 'M', 'h'), + (0x1D644, 'M', 'i'), + (0x1D645, 'M', 'j'), + (0x1D646, 'M', 'k'), + (0x1D647, 'M', 'l'), + (0x1D648, 'M', 'm'), + (0x1D649, 'M', 'n'), + (0x1D64A, 'M', 'o'), + (0x1D64B, 'M', 'p'), + (0x1D64C, 'M', 'q'), + (0x1D64D, 'M', 'r'), + (0x1D64E, 'M', 's'), + (0x1D64F, 'M', 't'), + (0x1D650, 'M', 'u'), + (0x1D651, 'M', 'v'), + (0x1D652, 'M', 'w'), + (0x1D653, 'M', 'x'), + (0x1D654, 'M', 'y'), + (0x1D655, 'M', 'z'), + (0x1D656, 'M', 'a'), + (0x1D657, 'M', 'b'), + (0x1D658, 'M', 'c'), + (0x1D659, 'M', 'd'), + (0x1D65A, 'M', 'e'), + (0x1D65B, 'M', 'f'), + (0x1D65C, 'M', 'g'), + (0x1D65D, 'M', 'h'), + (0x1D65E, 'M', 'i'), + (0x1D65F, 'M', 'j'), + (0x1D660, 'M', 'k'), + (0x1D661, 'M', 'l'), + (0x1D662, 'M', 'm'), + (0x1D663, 'M', 'n'), + (0x1D664, 'M', 'o'), + (0x1D665, 'M', 'p'), + (0x1D666, 'M', 'q'), + (0x1D667, 'M', 'r'), + (0x1D668, 'M', 's'), + (0x1D669, 'M', 't'), + (0x1D66A, 'M', 'u'), + (0x1D66B, 'M', 'v'), + (0x1D66C, 'M', 'w'), + (0x1D66D, 'M', 'x'), + (0x1D66E, 'M', 'y'), + (0x1D66F, 'M', 'z'), + (0x1D670, 'M', 'a'), + (0x1D671, 'M', 'b'), + (0x1D672, 'M', 'c'), + (0x1D673, 'M', 'd'), + (0x1D674, 'M', 'e'), + (0x1D675, 'M', 'f'), + (0x1D676, 'M', 'g'), + (0x1D677, 'M', 'h'), + (0x1D678, 'M', 'i'), + (0x1D679, 'M', 'j'), + (0x1D67A, 'M', 'k'), + (0x1D67B, 'M', 'l'), + (0x1D67C, 'M', 'm'), + (0x1D67D, 'M', 'n'), + (0x1D67E, 'M', 'o'), + ] + +def _seg_67() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D67F, 'M', 'p'), + (0x1D680, 'M', 'q'), + (0x1D681, 'M', 'r'), + (0x1D682, 'M', 's'), + (0x1D683, 'M', 't'), + (0x1D684, 'M', 'u'), + (0x1D685, 'M', 'v'), + (0x1D686, 'M', 'w'), + (0x1D687, 'M', 'x'), + (0x1D688, 'M', 'y'), + (0x1D689, 'M', 'z'), + (0x1D68A, 'M', 'a'), + (0x1D68B, 'M', 'b'), + (0x1D68C, 'M', 'c'), + (0x1D68D, 'M', 'd'), + (0x1D68E, 'M', 'e'), + (0x1D68F, 'M', 'f'), + (0x1D690, 'M', 'g'), + (0x1D691, 'M', 'h'), + (0x1D692, 'M', 'i'), + (0x1D693, 'M', 'j'), + (0x1D694, 'M', 'k'), + (0x1D695, 'M', 'l'), + (0x1D696, 'M', 'm'), + (0x1D697, 'M', 'n'), + (0x1D698, 'M', 'o'), + (0x1D699, 'M', 'p'), + (0x1D69A, 'M', 'q'), + (0x1D69B, 'M', 'r'), + (0x1D69C, 'M', 's'), + (0x1D69D, 'M', 't'), + (0x1D69E, 'M', 'u'), + (0x1D69F, 'M', 'v'), + (0x1D6A0, 'M', 'w'), + (0x1D6A1, 'M', 'x'), + (0x1D6A2, 'M', 'y'), + (0x1D6A3, 'M', 'z'), + (0x1D6A4, 'M', 'ı'), + (0x1D6A5, 'M', 'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', 'α'), + (0x1D6A9, 'M', 'β'), + (0x1D6AA, 'M', 'γ'), + (0x1D6AB, 'M', 'δ'), + (0x1D6AC, 'M', 'ε'), + (0x1D6AD, 'M', 'ζ'), + (0x1D6AE, 'M', 'η'), + (0x1D6AF, 'M', 'θ'), + (0x1D6B0, 'M', 'ι'), + (0x1D6B1, 'M', 'κ'), + (0x1D6B2, 'M', 'λ'), + (0x1D6B3, 'M', 'μ'), + (0x1D6B4, 'M', 'ν'), + (0x1D6B5, 'M', 'ξ'), + (0x1D6B6, 'M', 'ο'), + (0x1D6B7, 'M', 'π'), + (0x1D6B8, 'M', 'ρ'), + (0x1D6B9, 'M', 'θ'), + (0x1D6BA, 'M', 'σ'), + (0x1D6BB, 'M', 'τ'), + (0x1D6BC, 'M', 'υ'), + (0x1D6BD, 'M', 'φ'), + (0x1D6BE, 'M', 'χ'), + (0x1D6BF, 'M', 'ψ'), + (0x1D6C0, 'M', 'ω'), + (0x1D6C1, 'M', '∇'), + (0x1D6C2, 'M', 'α'), + (0x1D6C3, 'M', 'β'), + (0x1D6C4, 'M', 'γ'), + (0x1D6C5, 'M', 'δ'), + (0x1D6C6, 'M', 'ε'), + (0x1D6C7, 'M', 'ζ'), + (0x1D6C8, 'M', 'η'), + (0x1D6C9, 'M', 'θ'), + (0x1D6CA, 'M', 'ι'), + (0x1D6CB, 'M', 'κ'), + (0x1D6CC, 'M', 'λ'), + (0x1D6CD, 'M', 'μ'), + (0x1D6CE, 'M', 'ν'), + (0x1D6CF, 'M', 'ξ'), + (0x1D6D0, 'M', 'ο'), + (0x1D6D1, 'M', 'π'), + (0x1D6D2, 'M', 'ρ'), + (0x1D6D3, 'M', 'σ'), + (0x1D6D5, 'M', 'τ'), + (0x1D6D6, 'M', 'υ'), + (0x1D6D7, 'M', 'φ'), + (0x1D6D8, 'M', 'χ'), + (0x1D6D9, 'M', 'ψ'), + (0x1D6DA, 'M', 'ω'), + (0x1D6DB, 'M', '∂'), + (0x1D6DC, 'M', 'ε'), + (0x1D6DD, 'M', 'θ'), + (0x1D6DE, 'M', 'κ'), + (0x1D6DF, 'M', 'φ'), + (0x1D6E0, 'M', 'ρ'), + (0x1D6E1, 'M', 'π'), + (0x1D6E2, 'M', 'α'), + (0x1D6E3, 'M', 'β'), + (0x1D6E4, 'M', 'γ'), + ] + +def _seg_68() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D6E5, 'M', 'δ'), + (0x1D6E6, 'M', 'ε'), + (0x1D6E7, 'M', 'ζ'), + (0x1D6E8, 'M', 'η'), + (0x1D6E9, 'M', 'θ'), + (0x1D6EA, 'M', 'ι'), + (0x1D6EB, 'M', 'κ'), + (0x1D6EC, 'M', 'λ'), + (0x1D6ED, 'M', 'μ'), + (0x1D6EE, 'M', 'ν'), + (0x1D6EF, 'M', 'ξ'), + (0x1D6F0, 'M', 'ο'), + (0x1D6F1, 'M', 'π'), + (0x1D6F2, 'M', 'ρ'), + (0x1D6F3, 'M', 'θ'), + (0x1D6F4, 'M', 'σ'), + (0x1D6F5, 'M', 'τ'), + (0x1D6F6, 'M', 'υ'), + (0x1D6F7, 'M', 'φ'), + (0x1D6F8, 'M', 'χ'), + (0x1D6F9, 'M', 'ψ'), + (0x1D6FA, 'M', 'ω'), + (0x1D6FB, 'M', '∇'), + (0x1D6FC, 'M', 'α'), + (0x1D6FD, 'M', 'β'), + (0x1D6FE, 'M', 'γ'), + (0x1D6FF, 'M', 'δ'), + (0x1D700, 'M', 'ε'), + (0x1D701, 'M', 'ζ'), + (0x1D702, 'M', 'η'), + (0x1D703, 'M', 'θ'), + (0x1D704, 'M', 'ι'), + (0x1D705, 'M', 'κ'), + (0x1D706, 'M', 'λ'), + (0x1D707, 'M', 'μ'), + (0x1D708, 'M', 'ν'), + (0x1D709, 'M', 'ξ'), + (0x1D70A, 'M', 'ο'), + (0x1D70B, 'M', 'π'), + (0x1D70C, 'M', 'ρ'), + (0x1D70D, 'M', 'σ'), + (0x1D70F, 'M', 'τ'), + (0x1D710, 'M', 'υ'), + (0x1D711, 'M', 'φ'), + (0x1D712, 'M', 'χ'), + (0x1D713, 'M', 'ψ'), + (0x1D714, 'M', 'ω'), + (0x1D715, 'M', '∂'), + (0x1D716, 'M', 'ε'), + (0x1D717, 'M', 'θ'), + (0x1D718, 'M', 'κ'), + (0x1D719, 'M', 'φ'), + (0x1D71A, 'M', 'ρ'), + (0x1D71B, 'M', 'π'), + (0x1D71C, 'M', 'α'), + (0x1D71D, 'M', 'β'), + (0x1D71E, 'M', 'γ'), + (0x1D71F, 'M', 'δ'), + (0x1D720, 'M', 'ε'), + (0x1D721, 'M', 'ζ'), + (0x1D722, 'M', 'η'), + (0x1D723, 'M', 'θ'), + (0x1D724, 'M', 'ι'), + (0x1D725, 'M', 'κ'), + (0x1D726, 'M', 'λ'), + (0x1D727, 'M', 'μ'), + (0x1D728, 'M', 'ν'), + (0x1D729, 'M', 'ξ'), + (0x1D72A, 'M', 'ο'), + (0x1D72B, 'M', 'π'), + (0x1D72C, 'M', 'ρ'), + (0x1D72D, 'M', 'θ'), + (0x1D72E, 'M', 'σ'), + (0x1D72F, 'M', 'τ'), + (0x1D730, 'M', 'υ'), + (0x1D731, 'M', 'φ'), + (0x1D732, 'M', 'χ'), + (0x1D733, 'M', 'ψ'), + (0x1D734, 'M', 'ω'), + (0x1D735, 'M', '∇'), + (0x1D736, 'M', 'α'), + (0x1D737, 'M', 'β'), + (0x1D738, 'M', 'γ'), + (0x1D739, 'M', 'δ'), + (0x1D73A, 'M', 'ε'), + (0x1D73B, 'M', 'ζ'), + (0x1D73C, 'M', 'η'), + (0x1D73D, 'M', 'θ'), + (0x1D73E, 'M', 'ι'), + (0x1D73F, 'M', 'κ'), + (0x1D740, 'M', 'λ'), + (0x1D741, 'M', 'μ'), + (0x1D742, 'M', 'ν'), + (0x1D743, 'M', 'ξ'), + (0x1D744, 'M', 'ο'), + (0x1D745, 'M', 'π'), + (0x1D746, 'M', 'ρ'), + (0x1D747, 'M', 'σ'), + (0x1D749, 'M', 'τ'), + (0x1D74A, 'M', 'υ'), + ] + +def _seg_69() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D74B, 'M', 'φ'), + (0x1D74C, 'M', 'χ'), + (0x1D74D, 'M', 'ψ'), + (0x1D74E, 'M', 'ω'), + (0x1D74F, 'M', '∂'), + (0x1D750, 'M', 'ε'), + (0x1D751, 'M', 'θ'), + (0x1D752, 'M', 'κ'), + (0x1D753, 'M', 'φ'), + (0x1D754, 'M', 'ρ'), + (0x1D755, 'M', 'π'), + (0x1D756, 'M', 'α'), + (0x1D757, 'M', 'β'), + (0x1D758, 'M', 'γ'), + (0x1D759, 'M', 'δ'), + (0x1D75A, 'M', 'ε'), + (0x1D75B, 'M', 'ζ'), + (0x1D75C, 'M', 'η'), + (0x1D75D, 'M', 'θ'), + (0x1D75E, 'M', 'ι'), + (0x1D75F, 'M', 'κ'), + (0x1D760, 'M', 'λ'), + (0x1D761, 'M', 'μ'), + (0x1D762, 'M', 'ν'), + (0x1D763, 'M', 'ξ'), + (0x1D764, 'M', 'ο'), + (0x1D765, 'M', 'π'), + (0x1D766, 'M', 'ρ'), + (0x1D767, 'M', 'θ'), + (0x1D768, 'M', 'σ'), + (0x1D769, 'M', 'τ'), + (0x1D76A, 'M', 'υ'), + (0x1D76B, 'M', 'φ'), + (0x1D76C, 'M', 'χ'), + (0x1D76D, 'M', 'ψ'), + (0x1D76E, 'M', 'ω'), + (0x1D76F, 'M', '∇'), + (0x1D770, 'M', 'α'), + (0x1D771, 'M', 'β'), + (0x1D772, 'M', 'γ'), + (0x1D773, 'M', 'δ'), + (0x1D774, 'M', 'ε'), + (0x1D775, 'M', 'ζ'), + (0x1D776, 'M', 'η'), + (0x1D777, 'M', 'θ'), + (0x1D778, 'M', 'ι'), + (0x1D779, 'M', 'κ'), + (0x1D77A, 'M', 'λ'), + (0x1D77B, 'M', 'μ'), + (0x1D77C, 'M', 'ν'), + (0x1D77D, 'M', 'ξ'), + (0x1D77E, 'M', 'ο'), + (0x1D77F, 'M', 'π'), + (0x1D780, 'M', 'ρ'), + (0x1D781, 'M', 'σ'), + (0x1D783, 'M', 'τ'), + (0x1D784, 'M', 'υ'), + (0x1D785, 'M', 'φ'), + (0x1D786, 'M', 'χ'), + (0x1D787, 'M', 'ψ'), + (0x1D788, 'M', 'ω'), + (0x1D789, 'M', '∂'), + (0x1D78A, 'M', 'ε'), + (0x1D78B, 'M', 'θ'), + (0x1D78C, 'M', 'κ'), + (0x1D78D, 'M', 'φ'), + (0x1D78E, 'M', 'ρ'), + (0x1D78F, 'M', 'π'), + (0x1D790, 'M', 'α'), + (0x1D791, 'M', 'β'), + (0x1D792, 'M', 'γ'), + (0x1D793, 'M', 'δ'), + (0x1D794, 'M', 'ε'), + (0x1D795, 'M', 'ζ'), + (0x1D796, 'M', 'η'), + (0x1D797, 'M', 'θ'), + (0x1D798, 'M', 'ι'), + (0x1D799, 'M', 'κ'), + (0x1D79A, 'M', 'λ'), + (0x1D79B, 'M', 'μ'), + (0x1D79C, 'M', 'ν'), + (0x1D79D, 'M', 'ξ'), + (0x1D79E, 'M', 'ο'), + (0x1D79F, 'M', 'π'), + (0x1D7A0, 'M', 'ρ'), + (0x1D7A1, 'M', 'θ'), + (0x1D7A2, 'M', 'σ'), + (0x1D7A3, 'M', 'τ'), + (0x1D7A4, 'M', 'υ'), + (0x1D7A5, 'M', 'φ'), + (0x1D7A6, 'M', 'χ'), + (0x1D7A7, 'M', 'ψ'), + (0x1D7A8, 'M', 'ω'), + (0x1D7A9, 'M', '∇'), + (0x1D7AA, 'M', 'α'), + (0x1D7AB, 'M', 'β'), + (0x1D7AC, 'M', 'γ'), + (0x1D7AD, 'M', 'δ'), + (0x1D7AE, 'M', 'ε'), + (0x1D7AF, 'M', 'ζ'), + ] + +def _seg_70() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D7B0, 'M', 'η'), + (0x1D7B1, 'M', 'θ'), + (0x1D7B2, 'M', 'ι'), + (0x1D7B3, 'M', 'κ'), + (0x1D7B4, 'M', 'λ'), + (0x1D7B5, 'M', 'μ'), + (0x1D7B6, 'M', 'ν'), + (0x1D7B7, 'M', 'ξ'), + (0x1D7B8, 'M', 'ο'), + (0x1D7B9, 'M', 'π'), + (0x1D7BA, 'M', 'ρ'), + (0x1D7BB, 'M', 'σ'), + (0x1D7BD, 'M', 'τ'), + (0x1D7BE, 'M', 'υ'), + (0x1D7BF, 'M', 'φ'), + (0x1D7C0, 'M', 'χ'), + (0x1D7C1, 'M', 'ψ'), + (0x1D7C2, 'M', 'ω'), + (0x1D7C3, 'M', '∂'), + (0x1D7C4, 'M', 'ε'), + (0x1D7C5, 'M', 'θ'), + (0x1D7C6, 'M', 'κ'), + (0x1D7C7, 'M', 'φ'), + (0x1D7C8, 'M', 'ρ'), + (0x1D7C9, 'M', 'π'), + (0x1D7CA, 'M', 'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', '0'), + (0x1D7CF, 'M', '1'), + (0x1D7D0, 'M', '2'), + (0x1D7D1, 'M', '3'), + (0x1D7D2, 'M', '4'), + (0x1D7D3, 'M', '5'), + (0x1D7D4, 'M', '6'), + (0x1D7D5, 'M', '7'), + (0x1D7D6, 'M', '8'), + (0x1D7D7, 'M', '9'), + (0x1D7D8, 'M', '0'), + (0x1D7D9, 'M', '1'), + (0x1D7DA, 'M', '2'), + (0x1D7DB, 'M', '3'), + (0x1D7DC, 'M', '4'), + (0x1D7DD, 'M', '5'), + (0x1D7DE, 'M', '6'), + (0x1D7DF, 'M', '7'), + (0x1D7E0, 'M', '8'), + (0x1D7E1, 'M', '9'), + (0x1D7E2, 'M', '0'), + (0x1D7E3, 'M', '1'), + (0x1D7E4, 'M', '2'), + (0x1D7E5, 'M', '3'), + (0x1D7E6, 'M', '4'), + (0x1D7E7, 'M', '5'), + (0x1D7E8, 'M', '6'), + (0x1D7E9, 'M', '7'), + (0x1D7EA, 'M', '8'), + (0x1D7EB, 'M', '9'), + (0x1D7EC, 'M', '0'), + (0x1D7ED, 'M', '1'), + (0x1D7EE, 'M', '2'), + (0x1D7EF, 'M', '3'), + (0x1D7F0, 'M', '4'), + (0x1D7F1, 'M', '5'), + (0x1D7F2, 'M', '6'), + (0x1D7F3, 'M', '7'), + (0x1D7F4, 'M', '8'), + (0x1D7F5, 'M', '9'), + (0x1D7F6, 'M', '0'), + (0x1D7F7, 'M', '1'), + (0x1D7F8, 'M', '2'), + (0x1D7F9, 'M', '3'), + (0x1D7FA, 'M', '4'), + (0x1D7FB, 'M', '5'), + (0x1D7FC, 'M', '6'), + (0x1D7FD, 'M', '7'), + (0x1D7FE, 'M', '8'), + (0x1D7FF, 'M', '9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1DF00, 'V'), + (0x1DF1F, 'X'), + (0x1DF25, 'V'), + (0x1DF2B, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E030, 'M', 'а'), + (0x1E031, 'M', 'б'), + (0x1E032, 'M', 'в'), + ] + +def _seg_71() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E033, 'M', 'г'), + (0x1E034, 'M', 'д'), + (0x1E035, 'M', 'е'), + (0x1E036, 'M', 'ж'), + (0x1E037, 'M', 'з'), + (0x1E038, 'M', 'и'), + (0x1E039, 'M', 'к'), + (0x1E03A, 'M', 'л'), + (0x1E03B, 'M', 'м'), + (0x1E03C, 'M', 'о'), + (0x1E03D, 'M', 'п'), + (0x1E03E, 'M', 'р'), + (0x1E03F, 'M', 'с'), + (0x1E040, 'M', 'т'), + (0x1E041, 'M', 'у'), + (0x1E042, 'M', 'ф'), + (0x1E043, 'M', 'х'), + (0x1E044, 'M', 'ц'), + (0x1E045, 'M', 'ч'), + (0x1E046, 'M', 'ш'), + (0x1E047, 'M', 'ы'), + (0x1E048, 'M', 'э'), + (0x1E049, 'M', 'ю'), + (0x1E04A, 'M', 'ꚉ'), + (0x1E04B, 'M', 'ә'), + (0x1E04C, 'M', 'і'), + (0x1E04D, 'M', 'ј'), + (0x1E04E, 'M', 'ө'), + (0x1E04F, 'M', 'ү'), + (0x1E050, 'M', 'ӏ'), + (0x1E051, 'M', 'а'), + (0x1E052, 'M', 'б'), + (0x1E053, 'M', 'в'), + (0x1E054, 'M', 'г'), + (0x1E055, 'M', 'д'), + (0x1E056, 'M', 'е'), + (0x1E057, 'M', 'ж'), + (0x1E058, 'M', 'з'), + (0x1E059, 'M', 'и'), + (0x1E05A, 'M', 'к'), + (0x1E05B, 'M', 'л'), + (0x1E05C, 'M', 'о'), + (0x1E05D, 'M', 'п'), + (0x1E05E, 'M', 'с'), + (0x1E05F, 'M', 'у'), + (0x1E060, 'M', 'ф'), + (0x1E061, 'M', 'х'), + (0x1E062, 'M', 'ц'), + (0x1E063, 'M', 'ч'), + (0x1E064, 'M', 'ш'), + (0x1E065, 'M', 'ъ'), + (0x1E066, 'M', 'ы'), + (0x1E067, 'M', 'ґ'), + (0x1E068, 'M', 'і'), + (0x1E069, 'M', 'ѕ'), + (0x1E06A, 'M', 'џ'), + (0x1E06B, 'M', 'ҫ'), + (0x1E06C, 'M', 'ꙑ'), + (0x1E06D, 'M', 'ұ'), + (0x1E06E, 'X'), + (0x1E08F, 'V'), + (0x1E090, 'X'), + (0x1E100, 'V'), + (0x1E12D, 'X'), + (0x1E130, 'V'), + (0x1E13E, 'X'), + (0x1E140, 'V'), + (0x1E14A, 'X'), + (0x1E14E, 'V'), + (0x1E150, 'X'), + (0x1E290, 'V'), + (0x1E2AF, 'X'), + (0x1E2C0, 'V'), + (0x1E2FA, 'X'), + (0x1E2FF, 'V'), + (0x1E300, 'X'), + (0x1E4D0, 'V'), + (0x1E4FA, 'X'), + (0x1E7E0, 'V'), + (0x1E7E7, 'X'), + (0x1E7E8, 'V'), + (0x1E7EC, 'X'), + (0x1E7ED, 'V'), + (0x1E7EF, 'X'), + (0x1E7F0, 'V'), + (0x1E7FF, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', '𞤢'), + (0x1E901, 'M', '𞤣'), + (0x1E902, 'M', '𞤤'), + (0x1E903, 'M', '𞤥'), + (0x1E904, 'M', '𞤦'), + (0x1E905, 'M', '𞤧'), + (0x1E906, 'M', '𞤨'), + (0x1E907, 'M', '𞤩'), + (0x1E908, 'M', '𞤪'), + (0x1E909, 'M', '𞤫'), + ] + +def _seg_72() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E90A, 'M', '𞤬'), + (0x1E90B, 'M', '𞤭'), + (0x1E90C, 'M', '𞤮'), + (0x1E90D, 'M', '𞤯'), + (0x1E90E, 'M', '𞤰'), + (0x1E90F, 'M', '𞤱'), + (0x1E910, 'M', '𞤲'), + (0x1E911, 'M', '𞤳'), + (0x1E912, 'M', '𞤴'), + (0x1E913, 'M', '𞤵'), + (0x1E914, 'M', '𞤶'), + (0x1E915, 'M', '𞤷'), + (0x1E916, 'M', '𞤸'), + (0x1E917, 'M', '𞤹'), + (0x1E918, 'M', '𞤺'), + (0x1E919, 'M', '𞤻'), + (0x1E91A, 'M', '𞤼'), + (0x1E91B, 'M', '𞤽'), + (0x1E91C, 'M', '𞤾'), + (0x1E91D, 'M', '𞤿'), + (0x1E91E, 'M', '𞥀'), + (0x1E91F, 'M', '𞥁'), + (0x1E920, 'M', '𞥂'), + (0x1E921, 'M', '𞥃'), + (0x1E922, 'V'), + (0x1E94C, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + (0x1EC71, 'V'), + (0x1ECB5, 'X'), + (0x1ED01, 'V'), + (0x1ED3E, 'X'), + (0x1EE00, 'M', 'ا'), + (0x1EE01, 'M', 'ب'), + (0x1EE02, 'M', 'ج'), + (0x1EE03, 'M', 'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', 'و'), + (0x1EE06, 'M', 'ز'), + (0x1EE07, 'M', 'ح'), + (0x1EE08, 'M', 'ط'), + (0x1EE09, 'M', 'ي'), + (0x1EE0A, 'M', 'ك'), + (0x1EE0B, 'M', 'ل'), + (0x1EE0C, 'M', 'م'), + (0x1EE0D, 'M', 'ن'), + (0x1EE0E, 'M', 'س'), + (0x1EE0F, 'M', 'ع'), + (0x1EE10, 'M', 'ف'), + (0x1EE11, 'M', 'ص'), + (0x1EE12, 'M', 'ق'), + (0x1EE13, 'M', 'ر'), + (0x1EE14, 'M', 'ش'), + (0x1EE15, 'M', 'ت'), + (0x1EE16, 'M', 'ث'), + (0x1EE17, 'M', 'خ'), + (0x1EE18, 'M', 'ذ'), + (0x1EE19, 'M', 'ض'), + (0x1EE1A, 'M', 'ظ'), + (0x1EE1B, 'M', 'غ'), + (0x1EE1C, 'M', 'ٮ'), + (0x1EE1D, 'M', 'ں'), + (0x1EE1E, 'M', 'ڡ'), + (0x1EE1F, 'M', 'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', 'ب'), + (0x1EE22, 'M', 'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', 'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', 'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', 'ي'), + (0x1EE2A, 'M', 'ك'), + (0x1EE2B, 'M', 'ل'), + (0x1EE2C, 'M', 'م'), + (0x1EE2D, 'M', 'ن'), + (0x1EE2E, 'M', 'س'), + (0x1EE2F, 'M', 'ع'), + (0x1EE30, 'M', 'ف'), + (0x1EE31, 'M', 'ص'), + (0x1EE32, 'M', 'ق'), + (0x1EE33, 'X'), + (0x1EE34, 'M', 'ش'), + (0x1EE35, 'M', 'ت'), + (0x1EE36, 'M', 'ث'), + (0x1EE37, 'M', 'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', 'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', 'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', 'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', 'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', 'ي'), + (0x1EE4A, 'X'), + ] + +def _seg_73() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EE4B, 'M', 'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', 'ن'), + (0x1EE4E, 'M', 'س'), + (0x1EE4F, 'M', 'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', 'ص'), + (0x1EE52, 'M', 'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', 'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', 'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', 'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', 'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', 'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', 'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', 'ب'), + (0x1EE62, 'M', 'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', 'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', 'ح'), + (0x1EE68, 'M', 'ط'), + (0x1EE69, 'M', 'ي'), + (0x1EE6A, 'M', 'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', 'م'), + (0x1EE6D, 'M', 'ن'), + (0x1EE6E, 'M', 'س'), + (0x1EE6F, 'M', 'ع'), + (0x1EE70, 'M', 'ف'), + (0x1EE71, 'M', 'ص'), + (0x1EE72, 'M', 'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', 'ش'), + (0x1EE75, 'M', 'ت'), + (0x1EE76, 'M', 'ث'), + (0x1EE77, 'M', 'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', 'ض'), + (0x1EE7A, 'M', 'ظ'), + (0x1EE7B, 'M', 'غ'), + (0x1EE7C, 'M', 'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', 'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', 'ا'), + (0x1EE81, 'M', 'ب'), + (0x1EE82, 'M', 'ج'), + (0x1EE83, 'M', 'د'), + (0x1EE84, 'M', 'ه'), + (0x1EE85, 'M', 'و'), + (0x1EE86, 'M', 'ز'), + (0x1EE87, 'M', 'ح'), + (0x1EE88, 'M', 'ط'), + (0x1EE89, 'M', 'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', 'ل'), + (0x1EE8C, 'M', 'م'), + (0x1EE8D, 'M', 'ن'), + (0x1EE8E, 'M', 'س'), + (0x1EE8F, 'M', 'ع'), + (0x1EE90, 'M', 'ف'), + (0x1EE91, 'M', 'ص'), + (0x1EE92, 'M', 'ق'), + (0x1EE93, 'M', 'ر'), + (0x1EE94, 'M', 'ش'), + (0x1EE95, 'M', 'ت'), + (0x1EE96, 'M', 'ث'), + (0x1EE97, 'M', 'خ'), + (0x1EE98, 'M', 'ذ'), + (0x1EE99, 'M', 'ض'), + (0x1EE9A, 'M', 'ظ'), + (0x1EE9B, 'M', 'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', 'ب'), + (0x1EEA2, 'M', 'ج'), + (0x1EEA3, 'M', 'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', 'و'), + (0x1EEA6, 'M', 'ز'), + (0x1EEA7, 'M', 'ح'), + (0x1EEA8, 'M', 'ط'), + (0x1EEA9, 'M', 'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', 'ل'), + (0x1EEAC, 'M', 'م'), + (0x1EEAD, 'M', 'ن'), + (0x1EEAE, 'M', 'س'), + (0x1EEAF, 'M', 'ع'), + (0x1EEB0, 'M', 'ف'), + (0x1EEB1, 'M', 'ص'), + (0x1EEB2, 'M', 'ق'), + (0x1EEB3, 'M', 'ر'), + (0x1EEB4, 'M', 'ش'), + ] + +def _seg_74() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EEB5, 'M', 'ت'), + (0x1EEB6, 'M', 'ث'), + (0x1EEB7, 'M', 'خ'), + (0x1EEB8, 'M', 'ذ'), + (0x1EEB9, 'M', 'ض'), + (0x1EEBA, 'M', 'ظ'), + (0x1EEBB, 'M', 'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0C0, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0F6, 'X'), + (0x1F101, '3', '0,'), + (0x1F102, '3', '1,'), + (0x1F103, '3', '2,'), + (0x1F104, '3', '3,'), + (0x1F105, '3', '4,'), + (0x1F106, '3', '5,'), + (0x1F107, '3', '6,'), + (0x1F108, '3', '7,'), + (0x1F109, '3', '8,'), + (0x1F10A, '3', '9,'), + (0x1F10B, 'V'), + (0x1F110, '3', '(a)'), + (0x1F111, '3', '(b)'), + (0x1F112, '3', '(c)'), + (0x1F113, '3', '(d)'), + (0x1F114, '3', '(e)'), + (0x1F115, '3', '(f)'), + (0x1F116, '3', '(g)'), + (0x1F117, '3', '(h)'), + (0x1F118, '3', '(i)'), + (0x1F119, '3', '(j)'), + (0x1F11A, '3', '(k)'), + (0x1F11B, '3', '(l)'), + (0x1F11C, '3', '(m)'), + (0x1F11D, '3', '(n)'), + (0x1F11E, '3', '(o)'), + (0x1F11F, '3', '(p)'), + (0x1F120, '3', '(q)'), + (0x1F121, '3', '(r)'), + (0x1F122, '3', '(s)'), + (0x1F123, '3', '(t)'), + (0x1F124, '3', '(u)'), + (0x1F125, '3', '(v)'), + (0x1F126, '3', '(w)'), + (0x1F127, '3', '(x)'), + (0x1F128, '3', '(y)'), + (0x1F129, '3', '(z)'), + (0x1F12A, 'M', '〔s〕'), + (0x1F12B, 'M', 'c'), + (0x1F12C, 'M', 'r'), + (0x1F12D, 'M', 'cd'), + (0x1F12E, 'M', 'wz'), + (0x1F12F, 'V'), + (0x1F130, 'M', 'a'), + (0x1F131, 'M', 'b'), + (0x1F132, 'M', 'c'), + (0x1F133, 'M', 'd'), + (0x1F134, 'M', 'e'), + (0x1F135, 'M', 'f'), + (0x1F136, 'M', 'g'), + (0x1F137, 'M', 'h'), + (0x1F138, 'M', 'i'), + (0x1F139, 'M', 'j'), + (0x1F13A, 'M', 'k'), + (0x1F13B, 'M', 'l'), + (0x1F13C, 'M', 'm'), + (0x1F13D, 'M', 'n'), + (0x1F13E, 'M', 'o'), + (0x1F13F, 'M', 'p'), + (0x1F140, 'M', 'q'), + (0x1F141, 'M', 'r'), + (0x1F142, 'M', 's'), + (0x1F143, 'M', 't'), + (0x1F144, 'M', 'u'), + (0x1F145, 'M', 'v'), + (0x1F146, 'M', 'w'), + (0x1F147, 'M', 'x'), + (0x1F148, 'M', 'y'), + (0x1F149, 'M', 'z'), + (0x1F14A, 'M', 'hv'), + (0x1F14B, 'M', 'mv'), + (0x1F14C, 'M', 'sd'), + (0x1F14D, 'M', 'ss'), + (0x1F14E, 'M', 'ppv'), + (0x1F14F, 'M', 'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', 'mc'), + (0x1F16B, 'M', 'md'), + ] + +def _seg_75() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F16C, 'M', 'mr'), + (0x1F16D, 'V'), + (0x1F190, 'M', 'dj'), + (0x1F191, 'V'), + (0x1F1AE, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', 'ほか'), + (0x1F201, 'M', 'ココ'), + (0x1F202, 'M', 'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', '手'), + (0x1F211, 'M', '字'), + (0x1F212, 'M', '双'), + (0x1F213, 'M', 'デ'), + (0x1F214, 'M', '二'), + (0x1F215, 'M', '多'), + (0x1F216, 'M', '解'), + (0x1F217, 'M', '天'), + (0x1F218, 'M', '交'), + (0x1F219, 'M', '映'), + (0x1F21A, 'M', '無'), + (0x1F21B, 'M', '料'), + (0x1F21C, 'M', '前'), + (0x1F21D, 'M', '後'), + (0x1F21E, 'M', '再'), + (0x1F21F, 'M', '新'), + (0x1F220, 'M', '初'), + (0x1F221, 'M', '終'), + (0x1F222, 'M', '生'), + (0x1F223, 'M', '販'), + (0x1F224, 'M', '声'), + (0x1F225, 'M', '吹'), + (0x1F226, 'M', '演'), + (0x1F227, 'M', '投'), + (0x1F228, 'M', '捕'), + (0x1F229, 'M', '一'), + (0x1F22A, 'M', '三'), + (0x1F22B, 'M', '遊'), + (0x1F22C, 'M', '左'), + (0x1F22D, 'M', '中'), + (0x1F22E, 'M', '右'), + (0x1F22F, 'M', '指'), + (0x1F230, 'M', '走'), + (0x1F231, 'M', '打'), + (0x1F232, 'M', '禁'), + (0x1F233, 'M', '空'), + (0x1F234, 'M', '合'), + (0x1F235, 'M', '満'), + (0x1F236, 'M', '有'), + (0x1F237, 'M', '月'), + (0x1F238, 'M', '申'), + (0x1F239, 'M', '割'), + (0x1F23A, 'M', '営'), + (0x1F23B, 'M', '配'), + (0x1F23C, 'X'), + (0x1F240, 'M', '〔本〕'), + (0x1F241, 'M', '〔三〕'), + (0x1F242, 'M', '〔二〕'), + (0x1F243, 'M', '〔安〕'), + (0x1F244, 'M', '〔点〕'), + (0x1F245, 'M', '〔打〕'), + (0x1F246, 'M', '〔盗〕'), + (0x1F247, 'M', '〔勝〕'), + (0x1F248, 'M', '〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', '得'), + (0x1F251, 'M', '可'), + (0x1F252, 'X'), + (0x1F260, 'V'), + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D8, 'X'), + (0x1F6DC, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6FD, 'X'), + (0x1F700, 'V'), + (0x1F777, 'X'), + (0x1F77B, 'V'), + (0x1F7DA, 'X'), + (0x1F7E0, 'V'), + (0x1F7EC, 'X'), + (0x1F7F0, 'V'), + (0x1F7F1, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F8B0, 'V'), + (0x1F8B2, 'X'), + (0x1F900, 'V'), + (0x1FA54, 'X'), + (0x1FA60, 'V'), + (0x1FA6E, 'X'), + ] + +def _seg_76() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FA70, 'V'), + (0x1FA7D, 'X'), + (0x1FA80, 'V'), + (0x1FA89, 'X'), + (0x1FA90, 'V'), + (0x1FABE, 'X'), + (0x1FABF, 'V'), + (0x1FAC6, 'X'), + (0x1FACE, 'V'), + (0x1FADC, 'X'), + (0x1FAE0, 'V'), + (0x1FAE9, 'X'), + (0x1FAF0, 'V'), + (0x1FAF9, 'X'), + (0x1FB00, 'V'), + (0x1FB93, 'X'), + (0x1FB94, 'V'), + (0x1FBCB, 'X'), + (0x1FBF0, 'M', '0'), + (0x1FBF1, 'M', '1'), + (0x1FBF2, 'M', '2'), + (0x1FBF3, 'M', '3'), + (0x1FBF4, 'M', '4'), + (0x1FBF5, 'M', '5'), + (0x1FBF6, 'M', '6'), + (0x1FBF7, 'M', '7'), + (0x1FBF8, 'M', '8'), + (0x1FBF9, 'M', '9'), + (0x1FBFA, 'X'), + (0x20000, 'V'), + (0x2A6E0, 'X'), + (0x2A700, 'V'), + (0x2B73A, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', '丽'), + (0x2F801, 'M', '丸'), + (0x2F802, 'M', '乁'), + (0x2F803, 'M', '𠄢'), + (0x2F804, 'M', '你'), + (0x2F805, 'M', '侮'), + (0x2F806, 'M', '侻'), + (0x2F807, 'M', '倂'), + (0x2F808, 'M', '偺'), + (0x2F809, 'M', '備'), + (0x2F80A, 'M', '僧'), + (0x2F80B, 'M', '像'), + (0x2F80C, 'M', '㒞'), + (0x2F80D, 'M', '𠘺'), + (0x2F80E, 'M', '免'), + (0x2F80F, 'M', '兔'), + (0x2F810, 'M', '兤'), + (0x2F811, 'M', '具'), + (0x2F812, 'M', '𠔜'), + (0x2F813, 'M', '㒹'), + (0x2F814, 'M', '內'), + (0x2F815, 'M', '再'), + (0x2F816, 'M', '𠕋'), + (0x2F817, 'M', '冗'), + (0x2F818, 'M', '冤'), + (0x2F819, 'M', '仌'), + (0x2F81A, 'M', '冬'), + (0x2F81B, 'M', '况'), + (0x2F81C, 'M', '𩇟'), + (0x2F81D, 'M', '凵'), + (0x2F81E, 'M', '刃'), + (0x2F81F, 'M', '㓟'), + (0x2F820, 'M', '刻'), + (0x2F821, 'M', '剆'), + (0x2F822, 'M', '割'), + (0x2F823, 'M', '剷'), + (0x2F824, 'M', '㔕'), + (0x2F825, 'M', '勇'), + (0x2F826, 'M', '勉'), + (0x2F827, 'M', '勤'), + (0x2F828, 'M', '勺'), + (0x2F829, 'M', '包'), + (0x2F82A, 'M', '匆'), + (0x2F82B, 'M', '北'), + (0x2F82C, 'M', '卉'), + (0x2F82D, 'M', '卑'), + (0x2F82E, 'M', '博'), + (0x2F82F, 'M', '即'), + (0x2F830, 'M', '卽'), + (0x2F831, 'M', '卿'), + (0x2F834, 'M', '𠨬'), + (0x2F835, 'M', '灰'), + (0x2F836, 'M', '及'), + (0x2F837, 'M', '叟'), + (0x2F838, 'M', '𠭣'), + (0x2F839, 'M', '叫'), + (0x2F83A, 'M', '叱'), + (0x2F83B, 'M', '吆'), + (0x2F83C, 'M', '咞'), + (0x2F83D, 'M', '吸'), + (0x2F83E, 'M', '呈'), + ] + +def _seg_77() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F83F, 'M', '周'), + (0x2F840, 'M', '咢'), + (0x2F841, 'M', '哶'), + (0x2F842, 'M', '唐'), + (0x2F843, 'M', '啓'), + (0x2F844, 'M', '啣'), + (0x2F845, 'M', '善'), + (0x2F847, 'M', '喙'), + (0x2F848, 'M', '喫'), + (0x2F849, 'M', '喳'), + (0x2F84A, 'M', '嗂'), + (0x2F84B, 'M', '圖'), + (0x2F84C, 'M', '嘆'), + (0x2F84D, 'M', '圗'), + (0x2F84E, 'M', '噑'), + (0x2F84F, 'M', '噴'), + (0x2F850, 'M', '切'), + (0x2F851, 'M', '壮'), + (0x2F852, 'M', '城'), + (0x2F853, 'M', '埴'), + (0x2F854, 'M', '堍'), + (0x2F855, 'M', '型'), + (0x2F856, 'M', '堲'), + (0x2F857, 'M', '報'), + (0x2F858, 'M', '墬'), + (0x2F859, 'M', '𡓤'), + (0x2F85A, 'M', '売'), + (0x2F85B, 'M', '壷'), + (0x2F85C, 'M', '夆'), + (0x2F85D, 'M', '多'), + (0x2F85E, 'M', '夢'), + (0x2F85F, 'M', '奢'), + (0x2F860, 'M', '𡚨'), + (0x2F861, 'M', '𡛪'), + (0x2F862, 'M', '姬'), + (0x2F863, 'M', '娛'), + (0x2F864, 'M', '娧'), + (0x2F865, 'M', '姘'), + (0x2F866, 'M', '婦'), + (0x2F867, 'M', '㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', '嬈'), + (0x2F86A, 'M', '嬾'), + (0x2F86C, 'M', '𡧈'), + (0x2F86D, 'M', '寃'), + (0x2F86E, 'M', '寘'), + (0x2F86F, 'M', '寧'), + (0x2F870, 'M', '寳'), + (0x2F871, 'M', '𡬘'), + (0x2F872, 'M', '寿'), + (0x2F873, 'M', '将'), + (0x2F874, 'X'), + (0x2F875, 'M', '尢'), + (0x2F876, 'M', '㞁'), + (0x2F877, 'M', '屠'), + (0x2F878, 'M', '屮'), + (0x2F879, 'M', '峀'), + (0x2F87A, 'M', '岍'), + (0x2F87B, 'M', '𡷤'), + (0x2F87C, 'M', '嵃'), + (0x2F87D, 'M', '𡷦'), + (0x2F87E, 'M', '嵮'), + (0x2F87F, 'M', '嵫'), + (0x2F880, 'M', '嵼'), + (0x2F881, 'M', '巡'), + (0x2F882, 'M', '巢'), + (0x2F883, 'M', '㠯'), + (0x2F884, 'M', '巽'), + (0x2F885, 'M', '帨'), + (0x2F886, 'M', '帽'), + (0x2F887, 'M', '幩'), + (0x2F888, 'M', '㡢'), + (0x2F889, 'M', '𢆃'), + (0x2F88A, 'M', '㡼'), + (0x2F88B, 'M', '庰'), + (0x2F88C, 'M', '庳'), + (0x2F88D, 'M', '庶'), + (0x2F88E, 'M', '廊'), + (0x2F88F, 'M', '𪎒'), + (0x2F890, 'M', '廾'), + (0x2F891, 'M', '𢌱'), + (0x2F893, 'M', '舁'), + (0x2F894, 'M', '弢'), + (0x2F896, 'M', '㣇'), + (0x2F897, 'M', '𣊸'), + (0x2F898, 'M', '𦇚'), + (0x2F899, 'M', '形'), + (0x2F89A, 'M', '彫'), + (0x2F89B, 'M', '㣣'), + (0x2F89C, 'M', '徚'), + (0x2F89D, 'M', '忍'), + (0x2F89E, 'M', '志'), + (0x2F89F, 'M', '忹'), + (0x2F8A0, 'M', '悁'), + (0x2F8A1, 'M', '㤺'), + (0x2F8A2, 'M', '㤜'), + (0x2F8A3, 'M', '悔'), + (0x2F8A4, 'M', '𢛔'), + (0x2F8A5, 'M', '惇'), + (0x2F8A6, 'M', '慈'), + ] + +def _seg_78() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F8A7, 'M', '慌'), + (0x2F8A8, 'M', '慎'), + (0x2F8A9, 'M', '慌'), + (0x2F8AA, 'M', '慺'), + (0x2F8AB, 'M', '憎'), + (0x2F8AC, 'M', '憲'), + (0x2F8AD, 'M', '憤'), + (0x2F8AE, 'M', '憯'), + (0x2F8AF, 'M', '懞'), + (0x2F8B0, 'M', '懲'), + (0x2F8B1, 'M', '懶'), + (0x2F8B2, 'M', '成'), + (0x2F8B3, 'M', '戛'), + (0x2F8B4, 'M', '扝'), + (0x2F8B5, 'M', '抱'), + (0x2F8B6, 'M', '拔'), + (0x2F8B7, 'M', '捐'), + (0x2F8B8, 'M', '𢬌'), + (0x2F8B9, 'M', '挽'), + (0x2F8BA, 'M', '拼'), + (0x2F8BB, 'M', '捨'), + (0x2F8BC, 'M', '掃'), + (0x2F8BD, 'M', '揤'), + (0x2F8BE, 'M', '𢯱'), + (0x2F8BF, 'M', '搢'), + (0x2F8C0, 'M', '揅'), + (0x2F8C1, 'M', '掩'), + (0x2F8C2, 'M', '㨮'), + (0x2F8C3, 'M', '摩'), + (0x2F8C4, 'M', '摾'), + (0x2F8C5, 'M', '撝'), + (0x2F8C6, 'M', '摷'), + (0x2F8C7, 'M', '㩬'), + (0x2F8C8, 'M', '敏'), + (0x2F8C9, 'M', '敬'), + (0x2F8CA, 'M', '𣀊'), + (0x2F8CB, 'M', '旣'), + (0x2F8CC, 'M', '書'), + (0x2F8CD, 'M', '晉'), + (0x2F8CE, 'M', '㬙'), + (0x2F8CF, 'M', '暑'), + (0x2F8D0, 'M', '㬈'), + (0x2F8D1, 'M', '㫤'), + (0x2F8D2, 'M', '冒'), + (0x2F8D3, 'M', '冕'), + (0x2F8D4, 'M', '最'), + (0x2F8D5, 'M', '暜'), + (0x2F8D6, 'M', '肭'), + (0x2F8D7, 'M', '䏙'), + (0x2F8D8, 'M', '朗'), + (0x2F8D9, 'M', '望'), + (0x2F8DA, 'M', '朡'), + (0x2F8DB, 'M', '杞'), + (0x2F8DC, 'M', '杓'), + (0x2F8DD, 'M', '𣏃'), + (0x2F8DE, 'M', '㭉'), + (0x2F8DF, 'M', '柺'), + (0x2F8E0, 'M', '枅'), + (0x2F8E1, 'M', '桒'), + (0x2F8E2, 'M', '梅'), + (0x2F8E3, 'M', '𣑭'), + (0x2F8E4, 'M', '梎'), + (0x2F8E5, 'M', '栟'), + (0x2F8E6, 'M', '椔'), + (0x2F8E7, 'M', '㮝'), + (0x2F8E8, 'M', '楂'), + (0x2F8E9, 'M', '榣'), + (0x2F8EA, 'M', '槪'), + (0x2F8EB, 'M', '檨'), + (0x2F8EC, 'M', '𣚣'), + (0x2F8ED, 'M', '櫛'), + (0x2F8EE, 'M', '㰘'), + (0x2F8EF, 'M', '次'), + (0x2F8F0, 'M', '𣢧'), + (0x2F8F1, 'M', '歔'), + (0x2F8F2, 'M', '㱎'), + (0x2F8F3, 'M', '歲'), + (0x2F8F4, 'M', '殟'), + (0x2F8F5, 'M', '殺'), + (0x2F8F6, 'M', '殻'), + (0x2F8F7, 'M', '𣪍'), + (0x2F8F8, 'M', '𡴋'), + (0x2F8F9, 'M', '𣫺'), + (0x2F8FA, 'M', '汎'), + (0x2F8FB, 'M', '𣲼'), + (0x2F8FC, 'M', '沿'), + (0x2F8FD, 'M', '泍'), + (0x2F8FE, 'M', '汧'), + (0x2F8FF, 'M', '洖'), + (0x2F900, 'M', '派'), + (0x2F901, 'M', '海'), + (0x2F902, 'M', '流'), + (0x2F903, 'M', '浩'), + (0x2F904, 'M', '浸'), + (0x2F905, 'M', '涅'), + (0x2F906, 'M', '𣴞'), + (0x2F907, 'M', '洴'), + (0x2F908, 'M', '港'), + (0x2F909, 'M', '湮'), + (0x2F90A, 'M', '㴳'), + ] + +def _seg_79() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F90B, 'M', '滋'), + (0x2F90C, 'M', '滇'), + (0x2F90D, 'M', '𣻑'), + (0x2F90E, 'M', '淹'), + (0x2F90F, 'M', '潮'), + (0x2F910, 'M', '𣽞'), + (0x2F911, 'M', '𣾎'), + (0x2F912, 'M', '濆'), + (0x2F913, 'M', '瀹'), + (0x2F914, 'M', '瀞'), + (0x2F915, 'M', '瀛'), + (0x2F916, 'M', '㶖'), + (0x2F917, 'M', '灊'), + (0x2F918, 'M', '災'), + (0x2F919, 'M', '灷'), + (0x2F91A, 'M', '炭'), + (0x2F91B, 'M', '𠔥'), + (0x2F91C, 'M', '煅'), + (0x2F91D, 'M', '𤉣'), + (0x2F91E, 'M', '熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', '爨'), + (0x2F921, 'M', '爵'), + (0x2F922, 'M', '牐'), + (0x2F923, 'M', '𤘈'), + (0x2F924, 'M', '犀'), + (0x2F925, 'M', '犕'), + (0x2F926, 'M', '𤜵'), + (0x2F927, 'M', '𤠔'), + (0x2F928, 'M', '獺'), + (0x2F929, 'M', '王'), + (0x2F92A, 'M', '㺬'), + (0x2F92B, 'M', '玥'), + (0x2F92C, 'M', '㺸'), + (0x2F92E, 'M', '瑇'), + (0x2F92F, 'M', '瑜'), + (0x2F930, 'M', '瑱'), + (0x2F931, 'M', '璅'), + (0x2F932, 'M', '瓊'), + (0x2F933, 'M', '㼛'), + (0x2F934, 'M', '甤'), + (0x2F935, 'M', '𤰶'), + (0x2F936, 'M', '甾'), + (0x2F937, 'M', '𤲒'), + (0x2F938, 'M', '異'), + (0x2F939, 'M', '𢆟'), + (0x2F93A, 'M', '瘐'), + (0x2F93B, 'M', '𤾡'), + (0x2F93C, 'M', '𤾸'), + (0x2F93D, 'M', '𥁄'), + (0x2F93E, 'M', '㿼'), + (0x2F93F, 'M', '䀈'), + (0x2F940, 'M', '直'), + (0x2F941, 'M', '𥃳'), + (0x2F942, 'M', '𥃲'), + (0x2F943, 'M', '𥄙'), + (0x2F944, 'M', '𥄳'), + (0x2F945, 'M', '眞'), + (0x2F946, 'M', '真'), + (0x2F948, 'M', '睊'), + (0x2F949, 'M', '䀹'), + (0x2F94A, 'M', '瞋'), + (0x2F94B, 'M', '䁆'), + (0x2F94C, 'M', '䂖'), + (0x2F94D, 'M', '𥐝'), + (0x2F94E, 'M', '硎'), + (0x2F94F, 'M', '碌'), + (0x2F950, 'M', '磌'), + (0x2F951, 'M', '䃣'), + (0x2F952, 'M', '𥘦'), + (0x2F953, 'M', '祖'), + (0x2F954, 'M', '𥚚'), + (0x2F955, 'M', '𥛅'), + (0x2F956, 'M', '福'), + (0x2F957, 'M', '秫'), + (0x2F958, 'M', '䄯'), + (0x2F959, 'M', '穀'), + (0x2F95A, 'M', '穊'), + (0x2F95B, 'M', '穏'), + (0x2F95C, 'M', '𥥼'), + (0x2F95D, 'M', '𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', '䈂'), + (0x2F961, 'M', '𥮫'), + (0x2F962, 'M', '篆'), + (0x2F963, 'M', '築'), + (0x2F964, 'M', '䈧'), + (0x2F965, 'M', '𥲀'), + (0x2F966, 'M', '糒'), + (0x2F967, 'M', '䊠'), + (0x2F968, 'M', '糨'), + (0x2F969, 'M', '糣'), + (0x2F96A, 'M', '紀'), + (0x2F96B, 'M', '𥾆'), + (0x2F96C, 'M', '絣'), + (0x2F96D, 'M', '䌁'), + (0x2F96E, 'M', '緇'), + (0x2F96F, 'M', '縂'), + (0x2F970, 'M', '繅'), + (0x2F971, 'M', '䌴'), + ] + +def _seg_80() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F972, 'M', '𦈨'), + (0x2F973, 'M', '𦉇'), + (0x2F974, 'M', '䍙'), + (0x2F975, 'M', '𦋙'), + (0x2F976, 'M', '罺'), + (0x2F977, 'M', '𦌾'), + (0x2F978, 'M', '羕'), + (0x2F979, 'M', '翺'), + (0x2F97A, 'M', '者'), + (0x2F97B, 'M', '𦓚'), + (0x2F97C, 'M', '𦔣'), + (0x2F97D, 'M', '聠'), + (0x2F97E, 'M', '𦖨'), + (0x2F97F, 'M', '聰'), + (0x2F980, 'M', '𣍟'), + (0x2F981, 'M', '䏕'), + (0x2F982, 'M', '育'), + (0x2F983, 'M', '脃'), + (0x2F984, 'M', '䐋'), + (0x2F985, 'M', '脾'), + (0x2F986, 'M', '媵'), + (0x2F987, 'M', '𦞧'), + (0x2F988, 'M', '𦞵'), + (0x2F989, 'M', '𣎓'), + (0x2F98A, 'M', '𣎜'), + (0x2F98B, 'M', '舁'), + (0x2F98C, 'M', '舄'), + (0x2F98D, 'M', '辞'), + (0x2F98E, 'M', '䑫'), + (0x2F98F, 'M', '芑'), + (0x2F990, 'M', '芋'), + (0x2F991, 'M', '芝'), + (0x2F992, 'M', '劳'), + (0x2F993, 'M', '花'), + (0x2F994, 'M', '芳'), + (0x2F995, 'M', '芽'), + (0x2F996, 'M', '苦'), + (0x2F997, 'M', '𦬼'), + (0x2F998, 'M', '若'), + (0x2F999, 'M', '茝'), + (0x2F99A, 'M', '荣'), + (0x2F99B, 'M', '莭'), + (0x2F99C, 'M', '茣'), + (0x2F99D, 'M', '莽'), + (0x2F99E, 'M', '菧'), + (0x2F99F, 'M', '著'), + (0x2F9A0, 'M', '荓'), + (0x2F9A1, 'M', '菊'), + (0x2F9A2, 'M', '菌'), + (0x2F9A3, 'M', '菜'), + (0x2F9A4, 'M', '𦰶'), + (0x2F9A5, 'M', '𦵫'), + (0x2F9A6, 'M', '𦳕'), + (0x2F9A7, 'M', '䔫'), + (0x2F9A8, 'M', '蓱'), + (0x2F9A9, 'M', '蓳'), + (0x2F9AA, 'M', '蔖'), + (0x2F9AB, 'M', '𧏊'), + (0x2F9AC, 'M', '蕤'), + (0x2F9AD, 'M', '𦼬'), + (0x2F9AE, 'M', '䕝'), + (0x2F9AF, 'M', '䕡'), + (0x2F9B0, 'M', '𦾱'), + (0x2F9B1, 'M', '𧃒'), + (0x2F9B2, 'M', '䕫'), + (0x2F9B3, 'M', '虐'), + (0x2F9B4, 'M', '虜'), + (0x2F9B5, 'M', '虧'), + (0x2F9B6, 'M', '虩'), + (0x2F9B7, 'M', '蚩'), + (0x2F9B8, 'M', '蚈'), + (0x2F9B9, 'M', '蜎'), + (0x2F9BA, 'M', '蛢'), + (0x2F9BB, 'M', '蝹'), + (0x2F9BC, 'M', '蜨'), + (0x2F9BD, 'M', '蝫'), + (0x2F9BE, 'M', '螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', '蟡'), + (0x2F9C1, 'M', '蠁'), + (0x2F9C2, 'M', '䗹'), + (0x2F9C3, 'M', '衠'), + (0x2F9C4, 'M', '衣'), + (0x2F9C5, 'M', '𧙧'), + (0x2F9C6, 'M', '裗'), + (0x2F9C7, 'M', '裞'), + (0x2F9C8, 'M', '䘵'), + (0x2F9C9, 'M', '裺'), + (0x2F9CA, 'M', '㒻'), + (0x2F9CB, 'M', '𧢮'), + (0x2F9CC, 'M', '𧥦'), + (0x2F9CD, 'M', '䚾'), + (0x2F9CE, 'M', '䛇'), + (0x2F9CF, 'M', '誠'), + (0x2F9D0, 'M', '諭'), + (0x2F9D1, 'M', '變'), + (0x2F9D2, 'M', '豕'), + (0x2F9D3, 'M', '𧲨'), + (0x2F9D4, 'M', '貫'), + (0x2F9D5, 'M', '賁'), + ] + +def _seg_81() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F9D6, 'M', '贛'), + (0x2F9D7, 'M', '起'), + (0x2F9D8, 'M', '𧼯'), + (0x2F9D9, 'M', '𠠄'), + (0x2F9DA, 'M', '跋'), + (0x2F9DB, 'M', '趼'), + (0x2F9DC, 'M', '跰'), + (0x2F9DD, 'M', '𠣞'), + (0x2F9DE, 'M', '軔'), + (0x2F9DF, 'M', '輸'), + (0x2F9E0, 'M', '𨗒'), + (0x2F9E1, 'M', '𨗭'), + (0x2F9E2, 'M', '邔'), + (0x2F9E3, 'M', '郱'), + (0x2F9E4, 'M', '鄑'), + (0x2F9E5, 'M', '𨜮'), + (0x2F9E6, 'M', '鄛'), + (0x2F9E7, 'M', '鈸'), + (0x2F9E8, 'M', '鋗'), + (0x2F9E9, 'M', '鋘'), + (0x2F9EA, 'M', '鉼'), + (0x2F9EB, 'M', '鏹'), + (0x2F9EC, 'M', '鐕'), + (0x2F9ED, 'M', '𨯺'), + (0x2F9EE, 'M', '開'), + (0x2F9EF, 'M', '䦕'), + (0x2F9F0, 'M', '閷'), + (0x2F9F1, 'M', '𨵷'), + (0x2F9F2, 'M', '䧦'), + (0x2F9F3, 'M', '雃'), + (0x2F9F4, 'M', '嶲'), + (0x2F9F5, 'M', '霣'), + (0x2F9F6, 'M', '𩅅'), + (0x2F9F7, 'M', '𩈚'), + (0x2F9F8, 'M', '䩮'), + (0x2F9F9, 'M', '䩶'), + (0x2F9FA, 'M', '韠'), + (0x2F9FB, 'M', '𩐊'), + (0x2F9FC, 'M', '䪲'), + (0x2F9FD, 'M', '𩒖'), + (0x2F9FE, 'M', '頋'), + (0x2FA00, 'M', '頩'), + (0x2FA01, 'M', '𩖶'), + (0x2FA02, 'M', '飢'), + (0x2FA03, 'M', '䬳'), + (0x2FA04, 'M', '餩'), + (0x2FA05, 'M', '馧'), + (0x2FA06, 'M', '駂'), + (0x2FA07, 'M', '駾'), + (0x2FA08, 'M', '䯎'), + (0x2FA09, 'M', '𩬰'), + (0x2FA0A, 'M', '鬒'), + (0x2FA0B, 'M', '鱀'), + (0x2FA0C, 'M', '鳽'), + (0x2FA0D, 'M', '䳎'), + (0x2FA0E, 'M', '䳭'), + (0x2FA0F, 'M', '鵧'), + (0x2FA10, 'M', '𪃎'), + (0x2FA11, 'M', '䳸'), + (0x2FA12, 'M', '𪄅'), + (0x2FA13, 'M', '𪈎'), + (0x2FA14, 'M', '𪊑'), + (0x2FA15, 'M', '麻'), + (0x2FA16, 'M', '䵖'), + (0x2FA17, 'M', '黹'), + (0x2FA18, 'M', '黾'), + (0x2FA19, 'M', '鼅'), + (0x2FA1A, 'M', '鼏'), + (0x2FA1B, 'M', '鼖'), + (0x2FA1C, 'M', '鼻'), + (0x2FA1D, 'M', '𪘀'), + (0x2FA1E, 'X'), + (0x30000, 'V'), + (0x3134B, 'X'), + (0x31350, 'V'), + (0x323B0, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() + + _seg_78() + + _seg_79() + + _seg_80() + + _seg_81() +) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/LICENSE b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/METADATA new file mode 100644 index 0000000..639bbea --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/METADATA @@ -0,0 +1,138 @@ +Metadata-Version: 2.1 +Name: importlib-metadata +Version: 6.8.0 +Summary: Read metadata from Python packages +Home-page: https://github.com/python/importlib_metadata +Author: Jason R. Coombs +Author-email: jaraco@jaraco.com +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.8 +License-File: LICENSE +Requires-Dist: zipp (>=0.5) +Requires-Dist: typing-extensions (>=3.6.4) ; python_version < "3.8" +Provides-Extra: docs +Requires-Dist: sphinx (>=3.5) ; extra == 'docs' +Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs' +Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' +Requires-Dist: furo ; extra == 'docs' +Requires-Dist: sphinx-lint ; extra == 'docs' +Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs' +Provides-Extra: perf +Requires-Dist: ipython ; extra == 'perf' +Provides-Extra: testing +Requires-Dist: pytest (>=6) ; extra == 'testing' +Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing' +Requires-Dist: pytest-cov ; extra == 'testing' +Requires-Dist: pytest-enabler (>=2.2) ; extra == 'testing' +Requires-Dist: pytest-ruff ; extra == 'testing' +Requires-Dist: packaging ; extra == 'testing' +Requires-Dist: pyfakefs ; extra == 'testing' +Requires-Dist: flufl.flake8 ; extra == 'testing' +Requires-Dist: pytest-perf (>=0.9.2) ; extra == 'testing' +Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: importlib-resources (>=1.3) ; (python_version < "3.9") and extra == 'testing' + +.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg + :target: https://pypi.org/project/importlib_metadata + +.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg + +.. image:: https://github.com/python/importlib_metadata/workflows/tests/badge.svg + :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json + :target: https://github.com/astral-sh/ruff + :alt: Ruff + +.. 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/importlib-metadata/badge/?version=latest + :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2023-informational + :target: https://blog.jaraco.com/skeleton + +.. image:: https://tidelift.com/badges/package/pypi/importlib-metadata + :target: https://tidelift.com/subscription/pkg/pypi-importlib-metadata?utm_source=pypi-importlib-metadata&utm_medium=readme + +Library to access the metadata for a Python package. + +This package supplies third-party access to the functionality of +`importlib.metadata `_ +including improvements added to subsequent Python versions. + + +Compatibility +============= + +New features are introduced in this third-party library and later merged +into CPython. The following table indicates which versions of this library +were contributed to different versions in the standard library: + +.. list-table:: + :header-rows: 1 + + * - importlib_metadata + - stdlib + * - 6.5 + - 3.12 + * - 4.13 + - 3.11 + * - 4.6 + - 3.10 + * - 1.4 + - 3.8 + + +Usage +===== + +See the `online documentation `_ +for usage details. + +`Finder authors +`_ can +also add support for custom package installers. See the above documentation +for details. + + +Caveats +======= + +This project primarily supports third-party packages installed by PyPA +tools (or other conforming packages). It does not support: + +- Packages in the stdlib. +- Packages installed without metadata. + +Project details +=============== + + * Project home: https://github.com/python/importlib_metadata + * Report bugs at: https://github.com/python/importlib_metadata/issues + * Code hosting: https://github.com/python/importlib_metadata + * Documentation: https://importlib-metadata.readthedocs.io/ + +For Enterprise +============== + +Available as part of the Tidelift Subscription. + +This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. + +`Learn more `_. + +Security Contact +================ + +To report a security vulnerability, please use the +`Tidelift security contact `_. +Tidelift will coordinate the fix and disclosure. diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/RECORD new file mode 100644 index 0000000..aa20ad5 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/RECORD @@ -0,0 +1,25 @@ +importlib_metadata-6.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +importlib_metadata-6.8.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 +importlib_metadata-6.8.0.dist-info/METADATA,sha256=X79qGRh7gqvuaL_utK5X-MnwHJuIWke0e3eAx0IiLhc,5067 +importlib_metadata-6.8.0.dist-info/RECORD,, +importlib_metadata-6.8.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92 +importlib_metadata-6.8.0.dist-info/top_level.txt,sha256=CO3fD9yylANiXkrMo4qHLV_mqXL2sC5JFKgt1yWAT-A,19 +importlib_metadata/__init__.py,sha256=EiH0qTKP_6oa6pRGJgPrq0kvjnL3hJ18BJH8VaAYSBA,30749 +importlib_metadata/__pycache__/__init__.cpython-39.pyc,, +importlib_metadata/__pycache__/_adapters.cpython-39.pyc,, +importlib_metadata/__pycache__/_collections.cpython-39.pyc,, +importlib_metadata/__pycache__/_compat.cpython-39.pyc,, +importlib_metadata/__pycache__/_functools.cpython-39.pyc,, +importlib_metadata/__pycache__/_itertools.cpython-39.pyc,, +importlib_metadata/__pycache__/_meta.cpython-39.pyc,, +importlib_metadata/__pycache__/_py39compat.cpython-39.pyc,, +importlib_metadata/__pycache__/_text.cpython-39.pyc,, +importlib_metadata/_adapters.py,sha256=i8S6Ib1OQjcILA-l4gkzktMZe18TaeUNI49PLRp6OBU,2454 +importlib_metadata/_collections.py,sha256=CJ0OTCHIjWA0ZIVS4voORAsn2R4R2cQBEtPsZEJpASY,743 +importlib_metadata/_compat.py,sha256=zhjcWMfA9SNExFVVVBozOYbuiok0A4tdMsNk9ZDZi-A,1554 +importlib_metadata/_functools.py,sha256=PsY2-4rrKX4RVeRC1oGp1lB1pmC9eKN88_f-bD9uOoA,2895 +importlib_metadata/_itertools.py,sha256=cvr_2v8BRbxcIl5x5ldfqdHjhI8Yi8s8yk50G_nm6jQ,2068 +importlib_metadata/_meta.py,sha256=kypMW_-xSStooSm0WpJc6eupjT-Ipc2ZBIl23PyC3No,1613 +importlib_metadata/_py39compat.py,sha256=2Tk5twb_VgLCY-1NEAQjdZp_S9OFMC-pUzP2isuaPsQ,1098 +importlib_metadata/_text.py,sha256=HCsFksZpJLeTP3NEk_ngrAeXVRRtTrtyh9eOABoRP4A,2166 +importlib_metadata/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/WHEEL new file mode 100644 index 0000000..1f37c02 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/top_level.txt new file mode 100644 index 0000000..bbb0754 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata-6.8.0.dist-info/top_level.txt @@ -0,0 +1 @@ +importlib_metadata diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__init__.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__init__.py new file mode 100644 index 0000000..6ba414e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__init__.py @@ -0,0 +1,1015 @@ +import os +import re +import abc +import csv +import sys +import zipp +import email +import inspect +import pathlib +import operator +import textwrap +import warnings +import functools +import itertools +import posixpath +import collections + +from . import _adapters, _meta, _py39compat +from ._collections import FreezableDefaultDict, Pair +from ._compat import ( + NullFinder, + StrPath, + install, + pypy_partial, +) +from ._functools import method_cache, pass_none +from ._itertools import always_iterable, unique_everseen +from ._meta import PackageMetadata, SimplePath + +from contextlib import suppress +from importlib import import_module +from importlib.abc import MetaPathFinder +from itertools import starmap +from typing import Iterable, List, Mapping, Optional, Set, cast + +__all__ = [ + 'Distribution', + 'DistributionFinder', + 'PackageMetadata', + 'PackageNotFoundError', + 'distribution', + 'distributions', + 'entry_points', + 'files', + 'metadata', + 'packages_distributions', + 'requires', + 'version', +] + + +class PackageNotFoundError(ModuleNotFoundError): + """The package was not found.""" + + def __str__(self) -> str: + return f"No package metadata was found for {self.name}" + + @property + def name(self) -> str: # type: ignore[override] + (name,) = self.args + return name + + +class Sectioned: + """ + A simple entry point config parser for performance + + >>> for item in Sectioned.read(Sectioned._sample): + ... print(item) + Pair(name='sec1', value='# comments ignored') + Pair(name='sec1', value='a = 1') + Pair(name='sec1', value='b = 2') + Pair(name='sec2', value='a = 2') + + >>> res = Sectioned.section_pairs(Sectioned._sample) + >>> item = next(res) + >>> item.name + 'sec1' + >>> item.value + Pair(name='a', value='1') + >>> item = next(res) + >>> item.value + Pair(name='b', value='2') + >>> item = next(res) + >>> item.name + 'sec2' + >>> item.value + Pair(name='a', value='2') + >>> list(res) + [] + """ + + _sample = textwrap.dedent( + """ + [sec1] + # comments ignored + a = 1 + b = 2 + + [sec2] + a = 2 + """ + ).lstrip() + + @classmethod + def section_pairs(cls, text): + return ( + section._replace(value=Pair.parse(section.value)) + for section in cls.read(text, filter_=cls.valid) + if section.name is not None + ) + + @staticmethod + def read(text, filter_=None): + lines = filter(filter_, map(str.strip, text.splitlines())) + name = None + for value in lines: + section_match = value.startswith('[') and value.endswith(']') + if section_match: + name = value.strip('[]') + continue + yield Pair(name, value) + + @staticmethod + def valid(line: str): + return line and not line.startswith('#') + + +class DeprecatedTuple: + """ + Provide subscript item access for backward compatibility. + + >>> recwarn = getfixture('recwarn') + >>> ep = EntryPoint(name='name', value='value', group='group') + >>> ep[:] + ('name', 'value', 'group') + >>> ep[0] + 'name' + >>> len(recwarn) + 1 + """ + + # Do not remove prior to 2023-05-01 or Python 3.13 + _warn = functools.partial( + warnings.warn, + "EntryPoint tuple interface is deprecated. Access members by name.", + DeprecationWarning, + stacklevel=pypy_partial(2), + ) + + def __getitem__(self, item): + self._warn() + return self._key()[item] + + +class EntryPoint(DeprecatedTuple): + """An entry point as defined by Python packaging conventions. + + See `the packaging docs on entry points + `_ + for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] + """ + + pattern = re.compile( + r'(?P[\w.]+)\s*' + r'(:\s*(?P[\w.]+)\s*)?' + r'((?P\[.*\])\s*)?$' + ) + """ + A regular expression describing the syntax for an entry point, + which might look like: + + - module + - package.module + - package.module:attribute + - package.module:object.attribute + - package.module:attr [extra1, extra2] + + Other combinations are possible as well. + + The expression is lenient about whitespace around the ':', + following the attr, and following any extras. + """ + + name: str + value: str + group: str + + dist: Optional['Distribution'] = None + + def __init__(self, name: str, value: str, group: str) -> None: + vars(self).update(name=name, value=value, group=group) + + def load(self): + """Load the entry point from its definition. If only a module + is indicated by the value, return that module. Otherwise, + return the named object. + """ + match = self.pattern.match(self.value) + module = import_module(match.group('module')) + attrs = filter(None, (match.group('attr') or '').split('.')) + return functools.reduce(getattr, attrs, module) + + @property + def module(self) -> str: + match = self.pattern.match(self.value) + assert match is not None + return match.group('module') + + @property + def attr(self) -> str: + match = self.pattern.match(self.value) + assert match is not None + return match.group('attr') + + @property + def extras(self) -> List[str]: + match = self.pattern.match(self.value) + assert match is not None + return re.findall(r'\w+', match.group('extras') or '') + + def _for(self, dist): + vars(self).update(dist=dist) + return self + + def matches(self, **params): + """ + EntryPoint matches the given parameters. + + >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') + >>> ep.matches(group='foo') + True + >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') + True + >>> ep.matches(group='foo', name='other') + False + >>> ep.matches() + True + >>> ep.matches(extras=['extra1', 'extra2']) + True + >>> ep.matches(module='bing') + True + >>> ep.matches(attr='bong') + True + """ + attrs = (getattr(self, param) for param in params) + return all(map(operator.eq, params.values(), attrs)) + + def _key(self): + return self.name, self.value, self.group + + def __lt__(self, other): + return self._key() < other._key() + + def __eq__(self, other): + return self._key() == other._key() + + def __setattr__(self, name, value): + raise AttributeError("EntryPoint objects are immutable.") + + def __repr__(self): + return ( + f'EntryPoint(name={self.name!r}, value={self.value!r}, ' + f'group={self.group!r})' + ) + + def __hash__(self) -> int: + return hash(self._key()) + + +class EntryPoints(tuple): + """ + An immutable collection of selectable EntryPoint objects. + """ + + __slots__ = () + + def __getitem__(self, name: str) -> EntryPoint: # type: ignore[override] + """ + Get the EntryPoint in self matching name. + """ + try: + return next(iter(self.select(name=name))) + except StopIteration: + raise KeyError(name) + + def select(self, **params): + """ + Select entry points from self that match the + given parameters (typically group and/or name). + """ + return EntryPoints(ep for ep in self if _py39compat.ep_matches(ep, **params)) + + @property + def names(self) -> Set[str]: + """ + Return the set of all names of all entry points. + """ + return {ep.name for ep in self} + + @property + def groups(self) -> Set[str]: + """ + Return the set of all groups of all entry points. + """ + return {ep.group for ep in self} + + @classmethod + def _from_text_for(cls, text, dist): + return cls(ep._for(dist) for ep in cls._from_text(text)) + + @staticmethod + def _from_text(text): + return ( + EntryPoint(name=item.value.name, value=item.value.value, group=item.name) + for item in Sectioned.section_pairs(text or '') + ) + + +class PackagePath(pathlib.PurePosixPath): + """A reference to a path in a package""" + + hash: Optional["FileHash"] + size: int + dist: "Distribution" + + def read_text(self, encoding: str = 'utf-8') -> str: # type: ignore[override] + with self.locate().open(encoding=encoding) as stream: + return stream.read() + + def read_binary(self) -> bytes: + with self.locate().open('rb') as stream: + return stream.read() + + def locate(self) -> pathlib.Path: + """Return a path-like object for this path""" + return self.dist.locate_file(self) + + +class FileHash: + def __init__(self, spec: str) -> None: + self.mode, _, self.value = spec.partition('=') + + def __repr__(self) -> str: + return f'' + + +class DeprecatedNonAbstract: + def __new__(cls, *args, **kwargs): + all_names = { + name for subclass in inspect.getmro(cls) for name in vars(subclass) + } + abstract = { + name + for name in all_names + if getattr(getattr(cls, name), '__isabstractmethod__', False) + } + if abstract: + warnings.warn( + f"Unimplemented abstract methods {abstract}", + DeprecationWarning, + stacklevel=2, + ) + return super().__new__(cls) + + +class Distribution(DeprecatedNonAbstract): + """A Python distribution package.""" + + @abc.abstractmethod + def read_text(self, filename) -> Optional[str]: + """Attempt to load metadata file given by the name. + + :param filename: The name of the file in the distribution info. + :return: The text if found, otherwise None. + """ + + @abc.abstractmethod + def locate_file(self, path: StrPath) -> pathlib.Path: + """ + Given a path to a file in this distribution, return a path + to it. + """ + + @classmethod + def from_name(cls, name: str) -> "Distribution": + """Return the Distribution for the given package name. + + :param name: The name of the distribution package to search for. + :return: The Distribution instance (or subclass thereof) for the named + package, if found. + :raises PackageNotFoundError: When the named package's distribution + metadata cannot be found. + :raises ValueError: When an invalid value is supplied for name. + """ + if not name: + raise ValueError("A distribution name is required.") + try: + return next(iter(cls.discover(name=name))) + except StopIteration: + raise PackageNotFoundError(name) + + @classmethod + def discover(cls, **kwargs) -> Iterable["Distribution"]: + """Return an iterable of Distribution objects for all packages. + + Pass a ``context`` or pass keyword arguments for constructing + a context. + + :context: A ``DistributionFinder.Context`` object. + :return: Iterable of Distribution objects for all packages. + """ + context = kwargs.pop('context', None) + if context and kwargs: + raise ValueError("cannot accept context and kwargs") + context = context or DistributionFinder.Context(**kwargs) + return itertools.chain.from_iterable( + resolver(context) for resolver in cls._discover_resolvers() + ) + + @staticmethod + def at(path: StrPath) -> "Distribution": + """Return a Distribution for the indicated metadata path + + :param path: a string or path-like object + :return: a concrete Distribution instance for the path + """ + return PathDistribution(pathlib.Path(path)) + + @staticmethod + def _discover_resolvers(): + """Search the meta_path for resolvers.""" + declared = ( + getattr(finder, 'find_distributions', None) for finder in sys.meta_path + ) + return filter(None, declared) + + @property + def metadata(self) -> _meta.PackageMetadata: + """Return the parsed metadata for this Distribution. + + The returned object will have keys that name the various bits of + metadata. See PEP 566 for details. + """ + opt_text = ( + self.read_text('METADATA') + or self.read_text('PKG-INFO') + # This last clause is here to support old egg-info files. Its + # effect is to just end up using the PathDistribution's self._path + # (which points to the egg-info file) attribute unchanged. + or self.read_text('') + ) + text = cast(str, opt_text) + return _adapters.Message(email.message_from_string(text)) + + @property + def name(self) -> str: + """Return the 'Name' metadata for the distribution package.""" + return self.metadata['Name'] + + @property + def _normalized_name(self): + """Return a normalized version of the name.""" + return Prepared.normalize(self.name) + + @property + def version(self) -> str: + """Return the 'Version' metadata for the distribution package.""" + return self.metadata['Version'] + + @property + def entry_points(self) -> EntryPoints: + return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) + + @property + def files(self) -> Optional[List[PackagePath]]: + """Files in this distribution. + + :return: List of PackagePath for this distribution or None + + Result is `None` if the metadata file that enumerates files + (i.e. RECORD for dist-info, or installed-files.txt or + SOURCES.txt for egg-info) is missing. + Result may be empty if the metadata exists but is empty. + """ + + def make_file(name, hash=None, size_str=None): + result = PackagePath(name) + result.hash = FileHash(hash) if hash else None + result.size = int(size_str) if size_str else None + result.dist = self + return result + + @pass_none + def make_files(lines): + return starmap(make_file, csv.reader(lines)) + + @pass_none + def skip_missing_files(package_paths): + return list(filter(lambda path: path.locate().exists(), package_paths)) + + return skip_missing_files( + make_files( + self._read_files_distinfo() + or self._read_files_egginfo_installed() + or self._read_files_egginfo_sources() + ) + ) + + def _read_files_distinfo(self): + """ + Read the lines of RECORD + """ + text = self.read_text('RECORD') + return text and text.splitlines() + + def _read_files_egginfo_installed(self): + """ + Read installed-files.txt and return lines in a similar + CSV-parsable format as RECORD: each file must be placed + relative to the site-packages directory and must also be + quoted (since file names can contain literal commas). + + This file is written when the package is installed by pip, + but it might not be written for other installation methods. + Assume the file is accurate if it exists. + """ + text = self.read_text('installed-files.txt') + # Prepend the .egg-info/ subdir to the lines in this file. + # But this subdir is only available from PathDistribution's + # self._path. + subdir = getattr(self, '_path', None) + if not text or not subdir: + return + + paths = ( + (subdir / name) + .resolve() + .relative_to(self.locate_file('').resolve()) + .as_posix() + for name in text.splitlines() + ) + return map('"{}"'.format, paths) + + def _read_files_egginfo_sources(self): + """ + Read SOURCES.txt and return lines in a similar CSV-parsable + format as RECORD: each file name must be quoted (since it + might contain literal commas). + + Note that SOURCES.txt is not a reliable source for what + files are installed by a package. This file is generated + for a source archive, and the files that are present + there (e.g. setup.py) may not correctly reflect the files + that are present after the package has been installed. + """ + text = self.read_text('SOURCES.txt') + return text and map('"{}"'.format, text.splitlines()) + + @property + def requires(self) -> Optional[List[str]]: + """Generated requirements specified for this Distribution""" + reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() + return reqs and list(reqs) + + def _read_dist_info_reqs(self): + return self.metadata.get_all('Requires-Dist') + + def _read_egg_info_reqs(self): + source = self.read_text('requires.txt') + return pass_none(self._deps_from_requires_text)(source) + + @classmethod + def _deps_from_requires_text(cls, source): + return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) + + @staticmethod + def _convert_egg_info_reqs_to_simple_reqs(sections): + """ + Historically, setuptools would solicit and store 'extra' + requirements, including those with environment markers, + in separate sections. More modern tools expect each + dependency to be defined separately, with any relevant + extras and environment markers attached directly to that + requirement. This method converts the former to the + latter. See _test_deps_from_requires_text for an example. + """ + + def make_condition(name): + return name and f'extra == "{name}"' + + def quoted_marker(section): + section = section or '' + extra, sep, markers = section.partition(':') + if extra and markers: + markers = f'({markers})' + conditions = list(filter(None, [markers, make_condition(extra)])) + return '; ' + ' and '.join(conditions) if conditions else '' + + def url_req_space(req): + """ + PEP 508 requires a space between the url_spec and the quoted_marker. + Ref python/importlib_metadata#357. + """ + # '@' is uniquely indicative of a url_req. + return ' ' * ('@' in req) + + for section in sections: + space = url_req_space(section.value) + yield section.value + space + quoted_marker(section.name) + + +class DistributionFinder(MetaPathFinder): + """ + A MetaPathFinder capable of discovering installed distributions. + """ + + class Context: + """ + Keyword arguments presented by the caller to + ``distributions()`` or ``Distribution.discover()`` + to narrow the scope of a search for distributions + in all DistributionFinders. + + Each DistributionFinder may expect any parameters + and should attempt to honor the canonical + parameters defined below when appropriate. + """ + + name = None + """ + Specific name for which a distribution finder should match. + A name of ``None`` matches all distributions. + """ + + def __init__(self, **kwargs): + vars(self).update(kwargs) + + @property + def path(self) -> List[str]: + """ + The sequence of directory path that a distribution finder + should search. + + Typically refers to Python installed package paths such as + "site-packages" directories and defaults to ``sys.path``. + """ + return vars(self).get('path', sys.path) + + @abc.abstractmethod + def find_distributions(self, context=Context()) -> Iterable[Distribution]: + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the ``context``, + a DistributionFinder.Context instance. + """ + + +class FastPath: + """ + Micro-optimized class for searching a path for + children. + + >>> FastPath('').children() + ['...'] + """ + + @functools.lru_cache() # type: ignore + def __new__(cls, root): + return super().__new__(cls) + + def __init__(self, root): + self.root = root + + def joinpath(self, child): + return pathlib.Path(self.root, child) + + def children(self): + with suppress(Exception): + return os.listdir(self.root or '.') + with suppress(Exception): + return self.zip_children() + return [] + + def zip_children(self): + zip_path = zipp.Path(self.root) + names = zip_path.root.namelist() + self.joinpath = zip_path.joinpath + + return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) + + def search(self, name): + return self.lookup(self.mtime).search(name) + + @property + def mtime(self): + with suppress(OSError): + return os.stat(self.root).st_mtime + self.lookup.cache_clear() + + @method_cache + def lookup(self, mtime): + return Lookup(self) + + +class Lookup: + def __init__(self, path: FastPath): + base = os.path.basename(path.root).lower() + base_is_egg = base.endswith(".egg") + self.infos = FreezableDefaultDict(list) + self.eggs = FreezableDefaultDict(list) + + for child in path.children(): + low = child.lower() + if low.endswith((".dist-info", ".egg-info")): + # rpartition is faster than splitext and suitable for this purpose. + name = low.rpartition(".")[0].partition("-")[0] + normalized = Prepared.normalize(name) + self.infos[normalized].append(path.joinpath(child)) + elif base_is_egg and low == "egg-info": + name = base.rpartition(".")[0].partition("-")[0] + legacy_normalized = Prepared.legacy_normalize(name) + self.eggs[legacy_normalized].append(path.joinpath(child)) + + self.infos.freeze() + self.eggs.freeze() + + def search(self, prepared): + infos = ( + self.infos[prepared.normalized] + if prepared + else itertools.chain.from_iterable(self.infos.values()) + ) + eggs = ( + self.eggs[prepared.legacy_normalized] + if prepared + else itertools.chain.from_iterable(self.eggs.values()) + ) + return itertools.chain(infos, eggs) + + +class Prepared: + """ + A prepared search for metadata on a possibly-named package. + """ + + normalized = None + legacy_normalized = None + + def __init__(self, name): + self.name = name + if name is None: + return + self.normalized = self.normalize(name) + self.legacy_normalized = self.legacy_normalize(name) + + @staticmethod + def normalize(name): + """ + PEP 503 normalization plus dashes as underscores. + """ + return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') + + @staticmethod + def legacy_normalize(name): + """ + Normalize the package name as found in the convention in + older packaging tools versions and specs. + """ + return name.lower().replace('-', '_') + + def __bool__(self): + return bool(self.name) + + +@install +class MetadataPathFinder(NullFinder, DistributionFinder): + """A degenerate finder for distribution packages on the file system. + + This finder supplies only a find_distributions() method for versions + of Python that do not have a PathFinder find_distributions(). + """ + + def find_distributions( + self, context=DistributionFinder.Context() + ) -> Iterable["PathDistribution"]: + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching ``context.name`` + (or all names if ``None`` indicated) along the paths in the list + of directories ``context.path``. + """ + found = self._search_paths(context.name, context.path) + return map(PathDistribution, found) + + @classmethod + def _search_paths(cls, name, paths): + """Find metadata directories in paths heuristically.""" + prepared = Prepared(name) + return itertools.chain.from_iterable( + path.search(prepared) for path in map(FastPath, paths) + ) + + def invalidate_caches(cls) -> None: + FastPath.__new__.cache_clear() + + +class PathDistribution(Distribution): + def __init__(self, path: SimplePath) -> None: + """Construct a distribution. + + :param path: SimplePath indicating the metadata directory. + """ + self._path = path + + def read_text(self, filename: StrPath) -> Optional[str]: + with suppress( + FileNotFoundError, + IsADirectoryError, + KeyError, + NotADirectoryError, + PermissionError, + ): + return self._path.joinpath(filename).read_text(encoding='utf-8') + + return None + + read_text.__doc__ = Distribution.read_text.__doc__ + + def locate_file(self, path: StrPath) -> pathlib.Path: + return self._path.parent / path + + @property + def _normalized_name(self): + """ + Performance optimization: where possible, resolve the + normalized name from the file system path. + """ + stem = os.path.basename(str(self._path)) + return ( + pass_none(Prepared.normalize)(self._name_from_stem(stem)) + or super()._normalized_name + ) + + @staticmethod + def _name_from_stem(stem): + """ + >>> PathDistribution._name_from_stem('foo-3.0.egg-info') + 'foo' + >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') + 'CherryPy' + >>> PathDistribution._name_from_stem('face.egg-info') + 'face' + >>> PathDistribution._name_from_stem('foo.bar') + """ + filename, ext = os.path.splitext(stem) + if ext not in ('.dist-info', '.egg-info'): + return + name, sep, rest = filename.partition('-') + return name + + +def distribution(distribution_name: str) -> Distribution: + """Get the ``Distribution`` instance for the named package. + + :param distribution_name: The name of the distribution package as a string. + :return: A ``Distribution`` instance (or subclass thereof). + """ + return Distribution.from_name(distribution_name) + + +def distributions(**kwargs) -> Iterable[Distribution]: + """Get all ``Distribution`` instances in the current environment. + + :return: An iterable of ``Distribution`` instances. + """ + return Distribution.discover(**kwargs) + + +def metadata(distribution_name: str) -> _meta.PackageMetadata: + """Get the metadata for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: A PackageMetadata containing the parsed metadata. + """ + return Distribution.from_name(distribution_name).metadata + + +def version(distribution_name: str) -> str: + """Get the version string for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: The version string for the package as defined in the package's + "Version" metadata key. + """ + return distribution(distribution_name).version + + +_unique = functools.partial( + unique_everseen, + key=_py39compat.normalized_name, +) +""" +Wrapper for ``distributions`` to return unique distributions by name. +""" + + +def entry_points(**params) -> EntryPoints: + """Return EntryPoint objects for all installed packages. + + Pass selection parameters (group or name) to filter the + result to entry points matching those properties (see + EntryPoints.select()). + + :return: EntryPoints for all installed packages. + """ + eps = itertools.chain.from_iterable( + dist.entry_points for dist in _unique(distributions()) + ) + return EntryPoints(eps).select(**params) + + +def files(distribution_name: str) -> Optional[List[PackagePath]]: + """Return a list of files for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: List of files composing the distribution. + """ + return distribution(distribution_name).files + + +def requires(distribution_name: str) -> Optional[List[str]]: + """ + Return a list of requirements for the named package. + + :return: An iterable of requirements, suitable for + packaging.requirement.Requirement. + """ + return distribution(distribution_name).requires + + +def packages_distributions() -> Mapping[str, List[str]]: + """ + Return a mapping of top-level packages to their + distributions. + + >>> import collections.abc + >>> pkgs = packages_distributions() + >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) + True + """ + pkg_to_dist = collections.defaultdict(list) + for dist in distributions(): + for pkg in _top_level_declared(dist) or _top_level_inferred(dist): + pkg_to_dist[pkg].append(dist.metadata['Name']) + return dict(pkg_to_dist) + + +def _top_level_declared(dist): + return (dist.read_text('top_level.txt') or '').split() + + +def _topmost(name: PackagePath) -> Optional[str]: + """ + Return the top-most parent as long as there is a parent. + """ + top, *rest = name.parts + return top if rest else None + + +def _get_toplevel_name(name: PackagePath) -> str: + """ + Infer a possibly importable module name from a name presumed on + sys.path. + + >>> _get_toplevel_name(PackagePath('foo.py')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo.pyc')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo/__init__.py')) + 'foo' + >>> _get_toplevel_name(PackagePath('foo.pth')) + 'foo.pth' + >>> _get_toplevel_name(PackagePath('foo.dist-info')) + 'foo.dist-info' + """ + return _topmost(name) or ( + # python/typeshed#10328 + inspect.getmodulename(name) # type: ignore + or str(name) + ) + + +def _top_level_inferred(dist): + opt_names = set(map(_get_toplevel_name, always_iterable(dist.files))) + + def importable_name(name): + return '.' not in name + + return filter(importable_name, opt_names) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7167a770bce1d1d9f575fa905f4d6ac7ea1b8f20 GIT binary patch literal 37072 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 T*Bu0^Ti14i6s%86Zr%A8SpS4s literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_compat.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ae5f2d783387efc8d254d3a6280341375070d53 GIT binary patch literal 2078 zcmZuy-EJF26rPz~+Z)G;N|ZudA+e+q!id;Fg;1rcYSpT}fh1Cd5U#3ayfcnB-rd>G zj19I@3CVeo_L8^Y8MvG~#8qE`i^4gxuG3H^nctl`bLRWLbIiB4+5}4U=bqeY67m;L z-Yy|b?m;!bLL-QvIT_SF9Z)}K0|q_IgCZP+l!!otCv4CV4H2A^K~pqE3;Nb$A|er< z6A>=iAQBs*4XYcHp0>s2q@gPr%1ud5J96_n8L{hRuvK<&O?2v+pvR=U^$NTo2VLqK z-U!~f9}2zCbnZ44|zJNl(zB1 z%vhZbr+BJ%Ew<|N*_fBYpXS!eqOxE?#Ue9&m`iVLYD)CAkEEhM58YLHvO?GWM3<3V@RFZM-M7-%G|yyd`@NYgXMJ$3U(M}UmA87g`zEt;zXD`nv*~9A z0t7n}^h!>d6RoDD@M|D3&#FXK*>PrK zGm&6$Uf&|ee3mI)bNP<0F*c8(nj6sI+W`l%3trstoxX>df>ZP&pq7uAvBU;CW9oT7=Zn>H7dYfLE+uFvMt}?iI7$VfH=oy}PHkLp&>MWdtgIEy zaNoM1)G>t}LN(}#@Tuy+KN^?`xjr$jIr$m;|G?ok@QTD#GW`ONqb|uDo?xHjww@X9L4CGc3wd`(FhKr4nJGCiE=tQFhY^K8)(N5@+KP6zH=}l&?gsw?&W9k) literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_functools.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_functools.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9193ea5c52f33d17df752e73890e6ebfbfc30a6 GIT binary patch literal 3167 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 kUDk#&e)GM*0fhQ7jsO4v literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_meta.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/__pycache__/_meta.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0661e7fb5ebfc18789b74ef3100ace32a44381f7 GIT binary patch literal 2895 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 cDHK%8oX5s?An+a literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_adapters.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_adapters.py new file mode 100644 index 0000000..e33cba5 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_adapters.py @@ -0,0 +1,90 @@ +import functools +import warnings +import re +import textwrap +import email.message + +from ._text import FoldedCase +from ._compat import pypy_partial + + +# Do not remove prior to 2024-01-01 or Python 3.14 +_warn = functools.partial( + warnings.warn, + "Implicit None on return values is deprecated and will raise KeyErrors.", + DeprecationWarning, + stacklevel=pypy_partial(2), +) + + +class Message(email.message.Message): + multiple_use_keys = set( + map( + FoldedCase, + [ + 'Classifier', + 'Obsoletes-Dist', + 'Platform', + 'Project-URL', + 'Provides-Dist', + 'Provides-Extra', + 'Requires-Dist', + 'Requires-External', + 'Supported-Platform', + 'Dynamic', + ], + ) + ) + """ + Keys that may be indicated multiple times per PEP 566. + """ + + def __new__(cls, orig: email.message.Message): + res = super().__new__(cls) + vars(res).update(vars(orig)) + return res + + def __init__(self, *args, **kwargs): + self._headers = self._repair_headers() + + # suppress spurious error from mypy + def __iter__(self): + return super().__iter__() + + def __getitem__(self, item): + """ + Warn users that a ``KeyError`` can be expected when a + mising key is supplied. Ref python/importlib_metadata#371. + """ + res = super().__getitem__(item) + if res is None: + _warn() + return res + + def _repair_headers(self): + def redent(value): + "Correct for RFC822 indentation" + if not value or '\n' not in value: + return value + return textwrap.dedent(' ' * 8 + value) + + headers = [(key, redent(value)) for key, value in vars(self)['_headers']] + if self._payload: + headers.append(('Description', self.get_payload())) + return headers + + @property + def json(self): + """ + Convert PackageMetadata to a JSON-compatible format + per PEP 0566. + """ + + def transform(key): + value = self.get_all(key) if key in self.multiple_use_keys else self[key] + if key == 'Keywords': + value = re.split(r'\s+', value) + tk = key.lower().replace('-', '_') + return tk, value + + return dict(map(transform, map(FoldedCase, self))) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_collections.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_collections.py new file mode 100644 index 0000000..cf0954e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_collections.py @@ -0,0 +1,30 @@ +import collections + + +# from jaraco.collections 3.3 +class FreezableDefaultDict(collections.defaultdict): + """ + Often it is desirable to prevent the mutation of + a default dict after its initial construction, such + as to prevent mutation during iteration. + + >>> dd = FreezableDefaultDict(list) + >>> dd[0].append('1') + >>> dd.freeze() + >>> dd[1] + [] + >>> len(dd) + 1 + """ + + def __missing__(self, key): + return getattr(self, '_frozen', super().__missing__)(key) + + def freeze(self): + self._frozen = lambda key: self.default_factory() + + +class Pair(collections.namedtuple('Pair', 'name value')): + @classmethod + def parse(cls, text): + return cls(*map(str.strip, text.split("=", 1))) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_compat.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_compat.py new file mode 100644 index 0000000..c0f15c7 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_compat.py @@ -0,0 +1,67 @@ +import os +import sys +import platform + +from typing import Union + + +__all__ = ['install', 'NullFinder'] + + +def install(cls): + """ + Class decorator for installation on sys.meta_path. + + Adds the backport DistributionFinder to sys.meta_path and + attempts to disable the finder functionality of the stdlib + DistributionFinder. + """ + sys.meta_path.append(cls()) + disable_stdlib_finder() + return cls + + +def disable_stdlib_finder(): + """ + Give the backport primacy for discovering path-based distributions + by monkey-patching the stdlib O_O. + + See #91 for more background for rationale on this sketchy + behavior. + """ + + def matches(finder): + return getattr( + finder, '__module__', None + ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions') + + for finder in filter(matches, sys.meta_path): # pragma: nocover + del finder.find_distributions + + +class NullFinder: + """ + A "Finder" (aka "MetaClassFinder") that never finds any modules, + but may find distributions. + """ + + @staticmethod + def find_spec(*args, **kwargs): + return None + + +def pypy_partial(val): + """ + Adjust for variable stacklevel on partial under PyPy. + + Workaround for #327. + """ + is_pypy = platform.python_implementation() == 'PyPy' + return val + is_pypy + + +if sys.version_info >= (3, 9): + StrPath = Union[str, os.PathLike[str]] +else: + # PathLike is only subscriptable at runtime in 3.9+ + StrPath = Union[str, "os.PathLike[str]"] # pragma: no cover diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_functools.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_functools.py new file mode 100644 index 0000000..71f66bd --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_functools.py @@ -0,0 +1,104 @@ +import types +import functools + + +# from jaraco.functools 3.3 +def method_cache(method, cache_wrapper=None): + """ + Wrap lru_cache to support storing the cache data in the object instances. + + Abstracts the common paradigm where the method explicitly saves an + underscore-prefixed protected property on first call and returns that + subsequently. + + >>> class MyClass: + ... calls = 0 + ... + ... @method_cache + ... def method(self, value): + ... self.calls += 1 + ... return value + + >>> a = MyClass() + >>> a.method(3) + 3 + >>> for x in range(75): + ... res = a.method(x) + >>> a.calls + 75 + + Note that the apparent behavior will be exactly like that of lru_cache + except that the cache is stored on each instance, so values in one + instance will not flush values from another, and when an instance is + deleted, so are the cached values for that instance. + + >>> b = MyClass() + >>> for x in range(35): + ... res = b.method(x) + >>> b.calls + 35 + >>> a.method(0) + 0 + >>> a.calls + 75 + + Note that if method had been decorated with ``functools.lru_cache()``, + a.calls would have been 76 (due to the cached value of 0 having been + flushed by the 'b' instance). + + Clear the cache with ``.cache_clear()`` + + >>> a.method.cache_clear() + + Same for a method that hasn't yet been called. + + >>> c = MyClass() + >>> c.method.cache_clear() + + Another cache wrapper may be supplied: + + >>> cache = functools.lru_cache(maxsize=2) + >>> MyClass.method2 = method_cache(lambda self: 3, cache_wrapper=cache) + >>> a = MyClass() + >>> a.method2() + 3 + + Caution - do not subsequently wrap the method with another decorator, such + as ``@property``, which changes the semantics of the function. + + See also + http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ + for another implementation and additional justification. + """ + cache_wrapper = cache_wrapper or functools.lru_cache() + + def wrapper(self, *args, **kwargs): + # it's the first call, replace the method with a cached, bound method + bound_method = types.MethodType(method, self) + cached_method = cache_wrapper(bound_method) + setattr(self, method.__name__, cached_method) + return cached_method(*args, **kwargs) + + # Support cache clear even before cache has been created. + wrapper.cache_clear = lambda: None + + return wrapper + + +# From jaraco.functools 3.3 +def pass_none(func): + """ + Wrap func so it's not called if its first param is None + + >>> print_text = pass_none(print) + >>> print_text('text') + text + >>> print_text(None) + """ + + @functools.wraps(func) + def wrapper(param, *args, **kwargs): + if param is not None: + return func(param, *args, **kwargs) + + return wrapper diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_itertools.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_itertools.py new file mode 100644 index 0000000..d4ca9b9 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_itertools.py @@ -0,0 +1,73 @@ +from itertools import filterfalse + + +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +# copied from more_itertools 8.8 +def always_iterable(obj, base_type=(str, bytes)): + """If *obj* is iterable, return an iterator over its items:: + + >>> obj = (1, 2, 3) + >>> list(always_iterable(obj)) + [1, 2, 3] + + If *obj* is not iterable, return a one-item iterable containing *obj*:: + + >>> obj = 1 + >>> list(always_iterable(obj)) + [1] + + If *obj* is ``None``, return an empty iterable: + + >>> obj = None + >>> list(always_iterable(None)) + [] + + By default, binary and text strings are not considered iterable:: + + >>> obj = 'foo' + >>> list(always_iterable(obj)) + ['foo'] + + If *base_type* is set, objects for which ``isinstance(obj, base_type)`` + returns ``True`` won't be considered iterable. + + >>> obj = {'a': 1} + >>> list(always_iterable(obj)) # Iterate over the dict's keys + ['a'] + >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit + [{'a': 1}] + + Set *base_type* to ``None`` to avoid any special handling and treat objects + Python considers iterable as iterable: + + >>> obj = 'foo' + >>> list(always_iterable(obj, base_type=None)) + ['f', 'o', 'o'] + """ + if obj is None: + return iter(()) + + if (base_type is not None) and isinstance(obj, base_type): + return iter((obj,)) + + try: + return iter(obj) + except TypeError: + return iter((obj,)) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_meta.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_meta.py new file mode 100644 index 0000000..f670016 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_meta.py @@ -0,0 +1,63 @@ +from typing import Protocol +from typing import Any, Dict, Iterator, List, Optional, TypeVar, Union, overload + + +_T = TypeVar("_T") + + +class PackageMetadata(Protocol): + def __len__(self) -> int: + ... # pragma: no cover + + def __contains__(self, item: str) -> bool: + ... # pragma: no cover + + def __getitem__(self, key: str) -> str: + ... # pragma: no cover + + def __iter__(self) -> Iterator[str]: + ... # pragma: no cover + + @overload + def get(self, name: str, failobj: None = None) -> Optional[str]: + ... # pragma: no cover + + @overload + def get(self, name: str, failobj: _T) -> Union[str, _T]: + ... # pragma: no cover + + # overload per python/importlib_metadata#435 + @overload + def get_all(self, name: str, failobj: None = None) -> Optional[List[Any]]: + ... # pragma: no cover + + @overload + def get_all(self, name: str, failobj: _T) -> Union[List[Any], _T]: + """ + Return all values associated with a possibly multi-valued key. + """ + + @property + def json(self) -> Dict[str, Union[str, List[str]]]: + """ + A JSON-compatible form of the metadata. + """ + + +class SimplePath(Protocol[_T]): + """ + A minimal subset of pathlib.Path required by PathDistribution. + """ + + def joinpath(self, other: Union[str, _T]) -> _T: + ... # pragma: no cover + + def __truediv__(self, other: Union[str, _T]) -> _T: + ... # pragma: no cover + + @property + def parent(self) -> _T: + ... # pragma: no cover + + def read_text(self) -> str: + ... # pragma: no cover diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_py39compat.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_py39compat.py new file mode 100644 index 0000000..cde4558 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_py39compat.py @@ -0,0 +1,35 @@ +""" +Compatibility layer with Python 3.8/3.9 +""" +from typing import TYPE_CHECKING, Any, Optional + +if TYPE_CHECKING: # pragma: no cover + # Prevent circular imports on runtime. + from . import Distribution, EntryPoint +else: + Distribution = EntryPoint = Any + + +def normalized_name(dist: Distribution) -> Optional[str]: + """ + Honor name normalization for distributions that don't provide ``_normalized_name``. + """ + try: + return dist._normalized_name + except AttributeError: + from . import Prepared # -> delay to prevent circular imports. + + return Prepared.normalize(getattr(dist, "name", None) or dist.metadata['Name']) + + +def ep_matches(ep: EntryPoint, **params) -> bool: + """ + Workaround for ``EntryPoint`` objects without the ``matches`` method. + """ + try: + return ep.matches(**params) + except AttributeError: + from . import EntryPoint # -> delay to prevent circular imports. + + # Reconstruct the EntryPoint object to make sure it is compatible. + return EntryPoint(ep.name, ep.value, ep.group).matches(**params) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_text.py b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_text.py new file mode 100644 index 0000000..c88cfbb --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/_text.py @@ -0,0 +1,99 @@ +import re + +from ._functools import method_cache + + +# from jaraco.text 3.5 +class FoldedCase(str): + """ + A case insensitive string class; behaves just like str + except compares equal when the only variation is case. + + >>> s = FoldedCase('hello world') + + >>> s == 'Hello World' + True + + >>> 'Hello World' == s + True + + >>> s != 'Hello World' + False + + >>> s.index('O') + 4 + + >>> s.split('O') + ['hell', ' w', 'rld'] + + >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) + ['alpha', 'Beta', 'GAMMA'] + + Sequence membership is straightforward. + + >>> "Hello World" in [s] + True + >>> s in ["Hello World"] + True + + You may test for set inclusion, but candidate and elements + must both be folded. + + >>> FoldedCase("Hello World") in {s} + True + >>> s in {FoldedCase("Hello World")} + True + + String inclusion works as long as the FoldedCase object + is on the right. + + >>> "hello" in FoldedCase("Hello World") + True + + But not if the FoldedCase object is on the left: + + >>> FoldedCase('hello') in 'Hello World' + False + + In that case, use in_: + + >>> FoldedCase('hello').in_('Hello World') + True + + >>> FoldedCase('hello') > FoldedCase('Hello') + False + """ + + def __lt__(self, other): + return self.lower() < other.lower() + + def __gt__(self, other): + return self.lower() > other.lower() + + def __eq__(self, other): + return self.lower() == other.lower() + + def __ne__(self, other): + return self.lower() != other.lower() + + def __hash__(self): + return hash(self.lower()) + + def __contains__(self, other): + return super().lower().__contains__(other.lower()) + + def in_(self, other): + "Does self appear in other?" + return self in FoldedCase(other) + + # cache lower since it's likely to be called frequently. + @method_cache + def lower(self): + return super().lower() + + def index(self, sub): + return self.lower().index(sub.lower()) + + def split(self, splitter=' ', maxsplit=0): + pattern = re.compile(re.escape(splitter), re.I) + return pattern.split(self, maxsplit) diff --git a/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/py.typed b/testclient/.venv/lib/python3.9/site-packages/importlib_metadata/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2011 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/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/METADATA b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/METADATA new file mode 100644 index 0000000..1d935ed --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/METADATA @@ -0,0 +1,97 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.1.2 +Summary: Safely pass data to untrusted environments and back. +Home-page: https://palletsprojects.com/p/itsdangerous/ +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://itsdangerous.palletsprojects.com/ +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/itsdangerous/ +Project-URL: Issue Tracker, https://github.com/pallets/itsdangerous/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.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +ItsDangerous +============ + +... so better sign this + +Various helpers to pass data to untrusted environments and to get it +back safe and sound. Data is cryptographically signed to ensure that a +token has not been tampered with. + +It's possible to customize how data is serialized. Data is compressed as +needed. A timestamp can be added and verified automatically while +loading a token. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U itsdangerous + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +.. code-block:: python + + from itsdangerous import URLSafeSerializer + auth_s = URLSafeSerializer("secret key", "auth") + token = auth_s.dumps({"id": 5, "name": "itsdangerous"}) + + print(token) + # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg + + data = auth_s.loads(token) + print(data["name"]) + # itsdangerous + + +Donate +------ + +The Pallets organization develops and supports ItsDangerous 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://itsdangerous.palletsprojects.com/ +- Changes: https://itsdangerous.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/ItsDangerous/ +- Source Code: https://github.com/pallets/itsdangerous/ +- Issue Tracker: https://github.com/pallets/itsdangerous/issues/ +- Website: https://palletsprojects.com/p/itsdangerous/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/RECORD b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..1ddee7d --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/RECORD @@ -0,0 +1,23 @@ +itsdangerous-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.1.2.dist-info/LICENSE.rst,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.1.2.dist-info/METADATA,sha256=ThrHIJQ_6XlfbDMCAVe_hawT7IXiIxnTBIDrwxxtucQ,2928 +itsdangerous-2.1.2.dist-info/RECORD,, +itsdangerous-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +itsdangerous-2.1.2.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13 +itsdangerous/__init__.py,sha256=n4mkyjlIVn23pgsgCIw0MJKPdcHIetyeRpe5Fwsn8qg,876 +itsdangerous/__pycache__/__init__.cpython-39.pyc,, +itsdangerous/__pycache__/_json.cpython-39.pyc,, +itsdangerous/__pycache__/encoding.cpython-39.pyc,, +itsdangerous/__pycache__/exc.cpython-39.pyc,, +itsdangerous/__pycache__/serializer.cpython-39.pyc,, +itsdangerous/__pycache__/signer.cpython-39.pyc,, +itsdangerous/__pycache__/timed.cpython-39.pyc,, +itsdangerous/__pycache__/url_safe.cpython-39.pyc,, +itsdangerous/_json.py,sha256=wIhs_7-_XZolmyr-JvKNiy_LgAcfevYR0qhCVdlIhg8,450 +itsdangerous/encoding.py,sha256=pgh86snHC76dPLNCnPlrjR5SaYL_M8H-gWRiiLNbhCU,1419 +itsdangerous/exc.py,sha256=VFxmP2lMoSJFqxNMzWonqs35ROII4-fvCBfG0v1Tkbs,3206 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=zgZ1-U705jHDpt62x_pmLJdryEKDNAbt5UkJtnkcCSw,11144 +itsdangerous/signer.py,sha256=QUH0iX0in-OTptMAXKU5zWMwmOCXn1fsDsubXiGdFN4,9367 +itsdangerous/timed.py,sha256=5CBWLds4Nm8-3bFVC8RxNzFjx6PSwjch8wuZ5cwcHFI,8174 +itsdangerous/url_safe.py,sha256=5bC4jSKOjWNRkWrFseifWVXUnHnPgwOLROjiOwb-eeo,2402 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/WHEEL b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..e163955 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +itsdangerous diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__init__.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..fdb2dfd --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__init__.py @@ -0,0 +1,19 @@ +from .encoding import base64_decode as base64_decode +from .encoding import base64_encode as base64_encode +from .encoding import want_bytes as want_bytes +from .exc import BadData as BadData +from .exc import BadHeader as BadHeader +from .exc import BadPayload as BadPayload +from .exc import BadSignature as BadSignature +from .exc import BadTimeSignature as BadTimeSignature +from .exc import SignatureExpired as SignatureExpired +from .serializer import Serializer as Serializer +from .signer import HMACAlgorithm as HMACAlgorithm +from .signer import NoneAlgorithm as NoneAlgorithm +from .signer import Signer as Signer +from .timed import TimedSerializer as TimedSerializer +from .timed import TimestampSigner as TimestampSigner +from .url_safe import URLSafeSerializer as URLSafeSerializer +from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer + +__version__ = "2.1.2" diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..929f322c583fc29410368cd972a0e37c98d35d2a GIT binary patch literal 887 zcmaiy%Z}496o!+wY11_6b*965c3rd)142SVh~Xm50!E0!#+%4(Ovf5uD%&m7c_ZG3 zRd$FKufU3PtWnjnAyIyP|L@}?J2uU-B!DOWdCo*V2!5eCd}?4`!DoMfltCGaK!zj? zk!!#;QuAB~u9LdwhG@u$M4ltyCTV(Z0=G!Za|<{ovF8}LP1>H@zzIn_C!!-$l6vll zOm<1va|+xeJ&Vp7qiE+i|fgwD)v8vtChiy41=UEvAwxx?(1WV{}WwnR5AT z%hWa(e37qr?nbL8v*)?xj!oBec?-oh=gyW?!8ET_C#y zOcF^;vY_3~7QtI0nG7z83@+Frl=Oh4;ZN`*^Bnp1i9p!}virbPmt(;sT?8sr(R!eU zDn4Wn3CJVKt{|%nFT)GE7aQx?M1EMw*|?RipUs|U7V4csy~p5ev%*;^Y6#P<&ARVr z&BhGi#~8>mV1%9B--c$^mlyazFV}u>d@9V5H6b|u)h&ji@g0zT4D6g(j?6t^36RAe2}@`~|7ovFF;5d8b6$%|aqh>Q_oD|n;rvr8 z%HJFPt+u$68> vVj40=9|epWw5O2|aYOoE2X508^^tjivH1MId_I2JSN;mO&*DI08VA1sfga{f literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/encoding.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/encoding.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6c65ca3bf0e48f532df10b0fffb71bd6fa1c2e8 GIT binary patch literal 1900 zcma)6-ESL35Z~Q9pFd(d&X=3C6&w^HEMdEd5I~|8YT*G11wm6Pt_r8~?Z&xq*|T={ zLSrR7kiH@Qf)>enfmBzA73Z zfy}+9F0b<1<4Q0GXLVkG%6Nm%J$8fUpK_D8KyC@T*M35P&Oaf%{ev^>@cC03EC@DR z(~YAb0r{kgsuikM!2g;5}sX zi~{Y^qIxIdA4Dd4R>{py|DD3qMkTT7xdqilO~^Roi5wT6P%2Zp@RTsQlCgtE&KL47 z{O`hFUj<^w5i#_HsqPV(u_JoKPT4V>fp@yubBacy6RAxkV^KKZ53Hjf(Q_1{uBu3C zKz<~u1=}+@+|BmIP-Q}k{((ka5Js8l$C)%LOZ)qgjK)F@jnF1e6CurTa3JKtFil3o z$)VZJwiBG~lHJCPO}>wfuqKk^ZK zIrg(1-}?45W28jGhoz$(;hW6QweS<^-~a4mJ+L2s#aM3j zTpM%YjjXd`Ay+A02}c|2rDI4cI-c~X>c9;Pc}dzJ7OnDPSSl~Wk;ZHjw?@?p?9V-) z!2$M_ef};m_CY%7Awdp74aB_hK0&oHpeT&Zjz|~K*1(PMuVrdoifogoa^v zw^SE7cKg%mjnEA4Mrj(2Qt|MieeCw@J{)f46F5nv+1`foc4WT)AGM9OQP%d1UR3m^ zEjjFuRtTm-la)uZU6;iRU4;K{~Qqv@3P#mG%+HK zhr`G@q1;)+q2q3z;WSY`5Y(6s>zP2q?~u}y4Ixi6DUDjY9G#o7;=p$Xwm8JMjb z+g~<~Ma$M=mZTQo{1yU|F1&wJK)VAHU%j%G0w7e}9Z34OY8 zq(Lv2_UKhSasUVmxx#l{0>Q#zXF=_~{fy_SxQ!@k#HvQ^k2P7_CBHN3QTAK2-l=uk MtE>T1+v&J}0Od^3<^TWy literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/exc.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/exc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..888f931d17331552489e60366ea17a095dd5a5c3 GIT binary patch literal 3456 zcmb7G&vP3!6y9H6uN@~bErq81S~}B%8Dc{z2Qt7E+72+x1cvsM8D^ublz7W}*GO{O zcyeop-nekhfgXF|584~UiGP9i!1uIXd($NCRAb3{(n@-I-}l}VTV8HkD8b*C#cv(U z`iF#i@gQ7BRllR*7PnJt%f`QxIwNPxu`OZWby2-FYpY@UK6=e>Ebemep~XGnKXA7K z$PMm8_C)}>1-Z!s$bo1KYnhbl-Bgz2ypzJ4f~-Yu7fKcA&k-8%H+xdGn#Sp3n_R%yfaKx zh@Tz`tWcsIqU`1}WN8|T`>`17B+qD`>F_(PZnA7o$b6zgE_RblsD9fl>G#8ZAr-!5 zoD06O5q{MF_)|0W#4eg6p%mK_v16`UHq>`#RlR|ZwjNl2+K2XI+qMqvLo0H)b=!Jk zZ}!}xp(bM?iy(@UEYVRU8(7eD3Qvi2*9bVK6-9B%l!~G!)_=)hn2*Fj=0b_}eHG`N zgq>Wk$9bk@p01Br2A$+U3#H>U5t$zJ_eHipNRyqx_&^Wy?34ay1C?m8K4$SR_*e}R zt$1aF0Swe1AIJc@tfDG|rQNZo-5DVLN?%aGmqJfu7Tfr;D%7WX16BEG4z0Vmv!t%1 z-FmicQ6J2oHOuG~%_ve@M$vf)${5w2t}f0rbKnKcm9deCqM{u|qnuAt>UW~(*9l8! zGuVpfF@{~NGFOpwmtuKl%vhu;?7dKc+);%UNEGp^)G!=M@+}V{$|fHj3}C8 zc97qlVCwucHB6I?Bg7g5#ElU!bYeFd)YvMa+S~z>zd^HUd{MdlCWR z-))Lu4KeY^ts&7eF{X_e(=3S6cM!l9XzbL{pxCxf5ro%(q1ck`voxti8UQ!hF>Y$2 z1ESN0kv6vLhT86%S-8G|(%8CKq97U(?t;fv+{Aql2+K;is*7lUqzjN~5PiOZ+XN^;g={wdYN;fY;gF>@A&%uOuA{C(=dmg9)%KmE^@Q!Fmm!Tp!>b#jPO;OjmDHM z@{|inIUx(Tw@2)LgwVLXU1k%58@^$4oGAlsAXFNJk5OojvUjSf7JOeg*gLq)7jz-A zS71w$Pu!ZqCl%F4bL`e8-iU_q!E~?2^rm5YV3^(ltltWTD^CA<-WZ_w&`gmTX57X< zvg=4t-W<(RYM!MB#u7s|9t$K;%Bf1o1kNx;qAU~YknIZ?YPO@vv3nHD?j?FiDcS5W z$KVC2_Ug5nyLdHs@ymUSm0Tu!NygGhNSVvHipFFi>XY}lsOnubr+Lny2mf&?8JAJf zt3}24uttVxdX49uXg+nCCw-44CU02H70>sk=jKLVIFY*vFKV4i4T_Sb7geDW1bd15 z(DiQ6v9uWO(}w%l*3;5~;6zU)eQ|8jWVm!Q(6i z$qa4i9Y-&-*~gV@QBDI9xlm)gP4K##GjYz94@2;+TrCA1!opFaOnx-G>#<7ahGQ|&v?|oE>MJGk5DSkbavC^|qq`Wd61g`$zd&Aj3@P8DHr(?I>?rL|Xd$H?xFZ~ZOwep() literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/serializer.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/serializer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20bc1faba995d588eb4c9d69e57b65550abcd350 GIT binary patch literal 9764 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 OqC(Tb@5$0i`TqdYc4hGZ literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/signer.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/signer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67330be89545583bfe098e1c1299db49adffb331 GIT binary patch literal 8455 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 G<^KT^DSMj$ literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/timed.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/timed.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..983f5ec2824f48fa656bb8c48b6fbfede439b377 GIT binary patch literal 6501 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/url_safe.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/__pycache__/url_safe.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea93505136c98b188d75209bcac64ee7881a3e4f GIT binary patch literal 2736 zcmbVOPmdHu6tC+4J3BKAi2RFUMO55`ogqp{Kx04xMuUq146#GfThmp$+iXwwSXBee zWY&X=;iT~cZ~(%EFJZiR^Aq&Vc;f7hsPVm;S!M*(NKfk3t5?;ptA6!+?+tG>Y6PC> zm)B)yj*wq*F#Gs0I0a3A4?++@a}rbAJFz1i;pT4Fi#a%VP5Ob$MaT?@_M%sHz@gth&fTaMMO=`Z@F<3#`B^MK>q;>-rTDGcC!7rQRZyhG1u&tpE4|o9Z0=AQ$naVOZ4UeW zWHO3`cgMd?R;lnsaH|>DtUVCn9miTDF?XvT&)+5B)(_x-Hg4dc3Y0W`Riw`38ju7LG+eX* zP5%Hw&`p0t?*cvVQFU-cg)7K6&VI5xPc#7TpZ4km4PW7-w*ml1-rP@PKiJ zKMF?*aV|2_7w<`wh?4Qh3VC!}rdV{amo3G;D(TnA;Zf3044a%KKWfa+Lw* z@@6V~CMyd7w^^!eEh~7QNTo_OJUw-Xj9}<&h7VJRtEG~5R#<`nS0;0d5!{&J%4p=D z@?e+M+}Z6%&>&AHY|@{l|(+UsRkwpA&$T)M6?v|-RG%~DzxMwR(emlu3ZsGf?Gs2EduhNlfLQE(TR}!G;pgEeY&y ztHy+jsmycmWzS-TJ(@igR91py)<~U*dcGGpzawMdba=MMJD9>X&y*O9{Zr8N4iK{? zMmTU=Zng6nG7W#cQmPHj@(eQgNgE_5S6b7uvBEli!w@VD*+DR*ord}WN#AB-n~0I= z+tmPKNN3t$+(SaaGSTlr@J?R7Ayo=RmZj@lLE#1ac#(C(^WHk|NW-{hHvk>%S5^)u zhgVjPpt1yt^#ghf^hp(X=&3_+T=fQuH&MKWVhZe(E=OSEEHsVjF`^2`{~N^Z+WJ(z zAO7?_B%fOJZ*W=+;DT(~dvQ3e8^rwu;Z#ci%5%|c!NhrJ+vwqVac32nK@YB5y^ZhL zX!jFLy*5m$$X0or$7F9KzjC3-*jzu(+xW*Q_6`1hQdp5Kx9#01{KWJ2Qbq5NgY*NW Uyp8?{qP-3oVDfW!oY)oq1@`36S^xk5 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/_json.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/_json.py new file mode 100644 index 0000000..c70d37a --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/_json.py @@ -0,0 +1,16 @@ +import json as _json +import typing as _t + + +class _CompactJSON: + """Wrapper around json module that strips whitespace.""" + + @staticmethod + def loads(payload: _t.Union[str, bytes]) -> _t.Any: + return _json.loads(payload) + + @staticmethod + def dumps(obj: _t.Any, **kwargs: _t.Any) -> str: + kwargs.setdefault("ensure_ascii", False) + kwargs.setdefault("separators", (",", ":")) + return _json.dumps(obj, **kwargs) diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/encoding.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..edb04d1 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +import base64 +import string +import struct +import typing as _t + +from .exc import BadData + +_t_str_bytes = _t.Union[str, bytes] + + +def want_bytes( + s: _t_str_bytes, encoding: str = "utf-8", errors: str = "strict" +) -> bytes: + if isinstance(s, str): + s = s.encode(encoding, errors) + + return s + + +def base64_encode(string: _t_str_bytes) -> bytes: + """Base64 encode a string of bytes or text. The resulting bytes are + safe to use in URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).rstrip(b"=") + + +def base64_decode(string: _t_str_bytes) -> bytes: + """Base64 decode a URL-safe string of bytes or text. The result is + bytes. + """ + string = want_bytes(string, encoding="ascii", errors="ignore") + string += b"=" * (-len(string) % 4) + + try: + return base64.urlsafe_b64decode(string) + except (TypeError, ValueError) as e: + raise BadData("Invalid base64-encoded data") from e + + +# The alphabet used by base64.urlsafe_* +_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii") + +_int64_struct = struct.Struct(">Q") +_int_to_bytes = _int64_struct.pack +_bytes_to_int = _t.cast("_t.Callable[[bytes], _t.Tuple[int]]", _int64_struct.unpack) + + +def int_to_bytes(num: int) -> bytes: + return _int_to_bytes(num).lstrip(b"\x00") + + +def bytes_to_int(bytestr: bytes) -> int: + return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0] diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/exc.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..c38a6af --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/exc.py @@ -0,0 +1,107 @@ +import typing as _t +from datetime import datetime + +_t_opt_any = _t.Optional[_t.Any] +_t_opt_exc = _t.Optional[Exception] + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the base + for all exceptions that ItsDangerous defines. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return self.message + + +class BadSignature(BadData): + """Raised if a signature does not match.""" + + def __init__(self, message: str, payload: _t_opt_any = None): + super().__init__(message) + + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload: _t_opt_any = payload + + +class BadTimeSignature(BadSignature): + """Raised if a time-based signature is invalid. This is a subclass + of :class:`BadSignature`. + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + date_signed: _t.Optional[datetime] = None, + ): + super().__init__(message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionchanged:: 2.0 + #: The datetime value is timezone-aware rather than naive. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class SignatureExpired(BadTimeSignature): + """Raised if a signature timestamp is older than ``max_age``. This + is a subclass of :exc:`BadTimeSignature`. + """ + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + header: _t_opt_any = None, + original_error: _t_opt_exc = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: _t_opt_any = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error + + +class BadPayload(BadData): + """Raised if a payload is invalid. This could happen if the payload + is loaded despite an invalid signature, or if there is a mismatch + between the serializer and deserializer. The original exception + that occurred during loading is stored on as :attr:`original_error`. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str, original_error: _t_opt_exc = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/py.typed b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/serializer.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..9f4a84a --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/serializer.py @@ -0,0 +1,295 @@ +import json +import typing as _t + +from .encoding import want_bytes +from .exc import BadPayload +from .exc import BadSignature +from .signer import _make_keys_list +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_kwargs = _t.Dict[str, _t.Any] +_t_opt_kwargs = _t.Optional[_t_kwargs] +_t_signer = _t.Type[Signer] +_t_fallbacks = _t.List[_t.Union[_t_kwargs, _t.Tuple[_t_signer, _t_kwargs], _t_signer]] +_t_load_unsafe = _t.Tuple[bool, _t.Any] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +def is_text_serializer(serializer: _t.Any) -> bool: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer: + """A serializer wraps a :class:`~itsdangerous.signer.Signer` to + enable serializing and securely signing data other than bytes. It + can unsign to verify that the data hasn't been changed. + + The serializer provides :meth:`dumps` and :meth:`loads`, similar to + :mod:`json`, and by default uses :mod:`json` internally to serialize + the data to bytes. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param serializer: An object that provides ``dumps`` and ``loads`` + methods for serializing data to a string. Defaults to + :attr:`default_serializer`, which defaults to :mod:`json`. + :param serializer_kwargs: Keyword arguments to pass when calling + ``serializer.dumps``. + :param signer: A ``Signer`` class to instantiate when signing data. + Defaults to :attr:`default_signer`, which defaults to + :class:`~itsdangerous.signer.Signer`. + :param signer_kwargs: Keyword arguments to pass when instantiating + the ``Signer`` class. + :param fallback_signers: List of signer parameters to try when + unsigning with the default signer fails. Each item can be a dict + of ``signer_kwargs``, a ``Signer`` class, or a tuple of + ``(signer, signer_kwargs)``. Defaults to + :attr:`default_fallback_signers`. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 2.0 + Removed the default SHA-512 fallback signer from + ``default_fallback_signers``. + + .. versionchanged:: 1.1 + Added support for ``fallback_signers`` and configured a default + SHA-512 fallback. This fallback is for users who used the yanked + 1.0.0 release which defaulted to SHA-512. + + .. versionchanged:: 0.14 + The ``signer`` and ``signer_kwargs`` parameters were added to + the constructor. + """ + + #: The default serialization module to use to serialize data to a + #: string internally. The default is :mod:`json`, but can be changed + #: to any object that provides ``dumps`` and ``loads`` methods. + default_serializer: _t.Any = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: _t_signer = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: _t_fallbacks = [] + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous", + serializer: _t.Any = None, + serializer_kwargs: _t_opt_kwargs = None, + signer: _t.Optional[_t_signer] = None, + signer_kwargs: _t_opt_kwargs = None, + fallback_signers: _t.Optional[_t_fallbacks] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + + if salt is not None: + salt = want_bytes(salt) + # if salt is None then the signer's default is used + + self.salt = salt + + if serializer is None: + serializer = self.default_serializer + + self.serializer: _t.Any = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: _t_signer = signer + self.signer_kwargs: _t_kwargs = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers or ()) + + self.fallback_signers: _t_fallbacks = fallback_signers + self.serializer_kwargs: _t_kwargs = serializer_kwargs or {} + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def load_payload( + self, payload: bytes, serializer: _t.Optional[_t.Any] = None + ) -> _t.Any: + """Loads the encoded object. This function raises + :class:`.BadPayload` if the payload is not valid. The + ``serializer`` parameter can be used to override the serializer + stored on the class. The encoded ``payload`` should always be + bytes. + """ + if serializer is None: + serializer = self.serializer + is_text = self.is_text_serializer + else: + is_text = is_text_serializer(serializer) + + try: + if is_text: + return serializer.loads(payload.decode("utf-8")) + + return serializer.loads(payload) + except Exception as e: + raise BadPayload( + "Could not load the payload because an exception" + " occurred on unserializing the data.", + original_error=e, + ) from e + + def dump_payload(self, obj: _t.Any) -> bytes: + """Dumps the encoded object. The return value is always bytes. + If the internal serializer returns text, the value will be + encoded as UTF-8. + """ + return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) + + def make_signer(self, salt: _t_opt_str_bytes = None) -> Signer: + """Creates a new instance of the signer to be used. The default + implementation uses the :class:`.Signer` base class. + """ + if salt is None: + salt = self.salt + + return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs) + + def iter_unsigners(self, salt: _t_opt_str_bytes = None) -> _t.Iterator[Signer]: + """Iterates over all signers to be tried for unsigning. Starts + with the configured signer, then constructs each signer + specified in ``fallback_signers``. + """ + if salt is None: + salt = self.salt + + yield self.make_signer(salt) + + for fallback in self.fallback_signers: + if isinstance(fallback, dict): + kwargs = fallback + fallback = self.signer + elif isinstance(fallback, tuple): + fallback, kwargs = fallback + else: + kwargs = self.signer_kwargs + + for secret_key in self.secret_keys: + yield fallback(secret_key, salt=salt, **kwargs) + + def dumps(self, obj: _t.Any, salt: _t_opt_str_bytes = None) -> _t_str_bytes: + """Returns a signed string serialized with the internal + serializer. The return value can be either a byte or unicode + string depending on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + + if self.is_text_serializer: + return rv.decode("utf-8") + + return rv + + def dump(self, obj: _t.Any, f: _t.IO, salt: _t_opt_str_bytes = None) -> None: + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None, **kwargs: _t.Any + ) -> _t.Any: + """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + return self.load_payload(signer.unsign(s)) + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def load(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None + ) -> _t_load_unsafe: + """Like :meth:`loads` but without verifying the signature. This + is potentially very dangerous to use depending on how your + serializer works. The return value is ``(signature_valid, + payload)`` instead of just the payload. The first item will be a + boolean that indicates if the signature is valid. This function + never fails. + + Use it for debugging only and if you know that your serializer + module is not exploitable (for example, do not use it with a + pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl( + self, + s: _t_str_bytes, + salt: _t_opt_str_bytes, + load_kwargs: _t_opt_kwargs = None, + load_payload_kwargs: _t_opt_kwargs = None, + ) -> _t_load_unsafe: + """Low level helper function to implement :meth:`loads_unsafe` + in serializer subclasses. + """ + if load_kwargs is None: + load_kwargs = {} + + try: + return True, self.loads(s, salt=salt, **load_kwargs) + except BadSignature as e: + if e.payload is None: + return False, None + + if load_payload_kwargs is None: + load_payload_kwargs = {} + + try: + return ( + False, + self.load_payload(e.payload, **load_payload_kwargs), + ) + except BadPayload: + return False, None + + def load_unsafe(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t_load_unsafe: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/signer.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..aa12005 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/signer.py @@ -0,0 +1,257 @@ +import hashlib +import hmac +import typing as _t + +from .encoding import _base64_alphabet +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import want_bytes +from .exc import BadSignature + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +class SigningAlgorithm: + """Subclasses must implement :meth:`get_signature` to provide + signature generation functionality. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + """Returns the signature for the given key and value.""" + raise NotImplementedError() + + def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool: + """Verifies the given signature matches the expected + signature. + """ + return hmac.compare_digest(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """Provides an algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + return b"" + + +class HMACAlgorithm(SigningAlgorithm): + """Provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to + #: SHA1, but can be changed to any other function in the hashlib + #: module. + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + def __init__(self, digest_method: _t.Any = None): + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + def get_signature(self, key: bytes, value: bytes) -> bytes: + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +def _make_keys_list(secret_key: _t_secret_key) -> _t.List[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] + + +class Signer: + """A signer securely signs bytes, then unsigns them to verify that + the value hasn't been changed. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param sep: Separator between the signature and value. + :param key_derivation: How to derive the signing key from the secret + key and salt. Possible values are ``concat``, ``django-concat``, + or ``hmac``. Defaults to :attr:`default_key_derivation`, which + defaults to ``django-concat``. + :param digest_method: Hash function to use when generating the HMAC + signature. Defaults to :attr:`default_digest_method`, which + defaults to :func:`hashlib.sha1`. Note that the security of the + hash alone doesn't apply when used intermediately in HMAC. + :param algorithm: A :class:`SigningAlgorithm` instance to use + instead of building a default :class:`HMACAlgorithm` with the + ``digest_method``. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 0.18 + ``algorithm`` was added as an argument to the class constructor. + + .. versionchanged:: 0.14 + ``key_derivation`` and ``digest_method`` were added as arguments + to the class constructor. + """ + + #: The default digest method to use for the signer. The default is + #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or + #: compatible object. Note that the security of the hash alone + #: doesn't apply when used intermediately in HMAC. + #: + #: .. versionadded:: 0.14 + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + #: The default scheme to use to derive the signing key from the + #: secret key and salt. The default is ``django-concat``. Possible + #: values are ``concat``, ``django-concat``, and ``hmac``. + #: + #: .. versionadded:: 0.14 + default_key_derivation: str = "django-concat" + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous.Signer", + sep: _t_str_bytes = b".", + key_derivation: _t.Optional[str] = None, + digest_method: _t.Optional[_t.Any] = None, + algorithm: _t.Optional[SigningAlgorithm] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + self.sep: bytes = want_bytes(sep) + + if self.sep in _base64_alphabet: + raise ValueError( + "The given separator cannot be used because it may be" + " contained in the signature itself. ASCII letters," + " digits, and '-_=' must not be used." + ) + + if salt is not None: + salt = want_bytes(salt) + else: + salt = b"itsdangerous.Signer" + + self.salt = salt + + if key_derivation is None: + key_derivation = self.default_key_derivation + + self.key_derivation: str = key_derivation + + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + + self.algorithm: SigningAlgorithm = algorithm + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def derive_key(self, secret_key: _t_opt_str_bytes = None) -> bytes: + """This method is called to derive the key. The default key + derivation choices can be overridden here. Key derivation is not + intended to be used as a security method to make a complex key + out of a short password. Instead you should use large random + secret keys. + + :param secret_key: A specific secret key to derive from. + Defaults to the last item in :attr:`secret_keys`. + + .. versionchanged:: 2.0 + Added the ``secret_key`` parameter. + """ + if secret_key is None: + secret_key = self.secret_keys[-1] + else: + secret_key = want_bytes(secret_key) + + if self.key_derivation == "concat": + return _t.cast(bytes, self.digest_method(self.salt + secret_key).digest()) + elif self.key_derivation == "django-concat": + return _t.cast( + bytes, self.digest_method(self.salt + b"signer" + secret_key).digest() + ) + elif self.key_derivation == "hmac": + mac = hmac.new(secret_key, digestmod=self.digest_method) + mac.update(self.salt) + return mac.digest() + elif self.key_derivation == "none": + return secret_key + else: + raise TypeError("Unknown key derivation method") + + def get_signature(self, value: _t_str_bytes) -> bytes: + """Returns the signature for the given value.""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: _t_str_bytes, sig: _t_str_bytes) -> bool: + """Verifies the signature for the given value.""" + try: + sig = base64_decode(sig) + except Exception: + return False + + value = want_bytes(value) + + for secret_key in reversed(self.secret_keys): + key = self.derive_key(secret_key) + + if self.algorithm.verify_signature(key, value, sig): + return True + + return False + + def unsign(self, signed_value: _t_str_bytes) -> bytes: + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + + if self.sep not in signed_value: + raise BadSignature(f"No {self.sep!r} found in value") + + value, sig = signed_value.rsplit(self.sep, 1) + + if self.verify_signature(value, sig): + return value + + raise BadSignature(f"Signature {sig!r} does not match", payload=value) + + def validate(self, signed_value: _t_str_bytes) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid. + """ + try: + self.unsign(signed_value) + return True + except BadSignature: + return False diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/timed.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..cad8da3 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/timed.py @@ -0,0 +1,234 @@ +import time +import typing +import typing as _t +from datetime import datetime +from datetime import timezone + +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import bytes_to_int +from .encoding import int_to_bytes +from .encoding import want_bytes +from .exc import BadSignature +from .exc import BadTimeSignature +from .exc import SignatureExpired +from .serializer import Serializer +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_opt_int = _t.Optional[int] + +if _t.TYPE_CHECKING: + import typing_extensions as _te + + +class TimestampSigner(Signer): + """Works like the regular :class:`.Signer` but also records the time + of the signing and can be used to expire signatures. The + :meth:`unsign` method can raise :exc:`.SignatureExpired` if the + unsigning failed because the signature is expired. + """ + + def get_timestamp(self) -> int: + """Returns the current timestamp. The function must return an + integer. + """ + return int(time.time()) + + def timestamp_to_datetime(self, ts: int) -> datetime: + """Convert the timestamp from :meth:`get_timestamp` into an + aware :class`datetime.datetime` in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + return datetime.fromtimestamp(ts, tz=timezone.utc) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string and also attaches time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + # Ignore overlapping signatures check, return_timestamp is the only + # parameter that affects the return type. + + @typing.overload + def unsign( # type: ignore + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[False]" = False, + ) -> bytes: + ... + + @typing.overload + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[True]" = True, + ) -> _t.Tuple[bytes, datetime]: + ... + + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + ) -> _t.Union[_t.Tuple[bytes, datetime], bytes]: + """Works like the regular :meth:`.Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If ``return_timestamp`` is ``True`` the + timestamp of the signature will be returned as an aware + :class:`datetime.datetime` object in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + try: + result = super().unsign(signed_value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b"" + + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in + # which we shouldn't have come except someone uses a time-based + # serializer on non-timestamp data, so catch that. + if sep not in result: + if sig_error: + raise sig_error + + raise BadTimeSignature("timestamp missing", payload=result) + + value, ts_bytes = result.rsplit(sep, 1) + ts_int: _t_opt_int = None + ts_dt: _t.Optional[datetime] = None + + try: + ts_int = bytes_to_int(base64_decode(ts_bytes)) + except Exception: + pass + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + if ts_int is not None: + try: + ts_dt = self.timestamp_to_datetime(ts_int) + except (ValueError, OSError, OverflowError) as exc: + # Windows raises OSError + # 32-bit raises OverflowError + raise BadTimeSignature( + "Malformed timestamp", payload=value + ) from exc + + raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but we handle it anyway. + if ts_int is None: + raise BadTimeSignature("Malformed timestamp", payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - ts_int + + if age > max_age: + raise SignatureExpired( + f"Signature age {age} > {max_age} seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if age < 0: + raise SignatureExpired( + f"Signature age {age} < 0 seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if return_timestamp: + return value, self.timestamp_to_datetime(ts_int) + + return value + + def validate(self, signed_value: _t_str_bytes, max_age: _t_opt_int = None) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class TimedSerializer(Serializer): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: _t.Type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: _t_opt_str_bytes = None + ) -> _t.Iterator[TimestampSigner]: + return _t.cast("_t.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + salt: _t_opt_str_bytes = None, + ) -> _t.Any: + """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the + signature validation fails. If a ``max_age`` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`.SignatureExpired` is + raised. All arguments are forwarded to the signer's + :meth:`~TimestampSigner.unsign` method. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + base64d, timestamp = signer.unsign( + s, max_age=max_age, return_timestamp=True + ) + payload = self.load_payload(base64d) + + if return_timestamp: + return payload, timestamp + + return payload + except SignatureExpired: + # The signature was unsigned successfully but was + # expired. Do not try the next signer. + raise + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def loads_unsafe( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + salt: _t_opt_str_bytes = None, + ) -> _t.Tuple[bool, _t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/testclient/.venv/lib/python3.9/site-packages/itsdangerous/url_safe.py b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..d5a9b0c --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,80 @@ +import typing as _t +import zlib + +from ._json import _CompactJSON +from .encoding import base64_decode +from .encoding import base64_encode +from .exc import BadPayload +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer): + """Mixed in with a regular serializer it will attempt to zlib + compress the string to make it shorter if necessary. It will also + base64 encode the string so that it can safely be placed in a URL. + """ + + default_serializer = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: _t.Any, + serializer: _t.Optional[_t.Any] = None, + **kwargs: _t.Any, + ) -> _t.Any: + decompress = False + + if payload.startswith(b"."): + payload = payload[1:] + decompress = True + + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload( + "Could not base64 decode the payload because of an exception", + original_error=e, + ) from e + + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload( + "Could not zlib decompress the payload before decoding the payload", + original_error=e, + ) from e + + return super().load_payload(json, *args, **kwargs) + + def dump_payload(self, obj: _t.Any) -> bytes: + json = super().dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + + base64d = base64_encode(json) + + if is_compressed: + base64d = b"." + base64d + + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer): + """Works like :class:`.Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer): + """Works like :class:`.TimedSerializer` but dumps and loads into a + URL safe string consisting of the upper and lowercase character of + the alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__init__.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..e323926 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/__init__.py @@ -0,0 +1,37 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.2" diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/__init__.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..536abd2347c4569a751e263fd0e64974278e907b GIT binary patch literal 1623 zcmbu9%WfMt6oyB#WJ#m@#ggwH+erg2B%#TwKvAS|VxUDF7yKQ7p>CC~d43)@c~3NPU^ zzvMhG_J|kf;=ITud6Lf|?*Q+R9mfUW0x38yiej=$b{+2mmq^KRNtBZcsW>hJ`^0x# z0j`p&V;{IiYL2VGby9a+18$Ip<2rDYG#xiYD`}Iq<0f#2bR4&UyQJ&54csF=#~t83 zvgf!9+$VjUTuINk%^C;N{3;vhLBhmHrpN94%yKJYO)c6=#FYdjo%a6Z(%jJ6-a1+qL zvLqGMvVh4cmn`^Mb8DFlxD3*{X2IRc&XgPl-`F74YQbX$t$eBE@WPHhz#X`w2EG&K&<0HSDdT zF~f<}u4jrzo3j6!NA|I{wb_tIuW>V%5w7LYsoko0E;fDC?`ZUaPB%vFPQx6Qj}1E4 zGs-2M2=+KTm`dX{o6M)%PCua^SSZvKa%LLBraY_!Vw?9?!$h}(E8B%yBpB79`(p-| z$<2S-*HUUs7%6Gl(n5X9mAA44y!L~)pkgbqZJ1z@4e8t}W+IxhkHr_G&qvSST|HZu z!Z21*7?RQ?azksplk^Ts0c2g>8bKG)-bLGI%ZRz8H5zU4yZ;eY6HB`zQw}hal_X+;U;`5gNxRCn%>VXD9*4 zx*CQHrtzqS;qRV)h7~A(&&D&Au(5_6VZ(*NBL#(tvP0Zqt;8^)5)wj>Ei*O}9FF05 zw1CYR3qBdA?(n}DeK9uNvSIp=J!bqK?~mu>FyxZkFdU_;b@|K0<=R(xgw0EkLZO!X HA8-C2D|p4; literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/_identifier.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/_identifier.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1aed51a0ea588980330ff6bdb4c70cfb15ce16df GIT binary patch literal 2098 zcmYk7&2Qtz8OG(^wpkR&wSPcwK{0EfJro6sqJKdzy`?P*$5tCBUfZypEpns2wU!x+ z_O4{vmPCvCA}N}ZNPXC%B%tTEhaA?~b((!gK6Nf4kXtX!GdWejZ{BC#_u3|9>81@>{U~6AT-Xjg_s)hmmMRU)gwcwesPkjg{X=K6v~e z)FQw8?3Y;J4}bjI-$(yY*gxHWWxhY?1rQV->xO1)RqD^RaSJ%jq#te>EMKz&%fBzdrUS@K}@ zRPtVtS0JxOo@ynQ(hc6j%@=grqgy0yZ|HVHw*gJEj3z1tXB3nu7*H^x;D&-3 z1#_DA7|oJ2OVcbvGZm8}&2Y!FfaYng*o-SP9xE^&EAdzbLFcg=LY>E22o8_+5PTkw zGagrY{Fukjp~_q>Gp<(ox|cJUhg7Ic)Q4W`+}RV7&j~2M9mDiIp-G2)|7V?#yd&g!D>#DJ80PP_%)K( zaejS;;BdFexa;w5o$>C7dwIsa6Yjl4Xmiiu9(wb9?u`&`_y~`V5GDxog)(2nltt|2 zB9Ui{#N{G!wMaCex{Ku5B6+>=T(N8>a!Ws!{EUcNZ=E9B%+h)Rcg*_1V zP`KFHwS?OduCwe^mScr2$H&XDj^HlG-g4|OZ&bFtIbH_yFrS%*`J5i+)gi-h8|Lv_ z#gG6gkOoIGaSX;%NDH2`8=x8H{W_9jLG?+ugk%@PuxDB10YXSL_ft#P!6>- zX(=IbZbO`-ugfyTr5$Rz>{Q2D(*5 zA&}d3=b_d=f#|n@DFsS?55kuMJNP)UKLzqV5AY%fSa&Fw8-4+BCqoUK$^?!-k$p^t zVZlcC1=|k`9Vt4>lV z%P-;(FOp%ojf*L_hd`Rm4j6=G3l-}E39AaOq;SKE{N7ZQG{{PE2H>eESHJ*ufD5ZA zR#-9e5Jn-aG?EaF!*6wbqrTNM?w@}4!Q;1&_M&g!Ti-WQdKVAKJ=UH@hZzsARWzYB5cQ)kYqn!h`zO#L>x3k5bt!=OUHM+NY5Zymm-`b3B zAFMuo9^HPvy0!Vy>h9+UAMb4c;_0te_csrsYd;pTB+b>t{O~pKV2dvx5Eie}v)5;~%U%`rmh6^Z$te literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/async_utils.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/async_utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b9d40adc0655c9dc59d3fec706291918d2edc51 GIT binary patch literal 2682 zcma)7&2Jk;6rY)0+v~41aY9I2KC1Fnm&PtBRD4ubBPdV=QE5UdxvEwh&p26kz3a}5 z)5da64N7__f-B;XNF3;$|A0S%+uRVRp1EO&+MDoH?!~k-tWB^l*) zS&+SkM~Ps&d7j&&jRN<0ev34Uq9n>v28->lt1K?c-J(wJLlPc297+NUBp$z;d!srDpQxjrr@> zuio(I7ZoN8)y8cG3g(q0iHsL2KTsQS^D&hkoPA6r!uR)` z`dZQvb(shyX4h3S;kZ~y^ejd|Cedssh=Wxj>slz?j6xCXdTm|A>-8vHsdqQ@S`uHV zeNb1S7PH-;c?XnLy&cBwV6JYz==XFOsakhKj=>jgATW%C_UF>~>wye|Sl2E^Ni&Gl zt4J{~eJjxDtaqM5OH^CK3~_nvq3#$P!Lvm`o8|2xSs?z#(gxJcjQO zlysUv2`!$1p;C*hjw$$lC*i$F_&#vgkAn_MCEvf>3!-#|tOg>7tFhqrt}2t$aEZzF zx;)T=H(~MYhjeyfyb43T57Q1E5MTxamds#qIr$dyaT7Qt&jPbZNCxz0`W=uR7&o%2 zLh$jT^plPav&r7MX9-1Ds;()dc(;0S(|TqmVj=k9ge%60>_7rqC5r|EVRD$XT_I1S zm53s7Jm%68j4{@K=l=(C|DL64St6MmUP~q&KUrx@q_mBaapvQVG)fuW>qf#jN@$58 zFa;jAT0)ArDI_8%F}WL)mTxJ+{e3z?$WP!q&lVK`p)o#m-w(8wsxdL*Y`P_1hBJ^O zFTtbg*c(!IoP-T&p~yd@ClX1aCZPrDu>zaQRB|q@umUa7>7omJS=vAKU*H^Y1aFeB z;bd_~sM9Z&58Z(1D-1NDr8Dw%ctY98K+)_8iS6S^ilFXqFw_;8G%)A^)pVW68O?Sb z4s63T(e7>rBr4yvyHHm4*fr=fpF_PF)q?^nb8t_8OxNb`1)&aBB5`Z^b~S5Uz0nn> z0=2u-Nn*b%!%nEfb)km2XL4bzx}vE~F;v09alrcxxH5Hn$hkt$(}{1jK7!ZEc1~6T z(iH$>`8HZ{R@c6X!z8{1)?j(NriI+M=-eq?8(H4&S4MT9x}enzD&ziH{fQ=l^d;5e1% zVebf4Fr_S2u;|&ox=)xnAk6_Cp6{^;6ZVwfVJOVGRe-5KJ_^bY?5=we-KGosY&WcS z-q8C;jJ_0w&}WiP_wo|l^cM^Q8H7ZDKfW9GgrRCRbw{2B?dNYSjUN6Q6w+Gm$oD|5 zo|I?cVX{EoFkVf|PabQZhOVh>&9QaHWNa6+HOtllYf>-mee*h#{CkGStCb08YYK#DQ!cSvEQp# bVDhL3Wv7%Th~u4`aZZ&OWlu{mdr$uXUQc*q literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/bccache.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/bccache.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f9bc974992987b9c080acae5fabdc868dfa1fc8 GIT binary patch literal 13919 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 QUs%<}Z!f;n{6nMpzujgV3jhEB literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/compiler.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/compiler.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bfaca706960510dfc18ed7364b01b8dfc2f04bb GIT binary patch literal 54199 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�? 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 <5M3 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/exceptions.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/exceptions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..629113078bfa90143e94b99853e210334644b7e6 GIT binary patch literal 5600 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%0D1fCyM>ovgt%+yVQws2;3Ex6Wf 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 CByIBm literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/filters.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/filters.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5481cfc6fdc3d9fbc53ec202a69ef7ed782b39f GIT binary patch literal 50422 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/idtracking.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/idtracking.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..079f4574d351eb91c18b84548d257abb4fb697c1 GIT binary patch literal 11109 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/lexer.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/lexer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79e15ceed7022264c6eb949bab62fd99bb564424 GIT binary patch literal 20285 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 R(RCo*lU~Z~&9rw#|2Gly5K#aC literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/loaders.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/loaders.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bf9107c88eee55dec811223cbb1c6f77dbf96c4 GIT binary patch literal 20454 zcmb_^TW}oLnO@)Kg27-2fD~_{q&6*!7zG4q%5fwt#idM%wk!%}L|Tr=at4Fx1~A}Y zW_Y@XB*p`8Mbt)AYS(eL_F=P<5@0tsZS8t%GZz}J3N#!kFc}eBPe%Y5)ZKc+U znD6^fcTW!hN~$D->eIK==lY-j|NhHCV`{2o;8*-_XZ?R#GmQVvo9xfQ%@rKM+ooZ7 zM$Pa{&uW`BOU`!9ma|iHwkB(nCd+Wz<*ljOlw9Z9 z)>frfk?VZ>$kudi8rKD{*q+&%t3~%OvReK6|v))nM9rd4j zVAr0;{W0$e+&>}r&*1*JcLMh(oN$(WyPs#n4aDUo+68BHa{aM_f@t(r{Q*!@h z+&}F-gZpRvX_Wsg?p^Ooxc`#8|B7ebG^%F@Z@hBjb+^&++}2jF?Qi*=uo1Spoxok| zD!1Kjc&*O58~S+J2z@+N-7VK^t*!YASzWIYHcCOaubO_aQ2HgOZ@Fqlc4M`PlM`$- zzKZh{%I>PLzSZ^mZ66OxZ_3rJ?VkTjOs;`P)3@R}mb>A#ZolKUP*}+!m8UKCz-=( !{IIV&P1cnBY+R7QuHpzh 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∨+*H@Hlqw6Zq^G+6PEV2hgmjyb2Lgc+TeE*-dr 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nativetypes.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nativetypes.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9376237b29f2b1dfeb2fc9764dc260104f5fb284 GIT binary patch literal 4981 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nodes.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/nodes.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e5d16705ee02c2eb6aa28dd55ff62161bee7756 GIT binary patch literal 40894 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%0Dv$ByU~KWhkk;AfTF;(Q<&5y3U<}^ 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/optimizer.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/optimizer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9535e4b5ad66a2c017f197ceb3940146647a1c0d GIT binary patch literal 1948 zcmZWp&yO256t-t3lgVt-mQq?#5VE+Spl*UdLPA1S%W5eV(t_wpsDohej-Ab&N7AD0(7&7-d_xh}aVSheY&cd=h4T5!@le0soy6vOkqf&s|xU$I>uoN@cPn4Rhce0d<*gjsL)vzf7Sh7x{2om94ObSUBn@nB z?W$#Iw5kDz>7aesMrhw|$+MF-HqtGODgtzT+CumTeUcsM_H7s(Y3K=k5IFiIaN#U! zf+wAZJf%-jNA&my$3(e-zATCH8168@Q*htQ&A!X1GINCyT zk@UvbVY!rQG>qHcR~w18)U{Cok}`<0jgWZTS(dhR!w_E;F;QqA~>;}_SB=BqZ@tX_wUEk0`!Ce&Pj{{j~;H%tvSdjkeZG71krz=tow z$AO4M2Oe+;54t1cS=V=%i}-Q$h)k&HisWHGOCFI3C_^%OrU!10uecFLOeM!-$jWN6_JL9Lp*81W)+Tvgs?z28 zTd=ZTPxSaA!tk|av^gF|K22@J&7p1Mdq?>He?S;DM2Wub35LLX2UG!$id5}3*H`!MUw;)XuyHi5a`KrG)RDi9#ohR%|P%z7gDIs6ugMFecq zm7oNFcfsldpbdn>J>y?k(8f>!q|$5lTW!ZKK+EmmP%3H4BKNv$Q&68TmxVl4}-DktN*bpg2(Q8^FqY&eGfUTtk69s3e5vHQe`7M*WyeFg&Ae zFVBmLTbt)+K{r?6>>cR#G7KcV8ue*FV|s~3H2OQ~oTG7YeB~?$uizf0m@~y|ndfbq z=TOz5$iTdx=RYlYwLUQy!Lg@h`Zz;vwBb#)@^`m`Q&felstqzPjH_sj$@7ZDmBn-> z^a5av{_(rRLEFu9p$oV)b}KCOYyayD+pdqVHU`De4)*VUy_@fRvAgr-?Y&!T4dUxr j*lPYGY#s3qSe)y3hZq&sf$sSm^)Bq3{5% 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/runtime.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/runtime.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de267ada9877da2cb20ba994104de6a503e185ff GIT binary patch literal 32186 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 D0!1rO literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/sandbox.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/sandbox.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20bc366c14edb51ff91b910b962527df4bec4106 GIT binary patch literal 11939 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 R7bePv{%*g#-sku4{{x+R0}22D literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/utils.cpython-39.pyc b/testclient/.venv/lib/python3.9/site-packages/jinja2/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30576d90a8616424d5e461fbc2e5f2323bb6bfdf GIT binary patch literal 24559 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 literal 0 HcmV?d00001 diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/_identifier.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000..928c150 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/async_utils.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000..1a4f389 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/async_utils.py @@ -0,0 +1,84 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in t.cast("t.Iterable[V]", iterable): + yield item + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/bccache.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..d0ddf56 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/bccache.py @@ -0,0 +1,406 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: + ... + + def set(self, key: str, value: bytes, timeout: t.Optional[int] = None) -> None: + ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/compiler.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..3458095 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/compiler.py @@ -0,0 +1,1957 @@ +"""Compiles nodes from the parser into Python code.""" +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "Frame": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "Frame": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in (self.filters, visitor.filters, "filters"), ( + self.tests, + visitor.tests, + "tests", + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(vars): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, public_names)) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import exported, async_exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline( + f"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/constants.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/debug.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: "t.Optional[Context]" = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/defaults.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/testclient/.venv/lib/python3.9/site-packages/jinja2/environment.py b/testclient/.venv/lib/python3.9/site-packages/jinja2/environment.py new file mode 100644 index 0000000..ea04e8b --- /dev/null +++ b/testclient/.venv/lib/python3.9/site-packages/jinja2/environment.py @@ -0,0 +1,1667 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping], +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: "Environment") -> "Environment": + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = False, + ) -> "Environment": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``,, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) # type: ignore + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") # type: ignore + + @typing.overload + def compile( # type: ignore + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: + ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: + ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "

N0SB*iT3LT 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