#
tokens: 45648/50000 2/808 files (page 80/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 80 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .DS_Store
├── .venv
│   ├── __pycache__
│   │   └── hello.cpython-312.pyc
│   ├── bin
│   │   ├── activate
│   │   ├── activate.csh
│   │   ├── activate.fish
│   │   ├── Activate.ps1
│   │   ├── flask
│   │   ├── normalizer
│   │   ├── pip
│   │   ├── pip3
│   │   ├── pip3.12
│   │   ├── python
│   │   ├── python3
│   │   └── python3.12
│   ├── hello.py
│   ├── lib
│   │   └── python3.12
│   │       └── site-packages
│   │           ├── beautifulsoup4-4.12.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   ├── AUTHORS
│   │           │   │   └── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── blinker
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _utilities.cpython-312.pyc
│   │           │   │   └── base.cpython-312.pyc
│   │           │   ├── _utilities.py
│   │           │   ├── base.py
│   │           │   └── py.typed
│   │           ├── blinker-1.8.2.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── bs4
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── css.cpython-312.pyc
│   │           │   │   ├── dammit.cpython-312.pyc
│   │           │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   ├── element.cpython-312.pyc
│   │           │   │   └── formatter.cpython-312.pyc
│   │           │   ├── builder
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _html5lib.cpython-312.pyc
│   │           │   │   │   ├── _htmlparser.cpython-312.pyc
│   │           │   │   │   └── _lxml.cpython-312.pyc
│   │           │   │   ├── _html5lib.py
│   │           │   │   ├── _htmlparser.py
│   │           │   │   └── _lxml.py
│   │           │   ├── css.py
│   │           │   ├── dammit.py
│   │           │   ├── diagnose.py
│   │           │   ├── element.py
│   │           │   ├── formatter.py
│   │           │   └── tests
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── test_builder_registry.cpython-312.pyc
│   │           │       │   ├── test_builder.cpython-312.pyc
│   │           │       │   ├── test_css.cpython-312.pyc
│   │           │       │   ├── test_dammit.cpython-312.pyc
│   │           │       │   ├── test_docs.cpython-312.pyc
│   │           │       │   ├── test_element.cpython-312.pyc
│   │           │       │   ├── test_formatter.cpython-312.pyc
│   │           │       │   ├── test_fuzz.cpython-312.pyc
│   │           │       │   ├── test_html5lib.cpython-312.pyc
│   │           │       │   ├── test_htmlparser.cpython-312.pyc
│   │           │       │   ├── test_lxml.cpython-312.pyc
│   │           │       │   ├── test_navigablestring.cpython-312.pyc
│   │           │       │   ├── test_pageelement.cpython-312.pyc
│   │           │       │   ├── test_soup.cpython-312.pyc
│   │           │       │   ├── test_tag.cpython-312.pyc
│   │           │       │   └── test_tree.cpython-312.pyc
│   │           │       ├── fuzz
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│   │           │       │   ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│   │           │       │   └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│   │           │       ├── test_builder_registry.py
│   │           │       ├── test_builder.py
│   │           │       ├── test_css.py
│   │           │       ├── test_dammit.py
│   │           │       ├── test_docs.py
│   │           │       ├── test_element.py
│   │           │       ├── test_formatter.py
│   │           │       ├── test_fuzz.py
│   │           │       ├── test_html5lib.py
│   │           │       ├── test_htmlparser.py
│   │           │       ├── test_lxml.py
│   │           │       ├── test_navigablestring.py
│   │           │       ├── test_pageelement.py
│   │           │       ├── test_soup.py
│   │           │       ├── test_tag.py
│   │           │       └── test_tree.py
│   │           ├── certifi
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── core.cpython-312.pyc
│   │           │   ├── cacert.pem
│   │           │   ├── core.py
│   │           │   └── py.typed
│   │           ├── certifi-2024.8.30.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── charset_normalizer
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── cd.cpython-312.pyc
│   │           │   │   ├── constant.cpython-312.pyc
│   │           │   │   ├── legacy.cpython-312.pyc
│   │           │   │   ├── md.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── version.cpython-312.pyc
│   │           │   ├── api.py
│   │           │   ├── cd.py
│   │           │   ├── cli
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __main__.py
│   │           │   │   └── __pycache__
│   │           │   │       ├── __init__.cpython-312.pyc
│   │           │   │       └── __main__.cpython-312.pyc
│   │           │   ├── constant.py
│   │           │   ├── legacy.py
│   │           │   ├── md__mypyc.cpython-312-darwin.so
│   │           │   ├── md.cpython-312-darwin.so
│   │           │   ├── md.py
│   │           │   ├── models.py
│   │           │   ├── py.typed
│   │           │   ├── utils.py
│   │           │   └── version.py
│   │           ├── charset_normalizer-3.4.0.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── click
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _compat.cpython-312.pyc
│   │           │   │   ├── _termui_impl.cpython-312.pyc
│   │           │   │   ├── _textwrap.cpython-312.pyc
│   │           │   │   ├── _winconsole.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── decorators.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formatting.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── shell_completion.cpython-312.pyc
│   │           │   │   ├── termui.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── types.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── _compat.py
│   │           │   ├── _termui_impl.py
│   │           │   ├── _textwrap.py
│   │           │   ├── _winconsole.py
│   │           │   ├── core.py
│   │           │   ├── decorators.py
│   │           │   ├── exceptions.py
│   │           │   ├── formatting.py
│   │           │   ├── globals.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── shell_completion.py
│   │           │   ├── termui.py
│   │           │   ├── testing.py
│   │           │   ├── types.py
│   │           │   └── utils.py
│   │           ├── click-8.1.7.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.rst
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── fake_useragent
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── errors.cpython-312.pyc
│   │           │   │   ├── fake.cpython-312.pyc
│   │           │   │   ├── log.cpython-312.pyc
│   │           │   │   ├── settings.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── data
│   │           │   │   └── browsers.json
│   │           │   ├── errors.py
│   │           │   ├── fake.py
│   │           │   ├── log.py
│   │           │   ├── settings.py
│   │           │   └── utils.py
│   │           ├── fake_useragent-1.5.1.dist-info
│   │           │   ├── AUTHORS
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── flask
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── app.cpython-312.pyc
│   │           │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   ├── cli.cpython-312.pyc
│   │           │   │   ├── config.cpython-312.pyc
│   │           │   │   ├── ctx.cpython-312.pyc
│   │           │   │   ├── debughelpers.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── helpers.cpython-312.pyc
│   │           │   │   ├── logging.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── signals.cpython-312.pyc
│   │           │   │   ├── templating.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── typing.cpython-312.pyc
│   │           │   │   ├── views.cpython-312.pyc
│   │           │   │   └── wrappers.cpython-312.pyc
│   │           │   ├── app.py
│   │           │   ├── blueprints.py
│   │           │   ├── cli.py
│   │           │   ├── config.py
│   │           │   ├── ctx.py
│   │           │   ├── debughelpers.py
│   │           │   ├── globals.py
│   │           │   ├── helpers.py
│   │           │   ├── json
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── provider.cpython-312.pyc
│   │           │   │   │   └── tag.cpython-312.pyc
│   │           │   │   ├── provider.py
│   │           │   │   └── tag.py
│   │           │   ├── logging.py
│   │           │   ├── py.typed
│   │           │   ├── sansio
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── app.cpython-312.pyc
│   │           │   │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   │   └── scaffold.cpython-312.pyc
│   │           │   │   ├── app.py
│   │           │   │   ├── blueprints.py
│   │           │   │   ├── README.md
│   │           │   │   └── scaffold.py
│   │           │   ├── sessions.py
│   │           │   ├── signals.py
│   │           │   ├── templating.py
│   │           │   ├── testing.py
│   │           │   ├── typing.py
│   │           │   ├── views.py
│   │           │   └── wrappers.py
│   │           ├── flask-3.0.3.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── idna
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── codec.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   ├── intranges.cpython-312.pyc
│   │           │   │   ├── package_data.cpython-312.pyc
│   │           │   │   └── uts46data.cpython-312.pyc
│   │           │   ├── codec.py
│   │           │   ├── compat.py
│   │           │   ├── core.py
│   │           │   ├── idnadata.py
│   │           │   ├── intranges.py
│   │           │   ├── package_data.py
│   │           │   ├── py.typed
│   │           │   └── uts46data.py
│   │           ├── idna-3.10.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── itsdangerous
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _json.cpython-312.pyc
│   │           │   │   ├── encoding.cpython-312.pyc
│   │           │   │   ├── exc.cpython-312.pyc
│   │           │   │   ├── serializer.cpython-312.pyc
│   │           │   │   ├── signer.cpython-312.pyc
│   │           │   │   ├── timed.cpython-312.pyc
│   │           │   │   └── url_safe.cpython-312.pyc
│   │           │   ├── _json.py
│   │           │   ├── encoding.py
│   │           │   ├── exc.py
│   │           │   ├── py.typed
│   │           │   ├── serializer.py
│   │           │   ├── signer.py
│   │           │   ├── timed.py
│   │           │   └── url_safe.py
│   │           ├── itsdangerous-2.2.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── jinja2
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _identifier.cpython-312.pyc
│   │           │   │   ├── async_utils.cpython-312.pyc
│   │           │   │   ├── bccache.cpython-312.pyc
│   │           │   │   ├── compiler.cpython-312.pyc
│   │           │   │   ├── constants.cpython-312.pyc
│   │           │   │   ├── debug.cpython-312.pyc
│   │           │   │   ├── defaults.cpython-312.pyc
│   │           │   │   ├── environment.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── ext.cpython-312.pyc
│   │           │   │   ├── filters.cpython-312.pyc
│   │           │   │   ├── idtracking.cpython-312.pyc
│   │           │   │   ├── lexer.cpython-312.pyc
│   │           │   │   ├── loaders.cpython-312.pyc
│   │           │   │   ├── meta.cpython-312.pyc
│   │           │   │   ├── nativetypes.cpython-312.pyc
│   │           │   │   ├── nodes.cpython-312.pyc
│   │           │   │   ├── optimizer.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── runtime.cpython-312.pyc
│   │           │   │   ├── sandbox.cpython-312.pyc
│   │           │   │   ├── tests.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── visitor.cpython-312.pyc
│   │           │   ├── _identifier.py
│   │           │   ├── async_utils.py
│   │           │   ├── bccache.py
│   │           │   ├── compiler.py
│   │           │   ├── constants.py
│   │           │   ├── debug.py
│   │           │   ├── defaults.py
│   │           │   ├── environment.py
│   │           │   ├── exceptions.py
│   │           │   ├── ext.py
│   │           │   ├── filters.py
│   │           │   ├── idtracking.py
│   │           │   ├── lexer.py
│   │           │   ├── loaders.py
│   │           │   ├── meta.py
│   │           │   ├── nativetypes.py
│   │           │   ├── nodes.py
│   │           │   ├── optimizer.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── runtime.py
│   │           │   ├── sandbox.py
│   │           │   ├── tests.py
│   │           │   ├── utils.py
│   │           │   └── visitor.py
│   │           ├── jinja2-3.1.4.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── lxml
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _elementpath.cpython-312.pyc
│   │           │   │   ├── builder.cpython-312.pyc
│   │           │   │   ├── cssselect.cpython-312.pyc
│   │           │   │   ├── doctestcompare.cpython-312.pyc
│   │           │   │   ├── ElementInclude.cpython-312.pyc
│   │           │   │   ├── pyclasslookup.cpython-312.pyc
│   │           │   │   ├── sax.cpython-312.pyc
│   │           │   │   └── usedoctest.cpython-312.pyc
│   │           │   ├── _elementpath.cpython-312-darwin.so
│   │           │   ├── _elementpath.py
│   │           │   ├── apihelpers.pxi
│   │           │   ├── builder.cpython-312-darwin.so
│   │           │   ├── builder.py
│   │           │   ├── classlookup.pxi
│   │           │   ├── cleanup.pxi
│   │           │   ├── cssselect.py
│   │           │   ├── debug.pxi
│   │           │   ├── docloader.pxi
│   │           │   ├── doctestcompare.py
│   │           │   ├── dtd.pxi
│   │           │   ├── ElementInclude.py
│   │           │   ├── etree_api.h
│   │           │   ├── etree.cpython-312-darwin.so
│   │           │   ├── etree.h
│   │           │   ├── etree.pyx
│   │           │   ├── extensions.pxi
│   │           │   ├── html
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _diffcommand.cpython-312.pyc
│   │           │   │   │   ├── _html5builder.cpython-312.pyc
│   │           │   │   │   ├── _setmixin.cpython-312.pyc
│   │           │   │   │   ├── builder.cpython-312.pyc
│   │           │   │   │   ├── clean.cpython-312.pyc
│   │           │   │   │   ├── defs.cpython-312.pyc
│   │           │   │   │   ├── diff.cpython-312.pyc
│   │           │   │   │   ├── ElementSoup.cpython-312.pyc
│   │           │   │   │   ├── formfill.cpython-312.pyc
│   │           │   │   │   ├── html5parser.cpython-312.pyc
│   │           │   │   │   ├── soupparser.cpython-312.pyc
│   │           │   │   │   └── usedoctest.cpython-312.pyc
│   │           │   │   ├── _diffcommand.py
│   │           │   │   ├── _html5builder.py
│   │           │   │   ├── _setmixin.py
│   │           │   │   ├── builder.py
│   │           │   │   ├── clean.py
│   │           │   │   ├── defs.py
│   │           │   │   ├── diff.cpython-312-darwin.so
│   │           │   │   ├── diff.py
│   │           │   │   ├── ElementSoup.py
│   │           │   │   ├── formfill.py
│   │           │   │   ├── html5parser.py
│   │           │   │   ├── soupparser.py
│   │           │   │   └── usedoctest.py
│   │           │   ├── includes
│   │           │   │   ├── __init__.pxd
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   ├── c14n.pxd
│   │           │   │   ├── config.pxd
│   │           │   │   ├── dtdvalid.pxd
│   │           │   │   ├── etree_defs.h
│   │           │   │   ├── etreepublic.pxd
│   │           │   │   ├── extlibs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── libcharset.h
│   │           │   │   │   ├── localcharset.h
│   │           │   │   │   ├── zconf.h
│   │           │   │   │   └── zlib.h
│   │           │   │   ├── htmlparser.pxd
│   │           │   │   ├── libexslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── exslt.h
│   │           │   │   │   ├── exsltconfig.h
│   │           │   │   │   └── exsltexports.h
│   │           │   │   ├── libxml
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── c14n.h
│   │           │   │   │   ├── catalog.h
│   │           │   │   │   ├── chvalid.h
│   │           │   │   │   ├── debugXML.h
│   │           │   │   │   ├── dict.h
│   │           │   │   │   ├── encoding.h
│   │           │   │   │   ├── entities.h
│   │           │   │   │   ├── globals.h
│   │           │   │   │   ├── hash.h
│   │           │   │   │   ├── HTMLparser.h
│   │           │   │   │   ├── HTMLtree.h
│   │           │   │   │   ├── list.h
│   │           │   │   │   ├── nanoftp.h
│   │           │   │   │   ├── nanohttp.h
│   │           │   │   │   ├── parser.h
│   │           │   │   │   ├── parserInternals.h
│   │           │   │   │   ├── relaxng.h
│   │           │   │   │   ├── SAX.h
│   │           │   │   │   ├── SAX2.h
│   │           │   │   │   ├── schemasInternals.h
│   │           │   │   │   ├── schematron.h
│   │           │   │   │   ├── threads.h
│   │           │   │   │   ├── tree.h
│   │           │   │   │   ├── uri.h
│   │           │   │   │   ├── valid.h
│   │           │   │   │   ├── xinclude.h
│   │           │   │   │   ├── xlink.h
│   │           │   │   │   ├── xmlautomata.h
│   │           │   │   │   ├── xmlerror.h
│   │           │   │   │   ├── xmlexports.h
│   │           │   │   │   ├── xmlIO.h
│   │           │   │   │   ├── xmlmemory.h
│   │           │   │   │   ├── xmlmodule.h
│   │           │   │   │   ├── xmlreader.h
│   │           │   │   │   ├── xmlregexp.h
│   │           │   │   │   ├── xmlsave.h
│   │           │   │   │   ├── xmlschemas.h
│   │           │   │   │   ├── xmlschemastypes.h
│   │           │   │   │   ├── xmlstring.h
│   │           │   │   │   ├── xmlunicode.h
│   │           │   │   │   ├── xmlversion.h
│   │           │   │   │   ├── xmlwriter.h
│   │           │   │   │   ├── xpath.h
│   │           │   │   │   ├── xpathInternals.h
│   │           │   │   │   └── xpointer.h
│   │           │   │   ├── libxslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── attributes.h
│   │           │   │   │   ├── documents.h
│   │           │   │   │   ├── extensions.h
│   │           │   │   │   ├── extra.h
│   │           │   │   │   ├── functions.h
│   │           │   │   │   ├── imports.h
│   │           │   │   │   ├── keys.h
│   │           │   │   │   ├── namespaces.h
│   │           │   │   │   ├── numbersInternals.h
│   │           │   │   │   ├── pattern.h
│   │           │   │   │   ├── preproc.h
│   │           │   │   │   ├── security.h
│   │           │   │   │   ├── templates.h
│   │           │   │   │   ├── transform.h
│   │           │   │   │   ├── variables.h
│   │           │   │   │   ├── xslt.h
│   │           │   │   │   ├── xsltconfig.h
│   │           │   │   │   ├── xsltexports.h
│   │           │   │   │   ├── xsltInternals.h
│   │           │   │   │   ├── xsltlocale.h
│   │           │   │   │   └── xsltutils.h
│   │           │   │   ├── lxml-version.h
│   │           │   │   ├── relaxng.pxd
│   │           │   │   ├── schematron.pxd
│   │           │   │   ├── tree.pxd
│   │           │   │   ├── uri.pxd
│   │           │   │   ├── xinclude.pxd
│   │           │   │   ├── xmlerror.pxd
│   │           │   │   ├── xmlparser.pxd
│   │           │   │   ├── xmlschema.pxd
│   │           │   │   ├── xpath.pxd
│   │           │   │   └── xslt.pxd
│   │           │   ├── isoschematron
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   └── resources
│   │           │   │       ├── rng
│   │           │   │       │   └── iso-schematron.rng
│   │           │   │       └── xsl
│   │           │   │           ├── iso-schematron-xslt1
│   │           │   │           │   ├── iso_abstract_expand.xsl
│   │           │   │           │   ├── iso_dsdl_include.xsl
│   │           │   │           │   ├── iso_schematron_message.xsl
│   │           │   │           │   ├── iso_schematron_skeleton_for_xslt1.xsl
│   │           │   │           │   ├── iso_svrl_for_xslt1.xsl
│   │           │   │           │   └── readme.txt
│   │           │   │           ├── RNG2Schtrn.xsl
│   │           │   │           └── XSD2Schtrn.xsl
│   │           │   ├── iterparse.pxi
│   │           │   ├── lxml.etree_api.h
│   │           │   ├── lxml.etree.h
│   │           │   ├── nsclasses.pxi
│   │           │   ├── objectify.cpython-312-darwin.so
│   │           │   ├── objectify.pyx
│   │           │   ├── objectpath.pxi
│   │           │   ├── parser.pxi
│   │           │   ├── parsertarget.pxi
│   │           │   ├── proxy.pxi
│   │           │   ├── public-api.pxi
│   │           │   ├── pyclasslookup.py
│   │           │   ├── readonlytree.pxi
│   │           │   ├── relaxng.pxi
│   │           │   ├── sax.cpython-312-darwin.so
│   │           │   ├── sax.py
│   │           │   ├── saxparser.pxi
│   │           │   ├── schematron.pxi
│   │           │   ├── serializer.pxi
│   │           │   ├── usedoctest.py
│   │           │   ├── xinclude.pxi
│   │           │   ├── xmlerror.pxi
│   │           │   ├── xmlid.pxi
│   │           │   ├── xmlschema.pxi
│   │           │   ├── xpath.pxi
│   │           │   ├── xslt.pxi
│   │           │   └── xsltext.pxi
│   │           ├── lxml-5.3.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── LICENSES.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── markupsafe
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   └── _native.cpython-312.pyc
│   │           │   ├── _native.py
│   │           │   ├── _speedups.c
│   │           │   ├── _speedups.cpython-312-darwin.so
│   │           │   ├── _speedups.pyi
│   │           │   └── py.typed
│   │           ├── MarkupSafe-3.0.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── pip
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pip-runner__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── __pip-runner__.cpython-312.pyc
│   │           │   ├── _internal
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── build_env.cpython-312.pyc
│   │           │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   ├── pyproject.cpython-312.pyc
│   │           │   │   │   ├── self_outdated_check.cpython-312.pyc
│   │           │   │   │   └── wheel_builder.cpython-312.pyc
│   │           │   │   ├── build_env.py
│   │           │   │   ├── cache.py
│   │           │   │   ├── cli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── autocompletion.cpython-312.pyc
│   │           │   │   │   │   ├── base_command.cpython-312.pyc
│   │           │   │   │   │   ├── cmdoptions.cpython-312.pyc
│   │           │   │   │   │   ├── command_context.cpython-312.pyc
│   │           │   │   │   │   ├── index_command.cpython-312.pyc
│   │           │   │   │   │   ├── main_parser.cpython-312.pyc
│   │           │   │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   │   ├── parser.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bars.cpython-312.pyc
│   │           │   │   │   │   ├── req_command.cpython-312.pyc
│   │           │   │   │   │   ├── spinners.cpython-312.pyc
│   │           │   │   │   │   └── status_codes.cpython-312.pyc
│   │           │   │   │   ├── autocompletion.py
│   │           │   │   │   ├── base_command.py
│   │           │   │   │   ├── cmdoptions.py
│   │           │   │   │   ├── command_context.py
│   │           │   │   │   ├── index_command.py
│   │           │   │   │   ├── main_parser.py
│   │           │   │   │   ├── main.py
│   │           │   │   │   ├── parser.py
│   │           │   │   │   ├── progress_bars.py
│   │           │   │   │   ├── req_command.py
│   │           │   │   │   ├── spinners.py
│   │           │   │   │   └── status_codes.py
│   │           │   │   ├── commands
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── completion.cpython-312.pyc
│   │           │   │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   │   ├── debug.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   ├── hash.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── inspect.cpython-312.pyc
│   │           │   │   │   │   ├── install.cpython-312.pyc
│   │           │   │   │   │   ├── list.cpython-312.pyc
│   │           │   │   │   │   ├── search.cpython-312.pyc
│   │           │   │   │   │   ├── show.cpython-312.pyc
│   │           │   │   │   │   ├── uninstall.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── completion.py
│   │           │   │   │   ├── configuration.py
│   │           │   │   │   ├── debug.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── hash.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── inspect.py
│   │           │   │   │   ├── install.py
│   │           │   │   │   ├── list.py
│   │           │   │   │   ├── search.py
│   │           │   │   │   ├── show.py
│   │           │   │   │   ├── uninstall.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── configuration.py
│   │           │   │   ├── distributions
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   ├── installed.cpython-312.pyc
│   │           │   │   │   │   ├── sdist.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── installed.py
│   │           │   │   │   ├── sdist.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── index
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── collector.cpython-312.pyc
│   │           │   │   │   │   ├── package_finder.cpython-312.pyc
│   │           │   │   │   │   └── sources.cpython-312.pyc
│   │           │   │   │   ├── collector.py
│   │           │   │   │   ├── package_finder.py
│   │           │   │   │   └── sources.py
│   │           │   │   ├── locations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _distutils.cpython-312.pyc
│   │           │   │   │   │   ├── _sysconfig.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── _distutils.py
│   │           │   │   │   ├── _sysconfig.py
│   │           │   │   │   └── base.py
│   │           │   │   ├── main.py
│   │           │   │   ├── metadata
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _json.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   └── pkg_resources.cpython-312.pyc
│   │           │   │   │   ├── _json.py
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── importlib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   │   ├── _dists.cpython-312.pyc
│   │           │   │   │   │   │   └── _envs.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.py
│   │           │   │   │   │   ├── _dists.py
│   │           │   │   │   │   └── _envs.py
│   │           │   │   │   └── pkg_resources.py
│   │           │   │   ├── models
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── candidate.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url.cpython-312.pyc
│   │           │   │   │   │   ├── format_control.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── installation_report.cpython-312.pyc
│   │           │   │   │   │   ├── link.cpython-312.pyc
│   │           │   │   │   │   ├── scheme.cpython-312.pyc
│   │           │   │   │   │   ├── search_scope.cpython-312.pyc
│   │           │   │   │   │   ├── selection_prefs.cpython-312.pyc
│   │           │   │   │   │   ├── target_python.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── candidate.py
│   │           │   │   │   ├── direct_url.py
│   │           │   │   │   ├── format_control.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── installation_report.py
│   │           │   │   │   ├── link.py
│   │           │   │   │   ├── scheme.py
│   │           │   │   │   ├── search_scope.py
│   │           │   │   │   ├── selection_prefs.py
│   │           │   │   │   ├── target_python.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── network
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── lazy_wheel.cpython-312.pyc
│   │           │   │   │   │   ├── session.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── xmlrpc.cpython-312.pyc
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── lazy_wheel.py
│   │           │   │   │   ├── session.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── xmlrpc.py
│   │           │   │   ├── operations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   └── prepare.cpython-312.pyc
│   │           │   │   │   ├── build
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── build_tracker.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_legacy.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── build_tracker.py
│   │           │   │   │   │   ├── metadata_editable.py
│   │           │   │   │   │   ├── metadata_legacy.py
│   │           │   │   │   │   ├── metadata.py
│   │           │   │   │   │   ├── wheel_editable.py
│   │           │   │   │   │   ├── wheel_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── install
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── editable_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── editable_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   └── prepare.py
│   │           │   │   ├── pyproject.py
│   │           │   │   ├── req
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── constructors.cpython-312.pyc
│   │           │   │   │   │   ├── req_file.cpython-312.pyc
│   │           │   │   │   │   ├── req_install.cpython-312.pyc
│   │           │   │   │   │   ├── req_set.cpython-312.pyc
│   │           │   │   │   │   └── req_uninstall.cpython-312.pyc
│   │           │   │   │   ├── constructors.py
│   │           │   │   │   ├── req_file.py
│   │           │   │   │   ├── req_install.py
│   │           │   │   │   ├── req_set.py
│   │           │   │   │   └── req_uninstall.py
│   │           │   │   ├── resolution
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── legacy
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── resolver.cpython-312.pyc
│   │           │   │   │   │   └── resolver.py
│   │           │   │   │   └── resolvelib
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── base.cpython-312.pyc
│   │           │   │   │       │   ├── candidates.cpython-312.pyc
│   │           │   │   │       │   ├── factory.cpython-312.pyc
│   │           │   │   │       │   ├── found_candidates.cpython-312.pyc
│   │           │   │   │       │   ├── provider.cpython-312.pyc
│   │           │   │   │       │   ├── reporter.cpython-312.pyc
│   │           │   │   │       │   ├── requirements.cpython-312.pyc
│   │           │   │   │       │   └── resolver.cpython-312.pyc
│   │           │   │   │       ├── base.py
│   │           │   │   │       ├── candidates.py
│   │           │   │   │       ├── factory.py
│   │           │   │   │       ├── found_candidates.py
│   │           │   │   │       ├── provider.py
│   │           │   │   │       ├── reporter.py
│   │           │   │   │       ├── requirements.py
│   │           │   │   │       └── resolver.py
│   │           │   │   ├── self_outdated_check.py
│   │           │   │   ├── utils
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _jaraco_text.cpython-312.pyc
│   │           │   │   │   │   ├── _log.cpython-312.pyc
│   │           │   │   │   │   ├── appdirs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── compatibility_tags.cpython-312.pyc
│   │           │   │   │   │   ├── datetime.cpython-312.pyc
│   │           │   │   │   │   ├── deprecation.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url_helpers.cpython-312.pyc
│   │           │   │   │   │   ├── egg_link.cpython-312.pyc
│   │           │   │   │   │   ├── encoding.cpython-312.pyc
│   │           │   │   │   │   ├── entrypoints.cpython-312.pyc
│   │           │   │   │   │   ├── filesystem.cpython-312.pyc
│   │           │   │   │   │   ├── filetypes.cpython-312.pyc
│   │           │   │   │   │   ├── glibc.cpython-312.pyc
│   │           │   │   │   │   ├── hashes.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── misc.cpython-312.pyc
│   │           │   │   │   │   ├── packaging.cpython-312.pyc
│   │           │   │   │   │   ├── retry.cpython-312.pyc
│   │           │   │   │   │   ├── setuptools_build.cpython-312.pyc
│   │           │   │   │   │   ├── subprocess.cpython-312.pyc
│   │           │   │   │   │   ├── temp_dir.cpython-312.pyc
│   │           │   │   │   │   ├── unpacking.cpython-312.pyc
│   │           │   │   │   │   ├── urls.cpython-312.pyc
│   │           │   │   │   │   ├── virtualenv.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── _jaraco_text.py
│   │           │   │   │   ├── _log.py
│   │           │   │   │   ├── appdirs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── compatibility_tags.py
│   │           │   │   │   ├── datetime.py
│   │           │   │   │   ├── deprecation.py
│   │           │   │   │   ├── direct_url_helpers.py
│   │           │   │   │   ├── egg_link.py
│   │           │   │   │   ├── encoding.py
│   │           │   │   │   ├── entrypoints.py
│   │           │   │   │   ├── filesystem.py
│   │           │   │   │   ├── filetypes.py
│   │           │   │   │   ├── glibc.py
│   │           │   │   │   ├── hashes.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── misc.py
│   │           │   │   │   ├── packaging.py
│   │           │   │   │   ├── retry.py
│   │           │   │   │   ├── setuptools_build.py
│   │           │   │   │   ├── subprocess.py
│   │           │   │   │   ├── temp_dir.py
│   │           │   │   │   ├── unpacking.py
│   │           │   │   │   ├── urls.py
│   │           │   │   │   ├── virtualenv.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── vcs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── bazaar.cpython-312.pyc
│   │           │   │   │   │   ├── git.cpython-312.pyc
│   │           │   │   │   │   ├── mercurial.cpython-312.pyc
│   │           │   │   │   │   ├── subversion.cpython-312.pyc
│   │           │   │   │   │   └── versioncontrol.cpython-312.pyc
│   │           │   │   │   ├── bazaar.py
│   │           │   │   │   ├── git.py
│   │           │   │   │   ├── mercurial.py
│   │           │   │   │   ├── subversion.py
│   │           │   │   │   └── versioncontrol.py
│   │           │   │   └── wheel_builder.py
│   │           │   ├── _vendor
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   └── typing_extensions.cpython-312.pyc
│   │           │   │   ├── cachecontrol
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _cmd.cpython-312.pyc
│   │           │   │   │   │   ├── adapter.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── controller.cpython-312.pyc
│   │           │   │   │   │   ├── filewrapper.cpython-312.pyc
│   │           │   │   │   │   ├── heuristics.cpython-312.pyc
│   │           │   │   │   │   ├── serialize.cpython-312.pyc
│   │           │   │   │   │   └── wrapper.cpython-312.pyc
│   │           │   │   │   ├── _cmd.py
│   │           │   │   │   ├── adapter.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── caches
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── file_cache.cpython-312.pyc
│   │           │   │   │   │   │   └── redis_cache.cpython-312.pyc
│   │           │   │   │   │   ├── file_cache.py
│   │           │   │   │   │   └── redis_cache.py
│   │           │   │   │   ├── controller.py
│   │           │   │   │   ├── filewrapper.py
│   │           │   │   │   ├── heuristics.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── serialize.py
│   │           │   │   │   └── wrapper.py
│   │           │   │   ├── certifi
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── core.cpython-312.pyc
│   │           │   │   │   ├── cacert.pem
│   │           │   │   │   ├── core.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── distlib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── database.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── locators.cpython-312.pyc
│   │           │   │   │   │   ├── manifest.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── resources.cpython-312.pyc
│   │           │   │   │   │   ├── scripts.cpython-312.pyc
│   │           │   │   │   │   ├── util.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── database.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── locators.py
│   │           │   │   │   ├── manifest.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── resources.py
│   │           │   │   │   ├── scripts.py
│   │           │   │   │   ├── t32.exe
│   │           │   │   │   ├── t64-arm.exe
│   │           │   │   │   ├── t64.exe
│   │           │   │   │   ├── util.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   ├── w32.exe
│   │           │   │   │   ├── w64-arm.exe
│   │           │   │   │   ├── w64.exe
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── distro
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── distro.cpython-312.pyc
│   │           │   │   │   ├── distro.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── idna
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── codec.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── core.cpython-312.pyc
│   │           │   │   │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   │   │   ├── intranges.cpython-312.pyc
│   │           │   │   │   │   ├── package_data.cpython-312.pyc
│   │           │   │   │   │   └── uts46data.cpython-312.pyc
│   │           │   │   │   ├── codec.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── core.py
│   │           │   │   │   ├── idnadata.py
│   │           │   │   │   ├── intranges.py
│   │           │   │   │   ├── package_data.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   └── uts46data.py
│   │           │   │   ├── msgpack
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── ext.cpython-312.pyc
│   │           │   │   │   │   └── fallback.cpython-312.pyc
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── ext.py
│   │           │   │   │   └── fallback.py
│   │           │   │   ├── packaging
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _elffile.cpython-312.pyc
│   │           │   │   │   │   ├── _manylinux.cpython-312.pyc
│   │           │   │   │   │   ├── _musllinux.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _structures.cpython-312.pyc
│   │           │   │   │   │   ├── _tokenizer.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── requirements.cpython-312.pyc
│   │           │   │   │   │   ├── specifiers.cpython-312.pyc
│   │           │   │   │   │   ├── tags.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── version.cpython-312.pyc
│   │           │   │   │   ├── _elffile.py
│   │           │   │   │   ├── _manylinux.py
│   │           │   │   │   ├── _musllinux.py
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _structures.py
│   │           │   │   │   ├── _tokenizer.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── requirements.py
│   │           │   │   │   ├── specifiers.py
│   │           │   │   │   ├── tags.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── version.py
│   │           │   │   ├── pkg_resources
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   └── __pycache__
│   │           │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   ├── platformdirs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── android.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── macos.cpython-312.pyc
│   │           │   │   │   │   ├── unix.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── windows.cpython-312.pyc
│   │           │   │   │   ├── android.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── macos.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── unix.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   └── windows.py
│   │           │   │   ├── pygments
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── cmdline.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── filter.cpython-312.pyc
│   │           │   │   │   │   ├── formatter.cpython-312.pyc
│   │           │   │   │   │   ├── lexer.cpython-312.pyc
│   │           │   │   │   │   ├── modeline.cpython-312.pyc
│   │           │   │   │   │   ├── plugin.cpython-312.pyc
│   │           │   │   │   │   ├── regexopt.cpython-312.pyc
│   │           │   │   │   │   ├── scanner.cpython-312.pyc
│   │           │   │   │   │   ├── sphinxext.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── token.cpython-312.pyc
│   │           │   │   │   │   ├── unistring.cpython-312.pyc
│   │           │   │   │   │   └── util.cpython-312.pyc
│   │           │   │   │   ├── cmdline.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── filter.py
│   │           │   │   │   ├── filters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   └── __pycache__
│   │           │   │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   │   ├── formatter.py
│   │           │   │   │   ├── formatters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   ├── bbcode.cpython-312.pyc
│   │           │   │   │   │   │   ├── groff.cpython-312.pyc
│   │           │   │   │   │   │   ├── html.cpython-312.pyc
│   │           │   │   │   │   │   ├── img.cpython-312.pyc
│   │           │   │   │   │   │   ├── irc.cpython-312.pyc
│   │           │   │   │   │   │   ├── latex.cpython-312.pyc
│   │           │   │   │   │   │   ├── other.cpython-312.pyc
│   │           │   │   │   │   │   ├── pangomarkup.cpython-312.pyc
│   │           │   │   │   │   │   ├── rtf.cpython-312.pyc
│   │           │   │   │   │   │   ├── svg.cpython-312.pyc
│   │           │   │   │   │   │   ├── terminal.cpython-312.pyc
│   │           │   │   │   │   │   └── terminal256.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   ├── bbcode.py
│   │           │   │   │   │   ├── groff.py
│   │           │   │   │   │   ├── html.py
│   │           │   │   │   │   ├── img.py
│   │           │   │   │   │   ├── irc.py
│   │           │   │   │   │   ├── latex.py
│   │           │   │   │   │   ├── other.py
│   │           │   │   │   │   ├── pangomarkup.py
│   │           │   │   │   │   ├── rtf.py
│   │           │   │   │   │   ├── svg.py
│   │           │   │   │   │   ├── terminal.py
│   │           │   │   │   │   └── terminal256.py
│   │           │   │   │   ├── lexer.py
│   │           │   │   │   ├── lexers
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   └── python.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   └── python.py
│   │           │   │   │   ├── modeline.py
│   │           │   │   │   ├── plugin.py
│   │           │   │   │   ├── regexopt.py
│   │           │   │   │   ├── scanner.py
│   │           │   │   │   ├── sphinxext.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styles
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── _mapping.cpython-312.pyc
│   │           │   │   │   │   └── _mapping.py
│   │           │   │   │   ├── token.py
│   │           │   │   │   ├── unistring.py
│   │           │   │   │   └── util.py
│   │           │   │   ├── pyproject_hooks
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   └── _impl.cpython-312.pyc
│   │           │   │   │   ├── _compat.py
│   │           │   │   │   ├── _impl.py
│   │           │   │   │   └── _in_process
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   └── _in_process.cpython-312.pyc
│   │           │   │   │       └── _in_process.py
│   │           │   │   ├── requests
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __version__.cpython-312.pyc
│   │           │   │   │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   │   │   ├── adapters.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── certs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── cookies.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── hooks.cpython-312.pyc
│   │           │   │   │   │   ├── models.cpython-312.pyc
│   │           │   │   │   │   ├── packages.cpython-312.pyc
│   │           │   │   │   │   ├── sessions.cpython-312.pyc
│   │           │   │   │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   │   │   ├── structures.cpython-312.pyc
│   │           │   │   │   │   └── utils.cpython-312.pyc
│   │           │   │   │   ├── __version__.py
│   │           │   │   │   ├── _internal_utils.py
│   │           │   │   │   ├── adapters.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── certs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── cookies.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── hooks.py
│   │           │   │   │   ├── models.py
│   │           │   │   │   ├── packages.py
│   │           │   │   │   ├── sessions.py
│   │           │   │   │   ├── status_codes.py
│   │           │   │   │   ├── structures.py
│   │           │   │   │   └── utils.py
│   │           │   │   ├── resolvelib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── providers.cpython-312.pyc
│   │           │   │   │   │   ├── reporters.cpython-312.pyc
│   │           │   │   │   │   ├── resolvers.cpython-312.pyc
│   │           │   │   │   │   └── structs.cpython-312.pyc
│   │           │   │   │   ├── compat
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── collections_abc.cpython-312.pyc
│   │           │   │   │   │   └── collections_abc.py
│   │           │   │   │   ├── providers.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── reporters.py
│   │           │   │   │   ├── resolvers.py
│   │           │   │   │   └── structs.py
│   │           │   │   ├── rich
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── _cell_widths.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_codes.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_replace.cpython-312.pyc
│   │           │   │   │   │   ├── _export_format.cpython-312.pyc
│   │           │   │   │   │   ├── _extension.cpython-312.pyc
│   │           │   │   │   │   ├── _fileno.cpython-312.pyc
│   │           │   │   │   │   ├── _inspect.cpython-312.pyc
│   │           │   │   │   │   ├── _log_render.cpython-312.pyc
│   │           │   │   │   │   ├── _loop.cpython-312.pyc
│   │           │   │   │   │   ├── _null_file.cpython-312.pyc
│   │           │   │   │   │   ├── _palettes.cpython-312.pyc
│   │           │   │   │   │   ├── _pick.cpython-312.pyc
│   │           │   │   │   │   ├── _ratio.cpython-312.pyc
│   │           │   │   │   │   ├── _spinners.cpython-312.pyc
│   │           │   │   │   │   ├── _stack.cpython-312.pyc
│   │           │   │   │   │   ├── _timer.cpython-312.pyc
│   │           │   │   │   │   ├── _win32_console.cpython-312.pyc
│   │           │   │   │   │   ├── _windows_renderer.cpython-312.pyc
│   │           │   │   │   │   ├── _windows.cpython-312.pyc
│   │           │   │   │   │   ├── _wrap.cpython-312.pyc
│   │           │   │   │   │   ├── abc.cpython-312.pyc
│   │           │   │   │   │   ├── align.cpython-312.pyc
│   │           │   │   │   │   ├── ansi.cpython-312.pyc
│   │           │   │   │   │   ├── bar.cpython-312.pyc
│   │           │   │   │   │   ├── box.cpython-312.pyc
│   │           │   │   │   │   ├── cells.cpython-312.pyc
│   │           │   │   │   │   ├── color_triplet.cpython-312.pyc
│   │           │   │   │   │   ├── color.cpython-312.pyc
│   │           │   │   │   │   ├── columns.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── constrain.cpython-312.pyc
│   │           │   │   │   │   ├── containers.cpython-312.pyc
│   │           │   │   │   │   ├── control.cpython-312.pyc
│   │           │   │   │   │   ├── default_styles.cpython-312.pyc
│   │           │   │   │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   │   │   ├── emoji.cpython-312.pyc
│   │           │   │   │   │   ├── errors.cpython-312.pyc
│   │           │   │   │   │   ├── file_proxy.cpython-312.pyc
│   │           │   │   │   │   ├── filesize.cpython-312.pyc
│   │           │   │   │   │   ├── highlighter.cpython-312.pyc
│   │           │   │   │   │   ├── json.cpython-312.pyc
│   │           │   │   │   │   ├── jupyter.cpython-312.pyc
│   │           │   │   │   │   ├── layout.cpython-312.pyc
│   │           │   │   │   │   ├── live_render.cpython-312.pyc
│   │           │   │   │   │   ├── live.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── markup.cpython-312.pyc
│   │           │   │   │   │   ├── measure.cpython-312.pyc
│   │           │   │   │   │   ├── padding.cpython-312.pyc
│   │           │   │   │   │   ├── pager.cpython-312.pyc
│   │           │   │   │   │   ├── palette.cpython-312.pyc
│   │           │   │   │   │   ├── panel.cpython-312.pyc
│   │           │   │   │   │   ├── pretty.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bar.cpython-312.pyc
│   │           │   │   │   │   ├── progress.cpython-312.pyc
│   │           │   │   │   │   ├── prompt.cpython-312.pyc
│   │           │   │   │   │   ├── protocol.cpython-312.pyc
│   │           │   │   │   │   ├── region.cpython-312.pyc
│   │           │   │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   │   ├── rule.cpython-312.pyc
│   │           │   │   │   │   ├── scope.cpython-312.pyc
│   │           │   │   │   │   ├── screen.cpython-312.pyc
│   │           │   │   │   │   ├── segment.cpython-312.pyc
│   │           │   │   │   │   ├── spinner.cpython-312.pyc
│   │           │   │   │   │   ├── status.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── styled.cpython-312.pyc
│   │           │   │   │   │   ├── syntax.cpython-312.pyc
│   │           │   │   │   │   ├── table.cpython-312.pyc
│   │           │   │   │   │   ├── terminal_theme.cpython-312.pyc
│   │           │   │   │   │   ├── text.cpython-312.pyc
│   │           │   │   │   │   ├── theme.cpython-312.pyc
│   │           │   │   │   │   ├── themes.cpython-312.pyc
│   │           │   │   │   │   ├── traceback.cpython-312.pyc
│   │           │   │   │   │   └── tree.cpython-312.pyc
│   │           │   │   │   ├── _cell_widths.py
│   │           │   │   │   ├── _emoji_codes.py
│   │           │   │   │   ├── _emoji_replace.py
│   │           │   │   │   ├── _export_format.py
│   │           │   │   │   ├── _extension.py
│   │           │   │   │   ├── _fileno.py
│   │           │   │   │   ├── _inspect.py
│   │           │   │   │   ├── _log_render.py
│   │           │   │   │   ├── _loop.py
│   │           │   │   │   ├── _null_file.py
│   │           │   │   │   ├── _palettes.py
│   │           │   │   │   ├── _pick.py
│   │           │   │   │   ├── _ratio.py
│   │           │   │   │   ├── _spinners.py
│   │           │   │   │   ├── _stack.py
│   │           │   │   │   ├── _timer.py
│   │           │   │   │   ├── _win32_console.py
│   │           │   │   │   ├── _windows_renderer.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   ├── _wrap.py
│   │           │   │   │   ├── abc.py
│   │           │   │   │   ├── align.py
│   │           │   │   │   ├── ansi.py
│   │           │   │   │   ├── bar.py
│   │           │   │   │   ├── box.py
│   │           │   │   │   ├── cells.py
│   │           │   │   │   ├── color_triplet.py
│   │           │   │   │   ├── color.py
│   │           │   │   │   ├── columns.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── constrain.py
│   │           │   │   │   ├── containers.py
│   │           │   │   │   ├── control.py
│   │           │   │   │   ├── default_styles.py
│   │           │   │   │   ├── diagnose.py
│   │           │   │   │   ├── emoji.py
│   │           │   │   │   ├── errors.py
│   │           │   │   │   ├── file_proxy.py
│   │           │   │   │   ├── filesize.py
│   │           │   │   │   ├── highlighter.py
│   │           │   │   │   ├── json.py
│   │           │   │   │   ├── jupyter.py
│   │           │   │   │   ├── layout.py
│   │           │   │   │   ├── live_render.py
│   │           │   │   │   ├── live.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── markup.py
│   │           │   │   │   ├── measure.py
│   │           │   │   │   ├── padding.py
│   │           │   │   │   ├── pager.py
│   │           │   │   │   ├── palette.py
│   │           │   │   │   ├── panel.py
│   │           │   │   │   ├── pretty.py
│   │           │   │   │   ├── progress_bar.py
│   │           │   │   │   ├── progress.py
│   │           │   │   │   ├── prompt.py
│   │           │   │   │   ├── protocol.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── region.py
│   │           │   │   │   ├── repr.py
│   │           │   │   │   ├── rule.py
│   │           │   │   │   ├── scope.py
│   │           │   │   │   ├── screen.py
│   │           │   │   │   ├── segment.py
│   │           │   │   │   ├── spinner.py
│   │           │   │   │   ├── status.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styled.py
│   │           │   │   │   ├── syntax.py
│   │           │   │   │   ├── table.py
│   │           │   │   │   ├── terminal_theme.py
│   │           │   │   │   ├── text.py
│   │           │   │   │   ├── theme.py
│   │           │   │   │   ├── themes.py
│   │           │   │   │   ├── traceback.py
│   │           │   │   │   └── tree.py
│   │           │   │   ├── tomli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _re.cpython-312.pyc
│   │           │   │   │   │   └── _types.cpython-312.pyc
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _re.py
│   │           │   │   │   ├── _types.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── truststore
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _api.cpython-312.pyc
│   │           │   │   │   │   ├── _macos.cpython-312.pyc
│   │           │   │   │   │   ├── _openssl.cpython-312.pyc
│   │           │   │   │   │   ├── _ssl_constants.cpython-312.pyc
│   │           │   │   │   │   └── _windows.cpython-312.pyc
│   │           │   │   │   ├── _api.py
│   │           │   │   │   ├── _macos.py
│   │           │   │   │   ├── _openssl.py
│   │           │   │   │   ├── _ssl_constants.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── typing_extensions.py
│   │           │   │   ├── urllib3
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _collections.cpython-312.pyc
│   │           │   │   │   │   ├── _version.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── fields.cpython-312.pyc
│   │           │   │   │   │   ├── filepost.cpython-312.pyc
│   │           │   │   │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── _collections.py
│   │           │   │   │   ├── _version.py
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── connectionpool.py
│   │           │   │   │   ├── contrib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _appengine_environ.cpython-312.pyc
│   │           │   │   │   │   │   ├── appengine.cpython-312.pyc
│   │           │   │   │   │   │   ├── ntlmpool.cpython-312.pyc
│   │           │   │   │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   │   │   ├── securetransport.cpython-312.pyc
│   │           │   │   │   │   │   └── socks.cpython-312.pyc
│   │           │   │   │   │   ├── _appengine_environ.py
│   │           │   │   │   │   ├── _securetransport
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── bindings.cpython-312.pyc
│   │           │   │   │   │   │   │   └── low_level.cpython-312.pyc
│   │           │   │   │   │   │   ├── bindings.py
│   │           │   │   │   │   │   └── low_level.py
│   │           │   │   │   │   ├── appengine.py
│   │           │   │   │   │   ├── ntlmpool.py
│   │           │   │   │   │   ├── pyopenssl.py
│   │           │   │   │   │   ├── securetransport.py
│   │           │   │   │   │   └── socks.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── fields.py
│   │           │   │   │   ├── filepost.py
│   │           │   │   │   ├── packages
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── six.cpython-312.pyc
│   │           │   │   │   │   ├── backports
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── makefile.cpython-312.pyc
│   │           │   │   │   │   │   │   └── weakref_finalize.cpython-312.pyc
│   │           │   │   │   │   │   ├── makefile.py
│   │           │   │   │   │   │   └── weakref_finalize.py
│   │           │   │   │   │   └── six.py
│   │           │   │   │   ├── poolmanager.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   ├── response.py
│   │           │   │   │   └── util
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── connection.cpython-312.pyc
│   │           │   │   │       │   ├── proxy.cpython-312.pyc
│   │           │   │   │       │   ├── queue.cpython-312.pyc
│   │           │   │   │       │   ├── request.cpython-312.pyc
│   │           │   │   │       │   ├── response.cpython-312.pyc
│   │           │   │   │       │   ├── retry.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │   │   │       │   ├── ssltransport.cpython-312.pyc
│   │           │   │   │       │   ├── timeout.cpython-312.pyc
│   │           │   │   │       │   ├── url.cpython-312.pyc
│   │           │   │   │       │   └── wait.cpython-312.pyc
│   │           │   │   │       ├── connection.py
│   │           │   │   │       ├── proxy.py
│   │           │   │   │       ├── queue.py
│   │           │   │   │       ├── request.py
│   │           │   │   │       ├── response.py
│   │           │   │   │       ├── retry.py
│   │           │   │   │       ├── ssl_.py
│   │           │   │   │       ├── ssl_match_hostname.py
│   │           │   │   │       ├── ssltransport.py
│   │           │   │   │       ├── timeout.py
│   │           │   │   │       ├── url.py
│   │           │   │   │       └── wait.py
│   │           │   │   └── vendor.txt
│   │           │   └── py.typed
│   │           ├── pip-24.2.dist-info
│   │           │   ├── AUTHORS.txt
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── requests
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __version__.cpython-312.pyc
│   │           │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   ├── adapters.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── auth.cpython-312.pyc
│   │           │   │   ├── certs.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── cookies.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── help.cpython-312.pyc
│   │           │   │   ├── hooks.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── packages.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   ├── structures.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── __version__.py
│   │           │   ├── _internal_utils.py
│   │           │   ├── adapters.py
│   │           │   ├── api.py
│   │           │   ├── auth.py
│   │           │   ├── certs.py
│   │           │   ├── compat.py
│   │           │   ├── cookies.py
│   │           │   ├── exceptions.py
│   │           │   ├── help.py
│   │           │   ├── hooks.py
│   │           │   ├── models.py
│   │           │   ├── packages.py
│   │           │   ├── sessions.py
│   │           │   ├── status_codes.py
│   │           │   ├── structures.py
│   │           │   └── utils.py
│   │           ├── requests-2.32.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── soupsieve
│   │           │   ├── __init__.py
│   │           │   ├── __meta__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __meta__.cpython-312.pyc
│   │           │   │   ├── css_match.cpython-312.pyc
│   │           │   │   ├── css_parser.cpython-312.pyc
│   │           │   │   ├── css_types.cpython-312.pyc
│   │           │   │   ├── pretty.cpython-312.pyc
│   │           │   │   └── util.cpython-312.pyc
│   │           │   ├── css_match.py
│   │           │   ├── css_parser.py
│   │           │   ├── css_types.py
│   │           │   ├── pretty.py
│   │           │   ├── py.typed
│   │           │   └── util.py
│   │           ├── soupsieve-2.6.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── urllib3
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _base_connection.cpython-312.pyc
│   │           │   │   ├── _collections.cpython-312.pyc
│   │           │   │   ├── _request_methods.cpython-312.pyc
│   │           │   │   ├── _version.cpython-312.pyc
│   │           │   │   ├── connection.cpython-312.pyc
│   │           │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── fields.cpython-312.pyc
│   │           │   │   ├── filepost.cpython-312.pyc
│   │           │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   └── response.cpython-312.pyc
│   │           │   ├── _base_connection.py
│   │           │   ├── _collections.py
│   │           │   ├── _request_methods.py
│   │           │   ├── _version.py
│   │           │   ├── connection.py
│   │           │   ├── connectionpool.py
│   │           │   ├── contrib
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   └── socks.cpython-312.pyc
│   │           │   │   ├── emscripten
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── fetch.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── emscripten_fetch_worker.js
│   │           │   │   │   ├── fetch.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   └── response.py
│   │           │   │   ├── pyopenssl.py
│   │           │   │   └── socks.py
│   │           │   ├── exceptions.py
│   │           │   ├── fields.py
│   │           │   ├── filepost.py
│   │           │   ├── http2
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   └── probe.cpython-312.pyc
│   │           │   │   ├── connection.py
│   │           │   │   └── probe.py
│   │           │   ├── poolmanager.py
│   │           │   ├── py.typed
│   │           │   ├── response.py
│   │           │   └── util
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── connection.cpython-312.pyc
│   │           │       │   ├── proxy.cpython-312.pyc
│   │           │       │   ├── request.cpython-312.pyc
│   │           │       │   ├── response.cpython-312.pyc
│   │           │       │   ├── retry.cpython-312.pyc
│   │           │       │   ├── ssl_.cpython-312.pyc
│   │           │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │       │   ├── ssltransport.cpython-312.pyc
│   │           │       │   ├── timeout.cpython-312.pyc
│   │           │       │   ├── url.cpython-312.pyc
│   │           │       │   ├── util.cpython-312.pyc
│   │           │       │   └── wait.cpython-312.pyc
│   │           │       ├── connection.py
│   │           │       ├── proxy.py
│   │           │       ├── request.py
│   │           │       ├── response.py
│   │           │       ├── retry.py
│   │           │       ├── ssl_.py
│   │           │       ├── ssl_match_hostname.py
│   │           │       ├── ssltransport.py
│   │           │       ├── timeout.py
│   │           │       ├── url.py
│   │           │       ├── util.py
│   │           │       └── wait.py
│   │           ├── urllib3-2.2.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── useragent
│   │           │   ├── __init__.py
│   │           │   ├── __init__.pyc
│   │           │   ├── __pycache__
│   │           │   │   └── __init__.cpython-312.pyc
│   │           │   ├── resources
│   │           │   │   └── user_agent_data.json
│   │           │   └── test
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   └── __init__.cpython-312.pyc
│   │           │       ├── test_additional_os.json
│   │           │       ├── test_browser.json
│   │           │       ├── test_device.json
│   │           │       ├── test_firefox.json
│   │           │       ├── test_os.json
│   │           │       └── test_pgts_browser.json
│   │           ├── useragent-0.1.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── werkzeug
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _internal.cpython-312.pyc
│   │           │   │   ├── _reloader.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formparser.cpython-312.pyc
│   │           │   │   ├── http.cpython-312.pyc
│   │           │   │   ├── local.cpython-312.pyc
│   │           │   │   ├── security.cpython-312.pyc
│   │           │   │   ├── serving.cpython-312.pyc
│   │           │   │   ├── test.cpython-312.pyc
│   │           │   │   ├── testapp.cpython-312.pyc
│   │           │   │   ├── urls.cpython-312.pyc
│   │           │   │   ├── user_agent.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── wsgi.cpython-312.pyc
│   │           │   ├── _internal.py
│   │           │   ├── _reloader.py
│   │           │   ├── datastructures
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── accept.cpython-312.pyc
│   │           │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   ├── cache_control.cpython-312.pyc
│   │           │   │   │   ├── csp.cpython-312.pyc
│   │           │   │   │   ├── etag.cpython-312.pyc
│   │           │   │   │   ├── file_storage.cpython-312.pyc
│   │           │   │   │   ├── headers.cpython-312.pyc
│   │           │   │   │   ├── mixins.cpython-312.pyc
│   │           │   │   │   ├── range.cpython-312.pyc
│   │           │   │   │   └── structures.cpython-312.pyc
│   │           │   │   ├── accept.py
│   │           │   │   ├── accept.pyi
│   │           │   │   ├── auth.py
│   │           │   │   ├── cache_control.py
│   │           │   │   ├── cache_control.pyi
│   │           │   │   ├── csp.py
│   │           │   │   ├── csp.pyi
│   │           │   │   ├── etag.py
│   │           │   │   ├── etag.pyi
│   │           │   │   ├── file_storage.py
│   │           │   │   ├── file_storage.pyi
│   │           │   │   ├── headers.py
│   │           │   │   ├── headers.pyi
│   │           │   │   ├── mixins.py
│   │           │   │   ├── mixins.pyi
│   │           │   │   ├── range.py
│   │           │   │   ├── range.pyi
│   │           │   │   ├── structures.py
│   │           │   │   └── structures.pyi
│   │           │   ├── debug
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   └── tbtools.cpython-312.pyc
│   │           │   │   ├── console.py
│   │           │   │   ├── repr.py
│   │           │   │   ├── shared
│   │           │   │   │   ├── console.png
│   │           │   │   │   ├── debugger.js
│   │           │   │   │   ├── ICON_LICENSE.md
│   │           │   │   │   ├── less.png
│   │           │   │   │   ├── more.png
│   │           │   │   │   └── style.css
│   │           │   │   └── tbtools.py
│   │           │   ├── exceptions.py
│   │           │   ├── formparser.py
│   │           │   ├── http.py
│   │           │   ├── local.py
│   │           │   ├── middleware
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── dispatcher.cpython-312.pyc
│   │           │   │   │   ├── http_proxy.cpython-312.pyc
│   │           │   │   │   ├── lint.cpython-312.pyc
│   │           │   │   │   ├── profiler.cpython-312.pyc
│   │           │   │   │   ├── proxy_fix.cpython-312.pyc
│   │           │   │   │   └── shared_data.cpython-312.pyc
│   │           │   │   ├── dispatcher.py
│   │           │   │   ├── http_proxy.py
│   │           │   │   ├── lint.py
│   │           │   │   ├── profiler.py
│   │           │   │   ├── proxy_fix.py
│   │           │   │   └── shared_data.py
│   │           │   ├── py.typed
│   │           │   ├── routing
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── converters.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── map.cpython-312.pyc
│   │           │   │   │   ├── matcher.cpython-312.pyc
│   │           │   │   │   └── rules.cpython-312.pyc
│   │           │   │   ├── converters.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── map.py
│   │           │   │   ├── matcher.py
│   │           │   │   └── rules.py
│   │           │   ├── sansio
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── http.cpython-312.pyc
│   │           │   │   │   ├── multipart.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   ├── response.cpython-312.pyc
│   │           │   │   │   └── utils.cpython-312.pyc
│   │           │   │   ├── http.py
│   │           │   │   ├── multipart.py
│   │           │   │   ├── request.py
│   │           │   │   ├── response.py
│   │           │   │   └── utils.py
│   │           │   ├── security.py
│   │           │   ├── serving.py
│   │           │   ├── test.py
│   │           │   ├── testapp.py
│   │           │   ├── urls.py
│   │           │   ├── user_agent.py
│   │           │   ├── utils.py
│   │           │   ├── wrappers
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   └── response.cpython-312.pyc
│   │           │   │   ├── request.py
│   │           │   │   └── response.py
│   │           │   └── wsgi.py
│   │           └── werkzeug-3.0.4.dist-info
│   │               ├── INSTALLER
│   │               ├── LICENSE.txt
│   │               ├── METADATA
│   │               ├── RECORD
│   │               └── WHEEL
│   ├── pyvenv.cfg
│   ├── static
│   │   └── styles.css
│   ├── templates
│   │   └── index.html
│   └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
    ├── text1.txt
    └── text2.txt
```

# Files

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/req/req_uninstall.py:
--------------------------------------------------------------------------------

```python
  1 | import functools
  2 | import os
  3 | import sys
  4 | import sysconfig
  5 | from importlib.util import cache_from_source
  6 | from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Set, Tuple
  7 | 
  8 | from pip._internal.exceptions import LegacyDistutilsInstall, UninstallMissingRecord
  9 | from pip._internal.locations import get_bin_prefix, get_bin_user
 10 | from pip._internal.metadata import BaseDistribution
 11 | from pip._internal.utils.compat import WINDOWS
 12 | from pip._internal.utils.egg_link import egg_link_path_from_location
 13 | from pip._internal.utils.logging import getLogger, indent_log
 14 | from pip._internal.utils.misc import ask, normalize_path, renames, rmtree
 15 | from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory
 16 | from pip._internal.utils.virtualenv import running_under_virtualenv
 17 | 
 18 | logger = getLogger(__name__)
 19 | 
 20 | 
 21 | def _script_names(
 22 |     bin_dir: str, script_name: str, is_gui: bool
 23 | ) -> Generator[str, None, None]:
 24 |     """Create the fully qualified name of the files created by
 25 |     {console,gui}_scripts for the given ``dist``.
 26 |     Returns the list of file names
 27 |     """
 28 |     exe_name = os.path.join(bin_dir, script_name)
 29 |     yield exe_name
 30 |     if not WINDOWS:
 31 |         return
 32 |     yield f"{exe_name}.exe"
 33 |     yield f"{exe_name}.exe.manifest"
 34 |     if is_gui:
 35 |         yield f"{exe_name}-script.pyw"
 36 |     else:
 37 |         yield f"{exe_name}-script.py"
 38 | 
 39 | 
 40 | def _unique(
 41 |     fn: Callable[..., Generator[Any, None, None]]
 42 | ) -> Callable[..., Generator[Any, None, None]]:
 43 |     @functools.wraps(fn)
 44 |     def unique(*args: Any, **kw: Any) -> Generator[Any, None, None]:
 45 |         seen: Set[Any] = set()
 46 |         for item in fn(*args, **kw):
 47 |             if item not in seen:
 48 |                 seen.add(item)
 49 |                 yield item
 50 | 
 51 |     return unique
 52 | 
 53 | 
 54 | @_unique
 55 | def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]:
 56 |     """
 57 |     Yield all the uninstallation paths for dist based on RECORD-without-.py[co]
 58 | 
 59 |     Yield paths to all the files in RECORD. For each .py file in RECORD, add
 60 |     the .pyc and .pyo in the same directory.
 61 | 
 62 |     UninstallPathSet.add() takes care of the __pycache__ .py[co].
 63 | 
 64 |     If RECORD is not found, raises an error,
 65 |     with possible information from the INSTALLER file.
 66 | 
 67 |     https://packaging.python.org/specifications/recording-installed-packages/
 68 |     """
 69 |     location = dist.location
 70 |     assert location is not None, "not installed"
 71 | 
 72 |     entries = dist.iter_declared_entries()
 73 |     if entries is None:
 74 |         raise UninstallMissingRecord(distribution=dist)
 75 | 
 76 |     for entry in entries:
 77 |         path = os.path.join(location, entry)
 78 |         yield path
 79 |         if path.endswith(".py"):
 80 |             dn, fn = os.path.split(path)
 81 |             base = fn[:-3]
 82 |             path = os.path.join(dn, base + ".pyc")
 83 |             yield path
 84 |             path = os.path.join(dn, base + ".pyo")
 85 |             yield path
 86 | 
 87 | 
 88 | def compact(paths: Iterable[str]) -> Set[str]:
 89 |     """Compact a path set to contain the minimal number of paths
 90 |     necessary to contain all paths in the set. If /a/path/ and
 91 |     /a/path/to/a/file.txt are both in the set, leave only the
 92 |     shorter path."""
 93 | 
 94 |     sep = os.path.sep
 95 |     short_paths: Set[str] = set()
 96 |     for path in sorted(paths, key=len):
 97 |         should_skip = any(
 98 |             path.startswith(shortpath.rstrip("*"))
 99 |             and path[len(shortpath.rstrip("*").rstrip(sep))] == sep
100 |             for shortpath in short_paths
101 |         )
102 |         if not should_skip:
103 |             short_paths.add(path)
104 |     return short_paths
105 | 
106 | 
107 | def compress_for_rename(paths: Iterable[str]) -> Set[str]:
108 |     """Returns a set containing the paths that need to be renamed.
109 | 
110 |     This set may include directories when the original sequence of paths
111 |     included every file on disk.
112 |     """
113 |     case_map = {os.path.normcase(p): p for p in paths}
114 |     remaining = set(case_map)
115 |     unchecked = sorted({os.path.split(p)[0] for p in case_map.values()}, key=len)
116 |     wildcards: Set[str] = set()
117 | 
118 |     def norm_join(*a: str) -> str:
119 |         return os.path.normcase(os.path.join(*a))
120 | 
121 |     for root in unchecked:
122 |         if any(os.path.normcase(root).startswith(w) for w in wildcards):
123 |             # This directory has already been handled.
124 |             continue
125 | 
126 |         all_files: Set[str] = set()
127 |         all_subdirs: Set[str] = set()
128 |         for dirname, subdirs, files in os.walk(root):
129 |             all_subdirs.update(norm_join(root, dirname, d) for d in subdirs)
130 |             all_files.update(norm_join(root, dirname, f) for f in files)
131 |         # If all the files we found are in our remaining set of files to
132 |         # remove, then remove them from the latter set and add a wildcard
133 |         # for the directory.
134 |         if not (all_files - remaining):
135 |             remaining.difference_update(all_files)
136 |             wildcards.add(root + os.sep)
137 | 
138 |     return set(map(case_map.__getitem__, remaining)) | wildcards
139 | 
140 | 
141 | def compress_for_output_listing(paths: Iterable[str]) -> Tuple[Set[str], Set[str]]:
142 |     """Returns a tuple of 2 sets of which paths to display to user
143 | 
144 |     The first set contains paths that would be deleted. Files of a package
145 |     are not added and the top-level directory of the package has a '*' added
146 |     at the end - to signify that all it's contents are removed.
147 | 
148 |     The second set contains files that would have been skipped in the above
149 |     folders.
150 |     """
151 | 
152 |     will_remove = set(paths)
153 |     will_skip = set()
154 | 
155 |     # Determine folders and files
156 |     folders = set()
157 |     files = set()
158 |     for path in will_remove:
159 |         if path.endswith(".pyc"):
160 |             continue
161 |         if path.endswith("__init__.py") or ".dist-info" in path:
162 |             folders.add(os.path.dirname(path))
163 |         files.add(path)
164 | 
165 |     _normcased_files = set(map(os.path.normcase, files))
166 | 
167 |     folders = compact(folders)
168 | 
169 |     # This walks the tree using os.walk to not miss extra folders
170 |     # that might get added.
171 |     for folder in folders:
172 |         for dirpath, _, dirfiles in os.walk(folder):
173 |             for fname in dirfiles:
174 |                 if fname.endswith(".pyc"):
175 |                     continue
176 | 
177 |                 file_ = os.path.join(dirpath, fname)
178 |                 if (
179 |                     os.path.isfile(file_)
180 |                     and os.path.normcase(file_) not in _normcased_files
181 |                 ):
182 |                     # We are skipping this file. Add it to the set.
183 |                     will_skip.add(file_)
184 | 
185 |     will_remove = files | {os.path.join(folder, "*") for folder in folders}
186 | 
187 |     return will_remove, will_skip
188 | 
189 | 
190 | class StashedUninstallPathSet:
191 |     """A set of file rename operations to stash files while
192 |     tentatively uninstalling them."""
193 | 
194 |     def __init__(self) -> None:
195 |         # Mapping from source file root to [Adjacent]TempDirectory
196 |         # for files under that directory.
197 |         self._save_dirs: Dict[str, TempDirectory] = {}
198 |         # (old path, new path) tuples for each move that may need
199 |         # to be undone.
200 |         self._moves: List[Tuple[str, str]] = []
201 | 
202 |     def _get_directory_stash(self, path: str) -> str:
203 |         """Stashes a directory.
204 | 
205 |         Directories are stashed adjacent to their original location if
206 |         possible, or else moved/copied into the user's temp dir."""
207 | 
208 |         try:
209 |             save_dir: TempDirectory = AdjacentTempDirectory(path)
210 |         except OSError:
211 |             save_dir = TempDirectory(kind="uninstall")
212 |         self._save_dirs[os.path.normcase(path)] = save_dir
213 | 
214 |         return save_dir.path
215 | 
216 |     def _get_file_stash(self, path: str) -> str:
217 |         """Stashes a file.
218 | 
219 |         If no root has been provided, one will be created for the directory
220 |         in the user's temp directory."""
221 |         path = os.path.normcase(path)
222 |         head, old_head = os.path.dirname(path), None
223 |         save_dir = None
224 | 
225 |         while head != old_head:
226 |             try:
227 |                 save_dir = self._save_dirs[head]
228 |                 break
229 |             except KeyError:
230 |                 pass
231 |             head, old_head = os.path.dirname(head), head
232 |         else:
233 |             # Did not find any suitable root
234 |             head = os.path.dirname(path)
235 |             save_dir = TempDirectory(kind="uninstall")
236 |             self._save_dirs[head] = save_dir
237 | 
238 |         relpath = os.path.relpath(path, head)
239 |         if relpath and relpath != os.path.curdir:
240 |             return os.path.join(save_dir.path, relpath)
241 |         return save_dir.path
242 | 
243 |     def stash(self, path: str) -> str:
244 |         """Stashes the directory or file and returns its new location.
245 |         Handle symlinks as files to avoid modifying the symlink targets.
246 |         """
247 |         path_is_dir = os.path.isdir(path) and not os.path.islink(path)
248 |         if path_is_dir:
249 |             new_path = self._get_directory_stash(path)
250 |         else:
251 |             new_path = self._get_file_stash(path)
252 | 
253 |         self._moves.append((path, new_path))
254 |         if path_is_dir and os.path.isdir(new_path):
255 |             # If we're moving a directory, we need to
256 |             # remove the destination first or else it will be
257 |             # moved to inside the existing directory.
258 |             # We just created new_path ourselves, so it will
259 |             # be removable.
260 |             os.rmdir(new_path)
261 |         renames(path, new_path)
262 |         return new_path
263 | 
264 |     def commit(self) -> None:
265 |         """Commits the uninstall by removing stashed files."""
266 |         for save_dir in self._save_dirs.values():
267 |             save_dir.cleanup()
268 |         self._moves = []
269 |         self._save_dirs = {}
270 | 
271 |     def rollback(self) -> None:
272 |         """Undoes the uninstall by moving stashed files back."""
273 |         for p in self._moves:
274 |             logger.info("Moving to %s\n from %s", *p)
275 | 
276 |         for new_path, path in self._moves:
277 |             try:
278 |                 logger.debug("Replacing %s from %s", new_path, path)
279 |                 if os.path.isfile(new_path) or os.path.islink(new_path):
280 |                     os.unlink(new_path)
281 |                 elif os.path.isdir(new_path):
282 |                     rmtree(new_path)
283 |                 renames(path, new_path)
284 |             except OSError as ex:
285 |                 logger.error("Failed to restore %s", new_path)
286 |                 logger.debug("Exception: %s", ex)
287 | 
288 |         self.commit()
289 | 
290 |     @property
291 |     def can_rollback(self) -> bool:
292 |         return bool(self._moves)
293 | 
294 | 
295 | class UninstallPathSet:
296 |     """A set of file paths to be removed in the uninstallation of a
297 |     requirement."""
298 | 
299 |     def __init__(self, dist: BaseDistribution) -> None:
300 |         self._paths: Set[str] = set()
301 |         self._refuse: Set[str] = set()
302 |         self._pth: Dict[str, UninstallPthEntries] = {}
303 |         self._dist = dist
304 |         self._moved_paths = StashedUninstallPathSet()
305 |         # Create local cache of normalize_path results. Creating an UninstallPathSet
306 |         # can result in hundreds/thousands of redundant calls to normalize_path with
307 |         # the same args, which hurts performance.
308 |         self._normalize_path_cached = functools.lru_cache(normalize_path)
309 | 
310 |     def _permitted(self, path: str) -> bool:
311 |         """
312 |         Return True if the given path is one we are permitted to
313 |         remove/modify, False otherwise.
314 | 
315 |         """
316 |         # aka is_local, but caching normalized sys.prefix
317 |         if not running_under_virtualenv():
318 |             return True
319 |         return path.startswith(self._normalize_path_cached(sys.prefix))
320 | 
321 |     def add(self, path: str) -> None:
322 |         head, tail = os.path.split(path)
323 | 
324 |         # we normalize the head to resolve parent directory symlinks, but not
325 |         # the tail, since we only want to uninstall symlinks, not their targets
326 |         path = os.path.join(self._normalize_path_cached(head), os.path.normcase(tail))
327 | 
328 |         if not os.path.exists(path):
329 |             return
330 |         if self._permitted(path):
331 |             self._paths.add(path)
332 |         else:
333 |             self._refuse.add(path)
334 | 
335 |         # __pycache__ files can show up after 'installed-files.txt' is created,
336 |         # due to imports
337 |         if os.path.splitext(path)[1] == ".py":
338 |             self.add(cache_from_source(path))
339 | 
340 |     def add_pth(self, pth_file: str, entry: str) -> None:
341 |         pth_file = self._normalize_path_cached(pth_file)
342 |         if self._permitted(pth_file):
343 |             if pth_file not in self._pth:
344 |                 self._pth[pth_file] = UninstallPthEntries(pth_file)
345 |             self._pth[pth_file].add(entry)
346 |         else:
347 |             self._refuse.add(pth_file)
348 | 
349 |     def remove(self, auto_confirm: bool = False, verbose: bool = False) -> None:
350 |         """Remove paths in ``self._paths`` with confirmation (unless
351 |         ``auto_confirm`` is True)."""
352 | 
353 |         if not self._paths:
354 |             logger.info(
355 |                 "Can't uninstall '%s'. No files were found to uninstall.",
356 |                 self._dist.raw_name,
357 |             )
358 |             return
359 | 
360 |         dist_name_version = f"{self._dist.raw_name}-{self._dist.raw_version}"
361 |         logger.info("Uninstalling %s:", dist_name_version)
362 | 
363 |         with indent_log():
364 |             if auto_confirm or self._allowed_to_proceed(verbose):
365 |                 moved = self._moved_paths
366 | 
367 |                 for_rename = compress_for_rename(self._paths)
368 | 
369 |                 for path in sorted(compact(for_rename)):
370 |                     moved.stash(path)
371 |                     logger.verbose("Removing file or directory %s", path)
372 | 
373 |                 for pth in self._pth.values():
374 |                     pth.remove()
375 | 
376 |                 logger.info("Successfully uninstalled %s", dist_name_version)
377 | 
378 |     def _allowed_to_proceed(self, verbose: bool) -> bool:
379 |         """Display which files would be deleted and prompt for confirmation"""
380 | 
381 |         def _display(msg: str, paths: Iterable[str]) -> None:
382 |             if not paths:
383 |                 return
384 | 
385 |             logger.info(msg)
386 |             with indent_log():
387 |                 for path in sorted(compact(paths)):
388 |                     logger.info(path)
389 | 
390 |         if not verbose:
391 |             will_remove, will_skip = compress_for_output_listing(self._paths)
392 |         else:
393 |             # In verbose mode, display all the files that are going to be
394 |             # deleted.
395 |             will_remove = set(self._paths)
396 |             will_skip = set()
397 | 
398 |         _display("Would remove:", will_remove)
399 |         _display("Would not remove (might be manually added):", will_skip)
400 |         _display("Would not remove (outside of prefix):", self._refuse)
401 |         if verbose:
402 |             _display("Will actually move:", compress_for_rename(self._paths))
403 | 
404 |         return ask("Proceed (Y/n)? ", ("y", "n", "")) != "n"
405 | 
406 |     def rollback(self) -> None:
407 |         """Rollback the changes previously made by remove()."""
408 |         if not self._moved_paths.can_rollback:
409 |             logger.error(
410 |                 "Can't roll back %s; was not uninstalled",
411 |                 self._dist.raw_name,
412 |             )
413 |             return
414 |         logger.info("Rolling back uninstall of %s", self._dist.raw_name)
415 |         self._moved_paths.rollback()
416 |         for pth in self._pth.values():
417 |             pth.rollback()
418 | 
419 |     def commit(self) -> None:
420 |         """Remove temporary save dir: rollback will no longer be possible."""
421 |         self._moved_paths.commit()
422 | 
423 |     @classmethod
424 |     def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet":
425 |         dist_location = dist.location
426 |         info_location = dist.info_location
427 |         if dist_location is None:
428 |             logger.info(
429 |                 "Not uninstalling %s since it is not installed",
430 |                 dist.canonical_name,
431 |             )
432 |             return cls(dist)
433 | 
434 |         normalized_dist_location = normalize_path(dist_location)
435 |         if not dist.local:
436 |             logger.info(
437 |                 "Not uninstalling %s at %s, outside environment %s",
438 |                 dist.canonical_name,
439 |                 normalized_dist_location,
440 |                 sys.prefix,
441 |             )
442 |             return cls(dist)
443 | 
444 |         if normalized_dist_location in {
445 |             p
446 |             for p in {sysconfig.get_path("stdlib"), sysconfig.get_path("platstdlib")}
447 |             if p
448 |         }:
449 |             logger.info(
450 |                 "Not uninstalling %s at %s, as it is in the standard library.",
451 |                 dist.canonical_name,
452 |                 normalized_dist_location,
453 |             )
454 |             return cls(dist)
455 | 
456 |         paths_to_remove = cls(dist)
457 |         develop_egg_link = egg_link_path_from_location(dist.raw_name)
458 | 
459 |         # Distribution is installed with metadata in a "flat" .egg-info
460 |         # directory. This means it is not a modern .dist-info installation, an
461 |         # egg, or legacy editable.
462 |         setuptools_flat_installation = (
463 |             dist.installed_with_setuptools_egg_info
464 |             and info_location is not None
465 |             and os.path.exists(info_location)
466 |             # If dist is editable and the location points to a ``.egg-info``,
467 |             # we are in fact in the legacy editable case.
468 |             and not info_location.endswith(f"{dist.setuptools_filename}.egg-info")
469 |         )
470 | 
471 |         # Uninstall cases order do matter as in the case of 2 installs of the
472 |         # same package, pip needs to uninstall the currently detected version
473 |         if setuptools_flat_installation:
474 |             if info_location is not None:
475 |                 paths_to_remove.add(info_location)
476 |             installed_files = dist.iter_declared_entries()
477 |             if installed_files is not None:
478 |                 for installed_file in installed_files:
479 |                     paths_to_remove.add(os.path.join(dist_location, installed_file))
480 |             # FIXME: need a test for this elif block
481 |             # occurs with --single-version-externally-managed/--record outside
482 |             # of pip
483 |             elif dist.is_file("top_level.txt"):
484 |                 try:
485 |                     namespace_packages = dist.read_text("namespace_packages.txt")
486 |                 except FileNotFoundError:
487 |                     namespaces = []
488 |                 else:
489 |                     namespaces = namespace_packages.splitlines(keepends=False)
490 |                 for top_level_pkg in [
491 |                     p
492 |                     for p in dist.read_text("top_level.txt").splitlines()
493 |                     if p and p not in namespaces
494 |                 ]:
495 |                     path = os.path.join(dist_location, top_level_pkg)
496 |                     paths_to_remove.add(path)
497 |                     paths_to_remove.add(f"{path}.py")
498 |                     paths_to_remove.add(f"{path}.pyc")
499 |                     paths_to_remove.add(f"{path}.pyo")
500 | 
501 |         elif dist.installed_by_distutils:
502 |             raise LegacyDistutilsInstall(distribution=dist)
503 | 
504 |         elif dist.installed_as_egg:
505 |             # package installed by easy_install
506 |             # We cannot match on dist.egg_name because it can slightly vary
507 |             # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg
508 |             paths_to_remove.add(dist_location)
509 |             easy_install_egg = os.path.split(dist_location)[1]
510 |             easy_install_pth = os.path.join(
511 |                 os.path.dirname(dist_location),
512 |                 "easy-install.pth",
513 |             )
514 |             paths_to_remove.add_pth(easy_install_pth, "./" + easy_install_egg)
515 | 
516 |         elif dist.installed_with_dist_info:
517 |             for path in uninstallation_paths(dist):
518 |                 paths_to_remove.add(path)
519 | 
520 |         elif develop_egg_link:
521 |             # PEP 660 modern editable is handled in the ``.dist-info`` case
522 |             # above, so this only covers the setuptools-style editable.
523 |             with open(develop_egg_link) as fh:
524 |                 link_pointer = os.path.normcase(fh.readline().strip())
525 |                 normalized_link_pointer = paths_to_remove._normalize_path_cached(
526 |                     link_pointer
527 |                 )
528 |             assert os.path.samefile(
529 |                 normalized_link_pointer, normalized_dist_location
530 |             ), (
531 |                 f"Egg-link {develop_egg_link} (to {link_pointer}) does not match "
532 |                 f"installed location of {dist.raw_name} (at {dist_location})"
533 |             )
534 |             paths_to_remove.add(develop_egg_link)
535 |             easy_install_pth = os.path.join(
536 |                 os.path.dirname(develop_egg_link), "easy-install.pth"
537 |             )
538 |             paths_to_remove.add_pth(easy_install_pth, dist_location)
539 | 
540 |         else:
541 |             logger.debug(
542 |                 "Not sure how to uninstall: %s - Check: %s",
543 |                 dist,
544 |                 dist_location,
545 |             )
546 | 
547 |         if dist.in_usersite:
548 |             bin_dir = get_bin_user()
549 |         else:
550 |             bin_dir = get_bin_prefix()
551 | 
552 |         # find distutils scripts= scripts
553 |         try:
554 |             for script in dist.iter_distutils_script_names():
555 |                 paths_to_remove.add(os.path.join(bin_dir, script))
556 |                 if WINDOWS:
557 |                     paths_to_remove.add(os.path.join(bin_dir, f"{script}.bat"))
558 |         except (FileNotFoundError, NotADirectoryError):
559 |             pass
560 | 
561 |         # find console_scripts and gui_scripts
562 |         def iter_scripts_to_remove(
563 |             dist: BaseDistribution,
564 |             bin_dir: str,
565 |         ) -> Generator[str, None, None]:
566 |             for entry_point in dist.iter_entry_points():
567 |                 if entry_point.group == "console_scripts":
568 |                     yield from _script_names(bin_dir, entry_point.name, False)
569 |                 elif entry_point.group == "gui_scripts":
570 |                     yield from _script_names(bin_dir, entry_point.name, True)
571 | 
572 |         for s in iter_scripts_to_remove(dist, bin_dir):
573 |             paths_to_remove.add(s)
574 | 
575 |         return paths_to_remove
576 | 
577 | 
578 | class UninstallPthEntries:
579 |     def __init__(self, pth_file: str) -> None:
580 |         self.file = pth_file
581 |         self.entries: Set[str] = set()
582 |         self._saved_lines: Optional[List[bytes]] = None
583 | 
584 |     def add(self, entry: str) -> None:
585 |         entry = os.path.normcase(entry)
586 |         # On Windows, os.path.normcase converts the entry to use
587 |         # backslashes.  This is correct for entries that describe absolute
588 |         # paths outside of site-packages, but all the others use forward
589 |         # slashes.
590 |         # os.path.splitdrive is used instead of os.path.isabs because isabs
591 |         # treats non-absolute paths with drive letter markings like c:foo\bar
592 |         # as absolute paths. It also does not recognize UNC paths if they don't
593 |         # have more than "\\sever\share". Valid examples: "\\server\share\" or
594 |         # "\\server\share\folder".
595 |         if WINDOWS and not os.path.splitdrive(entry)[0]:
596 |             entry = entry.replace("\\", "/")
597 |         self.entries.add(entry)
598 | 
599 |     def remove(self) -> None:
600 |         logger.verbose("Removing pth entries from %s:", self.file)
601 | 
602 |         # If the file doesn't exist, log a warning and return
603 |         if not os.path.isfile(self.file):
604 |             logger.warning("Cannot remove entries from nonexistent file %s", self.file)
605 |             return
606 |         with open(self.file, "rb") as fh:
607 |             # windows uses '\r\n' with py3k, but uses '\n' with py2.x
608 |             lines = fh.readlines()
609 |             self._saved_lines = lines
610 |         if any(b"\r\n" in line for line in lines):
611 |             endline = "\r\n"
612 |         else:
613 |             endline = "\n"
614 |         # handle missing trailing newline
615 |         if lines and not lines[-1].endswith(endline.encode("utf-8")):
616 |             lines[-1] = lines[-1] + endline.encode("utf-8")
617 |         for entry in self.entries:
618 |             try:
619 |                 logger.verbose("Removing entry: %s", entry)
620 |                 lines.remove((entry + endline).encode("utf-8"))
621 |             except ValueError:
622 |                 pass
623 |         with open(self.file, "wb") as fh:
624 |             fh.writelines(lines)
625 | 
626 |     def rollback(self) -> bool:
627 |         if self._saved_lines is None:
628 |             logger.error("Cannot roll back changes to %s, none were made", self.file)
629 |             return False
630 |         logger.debug("Rolling %s back to previous state", self.file)
631 |         with open(self.file, "wb") as fh:
632 |             fh.writelines(self._saved_lines)
633 |         return True
634 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/jinja2/utils.py:
--------------------------------------------------------------------------------

```python
  1 | import enum
  2 | import json
  3 | import os
  4 | import re
  5 | import typing as t
  6 | from collections import abc
  7 | from collections import deque
  8 | from random import choice
  9 | from random import randrange
 10 | from threading import Lock
 11 | from types import CodeType
 12 | from urllib.parse import quote_from_bytes
 13 | 
 14 | import markupsafe
 15 | 
 16 | if t.TYPE_CHECKING:
 17 |     import typing_extensions as te
 18 | 
 19 | F = t.TypeVar("F", bound=t.Callable[..., t.Any])
 20 | 
 21 | # special singleton representing missing values for the runtime
 22 | missing: t.Any = type("MissingType", (), {"__repr__": lambda x: "missing"})()
 23 | 
 24 | internal_code: t.MutableSet[CodeType] = set()
 25 | 
 26 | concat = "".join
 27 | 
 28 | 
 29 | def pass_context(f: F) -> F:
 30 |     """Pass the :class:`~jinja2.runtime.Context` as the first argument
 31 |     to the decorated function when called while rendering a template.
 32 | 
 33 |     Can be used on functions, filters, and tests.
 34 | 
 35 |     If only ``Context.eval_context`` is needed, use
 36 |     :func:`pass_eval_context`. If only ``Context.environment`` is
 37 |     needed, use :func:`pass_environment`.
 38 | 
 39 |     .. versionadded:: 3.0.0
 40 |         Replaces ``contextfunction`` and ``contextfilter``.
 41 |     """
 42 |     f.jinja_pass_arg = _PassArg.context  # type: ignore
 43 |     return f
 44 | 
 45 | 
 46 | def pass_eval_context(f: F) -> F:
 47 |     """Pass the :class:`~jinja2.nodes.EvalContext` as the first argument
 48 |     to the decorated function when called while rendering a template.
 49 |     See :ref:`eval-context`.
 50 | 
 51 |     Can be used on functions, filters, and tests.
 52 | 
 53 |     If only ``EvalContext.environment`` is needed, use
 54 |     :func:`pass_environment`.
 55 | 
 56 |     .. versionadded:: 3.0.0
 57 |         Replaces ``evalcontextfunction`` and ``evalcontextfilter``.
 58 |     """
 59 |     f.jinja_pass_arg = _PassArg.eval_context  # type: ignore
 60 |     return f
 61 | 
 62 | 
 63 | def pass_environment(f: F) -> F:
 64 |     """Pass the :class:`~jinja2.Environment` as the first argument to
 65 |     the decorated function when called while rendering a template.
 66 | 
 67 |     Can be used on functions, filters, and tests.
 68 | 
 69 |     .. versionadded:: 3.0.0
 70 |         Replaces ``environmentfunction`` and ``environmentfilter``.
 71 |     """
 72 |     f.jinja_pass_arg = _PassArg.environment  # type: ignore
 73 |     return f
 74 | 
 75 | 
 76 | class _PassArg(enum.Enum):
 77 |     context = enum.auto()
 78 |     eval_context = enum.auto()
 79 |     environment = enum.auto()
 80 | 
 81 |     @classmethod
 82 |     def from_obj(cls, obj: F) -> t.Optional["_PassArg"]:
 83 |         if hasattr(obj, "jinja_pass_arg"):
 84 |             return obj.jinja_pass_arg  # type: ignore
 85 | 
 86 |         return None
 87 | 
 88 | 
 89 | def internalcode(f: F) -> F:
 90 |     """Marks the function as internally used"""
 91 |     internal_code.add(f.__code__)
 92 |     return f
 93 | 
 94 | 
 95 | def is_undefined(obj: t.Any) -> bool:
 96 |     """Check if the object passed is undefined.  This does nothing more than
 97 |     performing an instance check against :class:`Undefined` but looks nicer.
 98 |     This can be used for custom filters or tests that want to react to
 99 |     undefined variables.  For example a custom default filter can look like
100 |     this::
101 | 
102 |         def default(var, default=''):
103 |             if is_undefined(var):
104 |                 return default
105 |             return var
106 |     """
107 |     from .runtime import Undefined
108 | 
109 |     return isinstance(obj, Undefined)
110 | 
111 | 
112 | def consume(iterable: t.Iterable[t.Any]) -> None:
113 |     """Consumes an iterable without doing anything with it."""
114 |     for _ in iterable:
115 |         pass
116 | 
117 | 
118 | def clear_caches() -> None:
119 |     """Jinja keeps internal caches for environments and lexers.  These are
120 |     used so that Jinja doesn't have to recreate environments and lexers all
121 |     the time.  Normally you don't have to care about that but if you are
122 |     measuring memory consumption you may want to clean the caches.
123 |     """
124 |     from .environment import get_spontaneous_environment
125 |     from .lexer import _lexer_cache
126 | 
127 |     get_spontaneous_environment.cache_clear()
128 |     _lexer_cache.clear()
129 | 
130 | 
131 | def import_string(import_name: str, silent: bool = False) -> t.Any:
132 |     """Imports an object based on a string.  This is useful if you want to
133 |     use import paths as endpoints or something similar.  An import path can
134 |     be specified either in dotted notation (``xml.sax.saxutils.escape``)
135 |     or with a colon as object delimiter (``xml.sax.saxutils:escape``).
136 | 
137 |     If the `silent` is True the return value will be `None` if the import
138 |     fails.
139 | 
140 |     :return: imported object
141 |     """
142 |     try:
143 |         if ":" in import_name:
144 |             module, obj = import_name.split(":", 1)
145 |         elif "." in import_name:
146 |             module, _, obj = import_name.rpartition(".")
147 |         else:
148 |             return __import__(import_name)
149 |         return getattr(__import__(module, None, None, [obj]), obj)
150 |     except (ImportError, AttributeError):
151 |         if not silent:
152 |             raise
153 | 
154 | 
155 | def open_if_exists(filename: str, mode: str = "rb") -> t.Optional[t.IO[t.Any]]:
156 |     """Returns a file descriptor for the filename if that file exists,
157 |     otherwise ``None``.
158 |     """
159 |     if not os.path.isfile(filename):
160 |         return None
161 | 
162 |     return open(filename, mode)
163 | 
164 | 
165 | def object_type_repr(obj: t.Any) -> str:
166 |     """Returns the name of the object's type.  For some recognized
167 |     singletons the name of the object is returned instead. (For
168 |     example for `None` and `Ellipsis`).
169 |     """
170 |     if obj is None:
171 |         return "None"
172 |     elif obj is Ellipsis:
173 |         return "Ellipsis"
174 | 
175 |     cls = type(obj)
176 | 
177 |     if cls.__module__ == "builtins":
178 |         return f"{cls.__name__} object"
179 | 
180 |     return f"{cls.__module__}.{cls.__name__} object"
181 | 
182 | 
183 | def pformat(obj: t.Any) -> str:
184 |     """Format an object using :func:`pprint.pformat`."""
185 |     from pprint import pformat
186 | 
187 |     return pformat(obj)
188 | 
189 | 
190 | _http_re = re.compile(
191 |     r"""
192 |     ^
193 |     (
194 |         (https?://|www\.)  # scheme or www
195 |         (([\w%-]+\.)+)?  # subdomain
196 |         (
197 |             [a-z]{2,63}  # basic tld
198 |         |
199 |             xn--[\w%]{2,59}  # idna tld
200 |         )
201 |     |
202 |         ([\w%-]{2,63}\.)+  # basic domain
203 |         (com|net|int|edu|gov|org|info|mil)  # basic tld
204 |     |
205 |         (https?://)  # scheme
206 |         (
207 |             (([\d]{1,3})(\.[\d]{1,3}){3})  # IPv4
208 |         |
209 |             (\[([\da-f]{0,4}:){2}([\da-f]{0,4}:?){1,6}])  # IPv6
210 |         )
211 |     )
212 |     (?::[\d]{1,5})?  # port
213 |     (?:[/?#]\S*)?  # path, query, and fragment
214 |     $
215 |     """,
216 |     re.IGNORECASE | re.VERBOSE,
217 | )
218 | _email_re = re.compile(r"^\S+@\w[\w.-]*\.\w+$")
219 | 
220 | 
221 | def urlize(
222 |     text: str,
223 |     trim_url_limit: t.Optional[int] = None,
224 |     rel: t.Optional[str] = None,
225 |     target: t.Optional[str] = None,
226 |     extra_schemes: t.Optional[t.Iterable[str]] = None,
227 | ) -> str:
228 |     """Convert URLs in text into clickable links.
229 | 
230 |     This may not recognize links in some situations. Usually, a more
231 |     comprehensive formatter, such as a Markdown library, is a better
232 |     choice.
233 | 
234 |     Works on ``http://``, ``https://``, ``www.``, ``mailto:``, and email
235 |     addresses. Links with trailing punctuation (periods, commas, closing
236 |     parentheses) and leading punctuation (opening parentheses) are
237 |     recognized excluding the punctuation. Email addresses that include
238 |     header fields are not recognized (for example,
239 |     ``mailto:[email protected][email protected]``).
240 | 
241 |     :param text: Original text containing URLs to link.
242 |     :param trim_url_limit: Shorten displayed URL values to this length.
243 |     :param target: Add the ``target`` attribute to links.
244 |     :param rel: Add the ``rel`` attribute to links.
245 |     :param extra_schemes: Recognize URLs that start with these schemes
246 |         in addition to the default behavior.
247 | 
248 |     .. versionchanged:: 3.0
249 |         The ``extra_schemes`` parameter was added.
250 | 
251 |     .. versionchanged:: 3.0
252 |         Generate ``https://`` links for URLs without a scheme.
253 | 
254 |     .. versionchanged:: 3.0
255 |         The parsing rules were updated. Recognize email addresses with
256 |         or without the ``mailto:`` scheme. Validate IP addresses. Ignore
257 |         parentheses and brackets in more cases.
258 |     """
259 |     if trim_url_limit is not None:
260 | 
261 |         def trim_url(x: str) -> str:
262 |             if len(x) > trim_url_limit:
263 |                 return f"{x[:trim_url_limit]}..."
264 | 
265 |             return x
266 | 
267 |     else:
268 | 
269 |         def trim_url(x: str) -> str:
270 |             return x
271 | 
272 |     words = re.split(r"(\s+)", str(markupsafe.escape(text)))
273 |     rel_attr = f' rel="{markupsafe.escape(rel)}"' if rel else ""
274 |     target_attr = f' target="{markupsafe.escape(target)}"' if target else ""
275 | 
276 |     for i, word in enumerate(words):
277 |         head, middle, tail = "", word, ""
278 |         match = re.match(r"^([(<]|&lt;)+", middle)
279 | 
280 |         if match:
281 |             head = match.group()
282 |             middle = middle[match.end() :]
283 | 
284 |         # Unlike lead, which is anchored to the start of the string,
285 |         # need to check that the string ends with any of the characters
286 |         # before trying to match all of them, to avoid backtracking.
287 |         if middle.endswith((")", ">", ".", ",", "\n", "&gt;")):
288 |             match = re.search(r"([)>.,\n]|&gt;)+$", middle)
289 | 
290 |             if match:
291 |                 tail = match.group()
292 |                 middle = middle[: match.start()]
293 | 
294 |         # Prefer balancing parentheses in URLs instead of ignoring a
295 |         # trailing character.
296 |         for start_char, end_char in ("(", ")"), ("<", ">"), ("&lt;", "&gt;"):
297 |             start_count = middle.count(start_char)
298 | 
299 |             if start_count <= middle.count(end_char):
300 |                 # Balanced, or lighter on the left
301 |                 continue
302 | 
303 |             # Move as many as possible from the tail to balance
304 |             for _ in range(min(start_count, tail.count(end_char))):
305 |                 end_index = tail.index(end_char) + len(end_char)
306 |                 # Move anything in the tail before the end char too
307 |                 middle += tail[:end_index]
308 |                 tail = tail[end_index:]
309 | 
310 |         if _http_re.match(middle):
311 |             if middle.startswith("https://") or middle.startswith("http://"):
312 |                 middle = (
313 |                     f'<a href="{middle}"{rel_attr}{target_attr}>{trim_url(middle)}</a>'
314 |                 )
315 |             else:
316 |                 middle = (
317 |                     f'<a href="https://{middle}"{rel_attr}{target_attr}>'
318 |                     f"{trim_url(middle)}</a>"
319 |                 )
320 | 
321 |         elif middle.startswith("mailto:") and _email_re.match(middle[7:]):
322 |             middle = f'<a href="{middle}">{middle[7:]}</a>'
323 | 
324 |         elif (
325 |             "@" in middle
326 |             and not middle.startswith("www.")
327 |             and ":" not in middle
328 |             and _email_re.match(middle)
329 |         ):
330 |             middle = f'<a href="mailto:{middle}">{middle}</a>'
331 | 
332 |         elif extra_schemes is not None:
333 |             for scheme in extra_schemes:
334 |                 if middle != scheme and middle.startswith(scheme):
335 |                     middle = f'<a href="{middle}"{rel_attr}{target_attr}>{middle}</a>'
336 | 
337 |         words[i] = f"{head}{middle}{tail}"
338 | 
339 |     return "".join(words)
340 | 
341 | 
342 | def generate_lorem_ipsum(
343 |     n: int = 5, html: bool = True, min: int = 20, max: int = 100
344 | ) -> str:
345 |     """Generate some lorem ipsum for the template."""
346 |     from .constants import LOREM_IPSUM_WORDS
347 | 
348 |     words = LOREM_IPSUM_WORDS.split()
349 |     result = []
350 | 
351 |     for _ in range(n):
352 |         next_capitalized = True
353 |         last_comma = last_fullstop = 0
354 |         word = None
355 |         last = None
356 |         p = []
357 | 
358 |         # each paragraph contains out of 20 to 100 words.
359 |         for idx, _ in enumerate(range(randrange(min, max))):
360 |             while True:
361 |                 word = choice(words)
362 |                 if word != last:
363 |                     last = word
364 |                     break
365 |             if next_capitalized:
366 |                 word = word.capitalize()
367 |                 next_capitalized = False
368 |             # add commas
369 |             if idx - randrange(3, 8) > last_comma:
370 |                 last_comma = idx
371 |                 last_fullstop += 2
372 |                 word += ","
373 |             # add end of sentences
374 |             if idx - randrange(10, 20) > last_fullstop:
375 |                 last_comma = last_fullstop = idx
376 |                 word += "."
377 |                 next_capitalized = True
378 |             p.append(word)
379 | 
380 |         # ensure that the paragraph ends with a dot.
381 |         p_str = " ".join(p)
382 | 
383 |         if p_str.endswith(","):
384 |             p_str = p_str[:-1] + "."
385 |         elif not p_str.endswith("."):
386 |             p_str += "."
387 | 
388 |         result.append(p_str)
389 | 
390 |     if not html:
391 |         return "\n\n".join(result)
392 |     return markupsafe.Markup(
393 |         "\n".join(f"<p>{markupsafe.escape(x)}</p>" for x in result)
394 |     )
395 | 
396 | 
397 | def url_quote(obj: t.Any, charset: str = "utf-8", for_qs: bool = False) -> str:
398 |     """Quote a string for use in a URL using the given charset.
399 | 
400 |     :param obj: String or bytes to quote. Other types are converted to
401 |         string then encoded to bytes using the given charset.
402 |     :param charset: Encode text to bytes using this charset.
403 |     :param for_qs: Quote "/" and use "+" for spaces.
404 |     """
405 |     if not isinstance(obj, bytes):
406 |         if not isinstance(obj, str):
407 |             obj = str(obj)
408 | 
409 |         obj = obj.encode(charset)
410 | 
411 |     safe = b"" if for_qs else b"/"
412 |     rv = quote_from_bytes(obj, safe)
413 | 
414 |     if for_qs:
415 |         rv = rv.replace("%20", "+")
416 | 
417 |     return rv
418 | 
419 | 
420 | @abc.MutableMapping.register
421 | class LRUCache:
422 |     """A simple LRU Cache implementation."""
423 | 
424 |     # this is fast for small capacities (something below 1000) but doesn't
425 |     # scale.  But as long as it's only used as storage for templates this
426 |     # won't do any harm.
427 | 
428 |     def __init__(self, capacity: int) -> None:
429 |         self.capacity = capacity
430 |         self._mapping: t.Dict[t.Any, t.Any] = {}
431 |         self._queue: "te.Deque[t.Any]" = deque()
432 |         self._postinit()
433 | 
434 |     def _postinit(self) -> None:
435 |         # alias all queue methods for faster lookup
436 |         self._popleft = self._queue.popleft
437 |         self._pop = self._queue.pop
438 |         self._remove = self._queue.remove
439 |         self._wlock = Lock()
440 |         self._append = self._queue.append
441 | 
442 |     def __getstate__(self) -> t.Mapping[str, t.Any]:
443 |         return {
444 |             "capacity": self.capacity,
445 |             "_mapping": self._mapping,
446 |             "_queue": self._queue,
447 |         }
448 | 
449 |     def __setstate__(self, d: t.Mapping[str, t.Any]) -> None:
450 |         self.__dict__.update(d)
451 |         self._postinit()
452 | 
453 |     def __getnewargs__(self) -> t.Tuple[t.Any, ...]:
454 |         return (self.capacity,)
455 | 
456 |     def copy(self) -> "LRUCache":
457 |         """Return a shallow copy of the instance."""
458 |         rv = self.__class__(self.capacity)
459 |         rv._mapping.update(self._mapping)
460 |         rv._queue.extend(self._queue)
461 |         return rv
462 | 
463 |     def get(self, key: t.Any, default: t.Any = None) -> t.Any:
464 |         """Return an item from the cache dict or `default`"""
465 |         try:
466 |             return self[key]
467 |         except KeyError:
468 |             return default
469 | 
470 |     def setdefault(self, key: t.Any, default: t.Any = None) -> t.Any:
471 |         """Set `default` if the key is not in the cache otherwise
472 |         leave unchanged. Return the value of this key.
473 |         """
474 |         try:
475 |             return self[key]
476 |         except KeyError:
477 |             self[key] = default
478 |             return default
479 | 
480 |     def clear(self) -> None:
481 |         """Clear the cache."""
482 |         with self._wlock:
483 |             self._mapping.clear()
484 |             self._queue.clear()
485 | 
486 |     def __contains__(self, key: t.Any) -> bool:
487 |         """Check if a key exists in this cache."""
488 |         return key in self._mapping
489 | 
490 |     def __len__(self) -> int:
491 |         """Return the current size of the cache."""
492 |         return len(self._mapping)
493 | 
494 |     def __repr__(self) -> str:
495 |         return f"<{type(self).__name__} {self._mapping!r}>"
496 | 
497 |     def __getitem__(self, key: t.Any) -> t.Any:
498 |         """Get an item from the cache. Moves the item up so that it has the
499 |         highest priority then.
500 | 
501 |         Raise a `KeyError` if it does not exist.
502 |         """
503 |         with self._wlock:
504 |             rv = self._mapping[key]
505 | 
506 |             if self._queue[-1] != key:
507 |                 try:
508 |                     self._remove(key)
509 |                 except ValueError:
510 |                     # if something removed the key from the container
511 |                     # when we read, ignore the ValueError that we would
512 |                     # get otherwise.
513 |                     pass
514 | 
515 |                 self._append(key)
516 | 
517 |             return rv
518 | 
519 |     def __setitem__(self, key: t.Any, value: t.Any) -> None:
520 |         """Sets the value for an item. Moves the item up so that it
521 |         has the highest priority then.
522 |         """
523 |         with self._wlock:
524 |             if key in self._mapping:
525 |                 self._remove(key)
526 |             elif len(self._mapping) == self.capacity:
527 |                 del self._mapping[self._popleft()]
528 | 
529 |             self._append(key)
530 |             self._mapping[key] = value
531 | 
532 |     def __delitem__(self, key: t.Any) -> None:
533 |         """Remove an item from the cache dict.
534 |         Raise a `KeyError` if it does not exist.
535 |         """
536 |         with self._wlock:
537 |             del self._mapping[key]
538 | 
539 |             try:
540 |                 self._remove(key)
541 |             except ValueError:
542 |                 pass
543 | 
544 |     def items(self) -> t.Iterable[t.Tuple[t.Any, t.Any]]:
545 |         """Return a list of items."""
546 |         result = [(key, self._mapping[key]) for key in list(self._queue)]
547 |         result.reverse()
548 |         return result
549 | 
550 |     def values(self) -> t.Iterable[t.Any]:
551 |         """Return a list of all values."""
552 |         return [x[1] for x in self.items()]
553 | 
554 |     def keys(self) -> t.Iterable[t.Any]:
555 |         """Return a list of all keys ordered by most recent usage."""
556 |         return list(self)
557 | 
558 |     def __iter__(self) -> t.Iterator[t.Any]:
559 |         return reversed(tuple(self._queue))
560 | 
561 |     def __reversed__(self) -> t.Iterator[t.Any]:
562 |         """Iterate over the keys in the cache dict, oldest items
563 |         coming first.
564 |         """
565 |         return iter(tuple(self._queue))
566 | 
567 |     __copy__ = copy
568 | 
569 | 
570 | def select_autoescape(
571 |     enabled_extensions: t.Collection[str] = ("html", "htm", "xml"),
572 |     disabled_extensions: t.Collection[str] = (),
573 |     default_for_string: bool = True,
574 |     default: bool = False,
575 | ) -> t.Callable[[t.Optional[str]], bool]:
576 |     """Intelligently sets the initial value of autoescaping based on the
577 |     filename of the template.  This is the recommended way to configure
578 |     autoescaping if you do not want to write a custom function yourself.
579 | 
580 |     If you want to enable it for all templates created from strings or
581 |     for all templates with `.html` and `.xml` extensions::
582 | 
583 |         from jinja2 import Environment, select_autoescape
584 |         env = Environment(autoescape=select_autoescape(
585 |             enabled_extensions=('html', 'xml'),
586 |             default_for_string=True,
587 |         ))
588 | 
589 |     Example configuration to turn it on at all times except if the template
590 |     ends with `.txt`::
591 | 
592 |         from jinja2 import Environment, select_autoescape
593 |         env = Environment(autoescape=select_autoescape(
594 |             disabled_extensions=('txt',),
595 |             default_for_string=True,
596 |             default=True,
597 |         ))
598 | 
599 |     The `enabled_extensions` is an iterable of all the extensions that
600 |     autoescaping should be enabled for.  Likewise `disabled_extensions` is
601 |     a list of all templates it should be disabled for.  If a template is
602 |     loaded from a string then the default from `default_for_string` is used.
603 |     If nothing matches then the initial value of autoescaping is set to the
604 |     value of `default`.
605 | 
606 |     For security reasons this function operates case insensitive.
607 | 
608 |     .. versionadded:: 2.9
609 |     """
610 |     enabled_patterns = tuple(f".{x.lstrip('.').lower()}" for x in enabled_extensions)
611 |     disabled_patterns = tuple(f".{x.lstrip('.').lower()}" for x in disabled_extensions)
612 | 
613 |     def autoescape(template_name: t.Optional[str]) -> bool:
614 |         if template_name is None:
615 |             return default_for_string
616 |         template_name = template_name.lower()
617 |         if template_name.endswith(enabled_patterns):
618 |             return True
619 |         if template_name.endswith(disabled_patterns):
620 |             return False
621 |         return default
622 | 
623 |     return autoescape
624 | 
625 | 
626 | def htmlsafe_json_dumps(
627 |     obj: t.Any, dumps: t.Optional[t.Callable[..., str]] = None, **kwargs: t.Any
628 | ) -> markupsafe.Markup:
629 |     """Serialize an object to a string of JSON with :func:`json.dumps`,
630 |     then replace HTML-unsafe characters with Unicode escapes and mark
631 |     the result safe with :class:`~markupsafe.Markup`.
632 | 
633 |     This is available in templates as the ``|tojson`` filter.
634 | 
635 |     The following characters are escaped: ``<``, ``>``, ``&``, ``'``.
636 | 
637 |     The returned string is safe to render in HTML documents and
638 |     ``<script>`` tags. The exception is in HTML attributes that are
639 |     double quoted; either use single quotes or the ``|forceescape``
640 |     filter.
641 | 
642 |     :param obj: The object to serialize to JSON.
643 |     :param dumps: The ``dumps`` function to use. Defaults to
644 |         ``env.policies["json.dumps_function"]``, which defaults to
645 |         :func:`json.dumps`.
646 |     :param kwargs: Extra arguments to pass to ``dumps``. Merged onto
647 |         ``env.policies["json.dumps_kwargs"]``.
648 | 
649 |     .. versionchanged:: 3.0
650 |         The ``dumper`` parameter is renamed to ``dumps``.
651 | 
652 |     .. versionadded:: 2.9
653 |     """
654 |     if dumps is None:
655 |         dumps = json.dumps
656 | 
657 |     return markupsafe.Markup(
658 |         dumps(obj, **kwargs)
659 |         .replace("<", "\\u003c")
660 |         .replace(">", "\\u003e")
661 |         .replace("&", "\\u0026")
662 |         .replace("'", "\\u0027")
663 |     )
664 | 
665 | 
666 | class Cycler:
667 |     """Cycle through values by yield them one at a time, then restarting
668 |     once the end is reached. Available as ``cycler`` in templates.
669 | 
670 |     Similar to ``loop.cycle``, but can be used outside loops or across
671 |     multiple loops. For example, render a list of folders and files in a
672 |     list, alternating giving them "odd" and "even" classes.
673 | 
674 |     .. code-block:: html+jinja
675 | 
676 |         {% set row_class = cycler("odd", "even") %}
677 |         <ul class="browser">
678 |         {% for folder in folders %}
679 |           <li class="folder {{ row_class.next() }}">{{ folder }}
680 |         {% endfor %}
681 |         {% for file in files %}
682 |           <li class="file {{ row_class.next() }}">{{ file }}
683 |         {% endfor %}
684 |         </ul>
685 | 
686 |     :param items: Each positional argument will be yielded in the order
687 |         given for each cycle.
688 | 
689 |     .. versionadded:: 2.1
690 |     """
691 | 
692 |     def __init__(self, *items: t.Any) -> None:
693 |         if not items:
694 |             raise RuntimeError("at least one item has to be provided")
695 |         self.items = items
696 |         self.pos = 0
697 | 
698 |     def reset(self) -> None:
699 |         """Resets the current item to the first item."""
700 |         self.pos = 0
701 | 
702 |     @property
703 |     def current(self) -> t.Any:
704 |         """Return the current item. Equivalent to the item that will be
705 |         returned next time :meth:`next` is called.
706 |         """
707 |         return self.items[self.pos]
708 | 
709 |     def next(self) -> t.Any:
710 |         """Return the current item, then advance :attr:`current` to the
711 |         next item.
712 |         """
713 |         rv = self.current
714 |         self.pos = (self.pos + 1) % len(self.items)
715 |         return rv
716 | 
717 |     __next__ = next
718 | 
719 | 
720 | class Joiner:
721 |     """A joining helper for templates."""
722 | 
723 |     def __init__(self, sep: str = ", ") -> None:
724 |         self.sep = sep
725 |         self.used = False
726 | 
727 |     def __call__(self) -> str:
728 |         if not self.used:
729 |             self.used = True
730 |             return ""
731 |         return self.sep
732 | 
733 | 
734 | class Namespace:
735 |     """A namespace object that can hold arbitrary attributes.  It may be
736 |     initialized from a dictionary or with keyword arguments."""
737 | 
738 |     def __init__(*args: t.Any, **kwargs: t.Any) -> None:  # noqa: B902
739 |         self, args = args[0], args[1:]
740 |         self.__attrs = dict(*args, **kwargs)
741 | 
742 |     def __getattribute__(self, name: str) -> t.Any:
743 |         # __class__ is needed for the awaitable check in async mode
744 |         if name in {"_Namespace__attrs", "__class__"}:
745 |             return object.__getattribute__(self, name)
746 |         try:
747 |             return self.__attrs[name]
748 |         except KeyError:
749 |             raise AttributeError(name) from None
750 | 
751 |     def __setitem__(self, name: str, value: t.Any) -> None:
752 |         self.__attrs[name] = value
753 | 
754 |     def __repr__(self) -> str:
755 |         return f"<Namespace {self.__attrs!r}>"
756 | 
```
Page 80/168FirstPrevNextLast