From 01d373e731b13a01f330673b6a53d9d1000e2efc Mon Sep 17 00:00:00 2001 From: Damien De Paoli Date: Thu, 30 Jan 2025 16:23:05 +1100 Subject: [PATCH] initial commit of finplan - works, with basic csv dump, need to remove unneeded variables, reformat and improve csv next --- .python/bin/Activate.ps1 | 247 + .python/bin/activate | 70 + .python/bin/activate.csh | 27 + .python/bin/activate.fish | 69 + .python/bin/flask | 8 + .python/bin/pip | 8 + .python/bin/pip3 | 8 + .python/bin/pip3.12 | 8 + .python/bin/python | 1 + .python/bin/python3 | 1 + .python/bin/python3.12 | 1 + .../MarkupSafe-3.0.2.dist-info/INSTALLER | 1 + .../MarkupSafe-3.0.2.dist-info/LICENSE.txt | 28 + .../MarkupSafe-3.0.2.dist-info/METADATA | 92 + .../MarkupSafe-3.0.2.dist-info/RECORD | 14 + .../MarkupSafe-3.0.2.dist-info/WHEEL | 6 + .../MarkupSafe-3.0.2.dist-info/top_level.txt | 1 + .../blinker-1.9.0.dist-info/INSTALLER | 1 + .../blinker-1.9.0.dist-info/LICENSE.txt | 20 + .../blinker-1.9.0.dist-info/METADATA | 60 + .../blinker-1.9.0.dist-info/RECORD | 12 + .../blinker-1.9.0.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 487 bytes .../__pycache__/_utilities.cpython-312.pyc | Bin 0 -> 2714 bytes .../blinker/__pycache__/base.cpython-312.pyc | Bin 0 -> 21991 bytes .../site-packages/blinker/_utilities.py | 64 + .../python3.12/site-packages/blinker/base.py | 512 + .../python3.12/site-packages/blinker/py.typed | 0 .../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 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2692 bytes .../click/__pycache__/_compat.cpython-312.pyc | Bin 0 -> 27440 bytes .../__pycache__/_termui_impl.cpython-312.pyc | Bin 0 -> 30572 bytes .../__pycache__/_textwrap.cpython-312.pyc | Bin 0 -> 2438 bytes .../__pycache__/_winconsole.cpython-312.pyc | Bin 0 -> 11977 bytes .../click/__pycache__/core.cpython-312.pyc | Bin 0 -> 135761 bytes .../__pycache__/decorators.cpython-312.pyc | Bin 0 -> 23965 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 14727 bytes .../__pycache__/formatting.cpython-312.pyc | Bin 0 -> 14121 bytes .../click/__pycache__/globals.cpython-312.pyc | Bin 0 -> 3112 bytes .../click/__pycache__/parser.cpython-312.pyc | Bin 0 -> 21500 bytes .../shell_completion.cpython-312.pyc | Bin 0 -> 22763 bytes .../click/__pycache__/termui.cpython-312.pyc | Bin 0 -> 32781 bytes .../click/__pycache__/testing.cpython-312.pyc | Bin 0 -> 24569 bytes .../click/__pycache__/types.cpython-312.pyc | Bin 0 -> 49412 bytes .../click/__pycache__/utils.cpython-312.pyc | Bin 0 -> 26294 bytes .../python3.12/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 + .../python3.12/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.12/site-packages/click/globals.py | 68 + .../python3.12/site-packages/click/parser.py | 529 + .../python3.12/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.12/site-packages/click/termui.py | 784 ++ .../python3.12/site-packages/click/testing.py | 479 + .../python3.12/site-packages/click/types.py | 1089 +++ .../python3.12/site-packages/click/utils.py | 624 ++ .../flask-3.1.0.dist-info/INSTALLER | 1 + .../flask-3.1.0.dist-info/LICENSE.txt | 28 + .../flask-3.1.0.dist-info/METADATA | 81 + .../flask-3.1.0.dist-info/RECORD | 58 + .../flask-3.1.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.1.0.dist-info/WHEEL | 4 + .../flask-3.1.0.dist-info/entry_points.txt | 3 + .../site-packages/flask/__init__.py | 60 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2466 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 227 bytes .../flask/__pycache__/app.cpython-312.pyc | Bin 0 -> 62474 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 0 -> 4986 bytes .../flask/__pycache__/cli.cpython-312.pyc | Bin 0 -> 43389 bytes .../flask/__pycache__/config.cpython-312.pyc | Bin 0 -> 16238 bytes .../flask/__pycache__/ctx.cpython-312.pyc | Bin 0 -> 19824 bytes .../__pycache__/debughelpers.cpython-312.pyc | Bin 0 -> 9136 bytes .../flask/__pycache__/globals.cpython-312.pyc | Bin 0 -> 1851 bytes .../flask/__pycache__/helpers.cpython-312.pyc | Bin 0 -> 25431 bytes .../flask/__pycache__/logging.cpython-312.pyc | Bin 0 -> 3253 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 17119 bytes .../flask/__pycache__/signals.cpython-312.pyc | Bin 0 -> 1208 bytes .../__pycache__/templating.cpython-312.pyc | Bin 0 -> 9918 bytes .../flask/__pycache__/testing.cpython-312.pyc | Bin 0 -> 13588 bytes .../flask/__pycache__/typing.cpython-312.pyc | Bin 0 -> 3974 bytes .../flask/__pycache__/views.cpython-312.pyc | Bin 0 -> 7007 bytes .../__pycache__/wrappers.cpython-312.pyc | Bin 0 -> 10039 bytes .../lib/python3.12/site-packages/flask/app.py | 1536 +++ .../site-packages/flask/blueprints.py | 128 + .../lib/python3.12/site-packages/flask/cli.py | 1133 +++ .../python3.12/site-packages/flask/config.py | 367 + .../lib/python3.12/site-packages/flask/ctx.py | 449 + .../site-packages/flask/debughelpers.py | 178 + .../python3.12/site-packages/flask/globals.py | 51 + .../python3.12/site-packages/flask/helpers.py | 634 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6679 bytes .../json/__pycache__/provider.cpython-312.pyc | Bin 0 -> 9246 bytes .../json/__pycache__/tag.cpython-312.pyc | Bin 0 -> 13941 bytes .../site-packages/flask/json/provider.py | 215 + .../site-packages/flask/json/tag.py | 327 + .../python3.12/site-packages/flask/logging.py | 79 + .../python3.12/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-312.pyc | Bin 0 -> 33699 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 0 -> 31199 bytes .../__pycache__/scaffold.cpython-312.pyc | Bin 0 -> 30212 bytes .../site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 632 ++ .../site-packages/flask/sansio/scaffold.py | 792 ++ .../site-packages/flask/sessions.py | 398 + .../python3.12/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 219 + .../python3.12/site-packages/flask/testing.py | 297 + .../python3.12/site-packages/flask/typing.py | 90 + .../python3.12/site-packages/flask/views.py | 191 + .../site-packages/flask/wrappers.py | 257 + .../itsdangerous-2.2.0.dist-info/INSTALLER | 1 + .../itsdangerous-2.2.0.dist-info/LICENSE.txt | 28 + .../itsdangerous-2.2.0.dist-info/METADATA | 60 + .../itsdangerous-2.2.0.dist-info/RECORD | 22 + .../itsdangerous-2.2.0.dist-info/WHEEL | 4 + .../site-packages/itsdangerous/__init__.py | 38 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1618 bytes .../__pycache__/_json.cpython-312.pyc | Bin 0 -> 1172 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 0 -> 2672 bytes .../__pycache__/exc.cpython-312.pyc | Bin 0 -> 3932 bytes .../__pycache__/serializer.cpython-312.pyc | Bin 0 -> 15413 bytes .../__pycache__/signer.cpython-312.pyc | Bin 0 -> 11278 bytes .../__pycache__/timed.cpython-312.pyc | Bin 0 -> 8726 bytes .../__pycache__/url_safe.cpython-312.pyc | Bin 0 -> 3522 bytes .../site-packages/itsdangerous/_json.py | 18 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 106 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 406 + .../site-packages/itsdangerous/signer.py | 266 + .../site-packages/itsdangerous/timed.py | 228 + .../site-packages/itsdangerous/url_safe.py | 83 + .../jinja2-3.1.4.dist-info/INSTALLER | 1 + .../jinja2-3.1.4.dist-info/LICENSE.txt | 28 + .../jinja2-3.1.4.dist-info/METADATA | 76 + .../jinja2-3.1.4.dist-info/RECORD | 57 + .../jinja2-3.1.4.dist-info/WHEEL | 4 + .../jinja2-3.1.4.dist-info/entry_points.txt | 3 + .../site-packages/jinja2/__init__.py | 38 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1643 bytes .../__pycache__/_identifier.cpython-312.pyc | Bin 0 -> 2124 bytes .../__pycache__/async_utils.cpython-312.pyc | Bin 0 -> 4078 bytes .../__pycache__/bccache.cpython-312.pyc | Bin 0 -> 19335 bytes .../__pycache__/compiler.cpython-312.pyc | Bin 0 -> 102411 bytes .../__pycache__/constants.cpython-312.pyc | Bin 0 -> 1546 bytes .../jinja2/__pycache__/debug.cpython-312.pyc | Bin 0 -> 6571 bytes .../__pycache__/defaults.cpython-312.pyc | Bin 0 -> 1596 bytes .../__pycache__/environment.cpython-312.pyc | Bin 0 -> 76739 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7710 bytes .../jinja2/__pycache__/ext.cpython-312.pyc | Bin 0 -> 41894 bytes .../__pycache__/filters.cpython-312.pyc | Bin 0 -> 72071 bytes .../__pycache__/idtracking.cpython-312.pyc | Bin 0 -> 19219 bytes .../jinja2/__pycache__/lexer.cpython-312.pyc | Bin 0 -> 32038 bytes .../__pycache__/loaders.cpython-312.pyc | Bin 0 -> 31034 bytes .../jinja2/__pycache__/meta.cpython-312.pyc | Bin 0 -> 5480 bytes .../__pycache__/nativetypes.cpython-312.pyc | Bin 0 -> 7001 bytes .../jinja2/__pycache__/nodes.cpython-312.pyc | Bin 0 -> 58263 bytes .../__pycache__/optimizer.cpython-312.pyc | Bin 0 -> 2679 bytes .../jinja2/__pycache__/parser.cpython-312.pyc | Bin 0 -> 60824 bytes .../__pycache__/runtime.cpython-312.pyc | Bin 0 -> 48489 bytes .../__pycache__/sandbox.cpython-312.pyc | Bin 0 -> 17890 bytes .../jinja2/__pycache__/tests.cpython-312.pyc | Bin 0 -> 9040 bytes .../jinja2/__pycache__/utils.cpython-312.pyc | Bin 0 -> 34521 bytes .../__pycache__/visitor.cpython-312.pyc | Bin 0 -> 5355 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../site-packages/jinja2/bccache.py | 408 + .../site-packages/jinja2/compiler.py | 1960 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.12/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1675 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.12/site-packages/jinja2/ext.py | 870 ++ .../site-packages/jinja2/filters.py | 1866 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.12/site-packages/jinja2/lexer.py | 868 ++ .../site-packages/jinja2/loaders.py | 667 ++ .../python3.12/site-packages/jinja2/meta.py | 112 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.12/site-packages/jinja2/nodes.py | 1206 +++ .../site-packages/jinja2/optimizer.py | 48 + .../python3.12/site-packages/jinja2/parser.py | 1041 ++ .../python3.12/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1056 ++ .../site-packages/jinja2/sandbox.py | 429 + .../python3.12/site-packages/jinja2/tests.py | 256 + .../python3.12/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 395 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 20918 bytes .../__pycache__/_native.cpython-312.pyc | Bin 0 -> 605 bytes .../site-packages/markupsafe/_native.py | 8 + .../site-packages/markupsafe/_speedups.c | 204 + .../_speedups.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 43432 bytes .../site-packages/markupsafe/_speedups.pyi | 1 + .../site-packages/markupsafe/py.typed | 0 .../pip-24.0.dist-info/AUTHORS.txt | 760 ++ .../pip-24.0.dist-info/INSTALLER | 1 + .../pip-24.0.dist-info/LICENSE.txt | 20 + .../site-packages/pip-24.0.dist-info/METADATA | 88 + .../site-packages/pip-24.0.dist-info/RECORD | 1005 ++ .../pip-24.0.dist-info/REQUESTED | 0 .../site-packages/pip-24.0.dist-info/WHEEL | 5 + .../pip-24.0.dist-info/entry_points.txt | 4 + .../pip-24.0.dist-info/top_level.txt | 1 + .../python3.12/site-packages/pip/__init__.py | 13 + .../python3.12/site-packages/pip/__main__.py | 24 + .../site-packages/pip/__pip-runner__.py | 50 + .../pip/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 680 bytes .../pip/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 836 bytes .../__pip-runner__.cpython-312.pyc | Bin 0 -> 2199 bytes .../site-packages/pip/_internal/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 782 bytes .../__pycache__/build_env.cpython-312.pyc | Bin 0 -> 14289 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 12660 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 17661 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 33279 bytes .../__pycache__/main.cpython-312.pyc | Bin 0 -> 665 bytes .../__pycache__/pyproject.cpython-312.pyc | Bin 0 -> 4966 bytes .../self_outdated_check.cpython-312.pyc | Bin 0 -> 10547 bytes .../__pycache__/wheel_builder.cpython-312.pyc | Bin 0 -> 13644 bytes .../site-packages/pip/_internal/build_env.py | 311 + .../site-packages/pip/_internal/cache.py | 290 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 273 bytes .../autocompletion.cpython-312.pyc | Bin 0 -> 8460 bytes .../__pycache__/base_command.cpython-312.pyc | Bin 0 -> 10450 bytes .../__pycache__/cmdoptions.cpython-312.pyc | Bin 0 -> 30369 bytes .../command_context.cpython-312.pyc | Bin 0 -> 1776 bytes .../cli/__pycache__/main.cpython-312.pyc | Bin 0 -> 2293 bytes .../__pycache__/main_parser.cpython-312.pyc | Bin 0 -> 4900 bytes .../cli/__pycache__/parser.cpython-312.pyc | Bin 0 -> 15017 bytes .../__pycache__/progress_bars.cpython-312.pyc | Bin 0 -> 2615 bytes .../__pycache__/req_command.cpython-312.pyc | Bin 0 -> 18847 bytes .../cli/__pycache__/spinners.cpython-312.pyc | Bin 0 -> 7835 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 370 bytes .../pip/_internal/cli/autocompletion.py | 172 + .../pip/_internal/cli/base_command.py | 236 + .../pip/_internal/cli/cmdoptions.py | 1074 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 79 + .../pip/_internal/cli/main_parser.py | 134 + .../site-packages/pip/_internal/cli/parser.py | 294 + .../pip/_internal/cli/progress_bars.py | 68 + .../pip/_internal/cli/req_command.py | 505 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 132 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3997 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 9706 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 2085 bytes .../__pycache__/completion.cpython-312.pyc | Bin 0 -> 5187 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 13207 bytes .../__pycache__/debug.cpython-312.pyc | Bin 0 -> 10156 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 7584 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 4411 bytes .../commands/__pycache__/hash.cpython-312.pyc | Bin 0 -> 2978 bytes .../commands/__pycache__/help.cpython-312.pyc | Bin 0 -> 1668 bytes .../__pycache__/index.cpython-312.pyc | Bin 0 -> 6715 bytes .../__pycache__/inspect.cpython-312.pyc | Bin 0 -> 3970 bytes .../__pycache__/install.cpython-312.pyc | Bin 0 -> 28908 bytes .../commands/__pycache__/list.cpython-312.pyc | Bin 0 -> 15651 bytes .../__pycache__/search.cpython-312.pyc | Bin 0 -> 7616 bytes .../commands/__pycache__/show.cpython-312.pyc | Bin 0 -> 9723 bytes .../__pycache__/uninstall.cpython-312.pyc | Bin 0 -> 4721 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 8951 bytes .../pip/_internal/commands/cache.py | 225 + .../pip/_internal/commands/check.py | 54 + .../pip/_internal/commands/completion.py | 130 + .../pip/_internal/commands/configuration.py | 280 + .../pip/_internal/commands/debug.py | 201 + .../pip/_internal/commands/download.py | 147 + .../pip/_internal/commands/freeze.py | 109 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/inspect.py | 92 + .../pip/_internal/commands/install.py | 774 ++ .../pip/_internal/commands/list.py | 370 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 189 + .../pip/_internal/commands/uninstall.py | 113 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 383 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 936 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 2857 bytes .../__pycache__/installed.cpython-312.pyc | Bin 0 -> 1695 bytes .../__pycache__/sdist.cpython-312.pyc | Bin 0 -> 8483 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 2243 bytes .../pip/_internal/distributions/base.py | 51 + .../pip/_internal/distributions/installed.py | 29 + .../pip/_internal/distributions/sdist.py | 156 + .../pip/_internal/distributions/wheel.py | 40 + .../site-packages/pip/_internal/exceptions.py | 728 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 227 bytes .../__pycache__/collector.cpython-312.pyc | Bin 0 -> 21881 bytes .../package_finder.cpython-312.pyc | Bin 0 -> 40730 bytes .../index/__pycache__/sources.cpython-312.pyc | Bin 0 -> 12599 bytes .../pip/_internal/index/collector.py | 507 + .../pip/_internal/index/package_finder.py | 1027 ++ .../pip/_internal/index/sources.py | 285 + .../pip/_internal/locations/__init__.py | 467 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 16771 bytes .../__pycache__/_distutils.cpython-312.pyc | Bin 0 -> 6851 bytes .../__pycache__/_sysconfig.cpython-312.pyc | Bin 0 -> 8006 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 3776 bytes .../pip/_internal/locations/_distutils.py | 172 + .../pip/_internal/locations/_sysconfig.py | 213 + .../pip/_internal/locations/base.py | 81 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 128 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5877 bytes .../__pycache__/_json.cpython-312.pyc | Bin 0 -> 2870 bytes .../metadata/__pycache__/base.cpython-312.pyc | Bin 0 -> 35707 bytes .../__pycache__/pkg_resources.cpython-312.pyc | Bin 0 -> 15785 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 702 ++ .../_internal/metadata/importlib/__init__.py | 6 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 353 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 3328 bytes .../__pycache__/_dists.cpython-312.pyc | Bin 0 -> 13420 bytes .../__pycache__/_envs.cpython-312.pyc | Bin 0 -> 11175 bytes .../_internal/metadata/importlib/_compat.py | 55 + .../_internal/metadata/importlib/_dists.py | 227 + .../pip/_internal/metadata/importlib/_envs.py | 189 + .../pip/_internal/metadata/pkg_resources.py | 278 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 261 bytes .../__pycache__/candidate.cpython-312.pyc | Bin 0 -> 1900 bytes .../__pycache__/direct_url.cpython-312.pyc | Bin 0 -> 11194 bytes .../format_control.cpython-312.pyc | Bin 0 -> 4222 bytes .../models/__pycache__/index.cpython-312.pyc | Bin 0 -> 1689 bytes .../installation_report.cpython-312.pyc | Bin 0 -> 2267 bytes .../models/__pycache__/link.cpython-312.pyc | Bin 0 -> 25997 bytes .../models/__pycache__/scheme.cpython-312.pyc | Bin 0 -> 1164 bytes .../__pycache__/search_scope.cpython-312.pyc | Bin 0 -> 5083 bytes .../selection_prefs.cpython-312.pyc | Bin 0 -> 1846 bytes .../__pycache__/target_python.cpython-312.pyc | Bin 0 -> 4949 bytes .../models/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5775 bytes .../pip/_internal/models/candidate.py | 30 + .../pip/_internal/models/direct_url.py | 235 + .../pip/_internal/models/format_control.py | 78 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 56 + .../pip/_internal/models/link.py | 579 ++ .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 132 + .../pip/_internal/models/selection_prefs.py | 51 + .../pip/_internal/models/target_python.py | 122 + .../pip/_internal/models/wheel.py | 92 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 249 bytes .../network/__pycache__/auth.cpython-312.pyc | Bin 0 -> 21991 bytes .../network/__pycache__/cache.cpython-312.pyc | Bin 0 -> 6513 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 8548 bytes .../__pycache__/lazy_wheel.cpython-312.pyc | Bin 0 -> 11658 bytes .../__pycache__/session.cpython-312.pyc | Bin 0 -> 18769 bytes .../network/__pycache__/utils.cpython-312.pyc | Bin 0 -> 2248 bytes .../__pycache__/xmlrpc.cpython-312.pyc | Bin 0 -> 2944 bytes .../pip/_internal/network/auth.py | 561 ++ .../pip/_internal/network/cache.py | 106 + .../pip/_internal/network/download.py | 186 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 520 + .../pip/_internal/network/utils.py | 96 + .../pip/_internal/network/xmlrpc.py | 62 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 192 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 7574 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 10112 bytes .../__pycache__/prepare.cpython-312.pyc | Bin 0 -> 25742 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 198 bytes .../__pycache__/build_tracker.cpython-312.pyc | Bin 0 -> 7818 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 1875 bytes .../metadata_editable.cpython-312.pyc | Bin 0 -> 1909 bytes .../metadata_legacy.cpython-312.pyc | Bin 0 -> 3060 bytes .../build/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 1679 bytes .../wheel_editable.cpython-312.pyc | Bin 0 -> 2020 bytes .../__pycache__/wheel_legacy.cpython-312.pyc | Bin 0 -> 3924 bytes .../operations/build/build_tracker.py | 139 + .../_internal/operations/build/metadata.py | 39 + .../operations/build/metadata_editable.py | 41 + .../operations/build/metadata_legacy.py | 74 + .../pip/_internal/operations/build/wheel.py | 37 + .../operations/build/wheel_editable.py | 46 + .../operations/build/wheel_legacy.py | 102 + .../pip/_internal/operations/check.py | 187 + .../pip/_internal/operations/freeze.py | 255 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 261 bytes .../editable_legacy.cpython-312.pyc | Bin 0 -> 1812 bytes .../install/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 33854 bytes .../operations/install/editable_legacy.py | 46 + .../pip/_internal/operations/install/wheel.py | 734 ++ .../pip/_internal/operations/prepare.py | 730 ++ .../site-packages/pip/_internal/pyproject.py | 179 + .../pip/_internal/req/__init__.py | 92 + .../req/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3738 bytes .../__pycache__/constructors.cpython-312.pyc | Bin 0 -> 21577 bytes .../req/__pycache__/req_file.cpython-312.pyc | Bin 0 -> 21456 bytes .../__pycache__/req_install.cpython-312.pyc | Bin 0 -> 38409 bytes .../req/__pycache__/req_set.cpython-312.pyc | Bin 0 -> 7213 bytes .../__pycache__/req_uninstall.cpython-312.pyc | Bin 0 -> 32972 bytes .../pip/_internal/req/constructors.py | 576 ++ .../pip/_internal/req/req_file.py | 554 ++ .../pip/_internal/req/req_install.py | 923 ++ .../pip/_internal/req/req_set.py | 119 + .../pip/_internal/req/req_uninstall.py | 649 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 192 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 1180 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 199 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 22434 bytes .../_internal/resolution/legacy/resolver.py | 598 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 203 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 8332 bytes .../__pycache__/candidates.cpython-312.pyc | Bin 0 -> 30393 bytes .../__pycache__/factory.cpython-312.pyc | Bin 0 -> 32109 bytes .../found_candidates.cpython-312.pyc | Bin 0 -> 6203 bytes .../__pycache__/provider.cpython-312.pyc | Bin 0 -> 10373 bytes .../__pycache__/reporter.cpython-312.pyc | Bin 0 -> 4930 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 11424 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 12346 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 597 ++ .../resolution/resolvelib/factory.py | 812 ++ .../resolution/resolvelib/found_candidates.py | 155 + .../resolution/resolvelib/provider.py | 255 + .../resolution/resolvelib/reporter.py | 80 + .../resolution/resolvelib/requirements.py | 166 + .../resolution/resolvelib/resolver.py | 317 + .../pip/_internal/self_outdated_check.py | 248 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 187 bytes .../__pycache__/_jaraco_text.cpython-312.pyc | Bin 0 -> 4528 bytes .../utils/__pycache__/_log.cpython-312.pyc | Bin 0 -> 1858 bytes .../utils/__pycache__/appdirs.cpython-312.pyc | Bin 0 -> 2402 bytes .../utils/__pycache__/compat.cpython-312.pyc | Bin 0 -> 2205 bytes .../compatibility_tags.cpython-312.pyc | Bin 0 -> 5553 bytes .../__pycache__/datetime.cpython-312.pyc | Bin 0 -> 676 bytes .../__pycache__/deprecation.cpython-312.pyc | Bin 0 -> 4178 bytes .../direct_url_helpers.cpython-312.pyc | Bin 0 -> 3555 bytes .../__pycache__/egg_link.cpython-312.pyc | Bin 0 -> 3218 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 0 -> 2150 bytes .../__pycache__/entrypoints.cpython-312.pyc | Bin 0 -> 3985 bytes .../__pycache__/filesystem.cpython-312.pyc | Bin 0 -> 7450 bytes .../__pycache__/filetypes.cpython-312.pyc | Bin 0 -> 1156 bytes .../utils/__pycache__/glibc.cpython-312.pyc | Bin 0 -> 2334 bytes .../utils/__pycache__/hashes.cpython-312.pyc | Bin 0 -> 7546 bytes .../utils/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13549 bytes .../utils/__pycache__/misc.cpython-312.pyc | Bin 0 -> 34113 bytes .../utils/__pycache__/models.cpython-312.pyc | Bin 0 -> 2704 bytes .../__pycache__/packaging.cpython-312.pyc | Bin 0 -> 2575 bytes .../setuptools_build.cpython-312.pyc | Bin 0 -> 4542 bytes .../__pycache__/subprocess.cpython-312.pyc | Bin 0 -> 8710 bytes .../__pycache__/temp_dir.cpython-312.pyc | Bin 0 -> 12054 bytes .../__pycache__/unpacking.cpython-312.pyc | Bin 0 -> 11100 bytes .../utils/__pycache__/urls.cpython-312.pyc | Bin 0 -> 2397 bytes .../__pycache__/virtualenv.cpython-312.pyc | Bin 0 -> 4472 bytes .../utils/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5918 bytes .../pip/_internal/utils/_jaraco_text.py | 109 + .../site-packages/pip/_internal/utils/_log.py | 38 + .../pip/_internal/utils/appdirs.py | 52 + .../pip/_internal/utils/compat.py | 63 + .../pip/_internal/utils/compatibility_tags.py | 165 + .../pip/_internal/utils/datetime.py | 11 + .../pip/_internal/utils/deprecation.py | 120 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/egg_link.py | 80 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 84 + .../pip/_internal/utils/filesystem.py | 153 + .../pip/_internal/utils/filetypes.py | 27 + .../pip/_internal/utils/glibc.py | 88 + .../pip/_internal/utils/hashes.py | 151 + .../pip/_internal/utils/logging.py | 348 + .../site-packages/pip/_internal/utils/misc.py | 783 ++ .../pip/_internal/utils/models.py | 39 + .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/setuptools_build.py | 146 + .../pip/_internal/utils/subprocess.py | 260 + .../pip/_internal/utils/temp_dir.py | 296 + .../pip/_internal/utils/unpacking.py | 257 + .../site-packages/pip/_internal/utils/urls.py | 62 + .../pip/_internal/utils/virtualenv.py | 104 + .../pip/_internal/utils/wheel.py | 134 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 526 bytes .../vcs/__pycache__/bazaar.cpython-312.pyc | Bin 0 -> 5018 bytes .../vcs/__pycache__/git.cpython-312.pyc | Bin 0 -> 18987 bytes .../vcs/__pycache__/mercurial.cpython-312.pyc | Bin 0 -> 7607 bytes .../__pycache__/subversion.cpython-312.pyc | Bin 0 -> 12479 bytes .../versioncontrol.cpython-312.pyc | Bin 0 -> 29005 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 526 + .../pip/_internal/vcs/mercurial.py | 163 + .../pip/_internal/vcs/subversion.py | 324 + .../pip/_internal/vcs/versioncontrol.py | 705 ++ .../pip/_internal/wheel_builder.py | 354 + .../site-packages/pip/_vendor/__init__.py | 121 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4688 bytes .../_vendor/__pycache__/six.cpython-312.pyc | Bin 0 -> 41265 bytes .../typing_extensions.cpython-312.pyc | Bin 0 -> 122045 bytes .../pip/_vendor/cachecontrol/__init__.py | 28 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 898 bytes .../__pycache__/_cmd.cpython-312.pyc | Bin 0 -> 2642 bytes .../__pycache__/adapter.cpython-312.pyc | Bin 0 -> 6460 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 3805 bytes .../__pycache__/controller.cpython-312.pyc | Bin 0 -> 16163 bytes .../__pycache__/filewrapper.cpython-312.pyc | Bin 0 -> 4343 bytes .../__pycache__/heuristics.cpython-312.pyc | Bin 0 -> 6690 bytes .../__pycache__/serialize.cpython-312.pyc | Bin 0 -> 6401 bytes .../__pycache__/wrapper.cpython-312.pyc | Bin 0 -> 1670 bytes .../pip/_vendor/cachecontrol/_cmd.py | 70 + .../pip/_vendor/cachecontrol/adapter.py | 161 + .../pip/_vendor/cachecontrol/cache.py | 74 + .../_vendor/cachecontrol/caches/__init__.py | 8 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 431 bytes .../__pycache__/file_cache.cpython-312.pyc | Bin 0 -> 7706 bytes .../__pycache__/redis_cache.cpython-312.pyc | Bin 0 -> 2734 bytes .../_vendor/cachecontrol/caches/file_cache.py | 181 + .../cachecontrol/caches/redis_cache.py | 48 + .../pip/_vendor/cachecontrol/controller.py | 494 + .../pip/_vendor/cachecontrol/filewrapper.py | 119 + .../pip/_vendor/cachecontrol/heuristics.py | 154 + .../pip/_vendor/cachecontrol/serialize.py | 206 + .../pip/_vendor/cachecontrol/wrapper.py | 43 + .../pip/_vendor/certifi/__init__.py | 4 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 314 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 641 bytes .../certifi/__pycache__/core.cpython-312.pyc | Bin 0 -> 3323 bytes .../pip/_vendor/certifi/cacert.pem | 4635 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 119 + .../pip/_vendor/chardet/__init__.py | 115 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4564 bytes .../__pycache__/big5freq.cpython-312.pyc | Bin 0 -> 27195 bytes .../__pycache__/big5prober.cpython-312.pyc | Bin 0 -> 1383 bytes .../chardistribution.cpython-312.pyc | Bin 0 -> 9634 bytes .../charsetgroupprober.cpython-312.pyc | Bin 0 -> 4118 bytes .../__pycache__/charsetprober.cpython-312.pyc | Bin 0 -> 5014 bytes .../codingstatemachine.cpython-312.pyc | Bin 0 -> 3874 bytes .../codingstatemachinedict.cpython-312.pyc | Bin 0 -> 785 bytes .../__pycache__/cp949prober.cpython-312.pyc | Bin 0 -> 1392 bytes .../chardet/__pycache__/enums.cpython-312.pyc | Bin 0 -> 2992 bytes .../__pycache__/escprober.cpython-312.pyc | Bin 0 -> 4562 bytes .../chardet/__pycache__/escsm.cpython-312.pyc | Bin 0 -> 15306 bytes .../__pycache__/eucjpprober.cpython-312.pyc | Bin 0 -> 4379 bytes .../__pycache__/euckrfreq.cpython-312.pyc | Bin 0 -> 12078 bytes .../__pycache__/euckrprober.cpython-312.pyc | Bin 0 -> 1386 bytes .../__pycache__/euctwfreq.cpython-312.pyc | Bin 0 -> 27200 bytes .../__pycache__/euctwprober.cpython-312.pyc | Bin 0 -> 1386 bytes .../__pycache__/gb2312freq.cpython-312.pyc | Bin 0 -> 19122 bytes .../__pycache__/gb2312prober.cpython-312.pyc | Bin 0 -> 1399 bytes .../__pycache__/hebrewprober.cpython-312.pyc | Bin 0 -> 5818 bytes .../__pycache__/jisfreq.cpython-312.pyc | Bin 0 -> 22151 bytes .../__pycache__/johabfreq.cpython-312.pyc | Bin 0 -> 82999 bytes .../__pycache__/johabprober.cpython-312.pyc | Bin 0 -> 1390 bytes .../__pycache__/jpcntx.cpython-312.pyc | Bin 0 -> 39545 bytes .../langbulgarianmodel.cpython-312.pyc | Bin 0 -> 83118 bytes .../langgreekmodel.cpython-312.pyc | Bin 0 -> 76984 bytes .../langhebrewmodel.cpython-312.pyc | Bin 0 -> 77495 bytes .../langhungarianmodel.cpython-312.pyc | Bin 0 -> 83072 bytes .../langrussianmodel.cpython-312.pyc | Bin 0 -> 105247 bytes .../__pycache__/langthaimodel.cpython-312.pyc | Bin 0 -> 77673 bytes .../langturkishmodel.cpython-312.pyc | Bin 0 -> 77512 bytes .../__pycache__/latin1prober.cpython-312.pyc | Bin 0 -> 6998 bytes .../macromanprober.cpython-312.pyc | Bin 0 -> 7178 bytes .../mbcharsetprober.cpython-312.pyc | Bin 0 -> 3899 bytes .../mbcsgroupprober.cpython-312.pyc | Bin 0 -> 1584 bytes .../__pycache__/mbcssm.cpython-312.pyc | Bin 0 -> 38641 bytes .../__pycache__/resultdict.cpython-312.pyc | Bin 0 -> 628 bytes .../sbcharsetprober.cpython-312.pyc | Bin 0 -> 6383 bytes .../sbcsgroupprober.cpython-312.pyc | Bin 0 -> 2353 bytes .../__pycache__/sjisprober.cpython-312.pyc | Bin 0 -> 4491 bytes .../universaldetector.cpython-312.pyc | Bin 0 -> 12265 bytes .../__pycache__/utf1632prober.cpython-312.pyc | Bin 0 -> 9975 bytes .../__pycache__/utf8prober.cpython-312.pyc | Bin 0 -> 3171 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 484 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 261 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 147 + .../pip/_vendor/chardet/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 191 bytes .../__pycache__/chardetect.cpython-312.pyc | Bin 0 -> 4008 bytes .../pip/_vendor/chardet/cli/chardetect.py | 112 + .../pip/_vendor/chardet/codingstatemachine.py | 90 + .../_vendor/chardet/codingstatemachinedict.py | 19 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 85 + .../pip/_vendor/chardet/escprober.py | 102 + .../pip/_vendor/chardet/escsm.py | 261 + .../pip/_vendor/chardet/eucjpprober.py | 102 + .../pip/_vendor/chardet/euckrfreq.py | 196 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 388 + .../pip/_vendor/chardet/euctwprober.py | 47 + .../pip/_vendor/chardet/gb2312freq.py | 284 + .../pip/_vendor/chardet/gb2312prober.py | 47 + .../pip/_vendor/chardet/hebrewprober.py | 316 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/johabfreq.py | 2382 +++++ .../pip/_vendor/chardet/johabprober.py | 47 + .../pip/_vendor/chardet/jpcntx.py | 238 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4397 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4380 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5725 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4380 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4380 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 147 + .../pip/_vendor/chardet/macromanprober.py | 162 + .../pip/_vendor/chardet/mbcharsetprober.py | 95 + .../pip/_vendor/chardet/mbcsgroupprober.py | 57 + .../pip/_vendor/chardet/mbcssm.py | 661 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 196 bytes .../__pycache__/languages.cpython-312.pyc | Bin 0 -> 9751 bytes .../pip/_vendor/chardet/metadata/languages.py | 352 + .../pip/_vendor/chardet/resultdict.py | 16 + .../pip/_vendor/chardet/sbcharsetprober.py | 162 + .../pip/_vendor/chardet/sbcsgroupprober.py | 88 + .../pip/_vendor/chardet/sjisprober.py | 105 + .../pip/_vendor/chardet/universaldetector.py | 362 + .../pip/_vendor/chardet/utf1632prober.py | 225 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 488 bytes .../colorama/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 3946 bytes .../__pycache__/ansitowin32.cpython-312.pyc | Bin 0 -> 16417 bytes .../__pycache__/initialise.cpython-312.pyc | Bin 0 -> 3546 bytes .../__pycache__/win32.cpython-312.pyc | Bin 0 -> 8122 bytes .../__pycache__/winterm.cpython-312.pyc | Bin 0 -> 9084 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 277 + .../pip/_vendor/colorama/initialise.py | 121 + .../pip/_vendor/colorama/tests/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 194 bytes .../__pycache__/ansi_test.cpython-312.pyc | Bin 0 -> 5463 bytes .../ansitowin32_test.cpython-312.pyc | Bin 0 -> 18099 bytes .../initialise_test.cpython-312.pyc | Bin 0 -> 11744 bytes .../__pycache__/isatty_test.cpython-312.pyc | Bin 0 -> 4900 bytes .../tests/__pycache__/utils.cpython-312.pyc | Bin 0 -> 2484 bytes .../__pycache__/winterm_test.cpython-312.pyc | Bin 0 -> 6608 bytes .../pip/_vendor/colorama/tests/ansi_test.py | 76 + .../colorama/tests/ansitowin32_test.py | 294 + .../_vendor/colorama/tests/initialise_test.py | 189 + .../pip/_vendor/colorama/tests/isatty_test.py | 57 + .../pip/_vendor/colorama/tests/utils.py | 49 + .../_vendor/colorama/tests/winterm_test.py | 131 + .../pip/_vendor/colorama/win32.py | 180 + .../pip/_vendor/colorama/winterm.py | 195 + .../pip/_vendor/distlib/__init__.py | 33 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1265 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 45601 bytes .../__pycache__/database.cpython-312.pyc | Bin 0 -> 66023 bytes .../distlib/__pycache__/index.cpython-312.pyc | Bin 0 -> 24362 bytes .../__pycache__/locators.cpython-312.pyc | Bin 0 -> 60154 bytes .../__pycache__/manifest.cpython-312.pyc | Bin 0 -> 15121 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 7678 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 41795 bytes .../__pycache__/resources.cpython-312.pyc | Bin 0 -> 17321 bytes .../__pycache__/scripts.cpython-312.pyc | Bin 0 -> 19576 bytes .../distlib/__pycache__/util.cpython-312.pyc | Bin 0 -> 88252 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 30362 bytes .../distlib/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 51857 bytes .../pip/_vendor/distlib/compat.py | 1138 +++ .../pip/_vendor/distlib/database.py | 1359 +++ .../pip/_vendor/distlib/index.py | 508 + .../pip/_vendor/distlib/locators.py | 1303 +++ .../pip/_vendor/distlib/manifest.py | 384 + .../pip/_vendor/distlib/markers.py | 167 + .../pip/_vendor/distlib/metadata.py | 1068 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 452 + .../site-packages/pip/_vendor/distlib/util.py | 2025 ++++ .../pip/_vendor/distlib/version.py | 751 ++ .../pip/_vendor/distlib/wheel.py | 1099 +++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 956 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 288 bytes .../distro/__pycache__/distro.cpython-312.pyc | Bin 0 -> 53750 bytes .../pip/_vendor/distro/distro.py | 1399 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 877 bytes .../idna/__pycache__/codec.cpython-312.pyc | Bin 0 -> 4629 bytes .../idna/__pycache__/compat.cpython-312.pyc | Bin 0 -> 883 bytes .../idna/__pycache__/core.cpython-312.pyc | Bin 0 -> 16278 bytes .../idna/__pycache__/idnadata.cpython-312.pyc | Bin 0 -> 38378 bytes .../__pycache__/intranges.cpython-312.pyc | Bin 0 -> 2634 bytes .../__pycache__/package_data.cpython-312.pyc | Bin 0 -> 212 bytes .../__pycache__/uts46data.cpython-312.pyc | Bin 0 -> 158866 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 400 + .../pip/_vendor/idna/idnadata.py | 2151 +++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8600 +++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 57 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1827 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 2021 bytes .../msgpack/__pycache__/ext.cpython-312.pyc | Bin 0 -> 8664 bytes .../__pycache__/fallback.cpython-312.pyc | Bin 0 -> 43572 bytes .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1010 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-312.pyc | Bin 0 -> 626 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 462 bytes .../__pycache__/_manylinux.cpython-312.pyc | Bin 0 -> 12072 bytes .../__pycache__/_musllinux.cpython-312.pyc | Bin 0 -> 6906 bytes .../__pycache__/_structures.cpython-312.pyc | Bin 0 -> 3237 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 14054 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 6942 bytes .../__pycache__/specifiers.cpython-312.pyc | Bin 0 -> 31243 bytes .../__pycache__/tags.cpython-312.pyc | Bin 0 -> 18952 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 5864 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 19935 bytes .../pip/_vendor/packaging/_manylinux.py | 301 + .../pip/_vendor/packaging/_musllinux.py | 136 + .../pip/_vendor/packaging/_structures.py | 61 + .../pip/_vendor/packaging/markers.py | 304 + .../pip/_vendor/packaging/requirements.py | 146 + .../pip/_vendor/packaging/specifiers.py | 802 ++ .../pip/_vendor/packaging/tags.py | 487 + .../pip/_vendor/packaging/utils.py | 136 + .../pip/_vendor/packaging/version.py | 504 + .../pip/_vendor/pkg_resources/__init__.py | 3361 +++++++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 146470 bytes .../pip/_vendor/platformdirs/__init__.py | 566 ++ .../pip/_vendor/platformdirs/__main__.py | 53 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 18025 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 1942 bytes .../__pycache__/android.cpython-312.pyc | Bin 0 -> 9440 bytes .../__pycache__/api.cpython-312.pyc | Bin 0 -> 9668 bytes .../__pycache__/macos.cpython-312.pyc | Bin 0 -> 5633 bytes .../__pycache__/unix.cpython-312.pyc | Bin 0 -> 12437 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 307 bytes .../__pycache__/windows.cpython-312.pyc | Bin 0 -> 12995 bytes .../pip/_vendor/platformdirs/android.py | 210 + .../pip/_vendor/platformdirs/api.py | 223 + .../pip/_vendor/platformdirs/macos.py | 91 + .../pip/_vendor/platformdirs/unix.py | 223 + .../pip/_vendor/platformdirs/version.py | 4 + .../pip/_vendor/platformdirs/windows.py | 255 + .../pip/_vendor/pygments/__init__.py | 82 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3485 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 731 bytes .../__pycache__/cmdline.cpython-312.pyc | Bin 0 -> 26602 bytes .../__pycache__/console.cpython-312.pyc | Bin 0 -> 2623 bytes .../__pycache__/filter.cpython-312.pyc | Bin 0 -> 3229 bytes .../__pycache__/formatter.cpython-312.pyc | Bin 0 -> 4566 bytes .../__pycache__/lexer.cpython-312.pyc | Bin 0 -> 38326 bytes .../__pycache__/modeline.cpython-312.pyc | Bin 0 -> 1565 bytes .../__pycache__/plugin.cpython-312.pyc | Bin 0 -> 3393 bytes .../__pycache__/regexopt.cpython-312.pyc | Bin 0 -> 4078 bytes .../__pycache__/scanner.cpython-312.pyc | Bin 0 -> 4753 bytes .../__pycache__/sphinxext.cpython-312.pyc | Bin 0 -> 11043 bytes .../__pycache__/style.cpython-312.pyc | Bin 0 -> 6671 bytes .../__pycache__/token.cpython-312.pyc | Bin 0 -> 8139 bytes .../__pycache__/unistring.cpython-312.pyc | Bin 0 -> 32985 bytes .../pygments/__pycache__/util.cpython-312.pyc | Bin 0 -> 13978 bytes .../pip/_vendor/pygments/cmdline.py | 668 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 71 + .../pip/_vendor/pygments/filters/__init__.py | 940 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 37933 bytes .../pip/_vendor/pygments/formatter.py | 124 + .../_vendor/pygments/formatters/__init__.py | 158 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6923 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 4212 bytes .../__pycache__/bbcode.cpython-312.pyc | Bin 0 -> 4191 bytes .../__pycache__/groff.cpython-312.pyc | Bin 0 -> 7261 bytes .../__pycache__/html.cpython-312.pyc | Bin 0 -> 40569 bytes .../__pycache__/img.cpython-312.pyc | Bin 0 -> 27040 bytes .../__pycache__/irc.cpython-312.pyc | Bin 0 -> 6062 bytes .../__pycache__/latex.cpython-312.pyc | Bin 0 -> 19951 bytes .../__pycache__/other.cpython-312.pyc | Bin 0 -> 6881 bytes .../__pycache__/pangomarkup.cpython-312.pyc | Bin 0 -> 2927 bytes .../__pycache__/rtf.cpython-312.pyc | Bin 0 -> 6123 bytes .../__pycache__/svg.cpython-312.pyc | Bin 0 -> 9063 bytes .../__pycache__/terminal.cpython-312.pyc | Bin 0 -> 5826 bytes .../__pycache__/terminal256.cpython-312.pyc | Bin 0 -> 15154 bytes .../_vendor/pygments/formatters/_mapping.py | 23 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 170 + .../pip/_vendor/pygments/formatters/html.py | 989 ++ .../pip/_vendor/pygments/formatters/img.py | 645 ++ .../pip/_vendor/pygments/formatters/irc.py | 154 + .../pip/_vendor/pygments/formatters/latex.py | 521 + .../pip/_vendor/pygments/formatters/other.py | 161 + .../pygments/formatters/pangomarkup.py | 83 + .../pip/_vendor/pygments/formatters/rtf.py | 146 + .../pip/_vendor/pygments/formatters/svg.py | 188 + .../_vendor/pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 + .../pip/_vendor/pygments/lexer.py | 943 ++ .../pip/_vendor/pygments/lexers/__init__.py | 362 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 14649 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 64401 bytes .../lexers/__pycache__/python.cpython-312.pyc | Bin 0 -> 42636 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 559 ++ .../pip/_vendor/pygments/lexers/python.py | 1198 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 88 + .../pip/_vendor/pygments/regexopt.py | 91 + .../pip/_vendor/pygments/scanner.py | 104 + .../pip/_vendor/pygments/sphinxext.py | 217 + .../pip/_vendor/pygments/style.py | 197 + .../pip/_vendor/pygments/styles/__init__.py | 103 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4445 bytes .../pip/_vendor/pygments/token.py | 213 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 330 + .../pip/_vendor/pyparsing/__init__.py | 322 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7908 bytes .../__pycache__/actions.cpython-312.pyc | Bin 0 -> 8392 bytes .../__pycache__/common.cpython-312.pyc | Bin 0 -> 13411 bytes .../__pycache__/core.cpython-312.pyc | Bin 0 -> 267705 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 12991 bytes .../__pycache__/helpers.cpython-312.pyc | Bin 0 -> 48498 bytes .../__pycache__/results.cpython-312.pyc | Bin 0 -> 34107 bytes .../__pycache__/testing.cpython-312.pyc | Bin 0 -> 17185 bytes .../__pycache__/unicode.cpython-312.pyc | Bin 0 -> 13181 bytes .../__pycache__/util.cpython-312.pyc | Bin 0 -> 14901 bytes .../pip/_vendor/pyparsing/actions.py | 217 + .../pip/_vendor/pyparsing/common.py | 432 + .../pip/_vendor/pyparsing/core.py | 6115 ++++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 656 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 26810 bytes .../pip/_vendor/pyparsing/exceptions.py | 299 + .../pip/_vendor/pyparsing/helpers.py | 1100 +++ .../pip/_vendor/pyparsing/results.py | 796 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 361 + .../pip/_vendor/pyparsing/util.py | 284 + .../pip/_vendor/pyproject_hooks/__init__.py | 23 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 610 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 371 bytes .../__pycache__/_impl.cpython-312.pyc | Bin 0 -> 14722 bytes .../pip/_vendor/pyproject_hooks/_compat.py | 8 + .../pip/_vendor/pyproject_hooks/_impl.py | 330 + .../pyproject_hooks/_in_process/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1077 bytes .../__pycache__/_in_process.cpython-312.pyc | Bin 0 -> 14394 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5450 bytes .../__pycache__/__version__.cpython-312.pyc | Bin 0 -> 581 bytes .../_internal_utils.cpython-312.pyc | Bin 0 -> 2021 bytes .../__pycache__/adapters.cpython-312.pyc | Bin 0 -> 21277 bytes .../requests/__pycache__/api.cpython-312.pyc | Bin 0 -> 7201 bytes .../requests/__pycache__/auth.cpython-312.pyc | Bin 0 -> 13920 bytes .../__pycache__/certs.cpython-312.pyc | Bin 0 -> 919 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 1504 bytes .../__pycache__/cookies.cpython-312.pyc | Bin 0 -> 25243 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7044 bytes .../requests/__pycache__/help.cpython-312.pyc | Bin 0 -> 4309 bytes .../__pycache__/hooks.cpython-312.pyc | Bin 0 -> 1049 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 35445 bytes .../__pycache__/packages.cpython-312.pyc | Bin 0 -> 769 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 27754 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 5956 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 5614 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 36266 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 50 + .../pip/_vendor/requests/adapters.py | 538 ++ .../site-packages/pip/_vendor/requests/api.py | 157 + .../pip/_vendor/requests/auth.py | 315 + .../pip/_vendor/requests/certs.py | 24 + .../pip/_vendor/requests/compat.py | 67 + .../pip/_vendor/requests/cookies.py | 561 ++ .../pip/_vendor/requests/exceptions.py | 141 + .../pip/_vendor/requests/help.py | 131 + .../pip/_vendor/requests/hooks.py | 33 + .../pip/_vendor/requests/models.py | 1034 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 833 ++ .../pip/_vendor/requests/status_codes.py | 128 + .../pip/_vendor/requests/structures.py | 99 + .../pip/_vendor/requests/utils.py | 1094 +++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 631 bytes .../__pycache__/providers.cpython-312.pyc | Bin 0 -> 6848 bytes .../__pycache__/reporters.cpython-312.pyc | Bin 0 -> 2651 bytes .../__pycache__/resolvers.cpython-312.pyc | Bin 0 -> 25894 bytes .../__pycache__/structs.cpython-312.pyc | Bin 0 -> 10503 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 197 bytes .../collections_abc.cpython-312.pyc | Bin 0 -> 417 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 547 ++ .../pip/_vendor/resolvelib/structs.py | 170 + .../pip/_vendor/rich/__init__.py | 177 + .../pip/_vendor/rich/__main__.py | 274 + .../rich/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7012 bytes .../rich/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 10301 bytes .../__pycache__/_cell_widths.cpython-312.pyc | Bin 0 -> 7818 bytes .../__pycache__/_emoji_codes.cpython-312.pyc | Bin 0 -> 205973 bytes .../_emoji_replace.cpython-312.pyc | Bin 0 -> 1726 bytes .../_export_format.cpython-312.pyc | Bin 0 -> 2318 bytes .../__pycache__/_extension.cpython-312.pyc | Bin 0 -> 534 bytes .../rich/__pycache__/_fileno.cpython-312.pyc | Bin 0 -> 852 bytes .../rich/__pycache__/_inspect.cpython-312.pyc | Bin 0 -> 12074 bytes .../__pycache__/_log_render.cpython-312.pyc | Bin 0 -> 4144 bytes .../rich/__pycache__/_loop.cpython-312.pyc | Bin 0 -> 1882 bytes .../__pycache__/_null_file.cpython-312.pyc | Bin 0 -> 3617 bytes .../__pycache__/_palettes.cpython-312.pyc | Bin 0 -> 5157 bytes .../rich/__pycache__/_pick.cpython-312.pyc | Bin 0 -> 723 bytes .../rich/__pycache__/_ratio.cpython-312.pyc | Bin 0 -> 6576 bytes .../__pycache__/_spinners.cpython-312.pyc | Bin 0 -> 13176 bytes .../rich/__pycache__/_stack.cpython-312.pyc | Bin 0 -> 962 bytes .../rich/__pycache__/_timer.cpython-312.pyc | Bin 0 -> 862 bytes .../_win32_console.cpython-312.pyc | Bin 0 -> 28973 bytes .../rich/__pycache__/_windows.cpython-312.pyc | Bin 0 -> 2487 bytes .../_windows_renderer.cpython-312.pyc | Bin 0 -> 3570 bytes .../rich/__pycache__/_wrap.cpython-312.pyc | Bin 0 -> 2357 bytes .../rich/__pycache__/abc.cpython-312.pyc | Bin 0 -> 1605 bytes .../rich/__pycache__/align.cpython-312.pyc | Bin 0 -> 12319 bytes .../rich/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 9103 bytes .../rich/__pycache__/bar.cpython-312.pyc | Bin 0 -> 4269 bytes .../rich/__pycache__/box.cpython-312.pyc | Bin 0 -> 11855 bytes .../rich/__pycache__/cells.cpython-312.pyc | Bin 0 -> 5615 bytes .../rich/__pycache__/color.cpython-312.pyc | Bin 0 -> 26567 bytes .../__pycache__/color_triplet.cpython-312.pyc | Bin 0 -> 1698 bytes .../rich/__pycache__/columns.cpython-312.pyc | Bin 0 -> 8584 bytes .../rich/__pycache__/console.cpython-312.pyc | Bin 0 -> 113790 bytes .../__pycache__/constrain.cpython-312.pyc | Bin 0 -> 2255 bytes .../__pycache__/containers.cpython-312.pyc | Bin 0 -> 9223 bytes .../rich/__pycache__/control.cpython-312.pyc | Bin 0 -> 10926 bytes .../default_styles.cpython-312.pyc | Bin 0 -> 10370 bytes .../rich/__pycache__/diagnose.cpython-312.pyc | Bin 0 -> 1484 bytes .../rich/__pycache__/emoji.cpython-312.pyc | Bin 0 -> 4206 bytes .../rich/__pycache__/errors.cpython-312.pyc | Bin 0 -> 1842 bytes .../__pycache__/file_proxy.cpython-312.pyc | Bin 0 -> 3574 bytes .../rich/__pycache__/filesize.cpython-312.pyc | Bin 0 -> 3079 bytes .../__pycache__/highlighter.cpython-312.pyc | Bin 0 -> 9895 bytes .../rich/__pycache__/json.cpython-312.pyc | Bin 0 -> 6032 bytes .../rich/__pycache__/jupyter.cpython-312.pyc | Bin 0 -> 5206 bytes .../rich/__pycache__/layout.cpython-312.pyc | Bin 0 -> 20217 bytes .../rich/__pycache__/live.cpython-312.pyc | Bin 0 -> 19140 bytes .../__pycache__/live_render.cpython-312.pyc | Bin 0 -> 4891 bytes .../rich/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13551 bytes .../rich/__pycache__/markup.cpython-312.pyc | Bin 0 -> 9295 bytes .../rich/__pycache__/measure.cpython-312.pyc | Bin 0 -> 6373 bytes .../rich/__pycache__/padding.cpython-312.pyc | Bin 0 -> 7131 bytes .../rich/__pycache__/pager.cpython-312.pyc | Bin 0 -> 1817 bytes .../rich/__pycache__/palette.cpython-312.pyc | Bin 0 -> 5311 bytes .../rich/__pycache__/panel.cpython-312.pyc | Bin 0 -> 12094 bytes .../rich/__pycache__/pretty.cpython-312.pyc | Bin 0 -> 40053 bytes .../rich/__pycache__/progress.cpython-312.pyc | Bin 0 -> 75075 bytes .../__pycache__/progress_bar.cpython-312.pyc | Bin 0 -> 10386 bytes .../rich/__pycache__/prompt.cpython-312.pyc | Bin 0 -> 14778 bytes .../rich/__pycache__/protocol.cpython-312.pyc | Bin 0 -> 1789 bytes .../rich/__pycache__/region.cpython-312.pyc | Bin 0 -> 564 bytes .../rich/__pycache__/repr.cpython-312.pyc | Bin 0 -> 6623 bytes .../rich/__pycache__/rule.cpython-312.pyc | Bin 0 -> 6565 bytes .../rich/__pycache__/scope.cpython-312.pyc | Bin 0 -> 3827 bytes .../rich/__pycache__/screen.cpython-312.pyc | Bin 0 -> 2481 bytes .../rich/__pycache__/segment.cpython-312.pyc | Bin 0 -> 28158 bytes .../rich/__pycache__/spinner.cpython-312.pyc | Bin 0 -> 6061 bytes .../rich/__pycache__/status.cpython-312.pyc | Bin 0 -> 6065 bytes .../rich/__pycache__/style.cpython-312.pyc | Bin 0 -> 33511 bytes .../rich/__pycache__/styled.cpython-312.pyc | Bin 0 -> 2136 bytes .../rich/__pycache__/syntax.cpython-312.pyc | Bin 0 -> 39609 bytes .../rich/__pycache__/table.cpython-312.pyc | Bin 0 -> 43581 bytes .../terminal_theme.cpython-312.pyc | Bin 0 -> 3345 bytes .../rich/__pycache__/text.cpython-312.pyc | Bin 0 -> 58960 bytes .../rich/__pycache__/theme.cpython-312.pyc | Bin 0 -> 6337 bytes .../rich/__pycache__/themes.cpython-312.pyc | Bin 0 -> 311 bytes .../__pycache__/traceback.cpython-312.pyc | Bin 0 -> 31545 bytes .../rich/__pycache__/tree.cpython-312.pyc | Bin 0 -> 11436 bytes .../pip/_vendor/rich/_cell_widths.py | 451 + .../pip/_vendor/rich/_emoji_codes.py | 3610 +++++++ .../pip/_vendor/rich/_emoji_replace.py | 32 + .../pip/_vendor/rich/_export_format.py | 76 + .../pip/_vendor/rich/_extension.py | 10 + .../site-packages/pip/_vendor/rich/_fileno.py | 24 + .../pip/_vendor/rich/_inspect.py | 270 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_null_file.py | 69 + .../pip/_vendor/rich/_palettes.py | 309 + .../site-packages/pip/_vendor/rich/_pick.py | 17 + .../site-packages/pip/_vendor/rich/_ratio.py | 160 + .../pip/_vendor/rich/_spinners.py | 482 + .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_win32_console.py | 662 ++ .../pip/_vendor/rich/_windows.py | 72 + .../pip/_vendor/rich/_windows_renderer.py | 56 + .../site-packages/pip/_vendor/rich/_wrap.py | 56 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 311 + .../site-packages/pip/_vendor/rich/ansi.py | 240 + .../site-packages/pip/_vendor/rich/bar.py | 94 + .../site-packages/pip/_vendor/rich/box.py | 517 + .../site-packages/pip/_vendor/rich/cells.py | 154 + .../site-packages/pip/_vendor/rich/color.py | 622 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2633 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 225 + .../pip/_vendor/rich/default_styles.py | 190 + .../pip/_vendor/rich/diagnose.py | 37 + .../site-packages/pip/_vendor/rich/emoji.py | 96 + .../site-packages/pip/_vendor/rich/errors.py | 34 + .../pip/_vendor/rich/file_proxy.py | 57 + .../pip/_vendor/rich/filesize.py | 89 + .../pip/_vendor/rich/highlighter.py | 232 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 101 + .../site-packages/pip/_vendor/rich/layout.py | 443 + .../site-packages/pip/_vendor/rich/live.py | 375 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 289 + .../site-packages/pip/_vendor/rich/markup.py | 246 + .../site-packages/pip/_vendor/rich/measure.py | 151 + .../site-packages/pip/_vendor/rich/padding.py | 141 + .../site-packages/pip/_vendor/rich/pager.py | 34 + .../site-packages/pip/_vendor/rich/palette.py | 100 + .../site-packages/pip/_vendor/rich/panel.py | 308 + .../site-packages/pip/_vendor/rich/pretty.py | 994 ++ .../pip/_vendor/rich/progress.py | 1702 ++++ .../pip/_vendor/rich/progress_bar.py | 224 + .../site-packages/pip/_vendor/rich/prompt.py | 376 + .../pip/_vendor/rich/protocol.py | 42 + .../site-packages/pip/_vendor/rich/region.py | 10 + .../site-packages/pip/_vendor/rich/repr.py | 149 + .../site-packages/pip/_vendor/rich/rule.py | 130 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 739 ++ .../site-packages/pip/_vendor/rich/spinner.py | 137 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 796 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 948 ++ .../site-packages/pip/_vendor/rich/table.py | 1002 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1307 +++ .../site-packages/pip/_vendor/rich/theme.py | 115 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 756 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 608 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 27083 bytes .../__pycache__/_asyncio.cpython-312.pyc | Bin 0 -> 4803 bytes .../__pycache__/_utils.cpython-312.pyc | Bin 0 -> 2312 bytes .../__pycache__/after.cpython-312.pyc | Bin 0 -> 1621 bytes .../__pycache__/before.cpython-312.pyc | Bin 0 -> 1461 bytes .../__pycache__/before_sleep.cpython-312.pyc | Bin 0 -> 2299 bytes .../tenacity/__pycache__/nap.cpython-312.pyc | Bin 0 -> 1409 bytes .../__pycache__/retry.cpython-312.pyc | Bin 0 -> 14278 bytes .../tenacity/__pycache__/stop.cpython-312.pyc | Bin 0 -> 5565 bytes .../__pycache__/tornadoweb.cpython-312.pyc | Bin 0 -> 2583 bytes .../tenacity/__pycache__/wait.cpython-312.pyc | Bin 0 -> 12410 bytes .../pip/_vendor/tenacity/_asyncio.py | 94 + .../pip/_vendor/tenacity/_utils.py | 76 + .../pip/_vendor/tenacity/after.py | 51 + .../pip/_vendor/tenacity/before.py | 46 + .../pip/_vendor/tenacity/before_sleep.py | 71 + .../site-packages/pip/_vendor/tenacity/nap.py | 43 + .../pip/_vendor/tenacity/retry.py | 272 + .../pip/_vendor/tenacity/stop.py | 103 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 228 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 381 bytes .../tomli/__pycache__/_parser.cpython-312.pyc | Bin 0 -> 26924 bytes .../tomli/__pycache__/_re.cpython-312.pyc | Bin 0 -> 3905 bytes .../tomli/__pycache__/_types.cpython-312.pyc | Bin 0 -> 363 bytes .../pip/_vendor/tomli/_parser.py | 691 ++ .../site-packages/pip/_vendor/tomli/_re.py | 107 + .../site-packages/pip/_vendor/tomli/_types.py | 10 + .../pip/_vendor/truststore/__init__.py | 13 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 615 bytes .../__pycache__/_api.cpython-312.pyc | Bin 0 -> 15794 bytes .../__pycache__/_macos.cpython-312.pyc | Bin 0 -> 16659 bytes .../__pycache__/_openssl.cpython-312.pyc | Bin 0 -> 2212 bytes .../_ssl_constants.cpython-312.pyc | Bin 0 -> 1096 bytes .../__pycache__/_windows.cpython-312.pyc | Bin 0 -> 15503 bytes .../pip/_vendor/truststore/_api.py | 302 + .../pip/_vendor/truststore/_macos.py | 501 + .../pip/_vendor/truststore/_openssl.py | 66 + .../pip/_vendor/truststore/_ssl_constants.py | 31 + .../pip/_vendor/truststore/_windows.py | 554 ++ .../pip/_vendor/typing_extensions.py | 3072 ++++++ .../pip/_vendor/urllib3/__init__.py | 102 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3402 bytes .../__pycache__/_collections.cpython-312.pyc | Bin 0 -> 15928 bytes .../__pycache__/_version.cpython-312.pyc | Bin 0 -> 215 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 20404 bytes .../connectionpool.cpython-312.pyc | Bin 0 -> 36276 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 13490 bytes .../__pycache__/fields.cpython-312.pyc | Bin 0 -> 10410 bytes .../__pycache__/filepost.cpython-312.pyc | Bin 0 -> 4015 bytes .../__pycache__/poolmanager.cpython-312.pyc | Bin 0 -> 20299 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 7291 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 33965 bytes .../pip/_vendor/urllib3/_collections.py | 337 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 572 ++ .../pip/_vendor/urllib3/connectionpool.py | 1132 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 195 bytes .../_appengine_environ.cpython-312.pyc | Bin 0 -> 1845 bytes .../__pycache__/appengine.cpython-312.pyc | Bin 0 -> 11561 bytes .../__pycache__/ntlmpool.cpython-312.pyc | Bin 0 -> 5716 bytes .../__pycache__/pyopenssl.cpython-312.pyc | Bin 0 -> 24447 bytes .../securetransport.cpython-312.pyc | Bin 0 -> 35553 bytes .../contrib/__pycache__/socks.cpython-312.pyc | Bin 0 -> 7508 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 212 bytes .../__pycache__/bindings.cpython-312.pyc | Bin 0 -> 17424 bytes .../__pycache__/low_level.cpython-312.pyc | Bin 0 -> 14798 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 518 + .../urllib3/contrib/securetransport.py | 921 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 323 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 196 bytes .../packages/__pycache__/six.cpython-312.pyc | Bin 0 -> 41316 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../__pycache__/makefile.cpython-312.pyc | Bin 0 -> 1822 bytes .../weakref_finalize.cpython-312.pyc | Bin 0 -> 7328 bytes .../urllib3/packages/backports/makefile.py | 51 + .../packages/backports/weakref_finalize.py | 155 + .../pip/_vendor/urllib3/packages/six.py | 1076 +++ .../pip/_vendor/urllib3/poolmanager.py | 537 + .../pip/_vendor/urllib3/request.py | 191 + .../pip/_vendor/urllib3/response.py | 879 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1143 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 4753 bytes .../util/__pycache__/proxy.cpython-312.pyc | Bin 0 -> 1549 bytes .../util/__pycache__/queue.cpython-312.pyc | Bin 0 -> 1349 bytes .../util/__pycache__/request.cpython-312.pyc | Bin 0 -> 4180 bytes .../util/__pycache__/response.cpython-312.pyc | Bin 0 -> 2986 bytes .../util/__pycache__/retry.cpython-312.pyc | Bin 0 -> 21715 bytes .../util/__pycache__/ssl_.cpython-312.pyc | Bin 0 -> 15100 bytes .../ssl_match_hostname.cpython-312.pyc | Bin 0 -> 5068 bytes .../__pycache__/ssltransport.cpython-312.pyc | Bin 0 -> 10769 bytes .../util/__pycache__/timeout.cpython-312.pyc | Bin 0 -> 11136 bytes .../util/__pycache__/url.cpython-312.pyc | Bin 0 -> 15792 bytes .../util/__pycache__/wait.cpython-312.pyc | Bin 0 -> 4400 bytes .../pip/_vendor/urllib3/util/connection.py | 149 + .../pip/_vendor/urllib3/util/proxy.py | 57 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 137 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 622 ++ .../pip/_vendor/urllib3/util/ssl_.py | 495 + .../urllib3/util/ssl_match_hostname.py | 159 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 271 + .../pip/_vendor/urllib3/util/url.py | 435 + .../pip/_vendor/urllib3/util/wait.py | 152 + .../site-packages/pip/_vendor/vendor.txt | 24 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 11998 bytes .../__pycache__/labels.cpython-312.pyc | Bin 0 -> 7129 bytes .../__pycache__/mklabels.cpython-312.pyc | Bin 0 -> 2696 bytes .../__pycache__/tests.cpython-312.pyc | Bin 0 -> 9248 bytes .../x_user_defined.cpython-312.pyc | Bin 0 -> 3292 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../lib/python3.12/site-packages/pip/py.typed | 4 + .../pysqlite3-0.5.4.dist-info/INSTALLER | 1 + .../pysqlite3-0.5.4.dist-info/LICENSE | 19 + .../pysqlite3-0.5.4.dist-info/METADATA | 20 + .../pysqlite3-0.5.4.dist-info/RECORD | 12 + .../pysqlite3-0.5.4.dist-info/REQUESTED | 0 .../pysqlite3-0.5.4.dist-info/WHEEL | 5 + .../pysqlite3-0.5.4.dist-info/top_level.txt | 1 + .../site-packages/pysqlite3/__init__.py | 23 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 217 bytes .../__pycache__/dbapi2.cpython-312.pyc | Bin 0 -> 3752 bytes .../_sqlite3.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 387816 bytes .../site-packages/pysqlite3/dbapi2.py | 90 + .../werkzeug-3.1.3.dist-info/INSTALLER | 1 + .../werkzeug-3.1.3.dist-info/LICENSE.txt | 28 + .../werkzeug-3.1.3.dist-info/METADATA | 99 + .../werkzeug-3.1.3.dist-info/RECORD | 116 + .../werkzeug-3.1.3.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 330 bytes .../__pycache__/_internal.cpython-312.pyc | Bin 0 -> 9750 bytes .../__pycache__/_reloader.cpython-312.pyc | Bin 0 -> 20601 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 33316 bytes .../__pycache__/formparser.cpython-312.pyc | Bin 0 -> 17016 bytes .../werkzeug/__pycache__/http.cpython-312.pyc | Bin 0 -> 50241 bytes .../__pycache__/local.cpython-312.pyc | Bin 0 -> 28471 bytes .../__pycache__/security.cpython-312.pyc | Bin 0 -> 7124 bytes .../__pycache__/serving.cpython-312.pyc | Bin 0 -> 46118 bytes .../werkzeug/__pycache__/test.cpython-312.pyc | Bin 0 -> 59860 bytes .../__pycache__/testapp.cpython-312.pyc | Bin 0 -> 8881 bytes .../werkzeug/__pycache__/urls.cpython-312.pyc | Bin 0 -> 8260 bytes .../__pycache__/user_agent.cpython-312.pyc | Bin 0 -> 2143 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 28134 bytes .../werkzeug/__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 25206 bytes .../site-packages/werkzeug/_internal.py | 211 + .../site-packages/werkzeug/_reloader.py | 471 + .../werkzeug/datastructures/__init__.py | 64 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2407 bytes .../__pycache__/accept.cpython-312.pyc | Bin 0 -> 15934 bytes .../__pycache__/auth.cpython-312.pyc | Bin 0 -> 14449 bytes .../__pycache__/cache_control.cpython-312.pyc | Bin 0 -> 12216 bytes .../__pycache__/csp.cpython-312.pyc | Bin 0 -> 6177 bytes .../__pycache__/etag.cpython-312.pyc | Bin 0 -> 5392 bytes .../__pycache__/file_storage.cpython-312.pyc | Bin 0 -> 8814 bytes .../__pycache__/headers.cpython-312.pyc | Bin 0 -> 30510 bytes .../__pycache__/mixins.cpython-312.pyc | Bin 0 -> 16390 bytes .../__pycache__/range.cpython-312.pyc | Bin 0 -> 10045 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 59081 bytes .../werkzeug/datastructures/accept.py | 350 + .../werkzeug/datastructures/auth.py | 317 + .../werkzeug/datastructures/cache_control.py | 273 + .../werkzeug/datastructures/csp.py | 100 + .../werkzeug/datastructures/etag.py | 106 + .../werkzeug/datastructures/file_storage.py | 209 + .../werkzeug/datastructures/headers.py | 662 ++ .../werkzeug/datastructures/mixins.py | 317 + .../werkzeug/datastructures/range.py | 214 + .../werkzeug/datastructures/structures.py | 1239 +++ .../site-packages/werkzeug/debug/__init__.py | 565 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 23466 bytes .../debug/__pycache__/console.cpython-312.pyc | Bin 0 -> 11627 bytes .../debug/__pycache__/repr.cpython-312.pyc | Bin 0 -> 13800 bytes .../debug/__pycache__/tbtools.cpython-312.pyc | Bin 0 -> 16999 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../site-packages/werkzeug/debug/repr.py | 282 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 344 + .../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 | 450 + .../site-packages/werkzeug/exceptions.py | 894 ++ .../site-packages/werkzeug/formparser.py | 430 + .../python3.12/site-packages/werkzeug/http.py | 1405 +++ .../site-packages/werkzeug/local.py | 653 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 187 bytes .../__pycache__/dispatcher.cpython-312.pyc | Bin 0 -> 3305 bytes .../__pycache__/http_proxy.cpython-312.pyc | Bin 0 -> 9397 bytes .../__pycache__/lint.cpython-312.pyc | Bin 0 -> 17767 bytes .../__pycache__/profiler.cpython-312.pyc | Bin 0 -> 7191 bytes .../__pycache__/proxy_fix.cpython-312.pyc | Bin 0 -> 7188 bytes .../__pycache__/shared_data.cpython-312.pyc | Bin 0 -> 12743 bytes .../werkzeug/middleware/dispatcher.py | 81 + .../werkzeug/middleware/http_proxy.py | 236 + .../site-packages/werkzeug/middleware/lint.py | 439 + .../werkzeug/middleware/profiler.py | 155 + .../werkzeug/middleware/proxy_fix.py | 183 + .../werkzeug/middleware/shared_data.py | 283 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 134 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4660 bytes .../__pycache__/converters.cpython-312.pyc | Bin 0 -> 10900 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7903 bytes .../routing/__pycache__/map.cpython-312.pyc | Bin 0 -> 39828 bytes .../__pycache__/matcher.cpython-312.pyc | Bin 0 -> 8271 bytes .../routing/__pycache__/rules.cpython-312.pyc | Bin 0 -> 39162 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 152 + .../site-packages/werkzeug/routing/map.py | 951 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 928 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 183 bytes .../sansio/__pycache__/http.cpython-312.pyc | Bin 0 -> 5634 bytes .../__pycache__/multipart.cpython-312.pyc | Bin 0 -> 14042 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 21876 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 31731 bytes .../sansio/__pycache__/utils.cpython-312.pyc | Bin 0 -> 6173 bytes .../site-packages/werkzeug/sansio/http.py | 170 + .../werkzeug/sansio/multipart.py | 323 + .../site-packages/werkzeug/sansio/request.py | 534 + .../site-packages/werkzeug/sansio/response.py | 763 ++ .../site-packages/werkzeug/sansio/utils.py | 167 + .../site-packages/werkzeug/security.py | 166 + .../site-packages/werkzeug/serving.py | 1125 +++ .../python3.12/site-packages/werkzeug/test.py | 1464 +++ .../site-packages/werkzeug/testapp.py | 194 + .../python3.12/site-packages/werkzeug/urls.py | 203 + .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 691 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 307 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 26137 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 34562 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 831 ++ .../python3.12/site-packages/werkzeug/wsgi.py | 595 ++ .python/lib64 | 1 + .python/pyvenv.cfg | 5 + README | 10 + __pycache__/calc.cpython-312.pyc | Bin 0 -> 5754 bytes __pycache__/csv.cpython-312.pyc | Bin 0 -> 3159 bytes __pycache__/db.cpython-312.pyc | Bin 0 -> 4795 bytes __pycache__/main.cpython-312.pyc | Bin 0 -> 5690 bytes calc.py | 179 + db.py | 98 + finance.db | Bin 0 -> 12288 bytes main.py | 130 + requirements.txt | 8 + templates/index.html | 232 + 1355 files changed, 249815 insertions(+) create mode 100644 .python/bin/Activate.ps1 create mode 100644 .python/bin/activate create mode 100644 .python/bin/activate.csh create mode 100644 .python/bin/activate.fish create mode 100755 .python/bin/flask create mode 100755 .python/bin/pip create mode 100755 .python/bin/pip3 create mode 100755 .python/bin/pip3.12 create mode 120000 .python/bin/python create mode 120000 .python/bin/python3 create mode 120000 .python/bin/python3.12 create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt create mode 100644 .python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/blinker/__init__.py create mode 100644 .python/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/blinker/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/blinker/_utilities.py create mode 100644 .python/lib/python3.12/site-packages/blinker/base.py create mode 100644 .python/lib/python3.12/site-packages/blinker/py.typed create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 .python/lib/python3.12/site-packages/click/__init__.py create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/click/_compat.py create mode 100644 .python/lib/python3.12/site-packages/click/_termui_impl.py create mode 100644 .python/lib/python3.12/site-packages/click/_textwrap.py create mode 100644 .python/lib/python3.12/site-packages/click/_winconsole.py create mode 100644 .python/lib/python3.12/site-packages/click/core.py create mode 100644 .python/lib/python3.12/site-packages/click/decorators.py create mode 100644 .python/lib/python3.12/site-packages/click/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/click/formatting.py create mode 100644 .python/lib/python3.12/site-packages/click/globals.py create mode 100644 .python/lib/python3.12/site-packages/click/parser.py create mode 100644 .python/lib/python3.12/site-packages/click/py.typed create mode 100644 .python/lib/python3.12/site-packages/click/shell_completion.py create mode 100644 .python/lib/python3.12/site-packages/click/termui.py create mode 100644 .python/lib/python3.12/site-packages/click/testing.py create mode 100644 .python/lib/python3.12/site-packages/click/types.py create mode 100644 .python/lib/python3.12/site-packages/click/utils.py create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt create mode 100644 .python/lib/python3.12/site-packages/flask/__init__.py create mode 100644 .python/lib/python3.12/site-packages/flask/__main__.py create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/app.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/blueprints.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/cli.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/config.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/ctx.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/debughelpers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/globals.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/helpers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/signals.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/testing.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/typing.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/__pycache__/wrappers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/app.py create mode 100644 .python/lib/python3.12/site-packages/flask/blueprints.py create mode 100644 .python/lib/python3.12/site-packages/flask/cli.py create mode 100644 .python/lib/python3.12/site-packages/flask/config.py create mode 100644 .python/lib/python3.12/site-packages/flask/ctx.py create mode 100644 .python/lib/python3.12/site-packages/flask/debughelpers.py create mode 100644 .python/lib/python3.12/site-packages/flask/globals.py create mode 100644 .python/lib/python3.12/site-packages/flask/helpers.py create mode 100644 .python/lib/python3.12/site-packages/flask/json/__init__.py create mode 100644 .python/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/json/__pycache__/tag.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/json/provider.py create mode 100644 .python/lib/python3.12/site-packages/flask/json/tag.py create mode 100644 .python/lib/python3.12/site-packages/flask/logging.py create mode 100644 .python/lib/python3.12/site-packages/flask/py.typed create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/README.md create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/__pycache__/scaffold.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/app.py create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/blueprints.py create mode 100644 .python/lib/python3.12/site-packages/flask/sansio/scaffold.py create mode 100644 .python/lib/python3.12/site-packages/flask/sessions.py create mode 100644 .python/lib/python3.12/site-packages/flask/signals.py create mode 100644 .python/lib/python3.12/site-packages/flask/templating.py create mode 100644 .python/lib/python3.12/site-packages/flask/testing.py create mode 100644 .python/lib/python3.12/site-packages/flask/typing.py create mode 100644 .python/lib/python3.12/site-packages/flask/views.py create mode 100644 .python/lib/python3.12/site-packages/flask/wrappers.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__init__.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/__pycache__/url_safe.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/_json.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/encoding.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/exc.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/py.typed create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/serializer.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/signer.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/timed.py create mode 100644 .python/lib/python3.12/site-packages/itsdangerous/url_safe.py create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt create mode 100644 .python/lib/python3.12/site-packages/jinja2/__init__.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/optimizer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/parser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/jinja2/_identifier.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/async_utils.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/bccache.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/compiler.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/constants.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/debug.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/defaults.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/environment.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/ext.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/filters.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/idtracking.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/lexer.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/loaders.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/meta.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/nativetypes.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/nodes.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/optimizer.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/parser.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/py.typed create mode 100644 .python/lib/python3.12/site-packages/jinja2/runtime.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/sandbox.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/tests.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/utils.py create mode 100644 .python/lib/python3.12/site-packages/jinja2/visitor.py create mode 100644 .python/lib/python3.12/site-packages/markupsafe/__init__.py create mode 100644 .python/lib/python3.12/site-packages/markupsafe/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/markupsafe/__pycache__/_native.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/markupsafe/_native.py create mode 100644 .python/lib/python3.12/site-packages/markupsafe/_speedups.c create mode 100755 .python/lib/python3.12/site-packages/markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so create mode 100644 .python/lib/python3.12/site-packages/markupsafe/_speedups.pyi create mode 100644 .python/lib/python3.12/site-packages/markupsafe/py.typed create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/AUTHORS.txt create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/REQUESTED create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/entry_points.txt create mode 100644 .python/lib/python3.12/site-packages/pip-24.0.dist-info/top_level.txt create mode 100644 .python/lib/python3.12/site-packages/pip/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/__pip-runner__.py create mode 100644 .python/lib/python3.12/site-packages/pip/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/__pycache__/__pip-runner__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/main.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/build_env.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/base_command.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/command_context.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/main.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/main_parser.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/parser.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/req_command.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/spinners.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/cli/status_codes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/check.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/completion.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/debug.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/download.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/hash.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/help.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/index.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/list.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/search.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/show.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/check.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/completion.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/configuration.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/debug.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/download.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/freeze.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/hash.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/help.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/index.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/inspect.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/install.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/list.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/search.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/show.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/uninstall.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/commands/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/configuration.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/base.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/installed.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/sdist.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/distributions/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/collector.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/package_finder.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/index/sources.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/_distutils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/locations/base.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/main.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/_json.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/base.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/candidate.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/direct_url.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/format_control.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/index.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/installation_report.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/link.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/scheme.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/search_scope.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/target_python.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/models/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/auth.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/download.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/session.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/check.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/freeze.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/operations/prepare.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/pyproject.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/constructors.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/req_file.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/req_install.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/req_set.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/base.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/self_outdated_check.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/_jaraco_text.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/_log.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/appdirs.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/datetime.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/deprecation.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/egg_link.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/encoding.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/filesystem.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/filetypes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/glibc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/hashes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/logging.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/misc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/models.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/packaging.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/subprocess.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/unpacking.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/urls.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/utils/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/git.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/subversion.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 .python/lib/python3.12/site-packages/pip/_internal/wheel_builder.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/__pycache__/six.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/certifi/core.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/codingstatemachinedict.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/enums.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/johabfreq.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/johabprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/macromanprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/resultdict.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/utf1632prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/chardet/version.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/ansi_test.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/ansitowin32_test.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/initialise_test.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/isatty_test.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/tests/winterm_test.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/win32.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/database.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/index.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/locators.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/markers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/resources.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/util.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/version.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/distro/distro.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/codec.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/core.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/intranges.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/package_data.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/markers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/tags.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/packaging/version.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/console.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/filter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/style.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/token.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pygments/util.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_impl.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/help.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/__version__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/adapters.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/api.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/auth.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/certs.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/compat.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/cookies.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/help.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/hooks.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/models.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/packages.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/sessions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/structures.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/requests/utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__main__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/json.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/status.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_extension.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_fileno.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_loop.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_null_file.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_pick.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_stack.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_timer.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_windows.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/abc.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/align.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/ansi.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/bar.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/box.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/cells.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/color.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/columns.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/console.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/constrain.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/containers.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/control.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/emoji.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/errors.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/filesize.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/json.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/layout.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/live.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/live_render.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/logging.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/markup.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/measure.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/padding.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/pager.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/palette.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/panel.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/pretty.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/progress.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/prompt.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/protocol.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/region.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/repr.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/rule.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/scope.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/screen.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/segment.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/spinner.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/status.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/style.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/styled.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/syntax.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/table.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/text.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/theme.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/themes.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/traceback.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/rich/tree.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/six.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/after.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/before.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/_re.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/tomli/_types.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/_api.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/_openssl.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/_ssl_constants.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/truststore/_windows.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/typing_extensions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/request.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/response.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/vendor.txt create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 .python/lib/python3.12/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 .python/lib/python3.12/site-packages/pip/py.typed create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/LICENSE create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/REQUESTED create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/pysqlite3-0.5.4.dist-info/top_level.txt create mode 100644 .python/lib/python3.12/site-packages/pysqlite3/__init__.py create mode 100644 .python/lib/python3.12/site-packages/pysqlite3/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/pysqlite3/__pycache__/dbapi2.cpython-312.pyc create mode 100755 .python/lib/python3.12/site-packages/pysqlite3/_sqlite3.cpython-312-x86_64-linux-gnu.so create mode 100644 .python/lib/python3.12/site-packages/pysqlite3/dbapi2.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/INSTALLER create mode 100644 .python/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/LICENSE.txt create mode 100644 .python/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/METADATA create mode 100644 .python/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/RECORD create mode 100644 .python/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/WHEEL create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/_internal.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/_reloader.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/formparser.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/http.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/local.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/security.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/serving.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/test.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/testapp.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/urls.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/user_agent.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/__pycache__/wsgi.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/_internal.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/_reloader.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/range.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/accept.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/auth.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/csp.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/etag.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/headers.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/mixins.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/range.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/datastructures/structures.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/__pycache__/console.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/__pycache__/repr.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/console.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/repr.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/console.png create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/less.png create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/more.png create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/shared/style.css create mode 100644 .python/lib/python3.12/site-packages/werkzeug/debug/tbtools.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/formparser.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/http.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/local.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/lint.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/lint.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/profiler.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/middleware/shared_data.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/py.typed create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/converters.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/map.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/matcher.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/__pycache__/rules.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/converters.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/exceptions.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/map.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/matcher.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/routing/rules.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/http.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/request.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/response.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/utils.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/http.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/multipart.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/request.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/response.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/sansio/utils.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/security.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/serving.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/test.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/testapp.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/urls.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/user_agent.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/utils.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/__init__.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/request.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/response.cpython-312.pyc create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/request.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wrappers/response.py create mode 100644 .python/lib/python3.12/site-packages/werkzeug/wsgi.py create mode 120000 .python/lib64 create mode 100644 .python/pyvenv.cfg create mode 100644 README create mode 100644 __pycache__/calc.cpython-312.pyc create mode 100644 __pycache__/csv.cpython-312.pyc create mode 100644 __pycache__/db.cpython-312.pyc create mode 100644 __pycache__/main.cpython-312.pyc create mode 100644 calc.py create mode 100644 db.py create mode 100644 finance.db create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 templates/index.html diff --git a/.python/bin/Activate.ps1 b/.python/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/.python/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/.python/bin/activate b/.python/bin/activate new file mode 100644 index 0000000..b5fece6 --- /dev/null +++ b/.python/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/ddp/src/finplan/.python) +else + # use the path as-is + export VIRTUAL_ENV=/home/ddp/src/finplan/.python +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(.python) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(.python) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/.python/bin/activate.csh b/.python/bin/activate.csh new file mode 100644 index 0000000..40fa69e --- /dev/null +++ b/.python/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/ddp/src/finplan/.python + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(.python) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(.python) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.python/bin/activate.fish b/.python/bin/activate.fish new file mode 100644 index 0000000..52d01b0 --- /dev/null +++ b/.python/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/ddp/src/finplan/.python + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(.python) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(.python) ' +end diff --git a/.python/bin/flask b/.python/bin/flask new file mode 100755 index 0000000..3f399a3 --- /dev/null +++ b/.python/bin/flask @@ -0,0 +1,8 @@ +#!/home/ddp/src/finplan/.python/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.python/bin/pip b/.python/bin/pip new file mode 100755 index 0000000..efff4ea --- /dev/null +++ b/.python/bin/pip @@ -0,0 +1,8 @@ +#!/home/ddp/src/finplan/.python/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.python/bin/pip3 b/.python/bin/pip3 new file mode 100755 index 0000000..efff4ea --- /dev/null +++ b/.python/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/ddp/src/finplan/.python/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.python/bin/pip3.12 b/.python/bin/pip3.12 new file mode 100755 index 0000000..efff4ea --- /dev/null +++ b/.python/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/ddp/src/finplan/.python/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.python/bin/python b/.python/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.python/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.python/bin/python3 b/.python/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/.python/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/.python/bin/python3.12 b/.python/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.python/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt @@ -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/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA new file mode 100644 index 0000000..82261f2 --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA @@ -0,0 +1,92 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 3.0.2 +Summary: Safely add untrusted strings to HTML/XML markup. +Maintainer-email: Pallets +License: 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. + +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source, https://github.com/pallets/markupsafe/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +# MarkupSafe + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +## Examples + +```pycon +>>> from markupsafe import Markup, escape + +>>> # escape replaces special characters and wraps in Markup +>>> escape("") +Markup('<script>alert(document.cookie);</script>') + +>>> # wrap in Markup to mark text "safe" and prevent escaping +>>> Markup("Hello") +Markup('hello') + +>>> escape(Markup("Hello")) +Markup('hello') + +>>> # Markup is a str subclass +>>> # methods and operators escape their arguments +>>> template = Markup("Hello {name}") +>>> template.format(name='"World"') +Markup('Hello "World"') +``` + +## Donate + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +[please donate today][]. + +[please donate today]: https://palletsprojects.com/donate diff --git a/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD new file mode 100644 index 0000000..b7ba0b7 --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-3.0.2.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-3.0.2.dist-info/METADATA,sha256=aAwbZhSmXdfFuMM-rEHpeiHRkBOGESyVLJIuwzHP-nw,3975 +MarkupSafe-3.0.2.dist-info/RECORD,, +MarkupSafe-3.0.2.dist-info/WHEEL,sha256=OVgtqZzfzIXXtylXP90gxCZ6CKBCwKYyHM8PpMEjN1M,151 +MarkupSafe-3.0.2.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=sr-U6_27DfaSrj5jnHYxWN-pvhM27sjlDplMDPZKm7k,13214 +markupsafe/__pycache__/__init__.cpython-312.pyc,, +markupsafe/__pycache__/_native.cpython-312.pyc,, +markupsafe/_native.py,sha256=hSLs8Jmz5aqayuengJJ3kdT5PwNpBWpKrmQSdipndC8,210 +markupsafe/_speedups.c,sha256=O7XulmTo-epI6n2FtMVOrJXl8EAaIwD2iNYmBI5SEoQ,4149 +markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so,sha256=t1DBZlpsjFA30BOOvXfXfT1wvO_4cS16VbHz1-49q5U,43432 +markupsafe/_speedups.pyi,sha256=ENd1bYe7gbBUf2ywyYWOGUpnXOHNJ-cgTNqetlW8h5k,41 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL new file mode 100644 index 0000000..057fef6 --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.2.0) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/.python/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +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/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA new file mode 100644 index 0000000..6d343f5 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.3 +Name: blinker +Version: 1.9.0 +Summary: Fast, simple object-to-object and broadcast signaling +Author: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Source, 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". + + +## Pallets Community Ecosystem + +> [!IMPORTANT]\ +> This project is part of the Pallets Community Ecosystem. Pallets is the open +> source organization that maintains Flask; Pallets-Eco enables community +> maintenance of related projects. If you are interested in helping maintain +> this project, please reach out on [the Pallets Discord server][discord]. +> +> [discord]: https://discord.gg/pallets + + +## Example + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +```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! +``` + diff --git a/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD new file mode 100644 index 0000000..7cfb714 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD @@ -0,0 +1,12 @@ +blinker-1.9.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.9.0.dist-info/LICENSE.txt,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.9.0.dist-info/METADATA,sha256=uIRiM8wjjbHkCtbCyTvctU37IAZk0kEe5kxAld1dvzA,1633 +blinker-1.9.0.dist-info/RECORD,, +blinker-1.9.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +blinker/__init__.py,sha256=I2EdZqpy4LyjX17Hn1yzJGWCjeLaVaPzsMgHkLfj_cQ,317 +blinker/__pycache__/__init__.cpython-312.pyc,, +blinker/__pycache__/_utilities.cpython-312.pyc,, +blinker/__pycache__/base.cpython-312.pyc,, +blinker/_utilities.py,sha256=0J7eeXXTUx0Ivf8asfpx0ycVkp0Eqfqnj117x2mYX9E,1675 +blinker/base.py,sha256=QpDuvXXcwJF49lUBcH5BiST46Rz9wSG7VW_p7N_027M,19132 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.python/lib/python3.12/site-packages/blinker/__init__.py b/.python/lib/python3.12/site-packages/blinker/__init__.py new file mode 100644 index 0000000..1772fa4 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker/__init__.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from .base import ANY +from .base import default_namespace +from .base import NamedSignal +from .base import Namespace +from .base import Signal +from .base import signal + +__all__ = [ + "ANY", + "default_namespace", + "NamedSignal", + "Namespace", + "Signal", + "signal", +] diff --git a/.python/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..614b739e657980372abdb6abb53b5e3be3451195 GIT binary patch literal 487 zcmaKoy-ve05XaBWXH!*(0SO5)08+j#4@6Psp^!pK@Jx7np4FUMH&dxepAnPZDR}dhGf{et3fanNE zbuuS*T6U4$*lpQE_F}JPAK8!nmILG<4q6V8!#E_6fat!FxVwx7y_LOgKgM0Ld2bWtsgWXw1itKBg#<^Oecz!+DGv3FQw32a7mmS>U*QP9#%=rq-Z z;+hVNWi`t+Rq2>+@oIQ+Nz1g7=lGvFPh?5QD%EpoC}XKkE5@*B6JBSzSSWdG_OZPk kOL>Cw?GQp5IQ@cy2F@BdZs4eaLtH;@(CfSeW)HJ|0o4C^`2YX_ literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc b/.python/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83cf89fde376f59e79262a1e0aa116015a019515 GIT binary patch literal 2714 zcmb7G&2JM&6rb^~z3Y$IApt^45*C6=j8dDFL!}a>MN|SL8nsQ@N)FLxvpY^US+CvM zF<{HBQZ*Hh5G5R{@)OLVxl_bI1XMx4r{r1zE_#4l3Xr#+(m1p@Ni?8+|9EoJ&9)VQI*t9f;krd;FuUk_qp+4J$-@-;oEY;T5;j}3d^~OjX9ZLWCcJe4 zn5%Fxf^yhGxzML@!JK5HoNR?i*ph}pZ>e>Z$CkX9$VIHE6$T&*0E)n@0w4wEXdPX_ zx!4#=C;Z4*r7&G|s=u7pOaR0Tmua354Qj4!5~{IT!_}syiqmt%WCQ7`sf_jsDG`Ga zOEV3}@iax8xXZ zHdCrV{OB{We>|B~zDz2Iv$s=`Xv*%D< zx)EQBFMqJEc5kLS>ai_20_}AcN)aC0@+6gPO5h7qA58x*tya5bAcx5V#1yJZd zumL>07kGT*4gyL_bQgj^(9bOsKmb9i^G0Q2ulB#r|mgXtcS3YWYuGDBb&gh#+j19|=} zdK^;1>Z1;nIk9kdt?l@RoP8=s!kt^~INZGz0rCt;k8p_CyDMA5aE8d1Ux8UcY&( zRs{Af7@Frm^T*YxvxI4e23>#JftGC%m)Ut6dVao0K~9ND>`SnOl}B8QK#yfbZJKCh z51PN>fer7zG3ZI!JgIOy+vNummJ!0V>MQUPl;Gv?Rog2B&s)g0cxvR!F2tR4yuNvo z*k1G55V_?`w#y*A?QpBsj8_WAJkf27WKV;i0wE(3(2*P}#HGe@nVGwp_id9C-xBo%I;(NhIs$ zwRaXqgK}++FYmt+e?l$-^FOj6(HemoZbkxXcb>LwFZlj>E`NQ!-9S(ZY2;~mqrR=>6pH7EWJ1|MmI0`OWA8eik{1dmbYoTf-^b`Shra`^4G* E0PsRvIsgCw literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/blinker/__pycache__/base.cpython-312.pyc b/.python/lib/python3.12/site-packages/blinker/__pycache__/base.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf4f008c39ad4510f9b4aef3d1fd0c6bd9985c54 GIT binary patch literal 21991 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�*hv7)y8-3bq=B<*#!EjOl>pi&$FE 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/blinker/_utilities.py b/.python/lib/python3.12/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..000c902 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker/_utilities.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +import collections.abc as c +import inspect +import typing as t +from weakref import ref +from weakref import WeakMethod + +T = t.TypeVar("T") + + +class Symbol: + """A constant symbol, nicer than ``object()``. Repeated calls return the + same instance. + + >>> Symbol('foo') is Symbol('foo') + True + >>> Symbol('foo') + foo + """ + + symbols: t.ClassVar[dict[str, Symbol]] = {} + + def __new__(cls, name: str) -> Symbol: + if name in cls.symbols: + return cls.symbols[name] + + obj = super().__new__(cls) + cls.symbols[name] = obj + return obj + + def __init__(self, name: str) -> None: + self.name = name + + def __repr__(self) -> str: + return self.name + + def __getnewargs__(self) -> tuple[t.Any, ...]: + return (self.name,) + + +def make_id(obj: object) -> c.Hashable: + """Get a stable identifier for a receiver or sender, to be used as a dict + key or in a set. + """ + if inspect.ismethod(obj): + # The id of a bound method is not stable, but the id of the unbound + # function and instance are. + return id(obj.__func__), id(obj.__self__) + + if isinstance(obj, (str, int)): + # Instances with the same value always compare equal and have the same + # hash, even if the id may change. + return obj + + # Assume other types are not hashable but will always be the same instance. + return id(obj) + + +def make_ref(obj: T, callback: c.Callable[[ref[T]], None] | None = None) -> ref[T]: + if inspect.ismethod(obj): + return WeakMethod(obj, callback) # type: ignore[arg-type, return-value] + + return ref(obj, callback) diff --git a/.python/lib/python3.12/site-packages/blinker/base.py b/.python/lib/python3.12/site-packages/blinker/base.py new file mode 100644 index 0000000..d051b94 --- /dev/null +++ b/.python/lib/python3.12/site-packages/blinker/base.py @@ -0,0 +1,512 @@ +from __future__ import annotations + +import collections.abc as c +import sys +import typing as t +import weakref +from collections import defaultdict +from contextlib import contextmanager +from functools import cached_property +from inspect import iscoroutinefunction + +from ._utilities import make_id +from ._utilities import make_ref +from ._utilities import Symbol + +F = t.TypeVar("F", bound=c.Callable[..., t.Any]) + +ANY = Symbol("ANY") +"""Symbol for "any sender".""" + +ANY_ID = 0 + + +class Signal: + """A notification emitter. + + :param doc: The docstring for the signal. + """ + + ANY = ANY + """An alias for the :data:`~blinker.ANY` sender symbol.""" + + set_class: type[set[t.Any]] = set + """The set class to use for tracking connected receivers and senders. + Python's ``set`` is unordered. If receivers must be dispatched in the order + they were connected, an ordered set implementation can be used. + + .. versionadded:: 1.7 + """ + + @cached_property + def receiver_connected(self) -> Signal: + """Emitted at the end of each :meth:`connect` call. + + 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.") + + @cached_property + def receiver_disconnected(self) -> Signal: + """Emitted at the end of each :meth:`disconnect` call. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: ``receiver`` and ``sender``. + + This signal is emitted **only** when :meth:`disconnect` is called + explicitly. This signal cannot be emitted by an automatic disconnect + when a weakly referenced receiver or sender goes out of scope, as the + instance is no longer be available to be used as the sender for this + signal. + + 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: + if doc: + self.__doc__ = doc + + self.receivers: dict[ + t.Any, weakref.ref[c.Callable[..., t.Any]] | c.Callable[..., t.Any] + ] = {} + """The map of connected receivers. Useful to quickly check if any + receivers are connected to the signal: ``if s.receivers:``. The + structure and data is not part of the public API, but checking its + boolean value is. + """ + + self.is_muted: bool = False + self._by_receiver: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._by_sender: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._weak_senders: dict[t.Any, weakref.ref[t.Any]] = {} + + def connect(self, receiver: F, sender: t.Any = ANY, weak: bool = True) -> F: + """Connect ``receiver`` to be called when the signal is sent by + ``sender``. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends. + """ + receiver_id = make_id(receiver) + sender_id = ANY_ID if sender is ANY else make_id(sender) + + if weak: + self.receivers[receiver_id] = make_ref( + receiver, self._make_cleanup_receiver(receiver_id) + ) + else: + self.receivers[receiver_id] = receiver + + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + + if sender is not ANY and sender_id not in self._weak_senders: + # store a cleanup for weakref-able senders + try: + self._weak_senders[sender_id] = make_ref( + sender, self._make_cleanup_sender(sender_id) + ) + except TypeError: + pass + + 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: + # TODO no explanation or test for this + self.disconnect(receiver, sender) + raise + + return receiver + + def connect_via(self, sender: t.Any, weak: bool = False) -> c.Callable[[F], F]: + """Connect the decorated function to be called when the signal is sent + by ``sender``. + + The decorated function will be called when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument along + with any extra keyword arguments. + + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends.= + + .. versionadded:: 1.1 + """ + + def decorator(fn: F) -> F: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY + ) -> c.Generator[None, None, None]: + """A context manager that temporarily connects ``receiver`` to the + signal while a ``with`` block executes. When the block exits, the + receiver is disconnected. Useful for tests. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. + + .. versionadded:: 1.1 + """ + self.connect(receiver, sender=sender, weak=False) + + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> c.Generator[None, None, None]: + """A context manager that temporarily disables the signal. No receivers + will be called if the signal is sent, until the ``with`` block exits. + Useful for tests. + """ + self.is_muted = True + + try: + yield None + finally: + self.is_muted = False + + def send( + self, + sender: t.Any | None = None, + /, + *, + _async_wrapper: c.Callable[ + [c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]]], c.Callable[..., t.Any] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Call all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _async_wrapper: Will be called on any receivers that are async + coroutines to turn them into sync callables. For example, could run + the receiver with an event loop. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionchanged:: 1.7 + Added the ``_async_wrapper`` argument. + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if iscoroutinefunction(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function.") + + result = _async_wrapper(receiver)(sender, **kwargs) + else: + result = receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + async def send_async( + self, + sender: t.Any | None = None, + /, + *, + _sync_wrapper: c.Callable[ + [c.Callable[..., t.Any]], c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Await all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _sync_wrapper: Will be called on any receivers that are sync + callables to turn them into async coroutines. For example, + could call the receiver in a thread. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionadded:: 1.7 + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if not iscoroutinefunction(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function.") + + result = await _sync_wrapper(receiver)(sender, **kwargs) + else: + result = await receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + def has_receivers_for(self, sender: t.Any) -> bool: + """Check if there is at least one receiver that will be called with the + given ``sender``. A receiver connected to :data:`ANY` will always be + called, regardless of sender. Does not check if weakly referenced + receivers are still live. See :meth:`receivers_for` for a stronger + search. + + :param sender: Check for receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + if not self.receivers: + return False + + if self._by_sender[ANY_ID]: + return True + + if sender is ANY: + return False + + return make_id(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> c.Generator[c.Callable[..., t.Any], None, None]: + """Yield each receiver to be called for ``sender``, in addition to those + to be called for :data:`ANY`. Weakly referenced receivers that are not + live will be disconnected and skipped. + + :param sender: Yield receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + # TODO: test receivers_for(ANY) + if not self.receivers: + return + + sender_id = make_id(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, weakref.ref): + strong = receiver() + + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + + yield strong + else: + yield receiver + + def disconnect(self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY) -> None: + """Disconnect ``receiver`` from being called when the signal is sent by + ``sender``. + + :param receiver: A connected receiver callable. + :param sender: Disconnect from only this sender. By default, disconnect + from all senders. + """ + sender_id: c.Hashable + + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = make_id(sender) + + receiver_id = make_id(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: c.Hashable, sender_id: c.Hashable) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, None) is not None: + 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 _make_cleanup_receiver( + self, receiver_id: c.Hashable + ) -> c.Callable[[weakref.ref[c.Callable[..., t.Any]]], None]: + """Create a callback function to disconnect a weakly referenced + receiver when it is garbage collected. + """ + + def cleanup(ref: weakref.ref[c.Callable[..., t.Any]]) -> None: + # If the interpreter is shutting down, disconnecting can result in a + # weird ignored exception. Don't call it in that case. + if not sys.is_finalizing(): + self._disconnect(receiver_id, ANY_ID) + + return cleanup + + def _make_cleanup_sender( + self, sender_id: c.Hashable + ) -> c.Callable[[weakref.ref[t.Any]], None]: + """Create a callback function to disconnect all receivers for a weakly + referenced sender when it is garbage collected. + """ + assert sender_id != ANY_ID + + def cleanup(ref: weakref.ref[t.Any]) -> None: + 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) + + return cleanup + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leaves behind a small amount of bookkeeping + data. 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 process performing dynamic signal routing with high + volume, e.g. connecting to function closures, senders are all unique + object instances. Doing all of this over and over may cause memory usage + to 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 ident, bucket in list(mapping.items()): + if not bucket: + mapping.pop(ident, None) + + def _clear_state(self) -> None: + """Disconnect all receivers and senders. Useful for tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +class NamedSignal(Signal): + """A named generic notification emitter. The name is not used by the signal + itself, but matches the key in the :class:`Namespace` that it belongs to. + + :param name: The name of the signal within the namespace. + :param doc: The docstring for the signal. + """ + + def __init__(self, name: str, doc: str | None = None) -> None: + super().__init__(doc) + + #: The name of this signal. + self.name: str = name + + def __repr__(self) -> str: + base = super().__repr__() + return f"{base[:-1]}; {self.name!r}>" # noqa: E702 + + +class Namespace(dict[str, NamedSignal]): + """A dict mapping names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` for the given ``name``, creating it + if required. Repeated calls with the same name return the same signal. + + :param name: The name of the signal. + :param doc: The docstring of the signal. + """ + if name not in self: + self[name] = NamedSignal(name, doc) + + return self[name] + + +class _PNamespaceSignal(t.Protocol): + def __call__(self, name: str, doc: str | None = None) -> NamedSignal: ... + + +default_namespace: Namespace = Namespace() +"""A default :class:`Namespace` for creating named signals. :func:`signal` +creates a :class:`NamedSignal` in this namespace. +""" + +signal: _PNamespaceSignal = default_namespace.signal +"""Return a :class:`NamedSignal` in :data:`default_namespace` with the given +``name``, creating it if required. Repeated calls with the same name return the +same signal. +""" diff --git a/.python/lib/python3.12/site-packages/blinker/py.typed b/.python/lib/python3.12/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..497ee45 --- /dev/null +++ b/.python/lib/python3.12/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-312.pyc,, +click/__pycache__/_compat.cpython-312.pyc,, +click/__pycache__/_termui_impl.cpython-312.pyc,, +click/__pycache__/_textwrap.cpython-312.pyc,, +click/__pycache__/_winconsole.cpython-312.pyc,, +click/__pycache__/core.cpython-312.pyc,, +click/__pycache__/decorators.cpython-312.pyc,, +click/__pycache__/exceptions.cpython-312.pyc,, +click/__pycache__/formatting.cpython-312.pyc,, +click/__pycache__/globals.cpython-312.pyc,, +click/__pycache__/parser.cpython-312.pyc,, +click/__pycache__/shell_completion.cpython-312.pyc,, +click/__pycache__/termui.cpython-312.pyc,, +click/__pycache__/testing.cpython-312.pyc,, +click/__pycache__/types.cpython-312.pyc,, +click/__pycache__/utils.cpython-312.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/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/.python/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/.python/lib/python3.12/site-packages/click/__init__.py b/.python/lib/python3.12/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d0da1d2f2983a47781fcce5cff950e7e86335a8 GIT binary patch literal 2692 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

YhZgOe(fwnCn=T!dFL+kG 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 E-*Gn$?yNYey>~d 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 B>9zm> literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..880f964f8bd47ccc815d7c722508cbb1585a70b2 GIT binary patch literal 23965 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a631e0aa0bad4eeb671269421bfc47058203bfcd GIT binary patch literal 14727 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba09e026cb12cac434f7ab2879dd23cf5d9f701f GIT binary patch literal 14121 zcmb_@d2k!onP)c|_rVhsZ?Q>Al%RvOMC!0k(~_ve9%gJYal%Okg3wJ86bR7WpeS;{ z4U^H7L0cJ7NhXBGNg1h3Rp^qp!r7gzQEF;tJjWldntuROieQXV#jVY5t>&MFOig*B z+S=OR_qrPZDM;R}-6rw+;T_+5?|a|-&WC^Uc$^%bS?4!L|7APJ{TKRTJRUu>{wtp2 zmbkBS5-0ItZkWg06gEu=!varbLfAZE9=0HFmMmfGgl*Wy^473@!ZGYXo*#C~{P-3F zaPcj>8}UW)^CMsX?lctE5Um#cHH#d}?GbMyMKbOSRW6 z!*wR^EGK!db5h+MlQz=u7HJE{>NdtLzU8VHVxmg+7BEqdSv1V>zQ#w?ebC3}DuU5S zOuiPI2t)#-vVs!Zs2rn`N7#N2-|aD3ned0@2=WefG8~Heqm!|md*CZ?o;q{d|JM1_ zL+5g4B|5FS{c8WCVQHA0k=eLfjl5=T39qI?i!(rdXk6+;m6Jqi!$9 zeG}`R6Xwh@>dT%uKW;Jd#dlngcmqc_VT+Cs#l}y*U zn9KNvQH&E{6ybeG&l^xrKT~p%^9h3rZPtd>)9ickS?@yf8pi_zaqe3fo2`$ZGsR6m z;+J@yyWui(Gu*!yrg(M*qRK=d77Im2(dnt< z*r*(luT3f^X2l6PpiU{WKNh$gmb;IIqrpH}J<(lgQHwdKUL^mW`?q=S)2f5FVvBDl z+kaS{sXF-Ebu%iyTUpKfY&nM>+b;~o9{!nwq$#oC8Wt;vxO#&3@=*DeQEx4!fjJMZ@X z$GxjfuOtQ*d*6NSu|Q4p0`-4l=iIcqA74$4{5<^A@XsQvZ3pgE9b9!COq&m`V?-|J zz#RR-=u{*Y)Xymub3})o_^b~gF?Jnv-9R)SH%WY)FGu;a;L5XD@hp1jRMAwR3KJby zI*W5z$gHV$B_O-2@&zXrO9EY{h^2?M`F2Z zb?UMzzdeP#QB*sr$f~SdmHm?eB`~T4CdbrZ>G35L5nZp3199)T-|@Utu>_F;5yMUJ za}XnL)W!=A>L=-6mw5VlkwOlS=ez zNRlNCEKY~Q;f?cTP{slgsdO||+==OiBItB^MvP5IMR{T}HY0{nr24v@tke0C;`CH8 zpva;IM%sh<7bhMJM8wNji2{Jv0B|}K8xv8+ATmG%RU}O!0L~B@rL~EdE`9UzrAuOP z4Cg;c3)zX1YcCzXbjc^iqF90y3IbaUdkjb54x4BQ(PahSMW#MA|8>ncf+b)*;GLHycCm!`PVC2_h;qF*SijLHvl2j|EU0dTiu) zT35Y{mI8v=JTgRc5XfSrrR_A)OqpjSq^L2rF`y_SoR|UxY#99+{%TBs4Xkx|?)Yrs zWyaNuh(^Jn&5>|mlxS3y2?N+F+WW#T619HG_~J%t z)=98PeyTPXg@gyBpKA!a{1#D(tPDU5?m)4!6G^T{kr~eY(_;{SDl{K?Fo=r6Lrk66 z*7|=#@+ZO)x4^0V3{r_F4SKwwi{gv^7|dNVUBMX2?gi7hVAK`g3;Z=+1*?Jh5+rju zv4t@#64z8)6xI8tIv+9DKpJaN){QSJ8S2+D6;VE^DWcq9?ZL*(n z$AY$4tR}@r9Yq3V@w3XBth*-bsz|)OaPa1_g=6oXNDh7KYR|eoH_t7cTO9fRl@y=q zTlW5<@x#WI-j%mkl$ArPzN6{7WB1+1*EX~|u-y5JogeO8>AkZzU3d7N`{k^=^85V4 zfYOGs6w+~KO-|>BCWQ>#L7ywID!WmXb3)$*uY{Vb=FB4?&zzGPHHu=3XL}~t@Kfc1C$&@qLQpHJ+iO7@`|q66|kx~0lnm8(_lpK}gNYr_0lW$kC~EjM1z)-^6b z&#p`SyNAu4snhSDShQ#Bo0tCJ)*t*}Zqb}=Z2z-!%R@gK%rx#_v|@j5URb!W7`yLo z$=3qRV=rf^y#D%{!!`eEwsq_0oW;_eu{S2Hi^Aei*5iHPY0r3|w=Y|Nx@XnX^O!R` zx`~3SYL*c`Wch2J?A+G?QTG`b)l2}4R&v63_>axhR()RKULFWiuN$mBlcbnsF2yD z8$tlVY=+`@KDI+;B5X>X3WT8+j!!{cM`W24GSU~W%F2wWPRc=8L`;?`5oCgZr0&s_ zJwOm)O-C6R@Si9RqDD1|Ey-8qFsY819+awS1;UGjXh;#G(-Cnb5DCtR(W%(vR1Bh! zf#{EsGNwZ5AYBxorvo!s5cO1P22oh^6H#SmqoSm=GE`$)B$fjgQV2t^*_ZM)QP;b$F%y$O3fc!mLnVX4 zeCV(?_+YMT^Yj_Z%{kE6&nCh+eo!|98JSs;lC)m`dnC-brxL_DBl0e3sWH!FjD40vZ5Q1NT z^OL`fJ)PN7exkn_Sd`@^&#-O@|m2>#2P=AH2Be-8ekz6(0 zFA#wm{{3obR?gYrw3wQRs2T<VkDaxg@k6$-!zJb{*+S(U>h8c-(Q&J*N8B%8f5 zc0W49FX*4$vfbmOuzAFrsd7_(AQQQ-deO|>zWeg z8_w+3HiFok?cAO)f6v9#0pNwH(i>beL=cQ9jvzzMxN*EUKjoCXIDbbc8lHm-)ik^B zE$zSs#HmOq7?osQbJtEFkv*A{j2UPs?H=@*l#3XPX%@&2QT}U4RN76$$7Nv$dA4>V zDp}zlQCo7t&2wvZ_f6M=>w&!~V{b|xyl?MdYktQ0$kzHQy3ks$@#R(v9MJfio>_>- zpvhk-WovFaPuzo88#~w9nG6vB=pKa9^(I;~g87hVi&F_>n(K}!H?!W2i_-cppwT)> zEw-u$_U2FR&B@q9ESO`kz!iM1+y#o@XN2WWcCG1%;3tB zgVyjK1oj9gF)n^32@4hA0!f( zkTqdh(v0Zsh*&g;VWyMU1nzf?12qOB7ER#AijZY-915X2OC zzs6da7$UK*e4P@qfS9QB*)(2C+)BAbNdQUCJw@aDwd0m^lC7%i3S?=iBzI||cr@e6 z#h9$0^_p$m$f`=JZc*nikj!&=FHDQXiH8l1$(`@J7Uxp^>AJ4Oz*>`-s!sJi=scL| zJeck{v@)3%52YIq-}T?5b=2Rj_#~ zFda`dGq>XR+}rfli?Ms|mMj3BN|_&sy&19hFTQ?vWc9$A)s}%zsxvJYGIg(Q0-fBo z^0iN{J`qgSHBSUH;6iA7ZaNp7i+%U)4H`$YjmZHCj;amPwV-m5n!u#1E;I49@Q|0k z{ILYf;!BxV@kq~@eU{nw!co!3E{amH z)j`fSm)m!}@|V;%>uf;Bsv_^z^c1pB$i=*w zIqOD`=4yte7m=JAR}nQc4N)-o@Qs}*;j@eb4wX7FHOG;*Rc4Ln6*(PoKQv}kyd8O_ zQf&dP zZ#lDV+p`@zv)gt)aalbTPXxQenXh?gtGPO^Z)DvBjW4&2SmxSRET?k5G64hoG;rL$fR zmep80B3LJ5g}7b3P!3g!8I@OX5D~2_55)$Bu1sGe+*}+Zvi~^{3ga>LtK3X6M)_3} zj!PqpJQpj(4$*_;{-!5xVP-PVQoDiuIeQFhyY|Fwal7RB$azQS42Z2d#%XgmJ%(96 z=Zrg**UGOg?$qc4yJOw3D^AHJxtr*!$}Uiet9);^+b>voVb5I*enHv9e(o`Yo^I@V z4%`xqqt$U-191C1fe2Vsf!VVFA9LPl%G`7K68v6c(P=~{$xPE+S;U^erV#d-z{MX) zi~Sk?E!`(ZA+rJ>(=|f6QE)^I6m&<5E5hl7AROK7KrpBfK2s(bBNVR&!c%agZ3d(> z2~C4F{5_gKiNd5%I5iDZ^Hh}WuCo>m1g@N1Mu-u8S=>iOyfQW|>(M9;R4H3F*mLO{ z@vkUD3He5fBPy?hre=4ZxdsOxsm-)xZC2WHH*EsD0aVmN6k_F!%|C)=#SQs*jl&Zk z8}xZ79snN&U1L!?k>nghGn4WeMTsiPSEz6sB?T3Rg(sN8tHm46Q0*}!KDQaEGxYW22+^&#RwSKm9DZ2#2N{II4u-7>IR zb2jZh`x|e4(wcnxwj*_D)w_H7O2+$g!ttBdu2k%!iz{31{N8Ho%j;a7qkZ9b5@!|< z>Z(SvBl!lo3ifB(_NTY@uDq0P=}kBGt$cOmY`Xr~J@@g?Y8!PSmh8J%C1$G{9#+;T zE$@9h<--siFMnG3vQgig@_jV6GIb}K={TNgK5@V59=cnz+ITE+;bHT()Yq1WKN-5${AS|ytXF*C z-JS97UiI!xocYg{hI~!Rss7tz$>EfeJbABb_gYJPsy)?_JdaB{)ff52(@^%8F5J41 z>PWqjnpx?4&^wU9|Biul*V&IJ)7#Fb+s}RC{lxmo<#gK{_q}g^E>JgI^FjOu(mUDr zt19vFZlF$gMUbVqK_4UOOytKLrN(uo7llKa6wrAu`W2p{1ZOP@(z?)~aBYsKU<3an z6J31+2Q0Wi%e9>0JHNEeG^gF~U>E32vnkSjMyB9~*RD6hr_Am*g0=c;x0WobPlbbaqIH)c6lh6uU)2CE6I^x-?7-JP1*J9d?ne4EoFp zU0PGZl(4|x?;~dzDRangFj8##2(xt?wK~1{e^Gm42igs<3Mgj}>@694%RT#6Xmq-l zufJ4!yBHwNpLj%v%7i?HsxyzuYK=#{w;A@%luE3Zj^m@e}5bQpUnME?w8fb z{hhO>zeV`F76JJUPR0W9%%ju)8S!k``Z8o>h;4GTvaNq%n@wB4ufP1Jv*<>7&n2*4 z*nwxfe0s>2IXO2w1xoy%9&kK$cVP#tq#l1Mo=N%nZuJTNhh`s_#QVdVqrzVaCpIFO z7Ehn`!$`Z;nm8{w7rw@9#}6VP6r1SS__6F*AI-+M@#}z zm9HU(XaXH0zdz^n`zNB(RG9K^zyEE--}D-r-!DajC>EgfO|5wg-gN)6`sVDyY_fCV z+j$$6*g0?A(ve$7lEGUi^VBx)vogn087y9G=GkN zEOc4m5vtF#cUy<{-naiRoBq7%?x{a-W8c>to^=b_<$sqqSx%-d62z0sLj>{Ux?Qle z=A9Lm#-y6(@Jhwj>6P!|8k(}rEsq_$EbVI*l{d#1#*@__)Zea8)uw`}hD_tGOvUcJ z1+`dJORpQtp%@C|IaV{^uls1v#sxQ`o1n04e~84 zXGPODm{2umTK9g=;k(`jxqOw$vMt&91e4#U?FDT^&ZaB58yHlcPj+f}- zHEH%B_c@`&0xjt0T3{N^bF(C{t3M{mj6VFA_#z5cX)b~r zx;`%YkP^4)k?hye|Jh6DanpziXWJ2Qf$YxW@)lh@G#tAcF7%)joqC8Qy5z$czy!P) zOt?)%;RePXASF7fgy0xv(hu=uW*=zx`8ReT^8mixodq+&uSMB3xfzJe=>ArJNcF3T zw~zU73vhZ&#_d89rkd`lSq=IWnDIb&$O77JGLq438ep&Njv#{C@KZ++2G?u@ePxSR{qLpOk_^)B z^n1IKfyFl#-~N-KjJNBz3SkPj^NDC#z*4hN%yfHSyZU5N7OCzOl3Z<>jn4_d6Z6Dx z4j8*jC#L)<05sE7W{`nT%FQ|5xEs{emNwU~Rc@i9--XNk)lJFXA8bwWnd**&bJN^lgmlfe`}Xa554z>6IE(F_v)?&;t787_J#$+Y zj>?x8UdH-T`|o+XR$X1`ok!EIqiOR|O+c9+4bqxOF0o|5*O;@$X6Q<)@-7NP`61Sfmk)6c|!RaYJpcy?LnFsc%FaA z)%=><{%cPBuUzY|xmGak_U-fTM1V2&+J)#Uw=HkA@rRQ92hQ8h)V`k|`stzN-W6f_ zaHg{_({Lcqq4I9~-|qP3j*mM(RzKdEIr7>%mF2x=zBlW1-Q2aXYw?Yxw{E?ayqM}t zemzsym2vLK3sl>8h`rY=)^~=#GrY(z*>2gALh@qLo~dfjSUT1%Xa&b&jW^rWl5K6v zirXK%26(-6LW%B;C6@)pWq;&lyq8_U|chUUD3Wu08p);#M1BC8`{x@{RyUPFo literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4cd44a89ac01fc78c7b419b751dcb55e9cd5b96 GIT binary patch literal 3112 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b07872abbe2d36ce420ef822f8204b64ae0ee45 GIT binary patch literal 22763 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..440b2364a2cf0a68647b510a29c8f86cfdc4109f GIT binary patch literal 32781 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 Ne|@NbPQO^v_`iyWrHudp literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ca9ff324baac67a3f831aede81762e415df6c8e GIT binary patch literal 24569 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

Lz z(nUP|I%z74AZyw}KhloQPMRB?ooOecBx2O4wEbK-P9Q@>HK#4{XkU*~LuF8Yahe&Z z>%F$k=LY+ungmR>b<77g%mp^g2e!=xw%yp1 z3OxL_JQp}PQM3?PH6IAg1wyl%Q-PLSTjv7%CW@A9lG``AW4ipdE4bjRxUzd{_vO~R zzPgFlyY(AxG|qW;CLKE$Q231zgau@JQPiF| z6{j`CMfk6pUc0ghRa9v7^BU;mmWb@p(0ClvezdNjq4}RbM;Q_R zBAQDBp*=L8cytJ?(<}pclfw=K0n890!oWoAKSsNvz6%cw0{Eeau=&P%bO1t-NZq{R z`eqc|K*4GciO->&ZsC2Mu?KZi&EK01k)ftwI3BzZ?d!u^FPsaeIkxgQ%OW-a zW5W#laBOV}a7t^&gEi@yKYqNKZJ{*A-+;E39XM zrPZy(FwI}U$cRamGbAlyDRKcVjQWYPvPg5_3a_u?Oyz+8JC|iJ7 zhD3qngG?oapwZIo!c)7ulVTFd3t-tKc>@z}UUg}c@&?p*jY>&9AF9nfHo%ZOX_^a)qq4Ng2O|4 zPcStR@5fpWcApy_I3EXO2K#_m34p%nz$k%gP#|D2G2RDq1gO4-_vK6*bzW*;2w4X; zK%*@%{3f8GG0gP-Xm~(frw9Nggxws310j;}CcR!Lcz_5Kt_UH&fW0xMCUO#?h}hYI zK_wb#4hE0Y(!CIigVa&e>6zuF*D6R8bC{t#MW=d3ffR$X07oN^6-7M|8|dyE2Bwsq zAZbE`tel5Zfw2s!Thk8s^B{K_#{pl4k!7BPqqW)jv;6A?%3&28OeL>W>ieo=^31$v z)tqP5jAcH!doH*;AbnA{lzI8?YnT0D0~u&LAr}J8phXZ;k&oSar~&d}p`1rcvRy&H zUqXsF;h#XtN+eIs^v+rHjR$X+>`pp%iv|~AECkmns+1yPUSkV3wzCp%Z2t#>MbBWB z@U$JwZdNT!!nSn%2IG*;@pITunD7yNEg;^xEUvEL;F(?!+i?|P$>Q4CYKh(fpcy1; zn)VH#`9T8DDn0`+rR52*54u^OpmAWph>VSmW;!iaOw7Rx@mvZXYi2N;6I1qj`kail zy)kEHsz92dX4}9EgWbII=s=UG7A_OH5W^um**^(%SEA2@b3ueoPV<&!k?o}xVu1`t z)di+joEESO^m!5HRQ_XV7DAh}X_uXh#LvqI;OUaQ5sr>lW+!0&moHIT6{Oco-m(cN zPr#6=y**T|)ZuHosI#+wFf!an6py>J^Lc;~mHx4Jc7n9)>{R>|PfnyAhluC$R9Hz{ z&VVjVdpbLL%NCnIA_gd;8DKbV2I|8wCGF5q(6pr$^j_M0U|>Wclw5g$oXzBHBZqdS zwBsZV0hlYwE(+U2VU}Zn(#n4N&4}e1@->h{i;NwDUhyAbiTtMYfyrZaWL8V-9=LRD zvf;|csg2X8=E_#5EE^Z<>MtFh*!oJ#<(A3r%MYh4^%M=c*q}S@vcuKI^XO@M}F+duC3~HoUp^`r4U}x%w@O62dcEq>arB zYeOG6?bhvgJ>FM_FAry|@FQz)=_{j`N2ec{^Q_C*Daav}cwXta+%fH(D_)(U6qzEa z$n{F#a$wO#zsh9mXXKfhj70AnrEgW=tiE;V=Bh>hov~T1?pb`q>sIOatG`?Q_Mz|M z8-8X=%B_KgK>3x^Q>Qa#@~>%pqvcx5?D@GhEh6B+!M~_}r~2KtxdTsez+Gn%mup4r z%oc}r&&AiM~c<(>JZ>mW7sSn*Ly#1yrH zeQkc(qKhGHBbJagU3Lg?iuphK8abs@B8NQg4$)MU{~}TIxf_g@+ZSYI13p1s;A3@X=Urs?7Yx&>LvOJTHfdEw2>e|ilO<1RRtr1wi2QYCAWjy2ru_K=;I zrSdR7DvyxEtIq+ji#;tdq8y*}c4h|z>lma!tEoad};94=%H5eyc1`4;e> zZ5TXrZ%Iy4)f;u(FNYq}gw!KPtS`GeoDrLG%!nP~)PV(0#Gy(fjK8v6hHGWeF7Vl1 zsI_ZCx+r(Ju{pcb#Yct*y7l>$w)Eg9PqOwr#95zZgkTZk+*?pB`Z*?b(lp`+3=*l6 zQt>k)@f-}9#SEdTsyqcpL)*xohqi$=5*vsmz#1vft6;Mh{;wznbF6-<% zzQ-Hke0WK^ul1g>{ z5yg(c0jXefI72EIa{6@2w*hj)Cd0L_Yb zFI3jO=DzBl`Rr^gRk`b{){Gf}_pn11m%h?=xot8!eR}55kK7wF#mM7coY0Lgczx2> zoCkvDZ@NOJSs9+|H3#h0cPu7&-?7Q$x0jQD6@3g97eZv3{y>I+))GOgJcgeNbE?|N zN8KZ4@}uNqw5C{{yxoMDcVfFBo-J<|kBC`JoIQn{*XhG$I3K<&WlSb()%26EbzJS3 zEqya^JuqtrQV_Tqm@S#B+nJH@^;YX5y)q6nVlKx~ejy<|Q{=LSbnJlqdDsC3@f{ofpULLV9G`6nr)y7}##(4r7I{=OC zfbywH6O*NY0LId3pD*ToFiXS0~${q&&#A3sN7 zZwgXC-V{WDj-bMyDUz*q(`%N1z6d@&7xLfLbo88L zIjxQ)C^71*Msn7YlfTm}pNRT)(}D5M#ZbrO?53h^1WJ8&ThVu93$`e^SC=57Q1uzJ zXj>FXB2P*QstZ5aEr~ZTZOKd6kj~0dLf>AD7PVfkb<8?uIS)ydvTMZ}ShF>FnsEbc zf4QYWvCX*dh1;Jf<@nsdq-IG}Jx z;^_cH8l-y!KR9ig-V!em?3_W0oE_qIoD7lDww^dCImKyEiCwIUfW$UgQ7}_9xbc^W z9H)f^wi2Xv<&)7@Pv3T}xl`7dDqA;kC}S!r-ly$`CsUQ7No&S0`Ku<5-SL!7KKMJM zNk`R(O99Cr{JG>P-gl>}cD`!cT-CNz)s9Kqg0E`&bYxq`kLp^=rqj9-FPW5lYqWojSbW ztHf6yO1&2+i1BJ^i}b&&KDg2RPF?ANt)_Rj)*LLg{)t;g$e(y+@|On4AEJ!0ukybW!fe4{*TvM>pNnY7^Av{9D1(Iy5ZGmc6>}*WPo2im$uv#bX z2_DNW*&|Q|u1Mqn%JPg9H)spDr+_p>r}YLSGUWq3CcPx}Oki4yIBsuYjeroo{^yh~`ZK$vtfOl%u9uEs~st3gZf zq>%FTK%mM)(H};isZD?^GM>vT*DKx}Y!xb7%+`jkimDxzwuzKbXyE$9(2nF9j@_PP4)H%8y9Kd=y}n08H$&m2tp)+gQT5vj~Kxo2|I z^z%tiL(M{8LiIk#C$~< zC-(k0u@b<<@_3V_O)1Z&dC!hH&yHK4{rV(u`Zs0SGL7TBTR4-KH3nqn<-|j}ty`{hH~^c8fG_!!Pqo z$H&Y@LjIQyA>5$zvs492v>6SAMmwNn`zwxaGnWk+&$FoMxP9EQLcVrwsKy+qUlrGn zVjB)?{J@ySh@qyH{i*5(yhN{?{eHP}%_{Ypq5UsNignC3#w-x5VcCdjmnhc8BtgT- zkMUS(6rk1<<4(jQ;9l?~d|Ci8;u8Vw*9y53j{%P+X743=Tfu{!$~orzjzx=;tJ)`n z$=D4Qk#5tt^@8x3#~tJLe1FK=e$Uht9Ibwlv5W>~ob)b8=B%!*@#fLh%f6||hraxp z0k#O;Q^v@log(BGkj`&}P^7J_Bf-08+CkfM&tPAKmulMFA0A3uh@&DHn*?mqW}Gxp zewVT>G9>Wags?;-o!kblM7l%`QXxdTIPZ7bp&?Dm?;zWF5ghE;>LWHaTKS_TDtJ)& zNNxfN$Kil+S|U}}O}H0!?s;qM=Gc#_T4$e{UN^JuYICxxb)p2$U02D(!_)EkRXgWa z?M$vZv`|w&U$cF#X8Vo9shSoLXEtfe{`t*^<~AQnZ9e=MOCS*z4xkTW1^JY`Wf*3hqpm z@0xHeINYx|FFWtJ{R`fv1@DeKUf*Qvm19%KQr?C|yQR3~mk!AjxZE@S;B3vU^AkO( zlE)U@r3-G)FFX!s(MLZIN!5qtj}{#$|D(kcxQq);6}4`)yyK~DeaQAFbv3PfZFy*r z1;fFha|b-M;peJ@8-YS?Iby3e@%9W(yIl- z=#v66cGuF%SN+qG*ZQvZrK%oCRyNHZNP3!+j%Kk15IVJ7%Y-&MZo*x7e%nlqz~M%z zAG-iJJ2cbz$qFF=8FY?}_7xC8-HfphNJcDQ#XVt$kk0(FW6au`l@8ekYA&05b*Pq; zpX&XRnbTPc(~a3^Pv|zCrQHZCW!!F(#w=qx>V?Qb2415=)kTqO`{vv5C zG-9#{Ju6s(%L8Rm)+z)wMru-8G+x3v>Khu(KpK1hU(-FIaa6o;mQD2S2wXe@=lA5t zC7Cb<={X3{`P2eBweY!Y(k6Rc{xY!F-oE`0+NecVAO2s2 z?7vt3*z}VSoYdZ|z191}t!-a_ey;qnkK#0&zgXTN|ADth(5RIftsxCY z=uTdTtkFAULw<)q5f4gIkb%yiP~{q&ynaw#N607dfk&wa8j(cnffL*V6*nvXZPonN z!*g2?zm1-Fl6vBV+7peN~vkU+lj4iKY~XChC}@zwdz@X$DsbATynO&Utaa< znjEU)uFEs;s(;T_|C92^W*)d*{@CTCcdORSSB2)PLI8~ukNu?l1cjfNIC}SiZ9npC zp9xQuOh5laZ^L_@?McV>kMLrq>^oJS0}oh2@~KduP%3hO8kiN0JWfBkKU&F`6$3s- zKUb4O1d>p3dX#*$morRP=yZb6Yl@Pu2TmMKlpYa1@gfD1^VjrY5e{U6ADBv@-V~JF z{!6VNSWMPUGx8fn*NSGhU-OVaaMRmsT<*S!$|xXk-T2cVZ7W(-&|!v5(b5%}qE=&F6JiH4OV9+Z zl>4zs9V;**)iborCbcn})E)uj6>>=n%O#5=MaC&{LY3kfvv5nePPPa!Ry`}`K&)GX zlgO%`3$bI3zH;7NvN2=TqcT=WvPw+WQf8Buf&MK^J6dt_^Ayf?haU$XL0m#DK(I->f@Z>r`A5& zvi37AYfsXLk4qfPi7cj!LTGu~uC_Rj(P+XK`npI`5@OllNr}e`SjXlgY-IpYxN!EtSOX{KaWer{Nqw>N$4Ep2<^*0LV1Pk z)TdQ?4z@6uHA@Nz1rK^xKL$>W*-P@5E62dBm2qgqLd-;}N5PX-+elDj_%SY98@F$x z4fKrL5Rc}1!IRJ#jLb|VNWjkuxvIHojKW@>`KYBM^-!=xZ7VYq!75ZH5q)%1mLC`y z#7;uoLMAYBx3m`pECu^;^CyTN532Fw<2o;q_(S8cZqCr?gX@wUEKMRItxt78-DMzY-JyvjM&OtX7ka&_wb(*M)&oH=Yo6a3`bF>chKjJiv=8^6i7LAK-a!Zo(#4$v94Zvkb2PmOMrJpL<;r}tuxVN?(zN5jKRAvfnIJtV_A#ktPXCbL7q+z8PoU43M?G!pS z2ncH8eo4D>LZKS>UFxAQISebmLOuqv%vsrppK*c;1pRVAU#-zFX!>ziXx04-BqBv} zr?Ui#24CcxgB5JUeXP}<1I~=?MZp}&U+8dc@HgAubMse=F``o zCXq+04E9NB8RR0RzFq8h48Iec6SDJFqWa5; zi^E(LFQ}Hvv{#+cC&I9YM?j?=QpeZ;i5@Se9q@IM0X+D^7lqG?LooeA0;Je-dPFA; ziSKxSy&)W#&N)>C>50@yz=$8n_N7i*dHkpvM%S&%_wieKo1AyZ`4e*f6pp6ly3+S$ zDy~dIRu#5dCnevYnZF(xV-b5Le+AT$91Fg3epLqXDqc`ufohPKMLdb~unHZv{xNd- zSjy7S@DduSzxH=pN(>q&O0jS9F+@R{}soSLwg0Pt~@vO+=BWl zE2rbN8JFa&TEY<>pfHlR>eHQ~(nsqOCNPZ_#E?=S=$))m`(-F_d<8ogQIc6}K`d}I z7^R3b46cX*Q2_*lh9jo9q4-fm{hj{|xDakMY9!h;C`qG^m?|M za&olAO~`c*;?)#X51hZ8WH$19lkdWMki zpayAEUle}{0Zs{$rcGxNayG#bHEknw5+FVwF~VVcVd>^fv{Mx0G$bhh68R}RC{tS> z%t>J@v7N;`d{G=ZBTSHxDta#EU{;mO;DkzCzD*zkrw<84EZQVz<@?2Dmp^;C6UXWf z&u&i@Z=NtMfMC2hb#W$ik|1s$t641AnFSY#G6QGh`oO*F)#~Zt@?V5e^hUKl|o5iV$ z{YmfspA~*Ral`*s-OajG#luPO!#{JCPCb>22JT9Ech7qtne#rfP+dFII^Vc!u5nkY z5r^lc(gXRp;1c74-mEnR91s~C9*CsPk(hF?G!bn+#){W{&unc9Zrb`>+Cp1+-q}%f zr@;Sdq2wN;h5ZtF^zVa64D~f@gKA3obG=z%N3!sYh55AxZI&xA| zbDvG%MDQo}hI z0gi8U@=x0oG0K?15$iW?ya|pv1gL?M#zUx!@)J1s6XyfHq6_bavJFv&}!p-GJB zQ=Y`A9|5CA=)Pdy{gTFLAL4*{SHJqT-aqJ_Dw;hrVTE+!>pP|`Uu&87t()_$OO~yl zd4ASEAKEt;+LsDFoZRrp+kv<3Z$mA-E$L|EzPxU2Z$EP6NT}415GR^DZSCnB3@4OU z_;VCBj?zz}nuN9nZ`K4`6l$1I)QFO=2TmOI)zmZoJq42Uht!Dw2Oc`IZIf27TWDCj zP*qR=%WFO;c3W%i7MHNy7wcSceFn654Wg;0U^vK5K@JH*1}FK7$mb%T8@iPl$^oc# zQOTl*e6`LMG&&HTDX)Wt6-`lt{CO+^3dmy#AV6ga{K5)ORclKyKb3ImH|Vp^#-D z`?(qIpuKo*Ka9+kN62Bm)DiMA>xw50P42>jf`3C{wFH0ELxzT|fpS)3=WmWYLp^Xa?>KL5^aN(UNvf>6`&`zZYcOj#)~ zxr8HC!4^=DVVsL%JG|(nF7+fA_VBQZ&EiCsFk2aoFgC&3k2p(~JypecXS_>Q*1!he z)dd8zi;r!=8)nNb$n=0*!j~j8 zXGYBIA0wb(`(?z-qfNDDfp7(A711KOBz*v@27V!Z^7tp?mtRaegzUgzSsg%%oVCTE znSpNsYxKWTJaQ~l&USc670wOOO0DFsAp-+8Yt2HSGGnIqD(I8byJbJW?>gN}R{Rz# zj&jLcanv33d{Piqa)h=K9Y`tfBkd;yP}U>Ijvu%mh^olXTL)6O2PF%n%I^!LxH|U- zQvZ!=Ob)JX$pWb|0#a21NL2_RC5}XM)Vwa!nZ(n`B$r97U5ufzigA&I7w3-+)z8E= z87nHj@g*7na}KahVdMjUPMC~xGuyT3s4bhqa5eF+3x zl#(&4;>sSrfMq9awZb$kkmg+lNGZQ6~kt`{Ja*z&xnW zAzj)@k|?&=1T%9%gsj}Q=kPU7?V(*p=M_;dqrU8-()sqg2$1Z@SFnjda63yb+nIap zoA%9IytU!owP2(Wm)PVi`oJL-2d+A3Gr~`zPvtYk0dgGeWCue!a%w*T zy0pAip=q3!N5G+hm~tcrw2qg*-|(%+OVR+fZEy3 zFpEb04Ur-(4cG((^)jUVA^Zir@Q~Gr^^H4SaPpE>ff!`vaJK__!>cI_oT4=qL-wRF zfaB8`))@xSuokUVsWx$Ys$TC-o1Oyz58uz(!D$7KJu>h-S{ue0DZhVKAw!V96Wyf*nQ~O z^8Ds#glrGmvq^VkOzkjFkifUYbA zf2L8kmJ7sDpr~BPe^-E@^z`YrRt5w_WYKn+whRx)BA)^h&^qDWiFTbFfhL9V0~Ekw z#4FYWQ;JHB8LepzMvTj_rDZXK6uEGwz>3ypRvL0?^~k=n=gYGwN3VgRCm@Ax1R)<% zPGaXi7%9LB`9TlN+x3s%2xTt^9tP z_d}@SC6;OV-**LIDDu>6PhWldwrjm0UA=)Tt|`~oiYKfYi2w`u>9lcADRLNQV2d@Ib+J zp!d^>tX|$u4J7;q8miDiafUp`(4d4qlS7gM9U8FFK2MH*5&83=0R`ki0|e;M0RGJC zLTEsR~Fx44ZlhcK-I>FEN2>0J4?LDJf} z&sQq3I=hTCUsPxgIin>oL1lq{lMDJybau}*}FRXTl3}VH@Tr_R7RvO zaw)-iG9q++Ftg?C-Jr$KzR@Z#zHH2fXg=eTs_?nTOm3tUF$`K1DdVrc6~6lUE4A;_ zmFZyJsPc#};%EISx&@JPY1ZnSeMc&|mUPFVrK6Hb{3?+6)oBae^%?#LizKy1fvv+- zRWRq0Le-oWndE|rEFzBR$~~f-;JtvW;D|*h?gXS5On8E(3J>G1LC8GmUZ4?h{9xw= zOg*~ukEC1>jf)#vqBy>Us}3&Uj9It``-S?IZyw;RaM?%<$CV?&3xmpe6s6r3M0Exy z5sX;~&WKz?l>1hWkEDhBRIY7T*Cy2vmMWa3GgJvQi&_N_-Q=|F>JwP`*Nk5s)Grwn z;#uw-G~1vi+)!d3i(_`UaD{5k_YIv9-K8c%;b&m^3o>OYh$=!2%I{*$Kw?m5V`_as zC%(AHz*R*$baYrfh8ODwUsl`)n{!IAs}Hxl!n9Xkn67FVNGOASxIabQCd92#&820# zH`WiU95LunVL(x_VK9u(R72cUL006%^nv|Jn3#igc{MKB_jEZYGy$^LbFkeu;?ARCkj!FA6Q_WPV%+z~ zC-kTvxVgx_ALi_k8HR@L1LS)b)#{0k%MLH~RrrNL=qhxh3v^WhuD-}!RCpj7c(!3FoW;$dbj}o0 zC`vO8=TF597YY+`aM016eK?@VL#R&$)$jwlj2AMe;VwgWk){Ls3m1#2jDJibVd^eO z_6Jzwg5XF@7~4blsr`mYsX`xEzZ(XCLYEQ@qMJT>^eH012z5AaJvKCFM>W|5Q(meu zyMEjfgcf2(5R9Tb7m46WJ1836-N6@cw5Kh!5YrBA^`vc(qrvVUOpRbZr){D)f4!Qd zK;dv-xujH(Q%Mf4DVLOLIGQHuO5cq&NsEu5%{muqhA^1**fdysG*AV7QKzOaT3(A^ zF1BrtK>GC+*K&Fc+lWBk6?h6bc*{-P|H|5<-~pn_^ys>u5T)x~fbL@E9bpH`Uy!4J zT1nxvlshC>$@7n>Q??@Uib|fa9TU46yV3a8rkk6fzIog6NUqJhMkKvgpJ;}`_rZZ@ z0OXp2gYo7k!ijUoaF&?@o_j9u@S_@dDD@!eBl(-7ih+Tc@ZZoytosbLX9+QB_li@alN9(xh~G75NiVuo1CkG z2{@nlo$HPn8n)GX0EUh3JGZhr$3|MTIbVtKU+@riI;QKEVixNd?aMUVT9W@Kft2?G2a&g`iK6SMZbO1%?E{GJbIW_aQdUw^j?uzG0G% zz&JnI*#;FQ%b3H6;(;=prH~;Jk;War;TVy``+}^Q_@=X?b+qBgyzktT*N>Xlw**50 zoae%Q(X@%;KIrpN!RWLAxxj@1h_BEL&H=!@ebLU9E+#Ueb8rBXa1aV^@xAcl_ z%9gCyc`K0eK1_U&dgpPOk5z@{e4*L3Dc_cf)}MKNcLH?~97Bz6_to7qkvICU_1`%4 z)-yMsdDs6}HUFVz$!sbwn>0aE;jfr{7-}%{{Y->(lXcmtD(DK_{>Q#mdKs^un|=Px3)e5C*6qCQ-$gYDOgx&gN`XpI zhy3q%eg26@aY(EjR?exR;*{95{OV>jwR%gkYU>T(jVIsgxY=>zShD=U+Yi3GX5QUC z=WhSM>1_CM`Cgo6^1nJ*d$?HoQ`3P)yne8LE!;mVb{=t?|E#>}h~50>b}RgB=xVu9 zHVe`-6sK({-y|EGIWtGhI1`N#qvtH06|shieWYIusF8^|m@JDM*5v zl$=&_ST5N{zN}^>0l~DD(LkjMeqqV#7)7G?C{c2H;N)sa`Y9qgU!a!J)m9(U9etIM zVD8{U(F;w@ZyvpV^v&bfk7uvoJ9%|;%CZLwHc+|HxM5-SMpCJ)s3m2}y1ON%q(fN; znGMcH(*1rXr#5GxLRp9SrDa!&ri!MwPkBg{vJR@0xRbBX~;FAcqxP1;}B17oh*LeEx4jKJJ6BKo7lpN9~X zhehICmIilVa|Rsc9Kj}RT58__k<1`GiM~x+iT4x5F1reuF|VKJg}M`Mpm{;ghcqt; zS;7%C7cQ!pUYBw;yyx2c`e$cP-#D6DyEkdsE9f-6n(%12-{PMji{+eSW0A5E4%z|b zqTaIHtc5?yR}z39X(E(9%Qe<~ks1i7-B4|EgNy727ugM7F;24L&xyYxt7owV;-^x3R*s- zHmGex@O1+#d@bkN6-P=TRcpj4#FOcUE;0t<;XJdvImNI2}pcft=2Xq%zB z5k@b)oPIePagqiOXmGSiamA{Xtwj z?MmvdQxL#s4SlI)X{T-Ue7G29_!0vb9KT@&mkH88S-RK)s`C8z2stU7t(b3R?*x9D9kc8j{Y4^4;E0<3Xg_&7Kfuf$oCqsV| z@2jAC1a6ik)&f5+ar9!edw5xLx->!y|F|49egJKKMcHDbkR>Gx|&$d{*}&kp!lu%7v$KijaLfuobCX zfxFRdA$fy>aUZ+@>qv3bQ5!@u=Z5a3Kq^EXOYMqtUBaN(H4MhH$_EDq0+x4h1MYuD z>0rImwB*GVON5$(r{h9Iz>|os@6fNPrZ`M$Vet;);*$Z~3c?AAAWsp~Q>RG;> zpe1-{Z~&ZGAhc*H8|XR9nxKtv)>VQM1PA%uc zHii1rgZ%XNjjV7`P@x=wCKWz;IqJHi`8np4nN{7$D-(BF&~bTahwAWI*^S>JmvR6v zQE#U6Z=f3nDjur3!*8V${RnrfAqlCiWhj-mKoa7Z) zHsRLYXoCLG)Zpp)AL03@7aw3+=#xjU15Kh|mDwtPTU`KIv4pK~He|<><^Wh!1)_=- zho7g+GpKKzx+_4!OODb$MJ!FvNTihW|a`4C~M&4No>lx z2cu9R=;X}=dkwbr(F&ec%Rf9ylk0h8EmT0gs?_E?)i(~`+VTC}-`#yXba=tzdu8PE z$g79uJge?hRI$N<2U8WHq&Kus8n{w5RrP9gu5?YoCzYp}tlt8;TIgoz*5TB)gQ7zDA$yOgk?x?Txu|V?&pcpo0 z$=(#(yCs`W^J(xV{_&%&Yr+4sjP^FI#@Y9$YWt3CI?eYf+V0R+#Xn2iiQic8d~Dn0 zoN?b(kQhHdMcbYKtZg^COG`I##3qw<_9R56&oh+wFK=($2Z(Xsyt++K<81H8!aSW! z`1Q|(r=>~Lm;X)|)E2deOpDmwrA^8z+UjX<8(s4v@$<%Eq?dSA@X|eDI`4srQ8GHo z!Vj`r1TA!f1mLa+?p3p%;d(vC@%6-g31?Y#&9DPyoC)zeG|Kk=u{27!d34=<^2(CE z&7nF$dNI08B$E)}fXko|ZluuFU&% zYa*8Diz+N-wx8^5J9*;p(X>4dLs3u}V`4AO!L4m4nCgSJ7+dI1TTXNyf1GK+wB@tp zB}y=D`5e634KTD13-K52y}}li9fEb@FDa)ex(Q5CqLhN_lPjB65jAG-oCfL>|6`0g zurs$*;+rttg;|y6spj{}9-BG!M(4Focy5*5dNH~Cu?hQMd&+^T&3l6Hd4jN1Rl4f^ zK*g13rk zuk8Qo{?{XK^j+(_vF)vvn=QB3?I-hh&MD^|e;`@@P|Ck^-oJm&zki{wflds()_Juv zRoDEzRqqB;yN}}_W8h)f4h@t8WeZe86b*Y(FeF++Iq&=GzSmE^@$9u{Z>)Z6KU3p{V+Q^N-_e|fnf7gC{{Uf)U2AX*)~_R?Z&oL z%|q|`AIdHH(+|imd93Zo|6ZIh%XdP7$M;Boxo6#H9yI^2YYvp)^`CagaI>P}Jba&U za!h(@@mVXsIU_;6>ZWW3HIBu*fC$ZvyEj)px`0G*}AX+R} zXMlwr#GEeDV1UMZih+p?DG8Ykp+uTMg`)irp|9Rl@@Z0Mq zEI(!y1j}vjgGtXrNykIX`U*LZoH}*n)R805KClQuGx1MYn^+ipP&iBZ9j2vPIDy);RntZ&ug~<0YDhRYk@<#dh*h=D0 z;}@$S)I$XUpEhm2kNQDn-9j}CIn}W_r@DnYTyYs(*t{L?2Z0*v>btPcWW^hx-d~xq zlTRF}CZ9M_O+Gi-b1EiZ35@G!Jmm9AfvQX?`O2V`WN6|!Lwx0vI6BgWvq5x#0f|((H6h>^)nh;1uxKd`)Zhq2 zPgH>vnu|x|bA!V;sRAK5)Y8N$scaO!yBFuT+UUfFdh~)%gOFfQlg)ACRZRl*$Q5OU zWZVR9C56*|q?N<_5{_=HSnHs$XRk`=j-V3@Pi3H)sDl#iY3bq%!8TDrnhcIhRx1;a z_Q7N)+6K|BxJ)ao3MR!(Vz}`NXUlN-i-of+(k$ZosT(4NK*=Di-i(DqP!xa;fySRf z?@`xqg>Z@}+OOJ?0!2WH7=E|sY4d~eC{PlD!6b3R1+1oSaRDpTSjSB{nn1b?3fHiD zEOZTPo?d_Ui9Edu#O%H|=|`shzBZe}s43f(XA^7PRCEY)I;d)Y9T_!6^{f z;8X!wY|&OR?*24H!E*Wo^1X2r5H6FEv`)(heG^do21X)i<0eM9dObFJhFIciKV&5; z9AHs`h^;(J4sV)lq=niA?C6r{AKDs6%S8X=ic$WY`iRhg4-3U8yY_y+=(|NfsylRJ z>+}Hb85p=a@WcA%_v#K!I49T7IjY53kdJt_EGbuDpZ#BH-RyJt<)2VXn-&7*TQ zyFcO%`$Bo8EUag$7kANcDkqR64v(ZxZQ6}Si?T)iCFM)l9SoRiw{;;);AXwodvDk5 zPWg5x%UW*X&aS;lhpHn-*=Y~WYx+|y3FfR*!!gi$UN!#)9?I_{F;B&1RSn?Fs7q88 z`csLKzoNR*7JNy1-%~cZgAkhE`Fzq*FED~e%88nCKVb(+*}1-?&i>mbx|I5p)*1HV z^_FK@>m=+Lvz*_FVz*%4(ONHfvO+Yv{u<{usC+y|_hzxpCbPy?yllEmy4Y%bS<2q3 zHDR7GVgI+j?8ur`FrM|Osk#=H&wuROw)WAM7s2CV&^RvkV6dg2rlsHlN7#9WQV=QL za2!^b84q5-9>E5on@9J2>a^H))x-eI4z1+0lYE>%<^&HS(H(hfkv0ili^PciJ(Io~ zOC^bqrpOEyVPEjF<+54pG<7}t^424pJ%J{*z8aM~$Woyax$HQNB7r*<-tqbjikYZx zB?e3MeVU#mtWobn_CJ38!P#xI&rhA0mSLZF&3s_pod0pLSie|Nja!g&CO+rNF=U|PK|!; z;R(kbKiQ&rY{Gfh<)3!Ehtp)*#Wj@+{wEgvPcHcDaK(LT8LqhZRZXp%*>EE^xh_@q z2<*;+@s#mM#pO$qqqtmb4u5i)uL2CBn z3vU01vdC5*l^s+?f1QPcE3t9!Se- z2K4Bv*vg?XSvdwfR80Pin{!f{KPF{$R#zblAhXgIT*85R(W7k{hRNwhAtg9!{pnWF` z-E4td@4GL+!cT&rEkC(EP;iK@m@d&Yj;TvhY@=88O9hxn1BnN_>I&II(CH*LdvuD3 z6kQjYw-S{YDFW1G(n8fk1{Hz0pyvkGC$tkn*pXBV5un#_LLH~qh-Om;`-2dt2pvn# zCr7*U2+MU&jcz}XAR7im2!RF#g$5=dY!i^;b{G~4P}4|I*NhZpZx}U&nsL#ef<97+ zx1fBJd|xMrhDIzj22~882+Rtw^ta@DpPURit>n0nLAodwj}M=LA(41IU2-6fqxp2g zUYyMP1;rv&B(S^)QB>&i@wEHwFzzmnMtGY}TbQV_AQE+#fNwn%mz@7X@T~zJ2sDZ$ z*jhby*Y3PDI(ar(9=Zb?L}y>OzMhyKzwO#YHgqc%D(a`7pBkOCz}ld{eme5{>F>18 zeCD=q+nuWVSL3hmnDu|-^Qo%MQwQI#s+*2{qZ*!4Wb(DTiGz15Y9`$8+e;@`e?5BJ zUV8_Icu)M!2o86Pu-I*TaKTfGoyG3_^2wJ*CJ#vddE{Wz53PIZO?`~<&6vFZSSsr*Z=N`r2mOUv#FvC z*U>}#VV1lh*oDOT!m^aBHfgE-aLEY`EL<1jEWPXYzVE8kK4hE-x)-PQ`KR@(TAk7l zoX*x&<{#9{aK#O=4+#O-Q`D^q#7o;S6QTMlh$8f{q|g8ep%-o3X*({4?FTw7;%<~iKCu;NVE9V(@z}kJoM<{Lyxz$A5E8vk~(ptL3AKa zi9w>mMi`7xM-_rOjNqodd0bXR6TDfTi9{puEK<&qZ-|^1$sqz!+yVFR$@e$p{8w`R z8#zBG=Oc2+jFLFu!#gpbq~brP}{fTF;)wpGvELD%Ifs zU9;u4AO6C_Ke4R-sip3xmQ_EsZ26__ph+(KKq7bPF^g4hoQ4rlyq3HHIW*a}B;mER z#VOZK?_QGdTB@v&D<@-15?)I?&dKtQiKmw&dM`a?Zk6TgiIF9V-b?K!k6c2j@LFm- zDa((^xPN9zV&77q$tnkuzV%dCV98q{*CaiwW@;(lnx!39xgr?|(YJ~v?*VYcr9%U$mP>cs%H7pmbfhMoLKq-uGtUF zL*BRKc)=v^q-gYBQmmWhV=~MME=lD1AR_OU>n5MP(lOOBBfnw2W}OSH%SZ?VVpDyy z`qqK(AO7y)xvd8|?A_QRefpr?Bze}PN*XV@U_7;`D&?%cWP{J{`{KYQGd#|Ul%w*J Z6+TDci=V$_0rYTGrR>!&Ss35=e*ymJ$lw3~ literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc b/.python/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..daa08e8825e75e49254573de9a3dac05cc9bc762 GIT binary patch literal 26294 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 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/.python/lib/python3.12/site-packages/click/_termui_impl.py b/.python/lib/python3.12/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/_textwrap.py b/.python/lib/python3.12/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/_winconsole.py b/.python/lib/python3.12/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/core.py b/.python/lib/python3.12/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/decorators.py b/.python/lib/python3.12/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/exceptions.py b/.python/lib/python3.12/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/formatting.py b/.python/lib/python3.12/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/globals.py b/.python/lib/python3.12/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/parser.py b/.python/lib/python3.12/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/py.typed b/.python/lib/python3.12/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.python/lib/python3.12/site-packages/click/shell_completion.py b/.python/lib/python3.12/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/termui.py b/.python/lib/python3.12/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/testing.py b/.python/lib/python3.12/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/types.py b/.python/lib/python3.12/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/click/utils.py b/.python/lib/python3.12/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt @@ -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/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA new file mode 100644 index 0000000..c49ceb9 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA @@ -0,0 +1,81 @@ +Metadata-Version: 2.3 +Name: Flask +Version: 3.1.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +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 +Classifier: Typing :: Typed +Requires-Dist: Werkzeug>=3.1 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.9 +Requires-Dist: importlib-metadata>=3.6; 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: Source, 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/ + + +## A Simple Example + +```python +# save this as app.py +from flask import Flask + +app = Flask(__name__) + +@app.route("/") +def hello(): + return "Hello, World!" +``` + +``` +$ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +``` + + +## 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 + diff --git a/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD new file mode 100644 index 0000000..49c12ee --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=GoX94BFsK3PQevozpOK8temuiqCoET0BERc5QpMqrYg,233 +flask-3.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.1.0.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.1.0.dist-info/METADATA,sha256=Wvf66xwUclGRu89cNcvErpaMf1rMgcxeqIkTc4EmD90,2718 +flask-3.1.0.dist-info/RECORD,, +flask-3.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.1.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +flask-3.1.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-312.pyc,, +flask/__pycache__/__main__.cpython-312.pyc,, +flask/__pycache__/app.cpython-312.pyc,, +flask/__pycache__/blueprints.cpython-312.pyc,, +flask/__pycache__/cli.cpython-312.pyc,, +flask/__pycache__/config.cpython-312.pyc,, +flask/__pycache__/ctx.cpython-312.pyc,, +flask/__pycache__/debughelpers.cpython-312.pyc,, +flask/__pycache__/globals.cpython-312.pyc,, +flask/__pycache__/helpers.cpython-312.pyc,, +flask/__pycache__/logging.cpython-312.pyc,, +flask/__pycache__/sessions.cpython-312.pyc,, +flask/__pycache__/signals.cpython-312.pyc,, +flask/__pycache__/templating.cpython-312.pyc,, +flask/__pycache__/testing.cpython-312.pyc,, +flask/__pycache__/typing.cpython-312.pyc,, +flask/__pycache__/views.cpython-312.pyc,, +flask/__pycache__/wrappers.cpython-312.pyc,, +flask/app.py,sha256=GE7QOE_N9THDjuzKx0gUI9aF4hLh0xwBDa7hLVsjy-o,61725 +flask/blueprints.py,sha256=p5QE2lY18GItbdr_RKRpZ8Do17g0PvQGIgZkSUDhX2k,4541 +flask/cli.py,sha256=XdmkBD74SnT0jrt2gqyHrE9oXGdWlcdTrJQR-i5aApY,37093 +flask/config.py,sha256=PiqF0DPam6HW0FH4CH1hpXTBe30NSzjPEOwrz1b6kt0,13219 +flask/ctx.py,sha256=4atDhJJ_cpV1VMq4qsfU4E_61M1oN93jlS2H9gjrl58,15120 +flask/debughelpers.py,sha256=PGIDhStW_efRjpaa3zHIpo-htStJOR41Ip3OJWPYBwo,6080 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=7njmzkFJvrPSQudsgONsgQzaGrGppeBINevKgWescPk,23521 +flask/json/__init__.py,sha256=hLNR898paqoefdeAhraa5wyJy-bmRB2k2dV4EgVy2Z8,5602 +flask/json/__pycache__/__init__.cpython-312.pyc,, +flask/json/__pycache__/provider.cpython-312.pyc,, +flask/json/__pycache__/tag.cpython-312.pyc,, +flask/json/provider.py,sha256=5imEzY5HjV2HoUVrQbJLqXCzMNpZXfD0Y1XqdLV2XBA,7672 +flask/json/tag.py,sha256=DhaNwuIOhdt2R74oOC9Y4Z8ZprxFYiRb5dUP5byyINw,9281 +flask/logging.py,sha256=8sM3WMTubi1cBb2c_lPkWpN0J8dMAqrgKRYLLi1dCVI,2377 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-312.pyc,, +flask/sansio/__pycache__/blueprints.cpython-312.pyc,, +flask/sansio/__pycache__/scaffold.cpython-312.pyc,, +flask/sansio/app.py,sha256=Wj9NVGtiR1jvkZ9gSFd91usUlM8H0g06aPVz2sMh4bw,38116 +flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637 +flask/sansio/scaffold.py,sha256=q6wM4Y4aYMGGN_Litsj3PYKpBS3Zvut0xhDmpBEHFdo,30387 +flask/sessions.py,sha256=pImSFQIDCPtV-XSI8ttAyTTbvtRMkhDeqJ8VPZZUaf0,15430 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=2TcXLT85Asflm2W9WOSFxKCmYn5e49w_Jkg9-NaaJWo,7537 +flask/testing.py,sha256=5Dxg6VZ0ZPhjwG9ReUl4TrhvkjBYvgIzV949jkY0jIU,10100 +flask/typing.py,sha256=b7mMBIeAoOcAI_vFzzhfOm7KeZ_n868SIMw6xpX5KYQ,3166 +flask/views.py,sha256=xzJx6oJqGElThtEghZN7ZQGMw5TDFyuRxUkecwRuAoA,6962 +flask/wrappers.py,sha256=jUkv4mVek2Iq4hwxd4RvqrIMb69Bv0PElDgWLmd5ORo,9406 diff --git a/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/.python/lib/python3.12/site-packages/flask/__init__.py b/.python/lib/python3.12/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/flask/__main__.py b/.python/lib/python3.12/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa405872e1b6b8e75b6c65e5699f469a3a535099 GIT binary patch literal 2466 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/cli.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/cli.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..927984e59c23305ea80b1113e0e1d23407683ecc GIT binary patch literal 43389 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 S?-QR93nRaRV}=Jd`u_p}wZ2{e literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/ctx.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/ctx.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26e1fe61306b1c3ab73383ad9c41acb7262eb311 GIT binary patch literal 19824 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 V=vt)Wvq-sKN2^rvDU}%2{x7p2&O`tJ literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9dfde3073b127d038e032ccd6a41ac2c2be0258e GIT binary patch literal 3253 zcmZuz&2JmW6`xstik}u`sj#csgI2Oc*CyKr$$=G|wvH$pRvZIXnwD)quDC;TrR6R= zGqglOPKeZits;P%LnlTlj&$-k+7^SpVCni~(QLpTXax5d&*O9W9&sMlxox z8`o{y5xOuPn_q?R*sN34t!vC#?tCLn!%~FN-?b?hKn8x^YE^v`a@ODpAcXhkfLKRD zuBpL>`t*Y2dTto_1gu;~BIs`{gng<%Uq@L@e;@oPnzlhigOaAh1<_kA=Cqip3rZ+s z4kKJJsy9guNXZ2ZmRVI%<;dk4(Md0c7=dAOqF04^gPtRnQzyb9mC6#Yn>nS6S1RX- z16tUU$th{WQ>pL{&v9V@L#2|7DJ`J38-Y8-8L-BK)Doa>K(GA+XAdBZPJWrfM7!(_B7td3_K_8}oP3dwSa3HjtotWu%NqL9zm!2QLX@4d`S z*~?7Xb4sQ_=5Zx{AZytmlLzQVsC~m^j_n2@XKvU_+Q(>59_rI8`G(V^dBbSsIjiPt zrrol1JD+QHM8mQ3mN}pI$QN=y{z;yjf}U^b)kVEdx#v~h_o~%#GlxB6X|N(6PTYP>Ce+6ci&!n``*os^!bO;^IyeNcMEHUhrwZ%1g2`Qz<@+ZUPg7D{{qBqZ5^$m zg@gN&2Zmq3f6!LZO}vWPlmIDj+|g>-z_+5Scwzr)`+EqzvM>9frtu7L?ChtDn6M4T$!@F+8v{gm)@|Fqp?5`| z$*#=N3lc1*fOsEYK^P!o6}>rxR2CQf;10}d+Tuxs{)E>tM(+*>Q3w4ku!OT%LRCmP zlMT39?niE<7ca|zG?$hL>9Q2ePY0&z)TYZVc41|#q4Tm5EBE+wQks26VgQMte56 zJ0S5&uLEAW;TDv#Ex_%tmu5FoZ8N!a(Dk1w*WJNG{<80Z<BCZD9qPGS&5 z;T1wdC)acD4)q*2RY}6ZWu&Ye*5ipAB3Lmud;)Be6_Y+ zEmV4;NzJkuA8r~INU3N5WX|i{tV;2w4(`enWn*rnC+H49mCq`;bAvLEZb;=xRjnI^ z2xlemxgiz5DpNNGPG9nH*i9R>rnfEO15Z{1kbwV~@4~I&@&}0!ujZ3g_>~c~?4^QD z!d5}@T!U8^JvoU|!`sPI8_84m`2FP%mN%1=-QuH2>~`m!&b^WQqaTj$L{oRuYw3?7 z_mdwax1wjhijUs=+qie_{(J7yOFx(%mWyEe-g>LUtgOpU%WJZ@yg|^Gj5FQHaDG| zOqwz(%hStq@|hdJ&PZJeIFX_{NCpdUj8C@dN+);#A7XiNA?0h?JDZjF+8|?77b1Q zabi0&v5}d0I9b@t{Ir|iLFsKYx`9S_g2UaJ?cnf6aQNZK)y?2*PXZd&p2UW6MmhC= DH>E~K literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bab5991e388ae732750d05eec3e451520d6f88b8 GIT binary patch literal 17119 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 Iq$rmCANG$*RsaA1 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84507fa9e967eb58f90c31ddb235e498ef45dbed GIT binary patch literal 9918 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 kO*f)cd{`O}aUTlW{3gndB-v9sr literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/typing.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/typing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39e4b16117032c38fe8b22db4fdd28c72ed54700 GIT binary patch literal 3974 zcmbVO%}*QY8K3dI#vfpeu?@x{;3SYNkl^JjY#@XXHk$z5O-jf{wW^}Q^V%^PJl>hH z2wWO^iE|1**_?1rF>0mIQ`1xbfL`XUday={6lqVr5$$bHeP+gETj`i2wZzOb&)4tw z{N4}oPmjkrvA(REYI9VZ&_Bn3?rA4ku|GuFc#mgW0@ZuQ4qg)-}-A*60xH{}SvZ?BCOn zlbRY9xLgBb6*ux_xR7n7U#LD0WLRj?jL~WR>OHGm&o%9R{`B)xt-k>E7H8JFYZGPz z8mlCIy8frvLiF?2W)Lzzn=dH*St>x!FIk^Y^!%SSx@g^>bAaFCMy#&PrT?qytEN>$ z)xN{l8L(SEF;~)Nu5fImNe}CjVBX1Ar{oiu`p&B3UIyIHUVX^5P#12fkfB7=8LX=; zcPMT+msA2w#Yk~R642Bvg%p;-Tm9^i+67?t}OjS4bNtBiS*+USY=*~bt095mb3VX7WpO%=)wZfKhM!5LWz}!$u!@0Y z+K4#TV5}cmQG|b{DAjo{qsh(kst<&|C*A^}j0nXmct>?EvOLdj0H$kUn@!2O8CXaF zzf}!Zl4}X!TR0(z_`8%S$sfmpM(krZ;!<&0J^SD>=J`b-E#s&1eNl*GNfN|bU(YR8 z!ndEsu})L%Si`Ky3ESyfLSzkZWq4M`OFe;sl%J>!bIAPnY(-2-1B#K;X703gTTh&G8M`o>d_Wl&kU{QNO@iP`@rm z9}8PJ%5j;fB*vqOR2n8rM@KU|@?#+#u^(Rqd zH$%a%&g)wOm*w#dQM)3#I8GRvrr%NLf2KO$GwAvJpXT48(RV2N4vn3(P`=KB zBk!o7_6mZhtAd<4-^<{O;NHr6WPiT2x0H+Tj}@l!Q@KrodMe;s-doN|d-qH;OHlB{ z>#%o!U|c@iGtWtw@^-vTzDVxJi<2eh;93cn7mxkryRQVLYl^gAebx%F9ln>_FSaYl zqqQ+mW|j6ng8FNH_a78Tl;9xoUL@$!iQQ%&`oN$L+q1TlcB(s6Nam9jO`-fJU6e1pPZwNyS221V{&&aqXP)K0J6>bQAvt#e0FEfsbdBON$^=@F-YXCjC+3|Jq=n^`3y%1JF7Gt;1&y!w2Dp z+@7dHbyYw@D>tm|Zhp6Pp(K}vNcUw}t4gq|5X;9({t{Q7IHvz*|Es+`LoQxbBGYdJ zN@R`%Zzxn}r9YxcT(P%2kL|_wnZ5OWwy>GsECovO^4OcHqp8v+IX6bS#uYSiyr!UQ zu$&Q~*n1M7LOqQeiZ0mm_T07-8d1C>1YNF6s{4!dVe3JwGB8a--zeU12)d?C47;Pc ywcNF%TRoCW;F99KM9^2JfYSa#VI{w!L?%dJQt?g_G^Mqeh88~Co=2R78{)r?u2MVz literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e188d98ead8ae979f2f12f0a11470653fa28717 GIT binary patch literal 7007 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 PS>;>TIzA`x67&BrZY&WH literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/__pycache__/wrappers.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/__pycache__/wrappers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48ee151b1cb7bb5cf62e1e6a858c4b28875d6c0f GIT binary patch literal 10039 zcmeHNU2I&(b-s81xa2OmOD-wVluTagk0M1bsh>zPYsHZjTB0RU4#m{=Ho@J?y+iJj zyL&ft?~3A9HW~~ zw5D1`xjElfh^1np+>(zM+EeYa#QY0b$<~L5Fjpj>D0HSeWyvRVZ^~9z-qV)WUib zYGJ3=tT&_9;?!F72x?KM77?{prxq2pHmb2!y=PULll9oU(U0xLNU1i~w$STT8h-RW zdi>o$Loau1d&Af`i$7s(N5j~-H*cb0Y&&az!r0D+vF#YUSMO?Q=@2cu8d?%)d0yY$ z(9)^*ihXv!8%=fTeWLsv%DYyj>vC%MRcTP+A#7IrXGmfu%M@dLhoTT(PW zUoJpZ%w&t`ISERpvXs><>TD|IlA@W)cm|}+@$}nsVhU#|Y0Nb_rz{&~Wk~~3%fKQ_ zc`aj4iph6eH1*GDMa3-73bI%wrlb{_%o2+j*DQ;Bv)S8n=2XRyG|dG%+#}*Fe+Nbp z?fM3m7+&gT3K$kY@zjahZKn* zS42Z8U#7X{z*ezlLBuSvOl~fhQ4DlRil#?FD|xoKT#L|gRSSlWQ#e(L&|y?=C{yTI z3zvCb>L^WxL~7Rw+F zz#ejiazQDU=@^jcW|v7~7OC}84$_<@)zoxFF9Q$fZ4GoZED4q1PkAJ9gRoKQCf3Z2hoge6h(>>A4_l?%oa3ecULOW!3d z4jgH;vu!1-nI1jNnNFXxRb%9mP>pn2$%12GC!JIp`1;lJlQ^;*^cCFzdtt@^L(o^v zV(6jShnd)jtyzp0az%U*sH8xlnO1;KXIYW9sB4xc_(4*^{6~{WKA~l@-Yy(C#3Y7Tio=wv;x(i%gql1>~fi` zxAjH>F0UXSOF$OXhU8-up#a{&PNy9ffqprO~WW zV57QT8Z~)l6dDCHRUA#0maVK&9L?uuN9`hba%|Lux{Z{y%%V2W%u!+TMm=*;TIM|< zTIrd#?QwGZg8l&C%`2NzwR5WdB-Ze>F0CC$W1YabzuVq#8Z)S*+)7qWk?* zYl)F+bmY@m&ql0&E!JP%cXBOusv17^00g9r2aTvuSpaPZ3V>Mvq>7ULEK9d#xQ~Kk zw|)G1wAO;xG`M^=6BOQurmtN48|Y*b!&jvH`wy=MejQf0g6i)n;{OsnnQ1_LvR32@ z*?6xNmw_$Ck+~f7kBpi!mt#0*1r5ha^wT`OO{WWRqjF^4Mycxv0S8X>tf4Opcz&uW z@W?!~Nl~p%U7;UUsf+qT)r~>rh0WUHSzTj^BZGh z>e$#=8qVR@2TgCc0z3t9|Bpb^qbI;q;Pw9|Xg(v2dj~z0+dE<7^;KPXf-<807|FV zVlPy~FW6Y{44}mKVP3$J*xP<@*$x_g^|DPG;^5K2A;P15zt4DdYYQILJy3x>jtlDG zPl+=VzBl33|KpH-jory_6DQ@hv(qzIza9b|eRll$Kkl?WBmT5`_#?Oq1 z9`cCW-V-qA2nJPlZNnTfWQmUL<7m^j7U`=-jtI0FSW664qXTuc8LUPJ8_?$1TI_f= zeEh$SHex^9(B^3i{__T$={rC;vv)hr(5+WEU>8t$;yriQ&iCAfM%2W3dag>#GVZN@ zC&c50XT(L-4cgEZ!tukE?@nK8xcLZ=-M!Dcmle9|iJ^3{ozvj@=yXHC^-f&SW*IAb z<`Et>*$MPmX4Y21fTfI4n59b_?hUv%TUo`4%y^*(oJjk^Ai`0W;Zf!cPC2e>WrV6| z1EyABw0c^KrXc2lm9v7 zn#4PA$O|-T%cJ`~riJ3s{dP)LJ+(CMUw@_Pt27H{ObB&E7gI?XGHhO}_vY^B7*xt!}Ban>1=Qd_R(? zM*41@`{?v9uG~rN*+?8(OB}jot|yLsbapL~tVWYhSGLn2_%vl(@y%1{%Tu!(va4JO zb;*@~n-Qq+m_{KIUTFOmB$WlFo$JuT$5(QFw>)M{_aVg+t-Ws8xDh zp6^WcSLkDY3oi;{`9jTyonY0`U-qvjPE?~OzPuZI?sF;7eE43h=P&W9RNJNQ|?>jC0Wt+}R_^Gu2A%(ssM3~)9cnCtg zjrw%g!m3IDqN=qP)ycr1997jHl(oF`rAbwFBcrOk8Dn@1FXTbghHNc9k-Ng%=|#J= z!|rTAdJPhUN3BdRw-o z2uDKtmVInU*F=7h<~5V}^5vgMzw@;O!?003y(<^r>sk*ykMi^VD;HK5*8|FCSQ<*M zOjcuu)&nD(QEBveHPBVvePlgw?EaylYGC)zd)5O(cMcC%1JC_@d_6FHXWyZfEAOS& z1BdPhTOay*f~Oz&rBK@@l{QaHq3(@f?^>|;bDta>q%VD&RN4%o&qH5laNOyQ(&n%f z>e&b?Ye9v2AE7V()cc6n`-Io~1oiIR2==T6d#Lw8`m%?59~8Ym_eF!9PH&Vp_hP=! zeQ~c1rOgAPt<9bZD@N%Hr8Ri;KYE*jhkqyGB@jR`Farj951kV{@`G3K-k$%~eW`%% zXF)yiBEGW_<-b#5)~q*){B5WqcibZKxDgoZFmFOPB(EvfVP|E^MC-^MkIFf~Ev41>E7aWi%{b&>M$6$ZpBq7PLjC zx+_lG88{1VxIDmz5KapcBe;psypCfqxnp8kc$Y3EcO8OrPs}QdRS_q4&MMn%{ED=4 z-9xFTPmU(X1Zlvk^6J$qQ^+5eN(NkTFi7|@ZVJj>?yx68_d4ffe{A8;mGd6GCCZ8+ zRYvJsA~R1BU^sl#q-63r^4VOncIphbJ6eRpyeF;Ko8T-tS}sTI42H3oVup zv&F7kqgktv=jWinwYZ}ys;fe;?3@&M6`ddVk$9r+FYR;gUA9rRWHY8pww z5u=DJ23o#uYcV@_<*fn6jQln`ZX#m2u`N8_9>M(%22{GAw2*(tSCi}ptnn9ZQgrv- zMDIr8;9BBf^$;>hr>oJ^4?|MC>*ms0>`*m)NWhz87i)fG{RgA`+q9$!dJ(ws^Yogc z7ezA~jNBfrY#A8?e?gSN-vtu|wkBc818es_|2Ce(8mCeB@)oH}2NdowwIa>4O;3({@L-U;R19)(}D|IXu^ zTtk%%xk;kf^vkk*PulkzspB(g=$ 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, + "SECRET_KEY_FALLBACKS": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "TRUSTED_HOSTS": None, + "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_PARTITIONED": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "MAX_FORM_MEMORY_SIZE": 500_000, + "MAX_FORM_PARTS": 1_000, + "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, + "PROVIDE_AUTOMATIC_OPTIONS": True, + } + ) + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class: type[Request] = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class: type[Response] = 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[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | 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, + ) + + #: 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 = cli.AppGroup() + + # 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 + + # 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 # type: ignore[no-any-return] + + 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", encoding: str | None = None + ) -> 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"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) + + def open_instance_resource( + self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to the application's instance folder + :attr:`instance_path`. Unlike :meth:`open_resource`, files in the + instance folder can be opened for writing. + + :param resource: Path to the resource relative to :attr:`instance_path`. + :param mode: Open the file in this mode. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + path = os.path.join(self.instance_path, resource) + + if "b" in mode: + return open(path, mode) + + return open(path, mode, encoding=encoding) + + 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. + + .. versionchanged:: 3.1 + If :data:`SERVER_NAME` is set, it does not restrict requests to + only that domain, for both ``subdomain_matching`` and + ``host_matching``. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + + .. versionchanged:: 0.9 + This can be called outside a request when the URL adapter is created + for an application context. + + .. versionadded:: 0.6 + """ + if request is not None: + if (trusted_hosts := self.config["TRUSTED_HOSTS"]) is not None: + request.trusted_hosts = trusted_hosts + + # Check trusted_hosts here until bind_to_environ does. + request.host = get_host(request.environ, request.trusted_hosts) # pyright: ignore + subdomain = None + server_name = self.config["SERVER_NAME"] + + if self.url_map.host_matching: + # Don't pass SERVER_NAME, otherwise it's used and the actual + # host is ignored, which breaks host matching. + server_name = None + elif not self.subdomain_matching: + # Werkzeug doesn't implement subdomain matching yet. Until then, + # disable it by forcing the current subdomain to the default, or + # the empty string. + subdomain = self.url_map.default_subdomain or "" + + return self.url_map.bind_to_environ( + request.environ, server_name=server_name, subdomain=subdomain + ) + + # Need at least SERVER_NAME to match/build outside a request. + 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[misc] + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def update_template_context(self, context: dict[str, t.Any]) -> 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[str, t.Any]: + """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) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] + + 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.Any]) -> t.Callable[..., t.Any]: + """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.Any, t.Any, t.Any]] + ) -> 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: int | None = None + headers: HeadersValue | None = 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 # pyright: ignore + 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, cabc.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, # type: ignore[arg-type] + request.environ, + ) + 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) + + 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 # type: ignore[no-any-return] + + 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[assignment] + ) -> 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[assignment] + ) -> 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: WSGIEnvironment) -> 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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """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/.python/lib/python3.12/site-packages/flask/blueprints.py b/.python/lib/python3.12/site-packages/flask/blueprints.py new file mode 100644 index 0000000..b6d4e43 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/blueprints.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .cli import AppGroup +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 +from .sansio.scaffold import _sentinel + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore + ) -> None: + super().__init__( + name, + import_name, + static_folder, + static_url_path, + template_folder, + url_prefix, + subdomain, + url_defaults, + root_path, + cli_group, + ) + + #: 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() + + # 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 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 # type: ignore[no-any-return] + + 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", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for reading. The + blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource` + method. + + :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"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) diff --git a/.python/lib/python3.12/site-packages/flask/cli.py b/.python/lib/python3.12/site-packages/flask/cli.py new file mode 100644 index 0000000..dd03f3c --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/cli.py @@ -0,0 +1,1133 @@ +from __future__ import annotations + +import ast +import collections.abc as cabc +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 +from types import ModuleType + +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: + import ssl + + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module: ModuleType) -> Flask: + """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: t.Callable[..., Flask]) -> bool: + """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: ModuleType, app_name: str) -> Flask: + """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 + if kw.arg is not None + } + 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: str) -> str: + """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]) + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[True] = True +) -> Flask: ... + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[False] = ... +) -> Flask | None: ... + + +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: bool = True +) -> Flask | None: + 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: # type: ignore[union-attr] + 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 None + + 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: click.Context, param: click.Parameter, value: t.Any) -> None: + 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. + + .. versionchanged:: 3.1 + Added the ``load_dotenv_defaults`` parameter and attribute. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + load_dotenv_defaults: 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.load_dotenv_defaults = get_load_dotenv(load_dotenv_defaults) + """Whether default ``.flaskenv`` and ``.env`` files should be loaded. + + ``ScriptInfo`` doesn't load anything, this is for reference when doing + the load elsewhere during processing. + + .. versionadded:: 3.1 + """ + + 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 + app: Flask | None = None + 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 is not None: + break + + if app is None: + 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) + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def with_appcontext(f: F) -> 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: click.Context, /, *args: t.Any, **kwargs: t.Any) -> t.Any: + 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) # type: ignore[return-value] + + +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( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Command]: + """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: t.Callable[..., t.Any]) -> click.Command: + if wrap_for_ctx: + f = with_appcontext(f) + return super(AppGroup, self).command(*args, **kwargs)(f) # type: ignore[no-any-return] + + return decorator + + def group( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Group]: + """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 super().group(*args, **kwargs) # type: ignore[no-any-return] + + +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: + try: + import dotenv # noqa: F401 + except ImportError: + # Only show an error if a value was passed, otherwise we still want to + # call load_dotenv and show a message without exiting. + if value is not None: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Load if a value was passed, or we want to load default files, or both. + if value is not None or ctx.obj.load_dotenv_defaults: + load_dotenv(value, load_defaults=ctx.obj.load_dotenv_defaults) + + 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, taking precedence over" + " those set by '.env' and '.flaskenv'. Variables set directly in the" + " environment take highest precedence. 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:: 3.1 + ``-e path`` takes precedence over default ``.env`` and ``.flaskenv`` files. + + .. 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[click.Parameter] = 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) -> None: + 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 # pyright: ignore + + 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: click.Context, name: str) -> click.Command | None: + 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: # type: ignore[attr-defined] + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx: click.Context) -> list[str]: + 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" + + 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, + load_dotenv_defaults=self.load_dotenv, + ) + + 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: str, other: str) -> bool: + """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[str] | None = None, load_defaults: bool = True +) -> bool: + """Load "dotenv" files to set environment variables. A given path takes + precedence over ``.env``, which takes precedence over ``.flaskenv``. After + loading and combining these files, values are only set if the key is not + already set in ``os.environ``. + + 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. + :param load_defaults: Search for and load the default ``.flaskenv`` and + ``.env`` files. + :return: ``True`` if at least one env var was loaded. + + .. versionchanged:: 3.1 + Added the ``load_defaults`` parameter. A given path takes precedence + over default files. + + .. 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 files present. Install python-dotenv" + " to use them.", + fg="yellow", + err=True, + ) + + return False + + data: dict[str, str | None] = {} + + if load_defaults: + for default_name in (".flaskenv", ".env"): + if not (default_path := dotenv.find_dotenv(default_name, usecwd=True)): + continue + + data |= dotenv.dotenv_values(default_path, encoding="utf-8") + + if path is not None and os.path.isfile(path): + data |= dotenv.dotenv_values(path, encoding="utf-8") + + for key, value in data.items(): + if key in os.environ or value is None: + continue + + os.environ[key] = value + + return bool(data) # True if at least one env var was loaded. + + +def show_server_banner(debug: bool, app_import_path: str | None) -> None: + """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) -> None: + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + 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: click.Context, param: click.Parameter, value: t.Any) -> t.Any: + """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: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + items = self.split_envvar_value(value) + # can't call no-arg super() inside list comprehension until Python 3.12 + 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: ScriptInfo, + host: str, + port: int, + reload: bool, + debugger: bool, + with_threads: bool, + cert: ssl.SSLContext | tuple[str, str | None] | t.Literal["adhoc"] | None, + extra_files: list[str] | None, + exclude_patterns: list[str] | None, +) -> None: + """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: WSGIApplication = info.load_app() # pyright: ignore + 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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + 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[str, t.Any] = {} + + # 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/.python/lib/python3.12/site-packages/flask/config.py b/.python/lib/python3.12/site-packages/flask/config.py new file mode 100644 index 0000000..34ef1a5 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/config.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .sansio.app import App + + +T = t.TypeVar("T") + + +class ConfigAttribute(t.Generic[T]): + """Makes an attribute forward to the config""" + + def __init__( + self, name: str, get_converter: t.Callable[[t.Any], T] | None = None + ) -> None: + self.__name__ = name + self.get_converter = get_converter + + @t.overload + def __get__(self, obj: None, owner: None) -> te.Self: ... + + @t.overload + def __get__(self, obj: App, owner: type[App]) -> T: ... + + def __get__(self, obj: App | None, owner: type[App] | None = None) -> T | te.Self: + 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 # type: ignore[no-any-return] + + def __set__(self, obj: App, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): # type: ignore[type-arg] + """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[str], + defaults: dict[str, t.Any] | 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}_" + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + key = key.removeprefix(prefix) + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + 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[str], silent: bool = False + ) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: 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[str], + load: t.Callable[[t.IO[t.Any]], t.Mapping[str, t.Any]], + 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/.python/lib/python3.12/site-packages/flask/ctx.py b/.python/lib/python3.12/site-packages/flask/ctx.py new file mode 100644 index 0000000..9b164d3 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/ctx.py @@ -0,0 +1,449 @@ +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 _typeshed.wsgi import WSGIEnvironment + + 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[t.Any], +) -> ft.AfterRequestCallable[t.Any]: + """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 + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def copy_current_request_context(f: F) -> F: + """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: t.Any, **kwargs: t.Any) -> t.Any: + with ctx: # type: ignore[union-attr] + return ctx.app.ensure_sync(f)(*args, **kwargs) # type: ignore[union-attr] + + return update_wrapper(wrapper, f) # type: ignore[return-value] + + +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[AppContext]] = [] + + 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: WSGIEnvironment, + 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[t.Any]] = [] + + self._cv_tokens: list[ + tuple[contextvars.Token[RequestContext], 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/.python/lib/python3.12/site-packages/flask/debughelpers.py b/.python/lib/python3.12/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..2c8c4c4 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/debughelpers.py @@ -0,0 +1,178 @@ +from __future__ import annotations + +import typing as t + +from jinja2.loaders import BaseLoader +from werkzeug.routing import RequestRedirect + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + +if t.TYPE_CHECKING: + from .sansio.scaffold import Scaffold + from .wrappers import Request + + +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: Request, key: str) -> None: + 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) -> str: + 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: Request) -> None: + exc = request.routing_exception + assert isinstance(exc, RequestRedirect) + 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: Request) -> None: + """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): # type: ignore[valid-type, misc] + def __getitem__(self, key: str) -> t.Any: + 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: BaseLoader) -> t.Iterator[str]: + 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: str, + attempts: list[ + tuple[ + BaseLoader, + Scaffold, + tuple[str, str | None, t.Callable[[], bool] | None] | None, + ] + ], +) -> 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/.python/lib/python3.12/site-packages/flask/globals.py b/.python/lib/python3.12/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/flask/helpers.py b/.python/lib/python3.12/site-packages/flask/helpers.py new file mode 100644 index 0000000..a6b7e15 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/helpers.py @@ -0,0 +1,634 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import 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 werkzeug.wrappers import Response as BaseResponse + +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 .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") + + +@t.overload +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr], +) -> t.Iterator[t.AnyStr]: ... + + +@t.overload +def stream_with_context( + generator_or_function: t.Callable[..., t.Iterator[t.AnyStr]], +) -> t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]: ... + + +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]], +) -> 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[arg-type] + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore[operator] + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore[arg-type] + + def generator() -> t.Iterator[t.AnyStr | None]: + 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 # type: ignore[return-value] + + +def make_response(*args: t.Any) -> Response: + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for( + endpoint: str, + *, + _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[t.AnyStr] | 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] | str, + path: os.PathLike[str] | 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. This *must not* + be a value provided by the client, otherwise it becomes insecure. + :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) # pyright: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return] + + +@cache +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/.python/lib/python3.12/site-packages/flask/json/__init__.py b/.python/lib/python3.12/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..c0941d0 --- /dev/null +++ b/.python/lib/python3.12/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) # type: ignore[return-value] diff --git a/.python/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc32510f2d09b53039809a84d345d6ea1e28a7f8 GIT binary patch literal 6679 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c8200aa8635950984ba9984fa02647d2d84aafa GIT binary patch literal 9246 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 q>TYjP-oM(kE8(`=-z?ux` 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: 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) # type: ignore[arg-type] + + 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/.python/lib/python3.12/site-packages/flask/json/tag.py b/.python/lib/python3.12/site-packages/flask/json/tag.py new file mode 100644 index 0000000..8dc3629 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/json/tag.py @@ -0,0 +1,327 @@ +""" +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 empty, this tag is + #: only used as an intermediate step during tagging. + key: str = "" + + 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) -> dict[str, 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: + 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) -> 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 _untag_scan(self, value: t.Any) -> t.Any: + if isinstance(value, dict): + # untag each item recursively + value = {k: self._untag_scan(v) for k, v in value.items()} + # untag the dict itself + value = self.untag(value) + elif isinstance(value, list): + # untag each item recursively + value = [self._untag_scan(item) for item in value] + + return value + + 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 self._untag_scan(loads(value)) diff --git a/.python/lib/python3.12/site-packages/flask/logging.py b/.python/lib/python3.12/site-packages/flask/logging.py new file mode 100644 index 0000000..0cb8f43 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/logging.py @@ -0,0 +1,79 @@ +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``. + """ + if request: + return request.environ["wsgi.errors"] # type: ignore[no-any-return] + + return 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/.python/lib/python3.12/site-packages/flask/py.typed b/.python/lib/python3.12/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.python/lib/python3.12/site-packages/flask/sansio/README.md b/.python/lib/python3.12/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df462ff45f57ad84a79981ff5762b0441e5dc7f4 GIT binary patch literal 33699 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9390a7843458e3c193621be248dc88b83908b2f2 GIT binary patch literal 31199 zcmd^o3s4+qo?rJoU|ui-48v2<2oNC90FrE37)jR4*26}!gtTXAy)dE&X%Nido3h4Im-4KWwel~Y{RByD^Pa7R>F9i$_ks7^`q<|ql^|Z zmEF2&*-DgsS}S2ZO=Vj)EgL}D6Gj;=WGcID)3Q}4JD`;?o~E+xo0hFc*)v8NEo3UY z-NHS?i8ZfsVu=nfoh+^vadqL+x3Qn-y3jRk>8Sq;3U=^WcPJW-B|?cvEE*r6cQHH~ zni@}tk&y&mOQ$BqP$E2ZT?$Q3hNZtCNJMl|VtO(Xz5Exv@>)Fr$HH0f;818Z5tfFe@JmzSICaZ@DK-@qv%bNhOX1O&6xNa`Z&;FI($JMq zR2&aWS=ZoDA{>&$*!5_(p28E8<20a=STqrSIWaUT#YV#McudNcnNmk1<7hA^>hgH( zQfQnS(CbK`GuhI?p($y6NS(HLwpw|=7Q#qSJ4T~6FhVn~UFur!51vKLO)kt`;6)CY zjlW=ZavT4E(JZgpF4!nVEGm#*EZSbRU$9SGI~-Ces!aaRL5wseg`{cW3g$a339(CK z;gN)Z=@O*ym|_2NWvs)4U4P~iI@-?AJ_XUjNt83XymFuz{OxT$nuS-RD(@#5$>2@{y`MbdXt;6 z%y2_2fo?NA-Uw{jHDkq_id~Ur!<)J?c;m)wT0Y}B<}|`uNaWvEYn-*u*lz?-Qm<3X z!*OGb<{9r4qWox6@BL5FrbTbFXr^e>Ha)rRu{Mz(ZPF~U>!)bbI>V0x7B-$^L|XH%pQ6v;2edwGZSveS z*Wnn*I^$E9#MneA63w~@GXMvSMqbX^qM?a!)=hUUipzS;sN*)*QIfS{+hv{lmdqB% zCK;S(%SR(pJOM;UTUTP+GHbmYPDu3_g|vlk4RmY7Eo&q6ovonS86t}7_(^J_^dbeV zcNAxB@$mSl)Iuej>DEd&;%~RTJz?%aen26cfNA_E35u~q&YKn zjc@he>QC2o%5|M9&)wa*TDPA%R{e>C+tRe`|6ap)8q!UN<)*`{^+zb7Cgbp=9W}C} zChZVphkz{g->FYG^~z1XcY^P3U2Qu0zT@c!m;r8J#EhP3+W_SG2kSsZKziI5<;lCg zc4CH?`bEo_j^vCCg-eX-sL9AF>Zk|kK;Q6%(ns~2vwYN3xP@7M##Rui0yP&xncBAF zf!J@j6D3-^GgfUQ&H~{VLQ}JL(Kchd#z}RFGQE_2l#c-MkLk!pOW`=trq%de{vYwP zb_>mF0i;t1y%3oht2XM=Lf?XLf|OeA-FUJT%eS~U?FHx5uJvWcI%>r@>=Dcx^$Tc+ z?nAYfJLCX6f6fGAcu#b3iXZN78eNnDHNMh20r7v8JfvDH1_E;KG;#p zuvykN28J?Q1f(ZLCbLE3%F_kjLCvgSD5A#};S z9Ys(rT61qb#bQ=Et-^;8fflG&sua7zk>FqFBmFHzC|fg7+?fb;lX zKQMnF<=*x~Z$+l6_U6lrFJo6Xey1_rv`22*bJx1s)PGm}{j0xw^}XiR{R1iC)N0k~ zMcZ0c-OX1PUs$-F}dogmEw2Yx7~M6thOJ(+uX4=$Cf$U>yCLx+Ob7;Y{__h z8E-|}+bDY*Q>DT(zufY@j_-6V*R32}xw3L0<#{6QIUsuuylY+c9LabpKPoPAx_~VM z4eL${xj1j&fg2%-#McfNBPCgY3WFPzqFLKO zEE?{x3=E)>y~v-nV#OsAEvjr&GL)9B7qg&)E3aC2vY-nXf8EW39?n(z zpo9f4@tn|-+0nc1++ugFp`0C0)KIZyy_iA{&fm$>Fw_2;bvMOP@lQ$+Vx1d7NAyeO zp7;lcz=6J&Cs~LV=uE8Uzp#DOu~C{R6eHHoaict>jFJmQVx4G*G*TRPi1lL8tG2h* z<}Wx|OtC4(1$kvlZhc~d=zy%^M&3rzY0B#n1<{3iOT;G8jb~|C?VGqYw+8J^Y!*GQ z+V$4GlwWL7QpHxW#FXYUr%?`Zn^<}wWG1XM7@+StxfGMTMl+rC$nNn&^DLrDf zDWwke_d;`EtYiHg_cDKB%UP~tr__(d4gDBc_6$VXFv;>j{RUF+!plf(d>o=BR0t#* zO0+MLhiDC`h{UK0xY`|3nB+TAr#EpBnNR{UT~xRf)`=A|pq>!kL*r%&#HwKeV$j9H z2aQfJa)ibe376Fhyb!w{7eFe&SCW`(NV7%`z=wkx1E(AYKqVRB+a0!i}Utwe-DjN;c zoIolMMYXBY{D6s7Q7ey-J|)2j$wS(J_JT<}U4RY{m+@)6=HX$D3Jnhj(Mik& zacps6JO(XGn9bDiuoR0yDHTdw8CC|Yffw~npGSp-Qu{?}l*q^sY1P6~pKuWK#PmIE z*_1>9`YZ;j*luwE`#4lJijs$_jfbUcmAMGO)brKG<6vhhn^{`2q27HL$71{ z0MXT)(liuSAZTz*T9rzNLRd^O5+?$#=zG{GrwJ@c2U%#COrl07lqJ9$tsomgZq=lR zG&s#8N`=^PF=2Q(XU1qTj*~*m)OkUSVY;9f6|RJ?850#kS=K(2=!dbDsT5E}-c(`7 z0L&85bP=G9gvBtlW?lL`5oXM3&M2--%k@~aEkR%!8X?_e1k;l<6}kel@S1DMDt^@$ zTmX-1nrDN_NBdeCOl3$KxuP!HVBr;~-s_{$ffBV8Tyd>x;2YC&1Kji~wBNE?O$HKs$w3IrtBxf{?226*nw zvvFe~k&o1wG#wKJ$Ix<})h7d5Cp5Puf zmZt|sphMCx((PDDr<6kA4gMyV(39rfGu$_!8-jA(3bna?#`%5zZB;3mMzI43|X)G%8&&}PS&g86qVR!ojT|ztJ{d>Xaho+W`qOS z8wQxfbWkF*Y_c;inHH0v87vs6Ok1!`0BlL25iE4D!*{oGjNjg08XsEyTy?ar^5V+$Xi1vvj^# zc2sAon=`d-nfgxp7ie5}bIzJiIA{?*@^L=@2j%stEqhkWpMdsZ&0V_CGXErtI`jRh~}$IH?Sb>VSVj{wq&Y}NgY=pS%k(R9*NV)4;EWPEx;-u8sp&* zksabVAW=*cT%qc?!jlk7Lwp5EH^>esjFTZSni!uBx}GCi7M}uX8 z!DZauw7cb=yXAv&AyeM6e17@ZI>+y*%)lJ*!r}`HC)YWvaFAcO+R6^{53EHMrR!W# zN$I+k^R#XRC;}Ax=O2*vYBPW;sD#%oiA=3)N&eXx)l^H;nl91h3uuJ|EuA8L*H7;IZM)xM%mGrc5IU!+m;jW zJGwTmkZvPBhGMUQw29U^9{Mf*RSz>C=oVrmtCz9;XDsu)W`=lM&58B0bl8&r`%5wD zDnz;nwvsv(N*{-r*iUX03IR7J97F)yQd5)=R@KwkIy25G9Az7mR!>jGQpKWBz3Uib z1ZoLYmeHr%Kp?rYcL+Nc+aG%u+Kd8#!T2}57QIcyHct{Dp%SHKV=YI_(?**BRu%q1 z4+6wJ09$HvX?jXd3pWpIiD@EXNWIO&8HH(yJ1n4v1bNbzQAz;_h2~_7Rj-ufwtR?S zXe8KAlJ$6ee^AZ0P8ATGfEH!E{u{9l5g^p5>q)WKPX|TeuVkOABl_h7LNLCi?+n-Y*qPFPDr#_3b9*SOP$?NWU z_pc2s?^!tlOXd5HoeJEVNsJD+Wa|Y(rcd|`c{YFu&Lo11{sAMHK?AmQe?VXXa0gIN5v!}Ok>Mu-R=2Q^ zh|V;l3iYCOH4Lc?&sal$ib^%ofSJnE&gp|1R(3Y#RbS+wa56l79e7mV+!{KML)akC z8(IUl7Al{@5Rhq=NX^OgGf)tjM7Vs8MU^&a_6tc+JA*yJUcC>LYY+f5JWOmfL>9$N z$p8cl3pA~)TM9G7K&>6p`VKJ95T*>nB~`;ze*}#Bkn_}zq!?2baA0&uOH8>*f1A@C zqd4XReb8VVJ(+-VDl!SH6CqDxt)LW}ibmj_##)c()I+LWMQ?-tW`br#FmsHu{9wjwHx;V*tqLG(bfh4%C&(Qf`Q5D zBDgX2|4=7%9 zY8MG$c;_Fy3rt4#sTs?dzCW}~FulW*R->@9)=lzQ=L_y3y_{{v3RWB@e;C!R1sxf5 z(UbXM@neKt^DYRhd*J3!AZ5l*E=2RR$1S2g%8Ny_MI;Je-Gga|f6$B_tvlYdBE>RW zoX|y2(MdfLT{A_vyJw1V_q=vAy@gvTvF$ZYpil(JaQNC z(!$($-?Si&sCM2Z`o3SLwFZ@gBW{^-O6AB~mzNQ*=$r0i#$(OK>Nn;&!o3I&y;(Qh zJlr!bZQgk98y?$cP)e;4ASXuXzi{YvpFVtf$1o=Uo`5Ypg*0 z*B+noerem1?P?zI@{L*>H(k+D6OnLZq~V%7JxPh(ki%|o1w!Pnu|k9jA1 zi(Zhb(xjVBm%%gwg9TGqOVaJ{4DQOQZ$Q!5>ti9=_d0ZEP`r*namLgs(}wK^>U_O; z;p%hQ-ZLg=e2oz`F?!lkGX_;*ZZ-B(Z-z##u%eh|h*S`$V$$b!BcK1?I8M^v8SAA0 z0J<2FNNY`24C1v7QH;95v`H#kEk;J6o+d?+Y3>S)hw;}rgHeqnP-hx-Ff%z+f}cOX z`2!pL|3t8$`KL>9b`*fd6iq)_AhI?R>5^_39JEzQT7?7Me&C>pCkzyEvrjncynTsN`k_?#aCq#rg>ZCTxKrEs}R3+;&HUbmc;O-xt z&K4=ASm`|F8>M_@Q1Y|$F}h=i;*m&}nye2_SfZYaUS$JA6JhCc*bwNLJt)rfs*3%_ z3WHGAp&1+{VuK`byByAc!An++XCh?QHWHhhHoX6(-IUFtfkH*=V!HmnLC+j*n#B;g^|V{PIvJk*!qDFd$8-PCdp@r9{)@<|HsR9P{mEZkJdfyp&-PR!Xc zhP1os9tPkkOM4n*PXqHlZj&q8QswQb_9s%ly_wpEbZxg>+nuRtS}*2G8b6_KeN@VM zn&g%z;d7k!w8@^f73<32eb3Id>iTqbw_M%*F~>XW=Z^i*1C{JIPpw<=23OdI*0(O+ zy0}tzNBo`W52CAEj;0*7=)~(!%s-KK*Wbfg4sTP++mZ2A+$>%!PWuGeC!~FCvabz` z;<)Wdx9^qP_rCAz%ak>LcUms%$p|eAwwsPc$FG&>g_>n(_>O$<*msV-@7u8^?0iUu z`^eDRk#2oVZhhMeHLlidpF5GM-}ctPt$~&P)%qvqp3Bs= zzP10>{*}(vy2oLc^wy=k&6&pbbmLCBap!_(&Fg>tmHAgv-t8+hsct~P<993M?frMB ze*cxOGfBO z3%dbZ3ni#ub@29f-YH4-9AER-C`V$_{!ZE7xpH{b-*ab|?0@|3mh|4|NI~K7nQ^CQ}wjmo>>{O{uaSna-Yc=aX{hlawa=+Sl5< z=1wfk%AQuZj4MF06kk5^pFQ0l?Zt#`)C4s))hOh8Y)YAztSh&4)11EP2p3a%?*9SW|KJHZH)75YVn2WDwYAfQ^>3Me2<8v?3fw$K(*u3|&j zupvk($j_#<}4*Wi|z&M!ud=?)6&&N@lMN~z@3-wR@}9(ys}`;`0ADp8ziIXeP8!S zb`)VqN*Pv>^bb(&XKmE=i#U36aB}jLq<0VYlrC6&vPu8D%yj@}IvK2YU;nm21cFY|d5<4cZ##fsB z09lk$a}`B1zBA{LdOTaFJ2{b$QqB?ic!%4>{4uVUR!aH?Zdp64jJQV;$6V>I9zD%E z!!M60-b2iU%lPHE8)XDoOw~)_!LA|Fbi689c-_BB>-s#Q#kXJlE4#I<{38yxKdbIovMpT&RjjOew=;d{ ztbFL~>Y;P#+Vi(xS((1uvb1+uymer;_Pp#r|EU!P9@vX2OXrTlE1|Pz?r_?(RrYLM z-gVE@wqAiw;BZ)DbGo5dZs<)n?2#MxtTv!`JbE`UcWgn-baqo2;;@!pzUOHteyHc8 zBF^cZOQgN+vbTMuIlcXmy#3I9$KfA3N-4HY_O`85q&uFHJD$4lIEYxC*~)mlY0oy< zv+WbR6^>T0H?w*=WN*jHu5{-Sx%0?<$5FMOPTAYJayGr=n7rfIeaCS%wp;dg->FFV zo|b!0zwdbdCl8vrx-aoRVMAqx^*^Ytf7((02fIt2w$%T7z6jwzw9q~0d_K8bVfpz7 zzlFeS{A-ritgqQ#v)|?FlTeMIFTDjOk09>L1tN?os^i+DkS z9b_OYYTs~B(MFN9MLUlUA2J7jUF|VC1*a<e5_5!d2OnCOLd`qSlJw{0#Oe}|47mC1^|hj)XiH~dY!k;^YeC`p9QEy0BCf6 z7LF2@fozScycp8mh&6!{{snXx5T^+FxFYH^srTE6W5*Pk4nR35dV?;8$v$)RkB25M ziJ|?;cAZWH&5LgkFD>V91F+(xHUL^%h%SU~Mi-+Hz%st-jIRdAF01H(d*=}z=PnU+ zaTT>6xe>ad98nyA1H@?*&K5&;5K7?WB+V{!Sy4~CD!uKaSf;jMBcQP;ogb!4LBllO zWT0@rzfHZQhW^(L?xP0I<6p8ay?o2d%)tYz<)>1fQ-9|6f4d4s;1l<2_S`-E?%wp_ zb29$*pJSN@SIf_(Jm=ON9`bhiD+|2nKD9d3^P@Rz4I}|YCLrVAYl@ea1^bd4#dlJe zpOyuSXAKqS?nsS((V-W34Z#cY8eG8Xj0ya@p&i9HO4N_QK(|Rw(~9mMdQE*Vn)KK~ z;V6!Ufwqwv6G|>sxvXwyt)?NREwgc7RbkUc>0=HC+QDlD$W@mXt&hwB?0N(WHFG~S z>d2nD4;EF4jSqC8dPW!;*qm)aYz5mEWKMbmGSz%RTl);$ui(6`GL*2Sa%Z{Q7IMEL z3XhNNR1w@_N{kQRD80UI&GMs)a;p#DYE`D=u~d zBVX;Zr+uaDjz8sTzwdcGQ{kUG#<(-U{BI(gL~1;R)nXx17T#7}v>2E2&k@18H>|m6 zRTSt+a*GM%HxBpT66BMl@RJ+dUj{7BN^D18O-gepCTP_z9dc2v$}$LLJF z7I|rlRrAiL=qx??^OAE>s%HE9j!s2&WR`yQ&GtEDqG^-OL|^gxyCD+Pl9@yp)HjYo0g?V0RuQzLas%z4?n>W9Y7SgWgrbv%nL3z*g{X`H!#bV# z?*uMpIziIS@=Gg;lxN$0&+d(M0$v^}onRrN6Vi&-6%AOkWgFT~)|o)pOc|(SAJPue z=tAw^30(+%k)ZqtRDp*5v(W@rLqQAmFZovZMbQiC`+(D|o#suU6B0?!xqFBZZ?ew> zs`=D_N*nuV11^!)Fsn7oPy|pK3NqfZ6l%mdfvJJ=ZN*&HrXo5=N$iT@V?U4&mZ$^WB4V-{Tt;5 zrNf(Hf0M#D2Lmgm47kNJc4M)VyWW)aF!SQ-APFg}vuMDVroHSY5Fih5@D9*jh8M%>K#v^gNe7;k z15e&Pf=^clj-~_8%7JI!dww-=>W2DdHDVml5mF$TI-)2dv*jCGHXl{lnA$Csqr-R#(LN%H|v!Wyqfu7XOJE7IUm~Dk!oz;fsXC+*W_d0dbL*TL(nx zKj3vE1nw|#vh4fc4+X%z1pu&H4s@pjeR81h?(TQtuyrIII4K8CzISjnFkl8i=|Acn zP$92OnNCxSIWk~=cXn+CcLQH6+%22oF5dwB=%A--@l<4}9p=8IJ5qj*7F_wjx`rLV z>1vwm!V2kMFdF>Fj{LxC`lqAE8yo*6hs8G@1r~daWhW5aFvyL-c#0rlJL)!(<2`a=!E>1mMrJMY9Gu$!n z8U=xo37fvMNFet}G}rtsEi#2XBI3(wauYzKu`nwfSzh0;(3w}!0v`j-ib-AzDz}CV z`Zc5TaCBag?3@FIap^G>Ap^!{Ht#|nTn2+UuYaK%?hPulXi*Fl9`opMrZ|L#q?>eO z3?q$8(5!u>>}NmpSxX+x1z2-U2CV9Gyb+aK4Y{br>(LJBqkLTp_M6T{XWF+-_TjT0 ztG=$4=i#fxm^o&UU`i-W3vgfWEwfD$gEy>oS5Y>b*$V*g=k)QS2Fj$PvhXG3WK;tG z=X%*wzx0*+p017B=5p!+a{yzZt$4*WGESFG<3_8bkG7e)Bj)cD4=3-lK7|z4r@dIDQTN_*{1P@!UOA zc%;Tw(FCt?0)sqEze^76N(c7Kf&F(A@19u=97_jI$$?X;(~!K*+%QRA8yVkP0<*$x zCtDt+ha&Yy6T!?l|IEX2{?7`dIkbQVpnas`Q6W>)1pF;&K~9suwih6l|PnvVy~X_IDv zGt2y^Hvn9RUvXDCNaH_2Hx@dH&}UneZ_LNy!P7YHMF{UAVqVlfEdMO!K18?Y==K5K z2+EZ>B2r4I387>aa}-8#d_{>qcdyqnpyxZIg+Q==g~F^ShP$wh`O0Q1kEmbxJ4;`V zds_X~Ba>S(|1^H_shKJ$p<63%pZW5eXCG3M_EQGdLMcM<3TvT=e!5XHX&>E;9u(zO zEB%+v)0y2rZv@r>e9GUWc%88%=6c4akolh-rs}?pThdLx1E5WGfv#wN6RZ_h0rfJu zGZCbt*W}rC@uKNxxfE}T7rTUwaTqi)FUcA>aSy6qU{5nQF|8&AK=ekWr;r^>l-G1{ zlcveQmfJ9k(VC^7Ezp`BMAo0K(apxI=wNf3RpYdV&EtKB{gBz`G)=Q4mC=m>1cfxt z%B#mxNQ(uTRr69vi}mZV6hbU9KFLb_dR+M8(U(WU?6-|*ciZ)tMAk#4s}#~=NqkUZDb&%R_(UG1*r)0C4BgJt%|*8zbbEnrbO=TH+?Pn9QM!>~ zK>8}(uF>rYy4|MRZ_w@E(2cB}(!ZnI@6qiK>Gnr-`(wKO3EkeOTZV2w!Yx~(ephoO zJU%`&1fRP>#Kw8to>Dw#*!HB`bxL>)T=!qouTJd5uTEUyx%#G*ts1`v@kD=S+xE=f zeVL|K9B#|>?54ZWv0l|`KgP3Pm7oAv)x|ap($@Yz!MWdzpFtZ<##nGg>$)`L8(o~A^OtjK60>xiqrW+^!lrQi@Zg$R9Q zO9o#!eRSyXv7?7i9v^r{YNiCD(OHL%dq1St;z3};^C2ngKS*ljGm4!`%Y)y=#Lwjr zrp;C!Vqa0s%fPU7)_;^f`EZQcvLvmnL~|OmwV-xefCSA;+0Tnd;)izn&J5mxvf9uoIm2qKjfM}kZbsmYg)6~UOVvh10UL|*Q#sYa@}&JTK1-z`|ch|H9sX+A53wTnew`Yrkfp$ z9jW>qch00Adsco7W~@Is_ebaC$Ijj_AH3nsRMao@-rT#mH?^hvj+EYWO5Stoe#Pk& z=POk9e))4KQWBVZ{`D8;Us#w~*_rO#FL&<0Uvl7v3nzn@UV3Z#)^x_Ub!BUM`*ZU4 z=fKJemJ~rU zR9)wto#|c2V0ePt-Tpr!}6u{wxja4qv%6D`cVB>t}{IE`iP_Z TCu5d_4!&%`@hL}7wjBQ#ieOBd literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/scaffold.cpython-312.pyc b/.python/lib/python3.12/site-packages/flask/sansio/__pycache__/scaffold.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9656cf3810e13940a0ec8b5fb6d7ca54634c3796 GIT binary patch literal 30212 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 InHBB-0#}Ec{Qv*} literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/flask/sansio/app.py b/.python/lib/python3.12/site-packages/flask/sansio/app.py new file mode 100644 index 0000000..3620171 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/sansio/app.py @@ -0,0 +1,964 @@ +from __future__ import annotations + +import logging +import os +import sys +import typing as t +from datetime import timedelta +from itertools import chain + +from werkzeug.exceptions import Aborter +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.routing import BuildError +from werkzeug.routing import Map +from werkzeug.routing import Rule +from werkzeug.sansio.response import Response +from werkzeug.utils import cached_property +from werkzeug.utils import redirect as _wz_redirect + +from .. import typing as ft +from ..config import Config +from ..config import ConfigAttribute +from ..ctx import _AppCtxGlobals +from ..helpers import _split_blueprint_path +from ..helpers import get_debug_flag +from ..json.provider import DefaultJSONProvider +from ..json.provider import JSONProvider +from ..logging import create_logger +from ..templating import DispatchingJinjaLoader +from ..templating import Environment +from .scaffold import _endpoint_from_view_func +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + + from ..testing import FlaskClient + from ..testing import FlaskCliRunner + from .blueprints import Blueprint + +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 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[bool]("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[t.Union[str, bytes, None]]("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[timedelta]( + "PERMANENT_SESSION_LIFETIME", + get_converter=_make_timedelta, # type: ignore[arg-type] + ) + + 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[str, t.Any] = {} + + #: 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[str, t.Any] + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = 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[str, t.Any] = {} + + #: 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 + + 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: str | None = 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"] # type: ignore[no-any-return] + + @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[str] = 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 and self.config["PROVIDE_AUTOMATIC_OPTIONS"]: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule_obj = self.url_rule_class(rule, methods=methods, **options) + rule_obj.provide_automatic_options = provide_automatic_options # type: ignore[attr-defined] + + self.url_map.add(rule_obj) + 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[str, t.Any]) -> 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/.python/lib/python3.12/site-packages/flask/sansio/blueprints.py b/.python/lib/python3.12/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..4f912cc --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,632 @@ +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"], None] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +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: ft.RouteCallable | 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[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore[assignment] + ): + 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[str, t.Any]]] = [] + + 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: DeferredSetupFunction) -> 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: DeferredSetupFunction) -> 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[str, t.Any], 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[str, t.Any]) -> 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: dict[ft.AppOrBlueprintKey, list[t.Any]], + parent_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + ) -> None: + 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: + def from_blueprint(state: BlueprintSetupState) -> None: + state.app.errorhandler(code)(f) + + self.record_once(from_blueprint) + 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/.python/lib/python3.12/site-packages/flask/sansio/scaffold.py b/.python/lib/python3.12/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..3a839f5 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,792 @@ +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 BaseLoader +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 ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +if t.TYPE_CHECKING: # pragma: no cover + from click import Group + +# 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.Any]) +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: Scaffold, *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 + """ + + cli: Group + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | 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 + + #: 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, ft.RouteCallable] = {} + + #: 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[t.Any]] + ] = 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[str] | 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) -> BaseLoader | 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[str, t.Any], + ) -> 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: ft.RouteCallable) -> 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 _find_package_path(import_name: str) -> str: + """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.submodule_search_locations: + if root_spec.origin is None or root_spec.origin == "namespace": + # 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 package_path.is_relative_to(location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + else: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) # type: ignore[type-var, return-value] + + +def find_package(import_name: str) -> tuple[str | None, 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 pathlib.PurePath(package_path).is_relative_to(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/.python/lib/python3.12/site-packages/flask/sessions.py b/.python/lib/python3.12/site-packages/flask/sessions.py new file mode 100644 index 0000000..375de06 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/sessions.py @@ -0,0 +1,398 @@ +from __future__ import annotations + +import collections.abc as c +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 + import typing_extensions as te + + from .app import Flask + from .wrappers import Request + from .wrappers import Response + + +class SessionMixin(MutableMapping[str, t.Any]): + """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[str, t.Any], 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: c.Mapping[str, t.Any] | c.Iterable[tuple[str, t.Any]] | None = None, + ) -> None: + def on_update(self: te.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"] # type: ignore[no-any-return] + + 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``. + """ + return app.config["SESSION_COOKIE_DOMAIN"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + def get_cookie_samesite(self, app: Flask) -> str | None: + """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"] # type: ignore[no-any-return] + + def get_cookie_partitioned(self, app: Flask) -> bool: + """Returns True if the cookie should be partitioned. By default, uses + the value of :data:`SESSION_COOKIE_PARTITIONED`. + + .. versionadded:: 3.1 + """ + return app.config["SESSION_COOKIE_PARTITIONED"] # type: ignore[no-any-return] + + 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() + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +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(_lazy_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 + + keys: list[str | bytes] = [app.secret_key] + + if fallbacks := app.config["SECRET_KEY_FALLBACKS"]: + keys.extend(fallbacks) + + return URLSafeTimedSerializer( + keys, # type: ignore[arg-type] + salt=self.salt, + serializer=self.serializer, + signer_kwargs={ + "key_derivation": self.key_derivation, + "digest_method": self.digest_method, + }, + ) + + 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) + partitioned = self.get_cookie_partitioned(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, + partitioned=partitioned, + 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[union-attr] + response.set_cookie( + name, + val, + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + partitioned=partitioned, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/.python/lib/python3.12/site-packages/flask/signals.py b/.python/lib/python3.12/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/flask/templating.py b/.python/lib/python3.12/site-packages/flask/templating.py new file mode 100644 index 0000000..618a3b3 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/templating.py @@ -0,0 +1,219 @@ +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( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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.Iterator[tuple[Scaffold, BaseLoader]]: + 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/.python/lib/python3.12/site-packages/flask/testing.py b/.python/lib/python3.12/site-packages/flask/testing.py new file mode 100644 index 0000000..602b773 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/testing.py @@ -0,0 +1,297 @@ +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 _typeshed.wsgi import WSGIEnvironment + 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: + path = f"{path}?{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.Iterator[SessionMixin]: + """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: WSGIEnvironment) -> WSGIEnvironment: + 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: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> BaseRequest: + 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 {}) # type: ignore[arg-type] + 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 + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/.python/lib/python3.12/site-packages/flask/typing.py b/.python/lib/python3.12/site-packages/flask/typing.py new file mode 100644 index 0000000..e7234e9 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/typing.py @@ -0,0 +1,90 @@ +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, + 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, list[str], tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + tuple[ResponseValue, HeadersValue], + tuple[ResponseValue, int], + 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[[], 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[[], dict[str, t.Any]], + t.Callable[[], t.Awaitable[dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict[str, t.Any]], None] +URLValuePreprocessorCallable = t.Callable[ + [t.Optional[str], t.Optional[dict[str, t.Any]]], 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/.python/lib/python3.12/site-packages/flask/views.py b/.python/lib/python3.12/site-packages/flask/views.py new file mode 100644 index 0000000..53fe976 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/views.py @@ -0,0 +1,191 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +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[..., t.Any]]] = [] + + #: 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) # type: ignore[no-any-return] + + else: + self = cls(*class_args, **class_kwargs) # pyright: ignore + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] diff --git a/.python/lib/python3.12/site-packages/flask/wrappers.py b/.python/lib/python3.12/site-packages/flask/wrappers.py new file mode 100644 index 0000000..bab6102 --- /dev/null +++ b/.python/lib/python3.12/site-packages/flask/wrappers.py @@ -0,0 +1,257 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import HTTPException +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: HTTPException | None = None + + _max_content_length: int | None = None + _max_form_memory_size: int | None = None + _max_form_parts: int | None = None + + @property + def max_content_length(self) -> int | None: + """The maximum number of bytes that will be read during this request. If + this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge` + error is raised. If it is set to ``None``, no limit is enforced at the + Flask application level. However, if it is ``None`` and the request has + no ``Content-Length`` header and the WSGI server does not indicate that + it terminates the stream, then no data is read to avoid an infinite + stream. + + Each request defaults to the :data:`MAX_CONTENT_LENGTH` config, which + defaults to ``None``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This can be set per-request. + + .. versionchanged:: 0.6 + This is configurable through Flask config. + """ + if self._max_content_length is not None: + return self._max_content_length + + if not current_app: + return super().max_content_length + + return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] + + @max_content_length.setter + def max_content_length(self, value: int | None) -> None: + self._max_content_length = value + + @property + def max_form_memory_size(self) -> int | None: + """The maximum size in bytes any non-file form field may be in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_MEMORY_SIZE` config, which + defaults to ``500_000``. It can be set on a specific ``request`` to + apply the limit to that specific view. This should be set appropriately + based on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_memory_size is not None: + return self._max_form_memory_size + + if not current_app: + return super().max_form_memory_size + + return current_app.config["MAX_FORM_MEMORY_SIZE"] # type: ignore[no-any-return] + + @max_form_memory_size.setter + def max_form_memory_size(self, value: int | None) -> None: + self._max_form_memory_size = value + + @property # type: ignore[override] + def max_form_parts(self) -> int | None: + """The maximum number of fields that may be present in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_PARTS` config, which + defaults to ``1_000``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_parts is not None: + return self._max_form_parts + + if not current_app: + return super().max_form_parts + + return current_app.config["MAX_FORM_PARTS"] # type: ignore[no-any-return] + + @max_form_parts.setter + def max_form_parts(self, value: int | None) -> None: + self._max_form_parts = value + + @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 # type: ignore[no-any-return] + + 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 ebr: + if current_app and current_app.debug: + raise + + raise BadRequest() from ebr + + +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"] # type: ignore[no-any-return] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt @@ -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/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA new file mode 100644 index 0000000..ddf5464 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.2.0 +Summary: Safely pass data to untrusted environments and back. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +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 +Classifier: Typing :: Typed +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://itsdangerous.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/itsdangerous/ + +# 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. + + +## A Simple Example + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +```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 + diff --git a/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD new file mode 100644 index 0000000..245f43e --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD @@ -0,0 +1,22 @@ +itsdangerous-2.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.2.0.dist-info/LICENSE.txt,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.2.0.dist-info/METADATA,sha256=0rk0-1ZwihuU5DnwJVwPWoEI4yWOyCexih3JyZHblhE,1924 +itsdangerous-2.2.0.dist-info/RECORD,, +itsdangerous-2.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +itsdangerous/__init__.py,sha256=4SK75sCe29xbRgQE1ZQtMHnKUuZYAf3bSpZOrff1IAY,1427 +itsdangerous/__pycache__/__init__.cpython-312.pyc,, +itsdangerous/__pycache__/_json.cpython-312.pyc,, +itsdangerous/__pycache__/encoding.cpython-312.pyc,, +itsdangerous/__pycache__/exc.cpython-312.pyc,, +itsdangerous/__pycache__/serializer.cpython-312.pyc,, +itsdangerous/__pycache__/signer.cpython-312.pyc,, +itsdangerous/__pycache__/timed.cpython-312.pyc,, +itsdangerous/__pycache__/url_safe.cpython-312.pyc,, +itsdangerous/_json.py,sha256=wPQGmge2yZ9328EHKF6gadGeyGYCJQKxtU-iLKE6UnA,473 +itsdangerous/encoding.py,sha256=wwTz5q_3zLcaAdunk6_vSoStwGqYWe307Zl_U87aRFM,1409 +itsdangerous/exc.py,sha256=Rr3exo0MRFEcPZltwecyK16VV1bE2K9_F1-d-ljcUn4,3201 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=PmdwADLqkSyQLZ0jOKAgDsAW4k_H0TlA71Ei3z0C5aI,15601 +itsdangerous/signer.py,sha256=YO0CV7NBvHA6j549REHJFUjUojw2pHqwcUpQnU7yNYQ,9647 +itsdangerous/timed.py,sha256=6RvDMqNumGMxf0-HlpaZdN9PUQQmRvrQGplKhxuivUs,8083 +itsdangerous/url_safe.py,sha256=az4e5fXi_vs-YbWj8YZwn4wiVKfeD--GEKRT5Ueu4P4,2505 diff --git a/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL b/.python/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous-2.2.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/.python/lib/python3.12/site-packages/itsdangerous/__init__.py b/.python/lib/python3.12/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..ea55256 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/__init__.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import typing as t + +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 + + +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" + " ItsDangerous 2.3. Use feature detection or" + " 'importlib.metadata.version(\"itsdangerous\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("itsdangerous") + + raise AttributeError(name) diff --git a/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7729e5056b211d82b50d132679ce493773b2fb38 GIT binary patch literal 1618 zcmZXU&u<$=6vt=%V|Tsw+K%HmNr~D`D7bs54M{<&sE|TaC=x^nw?bMWt;U{-v+4e@ zX2(e#B@#j$;KYGLd*ucy{|T3t9$IZ>sZ!w(i9@91)Dv&UcI1@NYWDNKGxO%nzBl`) zX&MOHzVU7Mmn=fBgfVHU5hy4B0z5zj5yeM=;wXyXl%I0aBuz4YCdfKj(9$FetU9V> z6h-2yj6}1IWBTDWm(Wf`D9oA&G#m@Y9uB$N9&j4Nu=WWi8<=Cj9N=w= z31wgyV0?uKeuN2F1+ZFPH^jWpgwrzEcf5d})6R@r_j?|rVx7^V%)`F7FMXP~zg)k$ z?sp^R@$CSH&CMvJ(}F5|$hjrqo}61QrI_QOcQ$M0?$=+m@D@EcuQnFn@X!%oXwsmZ zP#PiSM~8}hD~G9r)Q*_@Mk8siP9&1~Bl`$^iKd_fWk(;S8Q!F$-C|@WijN~b(tvo{a^2FQ>#8D*DcIB^V)q* zEibkR?J?THoDvI%#M<+G-)d8f(IDCd%?qv1dAxzcE@e?awpJT!4eM@9tt~3E3+p-U zh@!G0X4So*7cuU8?M6U3CQvDjaXeR6JRXyYpB1|fu44}M(>M}witIzOI`@3KOZ}uU zJ=xZh%KsfF`W|MX7k1+$BPgkCjE@4rd@~wK^hp?rHjX1Hu1}7Ci?N8==_C{4fF`-K zE!YwS6pI{Lmi4;T+>Qd;B&64jS*N+>g*_jK%|>s)x1+ELXKjvft?~Y9Gxj*W+Jkf8 zE{&Vhr)ava7kb=vVWr4Z7d{X~0(p7|c3KcywxIhCJ=gL-9{!~*z0j9m=<_f2^3Uc^ z=5Z=zex{tN$h`D?e&INeaW<9(>zG;fXH) z1z<2y+Due3)1)hUzr#fNvYhC|-QRFd;u&@d4)1iA0Al|{BU;` zz$OyIw|bx2&=Nog?eyOlfoIWHV%?PqW4#d)%7J<&BJBiAJFEB9sfA6?p)_(hD?1fG zh#Dkt3Q=3s!oX?xOHK;s3peK+4kccP5|>HU&98vO}7>Bi0i&+kw*U| zg+qP(M8W#yu8NHOu|&rP zpc6&aXA<2{iPAXI8%l$MDlK3G#W6Y1Sd$x`_TCWf$PcP97D+C43EoeO=$Q*Cm3wRo f9^_8(iy)3wjPW-#b%Z9qp!_c*hi6U@h{W?Z`Bo5* literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc b/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b9e057a2485a2727e59c6a0ab4f9e566b61bffc GIT binary patch literal 2672 zcma(SOKcNIbjG{hINmsM67r*@ED0qwkhp}9rj$~k5Yegx(a@hMbvK?(Vt2E4XU2rM zNtIR{=&3rF89(6M*kn|W{M z{oni+iG&f1LinSJFM|j@6bpZ-9)i~nVT7(Af(W+J6i#3)@PHji1SC`viiB!Hl`xpl zh(c7mW-62jVN{DqeJ#uzKhi*g7lMge5+&LNH4z3_15me=OuH|9171b2zj0GJe_se$cj)DHfxTUXAuBc zGauZTj(7fPFEQ3gWz^q9r70iS0MPL6`Ok(lC!(=6>UZaOK;RT!tP zW;v-Wv4Dh`8PQ}g7$hZF2m!JC1?$45+N4GtKd0}ayvcY^DT?6@IKGP2a* z)_LA%oSw7{YO%b{1>GZ>)Cz-R4Q7s82G1IKW*KS6c=w&RS)U}V3EN(asnRp9HYSC+ zjd^N|BgwJB0Z*{2Q6V@7>7;oYFmckL5t!YGcP{Di(pK2p1RoQ53|?TQ5~WUz+UBSk#f@6w*jekHo+wDlX9ctXpwwG z-EjMci*-bT1r53o+*JT&=b%^c^;FIP<>|3;b`*6Z9`fm2b~CXW4{S%YaSn4~yc|UH zgEou53XqyP`~{xI)9AeNA)3aqP~l`HjKmUk0AYj>^vbCGk9ZnsCW9qo>c!0snk{Vg+ z6m@G)&*ZFQqDtNHd#0WDa4H-KGF!wcY%$R=jHhzJyMP)%+5#W5U|P?GrM6q`cOysU zhwrK3i{vs}9Q^k41^e2mQtOUVeNRd4nIB$NmEeK<4K2$JJ*9@8C9T{LFNWfO->+-A zTqx>Ye<2Ly`j%qr-g5oGt!>57tN*Mju=kh=t$y6JAKh*^yji(ZTX(ocxziE^yrA?Z zU!&p~Cz&K` z_L9E++WTd_x2X0$TSp?xrSb;>saF2Kl_u+L-8YUX9dH&}k~*>?N`iKYNd#V6Bi$$L z0d?IV&Ey#uFOS^jw923-S?O-LU>|%;Jhh%dZ9jB=*Lm%;rJiy}e_7vq^KeNYEUJUj zDrktoJRk2J^14up$3j$;x_T$ijsVvFc)Og4#NlTX&XP zcNSZAEe-#C;`)iD*Kc(fn-4BGA1gH<`*ot+JW@o_2hq+2?MmcQWRaAk-Sd%q(az;) qS1H;h(AEWfMZ2UG+lFrSF7F>H?H?&ePtHfyG>rQmg)n|u8uc&w4p^xG literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc b/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c366199213c3fb83dac727e42881207da0b20cab GIT binary patch literal 3932 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc b/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ef5fbbb536d4e455387b648a4016acfa8dd5c13 GIT binary patch literal 11278 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc b/.python/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7e131107aaf56f25635de03d813629e7cb64450 GIT binary patch literal 8726 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 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/.python/lib/python3.12/site-packages/itsdangerous/encoding.py b/.python/lib/python3.12/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..f5ca80f --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import base64 +import string +import struct +import typing as t + +from .exc import BadData + + +def want_bytes( + s: 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: 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: 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], 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/.python/lib/python3.12/site-packages/itsdangerous/exc.py b/.python/lib/python3.12/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..a75adcd --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/exc.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import typing as t +from datetime import datetime + + +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.Any | None = 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.Any | None = 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.Any | None = None, + date_signed: datetime | None = 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.Any | None = None, + header: t.Any | None = None, + original_error: Exception | None = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: t.Any | None = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = 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: Exception | None = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = original_error diff --git a/.python/lib/python3.12/site-packages/itsdangerous/py.typed b/.python/lib/python3.12/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.python/lib/python3.12/site-packages/itsdangerous/serializer.py b/.python/lib/python3.12/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..5ddf387 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/serializer.py @@ -0,0 +1,406 @@ +from __future__ import annotations + +import collections.abc as cabc +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 + +if t.TYPE_CHECKING: + import typing_extensions as te + + # This should be either be str or bytes. To avoid having to specify the + # bound type, it falls back to a union if structural matching fails. + _TSerialized = te.TypeVar( + "_TSerialized", bound=t.Union[str, bytes], default=t.Union[str, bytes] + ) +else: + # Still available at runtime on Python < 3.13, but without the default. + _TSerialized = t.TypeVar("_TSerialized", bound=t.Union[str, bytes]) + + +class _PDataSerializer(t.Protocol[_TSerialized]): + def loads(self, payload: _TSerialized, /) -> t.Any: ... + # A signature with additional arguments is not handled correctly by type + # checkers right now, so an overload is used below for serializers that + # don't match this strict protocol. + def dumps(self, obj: t.Any, /) -> _TSerialized: ... + + +# Use TypeIs once it's available in typing_extensions or 3.13. +def is_text_serializer( + serializer: _PDataSerializer[t.Any], +) -> te.TypeGuard[_PDataSerializer[str]]: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer(t.Generic[_TSerialized]): + """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: _PDataSerializer[t.Any] = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: type[Signer] = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = [] + + # Serializer[str] if no data serializer is provided, or if it returns str. + @t.overload + def __init__( + self: Serializer[str], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: None | _PDataSerializer[str] = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer positional argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer keyword argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a positional argument. If the strict signature of + # _PDataSerializer doesn't match, fall back to a union, requiring the user + # to specify the type. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a keyword argument. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: t.Any | None = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = 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: 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: _PDataSerializer[_TSerialized] = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: type[Signer] = signer + self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers) + + self.fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = fallback_signers + self.serializer_kwargs: dict[str, t.Any] = 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: _PDataSerializer[t.Any] | None = 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: + use_serializer = self.serializer + is_text = self.is_text_serializer + else: + use_serializer = serializer + is_text = is_text_serializer(serializer) + + try: + if is_text: + return use_serializer.loads(payload.decode("utf-8")) # type: ignore[arg-type] + + return use_serializer.loads(payload) # type: ignore[arg-type] + 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: str | bytes | None = 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: str | bytes | None = None) -> cabc.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: str | bytes | None = None) -> _TSerialized: + """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") # type: ignore[return-value] + + return rv # type: ignore[return-value] + + def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = 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: str | bytes, salt: str | bytes | None = 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[t.Any], salt: str | bytes | None = None) -> t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: str | bytes, salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """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: str | bytes, + salt: str | bytes | None, + load_kwargs: dict[str, t.Any] | None = None, + load_payload_kwargs: dict[str, t.Any] | None = None, + ) -> tuple[bool, t.Any]: + """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[t.Any], salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/.python/lib/python3.12/site-packages/itsdangerous/signer.py b/.python/lib/python3.12/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..e324dc0 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/signer.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +import collections.abc as cabc +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 + + +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"" + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +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(_lazy_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: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], +) -> list[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] # pyright: ignore + + +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(_lazy_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: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous.Signer", + sep: str | bytes = b".", + key_derivation: str | None = None, + digest_method: t.Any | None = None, + algorithm: SigningAlgorithm | None = 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: 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: str | bytes | None = 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: 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: str | bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: str | bytes, sig: 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: 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: 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/.python/lib/python3.12/site-packages/itsdangerous/timed.py b/.python/lib/python3.12/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..7384375 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/timed.py @@ -0,0 +1,228 @@ +from __future__ import annotations + +import collections.abc as cabc +import time +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 _TSerialized +from .serializer import Serializer +from .signer import Signer + + +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: 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. + + @t.overload + def unsign( # type: ignore[overload-overlap] + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[False] = False, + ) -> bytes: ... + + @t.overload + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[True] = True, + ) -> tuple[bytes, datetime]: ... + + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + ) -> 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: int | None = None + ts_dt: datetime | None = 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: str | bytes, max_age: int | None = 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[_TSerialized]): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: str | bytes | None = None + ) -> cabc.Iterator[TimestampSigner]: + return t.cast("cabc.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore[override] + self, + s: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + salt: str | bytes | None = 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[override] + self, + s: str | bytes, + max_age: int | None = None, + salt: str | bytes | None = None, + ) -> tuple[bool, t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/.python/lib/python3.12/site-packages/itsdangerous/url_safe.py b/.python/lib/python3.12/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..56a0793 --- /dev/null +++ b/.python/lib/python3.12/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +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 _PDataSerializer +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer[str]): + """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: _PDataSerializer[str] = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: t.Any, + serializer: t.Any | None = 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[str]): + """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[str]): + """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/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA new file mode 100644 index 0000000..265cc32 --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA @@ -0,0 +1,76 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.4 +Summary: A very fast and expressive template engine. +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ +Provides-Extra: i18n + +# Jinja + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +## In A Nutshell + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} +

+ {% endblock %} + + +## Donate + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD new file mode 100644 index 0000000..df3acaf --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.4.dist-info/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2-3.1.4.dist-info/METADATA,sha256=R_brzpPQVBvpGcsm-WbrtgotO7suQ1D0F-qkhTzeEfY,2640 +jinja2-3.1.4.dist-info/RECORD,, +jinja2-3.1.4.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +jinja2-3.1.4.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2/__init__.py,sha256=wIl45IM20KGw-kfr7jJhaBxxX5g4-kihlBYjxopX7Pw,1928 +jinja2/__pycache__/__init__.cpython-312.pyc,, +jinja2/__pycache__/_identifier.cpython-312.pyc,, +jinja2/__pycache__/async_utils.cpython-312.pyc,, +jinja2/__pycache__/bccache.cpython-312.pyc,, +jinja2/__pycache__/compiler.cpython-312.pyc,, +jinja2/__pycache__/constants.cpython-312.pyc,, +jinja2/__pycache__/debug.cpython-312.pyc,, +jinja2/__pycache__/defaults.cpython-312.pyc,, +jinja2/__pycache__/environment.cpython-312.pyc,, +jinja2/__pycache__/exceptions.cpython-312.pyc,, +jinja2/__pycache__/ext.cpython-312.pyc,, +jinja2/__pycache__/filters.cpython-312.pyc,, +jinja2/__pycache__/idtracking.cpython-312.pyc,, +jinja2/__pycache__/lexer.cpython-312.pyc,, +jinja2/__pycache__/loaders.cpython-312.pyc,, +jinja2/__pycache__/meta.cpython-312.pyc,, +jinja2/__pycache__/nativetypes.cpython-312.pyc,, +jinja2/__pycache__/nodes.cpython-312.pyc,, +jinja2/__pycache__/optimizer.cpython-312.pyc,, +jinja2/__pycache__/parser.cpython-312.pyc,, +jinja2/__pycache__/runtime.cpython-312.pyc,, +jinja2/__pycache__/sandbox.cpython-312.pyc,, +jinja2/__pycache__/tests.cpython-312.pyc,, +jinja2/__pycache__/utils.cpython-312.pyc,, +jinja2/__pycache__/visitor.cpython-312.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=JXKWCAXmTx0iZB4-hAsF50vgjxw_RJTjiLOlGGTBso0,2477 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=dpV-n6_iQUP4uSwlXwGUavJmwjvXdyxKzJ-AonFjPBk,72271 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=xhFkmxO0CESA76Ki5tz4XWq9yzGu-t0p93JCCVBVNps,61538 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=igsBH7c6C0byHaOtMbE-ugpt4GjLGgR-ywskyXtKgq8,31877 +jinja2/filters.py,sha256=bKeqjFjjz88TkHVLSyyMIEB75CzAN6b3Airgx0phJDg,54611 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=xnWWXhPndHFsoqzpc5VTjheDE9JuKk9MUo9DZkrM8Os,29754 +jinja2/loaders.py,sha256=ru0GIWHo5KiHJi7_MoI_LvGDoBBvP6rd0hiC1ReaTwk,23167 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=DV1iF1FR2Rsaj_5zl8rmx7j6Bj4S8iLHoYsvJ0bfEis,39890 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=POXT3tKNKJRENx2CymwUsOOXH2JwGPjW702njB5__cQ,33435 +jinja2/sandbox.py,sha256=TJjBNS9qRJ2ZgBMWdAgRBpyDLOHea2kT-2mk4PrjYx0,14616 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=nV7IpWLvRCMyHW1irBAK8CIPAnOFfkb2ukggDBjbBEY,23952 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.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/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt new file mode 100644 index 0000000..abc3eae --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/.python/lib/python3.12/site-packages/jinja2/__init__.py b/.python/lib/python3.12/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..2f0b5b2 --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2/__init__.py @@ -0,0 +1,38 @@ +"""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.4" diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c9a8be3322cf16e80401b09f181105b5400808b GIT binary patch literal 1643 zcmZ9M*>2lL6oyBeB~knC-L##wFanFn(j`C|px(M54vabhia`N_BBv4)a)y{0xstEi zyS_pD3VoKofdB#pdeyrYL2q)^Gow&aLr6cq`RAP3c!s}MDh7h**7$Dta~`2TRU>)Q z@8HdkDTIDO9>T~=dFdb(rg1u@I0Kx)8O>SXEY51q1-WnyuW4Qb&f~o1d{79BxTv`R zY+yrk5x9g)nhoGGE^96US8zph8Mun8nk&FHT+>_)>R|&nG}nNexT(1g+`=u*4d6Cz zYiMBht$71@2k&U!1m4BF znzw?z(8Q+ZZQy;puXzXf03T@H1wO=wn)iV3;5(X4;Jf%P@IL-vdT?}j`|H;}edUYQ`N)znE(V$>7kIg=M`Og#u{C*C(>D*ccov5mwRE5WVAyw-=6#8zKYk9-dYEI)Ad)I0-~#K)*e~Ys#uCX((wbX(?$d=_u)f%<_C*K)k1{btM~0HkE9F%yMJt2ZC=a zV@JuZl07A+l6{a_$+m9@S69upe?xD;LT@jv5etdsd66Z!YeA*KJ*QSb(ihqa{DCz` zIHU)b@Fh8p=G7srSL*xlz_M+h`qH)`=WXFhsB7sdKZeoOJrxw>?@TI{`X`-9W&br$ z>QRioh|zhB9>(Z6MqkG0;}|`O(OHb1#^@wQpKAZU*2gjWC`P~#4EmXFLhdIqx)&oW T`9TvRAOBJ9{8ZxiV9NghmNwy% literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fed6dd5df4ba6cd1eee049c8130fcfdb7c098f5 GIT binary patch literal 2124 zcmYL~%Wvb>8O3EA?c{+hyX&IpE-7x*ri*Th{s~3bX^O%fJBg#a8;`26*a4?b!?!PmiC)nqi7aDspc`>_=UB|DJ*Qx8w7kT!@ z@yi^0dG@k%Q(!lzH)rgocGJ9R-B|3#`AYk$!~V1Tb%TA~d1bR#-m3}e1x9*_^b?3d zdL7av-Gn%FUSf29LdGE@Q$;6)QB-^B&ZQk1GCK} zH8a%AQZt8vO3flQtJE~8Ii(hotpv3KY9VRH$;^-l!0y#x;s^l1S5vL18 z+&H;uNS54Ph)QmeItrssk~)~~CaH_*ZkD>3?yA&%PTc}^tJF29hs}Bk>IKw8)Ju|w zsFx)VQBNiBIe7*0s^l5uV@W?j{+RrLe5CtH>LcCHQXlEQO8p}BtJF7W5T`+chPyP} zXEc09!vYPD;Ld2+qoGHmE{%Lfqbs_^bGZDBuDW!E!qp{Rjp-_&ahB0orQnEy5(Rw< zh7?>= ztPAmZJkEGrO**uYF^Tg>qaXwGf;X3o=(L8xE_gpsjy7T^QKGfNKIJ;FWcB{Cz@zQPlSd?5* z@|h@2#BoI&pNW%>IOz&KF7&j}b3!+m(3_&Fh-yq!5j0Z5&>>x6%tWohM9mTP3={Q3 z(NLIZBt*kwqN#{xU9?OlS_5Gwgt;e7RhVNY%!#l%!s;<$`NA3sYb30xux7%J3EO7E zc7@#+_CUDU*|mh*7Or#GuH20jb~oC;8|e`DZsgsK{JTq)-CgeA1+y@pnS}YA9_G~n z!{sW>(&Gs7a6kS&)+j6%;`g7@#4GZ6Nzn(M7%wqoED05^4vsdWcmEE=-{h`xAB@~Wrm}B&HT825bLrs^R>Nu->pjvAe$kVhg!B`p`z(jYZhJkq!YSu1{ zRSLC^+^#bKa=Xqf)OrUny(TcF!Ia;H@uk5IK2GdUfPBtp+fd&p` z0mmQ9KE{KvV59qj?T3Z7G;LHSXr?fkhK1=q%=92U>6JkxET`%W7ZW(r^Z-s###<_< zQ_|#sC5;o7cj7QR$*|nQiz&ATK!(jW=!azsGu8C45f)h{1BeDZj6Z5?KFd3$?x zYr~A(%m3DIe;57u$>Y`N%F1T+>DI&Ohie;~>&qL_cQ-%X{`kp8bbakl(eLap-~GjV z(Wh(Mt88=m;h&d3T74RQw6^hR`Mu~L*H%_Hw%0yfTiwEK-@f+i$4^#1SzrCl*6Y|n x{+&Pl2`=H%!otE$89z1W>=xed*X8voVAa= zbB;q29EqD62cadjT@qHS5~N)<6p(o2v8a#jgIz~TdNxQwrBe5$G8@zaed#~Pw`8HB zTXn+u=bxE>{_%YOZTLfFr42zFxBYDBjuoN5&_S`8D==8C!U)YE8Ob<;`tv>RXJE`k z*eKV}VLHbG&-e4db21;XM1_9ANv1LWkiYuLoroXMs)-Cg$f{;M>9ZK_*N-ilK_4S z4PqHz5GQaF_aYzDy-wT$QZ6d~2`Kp(PohbF(lUeelFDJK@M~?VggaF#qXfEWNn*Vu zHO!UR5|corQN}tw&uqhDkt_EyqZd5~0bc9{?jo-?e8XKF-6iuAj9yvPtUF6wRgo)t z#W217*IJS(t`_?VRZen5w35`09=XsC+ zWGt%qWjXHGNXS1JR^t&#^|!>w^pi2w9|;fm^X%T1J*|E%tSjG+OQ8>>Aw}~Kht*-J z)o*GICiHMbgKdPm@_1{0azr9wN!454jKo4xM0=}6Rzfi%=`m8CD*i5tiM9#I8MN%) zFf(#xznAX*N{foY6ywAEa{3If3J6a>r^Pk8E~GHO5*5L!e82{wtsD2YGAA3-jIv1RQTavPy) zNfQvCVEUwC`QVfpH+aCXX9KhQr$?u`ht8@$yPN0Q z((cyzj*PoCUDf)~wRw(9yZrN(jLV;{@SD~+=Bp$$Xbo|Y#G=92z%ZeS#PlD74X9&z z|KasSJfaw^rs#wwCBr6%2L~0Rs3C>WG(hML4VM{p`A`lP;>#zJX1XSt1qTo`s>Pz*oj9KSjJ$DRoLh?@OqMX*AKl4={SVx(YB_OEEj{c@>Z}iEDoZ@-J{zSL33~ zn{j#Pj%QtaQsPpRcb-c(?MjOqSM07|jV`)h&%i(X>p2crc6|Eb^~AMA4gq_+_6hBB zHe9(Mm*@B6+qJ8(upj3fsOb<+iyM}knm^mRu>FnfmVJv`4raC-OdsmYZh1G`^d21Y z$m&R)PH*d2uy!s3JD&Eo-5Xf22L8cVt-DuQWZRD^{Z5X9@#A__v1z&fwRs_1zdLn! zW&6&Qupn+-a@MCDrV;aQ%9tRL7J5yZX5aVZU9EB*FvJf_v?6FUF@Os_VYc(`Tn|PS zb!o2F)MxPUEJ!GXimgj$)Y9kSTm3tbqX@4{Y2}d9>G5V8L8M-%kz}@)l?NHazJh!& z(&7DAkS*2k;tWFN6UgRQXl2S;&%?{`G&t>5W`_Ma&m%bH8~mb9bgAJEdkXv5ZbJQU z+@ZGwPDx>18i**z`%d^Q2B(k36{7~;QPF5j4aP}08rH)jidN3Th7eY@xDwJ0dsvf- z+kKeq29^10mp7J8O6akmDM315?YngS1dzW`TRjr&se|WFFVyeI2s@UYRhLJmMy5lv z?OA7YT5NtKI2MJ5jL#JUZHvyfwAl8@UU9i&s$+WVbRuit zl;$?&cvRK?T%&<@E>It6$M-kjz+UeD#zx?u@6=m>+C@@ycxHBz`SUWVySFJmvM+0LLsJvG*?FY3UjFfkQ6##eFBPRh`}az zDvv9M|Av@%hhj~=+Q6ghAgVAu8=N~5)^ySZ5_s`;s zfwbNK^iOtwn)5${?wLl5!a0WzPcvTb7o5j(6>ql9upY}NoR|AG_E_eym%AbQu#Y1& za7ZU5G>fgbGd%HVA)yz6));5DT-;ZXU%-1>L7({%Z zM9hp}W>kX>tGdAtMq-klFPSXd(%|T24NeY+bn+VgF|CyBrN{DSWEs{{GBM-bM9|=V zRK&f9!7Cy}J9{?~eW6maaRRMm0H$h&Rs$t{=X3 zcrNgpqc@J;W#M^yHJTcusDUc~Mt$G#j3{R+Qvm4`l8&*I%n_Rbs& W{R(fH>^s|+`oY=bPk0!c*Z4PU`jXB7 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91a0939a43e341cfe4b69d31cd4bbac45c9f234f GIT binary patch literal 19335 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৞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 h1WH$iY{zY4!_4rCK>5nIr4ypqIPD{@-R;oX7wG literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c72bcb91079d51e22ba8b9f0ae07c7b5e678829f GIT binary patch literal 102411 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e66cf8be3de11db110eba447af58db0d65f953ea GIT binary patch literal 1546 zcmX|>&#GKS5XR?flyKlKBDj^_W?=^7PQ;Zi1d~XD2qJ`@J~e0R+JDaNKLghn5g);4 zapl&nFA&HsD}Qz7>Tss&JAJCZ{<^BV|Gd7QcKm*weqMh6V7L3nUjF-C-GjFe0l)3$ z-A}u_tH5av?tC(nyEwmg$>17>^L_Fo z^irK4%Mf?agXDQ6cZfdE+FgjgH5W=sWiEII6SIi`+YDTj(4`Nl)Aqu$%qw{u)SEy1 z7!{7{F$_i>8!wIM=FMEP8@1UC=0 ze{-@(>nw%uPNL|M9Zi6H-4fZBWGJK}RB9m>YK!i+rVJi!Y}g%rKyK6jK?5ae(~+#1 zN_T|LY`tec%2*WIW2F`vqj$&Ag1Dvnv(Da~Y|E749<(N)FrCm?rK0R~2a^{>sSm@* zb#|Iosk0(cGf$AUTL9Huq;9@i(R6JiO*fK5J0J`xn-b| zq?C#)hf+I>l2}Poq&EmpUIL;FEZJ|CkmRGZ;n`H8N6dDcnf$2c=m@O3R0!)T6Tr5U z3bM`B10RXWXGImDLcX2VTkBslw(oi>nbJ*F>Hc8? zNUPb=D`d?ty5+lZUL-s67ipkvYLnSDAx5lkaAebx*tAcr1Z5R-g$>Wm0-`FmYVQVDc-rn z(N~V+dBk;e%J%&6)!&c4d-3v{XRp8g{?!l9UjO*w<=3zN*uAye_TBUSsU+FY^SW;} z?2nqMb>2T&?>g1kb7b}x`1zC1p6*Gfe7gGZi|5MO-)O$^Pxp2O+5vA&diU^4Zjlk? ftNJ1IcB8jz%$xVGuCCrZ_~_$L{@OjN4;c9uPJ=S= literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa85ee155fae21bcf12fb7945c540ba15f64b63f GIT binary patch literal 6571 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 W%8%p+a+v!i_151gBzWi?to0vv*~sVs literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f7ae191050f06fb1e4851e920baa486b046cfdd GIT binary patch literal 76739 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b41f0e5a61e729f8832d8d8bd2e5005c8cadcda GIT binary patch literal 7710 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 TH?(PI;|+V-?0Lh$xaR*KJRA6X literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23deaec50cf1122cd9052374acdd947699ec3138 GIT binary patch literal 72071 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∋>&#;3zmOHtyhq!VC-719X} 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 LW3IX6ROJ5v^0^}y literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7379645348c8eda0ff7bde5ec633f1e7e5cf1618 GIT binary patch literal 19219 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..246b674dbcba971dc2d48fcedb2ce6436b6d4524 GIT binary patch literal 31034 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 z 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 E4=05H(*OVf literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bae15164f7a3391a3237d02f449a57d62bfff5ec GIT binary patch literal 5480 zcmcgwZ%iD=6`#G^JB|Yk4&Xl!+mpi>4x7Uvb{so_)CTMjW1PlVRWEVQ%k3Pu=e^zQ z>>mFNDvd0~NUnk_wGcH@K#D{nx2ml~aw=7-Q>jX&elZ0Xx^kpQO{L}=4sM&~Q{T+) z-W|@R-`W+o^JZt}&HFd+_l7@KR0I(`PRk^J4E%n3v616lPj0OedL8p)$xPs(T z;=kdwXGP28AQ4kL@@rg5E(4x*ZZF@GEjyu;5aseKVzd(0;{2FP!Pk&W=Ue!?H{Ww9 z_`1)f^KC+m*1-NP`7bW@zuS@N72Wn>W50apwnS>IY*C3{~Evv~Su1b{1F+~Q8DhY*9BkZ+AgQy9sjO2}N zmBwN))i7c)gYAd$)YrXjNj**4WI5Aj(0E%y(I5u2wn%2oOzK*jstmT-> z?jC({C2;zF`{557uZs5q4I3~AS;FWhW3zAE*ep_J(U=hSjF)%oT9b)KD2Nv6e;=$z zSyrO8@G_XEFs9YeSUx^wyuP@Ad~ln)=0}Lu@HGh*vzugKTXPxy3B)4~_qh(g!A=7_ z0ysbAhPC~Pzf*4NE&Ntm&~ZpNK)TU|69~Nu>P&k0+dC;vcxB;IGbkxstDF!gP>Lt| z%{)@&oBOOcEWnCpn7`$lV<~`$N1q8Xug$e?5kXS%j_-Y$q)B>^P%Nn`&c`4wh{1?e z0%=26he?09lrl+JG(s+kajRM-##nk#R}IUj>XHl%cra~HCW2Kmr0Ro`YS2p7^GdQD z_S=4C`OOkymS5ue$MR()@Db&K#jJ|iGsRs_ABX<<6U7}~APHk>q~HZX`MDjG^>aNd zfzW56rp4BU*45DArO@Hk(6dXSXO}}AUm{QGk)`t8SC3EsaK=C9TdS;{+qqmBn$OPf2nH!YE|1(RohM9y{e}l_+U8?udv9Kr6sU6W!~$D zWCiD2gP4Q!9gM}&x|~%RT^@`5AS+x8OA34YaCZ!BbDbt@TZB;lYJx)|L z77GiueOOd}$2JWMHp*Viz{b^2skGV03z`{hzCnMy>+N1y{CzmLl zL1-p&Gx*sma*iP73(_{&@@1Z`4J=_ulvq#jP#u=2A`Pkla*D?D{_%4IHZG1R5XplC ztGa%P$T*w9396@qESzk7fY2Q^F(4?-LYhsJ2*xK!Tw(wMALDvDqo{x-FoG4c$-tU! z;!B!7qT!LG5>IkY`R(29V7ZKCk|CPR02a`g?Us?uBqzuyiDx-To6;qaS~58wM}z~9 z=mao;ZImK%B*XOL##9mX9U_;M4h zZ<^$L4$v&I)rdr}B&T&iJ}6j@9mBm)t3V3UOkTm*bHG!*EWc=wlg1pUZ31=0z}(!d zieZ8lSss_7eqLRX5!ew%djK+^$9B`_u zYz>7x$|4yM%!Rf z2!2Kjyr$5@eW-HpeAnXHg|o|B4o#g}6U*K>^P@8}4J+cdwX(-n%fd@#;k#m(=Z#H? zf*s`s_-)*Qv~U`ra~2MJDwi%`#CgnI+PLA2cB2{L!f^mcmNbgM?WD(KIhH>Y9y8$5 z#US&B!`+zvmNi8nwSZ$0P)>o-{g9^v(qE{vt^4E!fdpz?0?FN1hzVmclhDhJueg zCM#t4@XjUEx zzx0kkVJZzmAf1FH0|yy^g(VA05^#~y;*jw3cP$1od=!8P5QS$PjtzDm$CAbmKh#G2 zB8Bx~r|4oFlMzxUQmtFS`0K~=BET@5uZ1dsi-+-NZ6IdRDf+*Tt=Gp&Xg-Za{3 zLZVL+6>doItpIdX#W0)m$dh+LEaw7_JT^?d(p12`=>TS0U$DW2J0_QPZNnt8D!(Y& z@C}{?)N!twVBnKrN-`=jpu$Q5gVcCL(ro+&ETLpDtEe(SJv9who-l`wkU@6G!cu}I zehJ&+h*O>`Rvo9L20oJ7FUG8St+p^mkT!uZPgqn%VN}Q}aR+^=t(Pp|Gfy0q`;Z=SkW|NL60&93d2A3wbAM|&E69(=GB zR<3VD+v|T4Tr02nysUO6IjddQ-i@!6wX8i>HygPgSuV#918B>RIq_}sPWr9%O2vT> z>tOPm{nPz#pMSS|?#x54r#%Q9LoJKD7k0yip`v-F;(qn6x%4m2-K&0bt*&Xgrs+!` zd|nTt>h0HFe9$F;w*NNRP4)E?tv$Pi-yJ-$3!2|=se*U7j>1h3S$=RWR1211TF7=~ zz^OYaWyLbT0az6S-+!qm*7ZV9*XiE=Qw4Vn2K-iFz^Ozm?>S;}Uvm(*N_tr8fQwl0 zB;+J0u%J$~{B}!^GVbkcz3;pR*#+(?FO$RoM4A=ob#jvxILiwTN#)L^kWcM?U^ z1JBvlnNE5J1{ic3ci^?|6$Igd$0LXv0VGua4OM@N8a_q!pLxYMo`3!MPsQek{wm=J z7!^UYzOPnjnLoVPxzM?efV?T)Cb!5(UAIyjth;^?Ro1+jo=(r5U)|NZw5#>K?5`%? zpZMtfZ!i4%!rh9~Q^B>e@;8r6ADKBk+i|^PzHv3wz7%S|*>k(^R^Oe*Pg*~2y<2^D rsqCexz`DO(*zWEGB6C%sCTI#*4r=BpMj+%(`;!gd6w<#g+Bsya_Mk-C1AGpYSu@1AHJ6 zV7wRjU?RwPUpAC$Of)jy4}3Tg20oy2nLF)?R-Yj4sJ_|UI$)F_)NQdP)#vS73<*l; zl#pn4kOM?%JVlhS>c7leEfZ^)Gy>8lwXq^y%cN0|Hml)^be+0RU7Nha9&>_=t@#vR z24bA)%cc#L%GsoPT+YI~I4VOr!`=lX+4`xp~!zg)j-$C)58;^>Zhq%W6Qj=62rBLJT*N&%YUdySP0k5vZYHl;DqS&XT= z>7=SLMzs`@hfih!Fm*CM#Sa{4#oM0275Mk z`$1^SvG(JnjTlX~w$WVS*4o?<-%hB=!3v}tPmn<}PEPPokZ~^Nk~LV=N7>d$vZTpI z`nW1RJYkIFHOT;*kcMbJCmAEEluhe~lpm5(`P^tat11$+lDKqm$Rj~P6{_lESwl+e z(3PInhO;VD+9st9U1D~Cb(SHhN?dvf8qx8zu5QETtQ*#;BvTc}(NbVQFeMmE)+ODb z(4~$8)()1EHR+ftF(X%`@w73*`nhjtOiSH&RMw4ntv?)PBiY(tIi<>1Sp%<_xyKp< z29=K+eQNRc&(DU^Lx$brMf{HB15 zO`TZDXI0Jgq+vOAL)KEN$wLiAo2F>~rjW^}HH!X11$_5BhW^%1X`Y(i!3oWfPn2JN zqUQ2+g1y89igs%XBdV;JJe9{y?zoQaaVu{<+&PlZshx^4+Nsl2=TKS$U)DO~qs%Tk zv*}}<7JE;;Ye%OJ@n-v|oO(tcR`t$ITFb~gIxR~=3(}#P>9^jK)~3={7zuI%(ccDg zk}QXbFZ7c0?D5%W7ebpBysanq{oNZ}3PwI@@J#Rg#l+d(7oJ-RgwJ-J9-ii}2iMKE zo!74g+m<5D(}zCsM$ZnN&t3CwyB@t`cISoWg=ok0{-r?Z%<$>q3&%fdj$hdHl0Mt@ z^6?Lv;|qb#X}&19#K`sF`ehgKhtIan?!V@1E4jsxr$|J%=Znu8$ePa2VM_ir=e@5# zIp^*AjBsLPDH#5hr^o|$OGm%D5)1dOb6w@5eH+Nt4b6Q${MB6?&=k~FiXCoB3JY*5 z%XJBd!XOOR;kW{~JuFVRgv&Bmmn4#^Ng zli+f4Ha)3MZm#n+@h_?MU`H4ePLi9!rfFXZSYnF9Fxk;mIeVgrU~XfR(SVsD)r_lf z8I-Ro1r9P9aMB8=7(H}@A&$vA>#oa}^uCXs0U&^dxgLz1?VCAp?!d((AGO?b zkvl(lq4D>Reb92xLetKLVE3G>`wMtsLGb194xcGtDl)|(L_DU;-jEaqNxLA=R&x#* z*jg@AUJ+XXp9M#zb_dE;_6ki2H7G`~rFv5pk!0*3Qq!p&1YY0_uPrWc23i;^^}>pc zAE=`s43Yw07r9hsFi7ZK&{fQ3x&Z01g*RQ8rIIP*1jVRD5!0BSgSpYXuBRdIQH&<0 z&qjXxWJ3nbiCY#EX&hVJjid|74kWvQ=$OP{r|rFNuI%+lI;$j&yfyaZmap9J6}msb zZXW@1k`$e!F*@Tv=bu$y)n3sSLffasPl7G8M<9D#53gAax6X%K7sBmxzIMzb%K84q zmiT;2{F=9ODYAC@!JEM~XP!I#+^o6~Y@c(rQ$+g%D@*{lpP9g6V88_U3_Mqt=UWP- zu6xzhwvB)z6Yyi(aLEB_pQcQ4oIpm#pDc=@6{$~3y1p6|F9wRgRn zD&eE(^opC8n%2!6I(MkZBY)R6>$$ssarfZ-?m_l;)9pDEJsmBHpi#U-sA+;cHo<4L z3B28O`%5A`i#|bYsf>WUrQWhay#>^lLA}NLeEjGX{3``r5labcX2?pwl@J|7b*c@v zktJLc4#+)?R%od?z)tS%)g-lgpoQ~>Y*esJ@za9m0ihL{_xVb()C#?P0zixK> zg1_VW{noOe-il?h6GQ1OsHrZC$|nSctB)7IHac}8It5hv-SsCzf368I(fO~j)6-!GcW`>gZob_KzA_s;$xGkx6kq9NIuUXlyu548*8FK*;OBg-7`ZppGPE$r-vk7HJI-H6Df7nNar=vThqu4jmVk; z=|Z)u;q1-8&>-|f5jB`RK&n;Q8*a<6>&fU!!;f3yW6(+;1p?VCK!TCQz=rw2hV#aS z!*d&VUVLnRT0H~*(orzW2MC8CfYbv;^-!_yt)k&77lAbkQOM6B%luB9;eRQLWJ)LqaQ^Z2kQWMNaw8EBl;Lr(w`#1oI}y>=@Up2NS*>>8)kBSU8A<qF1Gf}xAwftFSPDi4DG!Z+B^HmZyV=Adq1BK?fn8?zotk0SI4z^ zVNYM2d%vSkBv(gb$|rJ0c<~h3ZcQl8&g9|xwdQKl4QCf>lw50UnFvaw6Ry9?KjA#qH`k`ncej2mRGi1 zc;t;EuN|4cV{4Is>@Dsc&)c4NyWa19uY3OP-V(}|_i=4p%k1`L0*~bfIf0AKdY1`2 emID&kbN2CN0*~T;jMv-?K`Fb literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..abf6c85fa756c19a335ddfe4dce8ad078b3020a8 GIT binary patch literal 58263 zcmd_T33yz`btZamFF-fCfyTZQY_3=cf;&Y*Tm&wlxPg*L$rfb=-9$IYrT{c`yFn5y zP^Ki>0&FD&ZP^4PIfN3$0wX7)lg!v2XJSd#bL?a?Myu%o)L~wjFV0Ky=9_$=fF!mi zFZ2F$>Tcb<04dq?-ka~;52#yxZr!@IoH}*RsZ*!^EI&U_!j;JT%<+;JCFyVIhj#H3 z{Fw23ByeMje77C7@!fvZfxErO*_(4TN2WB6p4?v7Q5WLQP)?7# zH}7bkEQK8>%eBmnyOPIwc#q~IZEjCNukWZ&mTZ*TZ=}*%#jl4H);`h;_u|lO~x-R257SuH|~J87{9a_psTgGaSwT3%{^L$TC6u3_@%|Hp~r33@NQcbUKC-tF67;UUnt==EjQy1=mW+tEe7ZgEpFUH`LEiK zF2)ys;o2OR@2T7cYPs8uGH5ZB@IftZ+yUKZ{L*589?;^(9ncQrmlgx`AuVp)L%s`A zs1W}}uey#l{xVv?y8idrpT*QJHffI(DnXe_!%c76MOlxoU}zbj<>6)>x{{$4fL7|G zrX^Gra)+u>j$bkAsl~!Agg>F0a7%YisP=;6=xWYk0djDMSAL^T&v^~Q7Xt1NuhF4v z8M+A2#U|)FhAshgsR_ECq00bW9$u^Guz{iVfHs(*8yVUNXp;$gA469F+H8VuV(3ah zTTIZ+3|$52Y7?}Tp=$tLYl7a-&~<>WH$k^BbOWFpP0+0jy${e$Cg?VXZU(f~1l`Wi z`vKizfakI19XQ8x|5+h0o`S4-(3vd4QP9Km)^d+8M+71 z2Tjm+hVBJ)p9#8$q5An4o(ZdI->m!h7|v?PKV}fIeb^?q}#>K#!Q9 z2N?P&ppTiL2O0V)KtFAQRx|W*K#zvk>0j$$=o5f`#sodY&?f=?6;pX13K4bwO%3mj zd#IB~K;SOp!*O!dct?xjonP1D#vM=#x=vrg6Dx{pncg}VGrh-%4PwMT!u36d`gWP> zdzhgiK*Qm~dW#)lXg8q8P0&XfdIHdhDTl`xdJ@p5Owdm;vJO7`5A_u2J}pLw_b}U8G07b0Tc9B7@7d|856XVp@V>) zGeH9keHPHqnxH|3o(J?f6Z9BEp9k~>6SRw=7Xba72^wPP=K+1u1PwEE2+-khyIzZK zhJFFiFPfmo8Tt~SziNV>VCb&_dePKo5r&QcddUPm$TgGW1nIzh;7-V(4!Gdeua?o@VG6ps$&r3PXPr(BCpa zV+?&A(BC#e;|%>epl_I<{R|xk^jf%IZ{O3Q-?1J;p*QD%*Mz=-G4;C`Q)j@Do(-RQ zQx>B-ys~pZ8{bcy8L&0}UgB!o;UoUOXeb=>9}oA1m0&y^@*f-U$4`X)r-Di>toXa5 z3jgei_MVFLgq0S5TTd+NKcz%ZNAO-=EZQ69Ec|gL9QL0G_ne})`un=#k!WAc-ygdp z%V1x~uVv?t^!cMoD6HhgqsT_-4faG5BEwiq-ak-zI~wJ*GZcQhKa5Du!JzU~|EYhV zI^n0Q^PylY)}|as+_SsybVP~v^@jW6>AcPkRBK1Hzb}+_P?Rz`Mn4;K({j^C@~V$) ztMK21=(3OG6(7kf(*>Q!B7MRR>hRARo#)kQ$4}H zRV}9m;wPegt9l~GR*C4kmNjcv#UkuO7sDI2P$kJJFW76?As>o-#EeUe+%a zQKcDb^2<_Kg3u1On#1_4s__k@5&aX)Yn zh}-KA`V~T)7~yr0F|wuOngeLl*%#~$cXk3#I(ws`{vL{ZJ3F855B8`}ayvUi(XP%; z(Iiw!(H4yqqhKxmV@?DYq_krPHv_}F0MakLO4PcURSMZINJkw5_C}P4F!ad4sc_=! zZT{YHJlNF(wC1tLJ&h^`zwyG}%U zLM>emy@rzHLY#5`CDisZWa(YflV6pjbB^QEIp?7Bq}B$eSK^eOuR)vQ9JGa40_=0f z^?U~%A-hHeH3}w6*0~MZPv&a*8F$V>9iv7LakrLY(568{j;E^8m$~~O`@g9^eqJ`E zbZRLLSR5J#aSiHEwNy_*X6M{;Ou6OXnSRhd=pfnXrBR23I{35{#yyl9a%nPIs|i zhX)dnAbKVoO89z$1JQoqO0=)LC(;#9yMo7JaRpc*& zC&Nf(2Ow?l3HPP#F~pqletaaIhj=L59mGe|jyTXhjltFzKGWIRn3J~mcE!>T8iXL& z!B{w!mO;Wf*W6eL7@rT{eCefNmGz0)CN(Dn%Vt;#(p2cd1_j5*-p?iU*7Wiy4Pdl_x;vjYRUTdOV&?#_e^Zu zlR{Xs{$_d2=$xKIt)mcaSBU;9RNHK-w3=WPY{Y-ei{OHE+h%jFoN>9GYXotk z#~H*)8#FWT;z=fPa!Vmk$R2WpoM1C(M#;LuIV^DGglu3oaxXZK=7w^RQb$lDd6?kE z#&0dA2>~G&Sd}~o>Yw245Pjbf%0mtw%n)Ai0H=dJJEMJZAY`KJ!Dvq?<_`nZ4}uo$ z^T#7#Rw8{gH821qa%Vq~3KNA!MPvT1V4we3m>|Kf6X8%Ep&5u@Bu=~vBYKQDn-+f1 zk@kcQwnL#7P3OnMy_nJCVV-2tIZ8O*uk>~4BoApQPX9CG2*57LgHk7A;xZ9O`J_$| zwWpG#kr}0KP(DfHH|sJ88*)_%Ak-uD4ZREl_@-6f^SyD+*3sVRQ1;++X%|foK}^IT zE0{3Cv92J7vFmgc^#+@W$=VSM_jGe&g;ZZL`m{D+X#$S)MdF>EiBeOKVc-fV>Azz8 z5uBH%bEMk(A;%3@6~RO} zx}v8BuF1+FB#+V81c^d(1W$((h3484jVrBi zm8fl1>P!RRbXbWeip`Z5u*Z=swiE%X@A6*EAI_h2)g)atH(U$!-?d3s?daj3xE2X2 zR*uw-UMs?wmN6|IIz=Nr*ng&1w8*5j2)?M z6$%K!V{rt6gu15lqyzFp@@>1zSvOVFFwOVPt>3HuPW9V6zq62k-*V^AIPrYCRCX>M z30{s|ij3LE9)9D|*B%|qOO~&gkpQ30u{jryF1p%yrEzTMc+p#B*UHBBC979WOMqYB zHA^>9Nh$^=L2!j>dsqCdvKPOtQQ#P!5CJ*gY~7{jJq9@m>0Jr#M(=9t_q0wwjJ&}~ z*g6t>!D{zKnVb?EKqS^5i9t?`fe&wH=8y^uULr=k>S>VBKAnpCO;oZ4_`^iR`$&Hu zk>uTq5>>eAfkOdQNC_e^OCae&FcO_a$vf3gDEHaD|w&3ptOv?;&jtae<-Sqj_OZ*cEco zFT6!!Sk@JCvj)x;%Hubv9N=8DFHFVOa8JmK={g_NWr1756kiuAu>KC9b=kS1Ou6)R zp7?#A@I4RS^IPORM|&c*Mg2q@Q#nwZLNFgi|KF-jh}#HdD?-_dL&d1Ya*H~ba!XQ+ zSoCz5pMtq5L2s3D9>fM_UGwFPXI3~mUs+V_73~|EtFN?@m7-)7p)z2-CnTYy<@jA0 zS{QPLJ)w$l6+?4Em1u+NkUvy~r!`o?vFuTNs|q>PAWdy}!AU~ytm|kU(&TpAcztJ~ z8ef3){sC{}B88;7;CC_W?10E%NY7wW{QF2{0?Gw#75Kd)kdHx`=-=Ph-+K(oswmMl z(t!m}2P4eXFlz^JDAL`H&z@3{B8*!YiVd)pcO-d`HEKwts@AxucceO^vYbdqQaVJnu+kd^ zAwHvE@nQ?C*)h;<08f18N^s zjzu5|Dg%CEw7Hekcd3=d^q^}GP{X*=-vv3&AB;gcbG*MNsBliu>_o)WjU12nb9*(L z`EsOxDm-uo+Cn1%%DEd{I@bqtj%dC3nW*W#R)3%;(iiTF2K)`wH1xyN^8}*SXyg_M zn5Lp826a)!O2m8xTA{D$IvQ{+#Pag>F>rWJ7SkrPWEhUQk`=08Ho?-4%=sx|B2xw6WE2&=6gIeU8$t z!ngom>hWFN`h~4Gi)$uo+fv0lCcHa7@D$zj6_0HE;xn&yjV*m+#cL~4buI7vTBa&$ zE$eh<^{vVJ)`{g?C$=7%So%<^`r(Pvhi{fIyjf8*y6ek{$%>|A zMbkw2%JI+q(UNb6zW3C3o=Uauo7lX6s(c~TQS0Bj|Jwbj`uo1U=KcCDWA=%KyQl4P z*&Z4Ea78ir;iBSOJ9b$>!6nx%8Y_LH=Czvf?$m+}A4+n5<0bcqW2Eb5Va2FpG&HvJ zCxwuL0KQdPdHK+#LrCJ@GPLWaw`643=+d#gHws=W7>{2+lJd9y#Ctzdy0`qbr;M7Q zZuK9Q{$c3bt*MResWp2hR_~jr-JdExFyTD_q1{`~oOn7ne738nAEJ*V+SfCXp*JDY zvIPG#UqY~7lIJ9H7!J#5FhMY~4ceY77?huLU?|C_<(O;Gc3ys|5Wj4vA)>!j=Efj1 zke-H|HaNO%U$tG9G3@Fc(tx}~GSt&cCB-gFk4rDDKO>#BKQ5h-f7gCSZnOoDqSud{ zz{CJG{)s5oCxB9z{$u_qWMDthe|5rTl|Ido(1c=263YAmo^*Mt03YEG1R5~qHH(S0 zF%a;x{*?HThme`7LN#Yf`3ZFsiDXz6(6frf>mjSDt0y!a_e6T3(&AF!7cb+fCBp)s zSl*)bOv#1wV?kFdtX_f#&GRbAeHY5#|k+g&xZ>sC?a$ilHBW1pES zt(hpTAK&%u++_3isnW`1>C*Ai>!rU_JMFL+RZUgby`DSn7!RfV>n5t#rApV`_Tl}X z%@#_P%Q04psy-;K#Hc8$`qx+!zV&=|?kP(;B>f>?J_=Mt64B1Q@r z#iLCdW;$wR4>wvW6Qhe!TCl1ryEcGHMq6|C`}YbKj#C)fb^C)VN@8pWnFZ#7N0=@+ zI%tP^G!b{q8EOMjaCd})9YE33=$CX}1jB?T!Y)ubdVvKPZR*hxI4wh=h^qCb<-Y8B zCtb*R%jpT}sG{P}Hde)%1_g2Jj?glRXGu9Ji$YZVraWoA|_araFX3QPnCa1PYG z%O+!Kov^0SmWZ@R(6iJF-4O*1Pv4?$4f>BqPKVJY_$-hFoeJGmtY4EA!e>c_q4)GI z7TqOiEphgNj%Z(46#_)(!QKF*I@Ad&4m!lN=2?`T6r3@vWo4?k9h5ZT<}RV=e?ZFE zas;3&E(ue8@1@?cy{YmRnmwzB+NVmYzHpG{%4#UG3rmGk3Jjrs5&yFU|1&Qkm~Xsm z>S?st3TiRaShN`|r{Wm2i4h1Uk@C*EkWy{=-B5cyW0xe%g|^Q-otSlBT1l;cpY&3$ zI&RN%FVO5}j0ek3pvTlD)WAVO?S&voEldxwlMWkJ|;#8PY})qG}(%$2%1-W zvnGafsDW~pg7XM6ddSJcB%^~kk;=Dez50E;7i&i#hKg4zubwPxN|rUH%9=lv?Cv!~ zyJ?6l8>_nETQOB$^CizzMeXHhFFiXJNmZ<#^sY{NSKrP>I&@+FnvY_{$3MTR%_08> zxy_dIT^C}k+RPXSG(VwrrJ3spE=zHJ6bwqo^*$iHSN5Q%C}q~A_4heD)_Ckzt2(D4 zHewdA8|y#FiG;%NB@vP1_}ssHSUF=SQU?kqO1zfVqZvh>BNda!pnq3 z{q>*mPV8X>=cQS%R9H3=8hPxC=Y|{~6ckUDR9xP2Y0HjfI_kLUx#CIsmQ2;u zjW}L*O?eA1?jPPi>X@utnXFuys$6x$yZS@7nI^zB( ze0fg9wGY~rM}b)LAuje}3_9jO+%i1T84i3%y`G~1K}hW|A+_BSsU7!-)OH~CqXMZD zEr(TnHmQr4EhQY+(V9^j`oR`f&8WSsd>%yvj+$Xby}IA)GQr8{5}LHBGBaZcGP^`0)uzcrpGx{=B?l&`>UCJk z(0b)+aO0lc=%)0tRo7*wCu=BerQE@~m~=r$G!9$79@dJ7Lkd~yFk`H(A^#cx8S8&J zot@#QVJ_g|<`zGuDbaQW=cSt---zRjt*;&#TlUHmNl(Mgl0_5VMKnB)OqMN6mMu$_ z)u((7-`IV9+2q=t$+bIEYj>xb+mpWb30J#dwe)Eh8B(8f%RZ0Di)h=BY-PnZBz0qN z*#+0I1asv(u3dLboaaoduEU1z(}KD|8wq6v=_J4Az$EMJ_{i4m&rtQc@IBIB&Fnz% z6c`Gb!m5s;_)*H5#)e0?7F~w5( zrt>U8f8^dmb23&ewk7;(Zz$nYN@r)wmYyigLSoxm^b|iw7R>bij5(_JYmdCWW=tN9 zL890*zU%rT=!llKPAu7aW5Kp$?UA4JWcNbtLir=P;Ul>bmXVH=(MVsG7EeVIn4l@g zW1Wzl7*hf&>4YhUD2}d^6F+}OMIoIa1bZThn=frn)gJkwZo;*09z1y!`MxN>Xd_G^%K>p&VTB=Po6=ce zfVu`}qm{KGdB}#9FZ%`W7v$s87i>0Z7{)x>7{`u9hZV6L)^+EMK|Ie0Ljp6Z)2B=D zKZ9Kr(pOLc6UmSaGNDWQHN!bp(n4G(97e&60uD&lZ=tbtDsQ}Jxfmc}F~Dx*2qn11 z;%2OPj_;V>9FWW^a;sdluRwnKRaI9aga4M5qB(MRXm7wovqYp|@uOkamZ$ zV9VN6rc%lP-e}BayiVIAp|fcxtM$@OR^2GiP=?OVP=D{KwEb9rcZ^V!W^(^|LCKUi z07z6a4Wm>B{ofK3d?VK zeHZr)?;9yl9XEnI)SZK7i14ex!-fPLwH_07?BFZ=M)&AR$=$6KCj zo>blX4<&E@qDy%r_K`4J(!SC7jnbtzD;JJA#=@z}<`E~AA^iH08zoIz zirCACZZ2yX?@uj*mfl{r^oo1bK6>PXn!2glg;)1o**6xyQQQ1MC5rwv&vY&lfTJj@ z@)`Qc z^?rzwyLUpy4MJzHq+NSiUkU4_)0BqfxU_?opcI;)mFFqAM!|Ush7hD3$D+|5<%{$i z)J0M*QGlgW*i?3QVhQ^MzW*x0eun~DbrbzjLouov2N6VKr6Ad#gPCuE(>3jv7A-m7 zKGb$`&+wj+ouefq4<@|}QjWz_OShiiHzHroy_5^&I6Ue~7A{ITw!+x({DVN;7xqsT z6<@BtR6TkyS=5wrG)+4Sod@MH`3>i5&S{C_*B}1Yqu+c~#J?S%Vc2wov}VK9$~Cuh zOPy7>)EwHb?!U5s+@7p$P8O}4cH#-tAilzjCx=gt7G15mQZsfqS=E>u!YMiwrU9%Eyj4;^nDGP+yOHvoZJI6N~~<7x5ON3(^OU z`dhw|=N=RYP7gnJIdg=0Orn{nIO%g?i@~~GGS&|IW6(KAx+7hhUIt2_o&gkG`Ibcy zze6wz{N^HVG!>B^W)#s509`Y!2#lt@yP;qe(!I4V?78^TSX&D6&J_V@n*6HtirQ zFy;GbuZ~97{9T}YkJ{L(@!z2b6s)pn{7N*w$9r+(@Wzql!`p5+s>Fz+_r-#<;N@PrRS5&`Q+jIZ23Fj#*Qj`J9avqMJ0~_i-`92M5CuL@&iH#9Uw#` z1QS1XOr*6xvDKxaKZd=G*ufX%k*=8}c3?d{Knv{}fZ3oxW3xX%@4~_WnQ|_$&!O)T zdEl>!HBZhAx_!o6rZYTZcuYV6Po-Q*ufTE-O7cLsCl>Au_|^4N{XMD>KE#=Ent=Zp zbO%r2gJPkM-V>u%U8sYp0(c|Rw1eWot{k*5KESK6EyAi1?S&OU>^4;}W<}{JnQmCA zZR=q*J&Y}|z6Yy}c%WHm^3Py1so%WfM+8JPu5t<;#uPH`KN+EHv}jSx%NPj87^y zwqT`&JBKDc>e5Jer>V;bs!UKo-PqAM&!p(4R9T&u)nz}XBosVMUA7q!B3RpQ<*%ao z@NONY(rk3w4M&Bb*_78Ww~IoKyVJ7}Z}&qN30h^{)nadgnTk0N2D_AK;%#hdrid_g zVk=)FEo9rH6Egatt?+VUbR_BbOvHo91z^H9SP&T12FjdFvx~xH&6XUP&}mY~3bL7= ziOhr@M>btjOG|hp=4xQf188?_Lq&>hfY-CGkeC_aKaFQJ>omNF1YCsJ|%^`hTN3TKwhH< zGB+l(9W+NIUOW(aik5!`N}Y+o%nloqVa-n%1d}&JX>%f5nudcR>U8?em_`xI5A+fv z0L^y&ee`BX&5tGqPKCKp!!^uRm~NS~K0*AWh7{QBhx|mZ>m8nU>?Gh6O0N8b0!yTr zhpOBIK1@=+6r3>QgUV?$KJYvs*zJ482g=VHA9mr1HSxDnpNd^Vns5_xAjX7!AP25D zJncM3i=M3NAYp}=0Wou9-CcMMX@QEL1`q9Brzu_iA>LJP;z@_{#|X10$iE;M1*C3` z(GDh}wo7j1FQhS|OCK~NdJSfgUa+n>>2L16;+Zmt_4XS*jhO4Kx9AA;$Bt@7f12wY zp901vt{>LKS;j?bIKpIu%_hsxy|8rX!L;WGU&1>|h^mS`FdEC1`I7$(a6V$J#z97A zE|50gYZN(f7~5JwtogfSxkdv^FkUS!+LwYM_=#w3^{;K&+_H{`7Z#FoRilY?jxf0s zG?OKOTWDS7uPG3Oa-K0^Fh@K(tZ3w4QAQLDQr~YvglMD#G}0>-tU&+g7hHU7__2}p z;a^EPYNovT7u$#1M>Y<35DR4BhAx>>R@PYYX*{vU3SESle}WXe5Hb7$3n*svwNng^ zr_5q&h9W?)%Gs^o1@|Dwx&7C*tZrG&?N2HIB5?uof&x3rP(Za|q%P;~(nuN4V(Ku9 zQD2ABF6|}bnetOqUHMxC^D?z_PHR?7?cY$A6bw_p(Nt;bxAj?b8|E(_yhPp#iZ65s zo`~MI?kdtmS#_0pCc|7Lx&gZ;P2G^Yw~wvR6ZLa+1T}0#q=6WAoOZR6Oq=%7@Y1%a zrVC(11jC@t-U#f8`i>j2uk!auto#Fl4lH8K$s#bmTeaKY(d!gkrgp1EglOHGTlx2+ z%?e6Wj?$^(a%!y7${UVK(NL89m(WnT84Z;~UU{&+d-;6r#7WG}BxELT111L4bOvl* zMF=+u%>v>l;BK+rYwT>*u@bv5O<0-N4(C0h!Gl#$|IgFr?B)k_9eu+MkEwz7 z00;=S;E*tlMGqzvq$C6*6bp7k>;^Z)k~SeYGgZ2C3`{Ra0Mwm#VcTC{j67YiGJR#p1NY#L`eqR&_qC=7KJ?@@4aCbO<2;w+g{AygpxFoYE9P*#QKlLx|GN%n0|ww zItB+=+GIp}Ii)+u9*)}J-{UM*5e(evpu*dV#HK~9YS2NU0eH#_Mf;)EKs_-%g2+L& z>TeKQKdP!~c}UyYm3XXCFn!GTfu$6!q(t$4FLNxKW>3tlU0`H*zlD%FG;R@h){KxY z+T=TgGsA`>C5XB~G~pfdq{+o*s6KUCrFLdZauQCsM`$M|nHOT^N!um?0VmiKAtyO3 z;+#RRhA}S_+1IF%lV29Z#u#Y-2&`jRhqWsOVR4bgiC&|Zc-(!1VpfCiztIBGz zg$NOIHzwh7slXV3s$9G1a{Z%vfxE=h)fg!qpSitCPiRlAg6G$6Amu zeUwtR8Kcw=09`YF1XiQe(CG;kJLy?@U8Akd;F-|Rv}Qou2_tf*)`+xNp$NR2C{Sk- zmIzbt7I^pw;Hw_;fBnT>89y*3cgECMT`4Hr}p2!@GjMs zXdu7#r`4o~ZT&fL z0pP~-JQy+MV#~eB&e0DIUy3mAn5_$E(I-OLQylF-MY*5o> z>FbwB(xrq!sG!8)^(vJ~7sQFgGoHF>XTOol9Bx>I1VJS=WH>{LSlhB*&jCq@_64-A zFm37M1~7>dlpV|n8`1jLREI$Sf_R28rz;pE{x}v-Bz-sjQ2X8w(&Kg)HRKHd|zCXEW)3k)&Z@2x)?ss<2P;|Q5 z<}4d!heBn7^QVlgNBdbkF-E(2 zAhcrbE2?01pD^xDpGm~k+wng`gd)?>(byJ6#Z%gLN!=7B=8Abz(8| z_FdsqAaKGPZ;VNaLZua*&7+2U+`aoOrG#bLHPv*V`aLaor{!?wwizC3i9!|Cbb2#G zBkMBWAp^f9W4p#1QYGt#$Xp@6Y|`t;+&SrOdf(eLRakmC|5E-~<>aCb$weC`7d@E7 zU*Us4Ew24?^MtqVrnefqEw*0Sn)Egf$C={DZ8<@3GcH1PWu3te-x`k+1^>w zx}#2dx6ZxeKKr}%o*irL@2+(s&W(AkU~bI;4SBJ+z&!i>WGIXH{2RSX!T(83v<(qr zFjn2luVdyE>x&*T9V;k$;UHU*-FDGYYLANd12zS^iJZ_e+TVRZX-A5_!(K}q%$-%Fr9he z|Mzs}O|$@AOfz(f^YLj$oC(%z#ES&U04gxEpP^=?? zP8K}iD`THW9v_!1>`5-#lPuh0kOl0fzPj?t%A~hp9eKx6+BY@Y?OB8fFb)55Xv~Q*}0@Iy8h^H2D%k_+yS<$}3~^5{}a~L(Iut zMz797Knx%+UO5m0T(peOYh*#n`vCMs(3hO@2Zh!NOgI~BKu*;*Ws^xC=`)0igH$8| z?1h9qi`cTys}m}BP5iV9?v9cZW8(b85`@W9SAf63KDuc4rs+e(@6xC8h@mB?UIE%| zij;H%{|KEy=3{npLC=Lj_aJ^hfHvj5qo&wi zz%n>tT>z@%9>A=Qd-fHA(-ZdKxQ$p9@`evD?T#a`l^_q36o*GHI9qPV)*als=?3-2 z14yhKL11Ew6=GDeA(6Vk;D;Ls!Dw(}V-0+m4h#=W_#c_@Ju=~Xgz5gghJ`#gvE2Ln z^g%05m{(CLsG$!nM}(A0s@cl|nviJq+wFY;2C=g9uuP0E-NmFsFLvQyzwB!47ed># zv*Yk1;qF8u0`d^o1??T}0w$b@!CQY=MOh(2kTWx_Pj}+;qH#HPN1syZsE9KT1VXy$ zIASTJh~6mVf|$Bv9ko&}UWT1LZQ>Pupi~e&$f6Nd1f!st-tprdq7mzEs$?Wk#57T-d*+&Y`Q{!VTO7xx$7QPxeQdPntNZ??7y_ zRF#CiLTmzelY@O<5U?)j{^%htIT{PnPG}LJqbNs>+hF6MYb*q1Q}y%aJ@l$q3tix4 z<#h~;06l`VX*s}HlbmCKJ_Q2n*9O=|Fc4VW9gQx=4>GHO37$$@S*Hzj7hB$YK{=Uf z(Xv2K_^e80_54VSO-hL1Q?+3fUgVLEoi+wo|Ik2* z8qPL0`nPWNpGDaq$rAx<6q5od*VoY%9LyyMqVdEKt43rlH+kBL7z>eF`8g7rRTx5` zDB#Y}`G)<3pF({>bTBcTm~g3hlLJt7TO!Rai3Z|G+zUm1$6aWvJ4iTN7fO=t24r zJ9~r8a6XJaI|)5_Pp8t2D#ND0r7b`yi>Y%+*8~fCdsk0P^u6BN{5*SaeE}_ub;9$o z0t0#+ZBQzDF%ybYxioJr|5PryoB!HZJNoDiAG`_+k?#XIaN96ee*K9XzP1Thn;?s% z1X8FQ8s`zqSiQ^oAD;DC(c4Zh60e%}uD42*QD4Nk<7Ga zt{Qu97~b&0f!ml6t25*>{MHmjh+^kVP7&nYCG}HlHr#d>ICsdmuw$oxxPRJ7Kkyuz zd$8YabloN2bS{HjQu(TBPKxOzujoS$L1*m9h;}0FP^VogT?S3o)yoG^Tx*)FDV(5c z2A621Og8ARMr%P8-D$73d14pL>k~C?2BK;<=b%-v=f@&Fc07;`zS4;D%|#z*=C$L0 zW{it!=#^<$X=;$U6h%KSlrr=FSF3%m+CYaJZprGowy{1(2uL0H zfKZqmq!?9%YdQx3D>Jv7PRDSjmlSKmtC{l8l&56UQ~SQBRvQBhsC(a2ce8{99e6cQ zl`Ng`F4dSomuhuD!(u)gXoCebmOk_mk&XHd=r@G|oPMU6i+tc%riwM-R&G0ToK+bp zkKb?aoRx4B!<636Kuuzn=$fGcXN{Ux(|D$#8y4|3r{5lC5Oft8=gmP_=tW^aVWpe^ zlqRICE96p51BB|L0E!PE1SmT5q7eIByvjH5LgJ6e{++DvvARu%MUk{aYnSZTPxz`~ zpY zzhLqiJ0y3*1;Pavh7rA;b=~Q!fhDF4VT)c{hyR%e5STnJlnIXuRt_SJE%>Uxg$npv zkjQ72(B8>R^sm{KuOiE|e3lj08QvC@%XpGl#Je=~0cvbi)*UT8L!*JPM|HGNx@|l- z^6=%OmyV9PCd(R=rQ3ea0>uk8buvr?LP#mRZg688>`j0-@2c!g=2r*k6HDn6nRMZ% zuQXML5djY&9!AHdQ zOWS`^vh;(B+G!_Xm<&~EihHlIXl~sr6Ea@DeUHk*Gd+_zW4fnddoSxioQ?t-Z*d#!EJ4g(^jeVipGe{tQW7gmE&YmB({do6}c269B?1%f3yFNubN4HPA z974RqO%O=>S_XmCrmmTn@#K>dNS@W5R_hMoJeGUt)B-O)kaYn{Gf37&Z>T(gmv{hP zEQbvm{KT=@j4D;?Qb-{1#F}RR+GhW{Cj$Wp35+ikn21aUjiEX-zMe)Tlfq;$0dx3% zxd=Cf$8l!IlO?oL11Cp1Q(#oY;NvgZUMh1S^*P&Ngfhp@=!dQFXypPEkBH&R2>vgK zD{D{#m0$?}Ct~R4(@ssDUVMQtXBCoX4&14hwQrrgcJjaYHjfu!hd6P0n|@Nb^nKsv z3D@SIv||^}7D|K(x9OB2AUF)*g4m0#OYG0Af!Q^1yVbw`Tp*yT z0eDK)jmz{scs%85^Z7%;h$76o)m;tB24Ga$L2w=;a}5s%8i0q#|JqZqvI^BzRvV*8 zbq&JPuAkanA4L|k?kj}0rdhXS>-fWPXF%RN&Q6v#BulpbTv>~})fpF}2Qn0-$9l@m z&-mhH%6>T-`e!hR$dO8y>PwV3G%i)L_4?9pHGQ+`M#tH6Ecw(n`EX33wl zrPeedWert+O2I`c)DaYlrXh99N#_3Il!F{Uth?{F-QnCeRatd4?@Hd-{mIHz(*z*r z2<5}&AUMuT&XK1t_h0HC@h061W}SE_sz9Hy9=^YU?^@44n(S!o-c^U|d~#$iq)e;f znrk)VAg#qbbmwqYHlz57+BQ0^LUr8@{eDCorAr79Yr*jjc03i@3fjy$uewSfYMt&P4OiJK%=3xgB|H*Zl8vV~!FNfjL6+tR!Q`#RE#yJ@w7mcMl*-zR5d`97J@ykfXwr08PYA_)_6XIPu>O3jrDMvlw9-hRk?U-fw>qdE-NuK1EceK0?OSl4qi!Y zv&L%Ra^|@#s>T*@QqKl8?TfOF8us21Uf6qnJcPFv@J?zR02)@i4EDhSK2dJU zHUot!*2G*j`S8F5+LLxc*BfGskE3m*Bn)Xs z4jDFP{)R{&JAH*x!+Zyq&sY4}!b0Re#UT_wi7Fe!8vHd=hHUibod;lXac9v|Ga$EYi+jE^RhZ zRha(?9}=TZZ!DqFw4PUrv>w$*;k$(8zk*z{Mj;Mj**v^?(z77xSulFyhNqq+{MJjY zlO@ZOCCkUorb<>%cvpj{!zXgohrI>4r_FKZUvp_a?&HdWDc#7KuagP&+#q647lZm0!deyOWT*p$k2=#!=*8+5YyrSn;*VSf2Z z-^1ab8Jau?n)H{e2%TRFBc}_n#TF*x7E;*zG*C=ZSkad8H6x2IH(hEP{q$t<@?_B# zRSL@!d-0i7-2y~R=RAeO?b)Nl0IaPkJontWiCjOMn(7XuujXILpR8<2 zRy*U;oXX~ z-olacp)C`RilOyt!U3Ma)Ex_54}f4{-AbDjPB>zs&Na}@uE?6NtEF!rQ`Y+LXo zOxt(apV}PUgm81By04lejc{S2Z3wm&4z+x8_^b1$;k`s5*HKu?AN7XvLwVLbN;tm? zHK0Q+Pu3!mb%BHNLKozNW2gdUFEB{M!UvGhgn$PL3p*$X(1W?2&S|$wM3;#6%mWDL z(Rf6b4wyai?RXNX!D^^&T~0~&XY^D=f*umlkHODw-!4|YbRNk zAy{dP<(NFpZPt+W0)C>+O6L5szM>~feJvR|S+pl|s+~J0E4(vG$vZ0SgU*OFnDe^) zYp|Qdq}imEmM7cXJ9~C8mnYlYXLF6o7Czh4B`4|VSxj96eO;ZrJGn33enbKNmm15n z7VOh`osk&MC1ZCd#Py|f#gACpN$$pC$|eBCpr(O}qln0i1r|K%TnI9>vn=gG4*W6p zkDShhqYgL>iKk1jfiR!o+Bi-#r-=;lJV^aQvmjljCB^DH*iM~o|3{h@AI0}F+4fu6RtLAh z$8Z0__Nnr^$?~RTdDCS1+GP3K;XStu!0KfA>Y+WieB~FP8GZ&kGd5q@oboLja@;Jb znJihFELl1RckfL@E@U;dWpvZ)XD93LOX9EQKAq#IuP#h_7EXE^-p6qQbh6<@^{VS- zDeryXUZ3=Czv(NV^flphjq&w2e5*B!@1Is6>+wygiuJ?ZA;(ZRonh}8_KdWR#4itA z8knqTOja~vmr2FC8?N=J*~@1qE1Hw|^E7L-xQsOzm{8=Gy;?b0wK9pn{FSC>lQpZ7 zHFQV|PMV`#CKaQl6D18}<;jwU32(z)jL84DExGLu=?4yX`vUt9@;&X9_8(L_5f|FL z!tCXpwS;hn0K+N>Ry@%13aiJ&j<)sm^Duf&X{Xqnk_}B=Jb(QSb#*_|eomUo->Zo< zW*=6XpAX@rW&Q90)uYu(xDqZ+7SyF2byI~!ykxaLS;$*lXgr%c$NIGg0TjIhFEAyMM@Qao!SP)ok+UH2eE`6|p)?uZm zgNJ`QNy2#{|7hNjbXGp}>(&mvEc~!%uBZi2PUK+%tZ8FZ}BT$gW=G9}q4Q z;Wd#A|3uED;X4*43lH7bf%b$w)o?y!i$a<}R3?JGtEdHKz=VtT+Y0-A)v*oJi~uS> z$38xACxTCT2$8SMDUw1%K`Hst#3Gy`?9gC16hr#eeDW9c4P7i{s}F2nB{3LI-vYP^ zLBJX7$M!4! z@R_7<;dteQZ(+)}cEYvxt~v%o4`__j%t4sWS4-Fx?&<05MBPZ1W1Id51YssLV_Ykt z;%%eik;cIZrws)XR179pk+&TV=ei6P1AdF4^)C{lwXrd+%5uV45oU-OxWJ4hW7 zq$N2G>uKs^%X+h`f_ZTszIJ1Aai$!hmcmdwJfd0-!e-}%| z70;=TCn!Ni2O=?F>N$0pL%F4obJk8sIkEnR8(%qM|q zX>@N6tlwhXBKihWl!;NAw@F^E&>XLTvC$5q4+t%Q=8lr_0c7jWm5&DPWsRJws|4yQ zJ3Q?YEew!ifpi1nSX~{YeZ_Eg8-|TMytxU&OP&d^$prLRY(YY4ndquE+WdfU3b_Y+ zfr{7%uW7iUy>8+U1{x_Bt>6T1QopL|uk~81)_G1r2UF;Mg*6>nf~LiTdEJ8oMAx#e`QOn>$17G4WZX6a2)c;Y}l_-#6ARern#-?r^%7PmusrpDd}LELoK-Sw;KW-Iv^x zg^QDgw60OuJRW-M#I+NXE!&eVwAkLVcgAijEtr;U`2|0N1F?`-qzaNFN?I}vB;;@UhGDF!_-L<}YcnVd{EWr(2F6bjm?6*i+4XjyaLt$dt= zB8UR7)C+@1PnJl4-yhI)=30_`bj4MK{R!&7tMVy1ON(yECPUa1@|}IldE?m zSMPXxQ)=~rABKJ$`B5ZQ^63fhr{_^7&>a27wzlQcJImc|+wJeH^0c+u-)VIs&ZAw4 zqWsz8^=X1p@F^Wi5?C0j%>98%bU8i6!=R2>S%*;hsoWIMMlt={OC4j9}_sJ(wXJA>T#p zGLS|!orj>ZfQG+nuz)<;H5T-+=1WmM&K!H_oa`4d?Z8G1DD$up?v&C`9dw$4GYIAy z;JIjObf7d-j70P8y};pqr0L|#YR^TSxC_3j5Qc1bNp0k1q4T92=$u4oQE*Bk7L`3B zXG!yrW3g87CdyCO+&*-&Qs_K^c#lFYg{GaSU6vhbJG8QQp0r4fM#~H{%?O0r;=DXS z>*;Di0M;*K{aM?GN>VZQHVoj#>It#8;XJbkX(!}FxYJs|=%Z5yW35y?rg2w|Pmub- zS3LC0R7K5HNjV)4J?2W4G){OMc~F5^g^0RG|A-|GKnf3kV& zKM`yeTieSnJqqn^>y_42+45^n@Gg;SkyOK`?<{-U@h9$g+^N=mDc}AH*M31N*f4e; zQ;j)wDTCDHOrW!56SB@xDCniy97SzR6s;Z}QyzrTnDOo>nJ6z5Ka)xq+0B`S} zmFO<&Kp*SEcl1jqcijM4%PE$7Dl{_13#Rw5Gs6QiMSI(MuSGg%XSA;?7*Bj!+{1mE z3s|xD0&=loIfWCbl;~-k9gag+x?#6YN-H>7wAK(meV}6)gv5J z<-5PV^m|R;X}VFqJLTIw;o5B)p7TfvhOXc}DiGUL8B&7LLRn+P9KD zbhI$&%~T%1stbM~!ik6)$1RnMN#_i~yV|1&qBTJW{h2TZhQuUSBBi z8SOv}_~xTrF#o|5(+g;&bgr64xqx4DaTL19(1b+u*d2TV`}VUqxc8hL+6GHI1nf54 z!fW~tOOJnAw;JtF+rLppy3RRGTemIOhKMJD@s?8)A!rv^%treb2c75aFKu&3C>IR7 z?l8;BF^>AxwGBC}ZOC~x$Ivz?`|$xR&JqFS))sRVwX{Nu@@ZT26ffZN3I^7b^i^Et zIeO*m6ugMkX?I`v4A!T6`f+S2ej5knW@;Z)MAC`OD2=GEBA3i5e5z`})v7C1lT|B{ zRV&6HOjT`|aBUdM87Z4~t9!2OnZ%KywPX}syK%&Q zv#NgF_LlRSGg*bRZLddCRS%5h{B^~G4{H3kDi>XH-uB^D_>(RyAIksPZ0_7j2@qlF z&9uOr4RCfh)^MF?lW00kfBl}Z_tD%0?G8)ygvGw9y5*RCd?wr^lAP+@y)t7X!s_p z0n_C2ys*dQ4Vuzs)EK`-jcMnOQDe}m zK42A+7Unw4RHm|KmH&$bqu>vy{G^>E->hqI`HHo}OzGjrFZHg->BJHQ;Fe59J~qIb zTyud*oasIOD`0-2fQ1ncqhD)M$+o|Xo;1`4u?!Oj=u*JGaqf{gcJ}?()naRZ%JFUSgLCD|Mv8yF*2jevt zKjlD)P!CBxy~HGj5dWg;QQ%|Y6Y*0@4I9Gix*L2)z3yq32R!wLkUqBBZ(hN`sf8gYu+ve=Z79u)iZ7!#WqA>LS z|KmtyJESB^vT^FrBQ0PTmH$^TD)x(El=3y|il3tgGQ53|w4Cr9GF0XNc<=agU_Aa- z;#y*I)sEyU(u=P;FyT62;E(bf^u;WeV2ofC{DT=G7J!5ZggBUu5C=^NaZp7FdOrgp z@SCssjArZ|(RiY~BYYf67@i&sNv=g9g`+jidz}hQ!3-5x<6->3U~Lwqho7J{;p2$~ z2XT^3R$2UgR6?AVJKrqzbt)7EKQ|W&r^M@w6+Qg;g?cC&OKh?#lrWGu9ric$k@F<7 zo#>6ic`EPIIJA+^QkqZCNF_)So?{< z7h^ba@c@>YS)|w3?SwG^F$A#DjVRGR@;aKeY#{7Ky8C;mrp%SWZaCa0&I#m2Lpno< z)Nyp^l0V2dK6{CMJ>oQUaW4H`1}j%o^MKJ-Jz^+d?&gLI)|L+>7SQs4KpT{?n~wO^j=lo zq-a*J{Vu^MD574YeGJrV!g8=+DP+0Ak{1raJ+Ibvl+?QG{CM{s27{N5V4=gl$PZa? zIkJO+s(v5}dlQ9ZAGy23H?c-9UI5I!3uPp19= zyQ$PZ*HGVeJkk=zSx~3K^^LH|6B&uF4G6ff=F)8JjS-1A1%C`}8|=((wP@?aha&unZoi)5%oAI@$IBOOMna4}3ZWj#91$c1Yd{VX)K zZ)Nl?Hw(3j@=Y{chh>jm#}kEuI`cSGPthdJMWKFJIHj`gOj7>N-Xh(s+91@W%Z(yfHUoyMTh2N07=@m=vT80Ce}n1?*g zBq#w&%0t=6L-Zc(xlRWoJwbA?stIyj9GC~4q7(I4hUSh&;nfp=*x?=qJr;e1Nj)cR}*IyD_EJe_B@a zup3j?!JzWgVR*Yuv{HPsKvt7oy3MBrm&rsyz_uK8Xg0x-;5%hKjQfcita~|2vk5uq#ba%9}Hk+pH zr51Y)b$>5}h~#D5oi5dye{XkNe;ns?(wvug?h_*=kzgiKY_S5*89^;q;$J}JpxGkH zAp1;XK39xSl-?jH+_$Om3BBjSZ0a_qb-%|gITvQb`c&0}Aenwy@0PS)JF>J?)#)kL zdSolBRmBr0-6mgyHe-a)I*?e5$QAmL4kQt7FL*FBA|50dRWQTef}RU|i;UG8h+u-2 zn7dFPO%D<7Qhs;%U&`KYr#kaB=~spvnT~(Iyk)|>5Xpu-hKM|$1MK&x8dgK@npVHL z)h^$q{-*%@*bL_wDtp4@8w)GgR8P*w+|JTWw@d(NUYW{Ai>{VkDH~akbT6EB;(;hS z<(x4v@td!iLfnjjNox({dNf^#wQt&bsha$~Bl_%jnMXdp1h{V2uX3bZAAW%;h#`OW5BN#u+T!L`1uAgwoBSrhHCSYhn0W|Gk zF~cotx#8yj*hy>=RY%@~ILbnZIf4OZHb?N6g3Z;k)oUY|Y%rnxRgLRprVX1MaC$(X zRXuKnmH^uLK)nX4Rzp1=);Cinw$`(7S>Gsj?NCDXQq3J3vRk=`hrz4`D9He2r(ENq0nnwn5u*!R)+# zDvV&=I}{RYv-y}mrh!1gXJ{bM{Bc40&{p7d2}GtR9}AHyc7+vC;81o;Cw?T5nR$^r zdSAt5tmV*A>D0n3eSlfq5vC(31#b*-iqC&$1lJHU`$O1L$cIdb1J&WCn#7n4q>44` z4ll*F2Y&zvreGkD-|Knijx}pIAM1vEn;MdWK667tgcS`*Pd-*dl7}g*Wc7y=OdBW$ zyx?OlL*5{o&AS*nT$miSqAAXNMOu;ke4_AnK6FlR? zb`*@RnN|b_B{Zw8?rvzt3N7d1F03^tN+IOoWNs)(x+3Julz=VDA0c->K(|BrV~S=m zUq7HSQ}9_TvrssY+Fcx)?76snc=-tS4(n$|Q&Q_{?3%M0^PB4E8`SiL^tAU7?AdyP z16;4*8~7xu78Nj2FV-u9=&PDGT__}y(SyMs2EC&5%QWeq8-tOSDews_WFb3}cXe}L z5EKY#3fA1Zgk0Pcj#D;4WNH0KQ zHT~kzs?H81#6lgS4tG__5efH%{OUe6RigoY3mt-F$|YlZ*{$kT`eVW4Ve`CTZomfh zD_co+$FWA(wJNk$4fV&vadHAg)2GE`A?A!@(a^xwCt6xso>XTBV?(FGO|B99IU!Dd ziV*5Q5~k^~c~5A5kCGb9%lGJ~n}RGv{UPN`!RHB47a;{{#yr?#SuGVTf*vKGj!uL@ zXg0>uJJuNc3lF@K-Ix!FJfZ!tY|E<2U>?4w{t#0~MPJG%B&P15uF%vsJsKMsx%mk}XkKh3ePk=F%qY_sNI3bc7E`%~B}gew zBjy(Zy2t>IC>D;BwSXCgEb7*v=Dzg_wKNU&MkZiA&=j$F!x1_=s1evg_=Dp?a@Dt# zKSRrOz!sWByzFhY>>9x^3EF|A0xPo6;7{oR1y=|SYE?8)k1newG$^?E*zjW`dxkr2 zIBEsyrR4vUFrbP_RLG*O5nOo`SY6^IZj!;v>e(#9y>o504;Y>dbjcWk!C24ZYR#Rf}k z7sMtxYy`u04ZN1k>%+Vr%Zr@6K*#GnyhOmtQC5YqNY3I2v(n7AGHc1a8qb4F1$o>t z#-_d4e-w{&sV7}+qY7ox&W~JMfDrvX;cd$Qfx6&Nid_PGjH8id`9qsscFg2SvhOb> z{1yMDwBT>)ujZEB@#6O9xBrD>@!#UC^!)Onhc7-p{P@V=_{JOgYtQFFHIP?)v39t2 z%3U<+u1dPArt*p>^J477H*r7T(S*@s@~FzTZgx1W_&x>(P}%NKlJp) z)5E7nx>Pg#r{Cy*t$*yenq^J z2YCxV$X|N9$o+|m?Urq`m9o539;w1fnz+xp3gk6I@mUGCe_32AFTO1ym~L^&zR``- zsHP8Xk#{Zc`u)jEzz+AUX% zINmHrrAzFQ+_ln_XKbFQ@Y0HoLk&J}grry3a25qBgr` zCERA~s3q_Qw@R(NLmt{QE75&+n^&$HxsOs+&DIqo6&~O=+vJj4hXBWIw%jXkqd0D} zbsl-2JhYK2w@;p}b<6h+byI8HH(OaEucTVwHr-q-R}$}8KU_aiyfT^BGHoYF>;1GX zr2)xXo^&enCySU+n1LdTPxQ!Z9Q6MEjkgG^MkJ zX87FkQjrgEHCOJC=?C3sOLOIe@=yi+I*4C(^nD|JuS|T8azpM{(R{m%8Nj)LXdCmY2w-^e%3*%|6*R0yu87OLJt`DC&>f zY_TlYPt|2nEo#dNtW tZxr6@r;)+N@uIiNu9b20`qmkO+;&N&{xNT=WaW9+4XN-0M4@XNen1!&Lgd_rt5|W(BCCCOTe#!DPn#}atvzeV< zx@Y~zf+7?t&cj_|=}son>5_|1x}bo_BRrwIS6(o=Q>+n4kq{5OEjXu(@HyD zjuFsFFIhJ#21Zn?b$3o}7`OpEhL^5qDjDEUQN32!u-ze@w3BhNo9|T(CwE@2<5H}!ViZ$Wn8A_^_2&8C6=(OcEt$>!Y z*`w69nu5k6h{NDsp9S*bzyg7m=c!F$vxe(W64$RXUbh0!L8$uIrBVuwbacY z4#*7SXThLI@o1Ymidkf5l(kdVG$j@RaH^D3Ku>Bwgj&@G`r-lbX#-|W!uYe6TH5UT0% z{`wfid4Ou^_0^baX|-HTua7MhOTXFC<`kGX|Bl2?1_hlB$dn71f=^{wLG%DZj5H{h zHbYPlh}gij<8W3k&Jt*6EXfOjBLR(NO}f+6FBOe2^LiZqAqJ#u2v;s`3Uvu;n4ETn z8x#{f1#4WI6K2*DMo1Xoh6m&2DORUt$7z%Wx62TTkP&{l)R+sVm|ynXGv$bUzO;8= z83fYj8kT+5nxvv!bN!mNue>G{4u$Ep*;cqgroPw>-8pp6KwGwd^z7~4r_P=DHrI9O z;KhS~esbxV#b-Wpud*xbhI9LO&)?4N|61R_3jD~HUEE?{tS-RH1@J9J6%22b=A;}A z-im~ifVV`wZt;<5baZNL_DVU)Us=bS%c-UpP!&7I`K}63v$&E0AE&vD2A+ZLp*WOL zpyE&>u!LH;g-oELHV3gWUc|~DMJ?0?^{Q$jwvf(dyV}@MRTj-AvJ1snk zTiSK}so|nl;ve`=_8(pnl%wloKC zgLNN#9_Jcx_ddc3(-x{p&>v}^XmR~G1s0w{yEbaKNp%`R9BSQZ#XEy$6Q|J(E+)pg z^bq*WfX9{kEOKEkOo}F?a+sf_KIN`$s&x^5{@uqnzm;NVVXkv2-2CH zQ}M$ehw1#ldgwf)+Y_)Uu0VHRWo2*w#hK-vp=%Rg_l(^5{Wm=$w_aWD8ClTprBT;o zmz}?kUOjo`{+%CMl zvg3)XBUeUN$j}|KXPNA2r_kWORiqDYZ6kfl)^;!IEiB~j-%FvwwmW^hmiu=7jBvhx zrMGamr*9$GPQm1XkWRdHBzNQx`q!bpqy3407clfiT_H0+5R{~8%(uKZHx!GvRVt1b zvod{rt4>Wb%$g?Dd?-OccbVq9P0NdR_yAm?Jj3N*4DW(2OdRp&6n0_01FcOx&om)l zhhSgGD)LH%uu6T|Nr#D}(A__eRyCX)ZW~*Yg_Xj#rIU*%+X+bzKmE_<-1Pf`o2R$cN6-B!yg|0PJg;>==i|p14}P0z69>X2X2h1;dAcb|#27K>{Q|5`0q>_!3_tDN3Xs)LWt`>tXsK%5KZpuYa6b!j%Bgy ztWo>f>|@#N+K%g-V>w2H&ool3R;K@oIjn5wv0RjwJ(_pcbv!svR$ej6D>-EloWEgw&nTxJD^;H5 zCOs=dIi2d;`Y)bt)bG?QJl(8b>%Vx~t>39vc)Cr!)_?JIhkmDC33+eZj(O3ad(l>LbTH`K9SHcu;P9A#pD2!rNGViPj$HBw2QR9R^HBOparlI9fVF`# zral?)T|7tcJNEg{4~t{|vp#mVQ zZQL|G6t|uj9Xoj@p5?n3^!bHA+fG-%gTo?|X zj^_-H2glI9!E?SQTioRPnYhXCiXE2NqS1p)7lpNN~!j*rI8!tnXH zeQ0!SOr$IG*)bvR7&to^JUzhr>Lm4_dbpH}hsC)xr+o&@WWzC&U_55dHqbxe2+e50 z>az$opLN8kzNr8DEHvIi){3e26;rbX(~wihdBb`vOECHDLnZ;UPH<*;C!5umi&T%^ z3iZloXQ|mj-jH2zp+v_c+U-U;rRv-IFP@g`cj^^dl`q3Lt7YXD%55lk!*VPS{n(Fo zJnEb14VzGiR=Zf=9~C?q`ryaYI-5|0y46bT3QiV0xslMtTiP=U{xK zdy!tp(hsU5p#LJh8tH3TdY}GWy+V2o(i??ZUz1SB`m_nqUXN$Z?41|Xocb@`S%dVo zEd7}NT)jei1Jc`A`Zv_4`Y+NOk-iRfb_j%JEJ73R*R%XXdOr0E`J0j6$J`%0B7HMU7uBcwFVb6)-tF5ua#4S(UI89o6xz@;?ZP@%!i1Wl|Dwk_ z-mt!>JUF%^Q%MT;{+e7K%KR$xd%ZFP`1A6cdh66HKq#l}c*>b+LuNKJbA%1a-zB#n zJ@Vhu7j$CA?+{)Rx>$b|j$BduL;nQ?ZbYu#YD!V1)C%c4kbYo=^qojQh+f>aVlVDSFCJQy+Znaq(2MX z#;qk|-&lmF@ZNJ@;=KcS@A(zp%hWT!rM6lBMVlA&JM~JTbQa+tYC4+n3rxZxq`!c4 zJ|C2cE4ZT8qyN%KWaJ`#N6)8TDfxMPFn1KbO#UIpQDb}$<14?mLVp*I{I1$A{TCSK zX}ougaW}R2wkK+<(5Jxo6TJnh^bBD6PajI#lcbU zIjm!c{inPqM+XA|@4;dJ$e?#T;0v^Qy$6B~0iVe0%POiNnhOJA3W>B z>JKYrc4cKR$8Dl7I4=56+SJd(FI|)P<6#|^($@`>#!16~mON=3QA8u!BV0_HCe4$U zN$YzS`6=E|7WGIo<4$`AxeNnJE-VhIY^z$*umN{kOHh-#2vsxSS7mT|3||M+aoIL$ z8*wKkE0;*EKx!6J3znx&8hD^TnMGoWtE()At8Es8U_x7%$cx@TMJ;ovC9ykg8eB3o znfrQ0`rf8ou>n8vY*}(JJmEwC2SwlDS+NPvMG_3fZ6`;^Fskt!eZ=Fg;h;~1SOGEt zHo9?3aPSlf2S^kWcMkx9f&;?>hI)8t*e61`fb;9MoEc0oAT9uQBq4-NYvJ@L1N5Ki(HEJ~(B$>WFzt@sk}Z_2MTtR$M_3 z6E;JxD`7Qc=U#Q;y1YJG)+v>BhRZg7W-w)MnmQ0G@m~Mt>^DC%7;`txm}3p=-hJ)X zYcrPXu36W-dC6V(z>I{18F}$~bq%#(Rji>2WxHZqw@+E_+E+b90}T+B1Wv_mqr-lm ze=KhHT|7DA2>ROk#-5iaj|R@jt4*FaaD&NXy5a@6Q7LK1h&Dm=gpuTul*gA%CYnM< zOfkcVHaYZn@RWux?NBG;>&7PI#Qfed|9PK(*ylg#^Pcr#7=cqx4+g#B;4tu!_c*@j zxR=CB41b*kios~ERS*| zH-yr(a#S27BP}Yq$tt$v1L9dH<#)uLxYL2Q$s%s12efvTlXl@MK%GTzi(7FKw+syq zk4`ugD5IOhlxY)AfH052SunLDR#bNV<=K~`MU7HXW3;GUDr%qV{WLFsrgrB1T=3?l z86u=#Nnm1Ft^BllF5CPj zf$*yFibXJ=GG5N|X9<=`<9AJh_1D<_q)qIYG=8fbAZa;o5Q`_XMj#?gKLlXr?;7YG z{R{j>8S(;8r{@J&=cSj4(XYu+f}NjV{#Lo|dOMIee|gzLHm_eNv()z{&1#<+4Z!(1 zeG?X%27mdFI3_BN`azt1Cxal@02uGskQbzxiJjXfO85Csj*a_);*mP;KjR;};P(RW zdcQEXO}z5b*tqwcICf(2#ONjO*+Bu5#q0M4g2XzU9R`j+<7-p62QV0NEtD1{mII}% z^`00HdX<@jA|T&AL+K5G;4xSSU9mOppW5fQqMf9B$ z(b=g=u4X)eUQI5pYj3C)ON4?U#`AGfPr7`GCq6Nu+)Up1h#KAxpurxcncV*uv> z&H91y;DB#zXrfT1H%SkVp_V`aX4DnK=T3vS_PgU#_E=FJ2t@YwseLi0=h`#V&%C`i z;@z-#G+ep$u5(+$jHDkr%3~dyKC1Yz;-0(kJ3VjLMyfg%cYeHH+Rz&=-ye2A_0Viu zpC>t2CG3Xk`jB(geTQpmTdbrrRNOVa|9)A=V%=ito%~SA)==@bsr^56RK{F|A=m2p zo`t8Ry3UxpL6j7_GAcSsQe@E^v+0GP=f0;Y;GF^K6+o*Lkh`^90@26yE8QRt{?fX5FaotWJmenoQ#J z_%e~GMw2-SNC`dz)Ej7m3~g>1uH@NF?ASy}673mKra2|NPVZLY1Ui(5?vL8bBzxIh z-Ml60?UKA*i|6m!cgVyhMZF;ia+2zUU%-n2Vi4G@&M%tjj}|pcMa^M%%ak?d zC<-~MW6u0*ho=wEl}DU)F}qV60qZ>azD*_c7qM((%(OT@3Kd&2gGNKoCc_*q*kr(O z`oWtBJeE!{f^HfwnJ_r@==$_xaL+A?Ger6z9x+@pH(4fD?G}CD!n|Pa2*Q=&81x3m z&yD(aHksqj^Mm3r%^CX8cs4`w?9wJ;PWt@)y%-N-#>721VI6Ym9F~ni(4&Dt|0T>1 z#)&aRO8ukG2Ip{KfYm`|X}CA};jbWffN(u#0Yh3_r?*BORg$AB>Zp|*wV{SS$|a zI00tmq-g-Tl6}>DzGSb#%IjWk;k9o}f8*_a(aJWdvMrq3 zK4rRR&%Ks2ofEZJNcM`kJ@Ym5{n7evslGc@w>9M5_VEiLdqu>4IOfWq%9cSSnPh1o zvId{_By;$(5wZyCjI-^3?dh36o6xB_i=&6$m51pG*8AdmrdD_)bMfz zHTejz&U3*+^&=(?;OieB`*65%0#ubJzHFvt>U&DzSf^B=Y~I%qznFHYZy60o@Q?o$ zg7pj}8Dc9+ElGPFw`vJLfqHFPy(Aq>JAN$n8hFaDkyU9`;g;VsDimO)Y57(?MggO$ zKKn}j@g>GjuwN#mw)%0~{>T~fCE@5&)}^dkS}lJmD7;{}V7O?0$#B8gls!?#P#176 z$#TJJGPx-UUE7#|Vj`awa!kgdu3q}%HjvVQZy;_t38pu0gTMnAxUaX#ty5N!C=go= z$r25=HX@!VZaqIZI_`@Xk}yve?+%>tUAh3Hoj^S6ln)PsV%&Ug>|ER}S3{Ky$Yw3g_`lA*pDlST8M(jt<1J5o`rIVM~xeYNU#+Q5RwFstI~CsT%gtz4U?xm ze;2O>7TC(_zT0!%G3$uBYbAFrF<|a%-P7H3#Y>LWF|1V%OdkjpH!XC1uP(aEeqoxOx~W1IJf=KRm}a|zni|mef~vY4Myw_n|E9HcNqRCw+iQf zlTGLU#oC7RALs8j;pYb(tDkb4;|@Utl#mc$)R(d>Ay$I^9yVj-Gg4H_k#-2Fi;uKa zy5%urf=R_|nU*X%Ka8ahpSE#?r93(%m>J&BM=3n!ExG+Bu_&l%D)_Y~wcAXr+~D(I z0-j}dj6afyF;IQVTb`E+^j*X7_nT{)PX80VdUw#QI7i7Sf z%Eco)#9FLutvJ=@QV|Y>N{i*5LRm?jbsTwQ-ALd#O4ka~yX#p)aYCK)Tppr&{t-aW1<8uzs&>PHRDx5x9>r2shcI-UHTzfTcWt}U29TN!Xd~67U zHd(MvT|EHvQ=3er;&xbtvTkF`Jee51L~mIj#|)+{$zP?%&=UsGLuqSrg#hXBq{%>7 z**XOa{2LS!AiF25{>n)N<(PITZ2bO+y$&lv^;x-OFQ3~Qu{Xr>i>|MlT{Slm&TpQw zao3FV<4caUL{y%hetNDs;;jFnqxhcFJ>$7vF6GcGnK6IeT%w^ z1Y^w?dt2XA7D-?r4I|p}K(A4-3C8!cG)CW=R4>QQ7WG0AjPWuqJU=fL51a@q;5bzrUe$R1d~k;@pb&j zEEQXa7Rpd3zY4BKB&O#zO%EhA9sdabz#?2 zQ%fWP%Vx1t(GskF=e!Ah~7~SZIV7osX1z?&=eYYwhw|s z%V7&@8Z6{ht4;bl8~P*<*y_r6P;^jSe|-Oh8xVaUcdnWap9 z_j`)05>r2aBA~AuPBvur^gHtb_=dtIa4=h9g z6uHS1&t*vB@PH)kPArFPhQJu2!4MP($@)@IC7M$YdUVM$B*J7poB0aT`VF#qB zke|l0wQmt;Db4Cby9PLlECp?#wP|PrPyPyT2L2W&h|EABLFc0RwNifV{K0U3do+Ke zl)o_c_Iid3R!gqcvGUc>InnCK`_N!==S*2(4&nApSyB*brbDxbqMim)G&ODxd$vqvC!v_#Vb>mD7l#Wr7g!O79hFf> zjpV4AKfUB=i+PHt_ucoDMm`%&y}Wi zC2m*lFEC6d9!?smSYDF8nuGPj?`HS{yZVh{X$DM|EtucWQ8C%1Nw?~P#FPZ<4n?Rz zDoCszfM3AxkDr8q=Q`TNa72GEm=4llG?_J=GCU*_`TinD#xZ^Y58j~{=qZrdKc{QL zGEI3hhAC++m(^HnI z^Rc{wSZQUnv{5Q;TpSOTHik>LPxV|qz#g_rrLCd17s914vPWeV_&FGpf9`oo=R7wn zZd8Ol^-!&2Mo&yn%(X;ZYwnd)UcWedaX$F&tG8Z_Hgro3-O+~KQp4^@$(|WY%w2rl zIqQ^#HuF6ZcT>z=8p|)fUOrnscPNtI7+YN%UEL|I?pz!QJ^w;zb!T|>i!-+GIHBUp z!0u}p;`n1=2;F7|(4<+-pwE;;g*GmfYf^#BM$lFh{zwYJDTOC-;MpV!CZ=KdZAFsF zD@l_)s4axzR^yr&|D$mVdX6Oi#KL9ylQ}5Uh(`PM5+;*#@V}AQG7TG|WoB-kSPv>MdQNUyWDMv%s#JEhib;4QTuv#*QO}$8sp^eY=KFj04(tP8xwtvilgu zkk{Z?kDom|$m}>_1NtT!g|&=RMHs}+$czXi!$gEVFfX8 zGI&u|qkos)&5~Cqfw+wckOMkOQDna20=@nLofhdt3`)AZH%G=5)G~!{QeC4E1B@n0bi~?QttB>b7F4KtLa$ zuTdA}3OlbiBu!|gC)5zQpT?^U+@r2G$<_9I!ky0VZ~flZ@W%bojeXL_zKH7?@VFqS zxi@m>M;Cjdod=}O1L4j?;nKsQ5)e_qnGRsPKM67b>n8xCIYgR>p1F--S53%XvjVVv z_EV%?8E6)7C9Da#cvvM0L0A%-g4Jr;q$#Lg8b)fg zOYK6fQ(P6SS0BQm9-QxpdYkmyqiNFBF$fs1c4zo%O&S62{4i{j`CI^Rgq(a$HW|06 z^`a+Xt8H`MD_H`K1TsG<$b<&t*heWJE+My1k6Lw93 z3hEp#Td6G*_19Gz;57V-@wyR1wZj7Q<=-}6Fy1!yHCf|1!%%EPf)C#S852AE70pi% z6hCnbsecfcBEaOb5W<++*2NuT}{ufWC$(pn5bt`AC-Gxozu1r zB30;`cC=~Pb`Xj^gx3Cr;qR^(J~LSM7z-eMD69M2YACCn-}-yj=(;`9x;^32y&=zD z80r>nj8&|ORmlrAH$E`a>wnM0u&?hn?Y0;vHa)KZh-}Ur zV189&ewazCqf8tcxloZU_l46C*RT(rurly!DwO-g$^a{k5{XyPZgGrG1fH_6$R>kl z+^#|99!eXa(_T8gL8nnX)3vW*s_F zu)LESsYmN^l6f@Hmv`#qwN|)hL$sz_s_Blnwt`1fg*R&?&zkx3VNYAs(*;fR*DNTn?c&xA|2;b|@`iouX+a%tI^PgBf5+fOFR zJ5}RjaCnNmXWJ)rj1q!+Ud@&Z+5Xn{*sAKAFWq?QGlMPnCF4x?y^`wrruUD2@XGC1 zA|>5_aPol)AdMa5%ky~_4fx*}EIY|c8qOUDW)Fm_UcBr1S|XPU0H>#_m6*lYelV-U zw}z$4_K1Dmqu4uI?*FvdJK#=$J-32`k<<$ygDldxR?DS^MN*GU@Qi7$n$k z%6Rw);c6A~;WaZlricotY$8iOtYL(QJ8iJNs=LWoWcJrrIfO??6{pYLeHn*2F!vi87C@CA~ek4(-ct) zyr{@{um3M8cQ2fDWvr=0>f&Kd@qa~5d5W-kv4q=ro?PgFQk)o}Ja_4o39~BEywWhM z^7JKwenQbtidmD@zzVs2I^tNr82sqf4_}RL+AnR|AKr8zx~Wgv)E9G>V*+i?0p!;< z5XdtdJSIM&IWhO#UFYiiHA)I8hZ`kVmdJV}M5j+58Xl)S8K}{t;WP*+bvBw0<8_vtd zY~-Qb1os-d!;k#?qy!x-;RNE`|JjOSf`QtO9 z30Cxy`Cku}N4cIyy&6h_6@UF#twa4HiiE0WuRJa^*ko51|Edh-@Gz{VTs8uZ zu8sv8)Gwa42)Qch4rB>=m>*g@rY*pfu2f>qqF{<^@%l-%2>PX^1KF!R^aARB*>v47 z&Gq@>F>O3E0Opo=CPNt-%S{!_hdL*?3kPjX#Xb7MfnT;dV%#<{Gvw){uqga8csNLH zA3Sg^m#mP;Q+QrD?Bf*AQWglJq&|YPVkr|SN!Q7hnz+iUg zfscV%eamc1w4g>Rs0kO;MGKmwf~JMGNWqqSbzohzrRi3wZtI=%Qr*58OT=AGR`5*Q z{ISAPMuqxC>M2=<^XIsV8wVyjN&FKaBSl1vg)=>MmnH*bfiTESmuz_< zRg}rAPk_>Y7nO96PSjbwO+_+E&*{atKMq+(*jlQX>N7|%LA7$6rB)&N!W_an-~43eynfDQ)O@G;%raR`=n$%Cip{%Dxebbs_{ zl!oYMar%44DMVdlI`mF(q344`w-1FIHb)zFN)0xUC|24RE3G1Z&ArO?i7Z1=)#nCFQ86S)NY{K$ z=PyMHJ7SgIXl18V*?A`zs_YC`_RQ>~LJrOzjC$%NPyPIPGGbWV_tC)*4~Ew4yzAKo zi>9RHA<~UTJnLCAWld>x%@%3Rmgt%t(wZF~H!Q6=5c8C2E;HGUQ}6RrL+f2-0^59lCvuPEXT`*3b+Us@RUvroX1A37jBWN4bP0f$CHx zuh&f$k;V_pKae7mz;rwR81nyE6 z!Agl95%zAn>)!lnei;>=J)0dWKM-*rR3u+>=7_U0QOL7|Xbk7A2hLUHpt5!X7JUQlh#jLDj{h;u{C1JnSUA>GvDiEN4fExzHWIJF$8F6|Hy@(}J83R3~l z(WW1N5+U}#DaB4mn?elK6#F0Y?Qt@W6>$KGZw8#nhW%uY&-|ig8`*3b&>X$&85h(@ ze=hpzq(RU!$*UMdy5h5~>Yf!p9R@J}k^tr?@+eF!dA+=ES?K@Z<=ZcZ8@EIocS()A zBCg#48Qpc}4gxtfgp0x1rWlKD|D=;?FrQ@u{|HS2^#1?U1Dxbd!^4@69`a4pfgXR&bh{oIU$} z0t6pQk}=0hYVxROt>js|2*a(lVb8XxXSd`5d|<9q$dXFQUOCqvvDYNc{1nx;t_WRb z6~Y*Ha+?2X&3s1OE5N%Zfjb2PcXDPd?b( zOQ~Hn;%#*ap*2AENuwgtmJp9@Oem=_d4?_9WX3wV9W*~!JN^Mw7v>KZ@iw3}xs}Q_ z&&g4RblxH!fr*IyeLX{Iyd}1_z`JY>>PVa08kL1-3sGKcS1#YC%R{+j$jbF*wsD_Y zdHNDPau(bhzXeglQ(v+lG%ks&{o}S1>hDLlY15=p^q@_grG;RfH0umJ+D{Iq+9E^m zY<2Vz;yR0~i%Aw2WbqapY6*c|s9}{}vU(+CCE2cPLJ*!&>PWTvj{d8b{$10rnb1OQ z8IqJk;WPn7S-`CJLBu&$LSkr6;!I*7yEPz)!frK)Iu;6J7btcGIg-o9drA;>THrGz z1glLJaA9cNk9ZDKj*77ofLi2gOSw$(Z6fs9``ZpRHdhoH^_5 zfw+|bNOSn*kPGIT2bmU$;(rl^E%)<%BnA1DCd%o!1idz*6 z!UrR_M?Nn4LFFG-MvD5Tdq2%B<`#;Vj?EsMx4!GR>r+mSqsA1f(I#9LVPg)%#@&= zgkczc?ZpM?tC6|uqd(IR6FL!XuEgqD#6*)9vigw_W2z_{u4k!~t|a$y$bv1eqS z$LfhI-lFhbSNvtj>^0d+lnHXu1TcDCi27#;)Zi6>C=7win1eWl>1maDzhtV6_agF15f8LiYzVWu=5 zO0QD4IAUr5hn}KdX{B0N5Ozyaq?J51kN!*1c@c1dB84jbk?|X8CZruazLE7|T0Xjc zL?0Qiep`-E+9!KVlLIt!f=tmU6T%hU7-?B_@1iSecig@gz_<@i11j^)P%{ew-XTW< zUoZb`NN2&RjEN#PAJz4M3fN8p%>Mz!LvXLgNvM!SHBQho~@6Co|noz4BWYsw0p za`F;qzA2KomT=$Gvrm8f8S-6D(nrt38mgVyLXi=CxU_ZFdcU-C#(K|FcD--5Z@z1x zezEAz`G}_%FYQ8c<|Rlp#1vW-0cd*JYML3C@AIV=^2w5H>v{-c~lL zkok&H-w-x+6^BoqPK%kvW`GvLT1LiWVg*6#&!Ub@&OGZpub#H1P+${}(H z%mlm#R}UswS_X$8^GR@M-i`d_z>29cAw+UjPKzajlIy-S)HO%)S_wraL*16yEpz?z zU5mw$!p)BfbJwc70^AYNM=qx&T z>Nxo9X>^+_z2GVwRl3d)9Xg$kO!3&%yjT+h8OcyUgUp~H*>{5(roWDoWN9OHSKQo( zoU74(bvXm?HsBZpPtwDfr7(AtHw`dQSt|jCtR>-T&JIQ#?e~hXgTc*~8!h3YHL}zG zR4?Hk1_d|2apN1|RjrFdk;3gE=XOxgsH<9XRfk=*A$#p|I!6P-hI$_7CmL${>a^q0 zbdKV3Aok1SQ&UZ~rB_8(Cczx_9+9;V=*$|wWEHF+@G$eV(t1QMuDFRJiD`hV)~iRp zRuy-8E&l(D-wv+WNoROFzf9{`0D>oL-LGe8oiaW2FT_OT2*7lufp{@PNgNYpb#ie_ z)cfF>3?=gP_Q`^_FEOqV_&w>k8vQjH+Q;iV?hJuB?v+V%07lwJ3`uZTncVC0HI^8} zpV?IY3}^{f1m8g-wzKz(6e2;4(w!A}0}mLQa-|b1MZrOP&37(%L!`xG5Fk>)1q&P>>vb9p#TGR`-O7FpFU zx!Ui!Jv03zXJIy|h1YXtbKdT{x&6lWh4RJzXxBceYhSo)f4JhQyY2%i3zhkoBKhqx zck&x>%Zaw{l-hTO+joa6_S|*vO?g9(7rD?J$?v*T_x+adwM4rQO5F#;-G`&y&q>|S z#oT2OnrtN-TC9jPW7zrph`TnmqLRhB==wd<`aR+GJ>iOdcip}B-9=nJ^1&*sogP#f z+=W>APaUF&7Fh3t57@A9KH}OKvTt0D?X^|SzeiX9xfQAgLtm37FrTfXj zpls(?N3Xn&)9vK>jlc((-zP@{VkNH9CpLM$r)f_a!Z}FO`d^}~m8LZrf*=S>+VV;RZ4^6F#515-wRO=p}R3H2sktiqM&Ldu-MSf?M{ zg&P-oS!<0~zm^o!T~m(2=%EpSX~pI}Y;*b)>RFIpCrm70vj-v zOcF#p{#=luJ=sl0`)wrJ&*8?;wUZ;}%~uNh7WmhA0W>C6QA2@Hr*hI(__Fd6D|lz|T+x!FDtW4D;@9Y^R%uo1f-k(P z^A0wG=$Y<`<(ABKE#-P2Gy8qoSAtAM!i5M8qKR+kv0X&Nl;u-LF;nw1zskCBVLQvh z3ze!V_!lrEpJX0FhMQ@}MdH6d;D^5xOpwF2>2r+dEtKI+^Ldzu@MfCMy0`YYZIlQ_^hpAHDX1VuIiIEFgsV!zU<<+g_|F z$=8WvQqHh|+~kxqckM>hE$xs)R*0uF`e~-+r(15>94xM{FQ4H1A78_e`D=_WE`q+yT7>ABYOEL@-JCR|0vjN3>9{=lBZWZd_^df)UAG3Wqj3w%M{1yV% zd71;q`&!tKjBF}LcYu%;N{^B+UdCR`W3435LyopU)jy!#%q6(A5;$hLX(jNz0NqLP zVKuD=GsWf3J5@emG`vR4W_};Dzih&G-Pi}g7qa;X8dt0GeLt;uZPH8FP#Jc z87#}ND}f)m`q+7NY*2{Xu#WB=|Z7^mQ(veTk!?5R`qF|-m-7)Vc?~W;lgAP^gl3crJmxNbmU!CuIck8XKq4j%0wR=A4`m=3+ zvMo~bwOI>oh=8qMLf&;!{yH^l=c4r^=ZDTn$@W>xkMR1$?1ZvQQLxGZ0iXV*Ez>KeT!Y;x-FsFZK2}rcgDXz`8{mpiM^}U_zt3tAom%ZQk+*b zp6Vjt=}mA|2*?AlOh34EjYDOy*OXDrE(l~u=$Gxqplg@QFH{j zG7KRuC&F9VXtycsQ*DRlJ&T33T3#f7O_3BC5G~O-8U1yg)`>>{H{fo-S!qC1VpDOa zj>n&%?>u^a>Xi}|90Bt$+xzpr!kA@9NEKyd@M$X&%#wq@WMZW_6Nn58TjRIX5T-Ky;6@O@{YiE z3q6UAJn^Q!1t#156y6M{#{`r#J_;X?(ZCqCM@5te>^+E!Q{$t9Vv>2b8qAw^Mje#h z9kiwm51}TxMFB*I_K7|?NFWY)TaK26d@EEh5$Xf-k~pih4qKj$!xWskP_!}6j^nx$ z1M`wNPDE9A#bAyf%w2-*_&F*&&?Os?qZq33xPMHu;ZC&`*BX}M$|8MHp`1#X)#_=#DP<61Hy~;xUb%J2xi6xrLx0 z0RNHT1t0d6J&qjm9;wHN{mh4k_HAYUIP^iM^`efad%;lCRO|ZVFE>!%cMtm;zJC08 zQrFSvQTyOhCSi~UaBk?deq_b0M!`qH>?g`7zK^(ac)!DL6Wa2Z>fPMl>%?k;X(hax@A;x^WB2 z5oO1qLEOu3xdU{ymrlg<#jX7WUx<`UUnkRHa*L3CL7$)2IZcK@9k!%6pZ~ z$vd})D|dz}_9PIvzsHF1@c9LwgNKs0X78LYhVim%Q^>w)x!R9L(Tu-`{~s6;u^ z4&4S+-kysu3gP)h@RqWQ|N9$CD66!(=$7ZTtDCK5^q%Fg1{vxnQJB%c7XhO<-X{1u z$MQxkXMuh!ypK?UsXOd$o3h3*E3GMJ`-=Lzc`2{+Qsl6_8;Y1qBw>SFUX|Jvc{!*iZ! zS({YW7A{*CadsrQRwT{gyiTYCQ$jp-N9=2qy}Rb>7pxyRZ#yFy0`d|nWE1V}{~9Km z^iMv~W&q-xiKb2|w$~rJEdAi3fn=-El}oi?dUGc7BPNa+j$vl*)Um2u{Cj|9I(`g@ zXcHl#tI}6S0U0c4GJFT1k`AB%1RHveP=Jl00H2HiE+b852^8C!EA(Iwofx@i2!Npi z!nkqEvxCDT!vb+j4@5vIf}d|t>E<)OOU!pTUGUSt94n9z>2C=uJV4p$SYdP6y>C|K?lfqgyE9k#m#lY6ItKW@T46i zKb3W=0kXx?qrGvgCH1I9myP~%=NM7 zjz;P56jwtEj-Lpe6o=1g@}G-M??3GX$&M2EbT z+$v~XC6hkOxnY>9Hz6yG;sY{#Bs**|e8a+*k&IduG}ETw;t&DUDV$OvVh=$?Y05Gx zN$*@hQ1J$eS{W){SaQ`eaA=fD5E(gK(ngZwin;Sk`SlBRAGF+Vi8gPSnzu)r_e#xs zKMpQ6A4-LhN5W1SP{nfC(L|K}n7YZat> zTWX!m83(OQKNOVG`Y0tAh%85uDZu1|$IpUqRqBFZ&&>T+>lq@Z6eN-(=!B}*%qv${ z;3Tz|M@+e`<(H}R*q1FyrEj-$Oi1t}q<<;Egc1@9eDaj!#-y z^f6vZJTYo^5-eDGv2@U?igfr$a=cO?jj>U@Iyq|468SQ=rS!Di@zJ?iKPps132&lvxGDuazguR(xr>uT#ck@ygYju%;a2iw7gj=Z(iuV)Ajvr z-`fVqqSAtd!IV$CHx^W0Up>2e{=iaxt0Mmim2X%)7VYYlx_Tq-{r3u32>-beIh4)f zM0C?r(x#^(1qa|v0X^RK+3oY5`G8t>r0}Vb^QoAkDJ@@e)W#Z`przyJAxD-9Hh)@J zf(9mq!?_Ugz>$iD|DWrLR(4309pTCi5qBqI+i^6JBjJM0a7u=nPTysEBI0bm=PH=# z{Dn(%yWjdIVuQ|g%$}Mx|ERcvHcFhYTd*yTe>C~wWTd!f#+>;ZuxU>AbatqqL)K8< zweMOk-_nd1Kf&l_lyC7c4Tp|pjOf98pM$9s+FPbm0AMG;V)~)uP{BYhBmSq6kHc|2 zaZ9S$=f9ua&ac=?Io9Ct6N~~Ef_|#KQv2v$d7PfpU4(cd3R-GT8i$R)s6-AWfdmX^ zbP7cDB4s;9MnD*ec^yfz(n6O|SdYL^#@Cb-XG9LSO%x+7-oqFXg_4xzgHCgH5mg|G z238Ne&^W;0kRPP)=z3wv(Uw9NJf$-mr+b*GXrolv7%psPcA&|7x9IAFl8PC}vbU#t z?sMXDQ$>mZW6p9Hn>Yd!zdZeNG}kNTdZW4ZQf_^yb&r(0N6Qo~ZIwz}vGM3#=eql{ z=wr@;y)rVDp3;!zlGadrkL2oEPBHGfJMXJxs(gKHgg>LwBV`t+Pg=THKj(xJ^S@ymGZug_*}?qF^HNww30 zc3Qt;JLUDp?_?;&wR~LFUgAQXgMIazysyqs0}lo`&I^~bGQ7_*9MboQV=%nZNZUbG zI8F@uCJ`f?jUgtpChe1U-o9|}=Pno3`#V$M7AA)>+yaKpxHdVHAQ-wcPHXVxD|~|v z)k5CouL=$Fo^hrb)78oh{msJ}Njn%qvOwV{EJMnkaQ_7W)GJ=YSvF_@4bu)nel&a! zdvK!7;3f@$RoE;oIggTAFix9z>_+ku6N^k!-$cu>|2#I#61;&+{@~z6ijJyNaUMpFcpG&a6qH&}>@^+N(z2Bu&mYhHeVbVjYG8 zw7LNiVjI2e|D@>8D*vSNuKNX;6?){&%=8U;L@%|b8{aR7Q+<TgmEC9cqu zzo63|I;C+ROZ1E_ZXJwHy})Pe=X-@~55t;M)tN>xSW z;>w44M1CQ{{~=n19S%2euqjo}%YLy6)K zwL2p2oyi8Xu)T;@tdlC%g)7$ol0A)OYm)Mt7LG3Eucv}0=KDh>P1rsx<@Ht7(N*iE zRqNpn^h>l6Fx-q-tk?$0)1d5aU|aHRL{!6@jvEfmX**ilE|s<~ZeA+g`T#Fg%yln# zLKUqMPg|_KiXuNn%Uh-L)@b<#seHrCUTw`y&VKXHMLZ2`^E73(P5Y*mQ$)pg>fdd> z)w*b2Jo<6h54Qc`wn)vhcRkO^6>OdlhALW?DxO=+xg&(u?ZMS28$X_ic%D}ZpV#+1 zig-5Puk=nmoq+CyH%JleZUhtc6x}!5o5@u;^TOQM<|jg~j*z`$x$v5p4?;^1e*>o{ zS$;EL0$RMM9V&@?1sLkG`LgA*^|DP5LB=C|KzpRWwSqx0@qC!DPm)6Dju^y0MRkxJ zwc|&g!4ov22pfujLnk&zv(jWs^1|Uf<-992v~{=Cx;xyuSF$%_x2&O=)AKp1mauN#GC#C%`c95w%kKJG$o@4p z2IAkLz?3}#XjRV!g3eDe5M1dhTcrjd+r*BxFHV{QMfwo%*S|U?5ASOM3#jVLr(9_DHe*v%c6Ua3I?%~Ju6~?PVhL!<|rytx=wK5K| z7^SSh)3Aw$Nq0F5X4-brGvLoA&=!e!@`yD&bQ^3U5|?Hk;pkKl8cWe;UN#C@3<;z+ z9rrwTgZo9YGzCz4^#}}J==Vjo^N77q9HyDdB;HK+O*4?G8W}zB#ZDwT4$!Ii70Sg3 zxP}+vwqAMTC59RlBS#V~SXl*j9Bo`1a<84S&vlaoc-!nY@CY-)T+jTPg~r8$ACLcF@((8=DEH*SU&Lmp zte!fYsO1r_HIck^|Kf0>j`^G{r%)PVJOM2KMC#SY2E!2rq%pGEp$j0y(#Kb?LNsAU zFl#fjj^a&g9um^5qj*S&As=2zMDx-Pu5wmJ8p7j$1D04epcr1APu%(x6v`{{$-V+8 zlp!*pHz2jF46S_JGG$dPp;K2{N8&bxkFf)FqE7#BeZ?B>@HwSzY96;IcuMhXAxF@* ze-FI;1f}tyT=NZO(FS+|fn+~W?j|m3PhHMNTR3XlNloR99NADw*!?Dqo?Z9n;fVuC z%?=`zrSOHESdH)J>7)pI%~mIs$5ZuUaXrE>MHvn9!iRMoHe;tSkNv$o;_%i z%hyWfYZqP!mv=_XyCwYhbW6@|&?auEE*5>oW~j!-w{_U~wma6?jAb-Oe$V#R?C6Si z?2|h7g**03&bFzZnKg5bw+?bd`3Zx)Ip=}Fo|l6qd#X0JO)6+xc=gT!tN;t1*FIa` z6`pApvLkRzP=z6TBkmq%?9?QcG=)oArk>L778=7P8*uNboarWwMG-bXfxv!ZdIBnh znYua4+|c~##TMSHO&cf9!)PJz{_F6fdy5^vn5^{zXWEfz>!zm!! zH*IfbT{oOEyalBER@QVDPh$#B(fF;349E&ll78scXGVkIn6gb}LAGy%Y+nv#%t7&3 z>D)p2oD`ni8D!PMTZ}4}Q2j_HU{5h59%WRJO&gGD3RY{I>DXzmTLA@qe13y|R|#`)Gw(B`5Hfc$0;YBjS=?ZpHMi^$p%8k3XnEFN7Yi_j)P?Of6SG`sRv0}lr zZKPIxs{iU1PS{pGA9;B5MYDopmRY=6z#+|oMw(HwBUrE2Ddeal{koCgt8A@yCw08g zbLGg*V{TULxoO)GLoG~?zg)jxFkCQPG{0oHU~F>som9Voeu-8S2tE9HoJdAKZ4!4( z1C5Yz7#B$yAVDXzmUie{!|_lFN;C+DatuD42bGUkyAMhfmilw1?b!AaQg(A+QWQ*! zOqX>r^B<#Pc;zr^J&WtOLl_JW4j=@>kWWk%s^<)ijt5Q;Q2IozLVcn1K1c3`x{&pSUT4%5bG11Ef^hW-7_TT*<5wVZ80EI${&jwchv6ca0jM*WW7XK$YvHp3TuHK^46*?WKlSn68 zbBKRHrx$UG+u#EWzuS1;?m)mN(l%22ShaSU5jskF?1O^9x>Ec(%q>|aFia)TAc$|^ zS<-%HyJSJV_${PqTbrm|e~-FZ!V4soR~!_Z*G@TNg;jElDflWnib9TR(Bi1GT5?uL zosE*SaiKio?EG7cCA&7^tjb=?ti8V7q6w*K`<)pp$pyM+yXT9S3Sr)kh#9~1>ZhgN zcZ#Cb8>H$Di~Bx0^x>gTtbgYG6KACQXr%Ood$3&dP_*v<-BV8iEwGhYsCL6r(FQFc z;;H}CgB^Y47+QCFLaSQCt9C~`do=kr+hXmTcOfuW_CnjfRJ86>Pt|u0Cl?YcsScI2 zhSv8j)_v6SVM}!VK56~F==wfseP67s_JP^7p%}g4txLddvOMIf2fRhy^^&_j>TZ(U zO?TZb(CN6>Bud!EX{}OOYq+d^X3xEn>iL>?gh+|n6Z3n1&4nF^NOC{F=WSPND__0q z+3=(C#!%DlaQU8)XHTMou~^?}dC+OdExCI5zN>6`)e(0Ka}4-9@PR8e?TY|mjXOQ< zPt_Ry*t&Zoetxh$3+GR2Rv$2$NwK3H1gV5Z7~)A5S@3WpFy;zkbmoz)AQcuSjI)SC z2_(i(J9HGpmNn*ybqq@|-|Y*h$422P4iD>5u>SDP#&&{(-sAns13BP8n;f)PK)G=L zpl^!X)f^1?<1V<85BU7&hs80rF{Ri*d6msKeiqj$n{SZ+@PspYp^%G0108sL#qcA9 zc&VDLnzy{0dn@-hU3ZL;{BAJZ_PnUQO0rkY1*5CmrPb{b`?{E`NZA4p$h5DIZKVt4 zWnYuAx5?Dj)@14L?dxqa_BUC2`*CqxbYN)WIRgU-Q!oxpH4t|W4E)Ua;3zH0aF;bO zAdH>Fg&FIlxG@;FKXXprY)&L}DH5w2H=~OX5(x42Ido(Ptya2q28dYU!c=Jqth?Z>1{gQqSJ5D={B8yn@%6n>0i<5 z4xRppPJcqDe@mzTjZVa_ig)Q0qf?wt{|BA!)9F9a>96SIpwnk``kYPyI{iJJf^_-kb*jIo88`;OOyC;P@5?Pd?Y08jA9q~0feV1-sbmgW~DV=D)6|s&^ z6s=rrr&A}LHq(iM1j@@*hQ`U;R6Ieaemb!wEIEdVXX)gp6IuU?WbGv@WZBC1Z>V18 zS3;6m@eHMYi>|KH6#*UF>R2XSTj_R zy5oLPO~Q&_pssvRB8#q|BXwUJnI4%doE}SL(~}%Sq33$@Z1dca+4h8ko*z4bu?t~S;RD1z#l`ywq)|JSjCw4=g>)H#` zFN8b|Qf^~{a-*W0l7|kus$64jy^joPJFK`zA>|b}i*FRq8{f^km9=1AII>`uyd6^6 z`a~9`+mkEFrYCZNbOi(M&dm?ZS=OB~Pf3FPR@b~+eye<8@2%DB{(g4xLo3n|V5n+z1zeuecS~-SEEIiEe!G0}xsP7>@P#}3zJKt02c@q4p{D&( z^-~WG$d%Y;*kjy}+AFNZG4xu)jfVN!`M`XmR1P{s54(4;-}~7)*NUf$XRI_jQg+2d zD-sjk+15kGxsIEgZfrups%^KnEfz&P_DCHRwMwek`_Mq?iQ;@~zj3bX=9U{<9vbL6 zvBqsJo~ysvc%$*50hft7m(?@3@8-c92Ok=6nW(W?YvmAD4-L2kBY^ayH($Q-@_Ljx`oRTkXu zi`I2XbzRg-Pr_-{TZzj=UKYE5<;E)y4Y*7c7;Mfr2fj6MzxM$60Baf4=?V7Rv6ubc z&(6D6K3)Eq6=@I623t`AQ?U%7BEJSGs`SRnSI4$&kFBnI;ILV@-S?CxtoTI|uCnL~ z8?II`@6O%t?!UEvVeew$!c%CWRJJjZP3bv?vQ-Is7n3u`ajj&!WTuGXPoP6aZj3tCgy!bh&!EdQ|lfbCK&ozcI_YdO=8_ z16L!M*~s@ss4rJ13UaMQ*o-#kRt}9uQKE|ay8dSK4eUJ2`kL-phz#Z4Vy#o}ahY%y zSvLVDFxws)aG7Y!W@B~i#xVj~Pomgv?U1|Vp#hf(&+>Gwe7n{2z~crq1QUQ}4;%vE zQ%ivDNz{2!tWpgw6HghT{)tu9&=}S?KXB|aS~s&^qziOoX=NgdU9QxREJKcAb!~#Z z&+W-jexsD#^e~s@?J?y5;+6S@%S36eevivUm4m@{^R4ED0hfzKAC-St{*W#cuzHVk=uaz5@xy~EFnYGs@YW-9&j+B{8lNu?V**D6FaJ` z9hgI?hvsny=J7`BdgY~-X4LMzXJ>`<&^VnJ!}d!3d?_C$h}h z-UnuDj_sipr6$f9t=5-}a_19{e95@rqrHx4&c9>?fs+wm5g`s4d9!hnJk1F+JtV}3 zUuqpD<;*_%N-2BwLy$pFqODFH*MtF=YRR}vKpMVv=L2&)ioi?+K+Zq+?u)lxTsX2= zyYMxsexp>rDM6{rF)AJ=P8coL;+gU5-<(6>LHFLN^kY*`op zPZo%qur4LmRm`URS;XeOFeu906Jw?rZ^c+6#xoHM70<@b+7qx?^999o^llT{6*un| zgt+<0_=&jr>G9FHxo7x%+}=AnHYU=Q`ROr1tfS0~&6%Yy`DHp00~L1-3^2XGAaS38 zfdQFMF;e<=dWU$IFYMc7Hg<>jE)wwH5cofFLR=Z6F>cuL9}Kzw&QS0l4TXPhX!~+oOe}AG~t=6}U8Q|K9d+{(&ob zvE1UR=dQgp{nE_j{Lyz`zV-5A{YUK|wuf`~T*>)i@#@b^xmMdlv#Z1uG88`W8j4ph zt==CldMacfKPWg@ZJFLej!Vmb+(p;(X7iM^2f116OjjJJ2^%_|W-<|#Nj^)ClW3CpcDe<50C(se&e+~B$$Y!p6u7a? zWOw#IRrlV$-MFCqn8~C_RM)Nd<5bl-r%s*vE0-%rfQjUM?(ElI5`-VnhidW_$LdQ~ zLAWXeg}U+d7;*lGB^R+%~u! zy$9(Il7_U1Bo4&3fuH*-6N^F}@8$&_i)ijac?nm=fPdlTf*EPxJ!FWnL8iuvfeW0_QGA>Th81Ca98wJFn1x`mA#ds zU=k$D&>pozQoq5XH%0!{TfJ_aVx)Z}l}2?1OW^;g`jz?}FqPutt%HI)t zTk%_k-?m`2R2}q5)dQAb&C8bFjX^5^bE%Z7%eeMbcckt>>RP1U^b4o1L+Z`h0{<60 z8mtdC1RGIiP%S_8D|N6^n-DsX@>N|@2mBvVzf!-!=CdL~&ZT@*7tfE61Gj@M>y*5H ziR+Fmt81&YJ=nHxp2KQQQopPf56^Ssy7`T!@=;wsLw>$s^FUs({bg%!CxfOAK+`4- zDt84pOB*oK8!*yaFjifXZOEXUp$lq>sb7}cR^-;K=Juu%*t>^?Z9~|0HLQ0p^V3ycPRp>QB9`6fbA(069i*FQEgJ~#|_ zSQ;50Mo6grZ>b$U&0@kFIMa_GYyY{x;3yn6Dbybrm&o;aKt4Y)4wpSNHW2oQ!t&qJ zGIvu<+gYwwuh%_4RS4W(Fvz3oknuAvbNxRShddk$f-@PIR0b8<9GK z!SRle+~0wb0Co40g?P_K>X+Vg?4QmA8SaC9iJr9*)~ zB*9?$`vb$net)Dmy;1FIKm(PY1#4PJ<_O-RRX7O>W!mJLvnhvBjGy11$npC}#)1>W z{X{&Fo@jbzo6RiRq+73zZZG8JA{ zelOdaU39mw=xXnL?}9l0T+)i~q)n*qNM@1CE)*0eDGp-idhR>m;@MJ;&AAB&HBtf9 zghzvLX+XlD^-Brsw=|$diz8jIgQY9~v7R#q0{pifb?kfEx@?%1(+} zKvA=`DIyaF)@)AXb%!QL`*nrOgtW;HiY;D}efaHH&=EKVf!qu>s3up1DdD8hEJjW| z#h@tU8w_K~kk3vKthf74hopgtVc)=*?CY20FxCWL_#CDd;*m?rA-IuJv!k7Pus+8y z?nDV8D$mFJejA)JS%)crCJzSQE;wD&M_E^5)THOrDoen@DjS32s&H1gEQYnlgb7TT znG)1h{IY4vbWnKikRV((Pl-d+y%}c8tYT-P5T^W@nKB1OHII<^T1{A;+CtEz#vh_S z%`jmaN@k|SDU+Imnxfw%qI)eu*qw@{hN0Wdk^KM|EMn4VfEH`?Xdvw4D=vC?z&9%O zOQBFeo@A>y7N`ptgpe;hh811LFtpPYITs$mBufZbJ-Wff)N6yY<7E;{@Amq>0erb2i!Y5W5AW-!gAQ1Rm6?8yA zzRZNFUCgAwLD$)0Wb4U6>~|7@x2_Md9a6W3sQ+oN#Aj+m+MCU+r{ulJSZ;>}u%fnj(c8h-mV07hQgWcf>cU}l@AO@lNIEV6mZ zd^u}0FV$;P)=Odtz!?+=#6iUTruZA;<*X^2ycMw>x_DV?4^rrm*4HRNF)EUVNr#qy z4pZ{7{c`qHc4{;xL`*36RQ6QXl%1%h*9t9Ib%yjcSMr(?5C_v}%KDb+O=aq`X;Obo z+2MWXq~UQ%<_i+a zM4(9$nuUcmu0XImr>9ojo*B#cvRo^k!dcr7J%w{;e{*CZKkjK;2*aAOA?ThBli*Ha zX|&-hpPM!M#C9;(75asFPI}a_B zgQJ6C;38#fasWEQ!!9F%vMa5W`erO&&gGNVLa0Vsb+y$fh$OU!4&gV`4Cx!F1Wt*B z{arSNwT+3IYLt2k?2|W@@i{5nH1%+#$SnT~GGO4E$bFR7il#NUWJ5>i7)vHB-?1 z4J(!jOV0yw&jZo-K-@>OpRjzn36Xh^QLo$-Sr6&fZUPLV1l9u#9`-WQhBm^Y{>XoQ zTh#KEu4QjS+}jY#Z(MkOvEc2hn^nurd*aP|Vom#RKOb{<$L!s#N3g}xt{~F{<8Y5< zht;Z?d|F^7vi$zwSU)QA40+KeBU9%m%-y4t@~_gTL{=?Xjbzo6MRSZ#G&n*XuwE9v zXW6i75v?^zo5{L=!A!G$|DyP|^`;f8fOUV;E?OTIqqX-1`sI01HVFqUmHrV4Xnrtl z+ttP}ifFH36jNJ+(a6ne<4WA8pgFY(7>(S3WkwhPKk#Meo5-CEusbS|86)B;Oe-%l zQyR90k+=46$k#eKtqlZ6v?;GrQ-4dmip6G@CY>HuS)PKR)nGE~e|DEew_V?JZO_;CExB7_ z_7)B?wnR3g-p9tU&s#6bf$}=qAFAinfOAiDt*dK&&#ZXJdP+c z6zu>klzhjU`-=Yy{<&wD04pZZ+B$bE37Ba8X3ZP*H|hyIT35}2Z37FtkG;ipWykD} z*K6iZFFDF%mU33ne&nSYb$3|pLwBd|B%p?UL35CH63dV_fLcmHvcX?XpYj$ICL4w3 z>AV%EWTTZdnDvl6X)nnzL4mRNXaF({&o7O=XJ4me%TQ59VthWl6;#)OoM1NSd}q)G zx<3bb|HAbPI*^*M#|#s6vT|%e7k1)Y^m;BzawD!m@3K4${K2HkLoMAb?KzTR7?olPdJ)INYVmW!1aOT4q|X0^Qx_t&S1Je=tuqS5oHwd9W5P2Qy+LTO z)Hv08qqRa7CMFfs-o4sX`yxFzVHCSA*GE!}im_ z-vPZKBojCd<6{!-M)bvMtcqmIE6gau0u5kM@A;X)M@CY$H#($11O*K zl0hPO5jUZ$k5ff`zLu7eiBOn|XlY@2onwp#MoEKXXPA~K+CEU>pu~rV$1b892IR33 z-&tvt7!XR+wKfq`*EcpgJc-(zQU`iqa2VVQ&fMlCv5wPzN>?}ap^klRtmHn>o}s=rUmu51axtn_aiFz4m^e6TQDh|= z&qYT7P)bfYfu$Gn`}>;FyWPRyAdNEvHUd#;|W7FgWbH2oOh_zQ?3V#>DUQotX%uoy4Q2@nWgF7y;hZr!h18e4IDW2z!Nn zpPIXTPW5ndo%TKXNwNr~=Y;!XaP{kH1C2n#p(hb&peIuFBp4ooU&H72FkM|FNv);E>fA)Q^#dCD?GSZsz- z%R4Asv0cgPHxCN^rsuL1MvRS^Hd9$=#jluNb6A9aFo7=Hkf*lcP9nCb_+M0TT?g;n zVzC=9QaKgn`J1OX=$;?I~;Z%52ega4NGnAgVD$RC|oF5_&gK zzjgE5Z8zKAY+o+gb)#;fX5q=X=cAjWweuI2igtk`;P@$iLo~7TcqeIb}of^&-Vo%<6^eUG^h_~dE`sU=vZ2~kG3@|)DOh=gcVDoB!fVwN!@JY z3=ZocPP;C#lNFpivgL$Rp=bv3Dh!-}12Uk#b^~C&%h2o`x=Ed%K!N!?GE8tUafA#VE zIYM3)F+vs_Zq+ZjJ7f0FpWM$D^2)&kM=svtWp8cVTf6Mt824^m$=`Bo+pVVCHL<)s z@9zX-uAm(xc|k5Xd#>E183`VQXrjH;)G6F<>8>|_P$$BcpMqZ^3ylp-42RQTipG~< zjFGh*rZ{(rjW`0h!H8Qi;--u-6C-gP8J+h{jAPJLB#F=h!fe`nKuh?NjZmdm6tl}mxP_KKWlo6IFfW>~>$((5QEDpiS}C?t zleF^n2rHc#X2#|kaj0N`j}IwIJuCo0t~t9L!xuHr?}|Aq zesYJ7HAM0%d$lKNhU-Cy4&+|4WC^c03eB&Jg=RkGwOs_EG&Ji zhT==-R;lx>37k`|!vWLw5j771+|swSd`@Dh!4WY9dXVwYIKn{c*6hdH_$vGIx}C2@ zJT~B)9Gd`+iy2L*Q4mKdKn;P|osrH3E)0&z04p4{$T-#15~ZUS{xR9FZ2mw{2(ob4 z81ivkqg?|fLVyW^CdRdV7{i2#I{=&JSP4(1%Vum;`lVo0rZobb#e4-3($$uq<+2^_ zC5ohQV%g+1$rsXL4@de8k&3ug_)|PSMpAYn%}xw*^Os$9aaY~K$t73wjOnh!^?LE_ z-i&4C*4CJJ+lG0igaIM4o|1q$~sObb$OLO0W+W13{;IuI_5{d~@7E>*3X1^Sh!a=l8{&HFq7k z2x*;fjXNqSWcU2;Xb5{<%vt+GchL+#H%Vi{Y8cSxkokHiCO~4vew^j0 zf#6v^I&osm{c7S!f!cj~-yc(&CRjKZZ{E1vygS~!`#-w(EOgI_bK6+YJvqN;-u;n# zPt3mOr}zoc{(Ysm*^<^xgsrgI`a5u}*G(a(@l3=VHJqU=KJv>nCxsNZ-8dyX95y_j zq61@^&5?i01xEnXL`Kv3IwZ~d6+R3IX-3x$j`j~v1R=1%qNzQp%@Gwp2!RMa4Af(6 z95QT!5rq;4jT|CDHog}Oo;}Cd4JuZkP?R)rK+Hof2!)SN`oO0lb_bXY#9LtyFhMe5 z;IX8pc-p+_LHEc(Si0jO`8>W;>og5GCh$K{BxRBS2Q0WU`Rb%H3u4Zy6}R`w3$MPQ zOc)>#cii5&gI6D$e=P3axUlVwT{m{Y5wmY(YjwiqSHQ{d$5z{(u#j{@!gl^5{iYo{ z5^NBPxca{UHVNSiikB^^^Oz}|xTpxa+!`h*V#eqk4U#bi1i+gLF7gGZaX3zAJ|$N* zhs)L}YYLk&I>`Zs^CZX|jcieC3zoh`%|$K%RBG}ysTh#eVPuaQ?=lD;!<;la`XM*FlBYQY)H!m3tOf^E_uksAS9IwT3DEw4t-?} zYWxTw`NnZ9`Z(D*{lc<}MV1SFFk(SF&H%Ac#mGa0x(pGenPGx9wdXR(i>%1s9^hLY zO~T<};wJK0Nb7{kR^$9TkO>#ZWbo@0sk0PqF)oi?0JaFBRj`mCUx=NOEg%_OJFFNw zu^M8eGVWattqEk*j8zIos}N+Pe1`17F<0@_r0} zOyHKV6VH^E3@+u!4w-+Q0zfRv;AsXEPQ6sC9HNwjp(f1ZW8(=|S{d?72xzt?a#M>D z6BNBdiRQ?fry(kf!g)24nSTP~_ESXWI3-Uo>#L_|3>?b_NBbdvAn%^3rer{ z%=gS3`k}Xc*;^O))-9Y~^0v;{?>fA%Us^71jN`wf5kfF|MOPxTk!ah;?#7kU>g!e4 zsupdFQ}L!fOQn0~Y%A_U7QFFecT+0(a=dBpQt3Vf7nIHIiiUy5%pP2E6@I;BxwJiw z|E_jo0(@rvGcj-dq9yKa(}Fj~OE<<{8xg!*&=4%n2HnOFs8Vih3DgAmQn?^I?TtQWphUw6o9{xgRNn@KFC?HR<8u}=tP%s1tYEa_PnlBu(kYYCL9o$UA2h#ArE46^RMm!P zFU&A%jSj9k$tM;F@D)qsy)~j_iljWz1x%ET=A<%*R78f39*7dv@jWnigCy1jDQJG; z67pSSd@fqxLX#oz{247w40OUoRg{R!&H6&%glKDwc0Rz^=~NEbTO__oGPqi-Q$1@? z#jR-nD#_G61|A@xi_hU?o5|pb7zVw-jmA41Fnv|LDvH8uMHa|~|GxR6C~rUp;GI~8 z2SZ^96r0*N$%F#Smtdult`D;J&>_vGad}^4gF3I3u1d){XmMzwhboZC-;m6~N0pD= z3@<)^t0wyVH|rLj|J}x~563GX`zgbNUn;8*!6!aNrP3P3S^I>1@pX&%$O+rTco4@! zjI*p#*d(II1Z>jkDSs8-DYQ+g;SQ>fgpg?gtUGVjiZgH7SrK7L^L$^}W~j&SZhLykd7>$(_wzwpYgSzw)tL;dftn z=Y{2+N8>w>F6})2aphwl+aFs=kwC!IG(&DS7YTKI7$pwTOx$)`kNCL&)+-+}Q;O;X z=eZ8KvVKb^UG%3sDbhvndzkvA8mS@O1XMMAb#i_(=JtK$-U-&`!M7i~`BKQs>3OTbPTWih@!`--CyeSOb9*9X49iSsOJ z2lWNCDbtrahJp;Do_}e`KQuG?m@{*J4ed~&>?ybt7Iv0K&BZ3iPbhvB9}%xQ5p;Zj zW7MTB2*o~U2ZgZgZiu@Z7D7wz))~uPhx_%Nv-|JlmyvXE%vpWc?VWM(-qrUXt*5Ma zIS29QmY=gCeTGrjM`Gz?RW+ai5Mud87WyADReeY;2Vg}kbkZ!JffMp<{p3xgE~Ae4 zR1M-&PdCvt)1TdNIl5ESEwpB>D@Rvxv*OLFSX0;Sy4&GzO};mId*s8-G56y!`{S&C zINbX(1nA@es!S`agykTPQMm}+S^BnrhG9;D;e`Ewf`%&BMM%&+_i=vC{W#97K^rpp zyM*=hC~z(LMaq*9D*08ih;br+nJl&{(f%ucgDhHVn0%E?lOSOMHVg8NpTe@GDq%ST zNiO;KC>{Zfp)lW33LuM+tk?`VjGXeHymf-ce8V@6wemNJnix9 zj#VpC+^fj3md}Nf0)7^reB<A5m7JCV$yFT3C^xLQA7pUkGO93jU+O`Y>xEu1fmI%1yMcy`?<4uq{j zoQ`LG?^nefYcc9KbZuzS^LEkAqFd%$PriHlozu5+z%+_i?V-*n{xF+5qWB)r&LDgTXHl^AN-yRvbWdIUpv3#YMDO#J%pXQ-g~Wg$=Ni0C<)Qe&IKk!>LS>iH)(IqWe13n4WAj6_@O1FF?=aGA#j@%Z^zFS!7 zkXBaE$b=2|FHt;x*)71d6Hr#iKR|kZy^pGeElb_Bp226NI9+sHJ6(U4R%jn$VB^Xa z3QO5Zc}X>$psy5_PcK(>XQJeDa5?#HRn#@wX7Y&sFexKu#*Nlc~H|cqSpYOG6Ya{bw#aIgF9Cm zqcbJv!4Gp&G+GwFi^fKsfPfD@ad!BnYkqT(UG-B@*PRq?7FHU81pZWjZjG`Fx{MpcP=kg9a?rC{@8gq>Us6anDg*Y z;?BcA#V4q!+?*K`HcCL%-r2p&j+(fmX4%p9k)uty5Eye-va`#dhBl#~mo|6r6aTfT z+iL$emTq&-dt$ek`$uND{=@>m4@42p56mLDEnSG3w*1giM{DP*5A|jQ2|hB7(IKYM zmRdkjg2c2q>68%}`tA-_f6zfaaivS_CSe^Vx@OkBc#oBSAAz_5ST zMbucimaImy>dAUewLVLYeGgxBF{dqQ$+1@4&GjU$_{A!lU!Ke&7wALJl?$^M<^orT z=7$!V7s`Rl4&5BO?Y%h`tJxbb+81~4Pi9k895#8A4stn#oZM9xxk?0EZqj74J}u5Y zfA!-0#aQ*8c=6s(1o9!IQwfBu9O0jKpwnAF5%8lRq;TPOA_Zjw;jaAz*dY(PM;^RY z)S!O+X~vAV$Z(7{5T2sJn% z3c6Tmu4E6ogJvMLbh(1A9z47(s&C8MvUp7(IPcM+u|-lbE_v92^5WWsx;XWgD1LO! zqEw54YZF?GGR+s)AvE7|&9_MBTcPwGJjZxu=|(fL-RWW(`5yi(N0r=`+gaHwIv zwxNRttv1Xp=uj`~K%-Hr{VlP$2QBfSx9JK(Jv1O0*TXGUA&w7m8iEZ$ z(vH-~df z7e(OA>A(GNFg>`&2$b|JX(aIn22dJND_l4hL1!f7DkZ#r+`Pv9Yg|4!%Y=s^;-_dH zApIQ-fhFl#ruSq*4oOU3N5aO4oK1|*N+Yvqv!}n+bFkKsS%RS$t%kIL&`ObABq2^Y zF~dkQi}pn%8KD-;Op1`Mdjv~6>mBMLMPNtm;VxV)QTiH33e^889=;M)I|l4B5WVv; zVLUpHpz}c*F0kAo&@#&JgiwiO#$^dYbr6L^xg*N86Y^JzfLIar9~Y%m#p5VbNGpRO z&PWY5pl8N{lXP^E(&s_BkYT|jf5-1r@EmcpxTZOLbkOcm9H5Zm5FCxL94QA9y3mr6 zpcBvB=j*|NW42%IHK=ug4k7kMtT`osoH>52y8u#3yX1e5!BDB*zl58^&R>y>f->cP zpMhVb-~{TEV%PFp-(RI&dJBR<`&0>K8$jgdu9Q|Tm$t-9TNXQ)O1CkevReGOS2!(v zx2S@I!PgQk8a$RD!}Rku6{S-VFC4f~Ya#MX)z{N$|AFdSl2%t;*StmbC8QEcCcv&g z`lT0R_R6(2A?Rf@gYLPmhYCZ|!w|hZiT&_rrOz=pP!u=oops?x`!aDZP;y=>N7WT3?2efUCT6d1-!qg(4c7hY zgyF@=Z=Ybxpn5q=1#q2&A4Fy8lu!-fw``Q_PnhoXAK~&vI?SNUHSDkgGPL@mjnH5O za@vECiwOB7Tn3YIL5vRkaTtl&hj|WRC0_u?lM&r~#ohBiL$&2UBI|#HmB>DYYw}#O zet|q=WDx+$(`5ZQSwumo=sts09l8%iB&@ZOd_BB!zgq;U*N~VolR*FNncWj})DjzE z&-@-7d?YQ_?9<|%@~UX~`is|ITqU{D?R!W)IBN+kB~#?lqhlAb zbdOH@hNTPAFeLFLiG=;NwV1E($`%di83YCZrlJfX+p~1na5KNZ0fjfTpk}s-@fIT< zeS6q8@aJgFDor8AO2R{Y*fn>HTc2nC-ygn_8DY#1xMVfAl9QyjZS zvT02VrculE7O;qag%-%)rzR6kmj(;k7;Hnxda!^cLPIMMO)(KHa_m@B?wJ@lgAEub zYJ9gtDVI%w9-j6CMGS;L@f@p?)+q?-;>nF_L0L+0>*FWv32tcVo=n_|L7IHvh8Sbl0ex z>}r3cV-c$Fig71Bd+ph{yD4UGdPpbvP~3X36co=lF}N{BHvP&uT*G9T89Ehd?ou;oz1Pp)K-^s&vsbTef&~%TlJxpRnvjwMoe<@9 z@eQ3MfZ@4xDi>A8RlhH@&bE#-65NOBGw8If!j?D;^kZDwsHw6$Ad|mzDjpheYo2g|s zZF;0GTpS=lOn!@78(tt#f#3zYxex3LxK+FFq?8iaQiMV&c9_((w4as7CdSW9@)3mg zQ78!mXtDku#TX#})DWD)z$qD|lCk^jzQBdCL8iC>+b_!{l?rS4e??z#;grnLvQRrC zdHQi8pL;YyMM#C&oJUC2=Vw2^_0}XN@=UQZ4D?kg z_aem5g!vbeSuef|AG3F_`B%K9D??)SGx$%q0KN> zyKl+6Kjz$@!Y?1vwRAfBX~0caU-SUZx?JNxAOppubvfO~Fa@$v&&(cXiyi}Q#ULhXi;n`YfyVi55@Iy6mg&Q6inLWAmS z1%?-DLn1&!zL1-L#Xsv`a#iWC>2b*DTJmBc+?~3d$Hb}AkV+a?I%ZmZ3Kk$k4Cxdw zrbZZYaqHZ`)9szw6pVo0E=7K9%6(JW0O_VL-Ko`(&9mUYs+t{Zj`-k~V!&-Ls zobOD4BwQ6HAnk(aO5EsVx82oki{p*JG&R6cxKEU27j{Kx?vQ;W;QaBDu_!{w76s8I zIaZ8r@|I!FQjY@}Mk2L3tcsYu%V>;zmnR<09=W7%R$%76w+O)L5N5465+oq4nxG zP#>j@LzcqgO{aJjPalni4@oe42y<9=)W#jP3llgKUTJKbIry=&4omA@cfs0aly(@l zLlHlT`d*>D`5{~oo_Z{X)IMU52H~B_`eVLrsK+XeB$IqKlEKtA#Q&lcXT<%{t<<7i zVvLL8?i7IyGkSm+E!53kL(KP0Wm6?i*d@_Opa4WaIAr~L`Fca18p@?!<8>gg)OHjC z(g8@_lA1|7!ke>FSfc!Q@Zd<|U2^>eS!@S=AFi}PM|aZ#xwgBxZwC$gX(U2-PDFZ8Mi<+#FW4PDU}*JO(S%aI7~^ryVJ#VcKGAs34Fn!N@JsV9+g@ zet53Kq^kGFGHi}~2N>$8ij4xNq1*7_?GpvzBdViK&zom#c}2eyF*menukmlNP-r(> z`9eN83JprU0J?8QdFrPADVod3$;UJ{F?J$N@4h}QM=V5)*U$CqGW->504`^pPfh*E zfpzj})Us(*b3tNu36p90(1L+XWA&&;cVSuo2tRynCl7fAmL8eB<)%gWo#--tn2sOYS2v z`;oOP46O$YYRFlZjI}XYs9S|h#hNXt*22NL*^orC(i65E^mE|x@Z#; zt}Aa{cC&2Jd8_+Y@ZIz8oWJ$l`!zB5!I=FZ>lOKPNQnjBM$F5tp9_oe?`{cki`h6|BGC2la(avK3RWH)=$WK04rfV zHG%uf^8ZI3`D76x%J0`nMs85(RL$twlboQ?a_e>@TZR3T2yy?Stt81r^ z%shFeceXcb27YL%T`4G^K0MQX<%_OCQA1$a^2{KuIb73mWrbIwXd4xoz)cpU#LY&BYw)Fsm0=_%$&E1LRb&_*#zj5w zVv6ybDqIrWLK@3y`61Kmlw63P3!w8SvURBnnD2V6H^?oRqY1L;CD{uhFa#O)-Xc~DT8T0Y`obu;lrRZtfi0QLZO)U4 zOUF^Tza*CrRvJY^`yKtQe(JHcOy{=pcVX%9Y<6H6smy$cq+Nfa{{-ztZluHQJ8a2i z(WWJLZOmS4ya9iaD)TzPQN7qW1dmMfKk4*3!fwbDnw()WgouF!>r2I}a@$OxY)AzS4VCpk4!)qB6tH=fp4X>lShiz01!XPdYVAzCSoul zWD@!O=tdz>r(W9S5G`%>uvyZH68 zZj<+8Y=V4Im1Q?^S#|&fx-!%7lS#<8d$hro{|h2za!46!6)9UYNa_*T zrXYw+~8Bx^8rFr6)1B@4>1QabC)65PwswvwS7L;h(&9KQd|^;f#^e zbz66C{l@LSu{-W=kJ;O)aWWpWOkZ4S_OjvnM>rlfTqzF0!%oVW@qd_|;_VO0)nV3L&?nt#gpu!5f*WI_kL?pDq`pffi)8v_*k!Nf7k{nZVcviG0#Z z!G_=%7&MG-SObOs6*Z5PuNkM*xzsR?6cKL>4AVFb+QC%PV$R;M;;VZj_eSoruQTrJ zT=I1-mvupoeeo!cqySSixm-&NM7x{FGMS?#(ef z?&dZq$`A``#jlDrmaC3hkt;*gSDMy(HU+|P{36ZzMGr*K0oBw2&0uVOg0kgRvfhW4 z#$_O4&|vPX-2NA+BM67$9l=k1mb`UP(D!hTf6^i3)~g-Vi4NLfx$5goA9Cs^>Yr6Y z!#|ayNs~okX|7#~wXl~_VVTrat;Mdip|GQ1Z72{m)94`S=jUo}FlLDTOly<^$^R7m zPJqXDHb4Gfv_6gL$?zB#x`>}Sq*xX2BW4=xP$Yw0QCrkrA>bkQ!P@00gYkJ6%*_|) zUtBKkh!=M(6>nblZ2md;pMbUeEnK4QrEdG9Ch>zD@lnC@fnx{UJt`lEpt!j-laJF1 z--JuI@Q%sswGo-r#>f`3-bNH1i$)ij1h*N+_ic*8Zq6{q%n#_3c2&-QVeA;jgkh`~ zyw%J!)8a8ia@A726l;YMEMz@Sz1M~qzXs(Ld31oyZ)D>>_L8OkuGNz?nXPpz;D|KN zH-czxxz@7qfWWezc$tx_MpBc?d-Dm($&H zmS{`#AVuAxMctz0V#D1W@r|q-S^UMG#TTFlA@18vS9w%s0=e>376Hir;v2;Q9;b%=O=Bp*I^88axYBKD~^R ztL3XXls8$jaoHsYe-8XP5mPN!iw8~ty9R`Zgk87}gFD`m6R$uRziC46mz3#}D$ZaY zYGl)2gi*IdynM1={S0#=&P6aEb>%tIg&FrRl>@y^lE-p01?i;`56=9G<;^H2Qv55p z4nQh_M(8n6?ahLAoo@Stg{1ZQb@N2Fs=F+daN-e${&Rk=7!Xg{u`g&&q@z|mhD&lj zaw1>RpzNoYBlvaDexle_V}^tNR-xvNHXAwxQo}%V;tT%V=+31yjeH2F)XY5Wj>MD| zF=;>JF-hlqmiCo}FAb{($4lBjc6Y4Q zZ(6S39k1Vg``}W2cMO_J>_Xj+8OwL=zNA%X*vtdrf43Iu`{B!1uQ_V-JXt!j4Q zq=~}li7AtOJZPCRLBVxtxK_<2h~;F6W@UzfDv9iGXip2jB>qe(a>9i2FcWT8T`AU{ z+K#W8zM(-6#DD~&tD$oBI&Gr(22e_Hqvns+9?`*;CPZYM^87*cV8_qYKD|~0Lx@&u zfD=;ZH>~OxYa=0&83wvhG47j3+c)Wr1ClmmD&8YDzBxxe%T#s_j$Rm}=Y;rK`^7O;l1Y`b360~0c2Yac zb5i#M64!OM)U!+hA40F*bXayYg zMVy)*)22{!b8#YP5c-U9Itme0nN~x7HNTd2i3R%fk&AI>*?tivzh5JZ*s=0HvT7&_ z?Qx{_Rk=Y29*=S$-%C;cj;xQ#qOA-US$KEgA`#7jlx|R7I+c_#j|~hYoa{{qWv}DA z;z>$Cr5U}S%Mbdsjfy(c@BahZsA^$BW~%{5{I4I6h8Mc8U3|;&altm+(TfJI6)%^z zLVeTBaR>}W#i(hnbN1j}y1lnKUb=ba_GjFoia4A9jy zX930GsavVoa2?vT7Q#yvZF7f!!55T7J3sQ)uGBWpomj~$UC#5x^Lz`1-_2{h=SDId z7*_a}%RA!b9Wy7WEa+Hyb@#QYmBMoN;JkgYZmF;X&yBbXXI|8CQKPi|!`8bgAR;=WgL<_E$UMr2dV)c)Fr{Fum4|n|O@KX25 z*dtHJ@_t1pQ9&AFmK~KJLHD~>nNtgO%Q&Rmup_piGgi6lyUwmVuDrQ|FFg}2ScZ<& z(v2UvHj-#Yst{D7q2NwIanwTnyj0Lg%2SgV$-O0J z-}00D(5_eF0}bV=yHip7l|z)IjuXD$&hi}DYx;}5?xT6u58Wbc2ABOB(h3kH_ZRWE zO7P7YAWVA)zB0{}_#23-=z~$&5@zfRI+>x=bMlaSHZzu+S7W(>>aM2wM7YFF3!gG< zHvTa@xLOtqT!gPNbPd|T157UqpJfrRg1G5DO=tiU>frnYZzc50cg=T2C!tJsnO=(c z&yKQzB+4+LEi`@P zCrRtHAxcGE4AhIdG(`bu+bBZNrSb-34Zbm3q`n2W+)ACQ^{m`Ni%MEY$_?;}xRmbW zy_rKDN2oLtKf|<%J1UkP^&hbd3tZ*y!r-m4B`>Zf?z!tKo;k%NH%eo!THdLi;;88> zWnjsqUfMt@nxQ^mJva@=dObLeXPrk2bmw@6_es@_@G?+R9UZ1^*ha`H6EYHETi9#J z)*cX#qhq6!BM^a?`%opO%25?8BH&M0NK8nl&+%WtGmW<;!6QXIaG|0?>c%bvpc|_; zkYcA;RmbcLe{kw{-M5jSbF|A=UOCK$x!bBgHmELja?F|eSKXEIT8E%~K*N<@G&D*ScYR=kKtdRb~f0&UuM z&s%QY!4xdw7pu9dMKRhREs5tsxgvQ(xnh1Yn_M}nz)kJ^?xcf!oI-JV(nYRZp`;?| zCRd)|DNK6El`m9Q@$CW{6<4XOWEW&KR;)!y({a(dRh0xG_u}(!Pu!eH3go^Gh7|9-=(vTxV{%W5^n}W z1|k?zmZ9KBHe<6`5vn0+TJEIu?_sI35K2RxVI=n4Egq^Ty(;vyE-C-BOW6>}$k7R8 zxTQR>qKwORuH$bHy1-n@)#c(rE~J{!Zkz%wck5#3OP)(&uNQv>_$%x!V&BDZm*B6o zw~T$4_g1jq%HAsWTMgYPl&+?C1N*J*tz*CS@N2+dV{a4tZic(1x0SiudN+dAWZXKt z)Q);VS4?lmr^KNLdpDtNo6&c~0NbMUBeAl!D*nXE+Q!;Hlra$aG_C=SIdX(1ncf{N z<>=3u653{ZJCU*-xj@HE?=HA$d`XW?7xbKzv9qSYIZS2}OI27XIyL+B3cRYlTT>(9 zBVQowqa>a>j{8L7Hb<}Mb^=WB20vb^k0&6alUae+{~cIS#! zzstw!M+A)4Z!C+O7I3{ZFFXS<8pgW;DGxkJkQRa3nkdjk(2DFySXgQ^y<)&NBs0P| zzlSzc)nLit8!O3{J)CLzGw9NkHv?Ey%^{={T;53*l`nU~6{4bPP!!P=#zD*1I!EK8 zZK8d!4sn_Mv9FG^%&KbWw|u1<>OzQxR@X>8ts1thrZKTBNQoSTRVs5mY+?QTvcRUO zTQW@Qr7gTELhpGQFtNa>5WfLge;vMM7%!|b4OE6ps7}WuFf9K~w1o_?5b%Ry=?&~n6H z^3~szjkwZaKaz(RlNrUX-X4zRt3LE3@*v(Qk$gBq+(OW_l`KYRZzESdSqzmS#&+fz zJl@sNs_Ivo5vkBY+?vom1bc+70rrTNTy|7{^0V+{E!-~O)BXrt_Oadg_+-$ z*1fe%mz^MR4vx-<^7=GQe<+ur`w?2_b0|vPgaC23oyK)HELFTsYh;MpqOKu{GC#eI z>?anIZm97V;+Pz%(+%{xv7VvD4fu^32fWA>b^wH2f!R4SrU5iuR&r%axkdUc{oHNaNW;*A>A34hJfjgnUM*5j4lA1@`RMmm*(3wNU@HXJa}g5QZZ}^vk*suQ6nux(Xhljy`Nq zvr#J74ui$O&vNX@3ZK4!09yFJk+NMNu^Bcks?J?X0UoBFHvo+)7( z405_Mh~zp+VJPtOV;Mb%8m4Wj+>a(rC=V&9_dKuH&4s_xvW|KyMB??cz;RU|rEEPi z;RkXpS((K`0T1vilcS=oHN z2n6GmW^{HPEY6Y&iic8+Cle_m7V%sQGM=QI%VS3^N_GbcK%HF_nn@5cy%{lc`7D1qlQS3K0bhi!-gG0 zz(;Q}WC9=e`yv&u!hylfQ=@Vi^51mk^}smEztIcMbCq* z6X+uri@V?z9K4`-aTgZ!Fo+TU;Y5CEUjw*jDDyBE!gQaM`?t<6&7+Oj78ak591NWz<9=E$7Zo1Oebr1S`o9^biwO2Zz4!8*%C-~sz7pVkpB1V($6%X>k zg);Y*r)Qsz6*R?N&7=dEu7q(Nz)gw{V6Qc2;lL*Xepb1F5?sj^b`{8G?G{%Gi>{uY zKb4Ck6a){t;d%vu;+R!G$_>91~-f zqti!V&76Z3EnetcX+OHwuV#15vU~cmxwe(sy)nz)=@WB%S4y|WEL(Bw?c7SqmY8J= zTxVA*cg8F`aWC$Lm8M5ymPe-#!^T%*qSoex zAYDUiPTE9kL(02>dpD4GRkW6(;6j^-TU_kcT0Xfw-0dNEkt$I}Z{z zwdxzyxFuKkPGP);6yAf6W*2d(tBxWSQtEQzso{si3V{i<<&B+%uD(bv{X*M9`w8}q zH)5b|Aq|D0l?d=8tggU%MR>(>RhSi~k3mF192PE{z)v?loB~ugqgsY*z?PTg4AJ_r>rAP1{WGOr$Lq8gSL~TM-3!~^rJqJZO#EQuwgdNF! z{m{r0fMOZKq$i*o3A~?UJPHfu%pIn24g4O?`=Mb#tO1s-$A{eMVkNIaE(x3b|66Z|U`TrS+PS zTwr)GJPD-~3OjFYDM~Gvl99D9+H=BmAy7|Qc;=TrIT4AssA-dt zVR4jcn(Z)te+_Zd;c-pNMxp@m>3q z92@1;=C;Z+T74hizh!y_=(QyD0@>@u+C%!?A&{x@hEfT^|2Oux1g!(M8DYl6Rsm-( zgm|Q^0TX;g_+-88?6t$kSWMI~N6uAN(%X?f2kD^=T=B_3m==n+f2h+1)RlbR4k%0^mcfg*-B>yr- zImPD@D@6HgokdY1oj-qPaa#4?=%()XoDk0V*jaVQTQa|M zen0M>#GG};gd|(Oe(BaRlbJdr$FCBlU8Z^VzASigg1Bjn;-up+r%*V zwQVBr$S=|+PB;Du+9bb(JXqE7pcsTJ1(~GzWa6F3pQWHyaxr3!%|b@IF>>SgDS&l0 zJKv_dKnR4-!G4K^puk$xz>CjGg0V-G37LS>zjWk5#{FafCSb82@qYTUuu@Polby6= zWtXg!mXSV*q?z0;t@JV;bKiB9{k;`_$$V3Gee~qt3;0ReP1z0FD|NVH5U=W>fCe5A z{4u#PAF~@+yX9X)sm=C8ma=OnvNeQk?=OQU}JU%T;ff4o7jOTI_won*q z>19Su;dF);ADI|O@~@Lcx$_A|%WfYQq(}JHSY!-~@@q)&Ds{pjbpn=_Ho=}d{o-HS zi|%?h%oQ(tHpD#}zS+6tX`8WOUtG4A#_grCvW{rua#=^btm6;N@8-OdvsAYGWBVSW zEuIp;evAlVp5N&pla_jj-m;o7*?BK#nu`Fvw|0 z0w9o6am3fsvr$u9j>ZBUm5)BSAUcZy=^={@k`N zO~&lX4WLs1k~E?c-@H1strNRhDV*2-B!bgebqC-PsWL2E#j%q)K^cuCEE-fRc>SL&gMG+JUzVaa7_(OHX|2(FTaorNj%3NjHow874+&m=Ajz z*$S?=b&AC7Z0rC!t0z**Xi285maErP2EEG{@j$>kG|_*~r<@sg`5uVRJ`kUam@%Fa zv+wd{Y;{{ua^`_?A!>s2#X9^XvXmp?w5dtRL!>AjjIboI6OI3y=FTM~1<6P9!R&0f zWb>`MNfTMoxIABhzmojr2b(ui0qw(!W zm+FqiYLDZN<=nw#@E;4BV&2w8I^XrQw51C_~EmhA{)>0aim^5%kh}3b{h;46a#88 z3xD?B>~+I)5bnUA6LMyTdGzK&A_>wlz;5sgb!yq5fm^$5V6$V|!uc9OJF==8kY1n- z`7Q$cqhG=@C1uwQLs=krVTej{J?Ei*75c^pe8lbse<6g21c*O_M-kY*4aI#yXknck zn_#j|!7+MAMAJpi?lV9Nf{WvDCF8Wg57N5?jr3duSHL{MwtZUM`V_A|AJt>cnwHV* zPhZqd$^TR`ON5c6%TfJPmi#|SP>W5io@V#@vyk>zM$vN$gw01f!jw~|BaCKZrz5{d z0kveMW^0sYD_Q@IX6sP|(rl$?%Ny8iU8!wbu00a31;75tG|mK$%v_8Xue5DnZhIo$ z_C(C`1abGDAnyJXbLSRHR=gF<-kovp&M%zcg;3VbmY%~sJ=@xc}Nu>a9aE>Vk)Dh~i|**<}lT=a6R0iSbYXx^!tvVlw%17E8><>nFm4 z!y%bCTe5?t&;->&GOZZ=h>dvN3G3)sPzteYH(({Qba@nm?%wfJH=@F2I&PO~DVIrl zHIYSX4WACkOvxdCZ1OAx5^k7qoqFbpL;eFt4;^^ySkDng^&~vJiGCk$yCbk$+{GQPL10nCPg`B?@^1m;XK_TU->3gg-xu1xFEo5#sA3UH5%hhb?E69m3$43raZPu>a_kGoX8OO_GcB&9 zKA~T+>{{8v0e*>o;ds2X<73OFY4NVv^2+{~_W!jd{|A;0Ke9C4x7ctNlz+YaTKRp* zRTq6y;C7m(?VtE8`KIaIWUfVY&EZxJ{RCF&Cz)#(i|3wXS9`=atT(Lj!iJ;(zs0Sq z^aGJ=v1YD@t8u)3`r7Guel66MiZzR793_c0I5TY9wBjvU>D;pd>2!CQXj}1ACC&J~ zix=nVzDNK3{-hP(KzUucR}Rk}p4%D~ujgFLSva<^`<6)L>+P-YxMQ{Z<0X&8ypP14 z-N`J9ZxU^i&IOV@lo-fKsL@u#fpWRq=27Aag}}$(PVw4{0rsFVqsh?{IThvS?odYvY%D6 zV1m#*bN{%rG{Pqs4N+CR1%DUo~^SE$NtRd)YsTe!yM zBvtu+=RUeyv^<{8U%4fnbMAS3=iGC?_xbv-eLfF|XTtN`NbLcR`ycdTJTASk`k|HM zu5qV0ksIJdUbMvc0iNZS0Sn8m12*K=n0?eS;NYo`4Q1zmla=i;*Qk5I&B~6LXVg33 zWo2iqWYjm{V`Uf0r30lXyG2jTKN=Vau(CH+Hd;PV&dMdRiqXn}N>=uvTs2U|a~4jr zo!M?IIhTv2sPD+V8zs??`d!9bE+4kk;pLsc4U1McP$!lR)B}3M4ZYLA28`^=jW9}5 z6OEKMiscU?FBl>Go)Hx^LaY?4PFn^xiPd5a@@BDCtV7-+InF$4%#q6hzjcHY>;H_u z!E3d{7W8~P*TX33JsZ~a>@(VPx!!X_K~JY%+n8TFY#V69H=W3hHA?H&_8UENIrcMD25E)FFw z3bF9GBn!#Y;iMqNm6R+gLMpC=hb18~CduJsG!a*XNH`u(B!wYKK;3Xc9+kun&nZP3 zPQ`=^r=>W?OF~i_9gBsNk`PTQQfyd=Bt`*jSWb)z;W&UM<&=_?L_tZUSTu=Nf3Fe=k4gCh z98ZMhv#GJaCz?PHZ*Tm3R8GW4r8o`nos=ReIhq{rmE{D%clIRWN$DcBxlhGKX*e2} zM3q0%feQOjA{7^-bAQZpYW=Cclif#pLq|^a_4FS*-WTfb?>}+u(5e33lWMKr_C#<0 zqsI^Dx41^4p%*y7Qr<{g=TIHtu`wwws!mxtFUg9eI-+q!l9Q@UNg#D#*U&6CQg651 zOyE4)keD=_)F#=&YPFuM)|{2S(O4`#k)%)Zg+^1!@KB77SBhYx!m${=($^(Zay+85 zIgH^rJN}6#+{adX@m9qrM@eDYcyW~Esewis+*E}i7g7=q7i2b1Q{ z^D;lqp_K{Dye1Sc@p&uZlO;y03Dq*mpXA25prtQpQ5_m`s~#;6jfTg9PSq1tu+hmd zPFuAn$Hyc^^*kXZPbb8Fyr^Y|Qqfp48qce8g*37VsVEWgg+i)TNy+a#53K39FC8G@e%U`i`<$NMx;0~O-XA}gbUH+X(24cr1%I5 ziD6+hA+rH-kAUZi?r(=qboU+Y1<#a5l@3-p@yH1cY$72HMMpY>elS;qT@S?)k+X^c zK88)uxOY4cR@;On*b%g;cD6j#irH1SIhE==4r(5bB`#V-LQFf+uVt) zmG=c#tyaG$%URu?tcNS{Uw%w}fPnME1;k9KNyoEViR2ncY?2G1q&<@yw%aoCUE=Es zHgh-?kC0dr60!hZ2eJ^thS2Kpur2K9fb zKAz8-@|k22CTGGaD}Aw{_TRuAg6bPC~Uck2%VXudFs2@s%ThLNb#*xs{2zd0O(=e*W6)jZwM0U=|XG z?7=L1*O|p;j#zJ&CIdcF(2!5lDfP6kOMWC79)B1gd#{R9$!DNPsEmn!8{KAl6b(OtwXx&~i3 zsfjO1%u@|JqDqJ{Jo5tv2`+RhS&oXL6xTV+Lk~TqskE9X>@fIpbaV_l5r%|}9SNC` z*yJ>@Xlonf^md_nR8BMpSx?%JZ!{zY^-R_W9SO%2ZB)N%1uWIqlaLcBs0k8N8p^ws z@p$B@CY};9tFwec!E$*wFhIT!iCS_*=d9E!6V=IkC?Wo(+LEMuxO%`=*{@k`4y^m+vwc0Gq98rcoaCfJk{9X^F<6<5=K|SQRrDm}XVLEk>iY!}h`CzMRSxAN zwOkX-)C8BD?JHjYQpJv2-W@9yHMiXrGd-_YE!PDzb-^XK-j?z1Sg2e&@Kk2^Q)Zva zC3h1>&UF6Zpjp@YM#uGzcUqU*4`$jA{wnpsi|@aft~_Zu^pZ2b;Ac zG-Wj-Q{ne@EgHL7-KDo5xse3x5YiaB++gDuPS57VaS~I>@Xj^+6 zSqE1VSgP2Y@$LmY47>91^ux1z7rjE-CNQZ~Ac{;qo5UPM5mN0r%zdYZ& z&C{;9NmGYb_*W_>`AO?}E@I&!#%c0r6rkivi=l|Zv1sYFI;Bq7739ZSHBi;oE1hkBrsB~mdFiWm%} zap+wP5GE#xPG+r1daOrOQbK3ri3@SVHfekQ5~!7#WyR?A>js^b#+7@>mH5IsgZ{~P zFq39b{Q*<4QBhd37YpWMpLNXmOkFW0vs?ii0qcTcuCdka!r&m|CWDLvYHa$OY)tcT zBGHT$7iUXHK#bdfIgH-~Z8^eJUBp?)h+rC%LRt-}U79jgU3_ok=g{kC_*aO1fmF9} zjqRUv7JGBXRXgRH*#e7WCNjJKzj`+V$!GV?JansMQ`U}lLjN)i%`wt^483JF4TS$b z5MAQn+2jT+@OAP7R?#wGlk8`VUgj`(`|QQE7t|KfT2Na=TS09RT?DnJ29lc&wY9l7 zqa<2icMkZZ(lbT$04ad_W}{~=NA2d^n^7uWJ7Otbule6}FI+FZ_CHAf} zs_5FJ79FP@VguH)dEK>az`p%sAvXeY>+gZw0*`SM`fYJ@;udiuW+RL$;;~<6j|Khf z3E$SEt|DinkJ^M$PZrtfqMQW&?V@|B!6G`sP6dD+%`e*rf?^A>ZgcSwe>l|?hl9Du zE8jlFUE~M0!J65sRu)tG!{j8+^R7S!=9vyKFODUlEs)nC7ClS$3;a6LND5w;{C-eS zG$kS_#bS!Cb&QThW8|4hJ;Wv&}L%v{P_ zk1!e@Hw+SOF`D;-ri25EX4jSoS9^3+f@40ct;^J>09rN;Fqm&}MKMo5RvC^&Bn1vA zLrtJ>H68je{ID#u7mPlIyy&D|i4rulF6m;VYp}qxPPzkwC5NL5vUuY^X8pO-V3dRLS%-S%Bd{E7I;Pv>m`c=7Xfq zi-c1nr<0mrtv~4eir@AXzeDBQzv6dJSa#yS9mQ6)Lic=!hNAJrSco~Hp|6k+N*+X_ zmKz;XX1iL>EIs-HNz?`^YFU0A^;Ij|`0IaXT^+o!%AOEZW1<9ZA`Ocnc z>m>K8jr^5S=+r;wf5h`#&MOK3v+3Z$Q2h~k5>t%`RJ-NMx zGt)+%IkuVdX=-(cLX2ME@5UC9#(0@&jPhB$O*9rG_YPwf{|8+Z;%{HVHSO|EJE1hr zZce*`b6ak?g13eCDchBj>5`deGOoszhK-S~q_bt}%pR&E`&pGv&&8gbYhhr%zLJKq=DqHctdI-rioa-6g>0)%CTr@q@ z7kQ-wr%of-18d5(u1c6=H2mz>F)=9mpbDZH&`dlcwpg!HSUIiQi!z3^H(BX zBiG81$~N&2J!FyV26-VCKv)^x?+)S6xQPTtW$ygfoH0Y8R6GVjgF(Oo9Jr|AhJGxX z=X_8XL$v?QO~6Ekj1eR8=mbe3h=Idra7h9zPQ>Ai)UE@D$prw9*NBPEgUp-Q5stx0 zsf2KE8Ws);%-@JP2s}OV5p35H)tlFg?uADrTuQPlH1os@d`JP~^o;MGX#LtlHoAeF zIfaZNSgirhS2@#@u4|v~T`alpR>`-2IdU`d;lcEYXBPK;J8QKBaCKsFd)QH{PJAof zRI4uSW%uE<%#TcuX!s@etQw@_?rsZF%`53w4>aPMR)eC`{Whfuu<>4gS=vx$_O?Rl~%RI)#l|jvuNxRFqjzL$%NTiF<9q8ccj#CQ5 z?V$OW4L6T5iQ(PF#hQ6k2ta_RS0uqt_w+(CMG3HBNID%pAH~W5EP^ZQa1_@=`f3fW zhE{`%A?P3qDP3^tid|j8eI5Hu@VLy0V|Q>t&W?NnW%+qZCMmguM4?S4Ksu>=XeTt` zKe4gs@#i|!(7}@~&hCN&?NiBR|Hh1e7Lh(HoeI9(JBztUb@vH$6_K!um0-S4{8_JzV zgeSR{Jm+fej%nDknUhoC*Cu&ST5>mg<}J^Vo6B8ZLq*V!|B@B;Zp_IZa>W`WF4@2m ziYSD%9ug)sS{YqZs!*n!)w9b{nAD zD1s>HQQdS~!S29S@8gLCVusj@b|G><=9Di|l0u>e^lM*IV6+IK(r)8EOatNWHH;b6 zZT2!a2~!vTh@jC`gr+mB;Upw)C-E7;>dzSodSxZS7-W!@`FTQqg=5W^Ktir3Xb>2GPzbM={ zYtOp44Z?E6?o7k(g_ebjA66|j99?N?`_so)HnuEp+?(0Bcj4sCw#AJ-w`zO7yzAvQ zz|+cCHGWdN0ayH0jsFW(wVO~?R`*F|Evm}u{&&_*YxpYL#04s^yfFR3T+95UQ!gy~ zJJYUCr622m$>!v~zwwaQ`j)r*faTwnbhleRsKV<<)#a47ySw+SJZd*-#Wb68x9W`IHM%jWVGU)hLy2oB5~c^MebLLwlB+eZ=6*G^%9xTP6S;s)01z=E{oe{iK{!%PV-2$n0_G8N$8^U=kM{pphZU*0X_0!^QDHg{Fl zV)a$6)YQ)&xcb7aK&Mq!HwQuA5)+~@BtDG->_)D* z-8gA^%_3Uz?L|Wr6pMvJU+YipVEB2#BJbF4*f0eiuvh!U?h`Ebj(Drd)=Vx7g-c_M zIowb>CMq>&5_1@tC^KOr-E5-V7z<5M8`=@H%72X6v{)D`d_q75!U>sT$K*~*NKT=f zsff#T#tLnRp@}ifT1Nw4%ezk!mh@uqW$uo@g4okaY4hBHxgA-K-xatWsGK?ZWA}2P zITL73`&-kk_tP04xKmcY5~#QxXv}(n8>^gylyirnobyVD>O~9#LRCYg?G|X`rqJ)g z%!P(oPS6{SL$1ve^#Rfv#t6hz2bL?=0ZFIh#`CCjA!422M^c?#L; zC5MGengTx;p*QI;z6jXpp7yAB8`Vt#BHJ zk<+Z&Lz+81x*G(ZNaj05L^5-5B;kkElm-Bg6JulM2Ij*>agMLSJakAb@VHOjh0l^n z!jrl8Mvh_L=O;J~!4=1Qt(!mn2^d4=1xyA~>MhCev{{^_OK zqtnNJTiZUrcd>TY)Ui9>>a@3c?)l}d4`jAJaC7q3)^FYRm(T3|;rML#4_c~n( z)zslTzUpOPQ^wacdv0#?ykpU~bIP*fuYM&t)BVE>Gx86gPrK?hUA-w(?Bn2J)GhA% zb=skA7BFcdbmq+cw~Av9x{4y5cRJdU&OxZnrh=)x3;S+%E>?7>OS+-^2CA3+TQdGFbEzf& zj@#uM=Q`(t>1~J7LeFCP;dII26@TN@I7x|FDedo^6L0xD=Z7;)m1WrTHs2TA&ZtoJ zghGf{NFjnfq?Uw2=ThMq`?*3$b%sJ>B7$nSVpt`bYoQj)MXYve2w_{PnCir@BqT9< zUUeZtHz89A0sa@zm=HC0Igj}J!w7hh$wWaw7QUMW$y>YQ5ccDDZ% z?=mI7q6Qy?``Pc&gp8Z|>`~?l# z{0o`Q52ZIgl&O7qm9yF%pKal`ciwnF8|A(3o$JZewk_KBeb&Tn+k0bM+Ez7l?%MNL zpP$>4soA<{>&)70_5-uwH>B%QmP2v=+%HmZr&#f3F!K88`<$F^0LXUpAo4;I?{W^a~5ab8@dEL-ii-@j7Rl(kaczC+79_q})O-BVh* z=kRYjKk8)VJ8sXFs_Cj#JNjm;o%W8o8k(eIp@(I;X*)jV|Hl4TcAB{(TV7?~w^C7g zt@A3NPRb8!`b*IZVW!%lHcC=(W{Pz22 zcfZkjy)(<9IDe953s1fG%)8IreCmT!@1OecSo+`-na;jdYR@*iavzK0LL`fW^xTZn zd3s=vKJf5o-UfTa9dBvYjvV1Y{=k)y>5-Z6HR-A}dvfMXrgT%*Nlh-Uto)kes$)i( z?S7;8dhg5xG{UT#njmRvt_@rrnB(8_yy=4f)_y8;_0ZF?hu|@WkRX z?5f;QdG5I~A1pR%kZ#WfF#%l(LWSvPaNCYXlX_5GME?aEA_1A7w`eRNf`};)a1fzu z;B3giVi~AGiVVaQpKENhkW%K1Eymw@FG1*O=KKv43r>|gw!uT$yqhA^J~xP z-bm*kli1vfkze9E)L%J$f%!7$#f9D_f7ePy?QbiB^DXnq#frUY|K7A~FGEFWt;{t0 zIW6U1Qu41TA;m|2mlEbddyh)AD4CpAGGpzSjnjGlf1*lCUZo}ML*dJp!Sk))`5v3S z)8KF@5`#l#Fd7s;w*8K3KBGh<4gyp_90uyI{sUSHi9>?zvJL@QMVlUqWd{K`M2F-Q zo#<;iE&)t`ibG%_F9f~Z=$FeSf@G{KSIy~xH&(P33kEDY287D)ZxHn5Lb!{Uk!lIq zN%AZ}t5yV$X!`yRy!PD_)=LW7D!C>IZ-I$IbCDC2OM6M^HoiH2p z>e+e8HR+TaF;Z98StmU?L*~?)XVNk0GKl?>*oG}9Ir(Sk z1qMNyvg(GHIK)B@(5E zd{m)z;K;N`i^gRWupQ6y!{ttorf02h(D4zIf+FtVYIZNwFIGP|?VYkuC09zzuf(V0 zv!~_`&u>{Q-3|4;o_X4KO+Pkubmpl~{M9Sf_1B_Tqs!G>Gu5Q7KebrB^Q!eu(OUAl z?SkA4RLt~FO{86Q8gufkWlltLdCZ9rP*H z2<%VkD~Y**X=N=Id&}&%a9wL}S=jwv=etl>P`ugy1!ZtX+Ur;98?#o*TemO;lqrpw z)_q##Bi+Aof8_qS<>PaIllrUF$L*O%poO7#p=xBE!S5tD{LYRBjpxx~3V0sY#GX~s z+H+yd6n8IQLscKd%NoW_gsee3KqczMl6UC)NWi?zt=L>z4{8h^(0Dz&8YTXrIuOE5 zJ4f7K^+pniq-Q_TQ)D6?ndn1xXnq8l0Ky#7-x%I{M%hoc$)c2rZe-GGRBvAFn@s1Y zdU63{nsw=vwOBWqnJ8qDs7|`oc{(i13j~NsqEae7LXB23e29;$Rx)|+r-nbLq>K`} zmyn;P#7GrsGx`;Yflrgy%oESa{p2 zi{k@-%a!~sSN)?VW0|_0OSWB?d1$M?ip%cL99;X38&zqpUeko@ERK%dYy2s~(NF%6k`GN3wRZrT*>i84zkYr${Fd~lbp6tN_!np2K6|qz)4^=E znukBENY@VmP0nvy-HcOzM0>IHKeYmvK)%@JuF)|yh?A`$M|Z# z3}%J>O?#F@kqjPW3;nB<-Mz2R%I}+f;4Vk`-64mE?@Vvre;0r|@7DYI`q{d>9J0Hc SdETAgxO?H@FF2GK?fzeJJJK8g literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67c8ed214a0eef12951cba1fe0c77afa91ef6d3f GIT binary patch literal 9040 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 literal 0 HcmV?d00001 diff --git a/.python/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc b/.python/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db3025508c703597713fc283471052dfa65568c8 GIT binary patch literal 34521 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 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 # type: ignore[attr-defined] + 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 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/.python/lib/python3.12/site-packages/jinja2/bccache.py b/.python/lib/python3.12/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..ada8b09 --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2/bccache.py @@ -0,0 +1,408 @@ +"""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/.python/lib/python3.12/site-packages/jinja2/compiler.py b/.python/lib/python3.12/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..2740717 --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2/compiler.py @@ -0,0 +1,1960 @@ +"""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: # noqa E721 + 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 async_exported + from .runtime import 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: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + 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/.python/lib/python3.12/site-packages/jinja2/constants.py b/.python/lib/python3.12/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/jinja2/debug.py b/.python/lib/python3.12/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/jinja2/defaults.py b/.python/lib/python3.12/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/.python/lib/python3.12/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/.python/lib/python3.12/site-packages/jinja2/environment.py b/.python/lib/python3.12/site-packages/jinja2/environment.py new file mode 100644 index 0000000..1d3be0b --- /dev/null +++ b/.python/lib/python3.12/site-packages/jinja2/environment.py @@ -0,0 +1,1675 @@ +"""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 # type: ignore[attr-defined] +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] +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[t.Any]", 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.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: # noqa E721 + 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) + + 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") + + @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 = "