FerrellSyntheticIntelligence commited on
Commit
f530c59
Β·
verified Β·
1 Parent(s): 4cb4369

Upload folder using huggingface_hub (part 9)

Browse files
This view is limited to 50 files because it contains too many changes. Β  See raw diff
Files changed (50) hide show
  1. .gitattributes +20 -0
  2. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/INSTALLER +1 -0
  3. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/METADATA +110 -0
  4. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/RECORD +885 -0
  5. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/REQUESTED +0 -0
  6. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/WHEEL +4 -0
  7. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/entry_points.txt +4 -0
  8. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/AUTHORS.txt +888 -0
  9. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/LICENSE.txt +20 -0
  10. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
  11. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
  12. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
  13. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
  14. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
  15. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
  16. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
  17. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
  18. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
  19. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
  20. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
  21. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
  22. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
  23. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
  24. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
  25. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
  26. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
  27. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
  28. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
  29. .venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
  30. .venv/lib/python3.12/site-packages/pip/_vendor/rich/prompt.py +400 -0
  31. .venv/lib/python3.12/site-packages/pip/_vendor/rich/protocol.py +42 -0
  32. .venv/lib/python3.12/site-packages/pip/_vendor/rich/py.typed +0 -0
  33. .venv/lib/python3.12/site-packages/pip/_vendor/rich/region.py +10 -0
  34. .venv/lib/python3.12/site-packages/pip/_vendor/rich/repr.py +149 -0
  35. .venv/lib/python3.12/site-packages/pip/_vendor/rich/rule.py +130 -0
  36. .venv/lib/python3.12/site-packages/pip/_vendor/rich/scope.py +86 -0
  37. .venv/lib/python3.12/site-packages/pip/_vendor/rich/screen.py +54 -0
  38. .venv/lib/python3.12/site-packages/pip/_vendor/rich/segment.py +752 -0
  39. .venv/lib/python3.12/site-packages/pip/_vendor/rich/spinner.py +132 -0
  40. .venv/lib/python3.12/site-packages/pip/_vendor/rich/status.py +131 -0
  41. .venv/lib/python3.12/site-packages/pip/_vendor/rich/style.py +792 -0
  42. .venv/lib/python3.12/site-packages/pip/_vendor/rich/styled.py +42 -0
  43. .venv/lib/python3.12/site-packages/pip/_vendor/rich/syntax.py +985 -0
  44. .venv/lib/python3.12/site-packages/pip/_vendor/rich/table.py +1006 -0
  45. .venv/lib/python3.12/site-packages/pip/_vendor/rich/terminal_theme.py +153 -0
  46. .venv/lib/python3.12/site-packages/pip/_vendor/rich/text.py +1361 -0
  47. .venv/lib/python3.12/site-packages/pip/_vendor/rich/theme.py +115 -0
  48. .venv/lib/python3.12/site-packages/pip/_vendor/rich/themes.py +5 -0
  49. .venv/lib/python3.12/site-packages/pip/_vendor/rich/traceback.py +899 -0
  50. .venv/lib/python3.12/site-packages/pip/_vendor/rich/tree.py +257 -0
.gitattributes CHANGED
@@ -78,3 +78,23 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
78
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/t64.exe filter=lfs diff=lfs merge=lfs -text
79
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64-arm.exe filter=lfs diff=lfs merge=lfs -text
80
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64.exe filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/t64.exe filter=lfs diff=lfs merge=lfs -text
79
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64-arm.exe filter=lfs diff=lfs merge=lfs -text
80
  .venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64.exe filter=lfs diff=lfs merge=lfs -text
81
+ .venv/lib/python3.12/site-packages/pyarrow/_acero.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
82
+ .venv/lib/python3.12/site-packages/pyarrow/_azurefs.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
83
+ .venv/lib/python3.12/site-packages/pyarrow/_compute.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
84
+ .venv/lib/python3.12/site-packages/pyarrow/_csv.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
85
+ .venv/lib/python3.12/site-packages/pyarrow/_dataset.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
86
+ .venv/lib/python3.12/site-packages/pyarrow/_dataset_orc.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
87
+ .venv/lib/python3.12/site-packages/pyarrow/_dataset_parquet.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
88
+ .venv/lib/python3.12/site-packages/pyarrow/_dataset_parquet_encryption.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
89
+ .venv/lib/python3.12/site-packages/pyarrow/_feather.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
90
+ .venv/lib/python3.12/site-packages/pyarrow/_flight.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
91
+ .venv/lib/python3.12/site-packages/pyarrow/_fs.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
92
+ .venv/lib/python3.12/site-packages/pyarrow/_gcsfs.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
93
+ .venv/lib/python3.12/site-packages/pyarrow/_hdfs.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
94
+ .venv/lib/python3.12/site-packages/pyarrow/_json.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
95
+ .venv/lib/python3.12/site-packages/pyarrow/_orc.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
96
+ .venv/lib/python3.12/site-packages/pyarrow/_parquet.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
97
+ .venv/lib/python3.12/site-packages/pyarrow/_parquet_encryption.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
98
+ .venv/lib/python3.12/site-packages/pyarrow/_pyarrow_cpp_tests.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
99
+ .venv/lib/python3.12/site-packages/pyarrow/_s3fs.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
100
+ .venv/lib/python3.12/site-packages/pyarrow/_substrait.cpython-312-aarch64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/METADATA ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: pip
3
+ Version: 26.2
4
+ Summary: The PyPA recommended tool for installing Python packages.
5
+ Author-email: The pip developers <distutils-sig@python.org>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/x-rst
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Software Development :: Build Tools
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: 3.15
21
+ Classifier: Programming Language :: Python :: Implementation :: CPython
22
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
23
+ License-File: AUTHORS.txt
24
+ License-File: LICENSE.txt
25
+ License-File: src/pip/_vendor/cachecontrol/LICENSE.txt
26
+ License-File: src/pip/_vendor/certifi/LICENSE
27
+ License-File: src/pip/_vendor/distlib/LICENSE.txt
28
+ License-File: src/pip/_vendor/distro/LICENSE
29
+ License-File: src/pip/_vendor/idna/LICENSE.md
30
+ License-File: src/pip/_vendor/msgpack/COPYING
31
+ License-File: src/pip/_vendor/packaging/LICENSE
32
+ License-File: src/pip/_vendor/packaging/LICENSE.APACHE
33
+ License-File: src/pip/_vendor/packaging/LICENSE.BSD
34
+ License-File: src/pip/_vendor/pkg_resources/LICENSE
35
+ License-File: src/pip/_vendor/platformdirs/LICENSE
36
+ License-File: src/pip/_vendor/pygments/LICENSE
37
+ License-File: src/pip/_vendor/pyproject_hooks/LICENSE
38
+ License-File: src/pip/_vendor/requests/LICENSE
39
+ License-File: src/pip/_vendor/resolvelib/LICENSE
40
+ License-File: src/pip/_vendor/rich/LICENSE
41
+ License-File: src/pip/_vendor/tomli/LICENSE
42
+ License-File: src/pip/_vendor/tomli_w/LICENSE
43
+ License-File: src/pip/_vendor/truststore/LICENSE
44
+ License-File: src/pip/_vendor/urllib3/LICENSE.txt
45
+ Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
46
+ Project-URL: Documentation, https://pip.pypa.io
47
+ Project-URL: Homepage, https://pip.pypa.io/
48
+ Project-URL: Source, https://github.com/pypa/pip
49
+
50
+ pip - The Python Package Installer
51
+ ==================================
52
+
53
+ .. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg
54
+ :target: https://pypi.org/project/pip/
55
+ :alt: PyPI
56
+
57
+ .. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip
58
+ :target: https://pypi.org/project/pip
59
+ :alt: PyPI - Python Version
60
+
61
+ .. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest
62
+ :target: https://pip.pypa.io/en/latest
63
+ :alt: Documentation
64
+
65
+ |pypi-version| |python-versions| |docs-badge|
66
+
67
+ Pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
68
+
69
+ Please take a look at our documentation for how to install and use pip:
70
+
71
+ * `Installation`_
72
+ * `Usage`_
73
+
74
+ We release updates regularly, with a new version every 3 months. Find more details in our documentation:
75
+
76
+ * `Release notes`_
77
+ * `Release process`_
78
+
79
+ If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
80
+
81
+ * `Issue tracking`_
82
+ * `Discourse channel`_
83
+ * `User IRC`_
84
+
85
+ If you want to get involved, head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
86
+
87
+ * `GitHub page`_
88
+ * `Development documentation`_
89
+ * `Development IRC`_
90
+
91
+ Code of Conduct
92
+ ---------------
93
+
94
+ Everyone interacting in the pip project's codebases, issue trackers, chat
95
+ rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
96
+
97
+ .. _package installer: https://packaging.python.org/guides/tool-recommendations/
98
+ .. _Python Package Index: https://pypi.org
99
+ .. _Installation: https://pip.pypa.io/en/stable/installation/
100
+ .. _Usage: https://pip.pypa.io/en/stable/
101
+ .. _Release notes: https://pip.pypa.io/en/stable/news.html
102
+ .. _Release process: https://pip.pypa.io/en/latest/development/release-process/
103
+ .. _GitHub page: https://github.com/pypa/pip
104
+ .. _Development documentation: https://pip.pypa.io/en/latest/development
105
+ .. _Issue tracking: https://github.com/pypa/pip/issues
106
+ .. _Discourse channel: https://discuss.python.org/c/packaging
107
+ .. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
108
+ .. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
109
+ .. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
110
+
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/RECORD ADDED
@@ -0,0 +1,885 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/pip,sha256=4G3tRQDfGPYE1gYSAfXoY4NkSind4RVuqKeM-i-Bb5A,274
2
+ ../../../bin/pip3,sha256=4G3tRQDfGPYE1gYSAfXoY4NkSind4RVuqKeM-i-Bb5A,274
3
+ ../../../bin/pip3.12,sha256=4G3tRQDfGPYE1gYSAfXoY4NkSind4RVuqKeM-i-Bb5A,274
4
+ pip-26.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
5
+ pip-26.2.dist-info/METADATA,sha256=wKcTSK4V341FIPhD3DO36evBk_qONBgQ8D6JJ1Samfk,4615
6
+ pip-26.2.dist-info/RECORD,,
7
+ pip-26.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ pip-26.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
9
+ pip-26.2.dist-info/entry_points.txt,sha256=Vhf8s0IYgX37mtd4vGL73BPcxdKnqeCFPzB5-d30x8o,84
10
+ pip-26.2.dist-info/licenses/AUTHORS.txt,sha256=TrH7FwXi3viY6BvLoZw6rIBiDSe6NWnWpt97RinRtcI,12139
11
+ pip-26.2.dist-info/licenses/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
12
+ pip-26.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt,sha256=hu7uh74qQ_P_H1ZJb0UfaSQ5JvAl_tuwM2ZsMExMFhs,558
13
+ pip-26.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989
14
+ pip-26.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt,sha256=gI4QyKarjesUn_mz-xn0R6gICUYG1xKpylf-rTVSWZ0,14531
15
+ pip-26.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
16
+ pip-26.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md,sha256=GppPDj1HmickDd1ZqRN6ZqtKD539yMphiMwL_YUYfwQ,1541
17
+ pip-26.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING,sha256=SS3tuoXaWHL3jmCRvNH-pHTWYNNay03ulkuKqz8AdCc,614
18
+ pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197
19
+ pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
20
+ pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344
21
+ pip-26.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
22
+ pip-26.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE,sha256=KeD9YukphQ6G6yjD_czwzv30-pSHkBHP-z0NS-1tTbY,1089
23
+ pip-26.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE,sha256=qdZvHVJt8C4p3Oc0NtNOVuhjL0bCdbvf_HBWnogvnxc,1331
24
+ pip-26.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE,sha256=GyKwSbUmfW38I6Z79KhNjsBLn9-xpR02DkK0NCyLQVQ,1081
25
+ pip-26.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
26
+ pip-26.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE,sha256=84j9OMrRMRLB3A9mm76A5_hFQe26-3LzAw0sp2QsPJ0,751
27
+ pip-26.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE,sha256=3u18F6QxgVgZCj6iOcyHmlpQJxzruYrnAl9I--WNyhU,1056
28
+ pip-26.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
29
+ pip-26.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
30
+ pip-26.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE,sha256=M757fo-k_Rmxdg4ajtimaL2rhSyRtpLdQUJLy3Jan8o,1086
31
+ pip-26.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt,sha256=Ew46ZNX91dCWp1JpRjSn2d8oRGnehuVzIQAmgEHj1oY,1093
32
+ pip/__init__.py,sha256=Eb5SpHacJaOLEMT6efjyxcw59tvcXW51ybwjpN19fAQ,353
33
+ pip/__main__.py,sha256=rOZRtrXjDBzY24niaxTnd9ZHHWL7B0EawVdLoJ3nI6c,874
34
+ pip/__pip-runner__.py,sha256=720Mt6h07Uce52v80EOF__JYauoLw9b7Pfs_5B91isg,1451
35
+ pip/__pycache__/__init__.cpython-312.pyc,,
36
+ pip/__pycache__/__main__.cpython-312.pyc,,
37
+ pip/__pycache__/__pip-runner__.cpython-312.pyc,,
38
+ pip/_internal/__init__.py,sha256=S7i9Dn9aSZS0MG-2Wrve3dV9TImPzvQn5jjhp9t_uf0,511
39
+ pip/_internal/__pycache__/__init__.cpython-312.pyc,,
40
+ pip/_internal/__pycache__/cache.cpython-312.pyc,,
41
+ pip/_internal/__pycache__/configuration.cpython-312.pyc,,
42
+ pip/_internal/__pycache__/exceptions.cpython-312.pyc,,
43
+ pip/_internal/__pycache__/main.cpython-312.pyc,,
44
+ pip/_internal/__pycache__/pyproject.cpython-312.pyc,,
45
+ pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc,,
46
+ pip/_internal/__pycache__/wheel_builder.cpython-312.pyc,,
47
+ pip/_internal/build_env/__init__.py,sha256=AI5x2Kfv1exG1IbsNHuIV1agqNgstTj_LWpbwWLq8ok,788
48
+ pip/_internal/build_env/__pycache__/__init__.cpython-312.pyc,,
49
+ pip/_internal/build_env/__pycache__/base.cpython-312.pyc,,
50
+ pip/_internal/build_env/__pycache__/installer.cpython-312.pyc,,
51
+ pip/_internal/build_env/__pycache__/noop.cpython-312.pyc,,
52
+ pip/_internal/build_env/__pycache__/venv.cpython-312.pyc,,
53
+ pip/_internal/build_env/__pycache__/virtual.cpython-312.pyc,,
54
+ pip/_internal/build_env/base.py,sha256=7RHW5X-QSVWHeK7_5Uei9Gbq0q1pAXHF9tq7Mj3wtTs,3440
55
+ pip/_internal/build_env/installer.py,sha256=eMUytQCdBiQ9TgkaGeTAzq_IVBqLHyD9OJ_kNTIjjcM,13046
56
+ pip/_internal/build_env/noop.py,sha256=FXk9ZFTTN0s1cecZE6ycN2ZznBh75Ok2I3QXF8HTo6I,1001
57
+ pip/_internal/build_env/venv.py,sha256=PsDl0PpmB9jRNaIawhy6Xk9R8WcYoAogLS2afmZ9AQc,5692
58
+ pip/_internal/build_env/virtual.py,sha256=HsVRzzhgBGyy06DZBoO0PW_3kIEacy9S4TI5H1q72Hk,4858
59
+ pip/_internal/cache.py,sha256=eqMQVfpD8x7GcCO0V0z73mnjPIuSapMFoQ_WRE7iLY8,10457
60
+ pip/_internal/cli/__init__.py,sha256=Iqg_tKA771XuMO1P4t_sDHnSKPzkUb9D0DqunAmw_ko,131
61
+ pip/_internal/cli/__pycache__/__init__.cpython-312.pyc,,
62
+ pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc,,
63
+ pip/_internal/cli/__pycache__/base_command.cpython-312.pyc,,
64
+ pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc,,
65
+ pip/_internal/cli/__pycache__/command_context.cpython-312.pyc,,
66
+ pip/_internal/cli/__pycache__/index_command.cpython-312.pyc,,
67
+ pip/_internal/cli/__pycache__/main.cpython-312.pyc,,
68
+ pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc,,
69
+ pip/_internal/cli/__pycache__/parser.cpython-312.pyc,,
70
+ pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc,,
71
+ pip/_internal/cli/__pycache__/req_command.cpython-312.pyc,,
72
+ pip/_internal/cli/__pycache__/spinners.cpython-312.pyc,,
73
+ pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc,,
74
+ pip/_internal/cli/autocompletion.py,sha256=gFtmiFhHccizyx4JPJnEKik-uftU7kwrUvm72cSFPHI,7353
75
+ pip/_internal/cli/base_command.py,sha256=yF5_mQEIrLG2G0nvymZS0nLhiDg4B0T89W5iX78H558,9431
76
+ pip/_internal/cli/cmdoptions.py,sha256=aBNxaIy4YV4AfjAqrG8RoZFcv7kwWzRAzg5mnZmOGDw,41180
77
+ pip/_internal/cli/command_context.py,sha256=kmu3EWZbfBega1oDamnGJTA_UaejhIQNuMj2CVmMXu0,817
78
+ pip/_internal/cli/index_command.py,sha256=_Qzc9oHnButVvD0wxYcHfe0uJZqRWOtIg5HaQpnSNeM,7504
79
+ pip/_internal/cli/main.py,sha256=O10guzBqF2MykAaZYo6sua097dXqC3nozKodtTOpHDc,3209
80
+ pip/_internal/cli/main_parser.py,sha256=7PhEfZ8AXiWUpTfB_KJMngI2sF8XIXl52alI1LZ_e_M,4368
81
+ pip/_internal/cli/parser.py,sha256=WvRHuI2MdFp187BWrY_D17L02asq9jmCnng81af52SQ,14147
82
+ pip/_internal/cli/progress_bars.py,sha256=13U3AY3DYwdEIwPYLtUn5B4QcpJUApLWCkfJ-u_PqzY,4706
83
+ pip/_internal/cli/req_command.py,sha256=wW-mRcPqPczeqxp9SQ_yh3YfrRAYAlEAZextlLcDbUc,18952
84
+ pip/_internal/cli/spinners.py,sha256=EJzZIZNyUtJljp3-WjcsyIrqxW-HUsfWzhuW84n_Tqw,7362
85
+ pip/_internal/cli/status_codes.py,sha256=9QhNe6hHqsiw5y5wufiNKBOgJjV0HF3I3P2K21nj-OM,136
86
+ pip/_internal/commands/__init__.py,sha256=aNeCbQurGWihfhQq7BqaLXHqWDQ0i3I04OS7kxK6plQ,4026
87
+ pip/_internal/commands/__pycache__/__init__.cpython-312.pyc,,
88
+ pip/_internal/commands/__pycache__/cache.cpython-312.pyc,,
89
+ pip/_internal/commands/__pycache__/check.cpython-312.pyc,,
90
+ pip/_internal/commands/__pycache__/completion.cpython-312.pyc,,
91
+ pip/_internal/commands/__pycache__/configuration.cpython-312.pyc,,
92
+ pip/_internal/commands/__pycache__/debug.cpython-312.pyc,,
93
+ pip/_internal/commands/__pycache__/download.cpython-312.pyc,,
94
+ pip/_internal/commands/__pycache__/freeze.cpython-312.pyc,,
95
+ pip/_internal/commands/__pycache__/hash.cpython-312.pyc,,
96
+ pip/_internal/commands/__pycache__/help.cpython-312.pyc,,
97
+ pip/_internal/commands/__pycache__/index.cpython-312.pyc,,
98
+ pip/_internal/commands/__pycache__/inspect.cpython-312.pyc,,
99
+ pip/_internal/commands/__pycache__/install.cpython-312.pyc,,
100
+ pip/_internal/commands/__pycache__/list.cpython-312.pyc,,
101
+ pip/_internal/commands/__pycache__/lock.cpython-312.pyc,,
102
+ pip/_internal/commands/__pycache__/search.cpython-312.pyc,,
103
+ pip/_internal/commands/__pycache__/show.cpython-312.pyc,,
104
+ pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc,,
105
+ pip/_internal/commands/__pycache__/wheel.cpython-312.pyc,,
106
+ pip/_internal/commands/cache.py,sha256=YLZrLWNvChl0pImBkoSZGGD3fb2MfdYGpYF4J0aQs6w,9251
107
+ pip/_internal/commands/check.py,sha256=hVFBQezQ3zj4EydoWbFQj_afPUppMt7r9JPAlY22U6Y,2244
108
+ pip/_internal/commands/completion.py,sha256=LjvRIZ6QUiDXJL3IOMFeD-_J97HfjMGgEk0j2tWGu1U,4565
109
+ pip/_internal/commands/configuration.py,sha256=5M6KM30G3i6oMHAsVUSWP4E93cSSJQoJ6evURC754E8,10132
110
+ pip/_internal/commands/debug.py,sha256=tCWUOEyz2HdlLGTvzNqSZIAJQkQYCy58zBTdfIWyzSo,6556
111
+ pip/_internal/commands/download.py,sha256=cuXEj9PmoZ4kCsxm_BaZ_OkmIsV_gluLiOVSuOO2MS0,5404
112
+ pip/_internal/commands/freeze.py,sha256=Lg8EOokxnRZrwdLWJgLpBWxNUt7-HrkWlEC05e-vBww,3100
113
+ pip/_internal/commands/hash.py,sha256=GO9pRN3wXC2kQaovK57TaLYBMc3IltOH92O6QEw6YE0,1679
114
+ pip/_internal/commands/help.py,sha256=Bz3LcjNQXkz4Cu__pL4CZ86o4-HNLZj1NZWdlJhjuu0,1108
115
+ pip/_internal/commands/index.py,sha256=ny_hGzXuZHzjsq4CIJh_6YfZGVJm7G7LqQQdKTibJ_Q,5608
116
+ pip/_internal/commands/inspect.py,sha256=iiAM-JuL_Z1-QP34cgAloZPSr50Mc7wAvuFDRzHQrQk,3185
117
+ pip/_internal/commands/install.py,sha256=DREULA-TGbCKhqBBLkrbDKztyQ557QbDe6ZJUYuh2yk,33761
118
+ pip/_internal/commands/list.py,sha256=W-FyxXTrHJhqRl4ZoqFp68_5GAwC9GYuY6fhFTJdHzU,13908
119
+ pip/_internal/commands/lock.py,sha256=VhpNRWItLdqywSOIqXg3vuIyf59cozh09-Z6Z9cMiLM,5987
120
+ pip/_internal/commands/search.py,sha256=zbMsX_YASj6kXA6XIBgTDv0bGK51xG-CV3IynZJcE-c,5782
121
+ pip/_internal/commands/show.py,sha256=91_XljhCHWyCNfoFBa4XdacbumQgoNbhkcHHk_gcW9Y,8247
122
+ pip/_internal/commands/uninstall.py,sha256=CsOihqvb6ZA6O67L70oXeoLHeOfNzMM88H9g-9aocgw,3868
123
+ pip/_internal/commands/wheel.py,sha256=5m3NvVKatqLDOVoC_4WOFiDDrvQRjB52jkbvpbZApug,6187
124
+ pip/_internal/configuration.py,sha256=0eEdh1xTlOHhoCrTtwHYM5DEj7BbTmhIaCaNNj3srBM,14562
125
+ pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
126
+ pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc,,
127
+ pip/_internal/distributions/__pycache__/base.cpython-312.pyc,,
128
+ pip/_internal/distributions/__pycache__/installed.cpython-312.pyc,,
129
+ pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc,,
130
+ pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc,,
131
+ pip/_internal/distributions/base.py,sha256=BjYazg2EhbEgrO1W_JD6jEZIDVlUpA_WZkqU-NvCBkQ,1907
132
+ pip/_internal/distributions/installed.py,sha256=QPDhCqc-GTGiWZAAOFaVKMETg1m_kYuf6RBO9ZZlDqY,994
133
+ pip/_internal/distributions/sdist.py,sha256=ALEkvmxHUnPvlmIuRRBYqC1x1kkMuFumNenV6xw_JXE,7486
134
+ pip/_internal/distributions/wheel.py,sha256=qOMVYzKT3tJsO0QundLjADcFiW_RODui4K51XRqMru8,1429
135
+ pip/_internal/exceptions.py,sha256=Zdu17pVbD1eI_yjg52Zd0ygAWDy8LtXS1Atfvn1pPts,38302
136
+ pip/_internal/index/__init__.py,sha256=tzwMH_fhQeubwMqHdSivasg1cRgTSbNg2CiMVnzMmyU,29
137
+ pip/_internal/index/__pycache__/__init__.cpython-312.pyc,,
138
+ pip/_internal/index/__pycache__/collector.cpython-312.pyc,,
139
+ pip/_internal/index/__pycache__/package_finder.cpython-312.pyc,,
140
+ pip/_internal/index/__pycache__/sources.cpython-312.pyc,,
141
+ pip/_internal/index/collector.py,sha256=bu-NBVToIeyYEbcv0_gtInAxsCK3E0yI6Je6yxAwE5k,16578
142
+ pip/_internal/index/package_finder.py,sha256=RoWK5rPkOcmOdiWEXhnk9aaFDgaj4QEE70FeQokqZf4,43149
143
+ pip/_internal/index/sources.py,sha256=fqqVli93Lr-HNk-wFD67yyfZzS6WeDkSZGv1RFw63QE,8621
144
+ pip/_internal/locations/__init__.py,sha256=iP9yVZn_4iPuNcaUNh2A_vJLcvUZ-8y4zvKLDVEqaM0,14022
145
+ pip/_internal/locations/__pycache__/__init__.cpython-312.pyc,,
146
+ pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc,,
147
+ pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc,,
148
+ pip/_internal/locations/__pycache__/base.cpython-312.pyc,,
149
+ pip/_internal/locations/_distutils.py,sha256=jpFj4V00rD9IR3vA9TqrGkwcdNVFc58LsChZavge9JY,5975
150
+ pip/_internal/locations/_sysconfig.py,sha256=HoZYQ1sVQD3IRpQCp4TpdTQLNrDFFzI9zRjXrTYnJWY,7788
151
+ pip/_internal/locations/base.py,sha256=5mVcXh9jnSepEO25aG2U-qZWguzeoOPIbT0mRiBDDME,2548
152
+ pip/_internal/main.py,sha256=1cHqjsfFCrMFf3B5twzocxTJUdHMLoXUpy5lJoFqUi8,338
153
+ pip/_internal/metadata/__init__.py,sha256=vp-JAxiWg_-l5F8AT0Jcey72uUnh8CDwwol9-KktHZ8,5824
154
+ pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc,,
155
+ pip/_internal/metadata/__pycache__/_json.cpython-312.pyc,,
156
+ pip/_internal/metadata/__pycache__/base.cpython-312.pyc,,
157
+ pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc,,
158
+ pip/_internal/metadata/_json.py,sha256=hNvnMHOXLAyNlzirWhPL9Nx2CvCqa1iRma6Osq1YfV8,2711
159
+ pip/_internal/metadata/base.py,sha256=_o9lMyHmia4Ea9fhceyB9rp3jUUU8k7FmlhXB7N9_tM,25642
160
+ pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
161
+ pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc,,
162
+ pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc,,
163
+ pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc,,
164
+ pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc,,
165
+ pip/_internal/metadata/importlib/_compat.py,sha256=sneVh4_6WxQZK4ljdl3ylVuP-q0ttSqbgl9mWt0HnOg,2804
166
+ pip/_internal/metadata/importlib/_dists.py,sha256=akX5xiLB_3dvbeb2gHL8i7wORi01_Cnty0HnKFQAF0Y,8717
167
+ pip/_internal/metadata/importlib/_envs.py,sha256=ulCRDEXYeinwS5AXL-Quj7C4Erk20kHhIwBmE2P3BYA,5590
168
+ pip/_internal/metadata/pkg_resources.py,sha256=NO76ZrfR2-LKJTyaXrmQoGhmJMArALvacrlZHViSDT8,10544
169
+ pip/_internal/models/__init__.py,sha256=AjmCEBxX_MH9f_jVjIGNCFJKYCYeSEe18yyvNx4uRKQ,62
170
+ pip/_internal/models/__pycache__/__init__.cpython-312.pyc,,
171
+ pip/_internal/models/__pycache__/candidate.cpython-312.pyc,,
172
+ pip/_internal/models/__pycache__/direct_url.cpython-312.pyc,,
173
+ pip/_internal/models/__pycache__/format_control.cpython-312.pyc,,
174
+ pip/_internal/models/__pycache__/index.cpython-312.pyc,,
175
+ pip/_internal/models/__pycache__/installation_report.cpython-312.pyc,,
176
+ pip/_internal/models/__pycache__/link.cpython-312.pyc,,
177
+ pip/_internal/models/__pycache__/release_control.cpython-312.pyc,,
178
+ pip/_internal/models/__pycache__/scheme.cpython-312.pyc,,
179
+ pip/_internal/models/__pycache__/search_scope.cpython-312.pyc,,
180
+ pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc,,
181
+ pip/_internal/models/__pycache__/target_python.cpython-312.pyc,,
182
+ pip/_internal/models/__pycache__/wheel.cpython-312.pyc,,
183
+ pip/_internal/models/candidate.py,sha256=MvANZJiHkw6Y4T-oYSM8710G6yYB4_DwofoD7BAmrnM,824
184
+ pip/_internal/models/direct_url.py,sha256=9RS3TQAXknwLd8JOOZWlbBV6WZFs9qn-YAYk0VQ8R_Q,944
185
+ pip/_internal/models/format_control.py,sha256=PwemYG1L27BM0f1KP61rm24wShENFyxqlD1TWu34alc,2471
186
+ pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
187
+ pip/_internal/models/installation_report.py,sha256=U4MlXWFB-8ev_yheuMO9T2m_y5b4C-hOzVaoHVobl38,2846
188
+ pip/_internal/models/link.py,sha256=SSXtFO3YAreUYY2R0PqtKXbAe1vV9Bqt5r_qPN218zE,23474
189
+ pip/_internal/models/release_control.py,sha256=31Jh-ZHsTIBZLe-7uPNoYLiRSWXAjEI1jGNxwqLKd4A,3365
190
+ pip/_internal/models/scheme.py,sha256=G-O9KElabcXqbPwfE_66lzX5fGahh3Gu6DAkz_9ZhJw,558
191
+ pip/_internal/models/search_scope.py,sha256=_i-Gj_w_FwZAvTs7WhjslBDD70J-8hmIdjXByI8uEZQ,4461
192
+ pip/_internal/models/selection_prefs.py,sha256=0teekwSVxW5MOk0WPG5Novw5q_XJjxijcd75kZO6E9g,1503
193
+ pip/_internal/models/target_python.py,sha256=I0eFS-eia3kwhrOvgsphFZtNAB2IwXZ9Sr9fp6IjBP4,4243
194
+ pip/_internal/models/wheel.py,sha256=1SdfDvN7ALTsbyZ9EOsNy1GPirP1n6EjHyzPrZyLSh8,2920
195
+ pip/_internal/network/__init__.py,sha256=FMy06P__y6jMjUc8z3ZcQdKF-pmZ2zM14_vBeHPGhUI,49
196
+ pip/_internal/network/__pycache__/__init__.cpython-312.pyc,,
197
+ pip/_internal/network/__pycache__/auth.cpython-312.pyc,,
198
+ pip/_internal/network/__pycache__/cache.cpython-312.pyc,,
199
+ pip/_internal/network/__pycache__/download.cpython-312.pyc,,
200
+ pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc,,
201
+ pip/_internal/network/__pycache__/session.cpython-312.pyc,,
202
+ pip/_internal/network/__pycache__/utils.cpython-312.pyc,,
203
+ pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc,,
204
+ pip/_internal/network/auth.py,sha256=TBpwe7zcaPuBdBldjAOZhf20lmkacpIgGA-AqLcr8eU,21545
205
+ pip/_internal/network/cache.py,sha256=6DlMXJ7pb35M1vgtTK0-L_kiHJFxf7t9zrfeJ9vqO34,4862
206
+ pip/_internal/network/download.py,sha256=SVrmKao567lfs8RaCdyuOitzIRCZp9Rf3RcDj_o8vkg,14618
207
+ pip/_internal/network/lazy_wheel.py,sha256=y9gVksdJCSjnLfYzs_m3DYUAtl3hc_k-xFPDBd9DgOs,7646
208
+ pip/_internal/network/session.py,sha256=2KqMv5Hu_PFRYRkDBhSjIbqbsBp0lXv4tqoLKnM2K6o,19924
209
+ pip/_internal/network/utils.py,sha256=OTA1vwFtu2Ee1zWrqLysBpRQGTjvXxCJJUTEqy7hNcA,8128
210
+ pip/_internal/network/xmlrpc.py,sha256=_-Rnk3vOff8uF9hAGmT6SLALflY1gMBcbGwS12fb_Y4,1830
211
+ pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
212
+ pip/_internal/operations/__pycache__/__init__.cpython-312.pyc,,
213
+ pip/_internal/operations/__pycache__/check.cpython-312.pyc,,
214
+ pip/_internal/operations/__pycache__/freeze.cpython-312.pyc,,
215
+ pip/_internal/operations/__pycache__/prepare.cpython-312.pyc,,
216
+ pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
+ pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc,,
218
+ pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc,,
219
+ pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc,,
220
+ pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc,,
221
+ pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc,,
222
+ pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc,,
223
+ pip/_internal/operations/build/build_tracker.py,sha256=W3b5cmkMWPaE6QIwfzsTayJo7-OlxFHWDxfPuax1KcE,4771
224
+ pip/_internal/operations/build/metadata.py,sha256=INHaeiRfOiLYCXApfDNRo9Cw2xI4VwTc0KItvfdfOjk,1421
225
+ pip/_internal/operations/build/metadata_editable.py,sha256=oWudMsnjy4loO_Jy7g4N9nxsnaEX_iDlVRgCy7pu1rs,1509
226
+ pip/_internal/operations/build/wheel.py,sha256=3bP-nNiJ4S8JvMaBnyessXQUBhxTqt1GBx6DQ1iPJDY,1136
227
+ pip/_internal/operations/build/wheel_editable.py,sha256=q3kfElclM6FutVbFwE87JOTpVWt5ixDf3_UkHAIVfz4,1478
228
+ pip/_internal/operations/check.py,sha256=k7mTjLb5yZbidYw8Nt9vu7_u1L1ekLOzUECeN4qcNsA,5891
229
+ pip/_internal/operations/freeze.py,sha256=PDdY-y_ZtZZJLAKcaWPIGRKAGW7DXR48f0aMRU0j7BA,9854
230
+ pip/_internal/operations/install/__init__.py,sha256=ak-UETcQPKlFZaWoYKWu5QVXbpFBvg0sXc3i0O4vSYY,50
231
+ pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc,,
232
+ pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc,,
233
+ pip/_internal/operations/install/wheel.py,sha256=qhFwJSShLm4quY8zIss_t-bff0YV49HTNAKfu4fSpic,29078
234
+ pip/_internal/operations/prepare.py,sha256=zLkVMSDu9cUR0KnDm3bZ3QvIeaErhJKrr109UyDMlKQ,35030
235
+ pip/_internal/pyproject.py,sha256=J-sTWqC-XfsKQgz9m1bypMWZPHItsSHzIN_NWeIRmhM,4555
236
+ pip/_internal/req/__init__.py,sha256=x3uB7ZW-l_MOPm8ldF8Gi0dh5C8W23dB_wOH2NmWpFc,3140
237
+ pip/_internal/req/__pycache__/__init__.cpython-312.pyc,,
238
+ pip/_internal/req/__pycache__/constructors.cpython-312.pyc,,
239
+ pip/_internal/req/__pycache__/pep723.cpython-312.pyc,,
240
+ pip/_internal/req/__pycache__/req_dependency_group.cpython-312.pyc,,
241
+ pip/_internal/req/__pycache__/req_file.cpython-312.pyc,,
242
+ pip/_internal/req/__pycache__/req_install.cpython-312.pyc,,
243
+ pip/_internal/req/__pycache__/req_set.cpython-312.pyc,,
244
+ pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc,,
245
+ pip/_internal/req/constructors.py,sha256=fwILg3OiIK_f13RUGX5zQyz4YasUMp7MC6u9uPvoGzw,22276
246
+ pip/_internal/req/pep723.py,sha256=JsG1p3CaVcW8cjclD2kDj7d9qtVrNQaevY_UnKh00tk,1242
247
+ pip/_internal/req/req_dependency_group.py,sha256=PrWKtlwI8xbWnWEKjXs9RkrpQx2_h02ABefYT0ZdeQg,3145
248
+ pip/_internal/req/req_file.py,sha256=dmGBSxZ9dj1eOq2NXv94bor0u1n8P4-AvmJL-vYzIsE,20644
249
+ pip/_internal/req/req_install.py,sha256=r289__WNVaTxpRtLFUz3FpNvdGv8yYa87G-QkP5DsJc,32173
250
+ pip/_internal/req/req_set.py,sha256=awkqIXnYA4Prmsj0Qb3zhqdbYUmXd-1o0P-KZ3mvRQs,2828
251
+ pip/_internal/req/req_uninstall.py,sha256=t5HSYuLoLxnF7jrcIBDjTEP-sjjr8O4fZouEqOkVM_c,24276
252
+ pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
253
+ pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc,,
254
+ pip/_internal/resolution/__pycache__/base.cpython-312.pyc,,
255
+ pip/_internal/resolution/base.py,sha256=J9Fq3kFOjFj9gBShYQtldEFPrRGSWtsp-rO9rIc4W4g,573
256
+ pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
257
+ pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc,,
258
+ pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc,,
259
+ pip/_internal/resolution/legacy/resolver.py,sha256=2CVLIZLm_nXkfJTt5RKtIbIxvCkn9Gavf4Yp9c1IjDU,24110
260
+ pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
+ pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc,,
262
+ pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc,,
263
+ pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc,,
264
+ pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc,,
265
+ pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc,,
266
+ pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc,,
267
+ pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc,,
268
+ pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc,,
269
+ pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc,,
270
+ pip/_internal/resolution/resolvelib/base.py,sha256=fo7ojoQtgjmQH5ca3VyKJAO3p5sHnihMDw79Z8_31-U,5900
271
+ pip/_internal/resolution/resolvelib/candidates.py,sha256=SEkpEH6T6zl7Ve7Dw9oIS6tnREj-1U_q4U-2xEH0ISc,20848
272
+ pip/_internal/resolution/resolvelib/factory.py,sha256=rqwnD4GWEdVgG7nGP6OGj493yiGW6jZr0cW_msMOK_U,36162
273
+ pip/_internal/resolution/resolvelib/found_candidates.py,sha256=F55YtXekKUbVwphlXska01LkdTGVgx1qONlLK7BX-HM,6005
274
+ pip/_internal/resolution/resolvelib/provider.py,sha256=Nkx4A16MOAxjCj9jFm8wmlMk5cbWh1YK2-UYWTKEJCw,12310
275
+ pip/_internal/resolution/resolvelib/reporter.py,sha256=tEC7MF8IqGU4Ww9t61YVfNFKtoaQpb6-AwLZptJz1VE,3918
276
+ pip/_internal/resolution/resolvelib/requirements.py,sha256=Izl9n8nc188lA1BSPS8QxfudfDQPHgngw-ij6hXt0nQ,8239
277
+ pip/_internal/resolution/resolvelib/resolver.py,sha256=wM3CcRTYPdjnQ1ai3YP6htFmkE32o1xx2RgjU-ykAjc,13849
278
+ pip/_internal/self_outdated_check.py,sha256=9XxOXPqsZlKceTP2tZS7I7rXjodnqd3GrIQ8U0_L8BM,8097
279
+ pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
+ pip/_internal/utils/__pycache__/__init__.cpython-312.pyc,,
281
+ pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc,,
282
+ pip/_internal/utils/__pycache__/_log.cpython-312.pyc,,
283
+ pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc,,
284
+ pip/_internal/utils/__pycache__/compat.cpython-312.pyc,,
285
+ pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc,,
286
+ pip/_internal/utils/__pycache__/datetime.cpython-312.pyc,,
287
+ pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc,,
288
+ pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc,,
289
+ pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc,,
290
+ pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc,,
291
+ pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc,,
292
+ pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc,,
293
+ pip/_internal/utils/__pycache__/glibc.cpython-312.pyc,,
294
+ pip/_internal/utils/__pycache__/hashes.cpython-312.pyc,,
295
+ pip/_internal/utils/__pycache__/logging.cpython-312.pyc,,
296
+ pip/_internal/utils/__pycache__/misc.cpython-312.pyc,,
297
+ pip/_internal/utils/__pycache__/packaging.cpython-312.pyc,,
298
+ pip/_internal/utils/__pycache__/pylock.cpython-312.pyc,,
299
+ pip/_internal/utils/__pycache__/retry.cpython-312.pyc,,
300
+ pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc,,
301
+ pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc,,
302
+ pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc,,
303
+ pip/_internal/utils/__pycache__/urls.cpython-312.pyc,,
304
+ pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc,,
305
+ pip/_internal/utils/__pycache__/wheel.cpython-312.pyc,,
306
+ pip/_internal/utils/_jaraco_text.py,sha256=M15uUPIh5NpP1tdUGBxRau6q1ZAEtI8-XyLEETscFfE,3350
307
+ pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
308
+ pip/_internal/utils/appdirs.py,sha256=LrzDPZMKVh0rubtCx9vu3XlZbLCSug6VSj4Qsvt66BA,1681
309
+ pip/_internal/utils/compat.py,sha256=i2JUZXGrqP-ZoD8t4gwckBA3KYNUWCluvRDXScts5fE,2601
310
+ pip/_internal/utils/compatibility_tags.py,sha256=DiNSLqpuruXUamGQwOJ2WZByDGLTGaXi9O-Xf8fOi34,6630
311
+ pip/_internal/utils/datetime.py,sha256=kuJOf1mW8G5tRFN6jWardddS-9qSaR53lK1jmx3NTZY,868
312
+ pip/_internal/utils/deprecation.py,sha256=IQFumZa-XWJ3UoPnX4duwbf79CTzOZD_Vk1PkivAu4g,4537
313
+ pip/_internal/utils/direct_url_helpers.py,sha256=WCCPJnmoPHz7kiYePrEcVAen2lDpCT9WQVImoHHWCO8,3363
314
+ pip/_internal/utils/egg_link.py,sha256=YWfsrbmfcrfWgqQYy6OuIjsyb9IfL1q_2v4zsms1WjI,2459
315
+ pip/_internal/utils/entrypoints.py,sha256=uPjAyShKObdotjQjJUzprQ6r3xQvDIZwUYfHHqZ7Dok,3324
316
+ pip/_internal/utils/filesystem.py,sha256=gig73bOOS1NnDB94EDDvdDnHjQoeRz_TlfQPiCV7Me0,6812
317
+ pip/_internal/utils/filetypes.py,sha256=sEMa38qaqjvx1Zid3OCAUja31BOBU-USuSMPBvU3yjo,689
318
+ pip/_internal/utils/glibc.py,sha256=sEh8RJJLYSdRvTqAO4THVPPA-YSDVLD4SI9So-bxX1U,3726
319
+ pip/_internal/utils/hashes.py,sha256=38-bCOJSHippQ7r9RttrMHxb2mv3EARt1Gw8kFmW73g,5040
320
+ pip/_internal/utils/logging.py,sha256=hGTjBuIjNZxydV6vs4woxAbhkHI8L-9uCO14OCvPlA8,13919
321
+ pip/_internal/utils/misc.py,sha256=28LWQFvFWmrpJqMcV0soif1xnl3_gb25B3gG_iU5zhM,25408
322
+ pip/_internal/utils/packaging.py,sha256=s5tpUmFumwV0H9JSTzryrIY4JwQM8paGt7Sm7eNwt2Y,1601
323
+ pip/_internal/utils/pylock.py,sha256=XQTZ1ggh7yfpHfRdbvjSAe1peOtg2Z2xFrUeZ7wl4Ts,10290
324
+ pip/_internal/utils/retry.py,sha256=oOK3VGgKRKxSkXDPARf73cnQS3hDtnE9-feAg4AlNZE,1488
325
+ pip/_internal/utils/subprocess.py,sha256=nqNz2p3G4QANCCBcaJkqIQvQUYA50TwjZnoYjiyPxs8,9001
326
+ pip/_internal/utils/temp_dir.py,sha256=TDiL9BzEp2eHalQLH0rhyM3m2xuydEg9c6t1h4bT5l8,9303
327
+ pip/_internal/utils/unpacking.py,sha256=5i9Sn__SNElhoCXnLt2SvQaQ-SnTzcUaDH1_JI1THUw,14789
328
+ pip/_internal/utils/urls.py,sha256=JQWrRAoXHBpPsY9Aij61bsZjMQLCcuyrUO1R6W_BwIo,1647
329
+ pip/_internal/utils/virtualenv.py,sha256=9od4LsceDynUSsLTEXXgtumlUQ8VvKp86b2xzK0Yu3g,2272
330
+ pip/_internal/utils/wheel.py,sha256=YdRuj6MicG-Q9Mg03FbUv1WTLam6Lc7AgijY4voVyis,4468
331
+ pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
332
+ pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc,,
333
+ pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc,,
334
+ pip/_internal/vcs/__pycache__/git.cpython-312.pyc,,
335
+ pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc,,
336
+ pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc,,
337
+ pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc,,
338
+ pip/_internal/vcs/bazaar.py,sha256=3W1eHjkYx2vc6boeb2NBh4I_rlGAXM-vrzfNhLm1Rxg,3734
339
+ pip/_internal/vcs/git.py,sha256=L52rqJN--Kq0kjAR8_9Si8RJEcNlULJdk6Vipg8ZlfA,19273
340
+ pip/_internal/vcs/mercurial.py,sha256=w1ZJWLKqNP1onEjkfjlwBVnMqPZNSIER8ayjQcnTq4w,5575
341
+ pip/_internal/vcs/subversion.py,sha256=uUgdPvxmvEB8Qwtjr0Hc0XgFjbiNi5cbvI4vARLOJXo,11787
342
+ pip/_internal/vcs/versioncontrol.py,sha256=JsUgTG53DkJPy5mXVBH7uqeFQyaL69707ibts5uCBYA,22579
343
+ pip/_internal/wheel_builder.py,sha256=kdPvAcxfknA8B_4g6hPDjB7C4uzL_cV5Vde2Oj2Ipzk,9146
344
+ pip/_vendor/README.rst,sha256=t7IinjaiuwUh812XmVApQHJb8pTw33U8A9URqy6GlF4,9222
345
+ pip/_vendor/__init__.py,sha256=WzusPTGWIMeQQWSVJ0h2rafGkVTa9WKJ2HT-2-EoZrU,4907
346
+ pip/_vendor/__pycache__/__init__.cpython-312.pyc,,
347
+ pip/_vendor/bom.cdx.json,sha256=eX4gCqf_8W-tn7Le6uzlCisr7GI-tsN1kXbu5s7hkyg,5319
348
+ pip/_vendor/cachecontrol/LICENSE.txt,sha256=hu7uh74qQ_P_H1ZJb0UfaSQ5JvAl_tuwM2ZsMExMFhs,558
349
+ pip/_vendor/cachecontrol/__init__.py,sha256=GxwRkm_TQBtPZpfpVK9r6S9dAy2DVnVgDVHJKTiPZ1k,820
350
+ pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc,,
351
+ pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc,,
352
+ pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc,,
353
+ pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc,,
354
+ pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc,,
355
+ pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc,,
356
+ pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc,,
357
+ pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc,,
358
+ pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc,,
359
+ pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
360
+ pip/_vendor/cachecontrol/adapter.py,sha256=W-HW-l01gyCsnxkOyCbqx7sxrWYoBbKrDsKkVVQN6NE,6586
361
+ pip/_vendor/cachecontrol/cache.py,sha256=OXwv7Fn2AwnKNiahJHnjtvaKLndvVLv_-zO-ltlV9qI,1953
362
+ pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
363
+ pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc,,
364
+ pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc,,
365
+ pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc,,
366
+ pip/_vendor/cachecontrol/caches/file_cache.py,sha256=d8upFmy_zwaCmlbWEVBlLXFddt8Zw8c5SFpxeOZsdfw,4117
367
+ pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
368
+ pip/_vendor/cachecontrol/controller.py,sha256=xBauC-vUSu5GsJsxD4-W-JaKqqbBz0MN6Zv8PA2N8hI,19102
369
+ pip/_vendor/cachecontrol/filewrapper.py,sha256=DhxC_rSk-beKdbsYhfvBUDovQHX9r3gHH_jP9-q_mKk,4354
370
+ pip/_vendor/cachecontrol/heuristics.py,sha256=gqMXU8w0gQuEQiSdu3Yg-0vd9kW7nrWKbLca75rheGE,4881
371
+ pip/_vendor/cachecontrol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
372
+ pip/_vendor/cachecontrol/serialize.py,sha256=HQd2IllQ05HzPkVLMXTF2uX5mjEQjDBkxCqUJUODpZk,5163
373
+ pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
374
+ pip/_vendor/certifi/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989
375
+ pip/_vendor/certifi/__init__.py,sha256=-W1R_y8WCaSkT1tdjuxH_zTBZY1YH6xQgdN1nbBajOE,94
376
+ pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
377
+ pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc,,
378
+ pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc,,
379
+ pip/_vendor/certifi/__pycache__/core.cpython-312.pyc,,
380
+ pip/_vendor/certifi/cacert.pem,sha256=u8fpwB11UbuKFZtd7dmJuO484QWv9SK2jrGwG_hUyrA,234354
381
+ pip/_vendor/certifi/core.py,sha256=gu_ECVI1m3Rq0ytpsNE61hgQGcKaOAt9Rs9G8KsTCOI,3442
382
+ pip/_vendor/certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
383
+ pip/_vendor/distlib/LICENSE.txt,sha256=gI4QyKarjesUn_mz-xn0R6gICUYG1xKpylf-rTVSWZ0,14531
384
+ pip/_vendor/distlib/__init__.py,sha256=tmYThB1xmgfRjRtyy8YP0i0ymrF2n6eVswcwK6OYbcc,625
385
+ pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc,,
386
+ pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc,,
387
+ pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc,,
388
+ pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc,,
389
+ pip/_vendor/distlib/__pycache__/util.cpython-312.pyc,,
390
+ pip/_vendor/distlib/compat.py,sha256=HTzhOY98c_fyMVE7xtVuZZ-AVkN4-RGes-hWmvuwquk,40605
391
+ pip/_vendor/distlib/resources.py,sha256=wZt_Ako8TY-L6ZIAmP42J7MNX0XTEF6gkM0Om5F7UPY,11350
392
+ pip/_vendor/distlib/scripts.py,sha256=rVm4A-YfGQDpsORwOy7AwepyRTayuy6rc-MnaCMBAcM,18835
393
+ pip/_vendor/distlib/t32.exe,sha256=a0GV5kCoWsMutvliiCKmIgV98eRZ33wXoS-XrqvJQVs,97792
394
+ pip/_vendor/distlib/t64-arm.exe,sha256=68TAa32V504xVBnufojh0PcenpR3U4wAqTqf-MZqbPw,182784
395
+ pip/_vendor/distlib/t64.exe,sha256=gaYY8hy4fbkHYTTnA4i26ct8IQZzkBG2pRdy0iyuBrc,108032
396
+ pip/_vendor/distlib/util.py,sha256=n2QDXvB0XtwrtehygnwdLgLkLia58sZjzgZPKyD6rAE,68167
397
+ pip/_vendor/distlib/w32.exe,sha256=R4csx3-OGM9kL4aPIzQKRo5TfmRSHZo6QWyLhDhNBks,91648
398
+ pip/_vendor/distlib/w64-arm.exe,sha256=xdyYhKj0WDcVUOCb05blQYvzdYIKMbmJn2SZvzkcey4,168448
399
+ pip/_vendor/distlib/w64.exe,sha256=ejGf-rojoBfXseGLpya6bFTFPWRG21X5KvU8J5iU-K0,101888
400
+ pip/_vendor/distro/LICENSE,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
401
+ pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
402
+ pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
403
+ pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc,,
404
+ pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc,,
405
+ pip/_vendor/distro/__pycache__/distro.cpython-312.pyc,,
406
+ pip/_vendor/distro/distro.py,sha256=XqbefacAhDT4zr_trnbA15eY8vdK4GTghgmvUGrEM_4,49430
407
+ pip/_vendor/distro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
408
+ pip/_vendor/idna/LICENSE.md,sha256=GppPDj1HmickDd1ZqRN6ZqtKD539yMphiMwL_YUYfwQ,1541
409
+ pip/_vendor/idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
410
+ pip/_vendor/idna/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83
411
+ pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc,,
412
+ pip/_vendor/idna/__pycache__/__main__.cpython-312.pyc,,
413
+ pip/_vendor/idna/__pycache__/cli.cpython-312.pyc,,
414
+ pip/_vendor/idna/__pycache__/codec.cpython-312.pyc,,
415
+ pip/_vendor/idna/__pycache__/compat.cpython-312.pyc,,
416
+ pip/_vendor/idna/__pycache__/core.cpython-312.pyc,,
417
+ pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc,,
418
+ pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc,,
419
+ pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc,,
420
+ pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc,,
421
+ pip/_vendor/idna/cli.py,sha256=swqJLMNc8Uzs60KziNpbWnHuqlG3WRQwJSbo4n8xDAo,4139
422
+ pip/_vendor/idna/codec.py,sha256=JRbo-f7pEkLdWeiH89Z72UR4VBYhvKDFrQBeNX6sRDE,5040
423
+ pip/_vendor/idna/compat.py,sha256=AepA39ceRHxkfHP41-FvKW5Ki-f4PfUZ90RUMlCNdmo,1353
424
+ pip/_vendor/idna/core.py,sha256=SfOr1xO3PoE0RDYx7bMciAnjiyjJPbPw_93AB5IUYOw,24685
425
+ pip/_vendor/idna/idnadata.py,sha256=Af-mo8WBmkhAK6TyXKOQH88OX0mQNDKtdL7UWtQpppk,44862
426
+ pip/_vendor/idna/intranges.py,sha256=g49scLSkqJtAhLmOODa7hVHriSjmb60tiTsEoocJdBI,1851
427
+ pip/_vendor/idna/package_data.py,sha256=TeI94EqAFAFaXfBJwsOPUMLn2969uirPa-DaeaceAyU,21
428
+ pip/_vendor/idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
429
+ pip/_vendor/idna/uts46data.py,sha256=jujNz5QqWMcJf-XYLv4X1jBvb5FlI0t6-e1mILsgbPk,234325
430
+ pip/_vendor/msgpack/COPYING,sha256=SS3tuoXaWHL3jmCRvNH-pHTWYNNay03ulkuKqz8AdCc,614
431
+ pip/_vendor/msgpack/__init__.py,sha256=RA8gcqK17YpkxBnNwXJVa1oa2LygWDgfF1nA1NPw3mo,1109
432
+ pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc,,
433
+ pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc,,
434
+ pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc,,
435
+ pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc,,
436
+ pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
437
+ pip/_vendor/msgpack/ext.py,sha256=kteJv03n9tYzd5oo3xYopVTo4vRaAxonBQQJhXohZZo,5726
438
+ pip/_vendor/msgpack/fallback.py,sha256=0g1Pzp0vtmBEmJ5w9F3s_-JMVURP8RS4G1cc5TRaAsI,32390
439
+ pip/_vendor/packaging/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197
440
+ pip/_vendor/packaging/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
441
+ pip/_vendor/packaging/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344
442
+ pip/_vendor/packaging/__init__.py,sha256=QhMEdPu2XogrJzV3S0KWS6t7l0I9k8EeDRJl4fnw87s,494
443
+ pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc,,
444
+ pip/_vendor/packaging/__pycache__/_elffile.cpython-312.pyc,,
445
+ pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc,,
446
+ pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc,,
447
+ pip/_vendor/packaging/__pycache__/_parser.cpython-312.pyc,,
448
+ pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc,,
449
+ pip/_vendor/packaging/__pycache__/_tokenizer.cpython-312.pyc,,
450
+ pip/_vendor/packaging/__pycache__/dependency_groups.cpython-312.pyc,,
451
+ pip/_vendor/packaging/__pycache__/direct_url.cpython-312.pyc,,
452
+ pip/_vendor/packaging/__pycache__/errors.cpython-312.pyc,,
453
+ pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc,,
454
+ pip/_vendor/packaging/__pycache__/metadata.cpython-312.pyc,,
455
+ pip/_vendor/packaging/__pycache__/pylock.cpython-312.pyc,,
456
+ pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc,,
457
+ pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc,,
458
+ pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc,,
459
+ pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc,,
460
+ pip/_vendor/packaging/__pycache__/version.cpython-312.pyc,,
461
+ pip/_vendor/packaging/_elffile.py,sha256=-sKkptYqzYw2-x3QByJa5mB4rfPWu1pxkZHRx1WAFCY,3211
462
+ pip/_vendor/packaging/_manylinux.py,sha256=Hf6nB0cOrayEs96-p3oIXAgGnFquv20DO5l-o2_Xnv0,9559
463
+ pip/_vendor/packaging/_musllinux.py,sha256=Z6swjH3MA7XS3qXnmMN7QPhqP3fnoYI0eQ18e9-HgAE,2707
464
+ pip/_vendor/packaging/_parser.py,sha256=Kf2nsDw4c54X82pY8ba4F02Bve6OygGMAjL-Begqcew,11698
465
+ pip/_vendor/packaging/_structures.py,sha256=60jRbF78p8z5MKnNd6cAprgOadCJHV0DlmUmRBqFZcs,1109
466
+ pip/_vendor/packaging/_tokenizer.py,sha256=tFU2Wr-ZZJdAbkXLEJo7qUQDJaIkfft9DqaifiEND7A,5391
467
+ pip/_vendor/packaging/dependency_groups.py,sha256=XZIAVFK9uHG4RCGprmJn3VInUWMesxha_kytJuMO9eY,10218
468
+ pip/_vendor/packaging/direct_url.py,sha256=eKmbDiPP1sLV4Mj_kCSZqqknrIyVO9Sr7JpF8KCjp4U,10917
469
+ pip/_vendor/packaging/errors.py,sha256=6hfEYXAf8v_IF65-lFadJOMIieBP2xIKtyEXjG1nGIs,2680
470
+ pip/_vendor/packaging/licenses/__init__.py,sha256=_Jx0XRiD_58palsWnyLrLuh59ZpGCPIPXLKdZo9OJvQ,7293
471
+ pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-312.pyc,,
472
+ pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-312.pyc,,
473
+ pip/_vendor/packaging/licenses/_spdx.py,sha256=WW7DXiyg68up_YND_wpRYlr1SHhiV4FfJLQffghhMxQ,51122
474
+ pip/_vendor/packaging/markers.py,sha256=QixBVcb9D2HjwEYiuhpNkbqk9znPRbU8zNX0kR1RIrU,17067
475
+ pip/_vendor/packaging/metadata.py,sha256=crAh0E3GVGVqPlu6EdRFsaG-Y6UYznTUqjuGKRGPv6c,38770
476
+ pip/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
477
+ pip/_vendor/packaging/pylock.py,sha256=G_1gncTmDbRLY1jo4VDI9Uw-b5IErh_Q9V_BbVJTmD8,33890
478
+ pip/_vendor/packaging/requirements.py,sha256=Q-BdEHVW5K785GBXt7RcP4UEsdIKWoWFqlrHjR4WV50,4395
479
+ pip/_vendor/packaging/specifiers.py,sha256=3XBcSslm-YQEEEO_zrv4F6dR5wRxs4ErJvJ0vjNBfGM,71550
480
+ pip/_vendor/packaging/tags.py,sha256=ANYHZxYQVp9BlOQYOHU5ArDNVIpTFl4KlbocYVBWnFs,34236
481
+ pip/_vendor/packaging/utils.py,sha256=M7-JMKic2sP1YtV_8aW7eVGB-x3ADuKCiSrsVeCd2Uo,9848
482
+ pip/_vendor/packaging/version.py,sha256=Mcu7Tf6Y1i0gQ4FXv4t0g8cbL5joAEshjgIpz_2vISI,38393
483
+ pip/_vendor/pkg_resources/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
484
+ pip/_vendor/pkg_resources/__init__.py,sha256=vbTJ0_ruUgGxQjlEqsruFmiNPVyh2t9q-zyTDT053xI,124451
485
+ pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc,,
486
+ pip/_vendor/platformdirs/LICENSE,sha256=KeD9YukphQ6G6yjD_czwzv30-pSHkBHP-z0NS-1tTbY,1089
487
+ pip/_vendor/platformdirs/__init__.py,sha256=gBmL_J_KdPgKiwM3dHCo-y-8CbS06QCa1XIhJ9bIgew,32389
488
+ pip/_vendor/platformdirs/__main__.py,sha256=DQ1o1E1l0Ghuitj4uQJKAPwkcKbGzkzO0sbhzd9RbUc,1773
489
+ pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc,,
490
+ pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc,,
491
+ pip/_vendor/platformdirs/__pycache__/_xdg.cpython-312.pyc,,
492
+ pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc,,
493
+ pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc,,
494
+ pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc,,
495
+ pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc,,
496
+ pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc,,
497
+ pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc,,
498
+ pip/_vendor/platformdirs/_xdg.py,sha256=5w6S07vVabEROhaUB_X7i0hmLNbdYtC9aEvPbsEIS8M,7894
499
+ pip/_vendor/platformdirs/android.py,sha256=BBj3wfw-dfuVxsCsKsvFByKVspRDgfv8gwIzhpE1JRQ,11566
500
+ pip/_vendor/platformdirs/api.py,sha256=EaIsFgXGu8cDTb41WM3hse_SrIoOUht8_TCo5XdOOSM,14887
501
+ pip/_vendor/platformdirs/macos.py,sha256=PWudeDZAY9UuwLP_5rN3exSRFtYdY542hDhjah4dSWA,9538
502
+ pip/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
503
+ pip/_vendor/platformdirs/unix.py,sha256=X7Cip1xOHFOnSVveqKWzU1P7jn4zuDGpRgmVxJnk4vk,13317
504
+ pip/_vendor/platformdirs/version.py,sha256=dJvdm7L_7wobEcxrNoJtH7CtmYcG_VR5yNmtBshJ-xs,522
505
+ pip/_vendor/platformdirs/windows.py,sha256=YOdSGNhdpxm_ydZq7uG74i9mX2_WWbcMSA4fobXwL0M,15798
506
+ pip/_vendor/pygments/LICENSE,sha256=qdZvHVJt8C4p3Oc0NtNOVuhjL0bCdbvf_HBWnogvnxc,1331
507
+ pip/_vendor/pygments/__init__.py,sha256=Xnd_7fJUqU_6D0bxXW0qS9M_OE9G6VW8YNPbGLWoKwQ,2986
508
+ pip/_vendor/pygments/__main__.py,sha256=IqAQ_836Kv2CTx8r6Ie6duRQuYSPl85sbYomEwIsY14,356
509
+ pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc,,
510
+ pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc,,
511
+ pip/_vendor/pygments/__pycache__/console.cpython-312.pyc,,
512
+ pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc,,
513
+ pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc,,
514
+ pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc,,
515
+ pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc,,
516
+ pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc,,
517
+ pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc,,
518
+ pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc,,
519
+ pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc,,
520
+ pip/_vendor/pygments/__pycache__/style.cpython-312.pyc,,
521
+ pip/_vendor/pygments/__pycache__/token.cpython-312.pyc,,
522
+ pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc,,
523
+ pip/_vendor/pygments/__pycache__/util.cpython-312.pyc,,
524
+ pip/_vendor/pygments/console.py,sha256=C189JAwhC1Qh0AKgshzb1wVDzFqBnv1VZ45kTEDIO30,1721
525
+ pip/_vendor/pygments/filter.py,sha256=1dnbkq2AdC3AkHt3DaXwnOkTBLChl1kR6naSLwnr_tc,1913
526
+ pip/_vendor/pygments/filters/__init__.py,sha256=Prd6xUK_7kw0rQv_OXPY3871RzwtWKGp_g7SddYHBXg,40397
527
+ pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc,,
528
+ pip/_vendor/pygments/formatter.py,sha256=EuAXPX6c3XQkCt3lD0VhSPSZByG7YQk8HrCwxlf-CZQ,4393
529
+ pip/_vendor/pygments/formatters/__init__.py,sha256=EYLDCIgBHL_DkuhNRQZlHpS2_UE5-MfsGL1hMcOa95w,5388
530
+ pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc,,
531
+ pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc,,
532
+ pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
533
+ pip/_vendor/pygments/lexer.py,sha256=wSXDzt2fNZJSrlfdIfnKVlheRpFkszkPmgwBJevbBNo,35394
534
+ pip/_vendor/pygments/lexers/__init__.py,sha256=s8I_tVlotrM8cFTGlnjw45UY5sj5jhDwdQzOOjhzgNg,12118
535
+ pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc,,
536
+ pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc,,
537
+ pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc,,
538
+ pip/_vendor/pygments/lexers/_mapping.py,sha256=wGAYjOBprDVZA01eocwcLJ6L8biM9rP2jxwr1bQJ96M,77934
539
+ pip/_vendor/pygments/lexers/python.py,sha256=TqyfQOPhCYPx35apQL65CAj9k-4BxuzLq8MDfdm2jvE,54250
540
+ pip/_vendor/pygments/modeline.py,sha256=me8g5rySidvPtMBOrDy2O1sMqZd02lBHMY5KDZefUws,1008
541
+ pip/_vendor/pygments/plugin.py,sha256=P6zIw-vkSQ0k1WKHrzbBTjpwlCZPbR-6Qe_dO9Bjdu0,1928
542
+ pip/_vendor/pygments/regexopt.py,sha256=d2hTvazlow5zzZIOCVnfeEG2CY0GrY_igH1kCSSf7ow,3308
543
+ pip/_vendor/pygments/scanner.py,sha256=DtoLi1pOKpNu-6jiakJpSQLUi_ep29SQQhv7oAwYWME,3095
544
+ pip/_vendor/pygments/sphinxext.py,sha256=RflpnfXB4rZLYyZ-OQ_igntVOlB8jG42xFYgEVIyHf8,7984
545
+ pip/_vendor/pygments/style.py,sha256=wJSXOXjehGYxI6e3DGaUtONeWuhmTfswfkysrL9Was0,6423
546
+ pip/_vendor/pygments/styles/__init__.py,sha256=kYdCGK8gZ1V8wfFQETOzpPmZTJ1nMB0b1iNlU8dHQ9E,2045
547
+ pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc,,
548
+ pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-312.pyc,,
549
+ pip/_vendor/pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312
550
+ pip/_vendor/pygments/token.py,sha256=DVil5T2ltHkTgQTUYy1dMtgyigjavCs1ypE4Qf2CrGo,6229
551
+ pip/_vendor/pygments/unistring.py,sha256=Z4w4HfOVUhueCURRkfhAqQ2b-69UzkhY4xuHevYEy5g,63211
552
+ pip/_vendor/pygments/util.py,sha256=zk935tJSpwSA9zxNmV1TuhcEP0MfboXiRZSGQnLPEqk,10046
553
+ pip/_vendor/pyproject_hooks/LICENSE,sha256=GyKwSbUmfW38I6Z79KhNjsBLn9-xpR02DkK0NCyLQVQ,1081
554
+ pip/_vendor/pyproject_hooks/__init__.py,sha256=cPB_a9LXz5xvsRbX1o2qyAdjLatZJdQ_Lc5McNX-X7Y,691
555
+ pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc,,
556
+ pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc,,
557
+ pip/_vendor/pyproject_hooks/_impl.py,sha256=jY-raxnmyRyB57ruAitrJRUzEexuAhGTpgMygqx67Z4,14936
558
+ pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=MJNPpfIxcO-FghxpBbxkG1rFiQf6HOUbV4U5mq0HFns,557
559
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc,,
560
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc,,
561
+ pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=qcXMhmx__MIJq10gGHW3mA4Tl8dy8YzHMccwnNoKlw0,12216
562
+ pip/_vendor/pyproject_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
563
+ pip/_vendor/requests/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
564
+ pip/_vendor/requests/__init__.py,sha256=nC2attFwdoYN-oE6-vQW4ciuvIu7J2P_TU1qQ2DcueE,5873
565
+ pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc,,
566
+ pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc,,
567
+ pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc,,
568
+ pip/_vendor/requests/__pycache__/_types.cpython-312.pyc,,
569
+ pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc,,
570
+ pip/_vendor/requests/__pycache__/api.cpython-312.pyc,,
571
+ pip/_vendor/requests/__pycache__/auth.cpython-312.pyc,,
572
+ pip/_vendor/requests/__pycache__/certs.cpython-312.pyc,,
573
+ pip/_vendor/requests/__pycache__/compat.cpython-312.pyc,,
574
+ pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc,,
575
+ pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc,,
576
+ pip/_vendor/requests/__pycache__/help.cpython-312.pyc,,
577
+ pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc,,
578
+ pip/_vendor/requests/__pycache__/models.cpython-312.pyc,,
579
+ pip/_vendor/requests/__pycache__/packages.cpython-312.pyc,,
580
+ pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc,,
581
+ pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc,,
582
+ pip/_vendor/requests/__pycache__/structures.cpython-312.pyc,,
583
+ pip/_vendor/requests/__pycache__/utils.cpython-312.pyc,,
584
+ pip/_vendor/requests/__version__.py,sha256=q7qQZwsDcKPcQNl8LepGo11L7JQf8Q18PPMJjvBKF_k,435
585
+ pip/_vendor/requests/_internal_utils.py,sha256=TH2NEyyYmPx9cV5HPzrHR4XdxKuW0skkD4eDXcbZgf8,1542
586
+ pip/_vendor/requests/_types.py,sha256=0G33n1SiecDMP67FlsRGJG1a0U7f1SnrMo3vvWKkSok,5838
587
+ pip/_vendor/requests/adapters.py,sha256=5kSKhXlJuR_enrOjd3khSGpRBj1WqCh08Qssu0CEZ8M,28208
588
+ pip/_vendor/requests/api.py,sha256=TRVICsBG8Ikgl5joZQR270oo6-b4G0AHWPjvQuxrVQk,7152
589
+ pip/_vendor/requests/auth.py,sha256=6TlRpVLUw8X9m4Sl4dSbA8qrpHI8T_ES2mBTYA7IWmU,12233
590
+ pip/_vendor/requests/certs.py,sha256=eD1G0RoMZ3kA0lydkw7oo0lmcKqvD1hhz6yOlgSKm8w,442
591
+ pip/_vendor/requests/compat.py,sha256=1UheFGomceWe7aysgboYWxcEOH_HpQFmKhIyPiAanog,2035
592
+ pip/_vendor/requests/cookies.py,sha256=ChzmFA8rlCBSLFCA41bmifp5bCUi9VyhCCb17Y4Kcjw,21549
593
+ pip/_vendor/requests/exceptions.py,sha256=Am6y4ncoBptpmesOjRxc5iiuBDYjx3UN1oRVBlNgRyE,4576
594
+ pip/_vendor/requests/help.py,sha256=TVWejkCROwKexHHB44KCZSr-c0o5XakNL7LT1UJlRy8,4114
595
+ pip/_vendor/requests/hooks.py,sha256=69igJHXTGg5HOo9VPpUB_0NkW5VjiFrVKETnpj8Ndqs,1138
596
+ pip/_vendor/requests/models.py,sha256=99d7WF4pR35NHo9jrbGiBocZ3LCMsloVU0DAcQ49x3Q,41848
597
+ pip/_vendor/requests/packages.py,sha256=_ZQDCJTJ8SP3kVWunSqBsRZNPzj2c1WFVqbdr08pz3U,1057
598
+ pip/_vendor/requests/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
599
+ pip/_vendor/requests/sessions.py,sha256=lvuzC7vwalmlJo0TtXiFFJdWqj8xaVtcFeQd17svZ6Y,34248
600
+ pip/_vendor/requests/status_codes.py,sha256=GVD0fInPGAGXh-B9jOSPZtazjmIvfZTXCpAkf-5sBA4,4351
601
+ pip/_vendor/requests/structures.py,sha256=upRgw5B48l5vHSokrJQaxvjS7pcZf6jI0MJi2KHmegI,4134
602
+ pip/_vendor/requests/utils.py,sha256=u7MICyzQTvfUa3asg9nBvcrnhSIPEc6qhJSxiGGwTOk,36334
603
+ pip/_vendor/resolvelib/LICENSE,sha256=84j9OMrRMRLB3A9mm76A5_hFQe26-3LzAw0sp2QsPJ0,751
604
+ pip/_vendor/resolvelib/__init__.py,sha256=yoX-d4STvwGGCiQRE5cJC9Cter69SgVgqClxOCvSP7M,541
605
+ pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc,,
606
+ pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc,,
607
+ pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc,,
608
+ pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc,,
609
+ pip/_vendor/resolvelib/providers.py,sha256=pIWJbIdJJ9GFtNbtwTH0Ia43Vj6hYCEJj2DOLue15FM,8914
610
+ pip/_vendor/resolvelib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
611
+ pip/_vendor/resolvelib/reporters.py,sha256=pNJf4nFxLpAeKxlBUi2GEj0a2Ij1nikY0UabTKXesT4,2037
612
+ pip/_vendor/resolvelib/resolvers/__init__.py,sha256=728M3EvmnPbVXS7ExXlv2kMu6b7wEsoPutEfl-uVk_I,640
613
+ pip/_vendor/resolvelib/resolvers/__pycache__/__init__.cpython-312.pyc,,
614
+ pip/_vendor/resolvelib/resolvers/__pycache__/abstract.cpython-312.pyc,,
615
+ pip/_vendor/resolvelib/resolvers/__pycache__/criterion.cpython-312.pyc,,
616
+ pip/_vendor/resolvelib/resolvers/__pycache__/exceptions.cpython-312.pyc,,
617
+ pip/_vendor/resolvelib/resolvers/__pycache__/resolution.cpython-312.pyc,,
618
+ pip/_vendor/resolvelib/resolvers/abstract.py,sha256=CNeQPnpAudY77nmzOkONSmAgRlzIf06X-X9mvRYODms,1543
619
+ pip/_vendor/resolvelib/resolvers/criterion.py,sha256=lcmZGv5sKHOnFD_RzZwvlGSj19MeA-5rCMpdf2Sgw7Y,1768
620
+ pip/_vendor/resolvelib/resolvers/exceptions.py,sha256=ln_jaQtgLlRUSFY627yiHG2gD7AgaXzRKaElFVh7fDQ,1768
621
+ pip/_vendor/resolvelib/resolvers/resolution.py,sha256=3J_zkW-sD3EY-BlNXjyln__njpyH5n0UZJT6uV7CheA,24212
622
+ pip/_vendor/resolvelib/structs.py,sha256=pu-EJiR2IBITr2SQeNPRa0rXhjlStfmO_GEgAhr3004,6420
623
+ pip/_vendor/rich/LICENSE,sha256=3u18F6QxgVgZCj6iOcyHmlpQJxzruYrnAl9I--WNyhU,1056
624
+ pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
625
+ pip/_vendor/rich/__main__.py,sha256=e_aVC-tDzarWQW9SuZMuCgBr6ODV_iDNV2Wh2xkxOlw,7896
626
+ pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc,,
627
+ pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc,,
628
+ pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc,,
629
+ pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc,,
630
+ pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc,,
631
+ pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc,,
632
+ pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc,,
633
+ pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc,,
634
+ pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc,,
635
+ pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc,,
636
+ pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc,,
637
+ pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc,,
638
+ pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc,,
639
+ pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc,,
640
+ pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc,,
641
+ pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc,,
642
+ pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc,,
643
+ pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc,,
644
+ pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc,,
645
+ pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc,,
646
+ pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc,,
647
+ pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc,,
648
+ pip/_vendor/rich/__pycache__/abc.cpython-312.pyc,,
649
+ pip/_vendor/rich/__pycache__/align.cpython-312.pyc,,
650
+ pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc,,
651
+ pip/_vendor/rich/__pycache__/bar.cpython-312.pyc,,
652
+ pip/_vendor/rich/__pycache__/box.cpython-312.pyc,,
653
+ pip/_vendor/rich/__pycache__/cells.cpython-312.pyc,,
654
+ pip/_vendor/rich/__pycache__/color.cpython-312.pyc,,
655
+ pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc,,
656
+ pip/_vendor/rich/__pycache__/columns.cpython-312.pyc,,
657
+ pip/_vendor/rich/__pycache__/console.cpython-312.pyc,,
658
+ pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc,,
659
+ pip/_vendor/rich/__pycache__/containers.cpython-312.pyc,,
660
+ pip/_vendor/rich/__pycache__/control.cpython-312.pyc,,
661
+ pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc,,
662
+ pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc,,
663
+ pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc,,
664
+ pip/_vendor/rich/__pycache__/errors.cpython-312.pyc,,
665
+ pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc,,
666
+ pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc,,
667
+ pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc,,
668
+ pip/_vendor/rich/__pycache__/json.cpython-312.pyc,,
669
+ pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc,,
670
+ pip/_vendor/rich/__pycache__/layout.cpython-312.pyc,,
671
+ pip/_vendor/rich/__pycache__/live.cpython-312.pyc,,
672
+ pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc,,
673
+ pip/_vendor/rich/__pycache__/logging.cpython-312.pyc,,
674
+ pip/_vendor/rich/__pycache__/markup.cpython-312.pyc,,
675
+ pip/_vendor/rich/__pycache__/measure.cpython-312.pyc,,
676
+ pip/_vendor/rich/__pycache__/padding.cpython-312.pyc,,
677
+ pip/_vendor/rich/__pycache__/pager.cpython-312.pyc,,
678
+ pip/_vendor/rich/__pycache__/palette.cpython-312.pyc,,
679
+ pip/_vendor/rich/__pycache__/panel.cpython-312.pyc,,
680
+ pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc,,
681
+ pip/_vendor/rich/__pycache__/progress.cpython-312.pyc,,
682
+ pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc,,
683
+ pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc,,
684
+ pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc,,
685
+ pip/_vendor/rich/__pycache__/region.cpython-312.pyc,,
686
+ pip/_vendor/rich/__pycache__/repr.cpython-312.pyc,,
687
+ pip/_vendor/rich/__pycache__/rule.cpython-312.pyc,,
688
+ pip/_vendor/rich/__pycache__/scope.cpython-312.pyc,,
689
+ pip/_vendor/rich/__pycache__/screen.cpython-312.pyc,,
690
+ pip/_vendor/rich/__pycache__/segment.cpython-312.pyc,,
691
+ pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc,,
692
+ pip/_vendor/rich/__pycache__/status.cpython-312.pyc,,
693
+ pip/_vendor/rich/__pycache__/style.cpython-312.pyc,,
694
+ pip/_vendor/rich/__pycache__/styled.cpython-312.pyc,,
695
+ pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc,,
696
+ pip/_vendor/rich/__pycache__/table.cpython-312.pyc,,
697
+ pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc,,
698
+ pip/_vendor/rich/__pycache__/text.cpython-312.pyc,,
699
+ pip/_vendor/rich/__pycache__/theme.cpython-312.pyc,,
700
+ pip/_vendor/rich/__pycache__/themes.cpython-312.pyc,,
701
+ pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc,,
702
+ pip/_vendor/rich/__pycache__/tree.cpython-312.pyc,,
703
+ pip/_vendor/rich/_cell_widths.py,sha256=fbmeyetEdHjzE_Vx2l1uK7tnPOhMs2X1lJfO3vsKDpA,10209
704
+ pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
705
+ pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
706
+ pip/_vendor/rich/_export_format.py,sha256=RI08pSrm5tBSzPMvnbTqbD9WIalaOoN5d4M1RTmLq1Y,2128
707
+ pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
708
+ pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
709
+ pip/_vendor/rich/_inspect.py,sha256=ROT0PLC2GMWialWZkqJIjmYq7INRijQQkoSokWTaAiI,9656
710
+ pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
711
+ pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
712
+ pip/_vendor/rich/_null_file.py,sha256=ADGKp1yt-k70FMKV6tnqCqecB-rSJzp-WQsD7LPL-kg,1394
713
+ pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
714
+ pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
715
+ pip/_vendor/rich/_ratio.py,sha256=IOtl78sQCYZsmHyxhe45krkb68u9xVz7zFsXVJD-b2Y,5325
716
+ pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
717
+ pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
718
+ pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
719
+ pip/_vendor/rich/_win32_console.py,sha256=BSaDRIMwBLITn_m0mTRLPqME5q-quGdSMuYMpYeYJwc,22755
720
+ pip/_vendor/rich/_windows.py,sha256=aBwaD_S56SbgopIvayVmpk0Y28uwY2C5Bab1wl3Bp-I,1925
721
+ pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
722
+ pip/_vendor/rich/_wrap.py,sha256=FlSsom5EX0LVkA3KWy34yHnCfLtqX-ZIepXKh-70rpc,3404
723
+ pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
724
+ pip/_vendor/rich/align.py,sha256=dg-7uY0ukMLLlUEsBDRLva22_sQgIJD4BK0dmZHFHug,10324
725
+ pip/_vendor/rich/ansi.py,sha256=Avs1LHbSdcyOvDOdpELZUoULcBiYewY76eNBp6uFBhs,6921
726
+ pip/_vendor/rich/bar.py,sha256=ldbVHOzKJOnflVNuv1xS7g6dLX2E3wMnXkdPbpzJTcs,3263
727
+ pip/_vendor/rich/box.py,sha256=kmavBc_dn73L_g_8vxWSwYJD2uzBXOUFTtJOfpbczcM,10686
728
+ pip/_vendor/rich/cells.py,sha256=KrQkj5-LghCCpJLSNQIyAZjndc4bnEqOEmi5YuZ9UCY,5130
729
+ pip/_vendor/rich/color.py,sha256=3HSULVDj7qQkXUdFWv78JOiSZzfy5y1nkcYhna296V0,18211
730
+ pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
731
+ pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
732
+ pip/_vendor/rich/console.py,sha256=t9azZpmRMVU5cphVBZSShNsmBxd2-IAWcTTlhor-E1s,100849
733
+ pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
734
+ pip/_vendor/rich/containers.py,sha256=c_56TxcedGYqDepHBMTuZdUIijitAQgnox-Qde0Z1qo,5502
735
+ pip/_vendor/rich/control.py,sha256=EUTSUFLQbxY6Zmo_sdM-5Ls323vIHTBfN8TPulqeHUY,6487
736
+ pip/_vendor/rich/default_styles.py,sha256=khQFqqaoDs3bprMqWpHw8nO5UpG2DN6QtuTd6LzZwYc,8257
737
+ pip/_vendor/rich/diagnose.py,sha256=fJl1TItRn19gGwouqTg-8zPUW3YqQBqGltrfPQs1H9w,1025
738
+ pip/_vendor/rich/emoji.py,sha256=Wd4bQubZdSy6-PyrRQNuMHtn2VkljK9uPZPVlu2cmx0,2367
739
+ pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
740
+ pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
741
+ pip/_vendor/rich/filesize.py,sha256=_iz9lIpRgvW7MNSeCZnLg-HwzbP4GETg543WqD8SFs0,2484
742
+ pip/_vendor/rich/highlighter.py,sha256=G_sn-8DKjM1sEjLG_oc4ovkWmiUpWvj8bXi0yed2LnY,9586
743
+ pip/_vendor/rich/json.py,sha256=vVEoKdawoJRjAFayPwXkMBPLy7RSTs-f44wSQDR2nJ0,5031
744
+ pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
745
+ pip/_vendor/rich/layout.py,sha256=ajkSFAtEVv9EFTcFs-w4uZfft7nEXhNzL7ZVdgrT5rI,14004
746
+ pip/_vendor/rich/live.py,sha256=tF3ukAAJZ_N2ZbGclqZ-iwLoIoZ8f0HHUz79jAyJqj8,15180
747
+ pip/_vendor/rich/live_render.py,sha256=It_39YdzrBm8o3LL0kaGorPFg-BfZWAcrBjLjFokbx4,3521
748
+ pip/_vendor/rich/logging.py,sha256=5KaPPSMP9FxcXPBcKM4cGd_zW78PMgf-YbMVnvfSw0o,12468
749
+ pip/_vendor/rich/markup.py,sha256=3euGKP5s41NCQwaSjTnJxus5iZMHjxpIM0W6fCxra38,8451
750
+ pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
751
+ pip/_vendor/rich/padding.py,sha256=KVEI3tOwo9sgK1YNSuH__M1_jUWmLZwRVV_KmOtVzyM,4908
752
+ pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
753
+ pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
754
+ pip/_vendor/rich/panel.py,sha256=9sQl00hPIqH5G2gALQo4NepFwpP0k9wT-s_gOms5pIc,11157
755
+ pip/_vendor/rich/pretty.py,sha256=gy3S72u4FRg2ytoo7N1ZDWDIvB4unbzd5iUGdgm-8fc,36391
756
+ pip/_vendor/rich/progress.py,sha256=CUc2lkU-X59mVdGfjMCBkZeiGPL3uxdONjhNJF2T7wY,60408
757
+ pip/_vendor/rich/progress_bar.py,sha256=mZTPpJUwcfcdgQCTTz3kyY-fc79ddLwtx6Ghhxfo064,8162
758
+ pip/_vendor/rich/prompt.py,sha256=l0RhQU-0UVTV9e08xW1BbIj0Jq2IXyChX4lC0lFNzt4,12447
759
+ pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
760
+ pip/_vendor/rich/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
761
+ pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
762
+ pip/_vendor/rich/repr.py,sha256=5MZJZmONgC6kud-QW-_m1okXwL2aR6u6y-pUcUCJz28,4431
763
+ pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
764
+ pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
765
+ pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
766
+ pip/_vendor/rich/segment.py,sha256=otnKeKGEV-WRlQVosfJVeFDcDxAKHpvJ_hLzSu5lumM,24743
767
+ pip/_vendor/rich/spinner.py,sha256=onIhpKlljRHppTZasxO8kXgtYyCHUkpSgKglRJ3o51g,4214
768
+ pip/_vendor/rich/status.py,sha256=kkPph3YeAZBo-X-4wPp8gTqZyU466NLwZBA4PZTTewo,4424
769
+ pip/_vendor/rich/style.py,sha256=W9Ccy8Py8lNICtlfcp-ryzMTuQaGxAU3av7-g5fHu0s,26990
770
+ pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
771
+ pip/_vendor/rich/syntax.py,sha256=eDKIRwl--eZ0Lwo2da2RRtfutXGavrJO61Cl5OkS59U,36371
772
+ pip/_vendor/rich/table.py,sha256=ZmT7V7MMCOYKw7TGY9SZLyYDf6JdM-WVf07FdVuVhTI,40049
773
+ pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
774
+ pip/_vendor/rich/text.py,sha256=AO7JPCz6-gaN1thVLXMBntEmDPVYFgFNG1oM61_sanU,47552
775
+ pip/_vendor/rich/theme.py,sha256=oNyhXhGagtDlbDye3tVu3esWOWk0vNkuxFw-_unlaK0,3771
776
+ pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
777
+ pip/_vendor/rich/traceback.py,sha256=c0WmB_L04_UfZbLaoH982_U_s7eosxKMUiAVmDPdRYU,35861
778
+ pip/_vendor/rich/tree.py,sha256=yWnQ6rAvRGJ3qZGqBrxS2SW2TKBTNrP0SdY8QxOFPuw,9451
779
+ pip/_vendor/tomli/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
780
+ pip/_vendor/tomli/__init__.py,sha256=nrBC18DbXRTCFo7ElG5BDeWpHJzOhokvXk215GM8Z2I,314
781
+ pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc,,
782
+ pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc,,
783
+ pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc,,
784
+ pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc,,
785
+ pip/_vendor/tomli/_parser.py,sha256=pBIjTIa_cQs2HglDJ2lh8OJfptfDa6eg5-7Iej4BjHs,26440
786
+ pip/_vendor/tomli/_re.py,sha256=oSNZ_ilFI6chEuQ01YRSoUydBQr_okF_mSdHTkFmv90,3396
787
+ pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
788
+ pip/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
789
+ pip/_vendor/tomli_w/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
790
+ pip/_vendor/tomli_w/__init__.py,sha256=0F8yDtXx3Uunhm874KrAcP76srsM98y7WyHQwCulZbo,169
791
+ pip/_vendor/tomli_w/__pycache__/__init__.cpython-312.pyc,,
792
+ pip/_vendor/tomli_w/__pycache__/_writer.cpython-312.pyc,,
793
+ pip/_vendor/tomli_w/_writer.py,sha256=dsifFS2xYf1i76mmRyfz9y125xC7Z_HQ845ZKhJsYXs,6961
794
+ pip/_vendor/tomli_w/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
795
+ pip/_vendor/truststore/LICENSE,sha256=M757fo-k_Rmxdg4ajtimaL2rhSyRtpLdQUJLy3Jan8o,1086
796
+ pip/_vendor/truststore/__init__.py,sha256=Bu7kqkmpunhLsj5xCu8gT_25ktoPXcSnwe8VHk1GmJo,1320
797
+ pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc,,
798
+ pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc,,
799
+ pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc,,
800
+ pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc,,
801
+ pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc,,
802
+ pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc,,
803
+ pip/_vendor/truststore/_api.py,sha256=CYJCV5BTfttZYfqY3movdMBE-8az7uhET_LYbKT2Nn4,11413
804
+ pip/_vendor/truststore/_macos.py,sha256=nZlLkOmszUE0g6ryRwBVGY5COzPyudcsiJtDWarM5LQ,20503
805
+ pip/_vendor/truststore/_openssl.py,sha256=zB-SQvJydks7tQ0yIwrP6GD3fQNSSaPiq7zw4yF5T40,2412
806
+ pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
807
+ pip/_vendor/truststore/_windows.py,sha256=rAHyKYD8M7t-bXfG8VgOVa3TpfhVhbt4rZQlO45YuP8,17993
808
+ pip/_vendor/truststore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
809
+ pip/_vendor/urllib3/LICENSE.txt,sha256=Ew46ZNX91dCWp1JpRjSn2d8oRGnehuVzIQAmgEHj1oY,1093
810
+ pip/_vendor/urllib3/__init__.py,sha256=JMo1tg1nIV1AeJ2vENC_Txfl0e5h6Gzl9DGVk1rWRbo,6979
811
+ pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc,,
812
+ pip/_vendor/urllib3/__pycache__/_base_connection.cpython-312.pyc,,
813
+ pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc,,
814
+ pip/_vendor/urllib3/__pycache__/_request_methods.cpython-312.pyc,,
815
+ pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc,,
816
+ pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc,,
817
+ pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc,,
818
+ pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc,,
819
+ pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc,,
820
+ pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc,,
821
+ pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc,,
822
+ pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc,,
823
+ pip/_vendor/urllib3/_base_connection.py,sha256=HzcSEHexgDrRUr60jNniB2KQjdw97SedD5luRfHtCXg,5580
824
+ pip/_vendor/urllib3/_collections.py,sha256=aOVm2mKilvuvT1efAGtkA7pi65C1NC3HJfpFxvYBS8A,17522
825
+ pip/_vendor/urllib3/_request_methods.py,sha256=gCeF85SO_UU4WoPwYHIoz_tw-eM_EVOkLFp8OFsC7DA,9931
826
+ pip/_vendor/urllib3/_version.py,sha256=-gMrKhsPiOj0XzUezVFa59d1S6QgQiKgQT5gGgyM8-w,520
827
+ pip/_vendor/urllib3/connection.py,sha256=Zos3qxKDW9-GQ6aVqfBQVRM5soB0IjHxY_xXWpJaFTI,42786
828
+ pip/_vendor/urllib3/connectionpool.py,sha256=sGFnddXYwlx7KC4JCP1gKvdNGLNK-YTCJDdGACGj3Y8,44164
829
+ pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
830
+ pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc,,
831
+ pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,,
832
+ pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc,,
833
+ pip/_vendor/urllib3/contrib/emscripten/__init__.py,sha256=ZruXaWKVzAEJdqNH3NEh0mrHrw--2VZYb0zX0RonNZA,870
834
+ pip/_vendor/urllib3/contrib/emscripten/__pycache__/__init__.cpython-312.pyc,,
835
+ pip/_vendor/urllib3/contrib/emscripten/__pycache__/connection.cpython-312.pyc,,
836
+ pip/_vendor/urllib3/contrib/emscripten/__pycache__/fetch.cpython-312.pyc,,
837
+ pip/_vendor/urllib3/contrib/emscripten/__pycache__/request.cpython-312.pyc,,
838
+ pip/_vendor/urllib3/contrib/emscripten/__pycache__/response.cpython-312.pyc,,
839
+ pip/_vendor/urllib3/contrib/emscripten/connection.py,sha256=giElsBoUsKVURbZzb8GCrJmqW23Xnvj2aNyQVF42slg,8960
840
+ pip/_vendor/urllib3/contrib/emscripten/emscripten_fetch_worker.js,sha256=z1k3zZ4_hDKd3-tN7wzz8LHjHC2pxN_uu8B3k9D9A3c,3677
841
+ pip/_vendor/urllib3/contrib/emscripten/fetch.py,sha256=5xcd--viFxZd2nBy0aK73dtJ9Tsh1yYZU_SUXwnwibk,23520
842
+ pip/_vendor/urllib3/contrib/emscripten/request.py,sha256=mL28szy1KvE3NJhWor5jNmarp8gwplDU-7gwGZY5g0Q,566
843
+ pip/_vendor/urllib3/contrib/emscripten/response.py,sha256=CDpY0GFoluR3IxECkM2gH5uDfYDM0EL1FWr7B76wtgM,9719
844
+ pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=Pi_qwvdl83tNpuj1k5pCpP_gmxlk4BfFrTlAeg-qZ_U,19760
845
+ pip/_vendor/urllib3/contrib/socks.py,sha256=rSuklfha4-vto-8qSLhSPmf5lmRPIYuqdAxKe9bg2RA,7639
846
+ pip/_vendor/urllib3/exceptions.py,sha256=hQPHoqo4yw46esNSVkciVQXVUgAxWAglsh6MbyQta-Q,9945
847
+ pip/_vendor/urllib3/fields.py,sha256=aGLFAVZpVU-FbJlllve4Ahg0-pH9ZZBQ2Iz7lfpkjkM,10801
848
+ pip/_vendor/urllib3/filepost.py,sha256=U8eNZ-mpKKHhrlbHEEiTxxgK16IejhEa7uz42yqA_dI,2388
849
+ pip/_vendor/urllib3/http2/__init__.py,sha256=xzrASH7R5ANRkPJOot5lGnATOq3KKuyXzI42rcnwmqs,1741
850
+ pip/_vendor/urllib3/http2/__pycache__/__init__.cpython-312.pyc,,
851
+ pip/_vendor/urllib3/http2/__pycache__/connection.cpython-312.pyc,,
852
+ pip/_vendor/urllib3/http2/__pycache__/probe.cpython-312.pyc,,
853
+ pip/_vendor/urllib3/http2/connection.py,sha256=bHMH6fNvatwXPrKqrcn74yA3pUWcqPDppnK1LcKCbP8,12578
854
+ pip/_vendor/urllib3/http2/probe.py,sha256=nnAkqbhAakOiF75rz7W0udZ38Eeh_uD8fjV74N73FEI,3014
855
+ pip/_vendor/urllib3/poolmanager.py,sha256=grIrETG1rgHYBaQau1yN4xxfK8U9CKVRYmwBXW_kdSo,23929
856
+ pip/_vendor/urllib3/py.typed,sha256=UaCuPFa3H8UAakbt-5G8SPacldTOGvJv18pPjUJ5gDY,93
857
+ pip/_vendor/urllib3/response.py,sha256=DzBM-dzl6x_h2EZGc9iw0gbOkQ36bolC7WESH4TurH8,53031
858
+ pip/_vendor/urllib3/util/__init__.py,sha256=-qeS0QceivazvBEKDNFCAI-6ACcdDOE4TMvo7SLNlAQ,1001
859
+ pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc,,
860
+ pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc,,
861
+ pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc,,
862
+ pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc,,
863
+ pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc,,
864
+ pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc,,
865
+ pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc,,
866
+ pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,,
867
+ pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc,,
868
+ pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc,,
869
+ pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc,,
870
+ pip/_vendor/urllib3/util/__pycache__/util.cpython-312.pyc,,
871
+ pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc,,
872
+ pip/_vendor/urllib3/util/connection.py,sha256=JjO722lzHlzLXPTkr9ZWBdhseXnMVjMSb1DJLVrXSnQ,4444
873
+ pip/_vendor/urllib3/util/proxy.py,sha256=seP8-Q5B6bB0dMtwPj-YcZZQ30vHuLqRu-tI0JZ2fzs,1148
874
+ pip/_vendor/urllib3/util/request.py,sha256=p9Ki9eo1tFBO-jqV_7KmmJ60RKqoY2r4ao0SmaHLyOs,8086
875
+ pip/_vendor/urllib3/util/response.py,sha256=vQE639uoEhj1vpjEdxu5lNIhJCSUZkd7pqllUI0BZOA,3374
876
+ pip/_vendor/urllib3/util/retry.py,sha256=2YnSX-_FecMShD61Mx5s68J0_btUHZrrc_BkFVRS1P4,19577
877
+ pip/_vendor/urllib3/util/ssl_.py,sha256=Oqe3rIhUU3e3GVgZob2hxmR8Q0ZDhrhESPlPP_GLaVQ,17742
878
+ pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ft44KJzTzGMmKff_ZXP91li2V4WhmvEy16PKBcv4vZk,5479
879
+ pip/_vendor/urllib3/util/ssltransport.py,sha256=Ez4O8pR_vT8dan_FvqBYS6dgDfBXEMfVfrzcdUoWfi4,8847
880
+ pip/_vendor/urllib3/util/timeout.py,sha256=vsUJRpO0nfKk-y1OKlgFGY1ONJGPgkaZ7B7kruEpVYw,10363
881
+ pip/_vendor/urllib3/util/url.py,sha256=PEDQMypidude0nAZctLLiFK9epN-LPnSH7KpOLLwqH0,15256
882
+ pip/_vendor/urllib3/util/util.py,sha256=j3lbZK1jPyiwD34T8IgJzdWEZVT-4E-0vYIJi9UjeNA,1146
883
+ pip/_vendor/urllib3/util/wait.py,sha256=_ph8IrUR3sqPqi0OopQgJUlH4wzkGeM5CiyA7XGGtmI,4423
884
+ pip/_vendor/vendor.txt,sha256=PfDJYBv6Lg3KI8xXSk-QCk1_2tBgqyA_q4NUNQ7ZMyA,317
885
+ pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/REQUESTED ADDED
File without changes
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: flit 3.12.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/entry_points.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ [console_scripts]
2
+ pip=pip._internal.cli.main:main
3
+ pip3=pip._internal.cli.main:main
4
+
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/AUTHORS.txt ADDED
@@ -0,0 +1,888 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @Switch01
2
+ A_Rog
3
+ Aakanksha Agrawal
4
+ Aarni Koskela
5
+ abdul rawoof
6
+ Abdul Rawoof Khan
7
+ Abhinav Sagar
8
+ ABHYUDAY PRATAP SINGH
9
+ abs51295
10
+ AceGentile
11
+ Adam Chainz
12
+ Adam Tse
13
+ Adam Turner
14
+ Adam Wentz
15
+ admin
16
+ Adolfo OchagavΓ­a
17
+ Adrien Morison
18
+ Agus
19
+ ahayrapetyan
20
+ Ahilya
21
+ AinsworthK
22
+ Akash Srivastava
23
+ Alan Yee
24
+ Albert Tugushev
25
+ Albert-Guan
26
+ albertg
27
+ Alberto Sottile
28
+ Aleks Bunin
29
+ Ales Erjavec
30
+ Alessandro Molina
31
+ Alethea Flowers
32
+ Alex Gaynor
33
+ Alex GrΓΆnholm
34
+ Alex Hedges
35
+ Alex Loosley
36
+ Alex Morega
37
+ Alex Stachowiak
38
+ Alexander Regueiro
39
+ Alexander Shtyrov
40
+ Alexandre Conrad
41
+ Alexey Popravka
42
+ AleΕ‘ Erjavec
43
+ Alli
44
+ Aman
45
+ Ami Fischman
46
+ Ananya Maiti
47
+ Anatoly Techtonik
48
+ Anders Kaseorg
49
+ Andre Aguiar
50
+ Andrea Corna
51
+ Andreas Lutro
52
+ Andrei Geacar
53
+ Andrew Gaul
54
+ Andrew Shymanel
55
+ Andrey Bienkowski
56
+ Andrey Bulgakov
57
+ AndrΓ©s Delfino
58
+ Andy Freeland
59
+ Andy Kluger
60
+ Ani Hayrapetyan
61
+ Aniruddha Basak
62
+ Anish Tambe
63
+ Anrs Hu
64
+ Anthony Sottile
65
+ Antoine Lambert
66
+ Antoine Musso
67
+ Anton Ovchinnikov
68
+ Anton Patrushev
69
+ Anton Zelenov
70
+ Antonio Alvarado Hernandez
71
+ Antony Lee
72
+ Antti Kaihola
73
+ Anubhav Patel
74
+ Anudit Nagar
75
+ Anuj Godase
76
+ AQNOUCH Mohammed
77
+ AraHaan
78
+ Aren Siekmeier
79
+ arena
80
+ arenasys
81
+ Arindam Choudhury
82
+ Armin Ronacher
83
+ Arnon Yaari
84
+ Artem
85
+ Arun Babu Neelicattu
86
+ Ashley Manton
87
+ Ashwin Ramaswami
88
+ atse
89
+ Atsushi Odagiri
90
+ Avinash Karhana
91
+ Avner Cohen
92
+ Awit (Ah-Wit) Ghirmai
93
+ Baptiste Mispelon
94
+ Barney Gale
95
+ barneygale
96
+ Bartek Ogryczak
97
+ Bastian Venthur
98
+ Ben Bodenmiller
99
+ Ben Darnell
100
+ Ben Hoyt
101
+ Ben Mares
102
+ Ben Rosser
103
+ Bence Nagy
104
+ Benjamin Peterson
105
+ Benjamin VanEvery
106
+ Benoit Pierre
107
+ Berker Peksag
108
+ Bernard
109
+ Bernard Tyers
110
+ Bernardo B. Marques
111
+ Bernhard M. Wiedemann
112
+ Bertil Hatt
113
+ Bhavam Vidyarthi
114
+ Blazej Michalik
115
+ Bogdan Opanchuk
116
+ BorisZZZ
117
+ Brad Erickson
118
+ Bradley Ayers
119
+ Bradley Reynolds
120
+ Branch Vincent
121
+ Brandon L. Reiss
122
+ Brandt Bucher
123
+ Brannon Dorsey
124
+ Brett Randall
125
+ Brett Rosen
126
+ Brian Cristante
127
+ Brian Rosner
128
+ briantracy
129
+ BrownTruck
130
+ Bruno Oliveira
131
+ Bruno ReniΓ©
132
+ Bruno S
133
+ Bstrdsmkr
134
+ Buck Golemon
135
+ burrows
136
+ Bussonnier Matthias
137
+ bwoodsend
138
+ c22
139
+ Caleb Brown
140
+ Caleb Martinez
141
+ Calvin Smith
142
+ Carl Meyer
143
+ Carlos Liam
144
+ Carol Willing
145
+ Carter Thayer
146
+ Cass
147
+ Chandrasekhar Atina
148
+ Charlie Marsh
149
+ charwick
150
+ Chih-Hsuan Yen
151
+ Chris Brinker
152
+ Chris Hunt
153
+ Chris Jerdonek
154
+ Chris Kuehl
155
+ Chris Markiewicz
156
+ Chris McDonough
157
+ Chris Pawley
158
+ Chris Pryer
159
+ Chris Wolfe
160
+ Christian Clauss
161
+ Christian Heimes
162
+ Christian Oudard
163
+ Christoph Reiter
164
+ Christopher Hunt
165
+ Christopher Snyder
166
+ chrysle
167
+ cjc7373
168
+ Clark Boylan
169
+ Claudio Jolowicz
170
+ Clay McClure
171
+ Cody
172
+ Cody Soyland
173
+ Colin Watson
174
+ Collin Anderson
175
+ Connor Osborn
176
+ Cooper Lees
177
+ Cooper Ry Lees
178
+ Cory Benfield
179
+ Cory Wright
180
+ Craig Kerstiens
181
+ Cristian Sorinel
182
+ Cristina
183
+ Cristina MuΓ±oz
184
+ ctg123
185
+ Curtis Doty
186
+ cytolentino
187
+ Daan De Meyer
188
+ Dale
189
+ Damian
190
+ Damian Quiroga
191
+ Damian Shaw
192
+ Dan Black
193
+ Dan Savilonis
194
+ Dan Sully
195
+ Dane Hillard
196
+ daniel
197
+ Daniel Collins
198
+ Daniel Hahler
199
+ Daniel Hollas
200
+ Daniel Holth
201
+ Daniel Jost
202
+ Daniel Katz
203
+ Daniel Shaulov
204
+ Daniele Esposti
205
+ Daniele Nicolodi
206
+ Daniele Procida
207
+ Daniil Konovalenko
208
+ Danny Hermes
209
+ Danny McClanahan
210
+ Darren Kavanagh
211
+ Dav Clark
212
+ Dave Abrahams
213
+ Dave Jones
214
+ David Aguilar
215
+ David Black
216
+ David Bordeynik
217
+ David Caro
218
+ David D Lowe
219
+ David Evans
220
+ David Hewitt
221
+ David Linke
222
+ David Poggi
223
+ David Poznik
224
+ David Pursehouse
225
+ David Runge
226
+ David Tucker
227
+ David Wales
228
+ Davidovich
229
+ Dayna Blackwell
230
+ ddelange
231
+ Deepak Sharma
232
+ Deepyaman Datta
233
+ Denis Roussel (ACSONE)
234
+ Denise Yu
235
+ dependabot[bot]
236
+ dereksz
237
+ derwolfe
238
+ Desetude
239
+ developer
240
+ Devesh Kumar
241
+ Devesh Kumar Singh
242
+ devsagul
243
+ Dewank Pant
244
+ Diego Caraballo
245
+ Diego Ramirez
246
+ DiegoCaraballo
247
+ Dimitri Merejkowsky
248
+ Dimitri Papadopoulos
249
+ Dimitri Papadopoulos Orfanos
250
+ Dirk Stolle
251
+ dkjsone
252
+ Dmitrii Sutiagin
253
+ Dmitry Gladkov
254
+ Dmitry Volodin
255
+ Domen KoΕΎar
256
+ Dominic Davis-Foster
257
+ Donald Stufft
258
+ Dongweiming
259
+ doron zarhi
260
+ Dos Moonen
261
+ Douglas Thor
262
+ DrFeathers
263
+ Dustin Ingram
264
+ Dustin Rodrigues
265
+ Dwayne Bailey
266
+ Ed Morley
267
+ Edgar RamΓ­rez
268
+ Edgar RamΓ­rez MondragΓ³n
269
+ Ee Durbin
270
+ Efflam Lemaillet
271
+ efflamlemaillet
272
+ Eitan Adler
273
+ ekristina
274
+ elainechan
275
+ Eli Schwartz
276
+ Elisha Hollander
277
+ Ellen Marie Dash
278
+ Emil Burzo
279
+ Emil Styrke
280
+ Emmanuel Arias
281
+ Endoh Takanao
282
+ enoch
283
+ Erdinc Mutlu
284
+ Eric Cousineau
285
+ Eric Gillingham
286
+ Eric Hanchrow
287
+ Eric Hopper
288
+ Erik M. Bray
289
+ Erik Rose
290
+ Erwin Janssen
291
+ Eugene Vereshchagin
292
+ everdimension
293
+ Federico
294
+ Felipe Peter
295
+ Felix Yan
296
+ fiber-space
297
+ Filip KokosiΕ„ski
298
+ Filipe LaΓ­ns
299
+ Finn Womack
300
+ finnagin
301
+ Flavio Amurrio
302
+ Florian Briand
303
+ Florian Rathgeber
304
+ Francesco
305
+ Francesco Montesano
306
+ Fredrik Orderud
307
+ Fredrik Roubert
308
+ Frost Ming
309
+ Gabriel Curio
310
+ Gabriel de Perthuis
311
+ Garry Polley
312
+ gavin
313
+ gdanielson
314
+ Gene Wood
315
+ Geoffrey Sneddon
316
+ George Margaritis
317
+ George Song
318
+ Georgi Valkov
319
+ Georgy Pchelkin
320
+ Gertjan van Zwieten
321
+ ghost
322
+ Giancarlo Cicellyn Comneno
323
+ Giftlin Rajaiah
324
+ gizmoguy1
325
+ gkdoc
326
+ Godefroid Chapelle
327
+ Gopinath M
328
+ GOTO Hayato
329
+ gousaiyang
330
+ gpiks
331
+ Greg Roodt
332
+ Greg Ward
333
+ Guido Diepen
334
+ Guilherme Espada
335
+ Guillaume Seguin
336
+ gutsytechster
337
+ Guy Rozendorn
338
+ Guy Tuval
339
+ gzpan123
340
+ Hanjun Kim
341
+ Hari Charan
342
+ Harsh Vardhan
343
+ Harsha Sai
344
+ harupy
345
+ Harutaka Kawamura
346
+ Hasan-8326
347
+ hauntsaninja
348
+ Henrich Hartzer
349
+ Henry Schreiner
350
+ Herbert Pfennig
351
+ Holly Stotelmyer
352
+ Honnix
353
+ Hsiaoming Yang
354
+ Hugo
355
+ Hugo Lopes Tavares
356
+ Hugo van Kemenade
357
+ Hugues Bruant
358
+ Hynek Schlawack
359
+ iamsrp-deshaw
360
+ Ian Bicking
361
+ Ian Cordasco
362
+ Ian Lee
363
+ Ian Stapleton Cordasco
364
+ Ian Wienand
365
+ Igor Kuzmitshov
366
+ Igor Sobreira
367
+ Ikko Ashimine
368
+ Ilan Schnell
369
+ Illia Volochii
370
+ Ilya Abdolmanafi
371
+ Ilya Baryshev
372
+ Inada Naoki
373
+ Ionel Cristian Mărieș
374
+ Ionel Maries Cristian
375
+ Itamar Turner-Trauring
376
+ iTrooz
377
+ Ivan Pozdeev
378
+ J. Nick Koston
379
+ Jacob Kim
380
+ Jacob Walls
381
+ Jaime Sanz
382
+ Jake Lishman
383
+ jakirkham
384
+ Jakub Kuczys
385
+ Jakub Stasiak
386
+ Jakub Vysoky
387
+ Jakub Wilk
388
+ James
389
+ James Cleveland
390
+ James Curtin
391
+ James Firth
392
+ James Gerity
393
+ James Polley
394
+ Jan PokornΓ½
395
+ Jannis Leidel
396
+ Jarek Potiuk
397
+ jarondl
398
+ Jason Curtis
399
+ Jason R. Coombs
400
+ JasonMo
401
+ JasonMo1
402
+ Jay Graves
403
+ Jean Abou Samra
404
+ Jean-Christophe Fillion-Robin
405
+ Jeff Barber
406
+ Jeff Dairiki
407
+ Jeff Widman
408
+ Jelmer VernooΔ³
409
+ jenix21
410
+ Jeremy Fleischman
411
+ Jeremy Stanley
412
+ Jeremy Zafran
413
+ Jesse Rittner
414
+ Jiashuo Li
415
+ Jim Fisher
416
+ Jim Garrison
417
+ Jinzhe Zeng
418
+ Jiun Bae
419
+ Jivan Amara
420
+ Joa
421
+ Joe Bylund
422
+ Joe Michelini
423
+ Johannes Altmanninger
424
+ John Paton
425
+ John Sirois
426
+ John T. Wodder II
427
+ John-Scott Atlakson
428
+ johnthagen
429
+ Jon Banafato
430
+ Jon Dufresne
431
+ Jon Parise
432
+ Jonas Nockert
433
+ Jonathan Herbert
434
+ Joonatan Partanen
435
+ Joost Molenaar
436
+ Jorge Niedbalski
437
+ Joseph Bylund
438
+ Joseph Long
439
+ Josh Bronson
440
+ Josh Cannon
441
+ Josh Hansen
442
+ Josh Schneier
443
+ Joshua
444
+ JoshuaPerdue
445
+ Jost Migenda
446
+ Juan Luis Cano RodrΓ­guez
447
+ Juanjo BazΓ‘n
448
+ Judah Rand
449
+ Julian Berman
450
+ Julian Gethmann
451
+ Julien Demoor
452
+ Julien Stephan
453
+ July Tikhonov
454
+ Jussi Kukkonen
455
+ Justin van Heek
456
+ jwg4
457
+ Jyrki Pulliainen
458
+ Kai Chen
459
+ Kai Mueller
460
+ Kamal Bin Mustafa
461
+ Karolina Surma
462
+ kasium
463
+ kaustav haldar
464
+ Kaz Nishimura
465
+ keanemind
466
+ Keith Maxwell
467
+ Kelsey Hightower
468
+ Kenneth Belitzky
469
+ Kenneth Reitz
470
+ Kevin Burke
471
+ Kevin Carter
472
+ Kevin Frommelt
473
+ Kevin R Patterson
474
+ Kevin Turcios
475
+ Kexuan Sun
476
+ Kit Randel
477
+ Klaas van Schelven
478
+ KOLANICH
479
+ konstin
480
+ kpinc
481
+ Krishan Bhasin
482
+ Krishna Oza
483
+ Kumar McMillan
484
+ Kuntal Majumder
485
+ Kurt McKee
486
+ Kyle Persohn
487
+ lakshmanaram
488
+ Laszlo Kiss-Kollar
489
+ Laurent Bristiel
490
+ Laurent LAPORTE
491
+ Laurie O
492
+ Laurie Opperman
493
+ layday
494
+ Leon Sasson
495
+ Lev Givon
496
+ Lincoln de Sousa
497
+ Lipis
498
+ lorddavidiii
499
+ Loren Carvalho
500
+ Louis Liu
501
+ Lucas Cimon
502
+ Ludovic Gasc
503
+ Luis Carlos
504
+ Luis Medel
505
+ Lukas Geiger
506
+ Lukas Juhrich
507
+ Luke Macken
508
+ Luo Jiebin
509
+ luojiebin
510
+ luz.paz
511
+ LΓ‘szlΓ³ Kiss KollΓ‘r
512
+ M00nL1ght
513
+ MajorTanya
514
+ Malcolm Smith
515
+ Marc Abramowitz
516
+ Marc Tamlyn
517
+ Marcus Smith
518
+ Mariatta
519
+ Mark Kohler
520
+ Mark McLoughlin
521
+ Mark Williams
522
+ Markus Hametner
523
+ Martey Dodoo
524
+ Martin Fischer
525
+ Martin HΓ€cker
526
+ Martin Pavlasek
527
+ Masaki
528
+ Masklinn
529
+ Matej Stuchlik
530
+ Mateusz SokΓ³Ε‚
531
+ Mathew Jennings
532
+ Mathieu Bridon
533
+ Mathieu Kniewallner
534
+ Matt Bacchi
535
+ Matt Good
536
+ Matt Maker
537
+ Matt Robenolt
538
+ Matt Wozniski
539
+ matthew
540
+ Matthew Einhorn
541
+ Matthew Feickert
542
+ Matthew Gilliard
543
+ Matthew Hughes
544
+ Matthew Iversen
545
+ Matthew Treinish
546
+ Matthew Trumbell
547
+ Matthew Willson
548
+ Matthias Bussonnier
549
+ mattip
550
+ Maurits van Rees
551
+ Max W Chase
552
+ Maxim Kurnikov
553
+ Maxime Rouyrre
554
+ mayeut
555
+ mbaluna
556
+ Md Sujauddin Sekh
557
+ mdebi
558
+ Meet Vasita
559
+ memoselyk
560
+ meowmeowcat
561
+ Michael
562
+ Michael Aquilina
563
+ Michael E. Karpeles
564
+ Michael Klich
565
+ Michael Mintz
566
+ Michael Williamson
567
+ michaelpacer
568
+ MichaΕ‚ GΓ³rny
569
+ MickaΓ«l Schoentgen
570
+ Miguel Araujo Perez
571
+ Mihir Singh
572
+ Mike
573
+ Mike Hendricks
574
+ Min RK
575
+ MinRK
576
+ Miro Hrončok
577
+ Mohsen Fooladnezhad
578
+ Monica Baluna
579
+ montefra
580
+ Monty Taylor
581
+ morotti
582
+ mrKazzila
583
+ Muha Ajjan
584
+ MUTHUSRIHEMADHARSHINI S A
585
+ Nadav Wexler
586
+ Nahuel Ambrosini
587
+ Nate Coraor
588
+ Nate Prewitt
589
+ Nathan Houghton
590
+ Nathaniel J. Smith
591
+ Nehal J Wani
592
+ Neil Botelho
593
+ Nguyα»…n Gia Phong
594
+ Nicholas Serra
595
+ Nick Coghlan
596
+ Nick Stenning
597
+ Nick Timkovich
598
+ Nicolas Bock
599
+ Nicole Harris
600
+ Nikhil Benesch
601
+ Nikhil Ladha
602
+ Nikita Chepanov
603
+ Nikolay Korolev
604
+ Nipunn Koorapati
605
+ Nitesh Sharma
606
+ Niyas Sait
607
+ Noah
608
+ Noah Gorny
609
+ Nok Lam Chan
610
+ Norbert Manthey
611
+ Nothing-991
612
+ Nowell Strite
613
+ NtaleGrey
614
+ nucccc
615
+ nvdv
616
+ OBITORASU
617
+ Ofek Lev
618
+ ofrinevo
619
+ Oleg Burnaev
620
+ Oliver Freund
621
+ Oliver Jeeves
622
+ Oliver Mannion
623
+ Oliver Tonnhofer
624
+ Olivier Girardot
625
+ Olivier Grisel
626
+ Ollie Rutherfurd
627
+ Omar Abdalgwad
628
+ OMOTO Kenji
629
+ Omry Yadan
630
+ onlinejudge95
631
+ Oren Held
632
+ Oscar Benjamin
633
+ oxygen dioxide
634
+ Oz N Tiram
635
+ Pachwenko
636
+ Paresh Joshi
637
+ Patrick Dubroy
638
+ Patrick Jenkins
639
+ Patrick Lawson
640
+ patricktokeeffe
641
+ Patrik Kopkan
642
+ Paul Ganssle
643
+ Paul Kehrer
644
+ Paul Moore
645
+ Paul Nasrat
646
+ Paul Oswald
647
+ Paul van der Linden
648
+ Paulus Schoutsen
649
+ Pavel Safronov
650
+ Pavithra Eswaramoorthy
651
+ Pawel Jasinski
652
+ PaweΕ‚ Szramowski
653
+ Pekka KlΓ€rck
654
+ Peter Gessler
655
+ Peter LisΓ‘k
656
+ Peter Shen
657
+ Peter Waller
658
+ Petr Viktorin
659
+ petr-tik
660
+ Phaneendra Chiruvella
661
+ Phil Elson
662
+ Phil Freo
663
+ Phil Pennock
664
+ Phil Whelan
665
+ Philip JΓ€genstedt
666
+ Philip Molloy
667
+ Philippe Ombredanne
668
+ Pi Delport
669
+ Pierre-Yves Rofes
670
+ Pieter Degroote
671
+ pip
672
+ Prabakaran Kumaresshan
673
+ Prabhjyotsing Surjit Singh Sodhi
674
+ Prabhu Marappan
675
+ Pradyun Gedam
676
+ Prashant Sharma
677
+ Pratik Mallya
678
+ pre-commit-ci[bot]
679
+ Preet Thakkar
680
+ Preston Holmes
681
+ Przemek Wrzos
682
+ Pulkit Goyal
683
+ q0w
684
+ Qiangning Hong
685
+ Qiming Xu
686
+ qraqras
687
+ Quentin Lee
688
+ Quentin Pradet
689
+ R. David Murray
690
+ Rafael Caricio
691
+ RAHUL KUMAR
692
+ rahulkotargasthi
693
+ Ralf Schmitt
694
+ Ran Benita
695
+ Randy DΓΆring
696
+ Razzi Abuissa
697
+ rdb
698
+ Reece Dunham
699
+ Remi Rampin
700
+ Rene Dudfield
701
+ Riccardo Magliocchetti
702
+ Riccardo Schirone
703
+ Richard Jones
704
+ Richard Si
705
+ Ricky Ng-Adam
706
+ Rishi
707
+ rmorotti
708
+ RobberPhex
709
+ Robert Collins
710
+ Robert McGibbon
711
+ Robert Pollak
712
+ Robert T. McGibbon
713
+ robin elisha robinson
714
+ Rodney, Tiara
715
+ Roey Berman
716
+ Rohan Jain
717
+ Roman Bogorodskiy
718
+ Roman Donchenko
719
+ Romuald Brunet
720
+ ronaudinho
721
+ Ronny Pfannschmidt
722
+ Rory McCann
723
+ Ross Brattain
724
+ Roy Wellington β…£
725
+ RoyS
726
+ Ruairidh MacLeod
727
+ Russell Keith-Magee
728
+ Ryan Shepherd
729
+ Ryan Wooden
730
+ ryneeverett
731
+ Ryuma Asai
732
+ S. Guliaev
733
+ Sachi King
734
+ Sai Sridhar Tarra
735
+ Salvatore Rinchiera
736
+ sandeepkiran-js
737
+ Sander Van Balen
738
+ Savio Jomton
739
+ schlamar
740
+ Scott Kitterman
741
+ Sean
742
+ seanj
743
+ Sebastian HΓΆffner
744
+ Sebastian Jordan
745
+ Sebastian Schaetz
746
+ Segev Finer
747
+ SeongSoo Cho
748
+ Sepehr Rasouli
749
+ sepehrrasooli
750
+ Sergey Vasilyev
751
+ Seth Michael Larson
752
+ Seth Woodworth
753
+ Shahar Epstein
754
+ Shantanu
755
+ shenxianpeng
756
+ shireenrao
757
+ Shivam Shrey
758
+ Shivansh-007
759
+ Shixian Sheng
760
+ Shlomi Fish
761
+ Shovan Maity
762
+ Shubham Nagure
763
+ Simeon Visser
764
+ Simon Cross
765
+ Simon Pichugin
766
+ sinoroc
767
+ sinscary
768
+ snook92
769
+ socketubs
770
+ Sorin Sbarnea
771
+ Srinivas Nyayapati
772
+ Srishti Hegde
773
+ Stavros Korokithakis
774
+ Stefan Scherfke
775
+ Stefano Rivera
776
+ Stephan Erb
777
+ Stephane Chazelas
778
+ Stephen Payne
779
+ Stephen Rosen
780
+ stepshal
781
+ Steve (Gadget) Barnes
782
+ Steve Barnes
783
+ Steve Dower
784
+ Steve Kowalik
785
+ Steven Myint
786
+ Steven Silvester
787
+ stonebig
788
+ studioj
789
+ StΓ©phane Bidoul
790
+ StΓ©phane Bidoul (ACSONE)
791
+ StΓ©phane Klein
792
+ Sumana Harihareswara
793
+ Surbhi Sharma
794
+ Sviatoslav Sydorenko
795
+ Sviatoslav Sydorenko (Бвятослав Π‘ΠΈΠ΄ΠΎΡ€Π΅Π½ΠΊΠΎ)
796
+ Swat009
797
+ Sylvain
798
+ S​age Abdullah
799
+ Takayuki SHIMIZUKAWA
800
+ Taneli Hukkinen
801
+ tbeswick
802
+ Terrance
803
+ Thiago
804
+ Thijs Triemstra
805
+ Thomas Fenzl
806
+ Thomas Grainger
807
+ Thomas Guettler
808
+ Thomas Johansson
809
+ Thomas Kluyver
810
+ Thomas Smith
811
+ Thomas VINCENT
812
+ Tim D. Smith
813
+ Tim Gates
814
+ Tim Harder
815
+ Tim Heap
816
+ tim smith
817
+ tinruufu
818
+ Tobias Hermann
819
+ Tom Forbes
820
+ Tom Freudenheim
821
+ Tom V
822
+ Tomas Hrnciar
823
+ Tomas Orsava
824
+ Tomer Chachamu
825
+ Tommi Enenkel | AnB
826
+ TomÑő Hrnčiar
827
+ Tony Beswick
828
+ Tony Narlock
829
+ Tony Zhaocheng Tan
830
+ TonyBeswick
831
+ toonarmycaptain
832
+ Toshio Kuratomi
833
+ toxinu
834
+ Travis Swicegood
835
+ Tushar Sadhwani
836
+ Tzu-ping Chung
837
+ Valentin Haenel
838
+ Victor Stinner
839
+ victorvpaulo
840
+ Vikram - Google
841
+ Viktor SzΓ©pe
842
+ Ville SkyttΓ€
843
+ Vinay Sajip
844
+ Vincent Fazio
845
+ Vincent Philippon
846
+ Vinicyus Macedo
847
+ Vipul Kumar
848
+ Vitaly Babiy
849
+ Vladimir Fokow
850
+ Vladimir Rutsky
851
+ W. Trevor King
852
+ Weida Hong
853
+ Wil Tan
854
+ Wilfred Hughes
855
+ William Edwards
856
+ William ML Leslie
857
+ William T Olson
858
+ William Woodruff
859
+ Wilson Mo
860
+ wim glenn
861
+ Winson Luk
862
+ Wolfgang Maier
863
+ Wu Zhenyu
864
+ XAMES3
865
+ Xavier Fernandez
866
+ Xianpeng Shen
867
+ xoviat
868
+ xtreak
869
+ YAMAMOTO Takashi
870
+ Yash
871
+ Yashraj
872
+ Yen Chi Hsuan
873
+ Yeray Diaz Diaz
874
+ Youngkwang Yang
875
+ Yoval P
876
+ Yu Jian
877
+ Yuan Jing Vincent Yan
878
+ Yuki Kobayashi
879
+ Yusuke Hayashi
880
+ Zachary Ware
881
+ zackzack38
882
+ Zearin
883
+ Zhiping Deng
884
+ ziebam
885
+ Zvezdan Petkovic
886
+ Łukasz Langa
887
+ Π ΠΎΠΌΠ°Π½ Π”ΠΎΠ½Ρ‡Π΅Π½ΠΊΠΎ
888
+ Π‘Π΅ΠΌΡ‘Π½ ΠœΠ°Ρ€ΡŒΡΡΠΈΠ½
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2012-2021 Eric Larson
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This package contains a modified version of ca-bundle.crt:
2
+
3
+ ca-bundle.crt -- Bundle of CA Root Certificates
4
+
5
+ This is a bundle of X.509 certificates of public Certificate Authorities
6
+ (CA). These were automatically extracted from Mozilla's root certificates
7
+ file (certdata.txt). This file can be found in the mozilla source tree:
8
+ https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt
9
+ It contains the certificates in PEM format and therefore
10
+ can be directly used with curl / libcurl / php_curl, or with
11
+ an Apache+mod_ssl webserver for SSL client authentication.
12
+ Just configure this file as the SSLCACertificateFile.#
13
+
14
+ ***** BEGIN LICENSE BLOCK *****
15
+ This Source Code Form is subject to the terms of the Mozilla Public License,
16
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
17
+ one at http://mozilla.org/MPL/2.0/.
18
+
19
+ ***** END LICENSE BLOCK *****
20
+ @(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ A. HISTORY OF THE SOFTWARE
2
+ ==========================
3
+
4
+ Python was created in the early 1990s by Guido van Rossum at Stichting
5
+ Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
6
+ as a successor of a language called ABC. Guido remains Python's
7
+ principal author, although it includes many contributions from others.
8
+
9
+ In 1995, Guido continued his work on Python at the Corporation for
10
+ National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
11
+ in Reston, Virginia where he released several versions of the
12
+ software.
13
+
14
+ In May 2000, Guido and the Python core development team moved to
15
+ BeOpen.com to form the BeOpen PythonLabs team. In October of the same
16
+ year, the PythonLabs team moved to Digital Creations (now Zope
17
+ Corporation, see http://www.zope.com). In 2001, the Python Software
18
+ Foundation (PSF, see http://www.python.org/psf/) was formed, a
19
+ non-profit organization created specifically to own Python-related
20
+ Intellectual Property. Zope Corporation is a sponsoring member of
21
+ the PSF.
22
+
23
+ All Python releases are Open Source (see http://www.opensource.org for
24
+ the Open Source Definition). Historically, most, but not all, Python
25
+ releases have also been GPL-compatible; the table below summarizes
26
+ the various releases.
27
+
28
+ Release Derived Year Owner GPL-
29
+ from compatible? (1)
30
+
31
+ 0.9.0 thru 1.2 1991-1995 CWI yes
32
+ 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
33
+ 1.6 1.5.2 2000 CNRI no
34
+ 2.0 1.6 2000 BeOpen.com no
35
+ 1.6.1 1.6 2001 CNRI yes (2)
36
+ 2.1 2.0+1.6.1 2001 PSF no
37
+ 2.0.1 2.0+1.6.1 2001 PSF yes
38
+ 2.1.1 2.1+2.0.1 2001 PSF yes
39
+ 2.2 2.1.1 2001 PSF yes
40
+ 2.1.2 2.1.1 2002 PSF yes
41
+ 2.1.3 2.1.2 2002 PSF yes
42
+ 2.2.1 2.2 2002 PSF yes
43
+ 2.2.2 2.2.1 2002 PSF yes
44
+ 2.2.3 2.2.2 2003 PSF yes
45
+ 2.3 2.2.2 2002-2003 PSF yes
46
+ 2.3.1 2.3 2002-2003 PSF yes
47
+ 2.3.2 2.3.1 2002-2003 PSF yes
48
+ 2.3.3 2.3.2 2002-2003 PSF yes
49
+ 2.3.4 2.3.3 2004 PSF yes
50
+ 2.3.5 2.3.4 2005 PSF yes
51
+ 2.4 2.3 2004 PSF yes
52
+ 2.4.1 2.4 2005 PSF yes
53
+ 2.4.2 2.4.1 2005 PSF yes
54
+ 2.4.3 2.4.2 2006 PSF yes
55
+ 2.4.4 2.4.3 2006 PSF yes
56
+ 2.5 2.4 2006 PSF yes
57
+ 2.5.1 2.5 2007 PSF yes
58
+ 2.5.2 2.5.1 2008 PSF yes
59
+ 2.5.3 2.5.2 2008 PSF yes
60
+ 2.6 2.5 2008 PSF yes
61
+ 2.6.1 2.6 2008 PSF yes
62
+ 2.6.2 2.6.1 2009 PSF yes
63
+ 2.6.3 2.6.2 2009 PSF yes
64
+ 2.6.4 2.6.3 2009 PSF yes
65
+ 2.6.5 2.6.4 2010 PSF yes
66
+ 3.0 2.6 2008 PSF yes
67
+ 3.0.1 3.0 2009 PSF yes
68
+ 3.1 3.0.1 2009 PSF yes
69
+ 3.1.1 3.1 2009 PSF yes
70
+ 3.1.2 3.1 2010 PSF yes
71
+ 3.2 3.1 2010 PSF yes
72
+
73
+ Footnotes:
74
+
75
+ (1) GPL-compatible doesn't mean that we're distributing Python under
76
+ the GPL. All Python licenses, unlike the GPL, let you distribute
77
+ a modified version without making your changes open source. The
78
+ GPL-compatible licenses make it possible to combine Python with
79
+ other software that is released under the GPL; the others don't.
80
+
81
+ (2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
82
+ because its license has a choice of law clause. According to
83
+ CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
84
+ is "not incompatible" with the GPL.
85
+
86
+ Thanks to the many outside volunteers who have worked under Guido's
87
+ direction to make these releases possible.
88
+
89
+
90
+ B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
91
+ ===============================================================
92
+
93
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
94
+ --------------------------------------------
95
+
96
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation
97
+ ("PSF"), and the Individual or Organization ("Licensee") accessing and
98
+ otherwise using this software ("Python") in source or binary form and
99
+ its associated documentation.
100
+
101
+ 2. Subject to the terms and conditions of this License Agreement, PSF hereby
102
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
103
+ analyze, test, perform and/or display publicly, prepare derivative works,
104
+ distribute, and otherwise use Python alone or in any derivative version,
105
+ provided, however, that PSF's License Agreement and PSF's notice of copyright,
106
+ i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
107
+ Python Software Foundation; All Rights Reserved" are retained in Python alone or
108
+ in any derivative version prepared by Licensee.
109
+
110
+ 3. In the event Licensee prepares a derivative work that is based on
111
+ or incorporates Python or any part thereof, and wants to make
112
+ the derivative work available to others as provided herein, then
113
+ Licensee hereby agrees to include in any such work a brief summary of
114
+ the changes made to Python.
115
+
116
+ 4. PSF is making Python available to Licensee on an "AS IS"
117
+ basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
118
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
119
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
120
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
121
+ INFRINGE ANY THIRD PARTY RIGHTS.
122
+
123
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
124
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
125
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
126
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
127
+
128
+ 6. This License Agreement will automatically terminate upon a material
129
+ breach of its terms and conditions.
130
+
131
+ 7. Nothing in this License Agreement shall be deemed to create any
132
+ relationship of agency, partnership, or joint venture between PSF and
133
+ Licensee. This License Agreement does not grant permission to use PSF
134
+ trademarks or trade name in a trademark sense to endorse or promote
135
+ products or services of Licensee, or any third party.
136
+
137
+ 8. By copying, installing or otherwise using Python, Licensee
138
+ agrees to be bound by the terms and conditions of this License
139
+ Agreement.
140
+
141
+
142
+ BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
143
+ -------------------------------------------
144
+
145
+ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
146
+
147
+ 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
148
+ office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
149
+ Individual or Organization ("Licensee") accessing and otherwise using
150
+ this software in source or binary form and its associated
151
+ documentation ("the Software").
152
+
153
+ 2. Subject to the terms and conditions of this BeOpen Python License
154
+ Agreement, BeOpen hereby grants Licensee a non-exclusive,
155
+ royalty-free, world-wide license to reproduce, analyze, test, perform
156
+ and/or display publicly, prepare derivative works, distribute, and
157
+ otherwise use the Software alone or in any derivative version,
158
+ provided, however, that the BeOpen Python License is retained in the
159
+ Software, alone or in any derivative version prepared by Licensee.
160
+
161
+ 3. BeOpen is making the Software available to Licensee on an "AS IS"
162
+ basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
163
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
164
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
165
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
166
+ INFRINGE ANY THIRD PARTY RIGHTS.
167
+
168
+ 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
169
+ SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
170
+ AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
171
+ DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
172
+
173
+ 5. This License Agreement will automatically terminate upon a material
174
+ breach of its terms and conditions.
175
+
176
+ 6. This License Agreement shall be governed by and interpreted in all
177
+ respects by the law of the State of California, excluding conflict of
178
+ law provisions. Nothing in this License Agreement shall be deemed to
179
+ create any relationship of agency, partnership, or joint venture
180
+ between BeOpen and Licensee. This License Agreement does not grant
181
+ permission to use BeOpen trademarks or trade names in a trademark
182
+ sense to endorse or promote products or services of Licensee, or any
183
+ third party. As an exception, the "BeOpen Python" logos available at
184
+ http://www.pythonlabs.com/logos.html may be used according to the
185
+ permissions granted on that web page.
186
+
187
+ 7. By copying, installing or otherwise using the software, Licensee
188
+ agrees to be bound by the terms and conditions of this License
189
+ Agreement.
190
+
191
+
192
+ CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
193
+ ---------------------------------------
194
+
195
+ 1. This LICENSE AGREEMENT is between the Corporation for National
196
+ Research Initiatives, having an office at 1895 Preston White Drive,
197
+ Reston, VA 20191 ("CNRI"), and the Individual or Organization
198
+ ("Licensee") accessing and otherwise using Python 1.6.1 software in
199
+ source or binary form and its associated documentation.
200
+
201
+ 2. Subject to the terms and conditions of this License Agreement, CNRI
202
+ hereby grants Licensee a nonexclusive, royalty-free, world-wide
203
+ license to reproduce, analyze, test, perform and/or display publicly,
204
+ prepare derivative works, distribute, and otherwise use Python 1.6.1
205
+ alone or in any derivative version, provided, however, that CNRI's
206
+ License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
207
+ 1995-2001 Corporation for National Research Initiatives; All Rights
208
+ Reserved" are retained in Python 1.6.1 alone or in any derivative
209
+ version prepared by Licensee. Alternately, in lieu of CNRI's License
210
+ Agreement, Licensee may substitute the following text (omitting the
211
+ quotes): "Python 1.6.1 is made available subject to the terms and
212
+ conditions in CNRI's License Agreement. This Agreement together with
213
+ Python 1.6.1 may be located on the Internet using the following
214
+ unique, persistent identifier (known as a handle): 1895.22/1013. This
215
+ Agreement may also be obtained from a proxy server on the Internet
216
+ using the following URL: http://hdl.handle.net/1895.22/1013".
217
+
218
+ 3. In the event Licensee prepares a derivative work that is based on
219
+ or incorporates Python 1.6.1 or any part thereof, and wants to make
220
+ the derivative work available to others as provided herein, then
221
+ Licensee hereby agrees to include in any such work a brief summary of
222
+ the changes made to Python 1.6.1.
223
+
224
+ 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
225
+ basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
226
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
227
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
228
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
229
+ INFRINGE ANY THIRD PARTY RIGHTS.
230
+
231
+ 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
232
+ 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
233
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
234
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
235
+
236
+ 6. This License Agreement will automatically terminate upon a material
237
+ breach of its terms and conditions.
238
+
239
+ 7. This License Agreement shall be governed by the federal
240
+ intellectual property law of the United States, including without
241
+ limitation the federal copyright law, and, to the extent such
242
+ U.S. federal law does not apply, by the law of the Commonwealth of
243
+ Virginia, excluding Virginia's conflict of law provisions.
244
+ Notwithstanding the foregoing, with regard to derivative works based
245
+ on Python 1.6.1 that incorporate non-separable material that was
246
+ previously distributed under the GNU General Public License (GPL), the
247
+ law of the Commonwealth of Virginia shall govern this License
248
+ Agreement only as to issues arising under or with respect to
249
+ Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
250
+ License Agreement shall be deemed to create any relationship of
251
+ agency, partnership, or joint venture between CNRI and Licensee. This
252
+ License Agreement does not grant permission to use CNRI trademarks or
253
+ trade name in a trademark sense to endorse or promote products or
254
+ services of Licensee, or any third party.
255
+
256
+ 8. By clicking on the "ACCEPT" button where indicated, or by copying,
257
+ installing or otherwise using Python 1.6.1, Licensee agrees to be
258
+ bound by the terms and conditions of this License Agreement.
259
+
260
+ ACCEPT
261
+
262
+
263
+ CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
264
+ --------------------------------------------------
265
+
266
+ Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
267
+ The Netherlands. All rights reserved.
268
+
269
+ Permission to use, copy, modify, and distribute this software and its
270
+ documentation for any purpose and without fee is hereby granted,
271
+ provided that the above copyright notice appear in all copies and that
272
+ both that copyright notice and this permission notice appear in
273
+ supporting documentation, and that the name of Stichting Mathematisch
274
+ Centrum or CWI not be used in advertising or publicity pertaining to
275
+ distribution of the software without specific, written prior
276
+ permission.
277
+
278
+ STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
279
+ THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
280
+ FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
281
+ FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
282
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
283
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
284
+ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2013-2026, Kim Davies and contributors.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are
8
+ met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ 3. Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from
19
+ this software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (C) 2008-2011 INADA Naoki <songofacandy@gmail.com>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ This software is made available under the terms of *either* of the licenses
2
+ found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made
3
+ under the terms of *both* these licenses.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) Donald Stufft and individual contributors.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Permission is hereby granted, free of charge, to any person obtaining a copy
2
+ of this software and associated documentation files (the "Software"), to
3
+ deal in the Software without restriction, including without limitation the
4
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
5
+ sell copies of the Software, and to permit persons to whom the Software is
6
+ furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in
9
+ all copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
16
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
17
+ IN THE SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2010-202x The platformdirs developers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2006-2022 by the respective authors (see AUTHORS file).
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Thomas Kluyver
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2018, Tzu-ping Chung <uranusjr@gmail.com>
2
+
3
+ Permission to use, copy, modify, and distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2020 Will McGugan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Taneli Hukkinen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Taneli Hukkinen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Seth Michael Larson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
.venv/lib/python3.12/site-packages/pip-26.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2008-2020 Andrey Petrov and contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.12/site-packages/pip/_vendor/rich/prompt.py ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Generic, List, Optional, TextIO, TypeVar, Union, overload
2
+
3
+ from . import get_console
4
+ from .console import Console
5
+ from .text import Text, TextType
6
+
7
+ PromptType = TypeVar("PromptType")
8
+ DefaultType = TypeVar("DefaultType")
9
+
10
+
11
+ class PromptError(Exception):
12
+ """Exception base class for prompt related errors."""
13
+
14
+
15
+ class InvalidResponse(PromptError):
16
+ """Exception to indicate a response was invalid. Raise this within process_response() to indicate an error
17
+ and provide an error message.
18
+
19
+ Args:
20
+ message (Union[str, Text]): Error message.
21
+ """
22
+
23
+ def __init__(self, message: TextType) -> None:
24
+ self.message = message
25
+
26
+ def __rich__(self) -> TextType:
27
+ return self.message
28
+
29
+
30
+ class PromptBase(Generic[PromptType]):
31
+ """Ask the user for input until a valid response is received. This is the base class, see one of
32
+ the concrete classes for examples.
33
+
34
+ Args:
35
+ prompt (TextType, optional): Prompt text. Defaults to "".
36
+ console (Console, optional): A Console instance or None to use global console. Defaults to None.
37
+ password (bool, optional): Enable password input. Defaults to False.
38
+ choices (List[str], optional): A list of valid choices. Defaults to None.
39
+ case_sensitive (bool, optional): Matching of choices should be case-sensitive. Defaults to True.
40
+ show_default (bool, optional): Show default in prompt. Defaults to True.
41
+ show_choices (bool, optional): Show choices in prompt. Defaults to True.
42
+ """
43
+
44
+ response_type: type = str
45
+
46
+ validate_error_message = "[prompt.invalid]Please enter a valid value"
47
+ illegal_choice_message = (
48
+ "[prompt.invalid.choice]Please select one of the available options"
49
+ )
50
+ prompt_suffix = ": "
51
+
52
+ choices: Optional[List[str]] = None
53
+
54
+ def __init__(
55
+ self,
56
+ prompt: TextType = "",
57
+ *,
58
+ console: Optional[Console] = None,
59
+ password: bool = False,
60
+ choices: Optional[List[str]] = None,
61
+ case_sensitive: bool = True,
62
+ show_default: bool = True,
63
+ show_choices: bool = True,
64
+ ) -> None:
65
+ self.console = console or get_console()
66
+ self.prompt = (
67
+ Text.from_markup(prompt, style="prompt")
68
+ if isinstance(prompt, str)
69
+ else prompt
70
+ )
71
+ self.password = password
72
+ if choices is not None:
73
+ self.choices = choices
74
+ self.case_sensitive = case_sensitive
75
+ self.show_default = show_default
76
+ self.show_choices = show_choices
77
+
78
+ @classmethod
79
+ @overload
80
+ def ask(
81
+ cls,
82
+ prompt: TextType = "",
83
+ *,
84
+ console: Optional[Console] = None,
85
+ password: bool = False,
86
+ choices: Optional[List[str]] = None,
87
+ case_sensitive: bool = True,
88
+ show_default: bool = True,
89
+ show_choices: bool = True,
90
+ default: DefaultType,
91
+ stream: Optional[TextIO] = None,
92
+ ) -> Union[DefaultType, PromptType]:
93
+ ...
94
+
95
+ @classmethod
96
+ @overload
97
+ def ask(
98
+ cls,
99
+ prompt: TextType = "",
100
+ *,
101
+ console: Optional[Console] = None,
102
+ password: bool = False,
103
+ choices: Optional[List[str]] = None,
104
+ case_sensitive: bool = True,
105
+ show_default: bool = True,
106
+ show_choices: bool = True,
107
+ stream: Optional[TextIO] = None,
108
+ ) -> PromptType:
109
+ ...
110
+
111
+ @classmethod
112
+ def ask(
113
+ cls,
114
+ prompt: TextType = "",
115
+ *,
116
+ console: Optional[Console] = None,
117
+ password: bool = False,
118
+ choices: Optional[List[str]] = None,
119
+ case_sensitive: bool = True,
120
+ show_default: bool = True,
121
+ show_choices: bool = True,
122
+ default: Any = ...,
123
+ stream: Optional[TextIO] = None,
124
+ ) -> Any:
125
+ """Shortcut to construct and run a prompt loop and return the result.
126
+
127
+ Example:
128
+ >>> filename = Prompt.ask("Enter a filename")
129
+
130
+ Args:
131
+ prompt (TextType, optional): Prompt text. Defaults to "".
132
+ console (Console, optional): A Console instance or None to use global console. Defaults to None.
133
+ password (bool, optional): Enable password input. Defaults to False.
134
+ choices (List[str], optional): A list of valid choices. Defaults to None.
135
+ case_sensitive (bool, optional): Matching of choices should be case-sensitive. Defaults to True.
136
+ show_default (bool, optional): Show default in prompt. Defaults to True.
137
+ show_choices (bool, optional): Show choices in prompt. Defaults to True.
138
+ stream (TextIO, optional): Optional text file open for reading to get input. Defaults to None.
139
+ """
140
+ _prompt = cls(
141
+ prompt,
142
+ console=console,
143
+ password=password,
144
+ choices=choices,
145
+ case_sensitive=case_sensitive,
146
+ show_default=show_default,
147
+ show_choices=show_choices,
148
+ )
149
+ return _prompt(default=default, stream=stream)
150
+
151
+ def render_default(self, default: DefaultType) -> Text:
152
+ """Turn the supplied default in to a Text instance.
153
+
154
+ Args:
155
+ default (DefaultType): Default value.
156
+
157
+ Returns:
158
+ Text: Text containing rendering of default value.
159
+ """
160
+ return Text(f"({default})", "prompt.default")
161
+
162
+ def make_prompt(self, default: DefaultType) -> Text:
163
+ """Make prompt text.
164
+
165
+ Args:
166
+ default (DefaultType): Default value.
167
+
168
+ Returns:
169
+ Text: Text to display in prompt.
170
+ """
171
+ prompt = self.prompt.copy()
172
+ prompt.end = ""
173
+
174
+ if self.show_choices and self.choices:
175
+ _choices = "/".join(self.choices)
176
+ choices = f"[{_choices}]"
177
+ prompt.append(" ")
178
+ prompt.append(choices, "prompt.choices")
179
+
180
+ if (
181
+ default != ...
182
+ and self.show_default
183
+ and isinstance(default, (str, self.response_type))
184
+ ):
185
+ prompt.append(" ")
186
+ _default = self.render_default(default)
187
+ prompt.append(_default)
188
+
189
+ prompt.append(self.prompt_suffix)
190
+
191
+ return prompt
192
+
193
+ @classmethod
194
+ def get_input(
195
+ cls,
196
+ console: Console,
197
+ prompt: TextType,
198
+ password: bool,
199
+ stream: Optional[TextIO] = None,
200
+ ) -> str:
201
+ """Get input from user.
202
+
203
+ Args:
204
+ console (Console): Console instance.
205
+ prompt (TextType): Prompt text.
206
+ password (bool): Enable password entry.
207
+
208
+ Returns:
209
+ str: String from user.
210
+ """
211
+ return console.input(prompt, password=password, stream=stream)
212
+
213
+ def check_choice(self, value: str) -> bool:
214
+ """Check value is in the list of valid choices.
215
+
216
+ Args:
217
+ value (str): Value entered by user.
218
+
219
+ Returns:
220
+ bool: True if choice was valid, otherwise False.
221
+ """
222
+ assert self.choices is not None
223
+ if self.case_sensitive:
224
+ return value.strip() in self.choices
225
+ return value.strip().lower() in [choice.lower() for choice in self.choices]
226
+
227
+ def process_response(self, value: str) -> PromptType:
228
+ """Process response from user, convert to prompt type.
229
+
230
+ Args:
231
+ value (str): String typed by user.
232
+
233
+ Raises:
234
+ InvalidResponse: If ``value`` is invalid.
235
+
236
+ Returns:
237
+ PromptType: The value to be returned from ask method.
238
+ """
239
+ value = value.strip()
240
+ try:
241
+ return_value: PromptType = self.response_type(value)
242
+ except ValueError:
243
+ raise InvalidResponse(self.validate_error_message)
244
+
245
+ if self.choices is not None:
246
+ if not self.check_choice(value):
247
+ raise InvalidResponse(self.illegal_choice_message)
248
+
249
+ if not self.case_sensitive:
250
+ # return the original choice, not the lower case version
251
+ return_value = self.response_type(
252
+ self.choices[
253
+ [choice.lower() for choice in self.choices].index(value.lower())
254
+ ]
255
+ )
256
+ return return_value
257
+
258
+ def on_validate_error(self, value: str, error: InvalidResponse) -> None:
259
+ """Called to handle validation error.
260
+
261
+ Args:
262
+ value (str): String entered by user.
263
+ error (InvalidResponse): Exception instance the initiated the error.
264
+ """
265
+ self.console.print(error)
266
+
267
+ def pre_prompt(self) -> None:
268
+ """Hook to display something before the prompt."""
269
+
270
+ @overload
271
+ def __call__(self, *, stream: Optional[TextIO] = None) -> PromptType:
272
+ ...
273
+
274
+ @overload
275
+ def __call__(
276
+ self, *, default: DefaultType, stream: Optional[TextIO] = None
277
+ ) -> Union[PromptType, DefaultType]:
278
+ ...
279
+
280
+ def __call__(self, *, default: Any = ..., stream: Optional[TextIO] = None) -> Any:
281
+ """Run the prompt loop.
282
+
283
+ Args:
284
+ default (Any, optional): Optional default value.
285
+
286
+ Returns:
287
+ PromptType: Processed value.
288
+ """
289
+ while True:
290
+ self.pre_prompt()
291
+ prompt = self.make_prompt(default)
292
+ value = self.get_input(self.console, prompt, self.password, stream=stream)
293
+ if value == "" and default != ...:
294
+ return default
295
+ try:
296
+ return_value = self.process_response(value)
297
+ except InvalidResponse as error:
298
+ self.on_validate_error(value, error)
299
+ continue
300
+ else:
301
+ return return_value
302
+
303
+
304
+ class Prompt(PromptBase[str]):
305
+ """A prompt that returns a str.
306
+
307
+ Example:
308
+ >>> name = Prompt.ask("Enter your name")
309
+
310
+
311
+ """
312
+
313
+ response_type = str
314
+
315
+
316
+ class IntPrompt(PromptBase[int]):
317
+ """A prompt that returns an integer.
318
+
319
+ Example:
320
+ >>> burrito_count = IntPrompt.ask("How many burritos do you want to order")
321
+
322
+ """
323
+
324
+ response_type = int
325
+ validate_error_message = "[prompt.invalid]Please enter a valid integer number"
326
+
327
+
328
+ class FloatPrompt(PromptBase[float]):
329
+ """A prompt that returns a float.
330
+
331
+ Example:
332
+ >>> temperature = FloatPrompt.ask("Enter desired temperature")
333
+
334
+ """
335
+
336
+ response_type = float
337
+ validate_error_message = "[prompt.invalid]Please enter a number"
338
+
339
+
340
+ class Confirm(PromptBase[bool]):
341
+ """A yes / no confirmation prompt.
342
+
343
+ Example:
344
+ >>> if Confirm.ask("Continue"):
345
+ run_job()
346
+
347
+ """
348
+
349
+ response_type = bool
350
+ validate_error_message = "[prompt.invalid]Please enter Y or N"
351
+ choices: List[str] = ["y", "n"]
352
+
353
+ def render_default(self, default: DefaultType) -> Text:
354
+ """Render the default as (y) or (n) rather than True/False."""
355
+ yes, no = self.choices
356
+ return Text(f"({yes})" if default else f"({no})", style="prompt.default")
357
+
358
+ def process_response(self, value: str) -> bool:
359
+ """Convert choices to a bool."""
360
+ value = value.strip().lower()
361
+ if value not in self.choices:
362
+ raise InvalidResponse(self.validate_error_message)
363
+ return value == self.choices[0]
364
+
365
+
366
+ if __name__ == "__main__": # pragma: no cover
367
+ from pip._vendor.rich import print
368
+
369
+ if Confirm.ask("Run [i]prompt[/i] tests?", default=True):
370
+ while True:
371
+ result = IntPrompt.ask(
372
+ ":rocket: Enter a number between [b]1[/b] and [b]10[/b]", default=5
373
+ )
374
+ if result >= 1 and result <= 10:
375
+ break
376
+ print(":pile_of_poo: [prompt.invalid]Number must be between 1 and 10")
377
+ print(f"number={result}")
378
+
379
+ while True:
380
+ password = Prompt.ask(
381
+ "Please enter a password [cyan](must be at least 5 characters)",
382
+ password=True,
383
+ )
384
+ if len(password) >= 5:
385
+ break
386
+ print("[prompt.invalid]password too short")
387
+ print(f"password={password!r}")
388
+
389
+ fruit = Prompt.ask("Enter a fruit", choices=["apple", "orange", "pear"])
390
+ print(f"fruit={fruit!r}")
391
+
392
+ doggie = Prompt.ask(
393
+ "What's the best Dog? (Case INSENSITIVE)",
394
+ choices=["Border Terrier", "Collie", "Labradoodle"],
395
+ case_sensitive=False,
396
+ )
397
+ print(f"doggie={doggie!r}")
398
+
399
+ else:
400
+ print("[b]OK :loudly_crying_face:")
.venv/lib/python3.12/site-packages/pip/_vendor/rich/protocol.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, cast, Set, TYPE_CHECKING
2
+ from inspect import isclass
3
+
4
+ if TYPE_CHECKING:
5
+ from pip._vendor.rich.console import RenderableType
6
+
7
+ _GIBBERISH = """aihwerij235234ljsdnp34ksodfipwoe234234jlskjdf"""
8
+
9
+
10
+ def is_renderable(check_object: Any) -> bool:
11
+ """Check if an object may be rendered by Rich."""
12
+ return (
13
+ isinstance(check_object, str)
14
+ or hasattr(check_object, "__rich__")
15
+ or hasattr(check_object, "__rich_console__")
16
+ )
17
+
18
+
19
+ def rich_cast(renderable: object) -> "RenderableType":
20
+ """Cast an object to a renderable by calling __rich__ if present.
21
+
22
+ Args:
23
+ renderable (object): A potentially renderable object
24
+
25
+ Returns:
26
+ object: The result of recursively calling __rich__.
27
+ """
28
+ from pip._vendor.rich.console import RenderableType
29
+
30
+ rich_visited_set: Set[type] = set() # Prevent potential infinite loop
31
+ while hasattr(renderable, "__rich__") and not isclass(renderable):
32
+ # Detect object which claim to have all the attributes
33
+ if hasattr(renderable, _GIBBERISH):
34
+ return repr(renderable)
35
+ cast_method = getattr(renderable, "__rich__")
36
+ renderable = cast_method()
37
+ renderable_type = type(renderable)
38
+ if renderable_type in rich_visited_set:
39
+ break
40
+ rich_visited_set.add(renderable_type)
41
+
42
+ return cast(RenderableType, renderable)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/py.typed ADDED
File without changes
.venv/lib/python3.12/site-packages/pip/_vendor/rich/region.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import NamedTuple
2
+
3
+
4
+ class Region(NamedTuple):
5
+ """Defines a rectangular region of the screen."""
6
+
7
+ x: int
8
+ y: int
9
+ width: int
10
+ height: int
.venv/lib/python3.12/site-packages/pip/_vendor/rich/repr.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ from functools import partial
3
+ from typing import (
4
+ Any,
5
+ Callable,
6
+ Iterable,
7
+ List,
8
+ Optional,
9
+ Tuple,
10
+ Type,
11
+ TypeVar,
12
+ Union,
13
+ overload,
14
+ )
15
+
16
+ T = TypeVar("T")
17
+
18
+
19
+ Result = Iterable[Union[Any, Tuple[Any], Tuple[str, Any], Tuple[str, Any, Any]]]
20
+ RichReprResult = Result
21
+
22
+
23
+ class ReprError(Exception):
24
+ """An error occurred when attempting to build a repr."""
25
+
26
+
27
+ @overload
28
+ def auto(cls: Optional[Type[T]]) -> Type[T]:
29
+ ...
30
+
31
+
32
+ @overload
33
+ def auto(*, angular: bool = False) -> Callable[[Type[T]], Type[T]]:
34
+ ...
35
+
36
+
37
+ def auto(
38
+ cls: Optional[Type[T]] = None, *, angular: Optional[bool] = None
39
+ ) -> Union[Type[T], Callable[[Type[T]], Type[T]]]:
40
+ """Class decorator to create __repr__ from __rich_repr__"""
41
+
42
+ def do_replace(cls: Type[T], angular: Optional[bool] = None) -> Type[T]:
43
+ def auto_repr(self: T) -> str:
44
+ """Create repr string from __rich_repr__"""
45
+ repr_str: List[str] = []
46
+ append = repr_str.append
47
+
48
+ angular: bool = getattr(self.__rich_repr__, "angular", False) # type: ignore[attr-defined]
49
+ for arg in self.__rich_repr__(): # type: ignore[attr-defined]
50
+ if isinstance(arg, tuple):
51
+ if len(arg) == 1:
52
+ append(repr(arg[0]))
53
+ else:
54
+ key, value, *default = arg
55
+ if key is None:
56
+ append(repr(value))
57
+ else:
58
+ if default and default[0] == value:
59
+ continue
60
+ append(f"{key}={value!r}")
61
+ else:
62
+ append(repr(arg))
63
+ if angular:
64
+ return f"<{self.__class__.__name__} {' '.join(repr_str)}>"
65
+ else:
66
+ return f"{self.__class__.__name__}({', '.join(repr_str)})"
67
+
68
+ def auto_rich_repr(self: Type[T]) -> Result:
69
+ """Auto generate __rich_rep__ from signature of __init__"""
70
+ try:
71
+ signature = inspect.signature(self.__init__)
72
+ for name, param in signature.parameters.items():
73
+ if param.kind == param.POSITIONAL_ONLY:
74
+ yield getattr(self, name)
75
+ elif param.kind in (
76
+ param.POSITIONAL_OR_KEYWORD,
77
+ param.KEYWORD_ONLY,
78
+ ):
79
+ if param.default is param.empty:
80
+ yield getattr(self, param.name)
81
+ else:
82
+ yield param.name, getattr(self, param.name), param.default
83
+ except Exception as error:
84
+ raise ReprError(
85
+ f"Failed to auto generate __rich_repr__; {error}"
86
+ ) from None
87
+
88
+ if not hasattr(cls, "__rich_repr__"):
89
+ auto_rich_repr.__doc__ = "Build a rich repr"
90
+ cls.__rich_repr__ = auto_rich_repr # type: ignore[attr-defined]
91
+
92
+ auto_repr.__doc__ = "Return repr(self)"
93
+ cls.__repr__ = auto_repr # type: ignore[assignment]
94
+ if angular is not None:
95
+ cls.__rich_repr__.angular = angular # type: ignore[attr-defined]
96
+ return cls
97
+
98
+ if cls is None:
99
+ return partial(do_replace, angular=angular)
100
+ else:
101
+ return do_replace(cls, angular=angular)
102
+
103
+
104
+ @overload
105
+ def rich_repr(cls: Optional[Type[T]]) -> Type[T]:
106
+ ...
107
+
108
+
109
+ @overload
110
+ def rich_repr(*, angular: bool = False) -> Callable[[Type[T]], Type[T]]:
111
+ ...
112
+
113
+
114
+ def rich_repr(
115
+ cls: Optional[Type[T]] = None, *, angular: bool = False
116
+ ) -> Union[Type[T], Callable[[Type[T]], Type[T]]]:
117
+ if cls is None:
118
+ return auto(angular=angular)
119
+ else:
120
+ return auto(cls)
121
+
122
+
123
+ if __name__ == "__main__":
124
+
125
+ @auto
126
+ class Foo:
127
+ def __rich_repr__(self) -> Result:
128
+ yield "foo"
129
+ yield "bar", {"shopping": ["eggs", "ham", "pineapple"]}
130
+ yield "buy", "hand sanitizer"
131
+
132
+ foo = Foo()
133
+ from pip._vendor.rich.console import Console
134
+
135
+ console = Console()
136
+
137
+ console.rule("Standard repr")
138
+ console.print(foo)
139
+
140
+ console.print(foo, width=60)
141
+ console.print(foo, width=30)
142
+
143
+ console.rule("Angular repr")
144
+ Foo.__rich_repr__.angular = True # type: ignore[attr-defined]
145
+
146
+ console.print(foo)
147
+
148
+ console.print(foo, width=60)
149
+ console.print(foo, width=30)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/rule.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Union
2
+
3
+ from .align import AlignMethod
4
+ from .cells import cell_len, set_cell_size
5
+ from .console import Console, ConsoleOptions, RenderResult
6
+ from .jupyter import JupyterMixin
7
+ from .measure import Measurement
8
+ from .style import Style
9
+ from .text import Text
10
+
11
+
12
+ class Rule(JupyterMixin):
13
+ """A console renderable to draw a horizontal rule (line).
14
+
15
+ Args:
16
+ title (Union[str, Text], optional): Text to render in the rule. Defaults to "".
17
+ characters (str, optional): Character(s) used to draw the line. Defaults to "─".
18
+ style (StyleType, optional): Style of Rule. Defaults to "rule.line".
19
+ end (str, optional): Character at end of Rule. defaults to "\\\\n"
20
+ align (str, optional): How to align the title, one of "left", "center", or "right". Defaults to "center".
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ title: Union[str, Text] = "",
26
+ *,
27
+ characters: str = "─",
28
+ style: Union[str, Style] = "rule.line",
29
+ end: str = "\n",
30
+ align: AlignMethod = "center",
31
+ ) -> None:
32
+ if cell_len(characters) < 1:
33
+ raise ValueError(
34
+ "'characters' argument must have a cell width of at least 1"
35
+ )
36
+ if align not in ("left", "center", "right"):
37
+ raise ValueError(
38
+ f'invalid value for align, expected "left", "center", "right" (not {align!r})'
39
+ )
40
+ self.title = title
41
+ self.characters = characters
42
+ self.style = style
43
+ self.end = end
44
+ self.align = align
45
+
46
+ def __repr__(self) -> str:
47
+ return f"Rule({self.title!r}, {self.characters!r})"
48
+
49
+ def __rich_console__(
50
+ self, console: Console, options: ConsoleOptions
51
+ ) -> RenderResult:
52
+ width = options.max_width
53
+
54
+ characters = (
55
+ "-"
56
+ if (options.ascii_only and not self.characters.isascii())
57
+ else self.characters
58
+ )
59
+
60
+ chars_len = cell_len(characters)
61
+ if not self.title:
62
+ yield self._rule_line(chars_len, width)
63
+ return
64
+
65
+ if isinstance(self.title, Text):
66
+ title_text = self.title
67
+ else:
68
+ title_text = console.render_str(self.title, style="rule.text")
69
+
70
+ title_text.plain = title_text.plain.replace("\n", " ")
71
+ title_text.expand_tabs()
72
+
73
+ required_space = 4 if self.align == "center" else 2
74
+ truncate_width = max(0, width - required_space)
75
+ if not truncate_width:
76
+ yield self._rule_line(chars_len, width)
77
+ return
78
+
79
+ rule_text = Text(end=self.end)
80
+ if self.align == "center":
81
+ title_text.truncate(truncate_width, overflow="ellipsis")
82
+ side_width = (width - cell_len(title_text.plain)) // 2
83
+ left = Text(characters * (side_width // chars_len + 1))
84
+ left.truncate(side_width - 1)
85
+ right_length = width - cell_len(left.plain) - cell_len(title_text.plain)
86
+ right = Text(characters * (side_width // chars_len + 1))
87
+ right.truncate(right_length)
88
+ rule_text.append(left.plain + " ", self.style)
89
+ rule_text.append(title_text)
90
+ rule_text.append(" " + right.plain, self.style)
91
+ elif self.align == "left":
92
+ title_text.truncate(truncate_width, overflow="ellipsis")
93
+ rule_text.append(title_text)
94
+ rule_text.append(" ")
95
+ rule_text.append(characters * (width - rule_text.cell_len), self.style)
96
+ elif self.align == "right":
97
+ title_text.truncate(truncate_width, overflow="ellipsis")
98
+ rule_text.append(characters * (width - title_text.cell_len - 1), self.style)
99
+ rule_text.append(" ")
100
+ rule_text.append(title_text)
101
+
102
+ rule_text.plain = set_cell_size(rule_text.plain, width)
103
+ yield rule_text
104
+
105
+ def _rule_line(self, chars_len: int, width: int) -> Text:
106
+ rule_text = Text(self.characters * ((width // chars_len) + 1), self.style)
107
+ rule_text.truncate(width)
108
+ rule_text.plain = set_cell_size(rule_text.plain, width)
109
+ return rule_text
110
+
111
+ def __rich_measure__(
112
+ self, console: Console, options: ConsoleOptions
113
+ ) -> Measurement:
114
+ return Measurement(1, 1)
115
+
116
+
117
+ if __name__ == "__main__": # pragma: no cover
118
+ import sys
119
+
120
+ from pip._vendor.rich.console import Console
121
+
122
+ try:
123
+ text = sys.argv[1]
124
+ except IndexError:
125
+ text = "Hello, World"
126
+ console = Console()
127
+ console.print(Rule(title=text))
128
+
129
+ console = Console()
130
+ console.print(Rule("foo"), width=4)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/scope.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Mapping
2
+ from typing import TYPE_CHECKING, Any, Optional, Tuple
3
+
4
+ from .highlighter import ReprHighlighter
5
+ from .panel import Panel
6
+ from .pretty import Pretty
7
+ from .table import Table
8
+ from .text import Text, TextType
9
+
10
+ if TYPE_CHECKING:
11
+ from .console import ConsoleRenderable
12
+
13
+
14
+ def render_scope(
15
+ scope: "Mapping[str, Any]",
16
+ *,
17
+ title: Optional[TextType] = None,
18
+ sort_keys: bool = True,
19
+ indent_guides: bool = False,
20
+ max_length: Optional[int] = None,
21
+ max_string: Optional[int] = None,
22
+ ) -> "ConsoleRenderable":
23
+ """Render python variables in a given scope.
24
+
25
+ Args:
26
+ scope (Mapping): A mapping containing variable names and values.
27
+ title (str, optional): Optional title. Defaults to None.
28
+ sort_keys (bool, optional): Enable sorting of items. Defaults to True.
29
+ indent_guides (bool, optional): Enable indentation guides. Defaults to False.
30
+ max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation.
31
+ Defaults to None.
32
+ max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to None.
33
+
34
+ Returns:
35
+ ConsoleRenderable: A renderable object.
36
+ """
37
+ highlighter = ReprHighlighter()
38
+ items_table = Table.grid(padding=(0, 1), expand=False)
39
+ items_table.add_column(justify="right")
40
+
41
+ def sort_items(item: Tuple[str, Any]) -> Tuple[bool, str]:
42
+ """Sort special variables first, then alphabetically."""
43
+ key, _ = item
44
+ return (not key.startswith("__"), key.lower())
45
+
46
+ items = sorted(scope.items(), key=sort_items) if sort_keys else scope.items()
47
+ for key, value in items:
48
+ key_text = Text.assemble(
49
+ (key, "scope.key.special" if key.startswith("__") else "scope.key"),
50
+ (" =", "scope.equals"),
51
+ )
52
+ items_table.add_row(
53
+ key_text,
54
+ Pretty(
55
+ value,
56
+ highlighter=highlighter,
57
+ indent_guides=indent_guides,
58
+ max_length=max_length,
59
+ max_string=max_string,
60
+ ),
61
+ )
62
+ return Panel.fit(
63
+ items_table,
64
+ title=title,
65
+ border_style="scope.border",
66
+ padding=(0, 1),
67
+ )
68
+
69
+
70
+ if __name__ == "__main__": # pragma: no cover
71
+ from pip._vendor.rich import print
72
+
73
+ print()
74
+
75
+ def test(foo: float, bar: float) -> None:
76
+ list_of_things = [1, 2, 3, None, 4, True, False, "Hello World"]
77
+ dict_of_things = {
78
+ "version": "1.1",
79
+ "method": "confirmFruitPurchase",
80
+ "params": [["apple", "orange", "mangoes", "pomelo"], 1.123],
81
+ "id": "194521489",
82
+ }
83
+ print(render_scope(locals(), title="[i]locals", sort_keys=False))
84
+
85
+ test(20.3423, 3.1427)
86
+ print()
.venv/lib/python3.12/site-packages/pip/_vendor/rich/screen.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, TYPE_CHECKING
2
+
3
+ from .segment import Segment
4
+ from .style import StyleType
5
+ from ._loop import loop_last
6
+
7
+
8
+ if TYPE_CHECKING:
9
+ from .console import (
10
+ Console,
11
+ ConsoleOptions,
12
+ RenderResult,
13
+ RenderableType,
14
+ Group,
15
+ )
16
+
17
+
18
+ class Screen:
19
+ """A renderable that fills the terminal screen and crops excess.
20
+
21
+ Args:
22
+ renderable (RenderableType): Child renderable.
23
+ style (StyleType, optional): Optional background style. Defaults to None.
24
+ """
25
+
26
+ renderable: "RenderableType"
27
+
28
+ def __init__(
29
+ self,
30
+ *renderables: "RenderableType",
31
+ style: Optional[StyleType] = None,
32
+ application_mode: bool = False,
33
+ ) -> None:
34
+ from pip._vendor.rich.console import Group
35
+
36
+ self.renderable = Group(*renderables)
37
+ self.style = style
38
+ self.application_mode = application_mode
39
+
40
+ def __rich_console__(
41
+ self, console: "Console", options: "ConsoleOptions"
42
+ ) -> "RenderResult":
43
+ width, height = options.size
44
+ style = console.get_style(self.style) if self.style else None
45
+ render_options = options.update(width=width, height=height)
46
+ lines = console.render_lines(
47
+ self.renderable or "", render_options, style=style, pad=True
48
+ )
49
+ lines = Segment.set_shape(lines, width, height, style=style)
50
+ new_line = Segment("\n\r") if self.application_mode else Segment.line()
51
+ for last, line in loop_last(lines):
52
+ yield from line
53
+ if not last:
54
+ yield new_line
.venv/lib/python3.12/site-packages/pip/_vendor/rich/segment.py ADDED
@@ -0,0 +1,752 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import IntEnum
2
+ from functools import lru_cache
3
+ from itertools import filterfalse
4
+ from logging import getLogger
5
+ from operator import attrgetter
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ Dict,
9
+ Iterable,
10
+ List,
11
+ NamedTuple,
12
+ Optional,
13
+ Sequence,
14
+ Tuple,
15
+ Type,
16
+ Union,
17
+ )
18
+
19
+ from .cells import (
20
+ _is_single_cell_widths,
21
+ cached_cell_len,
22
+ cell_len,
23
+ get_character_cell_size,
24
+ set_cell_size,
25
+ )
26
+ from .repr import Result, rich_repr
27
+ from .style import Style
28
+
29
+ if TYPE_CHECKING:
30
+ from .console import Console, ConsoleOptions, RenderResult
31
+
32
+ log = getLogger("rich")
33
+
34
+
35
+ class ControlType(IntEnum):
36
+ """Non-printable control codes which typically translate to ANSI codes."""
37
+
38
+ BELL = 1
39
+ CARRIAGE_RETURN = 2
40
+ HOME = 3
41
+ CLEAR = 4
42
+ SHOW_CURSOR = 5
43
+ HIDE_CURSOR = 6
44
+ ENABLE_ALT_SCREEN = 7
45
+ DISABLE_ALT_SCREEN = 8
46
+ CURSOR_UP = 9
47
+ CURSOR_DOWN = 10
48
+ CURSOR_FORWARD = 11
49
+ CURSOR_BACKWARD = 12
50
+ CURSOR_MOVE_TO_COLUMN = 13
51
+ CURSOR_MOVE_TO = 14
52
+ ERASE_IN_LINE = 15
53
+ SET_WINDOW_TITLE = 16
54
+
55
+
56
+ ControlCode = Union[
57
+ Tuple[ControlType],
58
+ Tuple[ControlType, Union[int, str]],
59
+ Tuple[ControlType, int, int],
60
+ ]
61
+
62
+
63
+ @rich_repr()
64
+ class Segment(NamedTuple):
65
+ """A piece of text with associated style. Segments are produced by the Console render process and
66
+ are ultimately converted in to strings to be written to the terminal.
67
+
68
+ Args:
69
+ text (str): A piece of text.
70
+ style (:class:`~rich.style.Style`, optional): An optional style to apply to the text.
71
+ control (Tuple[ControlCode], optional): Optional sequence of control codes.
72
+
73
+ Attributes:
74
+ cell_length (int): The cell length of this Segment.
75
+ """
76
+
77
+ text: str
78
+ style: Optional[Style] = None
79
+ control: Optional[Sequence[ControlCode]] = None
80
+
81
+ @property
82
+ def cell_length(self) -> int:
83
+ """The number of terminal cells required to display self.text.
84
+
85
+ Returns:
86
+ int: A number of cells.
87
+ """
88
+ text, _style, control = self
89
+ return 0 if control else cell_len(text)
90
+
91
+ def __rich_repr__(self) -> Result:
92
+ yield self.text
93
+ if self.control is None:
94
+ if self.style is not None:
95
+ yield self.style
96
+ else:
97
+ yield self.style
98
+ yield self.control
99
+
100
+ def __bool__(self) -> bool:
101
+ """Check if the segment contains text."""
102
+ return bool(self.text)
103
+
104
+ @property
105
+ def is_control(self) -> bool:
106
+ """Check if the segment contains control codes."""
107
+ return self.control is not None
108
+
109
+ @classmethod
110
+ @lru_cache(1024 * 16)
111
+ def _split_cells(cls, segment: "Segment", cut: int) -> Tuple["Segment", "Segment"]:
112
+ """Split a segment in to two at a given cell position.
113
+
114
+ Note that splitting a double-width character, may result in that character turning
115
+ into two spaces.
116
+
117
+ Args:
118
+ segment (Segment): A segment to split.
119
+ cut (int): A cell position to cut on.
120
+
121
+ Returns:
122
+ A tuple of two segments.
123
+ """
124
+ text, style, control = segment
125
+ _Segment = Segment
126
+ cell_length = segment.cell_length
127
+ if cut >= cell_length:
128
+ return segment, _Segment("", style, control)
129
+
130
+ cell_size = get_character_cell_size
131
+
132
+ pos = int((cut / cell_length) * len(text))
133
+
134
+ while True:
135
+ before = text[:pos]
136
+ cell_pos = cell_len(before)
137
+ out_by = cell_pos - cut
138
+ if not out_by:
139
+ return (
140
+ _Segment(before, style, control),
141
+ _Segment(text[pos:], style, control),
142
+ )
143
+ if out_by == -1 and cell_size(text[pos]) == 2:
144
+ return (
145
+ _Segment(text[:pos] + " ", style, control),
146
+ _Segment(" " + text[pos + 1 :], style, control),
147
+ )
148
+ if out_by == +1 and cell_size(text[pos - 1]) == 2:
149
+ return (
150
+ _Segment(text[: pos - 1] + " ", style, control),
151
+ _Segment(" " + text[pos:], style, control),
152
+ )
153
+ if cell_pos < cut:
154
+ pos += 1
155
+ else:
156
+ pos -= 1
157
+
158
+ def split_cells(self, cut: int) -> Tuple["Segment", "Segment"]:
159
+ """Split segment in to two segments at the specified column.
160
+
161
+ If the cut point falls in the middle of a 2-cell wide character then it is replaced
162
+ by two spaces, to preserve the display width of the parent segment.
163
+
164
+ Args:
165
+ cut (int): Offset within the segment to cut.
166
+
167
+ Returns:
168
+ Tuple[Segment, Segment]: Two segments.
169
+ """
170
+ text, style, control = self
171
+ assert cut >= 0
172
+
173
+ if _is_single_cell_widths(text):
174
+ # Fast path with all 1 cell characters
175
+ if cut >= len(text):
176
+ return self, Segment("", style, control)
177
+ return (
178
+ Segment(text[:cut], style, control),
179
+ Segment(text[cut:], style, control),
180
+ )
181
+
182
+ return self._split_cells(self, cut)
183
+
184
+ @classmethod
185
+ def line(cls) -> "Segment":
186
+ """Make a new line segment."""
187
+ return cls("\n")
188
+
189
+ @classmethod
190
+ def apply_style(
191
+ cls,
192
+ segments: Iterable["Segment"],
193
+ style: Optional[Style] = None,
194
+ post_style: Optional[Style] = None,
195
+ ) -> Iterable["Segment"]:
196
+ """Apply style(s) to an iterable of segments.
197
+
198
+ Returns an iterable of segments where the style is replaced by ``style + segment.style + post_style``.
199
+
200
+ Args:
201
+ segments (Iterable[Segment]): Segments to process.
202
+ style (Style, optional): Base style. Defaults to None.
203
+ post_style (Style, optional): Style to apply on top of segment style. Defaults to None.
204
+
205
+ Returns:
206
+ Iterable[Segments]: A new iterable of segments (possibly the same iterable).
207
+ """
208
+ result_segments = segments
209
+ if style:
210
+ apply = style.__add__
211
+ result_segments = (
212
+ cls(text, None if control else apply(_style), control)
213
+ for text, _style, control in result_segments
214
+ )
215
+ if post_style:
216
+ result_segments = (
217
+ cls(
218
+ text,
219
+ (
220
+ None
221
+ if control
222
+ else (_style + post_style if _style else post_style)
223
+ ),
224
+ control,
225
+ )
226
+ for text, _style, control in result_segments
227
+ )
228
+ return result_segments
229
+
230
+ @classmethod
231
+ def filter_control(
232
+ cls, segments: Iterable["Segment"], is_control: bool = False
233
+ ) -> Iterable["Segment"]:
234
+ """Filter segments by ``is_control`` attribute.
235
+
236
+ Args:
237
+ segments (Iterable[Segment]): An iterable of Segment instances.
238
+ is_control (bool, optional): is_control flag to match in search.
239
+
240
+ Returns:
241
+ Iterable[Segment]: And iterable of Segment instances.
242
+
243
+ """
244
+ if is_control:
245
+ return filter(attrgetter("control"), segments)
246
+ else:
247
+ return filterfalse(attrgetter("control"), segments)
248
+
249
+ @classmethod
250
+ def split_lines(cls, segments: Iterable["Segment"]) -> Iterable[List["Segment"]]:
251
+ """Split a sequence of segments in to a list of lines.
252
+
253
+ Args:
254
+ segments (Iterable[Segment]): Segments potentially containing line feeds.
255
+
256
+ Yields:
257
+ Iterable[List[Segment]]: Iterable of segment lists, one per line.
258
+ """
259
+ line: List[Segment] = []
260
+ append = line.append
261
+
262
+ for segment in segments:
263
+ if "\n" in segment.text and not segment.control:
264
+ text, style, _ = segment
265
+ while text:
266
+ _text, new_line, text = text.partition("\n")
267
+ if _text:
268
+ append(cls(_text, style))
269
+ if new_line:
270
+ yield line
271
+ line = []
272
+ append = line.append
273
+ else:
274
+ append(segment)
275
+ if line:
276
+ yield line
277
+
278
+ @classmethod
279
+ def split_and_crop_lines(
280
+ cls,
281
+ segments: Iterable["Segment"],
282
+ length: int,
283
+ style: Optional[Style] = None,
284
+ pad: bool = True,
285
+ include_new_lines: bool = True,
286
+ ) -> Iterable[List["Segment"]]:
287
+ """Split segments in to lines, and crop lines greater than a given length.
288
+
289
+ Args:
290
+ segments (Iterable[Segment]): An iterable of segments, probably
291
+ generated from console.render.
292
+ length (int): Desired line length.
293
+ style (Style, optional): Style to use for any padding.
294
+ pad (bool): Enable padding of lines that are less than `length`.
295
+
296
+ Returns:
297
+ Iterable[List[Segment]]: An iterable of lines of segments.
298
+ """
299
+ line: List[Segment] = []
300
+ append = line.append
301
+
302
+ adjust_line_length = cls.adjust_line_length
303
+ new_line_segment = cls("\n")
304
+
305
+ for segment in segments:
306
+ if "\n" in segment.text and not segment.control:
307
+ text, segment_style, _ = segment
308
+ while text:
309
+ _text, new_line, text = text.partition("\n")
310
+ if _text:
311
+ append(cls(_text, segment_style))
312
+ if new_line:
313
+ cropped_line = adjust_line_length(
314
+ line, length, style=style, pad=pad
315
+ )
316
+ if include_new_lines:
317
+ cropped_line.append(new_line_segment)
318
+ yield cropped_line
319
+ line.clear()
320
+ else:
321
+ append(segment)
322
+ if line:
323
+ yield adjust_line_length(line, length, style=style, pad=pad)
324
+
325
+ @classmethod
326
+ def adjust_line_length(
327
+ cls,
328
+ line: List["Segment"],
329
+ length: int,
330
+ style: Optional[Style] = None,
331
+ pad: bool = True,
332
+ ) -> List["Segment"]:
333
+ """Adjust a line to a given width (cropping or padding as required).
334
+
335
+ Args:
336
+ segments (Iterable[Segment]): A list of segments in a single line.
337
+ length (int): The desired width of the line.
338
+ style (Style, optional): The style of padding if used (space on the end). Defaults to None.
339
+ pad (bool, optional): Pad lines with spaces if they are shorter than `length`. Defaults to True.
340
+
341
+ Returns:
342
+ List[Segment]: A line of segments with the desired length.
343
+ """
344
+ line_length = sum(segment.cell_length for segment in line)
345
+ new_line: List[Segment]
346
+
347
+ if line_length < length:
348
+ if pad:
349
+ new_line = line + [cls(" " * (length - line_length), style)]
350
+ else:
351
+ new_line = line[:]
352
+ elif line_length > length:
353
+ new_line = []
354
+ append = new_line.append
355
+ line_length = 0
356
+ for segment in line:
357
+ segment_length = segment.cell_length
358
+ if line_length + segment_length < length or segment.control:
359
+ append(segment)
360
+ line_length += segment_length
361
+ else:
362
+ text, segment_style, _ = segment
363
+ text = set_cell_size(text, length - line_length)
364
+ append(cls(text, segment_style))
365
+ break
366
+ else:
367
+ new_line = line[:]
368
+ return new_line
369
+
370
+ @classmethod
371
+ def get_line_length(cls, line: List["Segment"]) -> int:
372
+ """Get the length of list of segments.
373
+
374
+ Args:
375
+ line (List[Segment]): A line encoded as a list of Segments (assumes no '\\\\n' characters),
376
+
377
+ Returns:
378
+ int: The length of the line.
379
+ """
380
+ _cell_len = cell_len
381
+ return sum(_cell_len(text) for text, style, control in line if not control)
382
+
383
+ @classmethod
384
+ def get_shape(cls, lines: List[List["Segment"]]) -> Tuple[int, int]:
385
+ """Get the shape (enclosing rectangle) of a list of lines.
386
+
387
+ Args:
388
+ lines (List[List[Segment]]): A list of lines (no '\\\\n' characters).
389
+
390
+ Returns:
391
+ Tuple[int, int]: Width and height in characters.
392
+ """
393
+ get_line_length = cls.get_line_length
394
+ max_width = max(get_line_length(line) for line in lines) if lines else 0
395
+ return (max_width, len(lines))
396
+
397
+ @classmethod
398
+ def set_shape(
399
+ cls,
400
+ lines: List[List["Segment"]],
401
+ width: int,
402
+ height: Optional[int] = None,
403
+ style: Optional[Style] = None,
404
+ new_lines: bool = False,
405
+ ) -> List[List["Segment"]]:
406
+ """Set the shape of a list of lines (enclosing rectangle).
407
+
408
+ Args:
409
+ lines (List[List[Segment]]): A list of lines.
410
+ width (int): Desired width.
411
+ height (int, optional): Desired height or None for no change.
412
+ style (Style, optional): Style of any padding added.
413
+ new_lines (bool, optional): Padded lines should include "\n". Defaults to False.
414
+
415
+ Returns:
416
+ List[List[Segment]]: New list of lines.
417
+ """
418
+ _height = height or len(lines)
419
+
420
+ blank = (
421
+ [cls(" " * width + "\n", style)] if new_lines else [cls(" " * width, style)]
422
+ )
423
+
424
+ adjust_line_length = cls.adjust_line_length
425
+ shaped_lines = lines[:_height]
426
+ shaped_lines[:] = [
427
+ adjust_line_length(line, width, style=style) for line in lines
428
+ ]
429
+ if len(shaped_lines) < _height:
430
+ shaped_lines.extend([blank] * (_height - len(shaped_lines)))
431
+ return shaped_lines
432
+
433
+ @classmethod
434
+ def align_top(
435
+ cls: Type["Segment"],
436
+ lines: List[List["Segment"]],
437
+ width: int,
438
+ height: int,
439
+ style: Style,
440
+ new_lines: bool = False,
441
+ ) -> List[List["Segment"]]:
442
+ """Aligns lines to top (adds extra lines to bottom as required).
443
+
444
+ Args:
445
+ lines (List[List[Segment]]): A list of lines.
446
+ width (int): Desired width.
447
+ height (int, optional): Desired height or None for no change.
448
+ style (Style): Style of any padding added.
449
+ new_lines (bool, optional): Padded lines should include "\n". Defaults to False.
450
+
451
+ Returns:
452
+ List[List[Segment]]: New list of lines.
453
+ """
454
+ extra_lines = height - len(lines)
455
+ if not extra_lines:
456
+ return lines[:]
457
+ lines = lines[:height]
458
+ blank = cls(" " * width + "\n", style) if new_lines else cls(" " * width, style)
459
+ lines = lines + [[blank]] * extra_lines
460
+ return lines
461
+
462
+ @classmethod
463
+ def align_bottom(
464
+ cls: Type["Segment"],
465
+ lines: List[List["Segment"]],
466
+ width: int,
467
+ height: int,
468
+ style: Style,
469
+ new_lines: bool = False,
470
+ ) -> List[List["Segment"]]:
471
+ """Aligns render to bottom (adds extra lines above as required).
472
+
473
+ Args:
474
+ lines (List[List[Segment]]): A list of lines.
475
+ width (int): Desired width.
476
+ height (int, optional): Desired height or None for no change.
477
+ style (Style): Style of any padding added. Defaults to None.
478
+ new_lines (bool, optional): Padded lines should include "\n". Defaults to False.
479
+
480
+ Returns:
481
+ List[List[Segment]]: New list of lines.
482
+ """
483
+ extra_lines = height - len(lines)
484
+ if not extra_lines:
485
+ return lines[:]
486
+ lines = lines[:height]
487
+ blank = cls(" " * width + "\n", style) if new_lines else cls(" " * width, style)
488
+ lines = [[blank]] * extra_lines + lines
489
+ return lines
490
+
491
+ @classmethod
492
+ def align_middle(
493
+ cls: Type["Segment"],
494
+ lines: List[List["Segment"]],
495
+ width: int,
496
+ height: int,
497
+ style: Style,
498
+ new_lines: bool = False,
499
+ ) -> List[List["Segment"]]:
500
+ """Aligns lines to middle (adds extra lines to above and below as required).
501
+
502
+ Args:
503
+ lines (List[List[Segment]]): A list of lines.
504
+ width (int): Desired width.
505
+ height (int, optional): Desired height or None for no change.
506
+ style (Style): Style of any padding added.
507
+ new_lines (bool, optional): Padded lines should include "\n". Defaults to False.
508
+
509
+ Returns:
510
+ List[List[Segment]]: New list of lines.
511
+ """
512
+ extra_lines = height - len(lines)
513
+ if not extra_lines:
514
+ return lines[:]
515
+ lines = lines[:height]
516
+ blank = cls(" " * width + "\n", style) if new_lines else cls(" " * width, style)
517
+ top_lines = extra_lines // 2
518
+ bottom_lines = extra_lines - top_lines
519
+ lines = [[blank]] * top_lines + lines + [[blank]] * bottom_lines
520
+ return lines
521
+
522
+ @classmethod
523
+ def simplify(cls, segments: Iterable["Segment"]) -> Iterable["Segment"]:
524
+ """Simplify an iterable of segments by combining contiguous segments with the same style.
525
+
526
+ Args:
527
+ segments (Iterable[Segment]): An iterable of segments.
528
+
529
+ Returns:
530
+ Iterable[Segment]: A possibly smaller iterable of segments that will render the same way.
531
+ """
532
+ iter_segments = iter(segments)
533
+ try:
534
+ last_segment = next(iter_segments)
535
+ except StopIteration:
536
+ return
537
+
538
+ _Segment = Segment
539
+ for segment in iter_segments:
540
+ if last_segment.style == segment.style and not segment.control:
541
+ last_segment = _Segment(
542
+ last_segment.text + segment.text, last_segment.style
543
+ )
544
+ else:
545
+ yield last_segment
546
+ last_segment = segment
547
+ yield last_segment
548
+
549
+ @classmethod
550
+ def strip_links(cls, segments: Iterable["Segment"]) -> Iterable["Segment"]:
551
+ """Remove all links from an iterable of styles.
552
+
553
+ Args:
554
+ segments (Iterable[Segment]): An iterable segments.
555
+
556
+ Yields:
557
+ Segment: Segments with link removed.
558
+ """
559
+ for segment in segments:
560
+ if segment.control or segment.style is None:
561
+ yield segment
562
+ else:
563
+ text, style, _control = segment
564
+ yield cls(text, style.update_link(None) if style else None)
565
+
566
+ @classmethod
567
+ def strip_styles(cls, segments: Iterable["Segment"]) -> Iterable["Segment"]:
568
+ """Remove all styles from an iterable of segments.
569
+
570
+ Args:
571
+ segments (Iterable[Segment]): An iterable segments.
572
+
573
+ Yields:
574
+ Segment: Segments with styles replace with None
575
+ """
576
+ for text, _style, control in segments:
577
+ yield cls(text, None, control)
578
+
579
+ @classmethod
580
+ def remove_color(cls, segments: Iterable["Segment"]) -> Iterable["Segment"]:
581
+ """Remove all color from an iterable of segments.
582
+
583
+ Args:
584
+ segments (Iterable[Segment]): An iterable segments.
585
+
586
+ Yields:
587
+ Segment: Segments with colorless style.
588
+ """
589
+
590
+ cache: Dict[Style, Style] = {}
591
+ for text, style, control in segments:
592
+ if style:
593
+ colorless_style = cache.get(style)
594
+ if colorless_style is None:
595
+ colorless_style = style.without_color
596
+ cache[style] = colorless_style
597
+ yield cls(text, colorless_style, control)
598
+ else:
599
+ yield cls(text, None, control)
600
+
601
+ @classmethod
602
+ def divide(
603
+ cls, segments: Iterable["Segment"], cuts: Iterable[int]
604
+ ) -> Iterable[List["Segment"]]:
605
+ """Divides an iterable of segments in to portions.
606
+
607
+ Args:
608
+ cuts (Iterable[int]): Cell positions where to divide.
609
+
610
+ Yields:
611
+ [Iterable[List[Segment]]]: An iterable of Segments in List.
612
+ """
613
+ split_segments: List["Segment"] = []
614
+ add_segment = split_segments.append
615
+
616
+ iter_cuts = iter(cuts)
617
+
618
+ while True:
619
+ cut = next(iter_cuts, -1)
620
+ if cut == -1:
621
+ return
622
+ if cut != 0:
623
+ break
624
+ yield []
625
+ pos = 0
626
+
627
+ segments_clear = split_segments.clear
628
+ segments_copy = split_segments.copy
629
+
630
+ _cell_len = cached_cell_len
631
+ for segment in segments:
632
+ text, _style, control = segment
633
+ while text:
634
+ end_pos = pos if control else pos + _cell_len(text)
635
+ if end_pos < cut:
636
+ add_segment(segment)
637
+ pos = end_pos
638
+ break
639
+
640
+ if end_pos == cut:
641
+ add_segment(segment)
642
+ yield segments_copy()
643
+ segments_clear()
644
+ pos = end_pos
645
+
646
+ cut = next(iter_cuts, -1)
647
+ if cut == -1:
648
+ if split_segments:
649
+ yield segments_copy()
650
+ return
651
+
652
+ break
653
+
654
+ else:
655
+ before, segment = segment.split_cells(cut - pos)
656
+ text, _style, control = segment
657
+ add_segment(before)
658
+ yield segments_copy()
659
+ segments_clear()
660
+ pos = cut
661
+
662
+ cut = next(iter_cuts, -1)
663
+ if cut == -1:
664
+ if split_segments:
665
+ yield segments_copy()
666
+ return
667
+
668
+ yield segments_copy()
669
+
670
+
671
+ class Segments:
672
+ """A simple renderable to render an iterable of segments. This class may be useful if
673
+ you want to print segments outside of a __rich_console__ method.
674
+
675
+ Args:
676
+ segments (Iterable[Segment]): An iterable of segments.
677
+ new_lines (bool, optional): Add new lines between segments. Defaults to False.
678
+ """
679
+
680
+ def __init__(self, segments: Iterable[Segment], new_lines: bool = False) -> None:
681
+ self.segments = list(segments)
682
+ self.new_lines = new_lines
683
+
684
+ def __rich_console__(
685
+ self, console: "Console", options: "ConsoleOptions"
686
+ ) -> "RenderResult":
687
+ if self.new_lines:
688
+ line = Segment.line()
689
+ for segment in self.segments:
690
+ yield segment
691
+ yield line
692
+ else:
693
+ yield from self.segments
694
+
695
+
696
+ class SegmentLines:
697
+ def __init__(self, lines: Iterable[List[Segment]], new_lines: bool = False) -> None:
698
+ """A simple renderable containing a number of lines of segments. May be used as an intermediate
699
+ in rendering process.
700
+
701
+ Args:
702
+ lines (Iterable[List[Segment]]): Lists of segments forming lines.
703
+ new_lines (bool, optional): Insert new lines after each line. Defaults to False.
704
+ """
705
+ self.lines = list(lines)
706
+ self.new_lines = new_lines
707
+
708
+ def __rich_console__(
709
+ self, console: "Console", options: "ConsoleOptions"
710
+ ) -> "RenderResult":
711
+ if self.new_lines:
712
+ new_line = Segment.line()
713
+ for line in self.lines:
714
+ yield from line
715
+ yield new_line
716
+ else:
717
+ for line in self.lines:
718
+ yield from line
719
+
720
+
721
+ if __name__ == "__main__": # pragma: no cover
722
+ from pip._vendor.rich.console import Console
723
+ from pip._vendor.rich.syntax import Syntax
724
+ from pip._vendor.rich.text import Text
725
+
726
+ code = """from rich.console import Console
727
+ console = Console()
728
+ text = Text.from_markup("Hello, [bold magenta]World[/]!")
729
+ console.print(text)"""
730
+
731
+ text = Text.from_markup("Hello, [bold magenta]World[/]!")
732
+
733
+ console = Console()
734
+
735
+ console.rule("rich.Segment")
736
+ console.print(
737
+ "A Segment is the last step in the Rich render process before generating text with ANSI codes."
738
+ )
739
+ console.print("\nConsider the following code:\n")
740
+ console.print(Syntax(code, "python", line_numbers=True))
741
+ console.print()
742
+ console.print(
743
+ "When you call [b]print()[/b], Rich [i]renders[/i] the object in to the following:\n"
744
+ )
745
+ fragments = list(console.render(text))
746
+ console.print(fragments)
747
+ console.print()
748
+ console.print("The Segments are then processed to produce the following output:\n")
749
+ console.print(text)
750
+ console.print(
751
+ "\nYou will only need to know this if you are implementing your own Rich renderables."
752
+ )
.venv/lib/python3.12/site-packages/pip/_vendor/rich/spinner.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import TYPE_CHECKING, List, Optional, Union, cast
2
+
3
+ from ._spinners import SPINNERS
4
+ from .measure import Measurement
5
+ from .table import Table
6
+ from .text import Text
7
+
8
+ if TYPE_CHECKING:
9
+ from .console import Console, ConsoleOptions, RenderableType, RenderResult
10
+ from .style import StyleType
11
+
12
+
13
+ class Spinner:
14
+ """A spinner animation.
15
+
16
+ Args:
17
+ name (str): Name of spinner (run python -m rich.spinner).
18
+ text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "".
19
+ style (StyleType, optional): Style for spinner animation. Defaults to None.
20
+ speed (float, optional): Speed factor for animation. Defaults to 1.0.
21
+
22
+ Raises:
23
+ KeyError: If name isn't one of the supported spinner animations.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ name: str,
29
+ text: "RenderableType" = "",
30
+ *,
31
+ style: Optional["StyleType"] = None,
32
+ speed: float = 1.0,
33
+ ) -> None:
34
+ try:
35
+ spinner = SPINNERS[name]
36
+ except KeyError:
37
+ raise KeyError(f"no spinner called {name!r}")
38
+ self.text: "Union[RenderableType, Text]" = (
39
+ Text.from_markup(text) if isinstance(text, str) else text
40
+ )
41
+ self.name = name
42
+ self.frames = cast(List[str], spinner["frames"])[:]
43
+ self.interval = cast(float, spinner["interval"])
44
+ self.start_time: Optional[float] = None
45
+ self.style = style
46
+ self.speed = speed
47
+ self.frame_no_offset: float = 0.0
48
+ self._update_speed = 0.0
49
+
50
+ def __rich_console__(
51
+ self, console: "Console", options: "ConsoleOptions"
52
+ ) -> "RenderResult":
53
+ yield self.render(console.get_time())
54
+
55
+ def __rich_measure__(
56
+ self, console: "Console", options: "ConsoleOptions"
57
+ ) -> Measurement:
58
+ text = self.render(0)
59
+ return Measurement.get(console, options, text)
60
+
61
+ def render(self, time: float) -> "RenderableType":
62
+ """Render the spinner for a given time.
63
+
64
+ Args:
65
+ time (float): Time in seconds.
66
+
67
+ Returns:
68
+ RenderableType: A renderable containing animation frame.
69
+ """
70
+ if self.start_time is None:
71
+ self.start_time = time
72
+
73
+ frame_no = ((time - self.start_time) * self.speed) / (
74
+ self.interval / 1000.0
75
+ ) + self.frame_no_offset
76
+ frame = Text(
77
+ self.frames[int(frame_no) % len(self.frames)], style=self.style or ""
78
+ )
79
+
80
+ if self._update_speed:
81
+ self.frame_no_offset = frame_no
82
+ self.start_time = time
83
+ self.speed = self._update_speed
84
+ self._update_speed = 0.0
85
+
86
+ if not self.text:
87
+ return frame
88
+ elif isinstance(self.text, (str, Text)):
89
+ return Text.assemble(frame, " ", self.text)
90
+ else:
91
+ table = Table.grid(padding=1)
92
+ table.add_row(frame, self.text)
93
+ return table
94
+
95
+ def update(
96
+ self,
97
+ *,
98
+ text: "RenderableType" = "",
99
+ style: Optional["StyleType"] = None,
100
+ speed: Optional[float] = None,
101
+ ) -> None:
102
+ """Updates attributes of a spinner after it has been started.
103
+
104
+ Args:
105
+ text (RenderableType, optional): A renderable to display at the right of the spinner (str or Text typically). Defaults to "".
106
+ style (StyleType, optional): Style for spinner animation. Defaults to None.
107
+ speed (float, optional): Speed factor for animation. Defaults to None.
108
+ """
109
+ if text:
110
+ self.text = Text.from_markup(text) if isinstance(text, str) else text
111
+ if style:
112
+ self.style = style
113
+ if speed:
114
+ self._update_speed = speed
115
+
116
+
117
+ if __name__ == "__main__": # pragma: no cover
118
+ from time import sleep
119
+
120
+ from .console import Group
121
+ from .live import Live
122
+
123
+ all_spinners = Group(
124
+ *[
125
+ Spinner(spinner_name, text=Text(repr(spinner_name), style="green"))
126
+ for spinner_name in sorted(SPINNERS.keys())
127
+ ]
128
+ )
129
+
130
+ with Live(all_spinners, refresh_per_second=20) as live:
131
+ while True:
132
+ sleep(0.1)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/status.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from types import TracebackType
2
+ from typing import Optional, Type
3
+
4
+ from .console import Console, RenderableType
5
+ from .jupyter import JupyterMixin
6
+ from .live import Live
7
+ from .spinner import Spinner
8
+ from .style import StyleType
9
+
10
+
11
+ class Status(JupyterMixin):
12
+ """Displays a status indicator with a 'spinner' animation.
13
+
14
+ Args:
15
+ status (RenderableType): A status renderable (str or Text typically).
16
+ console (Console, optional): Console instance to use, or None for global console. Defaults to None.
17
+ spinner (str, optional): Name of spinner animation (see python -m rich.spinner). Defaults to "dots".
18
+ spinner_style (StyleType, optional): Style of spinner. Defaults to "status.spinner".
19
+ speed (float, optional): Speed factor for spinner animation. Defaults to 1.0.
20
+ refresh_per_second (float, optional): Number of refreshes per second. Defaults to 12.5.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ status: RenderableType,
26
+ *,
27
+ console: Optional[Console] = None,
28
+ spinner: str = "dots",
29
+ spinner_style: StyleType = "status.spinner",
30
+ speed: float = 1.0,
31
+ refresh_per_second: float = 12.5,
32
+ ):
33
+ self.status = status
34
+ self.spinner_style = spinner_style
35
+ self.speed = speed
36
+ self._spinner = Spinner(spinner, text=status, style=spinner_style, speed=speed)
37
+ self._live = Live(
38
+ self.renderable,
39
+ console=console,
40
+ refresh_per_second=refresh_per_second,
41
+ transient=True,
42
+ )
43
+
44
+ @property
45
+ def renderable(self) -> Spinner:
46
+ return self._spinner
47
+
48
+ @property
49
+ def console(self) -> "Console":
50
+ """Get the Console used by the Status objects."""
51
+ return self._live.console
52
+
53
+ def update(
54
+ self,
55
+ status: Optional[RenderableType] = None,
56
+ *,
57
+ spinner: Optional[str] = None,
58
+ spinner_style: Optional[StyleType] = None,
59
+ speed: Optional[float] = None,
60
+ ) -> None:
61
+ """Update status.
62
+
63
+ Args:
64
+ status (Optional[RenderableType], optional): New status renderable or None for no change. Defaults to None.
65
+ spinner (Optional[str], optional): New spinner or None for no change. Defaults to None.
66
+ spinner_style (Optional[StyleType], optional): New spinner style or None for no change. Defaults to None.
67
+ speed (Optional[float], optional): Speed factor for spinner animation or None for no change. Defaults to None.
68
+ """
69
+ if status is not None:
70
+ self.status = status
71
+ if spinner_style is not None:
72
+ self.spinner_style = spinner_style
73
+ if speed is not None:
74
+ self.speed = speed
75
+ if spinner is not None:
76
+ self._spinner = Spinner(
77
+ spinner, text=self.status, style=self.spinner_style, speed=self.speed
78
+ )
79
+ self._live.update(self.renderable, refresh=True)
80
+ else:
81
+ self._spinner.update(
82
+ text=self.status, style=self.spinner_style, speed=self.speed
83
+ )
84
+
85
+ def start(self) -> None:
86
+ """Start the status animation."""
87
+ self._live.start()
88
+
89
+ def stop(self) -> None:
90
+ """Stop the spinner animation."""
91
+ self._live.stop()
92
+
93
+ def __rich__(self) -> RenderableType:
94
+ return self.renderable
95
+
96
+ def __enter__(self) -> "Status":
97
+ self.start()
98
+ return self
99
+
100
+ def __exit__(
101
+ self,
102
+ exc_type: Optional[Type[BaseException]],
103
+ exc_val: Optional[BaseException],
104
+ exc_tb: Optional[TracebackType],
105
+ ) -> None:
106
+ self.stop()
107
+
108
+
109
+ if __name__ == "__main__": # pragma: no cover
110
+ from time import sleep
111
+
112
+ from .console import Console
113
+
114
+ console = Console()
115
+ with console.status("[magenta]Covid detector booting up") as status:
116
+ sleep(3)
117
+ console.log("Importing advanced AI")
118
+ sleep(3)
119
+ console.log("Advanced Covid AI Ready")
120
+ sleep(3)
121
+ status.update(status="[bold blue] Scanning for Covid", spinner="earth")
122
+ sleep(3)
123
+ console.log("Found 10,000,000,000 copies of Covid32.exe")
124
+ sleep(3)
125
+ status.update(
126
+ status="[bold red]Moving Covid32.exe to Trash",
127
+ spinner="bouncingBall",
128
+ spinner_style="yellow",
129
+ )
130
+ sleep(5)
131
+ console.print("[bold green]Covid deleted successfully")
.venv/lib/python3.12/site-packages/pip/_vendor/rich/style.py ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ from functools import lru_cache
3
+ from operator import attrgetter
4
+ from pickle import dumps, loads
5
+ from random import randint
6
+ from typing import Any, Dict, Iterable, List, Optional, Type, Union, cast
7
+
8
+ from . import errors
9
+ from .color import Color, ColorParseError, ColorSystem, blend_rgb
10
+ from .repr import Result, rich_repr
11
+ from .terminal_theme import DEFAULT_TERMINAL_THEME, TerminalTheme
12
+
13
+ _hash_getter = attrgetter(
14
+ "_color", "_bgcolor", "_attributes", "_set_attributes", "_link", "_meta"
15
+ )
16
+
17
+ # Style instances and style definitions are often interchangeable
18
+ StyleType = Union[str, "Style"]
19
+
20
+
21
+ class _Bit:
22
+ """A descriptor to get/set a style attribute bit."""
23
+
24
+ __slots__ = ["bit"]
25
+
26
+ def __init__(self, bit_no: int) -> None:
27
+ self.bit = 1 << bit_no
28
+
29
+ def __get__(self, obj: "Style", objtype: Type["Style"]) -> Optional[bool]:
30
+ if obj._set_attributes & self.bit:
31
+ return obj._attributes & self.bit != 0
32
+ return None
33
+
34
+
35
+ @rich_repr
36
+ class Style:
37
+ """A terminal style.
38
+
39
+ A terminal style consists of a color (`color`), a background color (`bgcolor`), and a number of attributes, such
40
+ as bold, italic etc. The attributes have 3 states: they can either be on
41
+ (``True``), off (``False``), or not set (``None``).
42
+
43
+ Args:
44
+ color (Union[Color, str], optional): Color of terminal text. Defaults to None.
45
+ bgcolor (Union[Color, str], optional): Color of terminal background. Defaults to None.
46
+ bold (bool, optional): Enable bold text. Defaults to None.
47
+ dim (bool, optional): Enable dim text. Defaults to None.
48
+ italic (bool, optional): Enable italic text. Defaults to None.
49
+ underline (bool, optional): Enable underlined text. Defaults to None.
50
+ blink (bool, optional): Enabled blinking text. Defaults to None.
51
+ blink2 (bool, optional): Enable fast blinking text. Defaults to None.
52
+ reverse (bool, optional): Enabled reverse text. Defaults to None.
53
+ conceal (bool, optional): Enable concealed text. Defaults to None.
54
+ strike (bool, optional): Enable strikethrough text. Defaults to None.
55
+ underline2 (bool, optional): Enable doubly underlined text. Defaults to None.
56
+ frame (bool, optional): Enable framed text. Defaults to None.
57
+ encircle (bool, optional): Enable encircled text. Defaults to None.
58
+ overline (bool, optional): Enable overlined text. Defaults to None.
59
+ link (str, link): Link URL. Defaults to None.
60
+
61
+ """
62
+
63
+ _color: Optional[Color]
64
+ _bgcolor: Optional[Color]
65
+ _attributes: int
66
+ _set_attributes: int
67
+ _hash: Optional[int]
68
+ _null: bool
69
+ _meta: Optional[bytes]
70
+
71
+ __slots__ = [
72
+ "_color",
73
+ "_bgcolor",
74
+ "_attributes",
75
+ "_set_attributes",
76
+ "_link",
77
+ "_link_id",
78
+ "_ansi",
79
+ "_style_definition",
80
+ "_hash",
81
+ "_null",
82
+ "_meta",
83
+ ]
84
+
85
+ # maps bits on to SGR parameter
86
+ _style_map = {
87
+ 0: "1",
88
+ 1: "2",
89
+ 2: "3",
90
+ 3: "4",
91
+ 4: "5",
92
+ 5: "6",
93
+ 6: "7",
94
+ 7: "8",
95
+ 8: "9",
96
+ 9: "21",
97
+ 10: "51",
98
+ 11: "52",
99
+ 12: "53",
100
+ }
101
+
102
+ STYLE_ATTRIBUTES = {
103
+ "dim": "dim",
104
+ "d": "dim",
105
+ "bold": "bold",
106
+ "b": "bold",
107
+ "italic": "italic",
108
+ "i": "italic",
109
+ "underline": "underline",
110
+ "u": "underline",
111
+ "blink": "blink",
112
+ "blink2": "blink2",
113
+ "reverse": "reverse",
114
+ "r": "reverse",
115
+ "conceal": "conceal",
116
+ "c": "conceal",
117
+ "strike": "strike",
118
+ "s": "strike",
119
+ "underline2": "underline2",
120
+ "uu": "underline2",
121
+ "frame": "frame",
122
+ "encircle": "encircle",
123
+ "overline": "overline",
124
+ "o": "overline",
125
+ }
126
+
127
+ def __init__(
128
+ self,
129
+ *,
130
+ color: Optional[Union[Color, str]] = None,
131
+ bgcolor: Optional[Union[Color, str]] = None,
132
+ bold: Optional[bool] = None,
133
+ dim: Optional[bool] = None,
134
+ italic: Optional[bool] = None,
135
+ underline: Optional[bool] = None,
136
+ blink: Optional[bool] = None,
137
+ blink2: Optional[bool] = None,
138
+ reverse: Optional[bool] = None,
139
+ conceal: Optional[bool] = None,
140
+ strike: Optional[bool] = None,
141
+ underline2: Optional[bool] = None,
142
+ frame: Optional[bool] = None,
143
+ encircle: Optional[bool] = None,
144
+ overline: Optional[bool] = None,
145
+ link: Optional[str] = None,
146
+ meta: Optional[Dict[str, Any]] = None,
147
+ ):
148
+ self._ansi: Optional[str] = None
149
+ self._style_definition: Optional[str] = None
150
+
151
+ def _make_color(color: Union[Color, str]) -> Color:
152
+ return color if isinstance(color, Color) else Color.parse(color)
153
+
154
+ self._color = None if color is None else _make_color(color)
155
+ self._bgcolor = None if bgcolor is None else _make_color(bgcolor)
156
+ self._set_attributes = sum(
157
+ (
158
+ bold is not None,
159
+ dim is not None and 2,
160
+ italic is not None and 4,
161
+ underline is not None and 8,
162
+ blink is not None and 16,
163
+ blink2 is not None and 32,
164
+ reverse is not None and 64,
165
+ conceal is not None and 128,
166
+ strike is not None and 256,
167
+ underline2 is not None and 512,
168
+ frame is not None and 1024,
169
+ encircle is not None and 2048,
170
+ overline is not None and 4096,
171
+ )
172
+ )
173
+ self._attributes = (
174
+ sum(
175
+ (
176
+ bold and 1 or 0,
177
+ dim and 2 or 0,
178
+ italic and 4 or 0,
179
+ underline and 8 or 0,
180
+ blink and 16 or 0,
181
+ blink2 and 32 or 0,
182
+ reverse and 64 or 0,
183
+ conceal and 128 or 0,
184
+ strike and 256 or 0,
185
+ underline2 and 512 or 0,
186
+ frame and 1024 or 0,
187
+ encircle and 2048 or 0,
188
+ overline and 4096 or 0,
189
+ )
190
+ )
191
+ if self._set_attributes
192
+ else 0
193
+ )
194
+
195
+ self._link = link
196
+ self._meta = None if meta is None else dumps(meta)
197
+ self._link_id = (
198
+ f"{randint(0, 999999)}{hash(self._meta)}" if (link or meta) else ""
199
+ )
200
+ self._hash: Optional[int] = None
201
+ self._null = not (self._set_attributes or color or bgcolor or link or meta)
202
+
203
+ @classmethod
204
+ def null(cls) -> "Style":
205
+ """Create an 'null' style, equivalent to Style(), but more performant."""
206
+ return NULL_STYLE
207
+
208
+ @classmethod
209
+ def from_color(
210
+ cls, color: Optional[Color] = None, bgcolor: Optional[Color] = None
211
+ ) -> "Style":
212
+ """Create a new style with colors and no attributes.
213
+
214
+ Returns:
215
+ color (Optional[Color]): A (foreground) color, or None for no color. Defaults to None.
216
+ bgcolor (Optional[Color]): A (background) color, or None for no color. Defaults to None.
217
+ """
218
+ style: Style = cls.__new__(Style)
219
+ style._ansi = None
220
+ style._style_definition = None
221
+ style._color = color
222
+ style._bgcolor = bgcolor
223
+ style._set_attributes = 0
224
+ style._attributes = 0
225
+ style._link = None
226
+ style._link_id = ""
227
+ style._meta = None
228
+ style._null = not (color or bgcolor)
229
+ style._hash = None
230
+ return style
231
+
232
+ @classmethod
233
+ def from_meta(cls, meta: Optional[Dict[str, Any]]) -> "Style":
234
+ """Create a new style with meta data.
235
+
236
+ Returns:
237
+ meta (Optional[Dict[str, Any]]): A dictionary of meta data. Defaults to None.
238
+ """
239
+ style: Style = cls.__new__(Style)
240
+ style._ansi = None
241
+ style._style_definition = None
242
+ style._color = None
243
+ style._bgcolor = None
244
+ style._set_attributes = 0
245
+ style._attributes = 0
246
+ style._link = None
247
+ style._meta = dumps(meta)
248
+ style._link_id = f"{randint(0, 999999)}{hash(style._meta)}"
249
+ style._hash = None
250
+ style._null = not (meta)
251
+ return style
252
+
253
+ @classmethod
254
+ def on(cls, meta: Optional[Dict[str, Any]] = None, **handlers: Any) -> "Style":
255
+ """Create a blank style with meta information.
256
+
257
+ Example:
258
+ style = Style.on(click=self.on_click)
259
+
260
+ Args:
261
+ meta (Optional[Dict[str, Any]], optional): An optional dict of meta information.
262
+ **handlers (Any): Keyword arguments are translated in to handlers.
263
+
264
+ Returns:
265
+ Style: A Style with meta information attached.
266
+ """
267
+ meta = {} if meta is None else meta
268
+ meta.update({f"@{key}": value for key, value in handlers.items()})
269
+ return cls.from_meta(meta)
270
+
271
+ bold = _Bit(0)
272
+ dim = _Bit(1)
273
+ italic = _Bit(2)
274
+ underline = _Bit(3)
275
+ blink = _Bit(4)
276
+ blink2 = _Bit(5)
277
+ reverse = _Bit(6)
278
+ conceal = _Bit(7)
279
+ strike = _Bit(8)
280
+ underline2 = _Bit(9)
281
+ frame = _Bit(10)
282
+ encircle = _Bit(11)
283
+ overline = _Bit(12)
284
+
285
+ @property
286
+ def link_id(self) -> str:
287
+ """Get a link id, used in ansi code for links."""
288
+ return self._link_id
289
+
290
+ def __str__(self) -> str:
291
+ """Re-generate style definition from attributes."""
292
+ if self._style_definition is None:
293
+ attributes: List[str] = []
294
+ append = attributes.append
295
+ bits = self._set_attributes
296
+ if bits & 0b0000000001111:
297
+ if bits & 1:
298
+ append("bold" if self.bold else "not bold")
299
+ if bits & (1 << 1):
300
+ append("dim" if self.dim else "not dim")
301
+ if bits & (1 << 2):
302
+ append("italic" if self.italic else "not italic")
303
+ if bits & (1 << 3):
304
+ append("underline" if self.underline else "not underline")
305
+ if bits & 0b0000111110000:
306
+ if bits & (1 << 4):
307
+ append("blink" if self.blink else "not blink")
308
+ if bits & (1 << 5):
309
+ append("blink2" if self.blink2 else "not blink2")
310
+ if bits & (1 << 6):
311
+ append("reverse" if self.reverse else "not reverse")
312
+ if bits & (1 << 7):
313
+ append("conceal" if self.conceal else "not conceal")
314
+ if bits & (1 << 8):
315
+ append("strike" if self.strike else "not strike")
316
+ if bits & 0b1111000000000:
317
+ if bits & (1 << 9):
318
+ append("underline2" if self.underline2 else "not underline2")
319
+ if bits & (1 << 10):
320
+ append("frame" if self.frame else "not frame")
321
+ if bits & (1 << 11):
322
+ append("encircle" if self.encircle else "not encircle")
323
+ if bits & (1 << 12):
324
+ append("overline" if self.overline else "not overline")
325
+ if self._color is not None:
326
+ append(self._color.name)
327
+ if self._bgcolor is not None:
328
+ append("on")
329
+ append(self._bgcolor.name)
330
+ if self._link:
331
+ append("link")
332
+ append(self._link)
333
+ self._style_definition = " ".join(attributes) or "none"
334
+ return self._style_definition
335
+
336
+ def __bool__(self) -> bool:
337
+ """A Style is false if it has no attributes, colors, or links."""
338
+ return not self._null
339
+
340
+ def _make_ansi_codes(self, color_system: ColorSystem) -> str:
341
+ """Generate ANSI codes for this style.
342
+
343
+ Args:
344
+ color_system (ColorSystem): Color system.
345
+
346
+ Returns:
347
+ str: String containing codes.
348
+ """
349
+
350
+ if self._ansi is None:
351
+ sgr: List[str] = []
352
+ append = sgr.append
353
+ _style_map = self._style_map
354
+ attributes = self._attributes & self._set_attributes
355
+ if attributes:
356
+ if attributes & 1:
357
+ append(_style_map[0])
358
+ if attributes & 2:
359
+ append(_style_map[1])
360
+ if attributes & 4:
361
+ append(_style_map[2])
362
+ if attributes & 8:
363
+ append(_style_map[3])
364
+ if attributes & 0b0000111110000:
365
+ for bit in range(4, 9):
366
+ if attributes & (1 << bit):
367
+ append(_style_map[bit])
368
+ if attributes & 0b1111000000000:
369
+ for bit in range(9, 13):
370
+ if attributes & (1 << bit):
371
+ append(_style_map[bit])
372
+ if self._color is not None:
373
+ sgr.extend(self._color.downgrade(color_system).get_ansi_codes())
374
+ if self._bgcolor is not None:
375
+ sgr.extend(
376
+ self._bgcolor.downgrade(color_system).get_ansi_codes(
377
+ foreground=False
378
+ )
379
+ )
380
+ self._ansi = ";".join(sgr)
381
+ return self._ansi
382
+
383
+ @classmethod
384
+ @lru_cache(maxsize=1024)
385
+ def normalize(cls, style: str) -> str:
386
+ """Normalize a style definition so that styles with the same effect have the same string
387
+ representation.
388
+
389
+ Args:
390
+ style (str): A style definition.
391
+
392
+ Returns:
393
+ str: Normal form of style definition.
394
+ """
395
+ try:
396
+ return str(cls.parse(style))
397
+ except errors.StyleSyntaxError:
398
+ return style.strip().lower()
399
+
400
+ @classmethod
401
+ def pick_first(cls, *values: Optional[StyleType]) -> StyleType:
402
+ """Pick first non-None style."""
403
+ for value in values:
404
+ if value is not None:
405
+ return value
406
+ raise ValueError("expected at least one non-None style")
407
+
408
+ def __rich_repr__(self) -> Result:
409
+ yield "color", self.color, None
410
+ yield "bgcolor", self.bgcolor, None
411
+ yield "bold", self.bold, None,
412
+ yield "dim", self.dim, None,
413
+ yield "italic", self.italic, None
414
+ yield "underline", self.underline, None,
415
+ yield "blink", self.blink, None
416
+ yield "blink2", self.blink2, None
417
+ yield "reverse", self.reverse, None
418
+ yield "conceal", self.conceal, None
419
+ yield "strike", self.strike, None
420
+ yield "underline2", self.underline2, None
421
+ yield "frame", self.frame, None
422
+ yield "encircle", self.encircle, None
423
+ yield "link", self.link, None
424
+ if self._meta:
425
+ yield "meta", self.meta
426
+
427
+ def __eq__(self, other: Any) -> bool:
428
+ if not isinstance(other, Style):
429
+ return NotImplemented
430
+ return self.__hash__() == other.__hash__()
431
+
432
+ def __ne__(self, other: Any) -> bool:
433
+ if not isinstance(other, Style):
434
+ return NotImplemented
435
+ return self.__hash__() != other.__hash__()
436
+
437
+ def __hash__(self) -> int:
438
+ if self._hash is not None:
439
+ return self._hash
440
+ self._hash = hash(_hash_getter(self))
441
+ return self._hash
442
+
443
+ @property
444
+ def color(self) -> Optional[Color]:
445
+ """The foreground color or None if it is not set."""
446
+ return self._color
447
+
448
+ @property
449
+ def bgcolor(self) -> Optional[Color]:
450
+ """The background color or None if it is not set."""
451
+ return self._bgcolor
452
+
453
+ @property
454
+ def link(self) -> Optional[str]:
455
+ """Link text, if set."""
456
+ return self._link
457
+
458
+ @property
459
+ def transparent_background(self) -> bool:
460
+ """Check if the style specified a transparent background."""
461
+ return self.bgcolor is None or self.bgcolor.is_default
462
+
463
+ @property
464
+ def background_style(self) -> "Style":
465
+ """A Style with background only."""
466
+ return Style(bgcolor=self.bgcolor)
467
+
468
+ @property
469
+ def meta(self) -> Dict[str, Any]:
470
+ """Get meta information (can not be changed after construction)."""
471
+ return {} if self._meta is None else cast(Dict[str, Any], loads(self._meta))
472
+
473
+ @property
474
+ def without_color(self) -> "Style":
475
+ """Get a copy of the style with color removed."""
476
+ if self._null:
477
+ return NULL_STYLE
478
+ style: Style = self.__new__(Style)
479
+ style._ansi = None
480
+ style._style_definition = None
481
+ style._color = None
482
+ style._bgcolor = None
483
+ style._attributes = self._attributes
484
+ style._set_attributes = self._set_attributes
485
+ style._link = self._link
486
+ style._link_id = f"{randint(0, 999999)}" if self._link else ""
487
+ style._null = False
488
+ style._meta = None
489
+ style._hash = None
490
+ return style
491
+
492
+ @classmethod
493
+ @lru_cache(maxsize=4096)
494
+ def parse(cls, style_definition: str) -> "Style":
495
+ """Parse a style definition.
496
+
497
+ Args:
498
+ style_definition (str): A string containing a style.
499
+
500
+ Raises:
501
+ errors.StyleSyntaxError: If the style definition syntax is invalid.
502
+
503
+ Returns:
504
+ `Style`: A Style instance.
505
+ """
506
+ if style_definition.strip() == "none" or not style_definition:
507
+ return cls.null()
508
+
509
+ STYLE_ATTRIBUTES = cls.STYLE_ATTRIBUTES
510
+ color: Optional[str] = None
511
+ bgcolor: Optional[str] = None
512
+ attributes: Dict[str, Optional[Any]] = {}
513
+ link: Optional[str] = None
514
+
515
+ words = iter(style_definition.split())
516
+ for original_word in words:
517
+ word = original_word.lower()
518
+ if word == "on":
519
+ word = next(words, "")
520
+ if not word:
521
+ raise errors.StyleSyntaxError("color expected after 'on'")
522
+ try:
523
+ Color.parse(word)
524
+ except ColorParseError as error:
525
+ raise errors.StyleSyntaxError(
526
+ f"unable to parse {word!r} as background color; {error}"
527
+ ) from None
528
+ bgcolor = word
529
+
530
+ elif word == "not":
531
+ word = next(words, "")
532
+ attribute = STYLE_ATTRIBUTES.get(word)
533
+ if attribute is None:
534
+ raise errors.StyleSyntaxError(
535
+ f"expected style attribute after 'not', found {word!r}"
536
+ )
537
+ attributes[attribute] = False
538
+
539
+ elif word == "link":
540
+ word = next(words, "")
541
+ if not word:
542
+ raise errors.StyleSyntaxError("URL expected after 'link'")
543
+ link = word
544
+
545
+ elif word in STYLE_ATTRIBUTES:
546
+ attributes[STYLE_ATTRIBUTES[word]] = True
547
+
548
+ else:
549
+ try:
550
+ Color.parse(word)
551
+ except ColorParseError as error:
552
+ raise errors.StyleSyntaxError(
553
+ f"unable to parse {word!r} as color; {error}"
554
+ ) from None
555
+ color = word
556
+ style = Style(color=color, bgcolor=bgcolor, link=link, **attributes)
557
+ return style
558
+
559
+ @lru_cache(maxsize=1024)
560
+ def get_html_style(self, theme: Optional[TerminalTheme] = None) -> str:
561
+ """Get a CSS style rule."""
562
+ theme = theme or DEFAULT_TERMINAL_THEME
563
+ css: List[str] = []
564
+ append = css.append
565
+
566
+ color = self.color
567
+ bgcolor = self.bgcolor
568
+ if self.reverse:
569
+ color, bgcolor = bgcolor, color
570
+ if self.dim:
571
+ foreground_color = (
572
+ theme.foreground_color if color is None else color.get_truecolor(theme)
573
+ )
574
+ color = Color.from_triplet(
575
+ blend_rgb(foreground_color, theme.background_color, 0.5)
576
+ )
577
+ if color is not None:
578
+ theme_color = color.get_truecolor(theme)
579
+ append(f"color: {theme_color.hex}")
580
+ append(f"text-decoration-color: {theme_color.hex}")
581
+ if bgcolor is not None:
582
+ theme_color = bgcolor.get_truecolor(theme, foreground=False)
583
+ append(f"background-color: {theme_color.hex}")
584
+ if self.bold:
585
+ append("font-weight: bold")
586
+ if self.italic:
587
+ append("font-style: italic")
588
+ if self.underline:
589
+ append("text-decoration: underline")
590
+ if self.strike:
591
+ append("text-decoration: line-through")
592
+ if self.overline:
593
+ append("text-decoration: overline")
594
+ return "; ".join(css)
595
+
596
+ @classmethod
597
+ def combine(cls, styles: Iterable["Style"]) -> "Style":
598
+ """Combine styles and get result.
599
+
600
+ Args:
601
+ styles (Iterable[Style]): Styles to combine.
602
+
603
+ Returns:
604
+ Style: A new style instance.
605
+ """
606
+ iter_styles = iter(styles)
607
+ return sum(iter_styles, next(iter_styles))
608
+
609
+ @classmethod
610
+ def chain(cls, *styles: "Style") -> "Style":
611
+ """Combine styles from positional argument in to a single style.
612
+
613
+ Args:
614
+ *styles (Iterable[Style]): Styles to combine.
615
+
616
+ Returns:
617
+ Style: A new style instance.
618
+ """
619
+ iter_styles = iter(styles)
620
+ return sum(iter_styles, next(iter_styles))
621
+
622
+ def copy(self) -> "Style":
623
+ """Get a copy of this style.
624
+
625
+ Returns:
626
+ Style: A new Style instance with identical attributes.
627
+ """
628
+ if self._null:
629
+ return NULL_STYLE
630
+ style: Style = self.__new__(Style)
631
+ style._ansi = self._ansi
632
+ style._style_definition = self._style_definition
633
+ style._color = self._color
634
+ style._bgcolor = self._bgcolor
635
+ style._attributes = self._attributes
636
+ style._set_attributes = self._set_attributes
637
+ style._link = self._link
638
+ style._link_id = f"{randint(0, 999999)}" if self._link else ""
639
+ style._hash = self._hash
640
+ style._null = False
641
+ style._meta = self._meta
642
+ return style
643
+
644
+ @lru_cache(maxsize=128)
645
+ def clear_meta_and_links(self) -> "Style":
646
+ """Get a copy of this style with link and meta information removed.
647
+
648
+ Returns:
649
+ Style: New style object.
650
+ """
651
+ if self._null:
652
+ return NULL_STYLE
653
+ style: Style = self.__new__(Style)
654
+ style._ansi = self._ansi
655
+ style._style_definition = self._style_definition
656
+ style._color = self._color
657
+ style._bgcolor = self._bgcolor
658
+ style._attributes = self._attributes
659
+ style._set_attributes = self._set_attributes
660
+ style._link = None
661
+ style._link_id = ""
662
+ style._hash = None
663
+ style._null = False
664
+ style._meta = None
665
+ return style
666
+
667
+ def update_link(self, link: Optional[str] = None) -> "Style":
668
+ """Get a copy with a different value for link.
669
+
670
+ Args:
671
+ link (str, optional): New value for link. Defaults to None.
672
+
673
+ Returns:
674
+ Style: A new Style instance.
675
+ """
676
+ style: Style = self.__new__(Style)
677
+ style._ansi = self._ansi
678
+ style._style_definition = self._style_definition
679
+ style._color = self._color
680
+ style._bgcolor = self._bgcolor
681
+ style._attributes = self._attributes
682
+ style._set_attributes = self._set_attributes
683
+ style._link = link
684
+ style._link_id = f"{randint(0, 999999)}" if link else ""
685
+ style._hash = None
686
+ style._null = False
687
+ style._meta = self._meta
688
+ return style
689
+
690
+ def render(
691
+ self,
692
+ text: str = "",
693
+ *,
694
+ color_system: Optional[ColorSystem] = ColorSystem.TRUECOLOR,
695
+ legacy_windows: bool = False,
696
+ ) -> str:
697
+ """Render the ANSI codes for the style.
698
+
699
+ Args:
700
+ text (str, optional): A string to style. Defaults to "".
701
+ color_system (Optional[ColorSystem], optional): Color system to render to. Defaults to ColorSystem.TRUECOLOR.
702
+
703
+ Returns:
704
+ str: A string containing ANSI style codes.
705
+ """
706
+ if not text or color_system is None:
707
+ return text
708
+ attrs = self._ansi or self._make_ansi_codes(color_system)
709
+ rendered = f"\x1b[{attrs}m{text}\x1b[0m" if attrs else text
710
+ if self._link and not legacy_windows:
711
+ rendered = (
712
+ f"\x1b]8;id={self._link_id};{self._link}\x1b\\{rendered}\x1b]8;;\x1b\\"
713
+ )
714
+ return rendered
715
+
716
+ def test(self, text: Optional[str] = None) -> None:
717
+ """Write text with style directly to terminal.
718
+
719
+ This method is for testing purposes only.
720
+
721
+ Args:
722
+ text (Optional[str], optional): Text to style or None for style name.
723
+
724
+ """
725
+ text = text or str(self)
726
+ sys.stdout.write(f"{self.render(text)}\n")
727
+
728
+ @lru_cache(maxsize=1024)
729
+ def _add(self, style: Optional["Style"]) -> "Style":
730
+ if style is None or style._null:
731
+ return self
732
+ if self._null:
733
+ return style
734
+ new_style: Style = self.__new__(Style)
735
+ new_style._ansi = None
736
+ new_style._style_definition = None
737
+ new_style._color = style._color or self._color
738
+ new_style._bgcolor = style._bgcolor or self._bgcolor
739
+ new_style._attributes = (self._attributes & ~style._set_attributes) | (
740
+ style._attributes & style._set_attributes
741
+ )
742
+ new_style._set_attributes = self._set_attributes | style._set_attributes
743
+ new_style._link = style._link or self._link
744
+ new_style._link_id = style._link_id or self._link_id
745
+ new_style._null = style._null
746
+ if self._meta and style._meta:
747
+ new_style._meta = dumps({**self.meta, **style.meta})
748
+ else:
749
+ new_style._meta = self._meta or style._meta
750
+ new_style._hash = None
751
+ return new_style
752
+
753
+ def __add__(self, style: Optional["Style"]) -> "Style":
754
+ combined_style = self._add(style)
755
+ return combined_style.copy() if combined_style.link else combined_style
756
+
757
+
758
+ NULL_STYLE = Style()
759
+
760
+
761
+ class StyleStack:
762
+ """A stack of styles."""
763
+
764
+ __slots__ = ["_stack"]
765
+
766
+ def __init__(self, default_style: "Style") -> None:
767
+ self._stack: List[Style] = [default_style]
768
+
769
+ def __repr__(self) -> str:
770
+ return f"<stylestack {self._stack!r}>"
771
+
772
+ @property
773
+ def current(self) -> Style:
774
+ """Get the Style at the top of the stack."""
775
+ return self._stack[-1]
776
+
777
+ def push(self, style: Style) -> None:
778
+ """Push a new style on to the stack.
779
+
780
+ Args:
781
+ style (Style): New style to combine with current style.
782
+ """
783
+ self._stack.append(self._stack[-1] + style)
784
+
785
+ def pop(self) -> Style:
786
+ """Pop last style and discard.
787
+
788
+ Returns:
789
+ Style: New current style (also available as stack.current)
790
+ """
791
+ self._stack.pop()
792
+ return self._stack[-1]
.venv/lib/python3.12/site-packages/pip/_vendor/rich/styled.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import TYPE_CHECKING
2
+
3
+ from .measure import Measurement
4
+ from .segment import Segment
5
+ from .style import StyleType
6
+
7
+ if TYPE_CHECKING:
8
+ from .console import Console, ConsoleOptions, RenderResult, RenderableType
9
+
10
+
11
+ class Styled:
12
+ """Apply a style to a renderable.
13
+
14
+ Args:
15
+ renderable (RenderableType): Any renderable.
16
+ style (StyleType): A style to apply across the entire renderable.
17
+ """
18
+
19
+ def __init__(self, renderable: "RenderableType", style: "StyleType") -> None:
20
+ self.renderable = renderable
21
+ self.style = style
22
+
23
+ def __rich_console__(
24
+ self, console: "Console", options: "ConsoleOptions"
25
+ ) -> "RenderResult":
26
+ style = console.get_style(self.style)
27
+ rendered_segments = console.render(self.renderable, options)
28
+ segments = Segment.apply_style(rendered_segments, style)
29
+ return segments
30
+
31
+ def __rich_measure__(
32
+ self, console: "Console", options: "ConsoleOptions"
33
+ ) -> Measurement:
34
+ return Measurement.get(console, options, self.renderable)
35
+
36
+
37
+ if __name__ == "__main__": # pragma: no cover
38
+ from pip._vendor.rich import print
39
+ from pip._vendor.rich.panel import Panel
40
+
41
+ panel = Styled(Panel("hello"), "on blue")
42
+ print(panel)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/syntax.py ADDED
@@ -0,0 +1,985 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os.path
4
+ import re
5
+ import sys
6
+ import textwrap
7
+ from abc import ABC, abstractmethod
8
+ from pathlib import Path
9
+ from typing import (
10
+ Any,
11
+ Dict,
12
+ Iterable,
13
+ List,
14
+ NamedTuple,
15
+ Optional,
16
+ Sequence,
17
+ Set,
18
+ Tuple,
19
+ Type,
20
+ Union,
21
+ )
22
+
23
+ from pip._vendor.pygments.lexer import Lexer
24
+ from pip._vendor.pygments.lexers import get_lexer_by_name, guess_lexer_for_filename
25
+ from pip._vendor.pygments.style import Style as PygmentsStyle
26
+ from pip._vendor.pygments.styles import get_style_by_name
27
+ from pip._vendor.pygments.token import (
28
+ Comment,
29
+ Error,
30
+ Generic,
31
+ Keyword,
32
+ Name,
33
+ Number,
34
+ Operator,
35
+ String,
36
+ Token,
37
+ Whitespace,
38
+ )
39
+ from pip._vendor.pygments.util import ClassNotFound
40
+
41
+ from pip._vendor.rich.containers import Lines
42
+ from pip._vendor.rich.padding import Padding, PaddingDimensions
43
+
44
+ from ._loop import loop_first
45
+ from .cells import cell_len
46
+ from .color import Color, blend_rgb
47
+ from .console import Console, ConsoleOptions, JustifyMethod, RenderResult
48
+ from .jupyter import JupyterMixin
49
+ from .measure import Measurement
50
+ from .segment import Segment, Segments
51
+ from .style import Style, StyleType
52
+ from .text import Text
53
+
54
+ TokenType = Tuple[str, ...]
55
+
56
+ WINDOWS = sys.platform == "win32"
57
+ DEFAULT_THEME = "monokai"
58
+
59
+ # The following styles are based on https://github.com/pygments/pygments/blob/master/pygments/formatters/terminal.py
60
+ # A few modifications were made
61
+
62
+ ANSI_LIGHT: Dict[TokenType, Style] = {
63
+ Token: Style(),
64
+ Whitespace: Style(color="white"),
65
+ Comment: Style(dim=True),
66
+ Comment.Preproc: Style(color="cyan"),
67
+ Keyword: Style(color="blue"),
68
+ Keyword.Type: Style(color="cyan"),
69
+ Operator.Word: Style(color="magenta"),
70
+ Name.Builtin: Style(color="cyan"),
71
+ Name.Function: Style(color="green"),
72
+ Name.Namespace: Style(color="cyan", underline=True),
73
+ Name.Class: Style(color="green", underline=True),
74
+ Name.Exception: Style(color="cyan"),
75
+ Name.Decorator: Style(color="magenta", bold=True),
76
+ Name.Variable: Style(color="red"),
77
+ Name.Constant: Style(color="red"),
78
+ Name.Attribute: Style(color="cyan"),
79
+ Name.Tag: Style(color="bright_blue"),
80
+ String: Style(color="yellow"),
81
+ Number: Style(color="blue"),
82
+ Generic.Deleted: Style(color="bright_red"),
83
+ Generic.Inserted: Style(color="green"),
84
+ Generic.Heading: Style(bold=True),
85
+ Generic.Subheading: Style(color="magenta", bold=True),
86
+ Generic.Prompt: Style(bold=True),
87
+ Generic.Error: Style(color="bright_red"),
88
+ Error: Style(color="red", underline=True),
89
+ }
90
+
91
+ ANSI_DARK: Dict[TokenType, Style] = {
92
+ Token: Style(),
93
+ Whitespace: Style(color="bright_black"),
94
+ Comment: Style(dim=True),
95
+ Comment.Preproc: Style(color="bright_cyan"),
96
+ Keyword: Style(color="bright_blue"),
97
+ Keyword.Type: Style(color="bright_cyan"),
98
+ Operator.Word: Style(color="bright_magenta"),
99
+ Name.Builtin: Style(color="bright_cyan"),
100
+ Name.Function: Style(color="bright_green"),
101
+ Name.Namespace: Style(color="bright_cyan", underline=True),
102
+ Name.Class: Style(color="bright_green", underline=True),
103
+ Name.Exception: Style(color="bright_cyan"),
104
+ Name.Decorator: Style(color="bright_magenta", bold=True),
105
+ Name.Variable: Style(color="bright_red"),
106
+ Name.Constant: Style(color="bright_red"),
107
+ Name.Attribute: Style(color="bright_cyan"),
108
+ Name.Tag: Style(color="bright_blue"),
109
+ String: Style(color="yellow"),
110
+ Number: Style(color="bright_blue"),
111
+ Generic.Deleted: Style(color="bright_red"),
112
+ Generic.Inserted: Style(color="bright_green"),
113
+ Generic.Heading: Style(bold=True),
114
+ Generic.Subheading: Style(color="bright_magenta", bold=True),
115
+ Generic.Prompt: Style(bold=True),
116
+ Generic.Error: Style(color="bright_red"),
117
+ Error: Style(color="red", underline=True),
118
+ }
119
+
120
+ RICH_SYNTAX_THEMES = {"ansi_light": ANSI_LIGHT, "ansi_dark": ANSI_DARK}
121
+ NUMBERS_COLUMN_DEFAULT_PADDING = 2
122
+
123
+
124
+ class SyntaxTheme(ABC):
125
+ """Base class for a syntax theme."""
126
+
127
+ @abstractmethod
128
+ def get_style_for_token(self, token_type: TokenType) -> Style:
129
+ """Get a style for a given Pygments token."""
130
+ raise NotImplementedError # pragma: no cover
131
+
132
+ @abstractmethod
133
+ def get_background_style(self) -> Style:
134
+ """Get the background color."""
135
+ raise NotImplementedError # pragma: no cover
136
+
137
+
138
+ class PygmentsSyntaxTheme(SyntaxTheme):
139
+ """Syntax theme that delegates to Pygments theme."""
140
+
141
+ def __init__(self, theme: Union[str, Type[PygmentsStyle]]) -> None:
142
+ self._style_cache: Dict[TokenType, Style] = {}
143
+ if isinstance(theme, str):
144
+ try:
145
+ self._pygments_style_class = get_style_by_name(theme)
146
+ except ClassNotFound:
147
+ self._pygments_style_class = get_style_by_name("default")
148
+ else:
149
+ self._pygments_style_class = theme
150
+
151
+ self._background_color = self._pygments_style_class.background_color
152
+ self._background_style = Style(bgcolor=self._background_color)
153
+
154
+ def get_style_for_token(self, token_type: TokenType) -> Style:
155
+ """Get a style from a Pygments class."""
156
+ try:
157
+ return self._style_cache[token_type]
158
+ except KeyError:
159
+ try:
160
+ pygments_style = self._pygments_style_class.style_for_token(token_type)
161
+ except KeyError:
162
+ style = Style.null()
163
+ else:
164
+ color = pygments_style["color"]
165
+ bgcolor = pygments_style["bgcolor"]
166
+ style = Style(
167
+ color="#" + color if color else "#000000",
168
+ bgcolor="#" + bgcolor if bgcolor else self._background_color,
169
+ bold=pygments_style["bold"],
170
+ italic=pygments_style["italic"],
171
+ underline=pygments_style["underline"],
172
+ )
173
+ self._style_cache[token_type] = style
174
+ return style
175
+
176
+ def get_background_style(self) -> Style:
177
+ return self._background_style
178
+
179
+
180
+ class ANSISyntaxTheme(SyntaxTheme):
181
+ """Syntax theme to use standard colors."""
182
+
183
+ def __init__(self, style_map: Dict[TokenType, Style]) -> None:
184
+ self.style_map = style_map
185
+ self._missing_style = Style.null()
186
+ self._background_style = Style.null()
187
+ self._style_cache: Dict[TokenType, Style] = {}
188
+
189
+ def get_style_for_token(self, token_type: TokenType) -> Style:
190
+ """Look up style in the style map."""
191
+ try:
192
+ return self._style_cache[token_type]
193
+ except KeyError:
194
+ # Styles form a hierarchy
195
+ # We need to go from most to least specific
196
+ # e.g. ("foo", "bar", "baz") to ("foo", "bar") to ("foo",)
197
+ get_style = self.style_map.get
198
+ token = tuple(token_type)
199
+ style = self._missing_style
200
+ while token:
201
+ _style = get_style(token)
202
+ if _style is not None:
203
+ style = _style
204
+ break
205
+ token = token[:-1]
206
+ self._style_cache[token_type] = style
207
+ return style
208
+
209
+ def get_background_style(self) -> Style:
210
+ return self._background_style
211
+
212
+
213
+ SyntaxPosition = Tuple[int, int]
214
+
215
+
216
+ class _SyntaxHighlightRange(NamedTuple):
217
+ """
218
+ A range to highlight in a Syntax object.
219
+ `start` and `end` are 2-integers tuples, where the first integer is the line number
220
+ (starting from 1) and the second integer is the column index (starting from 0).
221
+ """
222
+
223
+ style: StyleType
224
+ start: SyntaxPosition
225
+ end: SyntaxPosition
226
+ style_before: bool = False
227
+
228
+
229
+ class PaddingProperty:
230
+ """Descriptor to get and set padding."""
231
+
232
+ def __get__(self, obj: Syntax, objtype: Type[Syntax]) -> Tuple[int, int, int, int]:
233
+ """Space around the Syntax."""
234
+ return obj._padding
235
+
236
+ def __set__(self, obj: Syntax, padding: PaddingDimensions) -> None:
237
+ obj._padding = Padding.unpack(padding)
238
+
239
+
240
+ class Syntax(JupyterMixin):
241
+ """Construct a Syntax object to render syntax highlighted code.
242
+
243
+ Args:
244
+ code (str): Code to highlight.
245
+ lexer (Lexer | str): Lexer to use (see https://pygments.org/docs/lexers/)
246
+ theme (str, optional): Color theme, aka Pygments style (see https://pygments.org/docs/styles/#getting-a-list-of-available-styles). Defaults to "monokai".
247
+ dedent (bool, optional): Enable stripping of initial whitespace. Defaults to False.
248
+ line_numbers (bool, optional): Enable rendering of line numbers. Defaults to False.
249
+ start_line (int, optional): Starting number for line numbers. Defaults to 1.
250
+ line_range (Tuple[int | None, int | None], optional): If given should be a tuple of the start and end line to render.
251
+ A value of None in the tuple indicates the range is open in that direction.
252
+ highlight_lines (Set[int]): A set of line numbers to highlight.
253
+ code_width: Width of code to render (not including line numbers), or ``None`` to use all available width.
254
+ tab_size (int, optional): Size of tabs. Defaults to 4.
255
+ word_wrap (bool, optional): Enable word wrapping.
256
+ background_color (str, optional): Optional background color, or None to use theme color. Defaults to None.
257
+ indent_guides (bool, optional): Show indent guides. Defaults to False.
258
+ padding (PaddingDimensions): Padding to apply around the syntax. Defaults to 0 (no padding).
259
+ """
260
+
261
+ _pygments_style_class: Type[PygmentsStyle]
262
+ _theme: SyntaxTheme
263
+
264
+ @classmethod
265
+ def get_theme(cls, name: Union[str, SyntaxTheme]) -> SyntaxTheme:
266
+ """Get a syntax theme instance."""
267
+ if isinstance(name, SyntaxTheme):
268
+ return name
269
+ theme: SyntaxTheme
270
+ if name in RICH_SYNTAX_THEMES:
271
+ theme = ANSISyntaxTheme(RICH_SYNTAX_THEMES[name])
272
+ else:
273
+ theme = PygmentsSyntaxTheme(name)
274
+ return theme
275
+
276
+ def __init__(
277
+ self,
278
+ code: str,
279
+ lexer: Union[Lexer, str],
280
+ *,
281
+ theme: Union[str, SyntaxTheme] = DEFAULT_THEME,
282
+ dedent: bool = False,
283
+ line_numbers: bool = False,
284
+ start_line: int = 1,
285
+ line_range: Optional[Tuple[Optional[int], Optional[int]]] = None,
286
+ highlight_lines: Optional[Set[int]] = None,
287
+ code_width: Optional[int] = None,
288
+ tab_size: int = 4,
289
+ word_wrap: bool = False,
290
+ background_color: Optional[str] = None,
291
+ indent_guides: bool = False,
292
+ padding: PaddingDimensions = 0,
293
+ ) -> None:
294
+ self.code = code
295
+ self._lexer = lexer
296
+ self.dedent = dedent
297
+ self.line_numbers = line_numbers
298
+ self.start_line = start_line
299
+ self.line_range = line_range
300
+ self.highlight_lines = highlight_lines or set()
301
+ self.code_width = code_width
302
+ self.tab_size = tab_size
303
+ self.word_wrap = word_wrap
304
+ self.background_color = background_color
305
+ self.background_style = (
306
+ Style(bgcolor=background_color) if background_color else Style()
307
+ )
308
+ self.indent_guides = indent_guides
309
+ self._padding = Padding.unpack(padding)
310
+
311
+ self._theme = self.get_theme(theme)
312
+ self._stylized_ranges: List[_SyntaxHighlightRange] = []
313
+
314
+ padding = PaddingProperty()
315
+
316
+ @classmethod
317
+ def from_path(
318
+ cls,
319
+ path: str,
320
+ encoding: str = "utf-8",
321
+ lexer: Optional[Union[Lexer, str]] = None,
322
+ theme: Union[str, SyntaxTheme] = DEFAULT_THEME,
323
+ dedent: bool = False,
324
+ line_numbers: bool = False,
325
+ line_range: Optional[Tuple[int, int]] = None,
326
+ start_line: int = 1,
327
+ highlight_lines: Optional[Set[int]] = None,
328
+ code_width: Optional[int] = None,
329
+ tab_size: int = 4,
330
+ word_wrap: bool = False,
331
+ background_color: Optional[str] = None,
332
+ indent_guides: bool = False,
333
+ padding: PaddingDimensions = 0,
334
+ ) -> "Syntax":
335
+ """Construct a Syntax object from a file.
336
+
337
+ Args:
338
+ path (str): Path to file to highlight.
339
+ encoding (str): Encoding of file.
340
+ lexer (str | Lexer, optional): Lexer to use. If None, lexer will be auto-detected from path/file content.
341
+ theme (str, optional): Color theme, aka Pygments style (see https://pygments.org/docs/styles/#getting-a-list-of-available-styles). Defaults to "emacs".
342
+ dedent (bool, optional): Enable stripping of initial whitespace. Defaults to True.
343
+ line_numbers (bool, optional): Enable rendering of line numbers. Defaults to False.
344
+ start_line (int, optional): Starting number for line numbers. Defaults to 1.
345
+ line_range (Tuple[int, int], optional): If given should be a tuple of the start and end line to render.
346
+ highlight_lines (Set[int]): A set of line numbers to highlight.
347
+ code_width: Width of code to render (not including line numbers), or ``None`` to use all available width.
348
+ tab_size (int, optional): Size of tabs. Defaults to 4.
349
+ word_wrap (bool, optional): Enable word wrapping of code.
350
+ background_color (str, optional): Optional background color, or None to use theme color. Defaults to None.
351
+ indent_guides (bool, optional): Show indent guides. Defaults to False.
352
+ padding (PaddingDimensions): Padding to apply around the syntax. Defaults to 0 (no padding).
353
+
354
+ Returns:
355
+ [Syntax]: A Syntax object that may be printed to the console
356
+ """
357
+ code = Path(path).read_text(encoding=encoding)
358
+
359
+ if not lexer:
360
+ lexer = cls.guess_lexer(path, code=code)
361
+
362
+ return cls(
363
+ code,
364
+ lexer,
365
+ theme=theme,
366
+ dedent=dedent,
367
+ line_numbers=line_numbers,
368
+ line_range=line_range,
369
+ start_line=start_line,
370
+ highlight_lines=highlight_lines,
371
+ code_width=code_width,
372
+ tab_size=tab_size,
373
+ word_wrap=word_wrap,
374
+ background_color=background_color,
375
+ indent_guides=indent_guides,
376
+ padding=padding,
377
+ )
378
+
379
+ @classmethod
380
+ def guess_lexer(cls, path: str, code: Optional[str] = None) -> str:
381
+ """Guess the alias of the Pygments lexer to use based on a path and an optional string of code.
382
+ If code is supplied, it will use a combination of the code and the filename to determine the
383
+ best lexer to use. For example, if the file is ``index.html`` and the file contains Django
384
+ templating syntax, then "html+django" will be returned. If the file is ``index.html``, and no
385
+ templating language is used, the "html" lexer will be used. If no string of code
386
+ is supplied, the lexer will be chosen based on the file extension..
387
+
388
+ Args:
389
+ path (AnyStr): The path to the file containing the code you wish to know the lexer for.
390
+ code (str, optional): Optional string of code that will be used as a fallback if no lexer
391
+ is found for the supplied path.
392
+
393
+ Returns:
394
+ str: The name of the Pygments lexer that best matches the supplied path/code.
395
+ """
396
+ lexer: Optional[Lexer] = None
397
+ lexer_name = "default"
398
+ if code:
399
+ try:
400
+ lexer = guess_lexer_for_filename(path, code)
401
+ except ClassNotFound:
402
+ pass
403
+
404
+ if not lexer:
405
+ try:
406
+ _, ext = os.path.splitext(path)
407
+ if ext:
408
+ extension = ext.lstrip(".").lower()
409
+ lexer = get_lexer_by_name(extension)
410
+ except ClassNotFound:
411
+ pass
412
+
413
+ if lexer:
414
+ if lexer.aliases:
415
+ lexer_name = lexer.aliases[0]
416
+ else:
417
+ lexer_name = lexer.name
418
+
419
+ return lexer_name
420
+
421
+ def _get_base_style(self) -> Style:
422
+ """Get the base style."""
423
+ default_style = self._theme.get_background_style() + self.background_style
424
+ return default_style
425
+
426
+ def _get_token_color(self, token_type: TokenType) -> Optional[Color]:
427
+ """Get a color (if any) for the given token.
428
+
429
+ Args:
430
+ token_type (TokenType): A token type tuple from Pygments.
431
+
432
+ Returns:
433
+ Optional[Color]: Color from theme, or None for no color.
434
+ """
435
+ style = self._theme.get_style_for_token(token_type)
436
+ return style.color
437
+
438
+ @property
439
+ def lexer(self) -> Optional[Lexer]:
440
+ """The lexer for this syntax, or None if no lexer was found.
441
+
442
+ Tries to find the lexer by name if a string was passed to the constructor.
443
+ """
444
+
445
+ if isinstance(self._lexer, Lexer):
446
+ return self._lexer
447
+ try:
448
+ return get_lexer_by_name(
449
+ self._lexer,
450
+ stripnl=False,
451
+ ensurenl=True,
452
+ tabsize=self.tab_size,
453
+ )
454
+ except ClassNotFound:
455
+ return None
456
+
457
+ @property
458
+ def default_lexer(self) -> Lexer:
459
+ """A Pygments Lexer to use if one is not specified or invalid."""
460
+ return get_lexer_by_name(
461
+ "text",
462
+ stripnl=False,
463
+ ensurenl=True,
464
+ tabsize=self.tab_size,
465
+ )
466
+
467
+ def highlight(
468
+ self,
469
+ code: str,
470
+ line_range: Optional[Tuple[Optional[int], Optional[int]]] = None,
471
+ ) -> Text:
472
+ """Highlight code and return a Text instance.
473
+
474
+ Args:
475
+ code (str): Code to highlight.
476
+ line_range(Tuple[int, int], optional): Optional line range to highlight.
477
+
478
+ Returns:
479
+ Text: A text instance containing highlighted syntax.
480
+ """
481
+
482
+ base_style = self._get_base_style()
483
+ justify: JustifyMethod = (
484
+ "default" if base_style.transparent_background else "left"
485
+ )
486
+
487
+ text = Text(
488
+ justify=justify,
489
+ style=base_style,
490
+ tab_size=self.tab_size,
491
+ no_wrap=not self.word_wrap,
492
+ )
493
+ _get_theme_style = self._theme.get_style_for_token
494
+
495
+ lexer = self.lexer or self.default_lexer
496
+
497
+ if lexer is None:
498
+ text.append(code)
499
+ else:
500
+ if line_range:
501
+ # More complicated path to only stylize a portion of the code
502
+ # This speeds up further operations as there are less spans to process
503
+ line_start, line_end = line_range
504
+
505
+ def line_tokenize() -> Iterable[Tuple[Any, str]]:
506
+ """Split tokens to one per line."""
507
+ assert lexer # required to make MyPy happy - we know lexer is not None at this point
508
+
509
+ for token_type, token in lexer.get_tokens(code):
510
+ while token:
511
+ line_token, new_line, token = token.partition("\n")
512
+ yield token_type, line_token + new_line
513
+
514
+ def tokens_to_spans() -> Iterable[Tuple[str, Optional[Style]]]:
515
+ """Convert tokens to spans."""
516
+ tokens = iter(line_tokenize())
517
+ line_no = 0
518
+ _line_start = line_start - 1 if line_start else 0
519
+
520
+ # Skip over tokens until line start
521
+ while line_no < _line_start:
522
+ try:
523
+ _token_type, token = next(tokens)
524
+ except StopIteration:
525
+ break
526
+ yield (token, None)
527
+ if token.endswith("\n"):
528
+ line_no += 1
529
+ # Generate spans until line end
530
+ for token_type, token in tokens:
531
+ yield (token, _get_theme_style(token_type))
532
+ if token.endswith("\n"):
533
+ line_no += 1
534
+ if line_end and line_no >= line_end:
535
+ break
536
+
537
+ text.append_tokens(tokens_to_spans())
538
+
539
+ else:
540
+ text.append_tokens(
541
+ (token, _get_theme_style(token_type))
542
+ for token_type, token in lexer.get_tokens(code)
543
+ )
544
+ if self.background_color is not None:
545
+ text.stylize(f"on {self.background_color}")
546
+
547
+ if self._stylized_ranges:
548
+ self._apply_stylized_ranges(text)
549
+
550
+ return text
551
+
552
+ def stylize_range(
553
+ self,
554
+ style: StyleType,
555
+ start: SyntaxPosition,
556
+ end: SyntaxPosition,
557
+ style_before: bool = False,
558
+ ) -> None:
559
+ """
560
+ Adds a custom style on a part of the code, that will be applied to the syntax display when it's rendered.
561
+ Line numbers are 1-based, while column indexes are 0-based.
562
+
563
+ Args:
564
+ style (StyleType): The style to apply.
565
+ start (Tuple[int, int]): The start of the range, in the form `[line number, column index]`.
566
+ end (Tuple[int, int]): The end of the range, in the form `[line number, column index]`.
567
+ style_before (bool): Apply the style before any existing styles.
568
+ """
569
+ self._stylized_ranges.append(
570
+ _SyntaxHighlightRange(style, start, end, style_before)
571
+ )
572
+
573
+ def _get_line_numbers_color(self, blend: float = 0.3) -> Color:
574
+ background_style = self._theme.get_background_style() + self.background_style
575
+ background_color = background_style.bgcolor
576
+ if background_color is None or background_color.is_system_defined:
577
+ return Color.default()
578
+ foreground_color = self._get_token_color(Token.Text)
579
+ if foreground_color is None or foreground_color.is_system_defined:
580
+ return foreground_color or Color.default()
581
+ new_color = blend_rgb(
582
+ background_color.get_truecolor(),
583
+ foreground_color.get_truecolor(),
584
+ cross_fade=blend,
585
+ )
586
+ return Color.from_triplet(new_color)
587
+
588
+ @property
589
+ def _numbers_column_width(self) -> int:
590
+ """Get the number of characters used to render the numbers column."""
591
+ column_width = 0
592
+ if self.line_numbers:
593
+ column_width = (
594
+ len(str(self.start_line + self.code.count("\n")))
595
+ + NUMBERS_COLUMN_DEFAULT_PADDING
596
+ )
597
+ return column_width
598
+
599
+ def _get_number_styles(self, console: Console) -> Tuple[Style, Style, Style]:
600
+ """Get background, number, and highlight styles for line numbers."""
601
+ background_style = self._get_base_style()
602
+ if background_style.transparent_background:
603
+ return Style.null(), Style(dim=True), Style.null()
604
+ if console.color_system in ("256", "truecolor"):
605
+ number_style = Style.chain(
606
+ background_style,
607
+ self._theme.get_style_for_token(Token.Text),
608
+ Style(color=self._get_line_numbers_color()),
609
+ self.background_style,
610
+ )
611
+ highlight_number_style = Style.chain(
612
+ background_style,
613
+ self._theme.get_style_for_token(Token.Text),
614
+ Style(bold=True, color=self._get_line_numbers_color(0.9)),
615
+ self.background_style,
616
+ )
617
+ else:
618
+ number_style = background_style + Style(dim=True)
619
+ highlight_number_style = background_style + Style(dim=False)
620
+ return background_style, number_style, highlight_number_style
621
+
622
+ def __rich_measure__(
623
+ self, console: "Console", options: "ConsoleOptions"
624
+ ) -> "Measurement":
625
+ _, right, _, left = self.padding
626
+ padding = left + right
627
+ if self.code_width is not None:
628
+ width = self.code_width + self._numbers_column_width + padding + 1
629
+ return Measurement(self._numbers_column_width, width)
630
+ lines = self.code.splitlines()
631
+ width = (
632
+ self._numbers_column_width
633
+ + padding
634
+ + (max(cell_len(line) for line in lines) if lines else 0)
635
+ )
636
+ if self.line_numbers:
637
+ width += 1
638
+ return Measurement(self._numbers_column_width, width)
639
+
640
+ def __rich_console__(
641
+ self, console: Console, options: ConsoleOptions
642
+ ) -> RenderResult:
643
+ segments = Segments(self._get_syntax(console, options))
644
+ if any(self.padding):
645
+ yield Padding(segments, style=self._get_base_style(), pad=self.padding)
646
+ else:
647
+ yield segments
648
+
649
+ def _get_syntax(
650
+ self,
651
+ console: Console,
652
+ options: ConsoleOptions,
653
+ ) -> Iterable[Segment]:
654
+ """
655
+ Get the Segments for the Syntax object, excluding any vertical/horizontal padding
656
+ """
657
+ transparent_background = self._get_base_style().transparent_background
658
+ _pad_top, pad_right, _pad_bottom, pad_left = self.padding
659
+ horizontal_padding = pad_left + pad_right
660
+ code_width = (
661
+ (
662
+ (options.max_width - self._numbers_column_width - 1)
663
+ if self.line_numbers
664
+ else options.max_width
665
+ )
666
+ - horizontal_padding
667
+ if self.code_width is None
668
+ else self.code_width
669
+ )
670
+ code_width = max(0, code_width)
671
+
672
+ ends_on_nl, processed_code = self._process_code(self.code)
673
+ text = self.highlight(processed_code, self.line_range)
674
+
675
+ if not self.line_numbers and not self.word_wrap and not self.line_range:
676
+ if not ends_on_nl:
677
+ text.remove_suffix("\n")
678
+ # Simple case of just rendering text
679
+ style = (
680
+ self._get_base_style()
681
+ + self._theme.get_style_for_token(Comment)
682
+ + Style(dim=True)
683
+ + self.background_style
684
+ )
685
+ if self.indent_guides and not options.ascii_only:
686
+ text = text.with_indent_guides(self.tab_size, style=style)
687
+ text.overflow = "crop"
688
+ if style.transparent_background:
689
+ yield from console.render(
690
+ text, options=options.update(width=code_width)
691
+ )
692
+ else:
693
+ syntax_lines = console.render_lines(
694
+ text,
695
+ options.update(width=code_width, height=None, justify="left"),
696
+ style=self.background_style,
697
+ pad=True,
698
+ new_lines=True,
699
+ )
700
+ for syntax_line in syntax_lines:
701
+ yield from syntax_line
702
+ return
703
+
704
+ start_line, end_line = self.line_range or (None, None)
705
+ line_offset = 0
706
+ if start_line:
707
+ line_offset = max(0, start_line - 1)
708
+ lines: Union[List[Text], Lines] = text.split("\n", allow_blank=ends_on_nl)
709
+ if self.line_range:
710
+ if line_offset > len(lines):
711
+ return
712
+ lines = lines[line_offset:end_line]
713
+
714
+ if self.indent_guides and not options.ascii_only:
715
+ style = (
716
+ self._get_base_style()
717
+ + self._theme.get_style_for_token(Comment)
718
+ + Style(dim=True)
719
+ + self.background_style
720
+ )
721
+ lines = (
722
+ Text("\n")
723
+ .join(lines)
724
+ .with_indent_guides(self.tab_size, style=style + Style(italic=False))
725
+ .split("\n", allow_blank=True)
726
+ )
727
+
728
+ numbers_column_width = self._numbers_column_width
729
+ render_options = options.update(width=code_width)
730
+
731
+ highlight_line = self.highlight_lines.__contains__
732
+ _Segment = Segment
733
+ new_line = _Segment("\n")
734
+
735
+ line_pointer = "> " if options.legacy_windows else "❱ "
736
+
737
+ (
738
+ background_style,
739
+ number_style,
740
+ highlight_number_style,
741
+ ) = self._get_number_styles(console)
742
+
743
+ for line_no, line in enumerate(lines, self.start_line + line_offset):
744
+ if self.word_wrap:
745
+ wrapped_lines = console.render_lines(
746
+ line,
747
+ render_options.update(height=None, justify="left"),
748
+ style=background_style,
749
+ pad=not transparent_background,
750
+ )
751
+ else:
752
+ segments = list(line.render(console, end=""))
753
+ if options.no_wrap:
754
+ wrapped_lines = [segments]
755
+ else:
756
+ wrapped_lines = [
757
+ _Segment.adjust_line_length(
758
+ segments,
759
+ render_options.max_width,
760
+ style=background_style,
761
+ pad=not transparent_background,
762
+ )
763
+ ]
764
+
765
+ if self.line_numbers:
766
+ wrapped_line_left_pad = _Segment(
767
+ " " * numbers_column_width + " ", background_style
768
+ )
769
+ for first, wrapped_line in loop_first(wrapped_lines):
770
+ if first:
771
+ line_column = str(line_no).rjust(numbers_column_width - 2) + " "
772
+ if highlight_line(line_no):
773
+ yield _Segment(line_pointer, Style(color="red"))
774
+ yield _Segment(line_column, highlight_number_style)
775
+ else:
776
+ yield _Segment(" ", highlight_number_style)
777
+ yield _Segment(line_column, number_style)
778
+ else:
779
+ yield wrapped_line_left_pad
780
+ yield from wrapped_line
781
+ yield new_line
782
+ else:
783
+ for wrapped_line in wrapped_lines:
784
+ yield from wrapped_line
785
+ yield new_line
786
+
787
+ def _apply_stylized_ranges(self, text: Text) -> None:
788
+ """
789
+ Apply stylized ranges to a text instance,
790
+ using the given code to determine the right portion to apply the style to.
791
+
792
+ Args:
793
+ text (Text): Text instance to apply the style to.
794
+ """
795
+ code = text.plain
796
+ newlines_offsets = [
797
+ # Let's add outer boundaries at each side of the list:
798
+ 0,
799
+ # N.B. using "\n" here is much faster than using metacharacters such as "^" or "\Z":
800
+ *[
801
+ match.start() + 1
802
+ for match in re.finditer("\n", code, flags=re.MULTILINE)
803
+ ],
804
+ len(code) + 1,
805
+ ]
806
+
807
+ for stylized_range in self._stylized_ranges:
808
+ start = _get_code_index_for_syntax_position(
809
+ newlines_offsets, stylized_range.start
810
+ )
811
+ end = _get_code_index_for_syntax_position(
812
+ newlines_offsets, stylized_range.end
813
+ )
814
+ if start is not None and end is not None:
815
+ if stylized_range.style_before:
816
+ text.stylize_before(stylized_range.style, start, end)
817
+ else:
818
+ text.stylize(stylized_range.style, start, end)
819
+
820
+ def _process_code(self, code: str) -> Tuple[bool, str]:
821
+ """
822
+ Applies various processing to a raw code string
823
+ (normalises it so it always ends with a line return, dedents it if necessary, etc.)
824
+
825
+ Args:
826
+ code (str): The raw code string to process
827
+
828
+ Returns:
829
+ Tuple[bool, str]: the boolean indicates whether the raw code ends with a line return,
830
+ while the string is the processed code.
831
+ """
832
+ ends_on_nl = code.endswith("\n")
833
+ processed_code = code if ends_on_nl else code + "\n"
834
+ processed_code = (
835
+ textwrap.dedent(processed_code) if self.dedent else processed_code
836
+ )
837
+ processed_code = processed_code.expandtabs(self.tab_size)
838
+ return ends_on_nl, processed_code
839
+
840
+
841
+ def _get_code_index_for_syntax_position(
842
+ newlines_offsets: Sequence[int], position: SyntaxPosition
843
+ ) -> Optional[int]:
844
+ """
845
+ Returns the index of the code string for the given positions.
846
+
847
+ Args:
848
+ newlines_offsets (Sequence[int]): The offset of each newline character found in the code snippet.
849
+ position (SyntaxPosition): The position to search for.
850
+
851
+ Returns:
852
+ Optional[int]: The index of the code string for this position, or `None`
853
+ if the given position's line number is out of range (if it's the column that is out of range
854
+ we silently clamp its value so that it reaches the end of the line)
855
+ """
856
+ lines_count = len(newlines_offsets)
857
+
858
+ line_number, column_index = position
859
+ if line_number > lines_count or len(newlines_offsets) < (line_number + 1):
860
+ return None # `line_number` is out of range
861
+ line_index = line_number - 1
862
+ line_length = newlines_offsets[line_index + 1] - newlines_offsets[line_index] - 1
863
+ # If `column_index` is out of range: let's silently clamp it:
864
+ column_index = min(line_length, column_index)
865
+ return newlines_offsets[line_index] + column_index
866
+
867
+
868
+ if __name__ == "__main__": # pragma: no cover
869
+ import argparse
870
+ import sys
871
+
872
+ parser = argparse.ArgumentParser(
873
+ description="Render syntax to the console with Rich"
874
+ )
875
+ parser.add_argument(
876
+ "path",
877
+ metavar="PATH",
878
+ help="path to file, or - for stdin",
879
+ )
880
+ parser.add_argument(
881
+ "-c",
882
+ "--force-color",
883
+ dest="force_color",
884
+ action="store_true",
885
+ default=None,
886
+ help="force color for non-terminals",
887
+ )
888
+ parser.add_argument(
889
+ "-i",
890
+ "--indent-guides",
891
+ dest="indent_guides",
892
+ action="store_true",
893
+ default=False,
894
+ help="display indent guides",
895
+ )
896
+ parser.add_argument(
897
+ "-l",
898
+ "--line-numbers",
899
+ dest="line_numbers",
900
+ action="store_true",
901
+ help="render line numbers",
902
+ )
903
+ parser.add_argument(
904
+ "-w",
905
+ "--width",
906
+ type=int,
907
+ dest="width",
908
+ default=None,
909
+ help="width of output (default will auto-detect)",
910
+ )
911
+ parser.add_argument(
912
+ "-r",
913
+ "--wrap",
914
+ dest="word_wrap",
915
+ action="store_true",
916
+ default=False,
917
+ help="word wrap long lines",
918
+ )
919
+ parser.add_argument(
920
+ "-s",
921
+ "--soft-wrap",
922
+ action="store_true",
923
+ dest="soft_wrap",
924
+ default=False,
925
+ help="enable soft wrapping mode",
926
+ )
927
+ parser.add_argument(
928
+ "-t", "--theme", dest="theme", default="monokai", help="pygments theme"
929
+ )
930
+ parser.add_argument(
931
+ "-b",
932
+ "--background-color",
933
+ dest="background_color",
934
+ default=None,
935
+ help="Override background color",
936
+ )
937
+ parser.add_argument(
938
+ "-x",
939
+ "--lexer",
940
+ default=None,
941
+ dest="lexer_name",
942
+ help="Lexer name",
943
+ )
944
+ parser.add_argument(
945
+ "-p", "--padding", type=int, default=0, dest="padding", help="Padding"
946
+ )
947
+ parser.add_argument(
948
+ "--highlight-line",
949
+ type=int,
950
+ default=None,
951
+ dest="highlight_line",
952
+ help="The line number (not index!) to highlight",
953
+ )
954
+ args = parser.parse_args()
955
+
956
+ from pip._vendor.rich.console import Console
957
+
958
+ console = Console(force_terminal=args.force_color, width=args.width)
959
+
960
+ if args.path == "-":
961
+ code = sys.stdin.read()
962
+ syntax = Syntax(
963
+ code=code,
964
+ lexer=args.lexer_name,
965
+ line_numbers=args.line_numbers,
966
+ word_wrap=args.word_wrap,
967
+ theme=args.theme,
968
+ background_color=args.background_color,
969
+ indent_guides=args.indent_guides,
970
+ padding=args.padding,
971
+ highlight_lines={args.highlight_line},
972
+ )
973
+ else:
974
+ syntax = Syntax.from_path(
975
+ args.path,
976
+ lexer=args.lexer_name,
977
+ line_numbers=args.line_numbers,
978
+ word_wrap=args.word_wrap,
979
+ theme=args.theme,
980
+ background_color=args.background_color,
981
+ indent_guides=args.indent_guides,
982
+ padding=args.padding,
983
+ highlight_lines={args.highlight_line},
984
+ )
985
+ console.print(syntax, soft_wrap=args.soft_wrap)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/table.py ADDED
@@ -0,0 +1,1006 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field, replace
2
+ from typing import (
3
+ TYPE_CHECKING,
4
+ Dict,
5
+ Iterable,
6
+ List,
7
+ NamedTuple,
8
+ Optional,
9
+ Sequence,
10
+ Tuple,
11
+ Union,
12
+ )
13
+
14
+ from . import box, errors
15
+ from ._loop import loop_first_last, loop_last
16
+ from ._pick import pick_bool
17
+ from ._ratio import ratio_distribute, ratio_reduce
18
+ from .align import VerticalAlignMethod
19
+ from .jupyter import JupyterMixin
20
+ from .measure import Measurement
21
+ from .padding import Padding, PaddingDimensions
22
+ from .protocol import is_renderable
23
+ from .segment import Segment
24
+ from .style import Style, StyleType
25
+ from .text import Text, TextType
26
+
27
+ if TYPE_CHECKING:
28
+ from .console import (
29
+ Console,
30
+ ConsoleOptions,
31
+ JustifyMethod,
32
+ OverflowMethod,
33
+ RenderableType,
34
+ RenderResult,
35
+ )
36
+
37
+
38
+ @dataclass
39
+ class Column:
40
+ """Defines a column within a ~Table.
41
+
42
+ Args:
43
+ title (Union[str, Text], optional): The title of the table rendered at the top. Defaults to None.
44
+ caption (Union[str, Text], optional): The table caption rendered below. Defaults to None.
45
+ width (int, optional): The width in characters of the table, or ``None`` to automatically fit. Defaults to None.
46
+ min_width (Optional[int], optional): The minimum width of the table, or ``None`` for no minimum. Defaults to None.
47
+ box (box.Box, optional): One of the constants in box.py used to draw the edges (see :ref:`appendix_box`), or ``None`` for no box lines. Defaults to box.HEAVY_HEAD.
48
+ safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.
49
+ padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1).
50
+ collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False.
51
+ pad_edge (bool, optional): Enable padding of edge cells. Defaults to True.
52
+ expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False.
53
+ show_header (bool, optional): Show a header row. Defaults to True.
54
+ show_footer (bool, optional): Show a footer row. Defaults to False.
55
+ show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.
56
+ show_lines (bool, optional): Draw lines between every row. Defaults to False.
57
+ leading (int, optional): Number of blank lines between rows (precludes ``show_lines``). Defaults to 0.
58
+ style (Union[str, Style], optional): Default style for the table. Defaults to "none".
59
+ row_styles (List[Union, str], optional): Optional list of row styles, if more than one style is given then the styles will alternate. Defaults to None.
60
+ header_style (Union[str, Style], optional): Style of the header. Defaults to "table.header".
61
+ footer_style (Union[str, Style], optional): Style of the footer. Defaults to "table.footer".
62
+ border_style (Union[str, Style], optional): Style of the border. Defaults to None.
63
+ title_style (Union[str, Style], optional): Style of the title. Defaults to None.
64
+ caption_style (Union[str, Style], optional): Style of the caption. Defaults to None.
65
+ title_justify (str, optional): Justify method for title. Defaults to "center".
66
+ caption_justify (str, optional): Justify method for caption. Defaults to "center".
67
+ highlight (bool, optional): Highlight cell contents (if str). Defaults to False.
68
+ """
69
+
70
+ header: "RenderableType" = ""
71
+ """RenderableType: Renderable for the header (typically a string)"""
72
+
73
+ footer: "RenderableType" = ""
74
+ """RenderableType: Renderable for the footer (typically a string)"""
75
+
76
+ header_style: StyleType = ""
77
+ """StyleType: The style of the header."""
78
+
79
+ footer_style: StyleType = ""
80
+ """StyleType: The style of the footer."""
81
+
82
+ style: StyleType = ""
83
+ """StyleType: The style of the column."""
84
+
85
+ justify: "JustifyMethod" = "left"
86
+ """str: How to justify text within the column ("left", "center", "right", or "full")"""
87
+
88
+ vertical: "VerticalAlignMethod" = "top"
89
+ """str: How to vertically align content ("top", "middle", or "bottom")"""
90
+
91
+ overflow: "OverflowMethod" = "ellipsis"
92
+ """str: Overflow method."""
93
+
94
+ width: Optional[int] = None
95
+ """Optional[int]: Width of the column, or ``None`` (default) to auto calculate width."""
96
+
97
+ min_width: Optional[int] = None
98
+ """Optional[int]: Minimum width of column, or ``None`` for no minimum. Defaults to None."""
99
+
100
+ max_width: Optional[int] = None
101
+ """Optional[int]: Maximum width of column, or ``None`` for no maximum. Defaults to None."""
102
+
103
+ ratio: Optional[int] = None
104
+ """Optional[int]: Ratio to use when calculating column width, or ``None`` (default) to adapt to column contents."""
105
+
106
+ no_wrap: bool = False
107
+ """bool: Prevent wrapping of text within the column. Defaults to ``False``."""
108
+
109
+ highlight: bool = False
110
+ """bool: Apply highlighter to column. Defaults to ``False``."""
111
+
112
+ _index: int = 0
113
+ """Index of column."""
114
+
115
+ _cells: List["RenderableType"] = field(default_factory=list)
116
+
117
+ def copy(self) -> "Column":
118
+ """Return a copy of this Column."""
119
+ return replace(self, _cells=[])
120
+
121
+ @property
122
+ def cells(self) -> Iterable["RenderableType"]:
123
+ """Get all cells in the column, not including header."""
124
+ yield from self._cells
125
+
126
+ @property
127
+ def flexible(self) -> bool:
128
+ """Check if this column is flexible."""
129
+ return self.ratio is not None
130
+
131
+
132
+ @dataclass
133
+ class Row:
134
+ """Information regarding a row."""
135
+
136
+ style: Optional[StyleType] = None
137
+ """Style to apply to row."""
138
+
139
+ end_section: bool = False
140
+ """Indicated end of section, which will force a line beneath the row."""
141
+
142
+
143
+ class _Cell(NamedTuple):
144
+ """A single cell in a table."""
145
+
146
+ style: StyleType
147
+ """Style to apply to cell."""
148
+ renderable: "RenderableType"
149
+ """Cell renderable."""
150
+ vertical: VerticalAlignMethod
151
+ """Cell vertical alignment."""
152
+
153
+
154
+ class Table(JupyterMixin):
155
+ """A console renderable to draw a table.
156
+
157
+ Args:
158
+ *headers (Union[Column, str]): Column headers, either as a string, or :class:`~rich.table.Column` instance.
159
+ title (Union[str, Text], optional): The title of the table rendered at the top. Defaults to None.
160
+ caption (Union[str, Text], optional): The table caption rendered below. Defaults to None.
161
+ width (int, optional): The width in characters of the table, or ``None`` to automatically fit. Defaults to None.
162
+ min_width (Optional[int], optional): The minimum width of the table, or ``None`` for no minimum. Defaults to None.
163
+ box (box.Box, optional): One of the constants in box.py used to draw the edges (see :ref:`appendix_box`), or ``None`` for no box lines. Defaults to box.HEAVY_HEAD.
164
+ safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.
165
+ padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1).
166
+ collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False.
167
+ pad_edge (bool, optional): Enable padding of edge cells. Defaults to True.
168
+ expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False.
169
+ show_header (bool, optional): Show a header row. Defaults to True.
170
+ show_footer (bool, optional): Show a footer row. Defaults to False.
171
+ show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.
172
+ show_lines (bool, optional): Draw lines between every row. Defaults to False.
173
+ leading (int, optional): Number of blank lines between rows (precludes ``show_lines``). Defaults to 0.
174
+ style (Union[str, Style], optional): Default style for the table. Defaults to "none".
175
+ row_styles (List[Union, str], optional): Optional list of row styles, if more than one style is given then the styles will alternate. Defaults to None.
176
+ header_style (Union[str, Style], optional): Style of the header. Defaults to "table.header".
177
+ footer_style (Union[str, Style], optional): Style of the footer. Defaults to "table.footer".
178
+ border_style (Union[str, Style], optional): Style of the border. Defaults to None.
179
+ title_style (Union[str, Style], optional): Style of the title. Defaults to None.
180
+ caption_style (Union[str, Style], optional): Style of the caption. Defaults to None.
181
+ title_justify (str, optional): Justify method for title. Defaults to "center".
182
+ caption_justify (str, optional): Justify method for caption. Defaults to "center".
183
+ highlight (bool, optional): Highlight cell contents (if str). Defaults to False.
184
+ """
185
+
186
+ columns: List[Column]
187
+ rows: List[Row]
188
+
189
+ def __init__(
190
+ self,
191
+ *headers: Union[Column, str],
192
+ title: Optional[TextType] = None,
193
+ caption: Optional[TextType] = None,
194
+ width: Optional[int] = None,
195
+ min_width: Optional[int] = None,
196
+ box: Optional[box.Box] = box.HEAVY_HEAD,
197
+ safe_box: Optional[bool] = None,
198
+ padding: PaddingDimensions = (0, 1),
199
+ collapse_padding: bool = False,
200
+ pad_edge: bool = True,
201
+ expand: bool = False,
202
+ show_header: bool = True,
203
+ show_footer: bool = False,
204
+ show_edge: bool = True,
205
+ show_lines: bool = False,
206
+ leading: int = 0,
207
+ style: StyleType = "none",
208
+ row_styles: Optional[Iterable[StyleType]] = None,
209
+ header_style: Optional[StyleType] = "table.header",
210
+ footer_style: Optional[StyleType] = "table.footer",
211
+ border_style: Optional[StyleType] = None,
212
+ title_style: Optional[StyleType] = None,
213
+ caption_style: Optional[StyleType] = None,
214
+ title_justify: "JustifyMethod" = "center",
215
+ caption_justify: "JustifyMethod" = "center",
216
+ highlight: bool = False,
217
+ ) -> None:
218
+ self.columns: List[Column] = []
219
+ self.rows: List[Row] = []
220
+ self.title = title
221
+ self.caption = caption
222
+ self.width = width
223
+ self.min_width = min_width
224
+ self.box = box
225
+ self.safe_box = safe_box
226
+ self._padding = Padding.unpack(padding)
227
+ self.pad_edge = pad_edge
228
+ self._expand = expand
229
+ self.show_header = show_header
230
+ self.show_footer = show_footer
231
+ self.show_edge = show_edge
232
+ self.show_lines = show_lines
233
+ self.leading = leading
234
+ self.collapse_padding = collapse_padding
235
+ self.style = style
236
+ self.header_style = header_style or ""
237
+ self.footer_style = footer_style or ""
238
+ self.border_style = border_style
239
+ self.title_style = title_style
240
+ self.caption_style = caption_style
241
+ self.title_justify: "JustifyMethod" = title_justify
242
+ self.caption_justify: "JustifyMethod" = caption_justify
243
+ self.highlight = highlight
244
+ self.row_styles: Sequence[StyleType] = list(row_styles or [])
245
+ append_column = self.columns.append
246
+ for header in headers:
247
+ if isinstance(header, str):
248
+ self.add_column(header=header)
249
+ else:
250
+ header._index = len(self.columns)
251
+ append_column(header)
252
+
253
+ @classmethod
254
+ def grid(
255
+ cls,
256
+ *headers: Union[Column, str],
257
+ padding: PaddingDimensions = 0,
258
+ collapse_padding: bool = True,
259
+ pad_edge: bool = False,
260
+ expand: bool = False,
261
+ ) -> "Table":
262
+ """Get a table with no lines, headers, or footer.
263
+
264
+ Args:
265
+ *headers (Union[Column, str]): Column headers, either as a string, or :class:`~rich.table.Column` instance.
266
+ padding (PaddingDimensions, optional): Get padding around cells. Defaults to 0.
267
+ collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to True.
268
+ pad_edge (bool, optional): Enable padding around edges of table. Defaults to False.
269
+ expand (bool, optional): Expand the table to fit the available space if ``True``, otherwise the table width will be auto-calculated. Defaults to False.
270
+
271
+ Returns:
272
+ Table: A table instance.
273
+ """
274
+ return cls(
275
+ *headers,
276
+ box=None,
277
+ padding=padding,
278
+ collapse_padding=collapse_padding,
279
+ show_header=False,
280
+ show_footer=False,
281
+ show_edge=False,
282
+ pad_edge=pad_edge,
283
+ expand=expand,
284
+ )
285
+
286
+ @property
287
+ def expand(self) -> bool:
288
+ """Setting a non-None self.width implies expand."""
289
+ return self._expand or self.width is not None
290
+
291
+ @expand.setter
292
+ def expand(self, expand: bool) -> None:
293
+ """Set expand."""
294
+ self._expand = expand
295
+
296
+ @property
297
+ def _extra_width(self) -> int:
298
+ """Get extra width to add to cell content."""
299
+ width = 0
300
+ if self.box and self.show_edge:
301
+ width += 2
302
+ if self.box:
303
+ width += len(self.columns) - 1
304
+ return width
305
+
306
+ @property
307
+ def row_count(self) -> int:
308
+ """Get the current number of rows."""
309
+ return len(self.rows)
310
+
311
+ def get_row_style(self, console: "Console", index: int) -> StyleType:
312
+ """Get the current row style."""
313
+ style = Style.null()
314
+ if self.row_styles:
315
+ style += console.get_style(self.row_styles[index % len(self.row_styles)])
316
+ row_style = self.rows[index].style
317
+ if row_style is not None:
318
+ style += console.get_style(row_style)
319
+ return style
320
+
321
+ def __rich_measure__(
322
+ self, console: "Console", options: "ConsoleOptions"
323
+ ) -> Measurement:
324
+ max_width = options.max_width
325
+ if self.width is not None:
326
+ max_width = self.width
327
+ if max_width < 0:
328
+ return Measurement(0, 0)
329
+
330
+ extra_width = self._extra_width
331
+ max_width = sum(
332
+ self._calculate_column_widths(
333
+ console, options.update_width(max_width - extra_width)
334
+ )
335
+ )
336
+ _measure_column = self._measure_column
337
+
338
+ measurements = [
339
+ _measure_column(console, options.update_width(max_width), column)
340
+ for column in self.columns
341
+ ]
342
+ minimum_width = (
343
+ sum(measurement.minimum for measurement in measurements) + extra_width
344
+ )
345
+ maximum_width = (
346
+ sum(measurement.maximum for measurement in measurements) + extra_width
347
+ if (self.width is None)
348
+ else self.width
349
+ )
350
+ measurement = Measurement(minimum_width, maximum_width)
351
+ measurement = measurement.clamp(self.min_width)
352
+ return measurement
353
+
354
+ @property
355
+ def padding(self) -> Tuple[int, int, int, int]:
356
+ """Get cell padding."""
357
+ return self._padding
358
+
359
+ @padding.setter
360
+ def padding(self, padding: PaddingDimensions) -> "Table":
361
+ """Set cell padding."""
362
+ self._padding = Padding.unpack(padding)
363
+ return self
364
+
365
+ def add_column(
366
+ self,
367
+ header: "RenderableType" = "",
368
+ footer: "RenderableType" = "",
369
+ *,
370
+ header_style: Optional[StyleType] = None,
371
+ highlight: Optional[bool] = None,
372
+ footer_style: Optional[StyleType] = None,
373
+ style: Optional[StyleType] = None,
374
+ justify: "JustifyMethod" = "left",
375
+ vertical: "VerticalAlignMethod" = "top",
376
+ overflow: "OverflowMethod" = "ellipsis",
377
+ width: Optional[int] = None,
378
+ min_width: Optional[int] = None,
379
+ max_width: Optional[int] = None,
380
+ ratio: Optional[int] = None,
381
+ no_wrap: bool = False,
382
+ ) -> None:
383
+ """Add a column to the table.
384
+
385
+ Args:
386
+ header (RenderableType, optional): Text or renderable for the header.
387
+ Defaults to "".
388
+ footer (RenderableType, optional): Text or renderable for the footer.
389
+ Defaults to "".
390
+ header_style (Union[str, Style], optional): Style for the header, or None for default. Defaults to None.
391
+ highlight (bool, optional): Whether to highlight the text. The default of None uses the value of the table (self) object.
392
+ footer_style (Union[str, Style], optional): Style for the footer, or None for default. Defaults to None.
393
+ style (Union[str, Style], optional): Style for the column cells, or None for default. Defaults to None.
394
+ justify (JustifyMethod, optional): Alignment for cells. Defaults to "left".
395
+ vertical (VerticalAlignMethod, optional): Vertical alignment, one of "top", "middle", or "bottom". Defaults to "top".
396
+ overflow (OverflowMethod): Overflow method: "crop", "fold", "ellipsis". Defaults to "ellipsis".
397
+ width (int, optional): Desired width of column in characters, or None to fit to contents. Defaults to None.
398
+ min_width (Optional[int], optional): Minimum width of column, or ``None`` for no minimum. Defaults to None.
399
+ max_width (Optional[int], optional): Maximum width of column, or ``None`` for no maximum. Defaults to None.
400
+ ratio (int, optional): Flexible ratio for the column (requires ``Table.expand`` or ``Table.width``). Defaults to None.
401
+ no_wrap (bool, optional): Set to ``True`` to disable wrapping of this column.
402
+ """
403
+
404
+ column = Column(
405
+ _index=len(self.columns),
406
+ header=header,
407
+ footer=footer,
408
+ header_style=header_style or "",
409
+ highlight=highlight if highlight is not None else self.highlight,
410
+ footer_style=footer_style or "",
411
+ style=style or "",
412
+ justify=justify,
413
+ vertical=vertical,
414
+ overflow=overflow,
415
+ width=width,
416
+ min_width=min_width,
417
+ max_width=max_width,
418
+ ratio=ratio,
419
+ no_wrap=no_wrap,
420
+ )
421
+ self.columns.append(column)
422
+
423
+ def add_row(
424
+ self,
425
+ *renderables: Optional["RenderableType"],
426
+ style: Optional[StyleType] = None,
427
+ end_section: bool = False,
428
+ ) -> None:
429
+ """Add a row of renderables.
430
+
431
+ Args:
432
+ *renderables (None or renderable): Each cell in a row must be a renderable object (including str),
433
+ or ``None`` for a blank cell.
434
+ style (StyleType, optional): An optional style to apply to the entire row. Defaults to None.
435
+ end_section (bool, optional): End a section and draw a line. Defaults to False.
436
+
437
+ Raises:
438
+ errors.NotRenderableError: If you add something that can't be rendered.
439
+ """
440
+
441
+ def add_cell(column: Column, renderable: "RenderableType") -> None:
442
+ column._cells.append(renderable)
443
+
444
+ cell_renderables: List[Optional["RenderableType"]] = list(renderables)
445
+
446
+ columns = self.columns
447
+ if len(cell_renderables) < len(columns):
448
+ cell_renderables = [
449
+ *cell_renderables,
450
+ *[None] * (len(columns) - len(cell_renderables)),
451
+ ]
452
+ for index, renderable in enumerate(cell_renderables):
453
+ if index == len(columns):
454
+ column = Column(_index=index, highlight=self.highlight)
455
+ for _ in self.rows:
456
+ add_cell(column, Text(""))
457
+ self.columns.append(column)
458
+ else:
459
+ column = columns[index]
460
+ if renderable is None:
461
+ add_cell(column, "")
462
+ elif is_renderable(renderable):
463
+ add_cell(column, renderable)
464
+ else:
465
+ raise errors.NotRenderableError(
466
+ f"unable to render {type(renderable).__name__}; a string or other renderable object is required"
467
+ )
468
+ self.rows.append(Row(style=style, end_section=end_section))
469
+
470
+ def add_section(self) -> None:
471
+ """Add a new section (draw a line after current row)."""
472
+
473
+ if self.rows:
474
+ self.rows[-1].end_section = True
475
+
476
+ def __rich_console__(
477
+ self, console: "Console", options: "ConsoleOptions"
478
+ ) -> "RenderResult":
479
+ if not self.columns:
480
+ yield Segment("\n")
481
+ return
482
+
483
+ max_width = options.max_width
484
+ if self.width is not None:
485
+ max_width = self.width
486
+
487
+ extra_width = self._extra_width
488
+ widths = self._calculate_column_widths(
489
+ console, options.update_width(max_width - extra_width)
490
+ )
491
+ table_width = sum(widths) + extra_width
492
+
493
+ render_options = options.update(
494
+ width=table_width, highlight=self.highlight, height=None
495
+ )
496
+
497
+ def render_annotation(
498
+ text: TextType, style: StyleType, justify: "JustifyMethod" = "center"
499
+ ) -> "RenderResult":
500
+ render_text = (
501
+ console.render_str(text, style=style, highlight=False)
502
+ if isinstance(text, str)
503
+ else text
504
+ )
505
+ return console.render(
506
+ render_text, options=render_options.update(justify=justify)
507
+ )
508
+
509
+ if self.title:
510
+ yield from render_annotation(
511
+ self.title,
512
+ style=Style.pick_first(self.title_style, "table.title"),
513
+ justify=self.title_justify,
514
+ )
515
+ yield from self._render(console, render_options, widths)
516
+ if self.caption:
517
+ yield from render_annotation(
518
+ self.caption,
519
+ style=Style.pick_first(self.caption_style, "table.caption"),
520
+ justify=self.caption_justify,
521
+ )
522
+
523
+ def _calculate_column_widths(
524
+ self, console: "Console", options: "ConsoleOptions"
525
+ ) -> List[int]:
526
+ """Calculate the widths of each column, including padding, not including borders."""
527
+ max_width = options.max_width
528
+ columns = self.columns
529
+ width_ranges = [
530
+ self._measure_column(console, options, column) for column in columns
531
+ ]
532
+ widths = [_range.maximum or 1 for _range in width_ranges]
533
+ get_padding_width = self._get_padding_width
534
+ extra_width = self._extra_width
535
+ if self.expand:
536
+ ratios = [col.ratio or 0 for col in columns if col.flexible]
537
+ if any(ratios):
538
+ fixed_widths = [
539
+ 0 if column.flexible else _range.maximum
540
+ for _range, column in zip(width_ranges, columns)
541
+ ]
542
+ flex_minimum = [
543
+ (column.width or 1) + get_padding_width(column._index)
544
+ for column in columns
545
+ if column.flexible
546
+ ]
547
+ flexible_width = max_width - sum(fixed_widths)
548
+ flex_widths = ratio_distribute(flexible_width, ratios, flex_minimum)
549
+ iter_flex_widths = iter(flex_widths)
550
+ for index, column in enumerate(columns):
551
+ if column.flexible:
552
+ widths[index] = fixed_widths[index] + next(iter_flex_widths)
553
+ table_width = sum(widths)
554
+
555
+ if table_width > max_width:
556
+ widths = self._collapse_widths(
557
+ widths,
558
+ [(column.width is None and not column.no_wrap) for column in columns],
559
+ max_width,
560
+ )
561
+ table_width = sum(widths)
562
+ # last resort, reduce columns evenly
563
+ if table_width > max_width:
564
+ excess_width = table_width - max_width
565
+ widths = ratio_reduce(excess_width, [1] * len(widths), widths, widths)
566
+ table_width = sum(widths)
567
+
568
+ width_ranges = [
569
+ self._measure_column(console, options.update_width(width), column)
570
+ for width, column in zip(widths, columns)
571
+ ]
572
+ widths = [_range.maximum or 0 for _range in width_ranges]
573
+
574
+ if (table_width < max_width and self.expand) or (
575
+ self.min_width is not None and table_width < (self.min_width - extra_width)
576
+ ):
577
+ _max_width = (
578
+ max_width
579
+ if self.min_width is None
580
+ else min(self.min_width - extra_width, max_width)
581
+ )
582
+ pad_widths = ratio_distribute(_max_width - table_width, widths)
583
+ widths = [_width + pad for _width, pad in zip(widths, pad_widths)]
584
+
585
+ return widths
586
+
587
+ @classmethod
588
+ def _collapse_widths(
589
+ cls, widths: List[int], wrapable: List[bool], max_width: int
590
+ ) -> List[int]:
591
+ """Reduce widths so that the total is under max_width.
592
+
593
+ Args:
594
+ widths (List[int]): List of widths.
595
+ wrapable (List[bool]): List of booleans that indicate if a column may shrink.
596
+ max_width (int): Maximum width to reduce to.
597
+
598
+ Returns:
599
+ List[int]: A new list of widths.
600
+ """
601
+ total_width = sum(widths)
602
+ excess_width = total_width - max_width
603
+ if any(wrapable):
604
+ while total_width and excess_width > 0:
605
+ max_column = max(
606
+ width for width, allow_wrap in zip(widths, wrapable) if allow_wrap
607
+ )
608
+ second_max_column = max(
609
+ width if allow_wrap and width != max_column else 0
610
+ for width, allow_wrap in zip(widths, wrapable)
611
+ )
612
+ column_difference = max_column - second_max_column
613
+ ratios = [
614
+ (1 if (width == max_column and allow_wrap) else 0)
615
+ for width, allow_wrap in zip(widths, wrapable)
616
+ ]
617
+ if not any(ratios) or not column_difference:
618
+ break
619
+ max_reduce = [min(excess_width, column_difference)] * len(widths)
620
+ widths = ratio_reduce(excess_width, ratios, max_reduce, widths)
621
+
622
+ total_width = sum(widths)
623
+ excess_width = total_width - max_width
624
+ return widths
625
+
626
+ def _get_cells(
627
+ self, console: "Console", column_index: int, column: Column
628
+ ) -> Iterable[_Cell]:
629
+ """Get all the cells with padding and optional header."""
630
+
631
+ collapse_padding = self.collapse_padding
632
+ pad_edge = self.pad_edge
633
+ padding = self.padding
634
+ any_padding = any(padding)
635
+
636
+ first_column = column_index == 0
637
+ last_column = column_index == len(self.columns) - 1
638
+
639
+ _padding_cache: Dict[Tuple[bool, bool], Tuple[int, int, int, int]] = {}
640
+
641
+ def get_padding(first_row: bool, last_row: bool) -> Tuple[int, int, int, int]:
642
+ cached = _padding_cache.get((first_row, last_row))
643
+ if cached:
644
+ return cached
645
+ top, right, bottom, left = padding
646
+
647
+ if collapse_padding:
648
+ if not first_column:
649
+ left = max(0, left - right)
650
+ if not last_row:
651
+ bottom = max(0, top - bottom)
652
+
653
+ if not pad_edge:
654
+ if first_column:
655
+ left = 0
656
+ if last_column:
657
+ right = 0
658
+ if first_row:
659
+ top = 0
660
+ if last_row:
661
+ bottom = 0
662
+ _padding = (top, right, bottom, left)
663
+ _padding_cache[(first_row, last_row)] = _padding
664
+ return _padding
665
+
666
+ raw_cells: List[Tuple[StyleType, "RenderableType"]] = []
667
+ _append = raw_cells.append
668
+ get_style = console.get_style
669
+ if self.show_header:
670
+ header_style = get_style(self.header_style or "") + get_style(
671
+ column.header_style
672
+ )
673
+ _append((header_style, column.header))
674
+ cell_style = get_style(column.style or "")
675
+ for cell in column.cells:
676
+ _append((cell_style, cell))
677
+ if self.show_footer:
678
+ footer_style = get_style(self.footer_style or "") + get_style(
679
+ column.footer_style
680
+ )
681
+ _append((footer_style, column.footer))
682
+
683
+ if any_padding:
684
+ _Padding = Padding
685
+ for first, last, (style, renderable) in loop_first_last(raw_cells):
686
+ yield _Cell(
687
+ style,
688
+ _Padding(renderable, get_padding(first, last)),
689
+ getattr(renderable, "vertical", None) or column.vertical,
690
+ )
691
+ else:
692
+ for style, renderable in raw_cells:
693
+ yield _Cell(
694
+ style,
695
+ renderable,
696
+ getattr(renderable, "vertical", None) or column.vertical,
697
+ )
698
+
699
+ def _get_padding_width(self, column_index: int) -> int:
700
+ """Get extra width from padding."""
701
+ _, pad_right, _, pad_left = self.padding
702
+ if self.collapse_padding:
703
+ if column_index > 0:
704
+ pad_left = max(0, pad_left - pad_right)
705
+ return pad_left + pad_right
706
+
707
+ def _measure_column(
708
+ self,
709
+ console: "Console",
710
+ options: "ConsoleOptions",
711
+ column: Column,
712
+ ) -> Measurement:
713
+ """Get the minimum and maximum width of the column."""
714
+
715
+ max_width = options.max_width
716
+ if max_width < 1:
717
+ return Measurement(0, 0)
718
+
719
+ padding_width = self._get_padding_width(column._index)
720
+
721
+ if column.width is not None:
722
+ # Fixed width column
723
+ return Measurement(
724
+ column.width + padding_width, column.width + padding_width
725
+ ).with_maximum(max_width)
726
+ # Flexible column, we need to measure contents
727
+ min_widths: List[int] = []
728
+ max_widths: List[int] = []
729
+ append_min = min_widths.append
730
+ append_max = max_widths.append
731
+ get_render_width = Measurement.get
732
+ for cell in self._get_cells(console, column._index, column):
733
+ _min, _max = get_render_width(console, options, cell.renderable)
734
+ append_min(_min)
735
+ append_max(_max)
736
+
737
+ measurement = Measurement(
738
+ max(min_widths) if min_widths else 1,
739
+ max(max_widths) if max_widths else max_width,
740
+ ).with_maximum(max_width)
741
+ measurement = measurement.clamp(
742
+ None if column.min_width is None else column.min_width + padding_width,
743
+ None if column.max_width is None else column.max_width + padding_width,
744
+ )
745
+ return measurement
746
+
747
+ def _render(
748
+ self, console: "Console", options: "ConsoleOptions", widths: List[int]
749
+ ) -> "RenderResult":
750
+ table_style = console.get_style(self.style or "")
751
+
752
+ border_style = table_style + console.get_style(self.border_style or "")
753
+ _column_cells = (
754
+ self._get_cells(console, column_index, column)
755
+ for column_index, column in enumerate(self.columns)
756
+ )
757
+ row_cells: List[Tuple[_Cell, ...]] = list(zip(*_column_cells))
758
+ _box = (
759
+ self.box.substitute(
760
+ options, safe=pick_bool(self.safe_box, console.safe_box)
761
+ )
762
+ if self.box
763
+ else None
764
+ )
765
+ _box = _box.get_plain_headed_box() if _box and not self.show_header else _box
766
+
767
+ new_line = Segment.line()
768
+
769
+ columns = self.columns
770
+ show_header = self.show_header
771
+ show_footer = self.show_footer
772
+ show_edge = self.show_edge
773
+ show_lines = self.show_lines
774
+ leading = self.leading
775
+
776
+ _Segment = Segment
777
+ if _box:
778
+ box_segments = [
779
+ (
780
+ _Segment(_box.head_left, border_style),
781
+ _Segment(_box.head_right, border_style),
782
+ _Segment(_box.head_vertical, border_style),
783
+ ),
784
+ (
785
+ _Segment(_box.mid_left, border_style),
786
+ _Segment(_box.mid_right, border_style),
787
+ _Segment(_box.mid_vertical, border_style),
788
+ ),
789
+ (
790
+ _Segment(_box.foot_left, border_style),
791
+ _Segment(_box.foot_right, border_style),
792
+ _Segment(_box.foot_vertical, border_style),
793
+ ),
794
+ ]
795
+ if show_edge:
796
+ yield _Segment(_box.get_top(widths), border_style)
797
+ yield new_line
798
+ else:
799
+ box_segments = []
800
+
801
+ get_row_style = self.get_row_style
802
+ get_style = console.get_style
803
+
804
+ for index, (first, last, row_cell) in enumerate(loop_first_last(row_cells)):
805
+ header_row = first and show_header
806
+ footer_row = last and show_footer
807
+ row = (
808
+ self.rows[index - show_header]
809
+ if (not header_row and not footer_row)
810
+ else None
811
+ )
812
+ max_height = 1
813
+ cells: List[List[List[Segment]]] = []
814
+ if header_row or footer_row:
815
+ row_style = Style.null()
816
+ else:
817
+ row_style = get_style(
818
+ get_row_style(console, index - 1 if show_header else index)
819
+ )
820
+ for width, cell, column in zip(widths, row_cell, columns):
821
+ render_options = options.update(
822
+ width=width,
823
+ justify=column.justify,
824
+ no_wrap=column.no_wrap,
825
+ overflow=column.overflow,
826
+ height=None,
827
+ highlight=column.highlight,
828
+ )
829
+ lines = console.render_lines(
830
+ cell.renderable,
831
+ render_options,
832
+ style=get_style(cell.style) + row_style,
833
+ )
834
+ max_height = max(max_height, len(lines))
835
+ cells.append(lines)
836
+
837
+ row_height = max(len(cell) for cell in cells)
838
+
839
+ def align_cell(
840
+ cell: List[List[Segment]],
841
+ vertical: "VerticalAlignMethod",
842
+ width: int,
843
+ style: Style,
844
+ ) -> List[List[Segment]]:
845
+ if header_row:
846
+ vertical = "bottom"
847
+ elif footer_row:
848
+ vertical = "top"
849
+
850
+ if vertical == "top":
851
+ return _Segment.align_top(cell, width, row_height, style)
852
+ elif vertical == "middle":
853
+ return _Segment.align_middle(cell, width, row_height, style)
854
+ return _Segment.align_bottom(cell, width, row_height, style)
855
+
856
+ cells[:] = [
857
+ _Segment.set_shape(
858
+ align_cell(
859
+ cell,
860
+ _cell.vertical,
861
+ width,
862
+ get_style(_cell.style) + row_style,
863
+ ),
864
+ width,
865
+ max_height,
866
+ )
867
+ for width, _cell, cell, column in zip(widths, row_cell, cells, columns)
868
+ ]
869
+
870
+ if _box:
871
+ if last and show_footer:
872
+ yield _Segment(
873
+ _box.get_row(widths, "foot", edge=show_edge), border_style
874
+ )
875
+ yield new_line
876
+ left, right, _divider = box_segments[0 if first else (2 if last else 1)]
877
+
878
+ # If the column divider is whitespace also style it with the row background
879
+ divider = (
880
+ _divider
881
+ if _divider.text.strip()
882
+ else _Segment(
883
+ _divider.text, row_style.background_style + _divider.style
884
+ )
885
+ )
886
+ for line_no in range(max_height):
887
+ if show_edge:
888
+ yield left
889
+ for last_cell, rendered_cell in loop_last(cells):
890
+ yield from rendered_cell[line_no]
891
+ if not last_cell:
892
+ yield divider
893
+ if show_edge:
894
+ yield right
895
+ yield new_line
896
+ else:
897
+ for line_no in range(max_height):
898
+ for rendered_cell in cells:
899
+ yield from rendered_cell[line_no]
900
+ yield new_line
901
+ if _box and first and show_header:
902
+ yield _Segment(
903
+ _box.get_row(widths, "head", edge=show_edge), border_style
904
+ )
905
+ yield new_line
906
+ end_section = row and row.end_section
907
+ if _box and (show_lines or leading or end_section):
908
+ if (
909
+ not last
910
+ and not (show_footer and index >= len(row_cells) - 2)
911
+ and not (show_header and header_row)
912
+ ):
913
+ if leading:
914
+ yield _Segment(
915
+ _box.get_row(widths, "mid", edge=show_edge) * leading,
916
+ border_style,
917
+ )
918
+ else:
919
+ yield _Segment(
920
+ _box.get_row(widths, "row", edge=show_edge), border_style
921
+ )
922
+ yield new_line
923
+
924
+ if _box and show_edge:
925
+ yield _Segment(_box.get_bottom(widths), border_style)
926
+ yield new_line
927
+
928
+
929
+ if __name__ == "__main__": # pragma: no cover
930
+ from pip._vendor.rich.console import Console
931
+ from pip._vendor.rich.highlighter import ReprHighlighter
932
+
933
+ from ._timer import timer
934
+
935
+ with timer("Table render"):
936
+ table = Table(
937
+ title="Star Wars Movies",
938
+ caption="Rich example table",
939
+ caption_justify="right",
940
+ )
941
+
942
+ table.add_column(
943
+ "Released", header_style="bright_cyan", style="cyan", no_wrap=True
944
+ )
945
+ table.add_column("Title", style="magenta")
946
+ table.add_column("Box Office", justify="right", style="green")
947
+
948
+ table.add_row(
949
+ "Dec 20, 2019",
950
+ "Star Wars: The Rise of Skywalker",
951
+ "$952,110,690",
952
+ )
953
+ table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347")
954
+ table.add_row(
955
+ "Dec 15, 2017",
956
+ "Star Wars Ep. V111: The Last Jedi",
957
+ "$1,332,539,889",
958
+ style="on black",
959
+ end_section=True,
960
+ )
961
+ table.add_row(
962
+ "Dec 16, 2016",
963
+ "Rogue One: A Star Wars Story",
964
+ "$1,332,439,889",
965
+ )
966
+
967
+ def header(text: str) -> None:
968
+ console.print()
969
+ console.rule(highlight(text))
970
+ console.print()
971
+
972
+ console = Console()
973
+ highlight = ReprHighlighter()
974
+ header("Example Table")
975
+ console.print(table, justify="center")
976
+
977
+ table.expand = True
978
+ header("expand=True")
979
+ console.print(table)
980
+
981
+ table.width = 50
982
+ header("width=50")
983
+
984
+ console.print(table, justify="center")
985
+
986
+ table.width = None
987
+ table.expand = False
988
+ table.row_styles = ["dim", "none"]
989
+ header("row_styles=['dim', 'none']")
990
+
991
+ console.print(table, justify="center")
992
+
993
+ table.width = None
994
+ table.expand = False
995
+ table.row_styles = ["dim", "none"]
996
+ table.leading = 1
997
+ header("leading=1, row_styles=['dim', 'none']")
998
+ console.print(table, justify="center")
999
+
1000
+ table.width = None
1001
+ table.expand = False
1002
+ table.row_styles = ["dim", "none"]
1003
+ table.show_lines = True
1004
+ table.leading = 0
1005
+ header("show_lines=True, row_styles=['dim', 'none']")
1006
+ console.print(table, justify="center")
.venv/lib/python3.12/site-packages/pip/_vendor/rich/terminal_theme.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ from .color_triplet import ColorTriplet
4
+ from .palette import Palette
5
+
6
+ _ColorTuple = Tuple[int, int, int]
7
+
8
+
9
+ class TerminalTheme:
10
+ """A color theme used when exporting console content.
11
+
12
+ Args:
13
+ background (Tuple[int, int, int]): The background color.
14
+ foreground (Tuple[int, int, int]): The foreground (text) color.
15
+ normal (List[Tuple[int, int, int]]): A list of 8 normal intensity colors.
16
+ bright (List[Tuple[int, int, int]], optional): A list of 8 bright colors, or None
17
+ to repeat normal intensity. Defaults to None.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ background: _ColorTuple,
23
+ foreground: _ColorTuple,
24
+ normal: List[_ColorTuple],
25
+ bright: Optional[List[_ColorTuple]] = None,
26
+ ) -> None:
27
+ self.background_color = ColorTriplet(*background)
28
+ self.foreground_color = ColorTriplet(*foreground)
29
+ self.ansi_colors = Palette(normal + (bright or normal))
30
+
31
+
32
+ DEFAULT_TERMINAL_THEME = TerminalTheme(
33
+ (255, 255, 255),
34
+ (0, 0, 0),
35
+ [
36
+ (0, 0, 0),
37
+ (128, 0, 0),
38
+ (0, 128, 0),
39
+ (128, 128, 0),
40
+ (0, 0, 128),
41
+ (128, 0, 128),
42
+ (0, 128, 128),
43
+ (192, 192, 192),
44
+ ],
45
+ [
46
+ (128, 128, 128),
47
+ (255, 0, 0),
48
+ (0, 255, 0),
49
+ (255, 255, 0),
50
+ (0, 0, 255),
51
+ (255, 0, 255),
52
+ (0, 255, 255),
53
+ (255, 255, 255),
54
+ ],
55
+ )
56
+
57
+ MONOKAI = TerminalTheme(
58
+ (12, 12, 12),
59
+ (217, 217, 217),
60
+ [
61
+ (26, 26, 26),
62
+ (244, 0, 95),
63
+ (152, 224, 36),
64
+ (253, 151, 31),
65
+ (157, 101, 255),
66
+ (244, 0, 95),
67
+ (88, 209, 235),
68
+ (196, 197, 181),
69
+ (98, 94, 76),
70
+ ],
71
+ [
72
+ (244, 0, 95),
73
+ (152, 224, 36),
74
+ (224, 213, 97),
75
+ (157, 101, 255),
76
+ (244, 0, 95),
77
+ (88, 209, 235),
78
+ (246, 246, 239),
79
+ ],
80
+ )
81
+ DIMMED_MONOKAI = TerminalTheme(
82
+ (25, 25, 25),
83
+ (185, 188, 186),
84
+ [
85
+ (58, 61, 67),
86
+ (190, 63, 72),
87
+ (135, 154, 59),
88
+ (197, 166, 53),
89
+ (79, 118, 161),
90
+ (133, 92, 141),
91
+ (87, 143, 164),
92
+ (185, 188, 186),
93
+ (136, 137, 135),
94
+ ],
95
+ [
96
+ (251, 0, 31),
97
+ (15, 114, 47),
98
+ (196, 112, 51),
99
+ (24, 109, 227),
100
+ (251, 0, 103),
101
+ (46, 112, 109),
102
+ (253, 255, 185),
103
+ ],
104
+ )
105
+ NIGHT_OWLISH = TerminalTheme(
106
+ (255, 255, 255),
107
+ (64, 63, 83),
108
+ [
109
+ (1, 22, 39),
110
+ (211, 66, 62),
111
+ (42, 162, 152),
112
+ (218, 170, 1),
113
+ (72, 118, 214),
114
+ (64, 63, 83),
115
+ (8, 145, 106),
116
+ (122, 129, 129),
117
+ (122, 129, 129),
118
+ ],
119
+ [
120
+ (247, 110, 110),
121
+ (73, 208, 197),
122
+ (218, 194, 107),
123
+ (92, 167, 228),
124
+ (105, 112, 152),
125
+ (0, 201, 144),
126
+ (152, 159, 177),
127
+ ],
128
+ )
129
+
130
+ SVG_EXPORT_THEME = TerminalTheme(
131
+ (41, 41, 41),
132
+ (197, 200, 198),
133
+ [
134
+ (75, 78, 85),
135
+ (204, 85, 90),
136
+ (152, 168, 75),
137
+ (208, 179, 68),
138
+ (96, 138, 177),
139
+ (152, 114, 159),
140
+ (104, 160, 179),
141
+ (197, 200, 198),
142
+ (154, 155, 153),
143
+ ],
144
+ [
145
+ (255, 38, 39),
146
+ (0, 130, 61),
147
+ (208, 132, 66),
148
+ (25, 132, 233),
149
+ (255, 44, 122),
150
+ (57, 130, 128),
151
+ (253, 253, 197),
152
+ ],
153
+ )
.venv/lib/python3.12/site-packages/pip/_vendor/rich/text.py ADDED
@@ -0,0 +1,1361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from functools import partial, reduce
3
+ from math import gcd
4
+ from operator import itemgetter
5
+ from typing import (
6
+ TYPE_CHECKING,
7
+ Any,
8
+ Callable,
9
+ Dict,
10
+ Iterable,
11
+ List,
12
+ NamedTuple,
13
+ Optional,
14
+ Pattern,
15
+ Tuple,
16
+ Union,
17
+ )
18
+
19
+ from ._loop import loop_last
20
+ from ._pick import pick_bool
21
+ from ._wrap import divide_line
22
+ from .align import AlignMethod
23
+ from .cells import cell_len, set_cell_size
24
+ from .containers import Lines
25
+ from .control import strip_control_codes
26
+ from .emoji import EmojiVariant
27
+ from .jupyter import JupyterMixin
28
+ from .measure import Measurement
29
+ from .segment import Segment
30
+ from .style import Style, StyleType
31
+
32
+ if TYPE_CHECKING: # pragma: no cover
33
+ from .console import Console, ConsoleOptions, JustifyMethod, OverflowMethod
34
+
35
+ DEFAULT_JUSTIFY: "JustifyMethod" = "default"
36
+ DEFAULT_OVERFLOW: "OverflowMethod" = "fold"
37
+
38
+
39
+ _re_whitespace = re.compile(r"\s+$")
40
+
41
+ TextType = Union[str, "Text"]
42
+ """A plain string or a :class:`Text` instance."""
43
+
44
+ GetStyleCallable = Callable[[str], Optional[StyleType]]
45
+
46
+
47
+ class Span(NamedTuple):
48
+ """A marked up region in some text."""
49
+
50
+ start: int
51
+ """Span start index."""
52
+ end: int
53
+ """Span end index."""
54
+ style: Union[str, Style]
55
+ """Style associated with the span."""
56
+
57
+ def __repr__(self) -> str:
58
+ return f"Span({self.start}, {self.end}, {self.style!r})"
59
+
60
+ def __bool__(self) -> bool:
61
+ return self.end > self.start
62
+
63
+ def split(self, offset: int) -> Tuple["Span", Optional["Span"]]:
64
+ """Split a span in to 2 from a given offset."""
65
+
66
+ if offset < self.start:
67
+ return self, None
68
+ if offset >= self.end:
69
+ return self, None
70
+
71
+ start, end, style = self
72
+ span1 = Span(start, min(end, offset), style)
73
+ span2 = Span(span1.end, end, style)
74
+ return span1, span2
75
+
76
+ def move(self, offset: int) -> "Span":
77
+ """Move start and end by a given offset.
78
+
79
+ Args:
80
+ offset (int): Number of characters to add to start and end.
81
+
82
+ Returns:
83
+ TextSpan: A new TextSpan with adjusted position.
84
+ """
85
+ start, end, style = self
86
+ return Span(start + offset, end + offset, style)
87
+
88
+ def right_crop(self, offset: int) -> "Span":
89
+ """Crop the span at the given offset.
90
+
91
+ Args:
92
+ offset (int): A value between start and end.
93
+
94
+ Returns:
95
+ Span: A new (possibly smaller) span.
96
+ """
97
+ start, end, style = self
98
+ if offset >= end:
99
+ return self
100
+ return Span(start, min(offset, end), style)
101
+
102
+ def extend(self, cells: int) -> "Span":
103
+ """Extend the span by the given number of cells.
104
+
105
+ Args:
106
+ cells (int): Additional space to add to end of span.
107
+
108
+ Returns:
109
+ Span: A span.
110
+ """
111
+ if cells:
112
+ start, end, style = self
113
+ return Span(start, end + cells, style)
114
+ else:
115
+ return self
116
+
117
+
118
+ class Text(JupyterMixin):
119
+ """Text with color / style.
120
+
121
+ Args:
122
+ text (str, optional): Default unstyled text. Defaults to "".
123
+ style (Union[str, Style], optional): Base style for text. Defaults to "".
124
+ justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
125
+ overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
126
+ no_wrap (bool, optional): Disable text wrapping, or None for default. Defaults to None.
127
+ end (str, optional): Character to end text with. Defaults to "\\\\n".
128
+ tab_size (int): Number of spaces per tab, or ``None`` to use ``console.tab_size``. Defaults to None.
129
+ spans (List[Span], optional). A list of predefined style spans. Defaults to None.
130
+ """
131
+
132
+ __slots__ = [
133
+ "_text",
134
+ "style",
135
+ "justify",
136
+ "overflow",
137
+ "no_wrap",
138
+ "end",
139
+ "tab_size",
140
+ "_spans",
141
+ "_length",
142
+ ]
143
+
144
+ def __init__(
145
+ self,
146
+ text: str = "",
147
+ style: Union[str, Style] = "",
148
+ *,
149
+ justify: Optional["JustifyMethod"] = None,
150
+ overflow: Optional["OverflowMethod"] = None,
151
+ no_wrap: Optional[bool] = None,
152
+ end: str = "\n",
153
+ tab_size: Optional[int] = None,
154
+ spans: Optional[List[Span]] = None,
155
+ ) -> None:
156
+ sanitized_text = strip_control_codes(text)
157
+ self._text = [sanitized_text]
158
+ self.style = style
159
+ self.justify: Optional["JustifyMethod"] = justify
160
+ self.overflow: Optional["OverflowMethod"] = overflow
161
+ self.no_wrap = no_wrap
162
+ self.end = end
163
+ self.tab_size = tab_size
164
+ self._spans: List[Span] = spans or []
165
+ self._length: int = len(sanitized_text)
166
+
167
+ def __len__(self) -> int:
168
+ return self._length
169
+
170
+ def __bool__(self) -> bool:
171
+ return bool(self._length)
172
+
173
+ def __str__(self) -> str:
174
+ return self.plain
175
+
176
+ def __repr__(self) -> str:
177
+ return f"<text {self.plain!r} {self._spans!r} {self.style!r}>"
178
+
179
+ def __add__(self, other: Any) -> "Text":
180
+ if isinstance(other, (str, Text)):
181
+ result = self.copy()
182
+ result.append(other)
183
+ return result
184
+ return NotImplemented
185
+
186
+ def __eq__(self, other: object) -> bool:
187
+ if not isinstance(other, Text):
188
+ return NotImplemented
189
+ return self.plain == other.plain and self._spans == other._spans
190
+
191
+ def __contains__(self, other: object) -> bool:
192
+ if isinstance(other, str):
193
+ return other in self.plain
194
+ elif isinstance(other, Text):
195
+ return other.plain in self.plain
196
+ return False
197
+
198
+ def __getitem__(self, slice: Union[int, slice]) -> "Text":
199
+ def get_text_at(offset: int) -> "Text":
200
+ _Span = Span
201
+ text = Text(
202
+ self.plain[offset],
203
+ spans=[
204
+ _Span(0, 1, style)
205
+ for start, end, style in self._spans
206
+ if end > offset >= start
207
+ ],
208
+ end="",
209
+ )
210
+ return text
211
+
212
+ if isinstance(slice, int):
213
+ return get_text_at(slice)
214
+ else:
215
+ start, stop, step = slice.indices(len(self.plain))
216
+ if step == 1:
217
+ lines = self.divide([start, stop])
218
+ return lines[1]
219
+ else:
220
+ # This would be a bit of work to implement efficiently
221
+ # For now, its not required
222
+ raise TypeError("slices with step!=1 are not supported")
223
+
224
+ @property
225
+ def cell_len(self) -> int:
226
+ """Get the number of cells required to render this text."""
227
+ return cell_len(self.plain)
228
+
229
+ @property
230
+ def markup(self) -> str:
231
+ """Get console markup to render this Text.
232
+
233
+ Returns:
234
+ str: A string potentially creating markup tags.
235
+ """
236
+ from .markup import escape
237
+
238
+ output: List[str] = []
239
+
240
+ plain = self.plain
241
+ markup_spans = [
242
+ (0, False, self.style),
243
+ *((span.start, False, span.style) for span in self._spans),
244
+ *((span.end, True, span.style) for span in self._spans),
245
+ (len(plain), True, self.style),
246
+ ]
247
+ markup_spans.sort(key=itemgetter(0, 1))
248
+ position = 0
249
+ append = output.append
250
+ for offset, closing, style in markup_spans:
251
+ if offset > position:
252
+ append(escape(plain[position:offset]))
253
+ position = offset
254
+ if style:
255
+ append(f"[/{style}]" if closing else f"[{style}]")
256
+ markup = "".join(output)
257
+ return markup
258
+
259
+ @classmethod
260
+ def from_markup(
261
+ cls,
262
+ text: str,
263
+ *,
264
+ style: Union[str, Style] = "",
265
+ emoji: bool = True,
266
+ emoji_variant: Optional[EmojiVariant] = None,
267
+ justify: Optional["JustifyMethod"] = None,
268
+ overflow: Optional["OverflowMethod"] = None,
269
+ end: str = "\n",
270
+ ) -> "Text":
271
+ """Create Text instance from markup.
272
+
273
+ Args:
274
+ text (str): A string containing console markup.
275
+ style (Union[str, Style], optional): Base style for text. Defaults to "".
276
+ emoji (bool, optional): Also render emoji code. Defaults to True.
277
+ emoji_variant (str, optional): Optional emoji variant, either "text" or "emoji". Defaults to None.
278
+ justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
279
+ overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
280
+ end (str, optional): Character to end text with. Defaults to "\\\\n".
281
+
282
+ Returns:
283
+ Text: A Text instance with markup rendered.
284
+ """
285
+ from .markup import render
286
+
287
+ rendered_text = render(text, style, emoji=emoji, emoji_variant=emoji_variant)
288
+ rendered_text.justify = justify
289
+ rendered_text.overflow = overflow
290
+ rendered_text.end = end
291
+ return rendered_text
292
+
293
+ @classmethod
294
+ def from_ansi(
295
+ cls,
296
+ text: str,
297
+ *,
298
+ style: Union[str, Style] = "",
299
+ justify: Optional["JustifyMethod"] = None,
300
+ overflow: Optional["OverflowMethod"] = None,
301
+ no_wrap: Optional[bool] = None,
302
+ end: str = "\n",
303
+ tab_size: Optional[int] = 8,
304
+ ) -> "Text":
305
+ """Create a Text object from a string containing ANSI escape codes.
306
+
307
+ Args:
308
+ text (str): A string containing escape codes.
309
+ style (Union[str, Style], optional): Base style for text. Defaults to "".
310
+ justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
311
+ overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
312
+ no_wrap (bool, optional): Disable text wrapping, or None for default. Defaults to None.
313
+ end (str, optional): Character to end text with. Defaults to "\\\\n".
314
+ tab_size (int): Number of spaces per tab, or ``None`` to use ``console.tab_size``. Defaults to None.
315
+ """
316
+ from .ansi import AnsiDecoder
317
+
318
+ joiner = Text(
319
+ "\n",
320
+ justify=justify,
321
+ overflow=overflow,
322
+ no_wrap=no_wrap,
323
+ end=end,
324
+ tab_size=tab_size,
325
+ style=style,
326
+ )
327
+ decoder = AnsiDecoder()
328
+ result = joiner.join(line for line in decoder.decode(text))
329
+ return result
330
+
331
+ @classmethod
332
+ def styled(
333
+ cls,
334
+ text: str,
335
+ style: StyleType = "",
336
+ *,
337
+ justify: Optional["JustifyMethod"] = None,
338
+ overflow: Optional["OverflowMethod"] = None,
339
+ ) -> "Text":
340
+ """Construct a Text instance with a pre-applied styled. A style applied in this way won't be used
341
+ to pad the text when it is justified.
342
+
343
+ Args:
344
+ text (str): A string containing console markup.
345
+ style (Union[str, Style]): Style to apply to the text. Defaults to "".
346
+ justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
347
+ overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
348
+
349
+ Returns:
350
+ Text: A text instance with a style applied to the entire string.
351
+ """
352
+ styled_text = cls(text, justify=justify, overflow=overflow)
353
+ styled_text.stylize(style)
354
+ return styled_text
355
+
356
+ @classmethod
357
+ def assemble(
358
+ cls,
359
+ *parts: Union[str, "Text", Tuple[str, StyleType]],
360
+ style: Union[str, Style] = "",
361
+ justify: Optional["JustifyMethod"] = None,
362
+ overflow: Optional["OverflowMethod"] = None,
363
+ no_wrap: Optional[bool] = None,
364
+ end: str = "\n",
365
+ tab_size: int = 8,
366
+ meta: Optional[Dict[str, Any]] = None,
367
+ ) -> "Text":
368
+ """Construct a text instance by combining a sequence of strings with optional styles.
369
+ The positional arguments should be either strings, or a tuple of string + style.
370
+
371
+ Args:
372
+ style (Union[str, Style], optional): Base style for text. Defaults to "".
373
+ justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
374
+ overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
375
+ no_wrap (bool, optional): Disable text wrapping, or None for default. Defaults to None.
376
+ end (str, optional): Character to end text with. Defaults to "\\\\n".
377
+ tab_size (int): Number of spaces per tab, or ``None`` to use ``console.tab_size``. Defaults to None.
378
+ meta (Dict[str, Any], optional). Meta data to apply to text, or None for no meta data. Default to None
379
+
380
+ Returns:
381
+ Text: A new text instance.
382
+ """
383
+ text = cls(
384
+ style=style,
385
+ justify=justify,
386
+ overflow=overflow,
387
+ no_wrap=no_wrap,
388
+ end=end,
389
+ tab_size=tab_size,
390
+ )
391
+ append = text.append
392
+ _Text = Text
393
+ for part in parts:
394
+ if isinstance(part, (_Text, str)):
395
+ append(part)
396
+ else:
397
+ append(*part)
398
+ if meta:
399
+ text.apply_meta(meta)
400
+ return text
401
+
402
+ @property
403
+ def plain(self) -> str:
404
+ """Get the text as a single string."""
405
+ if len(self._text) != 1:
406
+ self._text[:] = ["".join(self._text)]
407
+ return self._text[0]
408
+
409
+ @plain.setter
410
+ def plain(self, new_text: str) -> None:
411
+ """Set the text to a new value."""
412
+ if new_text != self.plain:
413
+ sanitized_text = strip_control_codes(new_text)
414
+ self._text[:] = [sanitized_text]
415
+ old_length = self._length
416
+ self._length = len(sanitized_text)
417
+ if old_length > self._length:
418
+ self._trim_spans()
419
+
420
+ @property
421
+ def spans(self) -> List[Span]:
422
+ """Get a reference to the internal list of spans."""
423
+ return self._spans
424
+
425
+ @spans.setter
426
+ def spans(self, spans: List[Span]) -> None:
427
+ """Set spans."""
428
+ self._spans = spans[:]
429
+
430
+ def blank_copy(self, plain: str = "") -> "Text":
431
+ """Return a new Text instance with copied metadata (but not the string or spans)."""
432
+ copy_self = Text(
433
+ plain,
434
+ style=self.style,
435
+ justify=self.justify,
436
+ overflow=self.overflow,
437
+ no_wrap=self.no_wrap,
438
+ end=self.end,
439
+ tab_size=self.tab_size,
440
+ )
441
+ return copy_self
442
+
443
+ def copy(self) -> "Text":
444
+ """Return a copy of this instance."""
445
+ copy_self = Text(
446
+ self.plain,
447
+ style=self.style,
448
+ justify=self.justify,
449
+ overflow=self.overflow,
450
+ no_wrap=self.no_wrap,
451
+ end=self.end,
452
+ tab_size=self.tab_size,
453
+ )
454
+ copy_self._spans[:] = self._spans
455
+ return copy_self
456
+
457
+ def stylize(
458
+ self,
459
+ style: Union[str, Style],
460
+ start: int = 0,
461
+ end: Optional[int] = None,
462
+ ) -> None:
463
+ """Apply a style to the text, or a portion of the text.
464
+
465
+ Args:
466
+ style (Union[str, Style]): Style instance or style definition to apply.
467
+ start (int): Start offset (negative indexing is supported). Defaults to 0.
468
+ end (Optional[int], optional): End offset (negative indexing is supported), or None for end of text. Defaults to None.
469
+ """
470
+ if style:
471
+ length = len(self)
472
+ if start < 0:
473
+ start = length + start
474
+ if end is None:
475
+ end = length
476
+ if end < 0:
477
+ end = length + end
478
+ if start >= length or end <= start:
479
+ # Span not in text or not valid
480
+ return
481
+ self._spans.append(Span(start, min(length, end), style))
482
+
483
+ def stylize_before(
484
+ self,
485
+ style: Union[str, Style],
486
+ start: int = 0,
487
+ end: Optional[int] = None,
488
+ ) -> None:
489
+ """Apply a style to the text, or a portion of the text. Styles will be applied before other styles already present.
490
+
491
+ Args:
492
+ style (Union[str, Style]): Style instance or style definition to apply.
493
+ start (int): Start offset (negative indexing is supported). Defaults to 0.
494
+ end (Optional[int], optional): End offset (negative indexing is supported), or None for end of text. Defaults to None.
495
+ """
496
+ if style:
497
+ length = len(self)
498
+ if start < 0:
499
+ start = length + start
500
+ if end is None:
501
+ end = length
502
+ if end < 0:
503
+ end = length + end
504
+ if start >= length or end <= start:
505
+ # Span not in text or not valid
506
+ return
507
+ self._spans.insert(0, Span(start, min(length, end), style))
508
+
509
+ def apply_meta(
510
+ self, meta: Dict[str, Any], start: int = 0, end: Optional[int] = None
511
+ ) -> None:
512
+ """Apply metadata to the text, or a portion of the text.
513
+
514
+ Args:
515
+ meta (Dict[str, Any]): A dict of meta information.
516
+ start (int): Start offset (negative indexing is supported). Defaults to 0.
517
+ end (Optional[int], optional): End offset (negative indexing is supported), or None for end of text. Defaults to None.
518
+
519
+ """
520
+ style = Style.from_meta(meta)
521
+ self.stylize(style, start=start, end=end)
522
+
523
+ def on(self, meta: Optional[Dict[str, Any]] = None, **handlers: Any) -> "Text":
524
+ """Apply event handlers (used by Textual project).
525
+
526
+ Example:
527
+ >>> from rich.text import Text
528
+ >>> text = Text("hello world")
529
+ >>> text.on(click="view.toggle('world')")
530
+
531
+ Args:
532
+ meta (Dict[str, Any]): Mapping of meta information.
533
+ **handlers: Keyword args are prefixed with "@" to defined handlers.
534
+
535
+ Returns:
536
+ Text: Self is returned to method may be chained.
537
+ """
538
+ meta = {} if meta is None else meta
539
+ meta.update({f"@{key}": value for key, value in handlers.items()})
540
+ self.stylize(Style.from_meta(meta))
541
+ return self
542
+
543
+ def remove_suffix(self, suffix: str) -> None:
544
+ """Remove a suffix if it exists.
545
+
546
+ Args:
547
+ suffix (str): Suffix to remove.
548
+ """
549
+ if self.plain.endswith(suffix):
550
+ self.right_crop(len(suffix))
551
+
552
+ def get_style_at_offset(self, console: "Console", offset: int) -> Style:
553
+ """Get the style of a character at give offset.
554
+
555
+ Args:
556
+ console (~Console): Console where text will be rendered.
557
+ offset (int): Offset in to text (negative indexing supported)
558
+
559
+ Returns:
560
+ Style: A Style instance.
561
+ """
562
+ # TODO: This is a little inefficient, it is only used by full justify
563
+ if offset < 0:
564
+ offset = len(self) + offset
565
+ get_style = console.get_style
566
+ style = get_style(self.style).copy()
567
+ for start, end, span_style in self._spans:
568
+ if end > offset >= start:
569
+ style += get_style(span_style, default="")
570
+ return style
571
+
572
+ def extend_style(self, spaces: int) -> None:
573
+ """Extend the Text given number of spaces where the spaces have the same style as the last character.
574
+
575
+ Args:
576
+ spaces (int): Number of spaces to add to the Text.
577
+ """
578
+ if spaces <= 0:
579
+ return
580
+ spans = self.spans
581
+ new_spaces = " " * spaces
582
+ if spans:
583
+ end_offset = len(self)
584
+ self._spans[:] = [
585
+ span.extend(spaces) if span.end >= end_offset else span
586
+ for span in spans
587
+ ]
588
+ self._text.append(new_spaces)
589
+ self._length += spaces
590
+ else:
591
+ self.plain += new_spaces
592
+
593
+ def highlight_regex(
594
+ self,
595
+ re_highlight: Union[Pattern[str], str],
596
+ style: Optional[Union[GetStyleCallable, StyleType]] = None,
597
+ *,
598
+ style_prefix: str = "",
599
+ ) -> int:
600
+ """Highlight text with a regular expression, where group names are
601
+ translated to styles.
602
+
603
+ Args:
604
+ re_highlight (Union[re.Pattern, str]): A regular expression object or string.
605
+ style (Union[GetStyleCallable, StyleType]): Optional style to apply to whole match, or a callable
606
+ which accepts the matched text and returns a style. Defaults to None.
607
+ style_prefix (str, optional): Optional prefix to add to style group names.
608
+
609
+ Returns:
610
+ int: Number of regex matches
611
+ """
612
+ count = 0
613
+ append_span = self._spans.append
614
+ _Span = Span
615
+ plain = self.plain
616
+ if isinstance(re_highlight, str):
617
+ re_highlight = re.compile(re_highlight)
618
+ for match in re_highlight.finditer(plain):
619
+ get_span = match.span
620
+ if style:
621
+ start, end = get_span()
622
+ match_style = style(plain[start:end]) if callable(style) else style
623
+ if match_style is not None and end > start:
624
+ append_span(_Span(start, end, match_style))
625
+
626
+ count += 1
627
+ for name in match.groupdict().keys():
628
+ start, end = get_span(name)
629
+ if start != -1 and end > start:
630
+ append_span(_Span(start, end, f"{style_prefix}{name}"))
631
+ return count
632
+
633
+ def highlight_words(
634
+ self,
635
+ words: Iterable[str],
636
+ style: Union[str, Style],
637
+ *,
638
+ case_sensitive: bool = True,
639
+ ) -> int:
640
+ """Highlight words with a style.
641
+
642
+ Args:
643
+ words (Iterable[str]): Words to highlight.
644
+ style (Union[str, Style]): Style to apply.
645
+ case_sensitive (bool, optional): Enable case sensitive matching. Defaults to True.
646
+
647
+ Returns:
648
+ int: Number of words highlighted.
649
+ """
650
+ re_words = "|".join(re.escape(word) for word in words)
651
+ add_span = self._spans.append
652
+ count = 0
653
+ _Span = Span
654
+ for match in re.finditer(
655
+ re_words, self.plain, flags=0 if case_sensitive else re.IGNORECASE
656
+ ):
657
+ start, end = match.span(0)
658
+ add_span(_Span(start, end, style))
659
+ count += 1
660
+ return count
661
+
662
+ def rstrip(self) -> None:
663
+ """Strip whitespace from end of text."""
664
+ self.plain = self.plain.rstrip()
665
+
666
+ def rstrip_end(self, size: int) -> None:
667
+ """Remove whitespace beyond a certain width at the end of the text.
668
+
669
+ Args:
670
+ size (int): The desired size of the text.
671
+ """
672
+ text_length = len(self)
673
+ if text_length > size:
674
+ excess = text_length - size
675
+ whitespace_match = _re_whitespace.search(self.plain)
676
+ if whitespace_match is not None:
677
+ whitespace_count = len(whitespace_match.group(0))
678
+ self.right_crop(min(whitespace_count, excess))
679
+
680
+ def set_length(self, new_length: int) -> None:
681
+ """Set new length of the text, clipping or padding is required."""
682
+ length = len(self)
683
+ if length != new_length:
684
+ if length < new_length:
685
+ self.pad_right(new_length - length)
686
+ else:
687
+ self.right_crop(length - new_length)
688
+
689
+ def __rich_console__(
690
+ self, console: "Console", options: "ConsoleOptions"
691
+ ) -> Iterable[Segment]:
692
+ tab_size: int = console.tab_size if self.tab_size is None else self.tab_size
693
+ justify = self.justify or options.justify or DEFAULT_JUSTIFY
694
+
695
+ overflow = self.overflow or options.overflow or DEFAULT_OVERFLOW
696
+
697
+ lines = self.wrap(
698
+ console,
699
+ options.max_width,
700
+ justify=justify,
701
+ overflow=overflow,
702
+ tab_size=tab_size or 8,
703
+ no_wrap=pick_bool(self.no_wrap, options.no_wrap, False),
704
+ )
705
+ all_lines = Text("\n").join(lines)
706
+ yield from all_lines.render(console, end=self.end)
707
+
708
+ def __rich_measure__(
709
+ self, console: "Console", options: "ConsoleOptions"
710
+ ) -> Measurement:
711
+ text = self.plain
712
+ lines = text.splitlines()
713
+ max_text_width = max(cell_len(line) for line in lines) if lines else 0
714
+ words = text.split()
715
+ min_text_width = (
716
+ max(cell_len(word) for word in words) if words else max_text_width
717
+ )
718
+ return Measurement(min_text_width, max_text_width)
719
+
720
+ def render(self, console: "Console", end: str = "") -> Iterable["Segment"]:
721
+ """Render the text as Segments.
722
+
723
+ Args:
724
+ console (Console): Console instance.
725
+ end (Optional[str], optional): Optional end character.
726
+
727
+ Returns:
728
+ Iterable[Segment]: Result of render that may be written to the console.
729
+ """
730
+ _Segment = Segment
731
+ text = self.plain
732
+ if not self._spans:
733
+ yield Segment(text)
734
+ if end:
735
+ yield _Segment(end)
736
+ return
737
+ get_style = partial(console.get_style, default=Style.null())
738
+
739
+ enumerated_spans = list(enumerate(self._spans, 1))
740
+ style_map = {index: get_style(span.style) for index, span in enumerated_spans}
741
+ style_map[0] = get_style(self.style)
742
+
743
+ spans = [
744
+ (0, False, 0),
745
+ *((span.start, False, index) for index, span in enumerated_spans),
746
+ *((span.end, True, index) for index, span in enumerated_spans),
747
+ (len(text), True, 0),
748
+ ]
749
+ spans.sort(key=itemgetter(0, 1))
750
+
751
+ stack: List[int] = []
752
+ stack_append = stack.append
753
+ stack_pop = stack.remove
754
+
755
+ style_cache: Dict[Tuple[Style, ...], Style] = {}
756
+ style_cache_get = style_cache.get
757
+ combine = Style.combine
758
+
759
+ def get_current_style() -> Style:
760
+ """Construct current style from stack."""
761
+ styles = tuple(style_map[_style_id] for _style_id in sorted(stack))
762
+ cached_style = style_cache_get(styles)
763
+ if cached_style is not None:
764
+ return cached_style
765
+ current_style = combine(styles)
766
+ style_cache[styles] = current_style
767
+ return current_style
768
+
769
+ for (offset, leaving, style_id), (next_offset, _, _) in zip(spans, spans[1:]):
770
+ if leaving:
771
+ stack_pop(style_id)
772
+ else:
773
+ stack_append(style_id)
774
+ if next_offset > offset:
775
+ yield _Segment(text[offset:next_offset], get_current_style())
776
+ if end:
777
+ yield _Segment(end)
778
+
779
+ def join(self, lines: Iterable["Text"]) -> "Text":
780
+ """Join text together with this instance as the separator.
781
+
782
+ Args:
783
+ lines (Iterable[Text]): An iterable of Text instances to join.
784
+
785
+ Returns:
786
+ Text: A new text instance containing join text.
787
+ """
788
+
789
+ new_text = self.blank_copy()
790
+
791
+ def iter_text() -> Iterable["Text"]:
792
+ if self.plain:
793
+ for last, line in loop_last(lines):
794
+ yield line
795
+ if not last:
796
+ yield self
797
+ else:
798
+ yield from lines
799
+
800
+ extend_text = new_text._text.extend
801
+ append_span = new_text._spans.append
802
+ extend_spans = new_text._spans.extend
803
+ offset = 0
804
+ _Span = Span
805
+
806
+ for text in iter_text():
807
+ extend_text(text._text)
808
+ if text.style:
809
+ append_span(_Span(offset, offset + len(text), text.style))
810
+ extend_spans(
811
+ _Span(offset + start, offset + end, style)
812
+ for start, end, style in text._spans
813
+ )
814
+ offset += len(text)
815
+ new_text._length = offset
816
+ return new_text
817
+
818
+ def expand_tabs(self, tab_size: Optional[int] = None) -> None:
819
+ """Converts tabs to spaces.
820
+
821
+ Args:
822
+ tab_size (int, optional): Size of tabs. Defaults to 8.
823
+
824
+ """
825
+ if "\t" not in self.plain:
826
+ return
827
+ if tab_size is None:
828
+ tab_size = self.tab_size
829
+ if tab_size is None:
830
+ tab_size = 8
831
+
832
+ new_text: List[Text] = []
833
+ append = new_text.append
834
+
835
+ for line in self.split("\n", include_separator=True):
836
+ if "\t" not in line.plain:
837
+ append(line)
838
+ else:
839
+ cell_position = 0
840
+ parts = line.split("\t", include_separator=True)
841
+ for part in parts:
842
+ if part.plain.endswith("\t"):
843
+ part._text[-1] = part._text[-1][:-1] + " "
844
+ cell_position += part.cell_len
845
+ tab_remainder = cell_position % tab_size
846
+ if tab_remainder:
847
+ spaces = tab_size - tab_remainder
848
+ part.extend_style(spaces)
849
+ cell_position += spaces
850
+ else:
851
+ cell_position += part.cell_len
852
+ append(part)
853
+
854
+ result = Text("").join(new_text)
855
+
856
+ self._text = [result.plain]
857
+ self._length = len(self.plain)
858
+ self._spans[:] = result._spans
859
+
860
+ def truncate(
861
+ self,
862
+ max_width: int,
863
+ *,
864
+ overflow: Optional["OverflowMethod"] = None,
865
+ pad: bool = False,
866
+ ) -> None:
867
+ """Truncate text if it is longer that a given width.
868
+
869
+ Args:
870
+ max_width (int): Maximum number of characters in text.
871
+ overflow (str, optional): Overflow method: "crop", "fold", or "ellipsis". Defaults to None, to use self.overflow.
872
+ pad (bool, optional): Pad with spaces if the length is less than max_width. Defaults to False.
873
+ """
874
+ _overflow = overflow or self.overflow or DEFAULT_OVERFLOW
875
+ if _overflow != "ignore":
876
+ length = cell_len(self.plain)
877
+ if length > max_width:
878
+ if _overflow == "ellipsis":
879
+ self.plain = set_cell_size(self.plain, max_width - 1) + "…"
880
+ else:
881
+ self.plain = set_cell_size(self.plain, max_width)
882
+ if pad and length < max_width:
883
+ spaces = max_width - length
884
+ self._text = [f"{self.plain}{' ' * spaces}"]
885
+ self._length = len(self.plain)
886
+
887
+ def _trim_spans(self) -> None:
888
+ """Remove or modify any spans that are over the end of the text."""
889
+ max_offset = len(self.plain)
890
+ _Span = Span
891
+ self._spans[:] = [
892
+ (
893
+ span
894
+ if span.end < max_offset
895
+ else _Span(span.start, min(max_offset, span.end), span.style)
896
+ )
897
+ for span in self._spans
898
+ if span.start < max_offset
899
+ ]
900
+
901
+ def pad(self, count: int, character: str = " ") -> None:
902
+ """Pad left and right with a given number of characters.
903
+
904
+ Args:
905
+ count (int): Width of padding.
906
+ character (str): The character to pad with. Must be a string of length 1.
907
+ """
908
+ assert len(character) == 1, "Character must be a string of length 1"
909
+ if count:
910
+ pad_characters = character * count
911
+ self.plain = f"{pad_characters}{self.plain}{pad_characters}"
912
+ _Span = Span
913
+ self._spans[:] = [
914
+ _Span(start + count, end + count, style)
915
+ for start, end, style in self._spans
916
+ ]
917
+
918
+ def pad_left(self, count: int, character: str = " ") -> None:
919
+ """Pad the left with a given character.
920
+
921
+ Args:
922
+ count (int): Number of characters to pad.
923
+ character (str, optional): Character to pad with. Defaults to " ".
924
+ """
925
+ assert len(character) == 1, "Character must be a string of length 1"
926
+ if count:
927
+ self.plain = f"{character * count}{self.plain}"
928
+ _Span = Span
929
+ self._spans[:] = [
930
+ _Span(start + count, end + count, style)
931
+ for start, end, style in self._spans
932
+ ]
933
+
934
+ def pad_right(self, count: int, character: str = " ") -> None:
935
+ """Pad the right with a given character.
936
+
937
+ Args:
938
+ count (int): Number of characters to pad.
939
+ character (str, optional): Character to pad with. Defaults to " ".
940
+ """
941
+ assert len(character) == 1, "Character must be a string of length 1"
942
+ if count:
943
+ self.plain = f"{self.plain}{character * count}"
944
+
945
+ def align(self, align: AlignMethod, width: int, character: str = " ") -> None:
946
+ """Align text to a given width.
947
+
948
+ Args:
949
+ align (AlignMethod): One of "left", "center", or "right".
950
+ width (int): Desired width.
951
+ character (str, optional): Character to pad with. Defaults to " ".
952
+ """
953
+ self.truncate(width)
954
+ excess_space = width - cell_len(self.plain)
955
+ if excess_space:
956
+ if align == "left":
957
+ self.pad_right(excess_space, character)
958
+ elif align == "center":
959
+ left = excess_space // 2
960
+ self.pad_left(left, character)
961
+ self.pad_right(excess_space - left, character)
962
+ else:
963
+ self.pad_left(excess_space, character)
964
+
965
+ def append(
966
+ self, text: Union["Text", str], style: Optional[Union[str, "Style"]] = None
967
+ ) -> "Text":
968
+ """Add text with an optional style.
969
+
970
+ Args:
971
+ text (Union[Text, str]): A str or Text to append.
972
+ style (str, optional): A style name. Defaults to None.
973
+
974
+ Returns:
975
+ Text: Returns self for chaining.
976
+ """
977
+
978
+ if not isinstance(text, (str, Text)):
979
+ raise TypeError("Only str or Text can be appended to Text")
980
+
981
+ if len(text):
982
+ if isinstance(text, str):
983
+ sanitized_text = strip_control_codes(text)
984
+ self._text.append(sanitized_text)
985
+ offset = len(self)
986
+ text_length = len(sanitized_text)
987
+ if style:
988
+ self._spans.append(Span(offset, offset + text_length, style))
989
+ self._length += text_length
990
+ elif isinstance(text, Text):
991
+ _Span = Span
992
+ if style is not None:
993
+ raise ValueError(
994
+ "style must not be set when appending Text instance"
995
+ )
996
+ text_length = self._length
997
+ if text.style:
998
+ self._spans.append(
999
+ _Span(text_length, text_length + len(text), text.style)
1000
+ )
1001
+ self._text.append(text.plain)
1002
+ self._spans.extend(
1003
+ _Span(start + text_length, end + text_length, style)
1004
+ for start, end, style in text._spans.copy()
1005
+ )
1006
+ self._length += len(text)
1007
+ return self
1008
+
1009
+ def append_text(self, text: "Text") -> "Text":
1010
+ """Append another Text instance. This method is more performant that Text.append, but
1011
+ only works for Text.
1012
+
1013
+ Args:
1014
+ text (Text): The Text instance to append to this instance.
1015
+
1016
+ Returns:
1017
+ Text: Returns self for chaining.
1018
+ """
1019
+ _Span = Span
1020
+ text_length = self._length
1021
+ if text.style:
1022
+ self._spans.append(_Span(text_length, text_length + len(text), text.style))
1023
+ self._text.append(text.plain)
1024
+ self._spans.extend(
1025
+ _Span(start + text_length, end + text_length, style)
1026
+ for start, end, style in text._spans.copy()
1027
+ )
1028
+ self._length += len(text)
1029
+ return self
1030
+
1031
+ def append_tokens(
1032
+ self, tokens: Iterable[Tuple[str, Optional[StyleType]]]
1033
+ ) -> "Text":
1034
+ """Append iterable of str and style. Style may be a Style instance or a str style definition.
1035
+
1036
+ Args:
1037
+ tokens (Iterable[Tuple[str, Optional[StyleType]]]): An iterable of tuples containing str content and style.
1038
+
1039
+ Returns:
1040
+ Text: Returns self for chaining.
1041
+ """
1042
+ append_text = self._text.append
1043
+ append_span = self._spans.append
1044
+ _Span = Span
1045
+ offset = len(self)
1046
+ for content, style in tokens:
1047
+ content = strip_control_codes(content)
1048
+ append_text(content)
1049
+ if style:
1050
+ append_span(_Span(offset, offset + len(content), style))
1051
+ offset += len(content)
1052
+ self._length = offset
1053
+ return self
1054
+
1055
+ def copy_styles(self, text: "Text") -> None:
1056
+ """Copy styles from another Text instance.
1057
+
1058
+ Args:
1059
+ text (Text): A Text instance to copy styles from, must be the same length.
1060
+ """
1061
+ self._spans.extend(text._spans)
1062
+
1063
+ def split(
1064
+ self,
1065
+ separator: str = "\n",
1066
+ *,
1067
+ include_separator: bool = False,
1068
+ allow_blank: bool = False,
1069
+ ) -> Lines:
1070
+ """Split rich text in to lines, preserving styles.
1071
+
1072
+ Args:
1073
+ separator (str, optional): String to split on. Defaults to "\\\\n".
1074
+ include_separator (bool, optional): Include the separator in the lines. Defaults to False.
1075
+ allow_blank (bool, optional): Return a blank line if the text ends with a separator. Defaults to False.
1076
+
1077
+ Returns:
1078
+ List[RichText]: A list of rich text, one per line of the original.
1079
+ """
1080
+ assert separator, "separator must not be empty"
1081
+
1082
+ text = self.plain
1083
+ if separator not in text:
1084
+ return Lines([self.copy()])
1085
+
1086
+ if include_separator:
1087
+ lines = self.divide(
1088
+ match.end() for match in re.finditer(re.escape(separator), text)
1089
+ )
1090
+ else:
1091
+
1092
+ def flatten_spans() -> Iterable[int]:
1093
+ for match in re.finditer(re.escape(separator), text):
1094
+ start, end = match.span()
1095
+ yield start
1096
+ yield end
1097
+
1098
+ lines = Lines(
1099
+ line for line in self.divide(flatten_spans()) if line.plain != separator
1100
+ )
1101
+
1102
+ if not allow_blank and text.endswith(separator):
1103
+ lines.pop()
1104
+
1105
+ return lines
1106
+
1107
+ def divide(self, offsets: Iterable[int]) -> Lines:
1108
+ """Divide text in to a number of lines at given offsets.
1109
+
1110
+ Args:
1111
+ offsets (Iterable[int]): Offsets used to divide text.
1112
+
1113
+ Returns:
1114
+ Lines: New RichText instances between offsets.
1115
+ """
1116
+ _offsets = list(offsets)
1117
+
1118
+ if not _offsets:
1119
+ return Lines([self.copy()])
1120
+
1121
+ text = self.plain
1122
+ text_length = len(text)
1123
+ divide_offsets = [0, *_offsets, text_length]
1124
+ line_ranges = list(zip(divide_offsets, divide_offsets[1:]))
1125
+
1126
+ style = self.style
1127
+ justify = self.justify
1128
+ overflow = self.overflow
1129
+ _Text = Text
1130
+ new_lines = Lines(
1131
+ _Text(
1132
+ text[start:end],
1133
+ style=style,
1134
+ justify=justify,
1135
+ overflow=overflow,
1136
+ )
1137
+ for start, end in line_ranges
1138
+ )
1139
+ if not self._spans:
1140
+ return new_lines
1141
+
1142
+ _line_appends = [line._spans.append for line in new_lines._lines]
1143
+ line_count = len(line_ranges)
1144
+ _Span = Span
1145
+
1146
+ for span_start, span_end, style in self._spans:
1147
+ lower_bound = 0
1148
+ upper_bound = line_count
1149
+ start_line_no = (lower_bound + upper_bound) // 2
1150
+
1151
+ while True:
1152
+ line_start, line_end = line_ranges[start_line_no]
1153
+ if span_start < line_start:
1154
+ upper_bound = start_line_no - 1
1155
+ elif span_start > line_end:
1156
+ lower_bound = start_line_no + 1
1157
+ else:
1158
+ break
1159
+ start_line_no = (lower_bound + upper_bound) // 2
1160
+
1161
+ if span_end < line_end:
1162
+ end_line_no = start_line_no
1163
+ else:
1164
+ end_line_no = lower_bound = start_line_no
1165
+ upper_bound = line_count
1166
+
1167
+ while True:
1168
+ line_start, line_end = line_ranges[end_line_no]
1169
+ if span_end < line_start:
1170
+ upper_bound = end_line_no - 1
1171
+ elif span_end > line_end:
1172
+ lower_bound = end_line_no + 1
1173
+ else:
1174
+ break
1175
+ end_line_no = (lower_bound + upper_bound) // 2
1176
+
1177
+ for line_no in range(start_line_no, end_line_no + 1):
1178
+ line_start, line_end = line_ranges[line_no]
1179
+ new_start = max(0, span_start - line_start)
1180
+ new_end = min(span_end - line_start, line_end - line_start)
1181
+ if new_end > new_start:
1182
+ _line_appends[line_no](_Span(new_start, new_end, style))
1183
+
1184
+ return new_lines
1185
+
1186
+ def right_crop(self, amount: int = 1) -> None:
1187
+ """Remove a number of characters from the end of the text."""
1188
+ max_offset = len(self.plain) - amount
1189
+ _Span = Span
1190
+ self._spans[:] = [
1191
+ (
1192
+ span
1193
+ if span.end < max_offset
1194
+ else _Span(span.start, min(max_offset, span.end), span.style)
1195
+ )
1196
+ for span in self._spans
1197
+ if span.start < max_offset
1198
+ ]
1199
+ self._text = [self.plain[:-amount]]
1200
+ self._length -= amount
1201
+
1202
+ def wrap(
1203
+ self,
1204
+ console: "Console",
1205
+ width: int,
1206
+ *,
1207
+ justify: Optional["JustifyMethod"] = None,
1208
+ overflow: Optional["OverflowMethod"] = None,
1209
+ tab_size: int = 8,
1210
+ no_wrap: Optional[bool] = None,
1211
+ ) -> Lines:
1212
+ """Word wrap the text.
1213
+
1214
+ Args:
1215
+ console (Console): Console instance.
1216
+ width (int): Number of cells available per line.
1217
+ justify (str, optional): Justify method: "default", "left", "center", "full", "right". Defaults to "default".
1218
+ overflow (str, optional): Overflow method: "crop", "fold", or "ellipsis". Defaults to None.
1219
+ tab_size (int, optional): Default tab size. Defaults to 8.
1220
+ no_wrap (bool, optional): Disable wrapping, Defaults to False.
1221
+
1222
+ Returns:
1223
+ Lines: Number of lines.
1224
+ """
1225
+ wrap_justify = justify or self.justify or DEFAULT_JUSTIFY
1226
+ wrap_overflow = overflow or self.overflow or DEFAULT_OVERFLOW
1227
+
1228
+ no_wrap = pick_bool(no_wrap, self.no_wrap, False) or overflow == "ignore"
1229
+
1230
+ lines = Lines()
1231
+ for line in self.split(allow_blank=True):
1232
+ if "\t" in line:
1233
+ line.expand_tabs(tab_size)
1234
+ if no_wrap:
1235
+ new_lines = Lines([line])
1236
+ else:
1237
+ offsets = divide_line(str(line), width, fold=wrap_overflow == "fold")
1238
+ new_lines = line.divide(offsets)
1239
+ for line in new_lines:
1240
+ line.rstrip_end(width)
1241
+ if wrap_justify:
1242
+ new_lines.justify(
1243
+ console, width, justify=wrap_justify, overflow=wrap_overflow
1244
+ )
1245
+ for line in new_lines:
1246
+ line.truncate(width, overflow=wrap_overflow)
1247
+ lines.extend(new_lines)
1248
+ return lines
1249
+
1250
+ def fit(self, width: int) -> Lines:
1251
+ """Fit the text in to given width by chopping in to lines.
1252
+
1253
+ Args:
1254
+ width (int): Maximum characters in a line.
1255
+
1256
+ Returns:
1257
+ Lines: Lines container.
1258
+ """
1259
+ lines: Lines = Lines()
1260
+ append = lines.append
1261
+ for line in self.split():
1262
+ line.set_length(width)
1263
+ append(line)
1264
+ return lines
1265
+
1266
+ def detect_indentation(self) -> int:
1267
+ """Auto-detect indentation of code.
1268
+
1269
+ Returns:
1270
+ int: Number of spaces used to indent code.
1271
+ """
1272
+
1273
+ _indentations = {
1274
+ len(match.group(1))
1275
+ for match in re.finditer(r"^( *)(.*)$", self.plain, flags=re.MULTILINE)
1276
+ }
1277
+
1278
+ try:
1279
+ indentation = (
1280
+ reduce(gcd, [indent for indent in _indentations if not indent % 2]) or 1
1281
+ )
1282
+ except TypeError:
1283
+ indentation = 1
1284
+
1285
+ return indentation
1286
+
1287
+ def with_indent_guides(
1288
+ self,
1289
+ indent_size: Optional[int] = None,
1290
+ *,
1291
+ character: str = "β”‚",
1292
+ style: StyleType = "dim green",
1293
+ ) -> "Text":
1294
+ """Adds indent guide lines to text.
1295
+
1296
+ Args:
1297
+ indent_size (Optional[int]): Size of indentation, or None to auto detect. Defaults to None.
1298
+ character (str, optional): Character to use for indentation. Defaults to "β”‚".
1299
+ style (Union[Style, str], optional): Style of indent guides.
1300
+
1301
+ Returns:
1302
+ Text: New text with indentation guides.
1303
+ """
1304
+
1305
+ _indent_size = self.detect_indentation() if indent_size is None else indent_size
1306
+
1307
+ text = self.copy()
1308
+ text.expand_tabs()
1309
+ indent_line = f"{character}{' ' * (_indent_size - 1)}"
1310
+
1311
+ re_indent = re.compile(r"^( *)(.*)$")
1312
+ new_lines: List[Text] = []
1313
+ add_line = new_lines.append
1314
+ blank_lines = 0
1315
+ for line in text.split(allow_blank=True):
1316
+ match = re_indent.match(line.plain)
1317
+ if not match or not match.group(2):
1318
+ blank_lines += 1
1319
+ continue
1320
+ indent = match.group(1)
1321
+ full_indents, remaining_space = divmod(len(indent), _indent_size)
1322
+ new_indent = f"{indent_line * full_indents}{' ' * remaining_space}"
1323
+ line.plain = new_indent + line.plain[len(new_indent) :]
1324
+ line.stylize(style, 0, len(new_indent))
1325
+ if blank_lines:
1326
+ new_lines.extend([Text(new_indent, style=style)] * blank_lines)
1327
+ blank_lines = 0
1328
+ add_line(line)
1329
+ if blank_lines:
1330
+ new_lines.extend([Text("", style=style)] * blank_lines)
1331
+
1332
+ new_text = text.blank_copy("\n").join(new_lines)
1333
+ return new_text
1334
+
1335
+
1336
+ if __name__ == "__main__": # pragma: no cover
1337
+ from pip._vendor.rich.console import Console
1338
+
1339
+ text = Text(
1340
+ """\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"""
1341
+ )
1342
+ text.highlight_words(["Lorem"], "bold")
1343
+ text.highlight_words(["ipsum"], "italic")
1344
+
1345
+ console = Console()
1346
+
1347
+ console.rule("justify='left'")
1348
+ console.print(text, style="red")
1349
+ console.print()
1350
+
1351
+ console.rule("justify='center'")
1352
+ console.print(text, style="green", justify="center")
1353
+ console.print()
1354
+
1355
+ console.rule("justify='right'")
1356
+ console.print(text, style="blue", justify="right")
1357
+ console.print()
1358
+
1359
+ console.rule("justify='full'")
1360
+ console.print(text, style="magenta", justify="full")
1361
+ console.print()
.venv/lib/python3.12/site-packages/pip/_vendor/rich/theme.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import configparser
2
+ from typing import IO, Dict, List, Mapping, Optional
3
+
4
+ from .default_styles import DEFAULT_STYLES
5
+ from .style import Style, StyleType
6
+
7
+
8
+ class Theme:
9
+ """A container for style information, used by :class:`~rich.console.Console`.
10
+
11
+ Args:
12
+ styles (Dict[str, Style], optional): A mapping of style names on to styles. Defaults to None for a theme with no styles.
13
+ inherit (bool, optional): Inherit default styles. Defaults to True.
14
+ """
15
+
16
+ styles: Dict[str, Style]
17
+
18
+ def __init__(
19
+ self, styles: Optional[Mapping[str, StyleType]] = None, inherit: bool = True
20
+ ):
21
+ self.styles = DEFAULT_STYLES.copy() if inherit else {}
22
+ if styles is not None:
23
+ self.styles.update(
24
+ {
25
+ name: style if isinstance(style, Style) else Style.parse(style)
26
+ for name, style in styles.items()
27
+ }
28
+ )
29
+
30
+ @property
31
+ def config(self) -> str:
32
+ """Get contents of a config file for this theme."""
33
+ config = "[styles]\n" + "\n".join(
34
+ f"{name} = {style}" for name, style in sorted(self.styles.items())
35
+ )
36
+ return config
37
+
38
+ @classmethod
39
+ def from_file(
40
+ cls, config_file: IO[str], source: Optional[str] = None, inherit: bool = True
41
+ ) -> "Theme":
42
+ """Load a theme from a text mode file.
43
+
44
+ Args:
45
+ config_file (IO[str]): An open conf file.
46
+ source (str, optional): The filename of the open file. Defaults to None.
47
+ inherit (bool, optional): Inherit default styles. Defaults to True.
48
+
49
+ Returns:
50
+ Theme: A New theme instance.
51
+ """
52
+ config = configparser.ConfigParser()
53
+ config.read_file(config_file, source=source)
54
+ styles = {name: Style.parse(value) for name, value in config.items("styles")}
55
+ theme = Theme(styles, inherit=inherit)
56
+ return theme
57
+
58
+ @classmethod
59
+ def read(
60
+ cls, path: str, inherit: bool = True, encoding: Optional[str] = None
61
+ ) -> "Theme":
62
+ """Read a theme from a path.
63
+
64
+ Args:
65
+ path (str): Path to a config file readable by Python configparser module.
66
+ inherit (bool, optional): Inherit default styles. Defaults to True.
67
+ encoding (str, optional): Encoding of the config file. Defaults to None.
68
+
69
+ Returns:
70
+ Theme: A new theme instance.
71
+ """
72
+ with open(path, encoding=encoding) as config_file:
73
+ return cls.from_file(config_file, source=path, inherit=inherit)
74
+
75
+
76
+ class ThemeStackError(Exception):
77
+ """Base exception for errors related to the theme stack."""
78
+
79
+
80
+ class ThemeStack:
81
+ """A stack of themes.
82
+
83
+ Args:
84
+ theme (Theme): A theme instance
85
+ """
86
+
87
+ def __init__(self, theme: Theme) -> None:
88
+ self._entries: List[Dict[str, Style]] = [theme.styles]
89
+ self.get = self._entries[-1].get
90
+
91
+ def push_theme(self, theme: Theme, inherit: bool = True) -> None:
92
+ """Push a theme on the top of the stack.
93
+
94
+ Args:
95
+ theme (Theme): A Theme instance.
96
+ inherit (boolean, optional): Inherit styles from current top of stack.
97
+ """
98
+ styles: Dict[str, Style]
99
+ styles = (
100
+ {**self._entries[-1], **theme.styles} if inherit else theme.styles.copy()
101
+ )
102
+ self._entries.append(styles)
103
+ self.get = self._entries[-1].get
104
+
105
+ def pop_theme(self) -> None:
106
+ """Pop (and discard) the top-most theme."""
107
+ if len(self._entries) == 1:
108
+ raise ThemeStackError("Unable to pop base theme")
109
+ self._entries.pop()
110
+ self.get = self._entries[-1].get
111
+
112
+
113
+ if __name__ == "__main__": # pragma: no cover
114
+ theme = Theme()
115
+ print(theme.config)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/themes.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from .default_styles import DEFAULT_STYLES
2
+ from .theme import Theme
3
+
4
+
5
+ DEFAULT = Theme(DEFAULT_STYLES)
.venv/lib/python3.12/site-packages/pip/_vendor/rich/traceback.py ADDED
@@ -0,0 +1,899 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ import linecache
3
+ import os
4
+ import sys
5
+ from dataclasses import dataclass, field
6
+ from itertools import islice
7
+ from traceback import walk_tb
8
+ from types import ModuleType, TracebackType
9
+ from typing import (
10
+ Any,
11
+ Callable,
12
+ Dict,
13
+ Iterable,
14
+ List,
15
+ Optional,
16
+ Sequence,
17
+ Set,
18
+ Tuple,
19
+ Type,
20
+ Union,
21
+ )
22
+
23
+ from pip._vendor.pygments.lexers import guess_lexer_for_filename
24
+ from pip._vendor.pygments.token import Comment, Keyword, Name, Number, Operator, String
25
+ from pip._vendor.pygments.token import Text as TextToken
26
+ from pip._vendor.pygments.token import Token
27
+ from pip._vendor.pygments.util import ClassNotFound
28
+
29
+ from . import pretty
30
+ from ._loop import loop_first_last, loop_last
31
+ from .columns import Columns
32
+ from .console import (
33
+ Console,
34
+ ConsoleOptions,
35
+ ConsoleRenderable,
36
+ Group,
37
+ RenderResult,
38
+ group,
39
+ )
40
+ from .constrain import Constrain
41
+ from .highlighter import RegexHighlighter, ReprHighlighter
42
+ from .panel import Panel
43
+ from .scope import render_scope
44
+ from .style import Style
45
+ from .syntax import Syntax, SyntaxPosition
46
+ from .text import Text
47
+ from .theme import Theme
48
+
49
+ WINDOWS = sys.platform == "win32"
50
+
51
+ LOCALS_MAX_LENGTH = 10
52
+ LOCALS_MAX_STRING = 80
53
+
54
+
55
+ def _iter_syntax_lines(
56
+ start: SyntaxPosition, end: SyntaxPosition
57
+ ) -> Iterable[Tuple[int, int, int]]:
58
+ """Yield start and end positions per line.
59
+
60
+ Args:
61
+ start: Start position.
62
+ end: End position.
63
+
64
+ Returns:
65
+ Iterable of (LINE, COLUMN1, COLUMN2).
66
+ """
67
+
68
+ line1, column1 = start
69
+ line2, column2 = end
70
+
71
+ if line1 == line2:
72
+ yield line1, column1, column2
73
+ else:
74
+ for first, last, line_no in loop_first_last(range(line1, line2 + 1)):
75
+ if first:
76
+ yield line_no, column1, -1
77
+ elif last:
78
+ yield line_no, 0, column2
79
+ else:
80
+ yield line_no, 0, -1
81
+
82
+
83
+ def install(
84
+ *,
85
+ console: Optional[Console] = None,
86
+ width: Optional[int] = 100,
87
+ code_width: Optional[int] = 88,
88
+ extra_lines: int = 3,
89
+ theme: Optional[str] = None,
90
+ word_wrap: bool = False,
91
+ show_locals: bool = False,
92
+ locals_max_length: int = LOCALS_MAX_LENGTH,
93
+ locals_max_string: int = LOCALS_MAX_STRING,
94
+ locals_hide_dunder: bool = True,
95
+ locals_hide_sunder: Optional[bool] = None,
96
+ indent_guides: bool = True,
97
+ suppress: Iterable[Union[str, ModuleType]] = (),
98
+ max_frames: int = 100,
99
+ ) -> Callable[[Type[BaseException], BaseException, Optional[TracebackType]], Any]:
100
+ """Install a rich traceback handler.
101
+
102
+ Once installed, any tracebacks will be printed with syntax highlighting and rich formatting.
103
+
104
+
105
+ Args:
106
+ console (Optional[Console], optional): Console to write exception to. Default uses internal Console instance.
107
+ width (Optional[int], optional): Width (in characters) of traceback. Defaults to 100.
108
+ code_width (Optional[int], optional): Code width (in characters) of traceback. Defaults to 88.
109
+ extra_lines (int, optional): Extra lines of code. Defaults to 3.
110
+ theme (Optional[str], optional): Pygments theme to use in traceback. Defaults to ``None`` which will pick
111
+ a theme appropriate for the platform.
112
+ word_wrap (bool, optional): Enable word wrapping of long lines. Defaults to False.
113
+ show_locals (bool, optional): Enable display of local variables. Defaults to False.
114
+ locals_max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation.
115
+ Defaults to 10.
116
+ locals_max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to 80.
117
+ locals_hide_dunder (bool, optional): Hide locals prefixed with double underscore. Defaults to True.
118
+ locals_hide_sunder (bool, optional): Hide locals prefixed with single underscore. Defaults to False.
119
+ indent_guides (bool, optional): Enable indent guides in code and locals. Defaults to True.
120
+ suppress (Sequence[Union[str, ModuleType]]): Optional sequence of modules or paths to exclude from traceback.
121
+
122
+ Returns:
123
+ Callable: The previous exception handler that was replaced.
124
+
125
+ """
126
+ traceback_console = Console(stderr=True) if console is None else console
127
+
128
+ locals_hide_sunder = (
129
+ True
130
+ if (traceback_console.is_jupyter and locals_hide_sunder is None)
131
+ else locals_hide_sunder
132
+ )
133
+
134
+ def excepthook(
135
+ type_: Type[BaseException],
136
+ value: BaseException,
137
+ traceback: Optional[TracebackType],
138
+ ) -> None:
139
+ exception_traceback = Traceback.from_exception(
140
+ type_,
141
+ value,
142
+ traceback,
143
+ width=width,
144
+ code_width=code_width,
145
+ extra_lines=extra_lines,
146
+ theme=theme,
147
+ word_wrap=word_wrap,
148
+ show_locals=show_locals,
149
+ locals_max_length=locals_max_length,
150
+ locals_max_string=locals_max_string,
151
+ locals_hide_dunder=locals_hide_dunder,
152
+ locals_hide_sunder=bool(locals_hide_sunder),
153
+ indent_guides=indent_guides,
154
+ suppress=suppress,
155
+ max_frames=max_frames,
156
+ )
157
+ traceback_console.print(exception_traceback)
158
+
159
+ def ipy_excepthook_closure(ip: Any) -> None: # pragma: no cover
160
+ tb_data = {} # store information about showtraceback call
161
+ default_showtraceback = ip.showtraceback # keep reference of default traceback
162
+
163
+ def ipy_show_traceback(*args: Any, **kwargs: Any) -> None:
164
+ """wrap the default ip.showtraceback to store info for ip._showtraceback"""
165
+ nonlocal tb_data
166
+ tb_data = kwargs
167
+ default_showtraceback(*args, **kwargs)
168
+
169
+ def ipy_display_traceback(
170
+ *args: Any, is_syntax: bool = False, **kwargs: Any
171
+ ) -> None:
172
+ """Internally called traceback from ip._showtraceback"""
173
+ nonlocal tb_data
174
+ exc_tuple = ip._get_exc_info()
175
+
176
+ # do not display trace on syntax error
177
+ tb: Optional[TracebackType] = None if is_syntax else exc_tuple[2]
178
+
179
+ # determine correct tb_offset
180
+ compiled = tb_data.get("running_compiled_code", False)
181
+ tb_offset = tb_data.get("tb_offset")
182
+ if tb_offset is None:
183
+ tb_offset = 1 if compiled else 0
184
+ # remove ipython internal frames from trace with tb_offset
185
+ for _ in range(tb_offset):
186
+ if tb is None:
187
+ break
188
+ tb = tb.tb_next
189
+
190
+ excepthook(exc_tuple[0], exc_tuple[1], tb)
191
+ tb_data = {} # clear data upon usage
192
+
193
+ # replace _showtraceback instead of showtraceback to allow ipython features such as debugging to work
194
+ # this is also what the ipython docs recommends to modify when subclassing InteractiveShell
195
+ ip._showtraceback = ipy_display_traceback
196
+ # add wrapper to capture tb_data
197
+ ip.showtraceback = ipy_show_traceback
198
+ ip.showsyntaxerror = lambda *args, **kwargs: ipy_display_traceback(
199
+ *args, is_syntax=True, **kwargs
200
+ )
201
+
202
+ try: # pragma: no cover
203
+ # if within ipython, use customized traceback
204
+ ip = get_ipython() # type: ignore[name-defined]
205
+ ipy_excepthook_closure(ip)
206
+ return sys.excepthook
207
+ except Exception:
208
+ # otherwise use default system hook
209
+ old_excepthook = sys.excepthook
210
+ sys.excepthook = excepthook
211
+ return old_excepthook
212
+
213
+
214
+ @dataclass
215
+ class Frame:
216
+ filename: str
217
+ lineno: int
218
+ name: str
219
+ line: str = ""
220
+ locals: Optional[Dict[str, pretty.Node]] = None
221
+ last_instruction: Optional[Tuple[Tuple[int, int], Tuple[int, int]]] = None
222
+
223
+
224
+ @dataclass
225
+ class _SyntaxError:
226
+ offset: int
227
+ filename: str
228
+ line: str
229
+ lineno: int
230
+ msg: str
231
+ notes: List[str] = field(default_factory=list)
232
+
233
+
234
+ @dataclass
235
+ class Stack:
236
+ exc_type: str
237
+ exc_value: str
238
+ syntax_error: Optional[_SyntaxError] = None
239
+ is_cause: bool = False
240
+ frames: List[Frame] = field(default_factory=list)
241
+ notes: List[str] = field(default_factory=list)
242
+ is_group: bool = False
243
+ exceptions: List["Trace"] = field(default_factory=list)
244
+
245
+
246
+ @dataclass
247
+ class Trace:
248
+ stacks: List[Stack]
249
+
250
+
251
+ class PathHighlighter(RegexHighlighter):
252
+ highlights = [r"(?P<dim>.*/)(?P<bold>.+)"]
253
+
254
+
255
+ class Traceback:
256
+ """A Console renderable that renders a traceback.
257
+
258
+ Args:
259
+ trace (Trace, optional): A `Trace` object produced from `extract`. Defaults to None, which uses
260
+ the last exception.
261
+ width (Optional[int], optional): Number of characters used to traceback. Defaults to 100.
262
+ code_width (Optional[int], optional): Number of code characters used to traceback. Defaults to 88.
263
+ extra_lines (int, optional): Additional lines of code to render. Defaults to 3.
264
+ theme (str, optional): Override pygments theme used in traceback.
265
+ word_wrap (bool, optional): Enable word wrapping of long lines. Defaults to False.
266
+ show_locals (bool, optional): Enable display of local variables. Defaults to False.
267
+ indent_guides (bool, optional): Enable indent guides in code and locals. Defaults to True.
268
+ locals_max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation.
269
+ Defaults to 10.
270
+ locals_max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to 80.
271
+ locals_hide_dunder (bool, optional): Hide locals prefixed with double underscore. Defaults to True.
272
+ locals_hide_sunder (bool, optional): Hide locals prefixed with single underscore. Defaults to False.
273
+ suppress (Sequence[Union[str, ModuleType]]): Optional sequence of modules or paths to exclude from traceback.
274
+ max_frames (int): Maximum number of frames to show in a traceback, 0 for no maximum. Defaults to 100.
275
+
276
+ """
277
+
278
+ LEXERS = {
279
+ "": "text",
280
+ ".py": "python",
281
+ ".pxd": "cython",
282
+ ".pyx": "cython",
283
+ ".pxi": "pyrex",
284
+ }
285
+
286
+ def __init__(
287
+ self,
288
+ trace: Optional[Trace] = None,
289
+ *,
290
+ width: Optional[int] = 100,
291
+ code_width: Optional[int] = 88,
292
+ extra_lines: int = 3,
293
+ theme: Optional[str] = None,
294
+ word_wrap: bool = False,
295
+ show_locals: bool = False,
296
+ locals_max_length: int = LOCALS_MAX_LENGTH,
297
+ locals_max_string: int = LOCALS_MAX_STRING,
298
+ locals_hide_dunder: bool = True,
299
+ locals_hide_sunder: bool = False,
300
+ indent_guides: bool = True,
301
+ suppress: Iterable[Union[str, ModuleType]] = (),
302
+ max_frames: int = 100,
303
+ ):
304
+ if trace is None:
305
+ exc_type, exc_value, traceback = sys.exc_info()
306
+ if exc_type is None or exc_value is None or traceback is None:
307
+ raise ValueError(
308
+ "Value for 'trace' required if not called in except: block"
309
+ )
310
+ trace = self.extract(
311
+ exc_type, exc_value, traceback, show_locals=show_locals
312
+ )
313
+ self.trace = trace
314
+ self.width = width
315
+ self.code_width = code_width
316
+ self.extra_lines = extra_lines
317
+ self.theme = Syntax.get_theme(theme or "ansi_dark")
318
+ self.word_wrap = word_wrap
319
+ self.show_locals = show_locals
320
+ self.indent_guides = indent_guides
321
+ self.locals_max_length = locals_max_length
322
+ self.locals_max_string = locals_max_string
323
+ self.locals_hide_dunder = locals_hide_dunder
324
+ self.locals_hide_sunder = locals_hide_sunder
325
+
326
+ self.suppress: Sequence[str] = []
327
+ for suppress_entity in suppress:
328
+ if not isinstance(suppress_entity, str):
329
+ assert (
330
+ suppress_entity.__file__ is not None
331
+ ), f"{suppress_entity!r} must be a module with '__file__' attribute"
332
+ path = os.path.dirname(suppress_entity.__file__)
333
+ else:
334
+ path = suppress_entity
335
+ path = os.path.normpath(os.path.abspath(path))
336
+ self.suppress.append(path)
337
+ self.max_frames = max(4, max_frames) if max_frames > 0 else 0
338
+
339
+ @classmethod
340
+ def from_exception(
341
+ cls,
342
+ exc_type: Type[Any],
343
+ exc_value: BaseException,
344
+ traceback: Optional[TracebackType],
345
+ *,
346
+ width: Optional[int] = 100,
347
+ code_width: Optional[int] = 88,
348
+ extra_lines: int = 3,
349
+ theme: Optional[str] = None,
350
+ word_wrap: bool = False,
351
+ show_locals: bool = False,
352
+ locals_max_length: int = LOCALS_MAX_LENGTH,
353
+ locals_max_string: int = LOCALS_MAX_STRING,
354
+ locals_hide_dunder: bool = True,
355
+ locals_hide_sunder: bool = False,
356
+ indent_guides: bool = True,
357
+ suppress: Iterable[Union[str, ModuleType]] = (),
358
+ max_frames: int = 100,
359
+ ) -> "Traceback":
360
+ """Create a traceback from exception info
361
+
362
+ Args:
363
+ exc_type (Type[BaseException]): Exception type.
364
+ exc_value (BaseException): Exception value.
365
+ traceback (TracebackType): Python Traceback object.
366
+ width (Optional[int], optional): Number of characters used to traceback. Defaults to 100.
367
+ code_width (Optional[int], optional): Number of code characters used to traceback. Defaults to 88.
368
+ extra_lines (int, optional): Additional lines of code to render. Defaults to 3.
369
+ theme (str, optional): Override pygments theme used in traceback.
370
+ word_wrap (bool, optional): Enable word wrapping of long lines. Defaults to False.
371
+ show_locals (bool, optional): Enable display of local variables. Defaults to False.
372
+ indent_guides (bool, optional): Enable indent guides in code and locals. Defaults to True.
373
+ locals_max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation.
374
+ Defaults to 10.
375
+ locals_max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to 80.
376
+ locals_hide_dunder (bool, optional): Hide locals prefixed with double underscore. Defaults to True.
377
+ locals_hide_sunder (bool, optional): Hide locals prefixed with single underscore. Defaults to False.
378
+ suppress (Iterable[Union[str, ModuleType]]): Optional sequence of modules or paths to exclude from traceback.
379
+ max_frames (int): Maximum number of frames to show in a traceback, 0 for no maximum. Defaults to 100.
380
+
381
+ Returns:
382
+ Traceback: A Traceback instance that may be printed.
383
+ """
384
+ rich_traceback = cls.extract(
385
+ exc_type,
386
+ exc_value,
387
+ traceback,
388
+ show_locals=show_locals,
389
+ locals_max_length=locals_max_length,
390
+ locals_max_string=locals_max_string,
391
+ locals_hide_dunder=locals_hide_dunder,
392
+ locals_hide_sunder=locals_hide_sunder,
393
+ )
394
+
395
+ return cls(
396
+ rich_traceback,
397
+ width=width,
398
+ code_width=code_width,
399
+ extra_lines=extra_lines,
400
+ theme=theme,
401
+ word_wrap=word_wrap,
402
+ show_locals=show_locals,
403
+ indent_guides=indent_guides,
404
+ locals_max_length=locals_max_length,
405
+ locals_max_string=locals_max_string,
406
+ locals_hide_dunder=locals_hide_dunder,
407
+ locals_hide_sunder=locals_hide_sunder,
408
+ suppress=suppress,
409
+ max_frames=max_frames,
410
+ )
411
+
412
+ @classmethod
413
+ def extract(
414
+ cls,
415
+ exc_type: Type[BaseException],
416
+ exc_value: BaseException,
417
+ traceback: Optional[TracebackType],
418
+ *,
419
+ show_locals: bool = False,
420
+ locals_max_length: int = LOCALS_MAX_LENGTH,
421
+ locals_max_string: int = LOCALS_MAX_STRING,
422
+ locals_hide_dunder: bool = True,
423
+ locals_hide_sunder: bool = False,
424
+ _visited_exceptions: Optional[Set[BaseException]] = None,
425
+ ) -> Trace:
426
+ """Extract traceback information.
427
+
428
+ Args:
429
+ exc_type (Type[BaseException]): Exception type.
430
+ exc_value (BaseException): Exception value.
431
+ traceback (TracebackType): Python Traceback object.
432
+ show_locals (bool, optional): Enable display of local variables. Defaults to False.
433
+ locals_max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation.
434
+ Defaults to 10.
435
+ locals_max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to 80.
436
+ locals_hide_dunder (bool, optional): Hide locals prefixed with double underscore. Defaults to True.
437
+ locals_hide_sunder (bool, optional): Hide locals prefixed with single underscore. Defaults to False.
438
+
439
+ Returns:
440
+ Trace: A Trace instance which you can use to construct a `Traceback`.
441
+ """
442
+
443
+ stacks: List[Stack] = []
444
+ is_cause = False
445
+
446
+ from pip._vendor.rich import _IMPORT_CWD
447
+
448
+ notes: List[str] = getattr(exc_value, "__notes__", None) or []
449
+
450
+ grouped_exceptions: Set[BaseException] = (
451
+ set() if _visited_exceptions is None else _visited_exceptions
452
+ )
453
+
454
+ def safe_str(_object: Any) -> str:
455
+ """Don't allow exceptions from __str__ to propagate."""
456
+ try:
457
+ return str(_object)
458
+ except Exception:
459
+ return "<exception str() failed>"
460
+
461
+ while True:
462
+ stack = Stack(
463
+ exc_type=safe_str(exc_type.__name__),
464
+ exc_value=safe_str(exc_value),
465
+ is_cause=is_cause,
466
+ notes=notes,
467
+ )
468
+
469
+ if sys.version_info >= (3, 11):
470
+ if isinstance(exc_value, (BaseExceptionGroup, ExceptionGroup)):
471
+ stack.is_group = True
472
+ for exception in exc_value.exceptions:
473
+ if exception in grouped_exceptions:
474
+ continue
475
+ grouped_exceptions.add(exception)
476
+ stack.exceptions.append(
477
+ Traceback.extract(
478
+ type(exception),
479
+ exception,
480
+ exception.__traceback__,
481
+ show_locals=show_locals,
482
+ locals_max_length=locals_max_length,
483
+ locals_hide_dunder=locals_hide_dunder,
484
+ locals_hide_sunder=locals_hide_sunder,
485
+ _visited_exceptions=grouped_exceptions,
486
+ )
487
+ )
488
+
489
+ if isinstance(exc_value, SyntaxError):
490
+ stack.syntax_error = _SyntaxError(
491
+ offset=exc_value.offset or 0,
492
+ filename=exc_value.filename or "?",
493
+ lineno=exc_value.lineno or 0,
494
+ line=exc_value.text or "",
495
+ msg=exc_value.msg,
496
+ notes=notes,
497
+ )
498
+
499
+ stacks.append(stack)
500
+ append = stack.frames.append
501
+
502
+ def get_locals(
503
+ iter_locals: Iterable[Tuple[str, object]],
504
+ ) -> Iterable[Tuple[str, object]]:
505
+ """Extract locals from an iterator of key pairs."""
506
+ if not (locals_hide_dunder or locals_hide_sunder):
507
+ yield from iter_locals
508
+ return
509
+ for key, value in iter_locals:
510
+ if locals_hide_dunder and key.startswith("__"):
511
+ continue
512
+ if locals_hide_sunder and key.startswith("_"):
513
+ continue
514
+ yield key, value
515
+
516
+ for frame_summary, line_no in walk_tb(traceback):
517
+ filename = frame_summary.f_code.co_filename
518
+
519
+ last_instruction: Optional[Tuple[Tuple[int, int], Tuple[int, int]]]
520
+ last_instruction = None
521
+ if sys.version_info >= (3, 11):
522
+ instruction_index = frame_summary.f_lasti // 2
523
+ instruction_position = next(
524
+ islice(
525
+ frame_summary.f_code.co_positions(),
526
+ instruction_index,
527
+ instruction_index + 1,
528
+ )
529
+ )
530
+ (
531
+ start_line,
532
+ end_line,
533
+ start_column,
534
+ end_column,
535
+ ) = instruction_position
536
+ if (
537
+ start_line is not None
538
+ and end_line is not None
539
+ and start_column is not None
540
+ and end_column is not None
541
+ ):
542
+ last_instruction = (
543
+ (start_line, start_column),
544
+ (end_line, end_column),
545
+ )
546
+
547
+ if filename and not filename.startswith("<"):
548
+ if not os.path.isabs(filename):
549
+ filename = os.path.join(_IMPORT_CWD, filename)
550
+ if frame_summary.f_locals.get("_rich_traceback_omit", False):
551
+ continue
552
+
553
+ frame = Frame(
554
+ filename=filename or "?",
555
+ lineno=line_no,
556
+ name=frame_summary.f_code.co_name,
557
+ locals=(
558
+ {
559
+ key: pretty.traverse(
560
+ value,
561
+ max_length=locals_max_length,
562
+ max_string=locals_max_string,
563
+ )
564
+ for key, value in get_locals(frame_summary.f_locals.items())
565
+ if not (inspect.isfunction(value) or inspect.isclass(value))
566
+ }
567
+ if show_locals
568
+ else None
569
+ ),
570
+ last_instruction=last_instruction,
571
+ )
572
+ append(frame)
573
+ if frame_summary.f_locals.get("_rich_traceback_guard", False):
574
+ del stack.frames[:]
575
+
576
+ if not grouped_exceptions:
577
+ cause = getattr(exc_value, "__cause__", None)
578
+ if cause is not None and cause is not exc_value:
579
+ exc_type = cause.__class__
580
+ exc_value = cause
581
+ # __traceback__ can be None, e.g. for exceptions raised by the
582
+ # 'multiprocessing' module
583
+ traceback = cause.__traceback__
584
+ is_cause = True
585
+ continue
586
+
587
+ cause = exc_value.__context__
588
+ if cause is not None and not getattr(
589
+ exc_value, "__suppress_context__", False
590
+ ):
591
+ exc_type = cause.__class__
592
+ exc_value = cause
593
+ traceback = cause.__traceback__
594
+ is_cause = False
595
+ continue
596
+ # No cover, code is reached but coverage doesn't recognize it.
597
+ break # pragma: no cover
598
+
599
+ trace = Trace(stacks=stacks)
600
+
601
+ return trace
602
+
603
+ def __rich_console__(
604
+ self, console: Console, options: ConsoleOptions
605
+ ) -> RenderResult:
606
+ theme = self.theme
607
+ background_style = theme.get_background_style()
608
+ token_style = theme.get_style_for_token
609
+
610
+ traceback_theme = Theme(
611
+ {
612
+ "pretty": token_style(TextToken),
613
+ "pygments.text": token_style(Token),
614
+ "pygments.string": token_style(String),
615
+ "pygments.function": token_style(Name.Function),
616
+ "pygments.number": token_style(Number),
617
+ "repr.indent": token_style(Comment) + Style(dim=True),
618
+ "repr.str": token_style(String),
619
+ "repr.brace": token_style(TextToken) + Style(bold=True),
620
+ "repr.number": token_style(Number),
621
+ "repr.bool_true": token_style(Keyword.Constant),
622
+ "repr.bool_false": token_style(Keyword.Constant),
623
+ "repr.none": token_style(Keyword.Constant),
624
+ "scope.border": token_style(String.Delimiter),
625
+ "scope.equals": token_style(Operator),
626
+ "scope.key": token_style(Name),
627
+ "scope.key.special": token_style(Name.Constant) + Style(dim=True),
628
+ },
629
+ inherit=False,
630
+ )
631
+
632
+ highlighter = ReprHighlighter()
633
+
634
+ @group()
635
+ def render_stack(stack: Stack, last: bool) -> RenderResult:
636
+ if stack.frames:
637
+ stack_renderable: ConsoleRenderable = Panel(
638
+ self._render_stack(stack),
639
+ title="[traceback.title]Traceback [dim](most recent call last)",
640
+ style=background_style,
641
+ border_style="traceback.border",
642
+ expand=True,
643
+ padding=(0, 1),
644
+ )
645
+ stack_renderable = Constrain(stack_renderable, self.width)
646
+ with console.use_theme(traceback_theme):
647
+ yield stack_renderable
648
+
649
+ if stack.syntax_error is not None:
650
+ with console.use_theme(traceback_theme):
651
+ yield Constrain(
652
+ Panel(
653
+ self._render_syntax_error(stack.syntax_error),
654
+ style=background_style,
655
+ border_style="traceback.border.syntax_error",
656
+ expand=True,
657
+ padding=(0, 1),
658
+ width=self.width,
659
+ ),
660
+ self.width,
661
+ )
662
+ yield Text.assemble(
663
+ (f"{stack.exc_type}: ", "traceback.exc_type"),
664
+ highlighter(stack.syntax_error.msg),
665
+ )
666
+ elif stack.exc_value:
667
+ yield Text.assemble(
668
+ (f"{stack.exc_type}: ", "traceback.exc_type"),
669
+ highlighter(stack.exc_value),
670
+ )
671
+ else:
672
+ yield Text.assemble((f"{stack.exc_type}", "traceback.exc_type"))
673
+
674
+ for note in stack.notes:
675
+ yield Text.assemble(("[NOTE] ", "traceback.note"), highlighter(note))
676
+
677
+ if stack.is_group:
678
+ for group_no, group_exception in enumerate(stack.exceptions, 1):
679
+ grouped_exceptions: List[Group] = []
680
+ for group_last, group_stack in loop_last(group_exception.stacks):
681
+ grouped_exceptions.append(render_stack(group_stack, group_last))
682
+ yield ""
683
+ yield Constrain(
684
+ Panel(
685
+ Group(*grouped_exceptions),
686
+ title=f"Sub-exception #{group_no}",
687
+ border_style="traceback.group.border",
688
+ ),
689
+ self.width,
690
+ )
691
+
692
+ if not last:
693
+ if stack.is_cause:
694
+ yield Text.from_markup(
695
+ "\n[i]The above exception was the direct cause of the following exception:\n",
696
+ )
697
+ else:
698
+ yield Text.from_markup(
699
+ "\n[i]During handling of the above exception, another exception occurred:\n",
700
+ )
701
+
702
+ for last, stack in loop_last(reversed(self.trace.stacks)):
703
+ yield render_stack(stack, last)
704
+
705
+ @group()
706
+ def _render_syntax_error(self, syntax_error: _SyntaxError) -> RenderResult:
707
+ highlighter = ReprHighlighter()
708
+ path_highlighter = PathHighlighter()
709
+ if syntax_error.filename != "<stdin>":
710
+ if os.path.exists(syntax_error.filename):
711
+ text = Text.assemble(
712
+ (f" {syntax_error.filename}", "pygments.string"),
713
+ (":", "pygments.text"),
714
+ (str(syntax_error.lineno), "pygments.number"),
715
+ style="pygments.text",
716
+ )
717
+ yield path_highlighter(text)
718
+ syntax_error_text = highlighter(syntax_error.line.rstrip())
719
+ syntax_error_text.no_wrap = True
720
+ offset = min(syntax_error.offset - 1, len(syntax_error_text))
721
+ syntax_error_text.stylize("bold underline", offset, offset)
722
+ syntax_error_text += Text.from_markup(
723
+ "\n" + " " * offset + "[traceback.offset]β–²[/]",
724
+ style="pygments.text",
725
+ )
726
+ yield syntax_error_text
727
+
728
+ @classmethod
729
+ def _guess_lexer(cls, filename: str, code: str) -> str:
730
+ ext = os.path.splitext(filename)[-1]
731
+ if not ext:
732
+ # No extension, look at first line to see if it is a hashbang
733
+ # Note, this is an educated guess and not a guarantee
734
+ # If it fails, the only downside is that the code is highlighted strangely
735
+ new_line_index = code.index("\n")
736
+ first_line = code[:new_line_index] if new_line_index != -1 else code
737
+ if first_line.startswith("#!") and "python" in first_line.lower():
738
+ return "python"
739
+ try:
740
+ return cls.LEXERS.get(ext) or guess_lexer_for_filename(filename, code).name
741
+ except ClassNotFound:
742
+ return "text"
743
+
744
+ @group()
745
+ def _render_stack(self, stack: Stack) -> RenderResult:
746
+ path_highlighter = PathHighlighter()
747
+ theme = self.theme
748
+
749
+ def render_locals(frame: Frame) -> Iterable[ConsoleRenderable]:
750
+ if frame.locals:
751
+ yield render_scope(
752
+ frame.locals,
753
+ title="locals",
754
+ indent_guides=self.indent_guides,
755
+ max_length=self.locals_max_length,
756
+ max_string=self.locals_max_string,
757
+ )
758
+
759
+ exclude_frames: Optional[range] = None
760
+ if self.max_frames != 0:
761
+ exclude_frames = range(
762
+ self.max_frames // 2,
763
+ len(stack.frames) - self.max_frames // 2,
764
+ )
765
+
766
+ excluded = False
767
+ for frame_index, frame in enumerate(stack.frames):
768
+ if exclude_frames and frame_index in exclude_frames:
769
+ excluded = True
770
+ continue
771
+
772
+ if excluded:
773
+ assert exclude_frames is not None
774
+ yield Text(
775
+ f"\n... {len(exclude_frames)} frames hidden ...",
776
+ justify="center",
777
+ style="traceback.error",
778
+ )
779
+ excluded = False
780
+
781
+ first = frame_index == 0
782
+ frame_filename = frame.filename
783
+ suppressed = any(frame_filename.startswith(path) for path in self.suppress)
784
+
785
+ if os.path.exists(frame.filename):
786
+ text = Text.assemble(
787
+ path_highlighter(Text(frame.filename, style="pygments.string")),
788
+ (":", "pygments.text"),
789
+ (str(frame.lineno), "pygments.number"),
790
+ " in ",
791
+ (frame.name, "pygments.function"),
792
+ style="pygments.text",
793
+ )
794
+ else:
795
+ text = Text.assemble(
796
+ "in ",
797
+ (frame.name, "pygments.function"),
798
+ (":", "pygments.text"),
799
+ (str(frame.lineno), "pygments.number"),
800
+ style="pygments.text",
801
+ )
802
+ if not frame.filename.startswith("<") and not first:
803
+ yield ""
804
+ yield text
805
+ if frame.filename.startswith("<"):
806
+ yield from render_locals(frame)
807
+ continue
808
+ if not suppressed:
809
+ try:
810
+ code_lines = linecache.getlines(frame.filename)
811
+ code = "".join(code_lines)
812
+ if not code:
813
+ # code may be an empty string if the file doesn't exist, OR
814
+ # if the traceback filename is generated dynamically
815
+ continue
816
+ lexer_name = self._guess_lexer(frame.filename, code)
817
+ syntax = Syntax(
818
+ code,
819
+ lexer_name,
820
+ theme=theme,
821
+ line_numbers=True,
822
+ line_range=(
823
+ frame.lineno - self.extra_lines,
824
+ frame.lineno + self.extra_lines,
825
+ ),
826
+ highlight_lines={frame.lineno},
827
+ word_wrap=self.word_wrap,
828
+ code_width=self.code_width,
829
+ indent_guides=self.indent_guides,
830
+ dedent=False,
831
+ )
832
+ yield ""
833
+ except Exception as error:
834
+ yield Text.assemble(
835
+ (f"\n{error}", "traceback.error"),
836
+ )
837
+ else:
838
+ if frame.last_instruction is not None:
839
+ start, end = frame.last_instruction
840
+
841
+ # Stylize a line at a time
842
+ # So that indentation isn't underlined (which looks bad)
843
+ for line1, column1, column2 in _iter_syntax_lines(start, end):
844
+ try:
845
+ if column1 == 0:
846
+ line = code_lines[line1 - 1]
847
+ column1 = len(line) - len(line.lstrip())
848
+ if column2 == -1:
849
+ column2 = len(code_lines[line1 - 1])
850
+ except IndexError:
851
+ # Being defensive here
852
+ # If last_instruction reports a line out-of-bounds, we don't want to crash
853
+ continue
854
+
855
+ syntax.stylize_range(
856
+ style="traceback.error_range",
857
+ start=(line1, column1),
858
+ end=(line1, column2),
859
+ )
860
+ yield (
861
+ Columns(
862
+ [
863
+ syntax,
864
+ *render_locals(frame),
865
+ ],
866
+ padding=1,
867
+ )
868
+ if frame.locals
869
+ else syntax
870
+ )
871
+
872
+
873
+ if __name__ == "__main__": # pragma: no cover
874
+ install(show_locals=True)
875
+ import sys
876
+
877
+ def bar(
878
+ a: Any,
879
+ ) -> None: # θΏ™ζ˜―ε―ΉδΊšζ΄²θ―­θ¨€ζ”―ζŒηš„ζ΅‹θ―•γ€‚ι’ε―Ήζ¨‘ζ£±δΈ€ε―ηš„ζƒ³ζ³•οΌŒζ‹’η»ηŒœζ΅‹ηš„θ―±ζƒ‘
880
+ one = 1
881
+ print(one / a)
882
+
883
+ def foo(a: Any) -> None:
884
+ _rich_traceback_guard = True
885
+ zed = {
886
+ "characters": {
887
+ "Paul Atreides",
888
+ "Vladimir Harkonnen",
889
+ "Thufir Hawat",
890
+ "Duncan Idaho",
891
+ },
892
+ "atomic_types": (None, False, True),
893
+ }
894
+ bar(a)
895
+
896
+ def error() -> None:
897
+ foo(0)
898
+
899
+ error()
.venv/lib/python3.12/site-packages/pip/_vendor/rich/tree.py ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Iterator, List, Optional, Tuple
2
+
3
+ from ._loop import loop_first, loop_last
4
+ from .console import Console, ConsoleOptions, RenderableType, RenderResult
5
+ from .jupyter import JupyterMixin
6
+ from .measure import Measurement
7
+ from .segment import Segment
8
+ from .style import Style, StyleStack, StyleType
9
+ from .styled import Styled
10
+
11
+ GuideType = Tuple[str, str, str, str]
12
+
13
+
14
+ class Tree(JupyterMixin):
15
+ """A renderable for a tree structure.
16
+
17
+ Attributes:
18
+ ASCII_GUIDES (GuideType): Guide lines used when Console.ascii_only is True.
19
+ TREE_GUIDES (List[GuideType, GuideType, GuideType]): Default guide lines.
20
+
21
+ Args:
22
+ label (RenderableType): The renderable or str for the tree label.
23
+ style (StyleType, optional): Style of this tree. Defaults to "tree".
24
+ guide_style (StyleType, optional): Style of the guide lines. Defaults to "tree.line".
25
+ expanded (bool, optional): Also display children. Defaults to True.
26
+ highlight (bool, optional): Highlight renderable (if str). Defaults to False.
27
+ hide_root (bool, optional): Hide the root node. Defaults to False.
28
+ """
29
+
30
+ ASCII_GUIDES = (" ", "| ", "+-- ", "`-- ")
31
+ TREE_GUIDES = [
32
+ (" ", "β”‚ ", "β”œβ”€β”€ ", "└── "),
33
+ (" ", "┃ ", "┣━━ ", "┗━━ "),
34
+ (" ", "β•‘ ", "╠══ ", "β•šβ•β• "),
35
+ ]
36
+
37
+ def __init__(
38
+ self,
39
+ label: RenderableType,
40
+ *,
41
+ style: StyleType = "tree",
42
+ guide_style: StyleType = "tree.line",
43
+ expanded: bool = True,
44
+ highlight: bool = False,
45
+ hide_root: bool = False,
46
+ ) -> None:
47
+ self.label = label
48
+ self.style = style
49
+ self.guide_style = guide_style
50
+ self.children: List[Tree] = []
51
+ self.expanded = expanded
52
+ self.highlight = highlight
53
+ self.hide_root = hide_root
54
+
55
+ def add(
56
+ self,
57
+ label: RenderableType,
58
+ *,
59
+ style: Optional[StyleType] = None,
60
+ guide_style: Optional[StyleType] = None,
61
+ expanded: bool = True,
62
+ highlight: Optional[bool] = False,
63
+ ) -> "Tree":
64
+ """Add a child tree.
65
+
66
+ Args:
67
+ label (RenderableType): The renderable or str for the tree label.
68
+ style (StyleType, optional): Style of this tree. Defaults to "tree".
69
+ guide_style (StyleType, optional): Style of the guide lines. Defaults to "tree.line".
70
+ expanded (bool, optional): Also display children. Defaults to True.
71
+ highlight (Optional[bool], optional): Highlight renderable (if str). Defaults to False.
72
+
73
+ Returns:
74
+ Tree: A new child Tree, which may be further modified.
75
+ """
76
+ node = Tree(
77
+ label,
78
+ style=self.style if style is None else style,
79
+ guide_style=self.guide_style if guide_style is None else guide_style,
80
+ expanded=expanded,
81
+ highlight=self.highlight if highlight is None else highlight,
82
+ )
83
+ self.children.append(node)
84
+ return node
85
+
86
+ def __rich_console__(
87
+ self, console: "Console", options: "ConsoleOptions"
88
+ ) -> "RenderResult":
89
+ stack: List[Iterator[Tuple[bool, Tree]]] = []
90
+ pop = stack.pop
91
+ push = stack.append
92
+ new_line = Segment.line()
93
+
94
+ get_style = console.get_style
95
+ null_style = Style.null()
96
+ guide_style = get_style(self.guide_style, default="") or null_style
97
+ SPACE, CONTINUE, FORK, END = range(4)
98
+
99
+ _Segment = Segment
100
+
101
+ def make_guide(index: int, style: Style) -> Segment:
102
+ """Make a Segment for a level of the guide lines."""
103
+ if options.ascii_only:
104
+ line = self.ASCII_GUIDES[index]
105
+ else:
106
+ guide = 1 if style.bold else (2 if style.underline2 else 0)
107
+ line = self.TREE_GUIDES[0 if options.legacy_windows else guide][index]
108
+ return _Segment(line, style)
109
+
110
+ levels: List[Segment] = [make_guide(CONTINUE, guide_style)]
111
+ push(iter(loop_last([self])))
112
+
113
+ guide_style_stack = StyleStack(get_style(self.guide_style))
114
+ style_stack = StyleStack(get_style(self.style))
115
+ remove_guide_styles = Style(bold=False, underline2=False)
116
+
117
+ depth = 0
118
+
119
+ while stack:
120
+ stack_node = pop()
121
+ try:
122
+ last, node = next(stack_node)
123
+ except StopIteration:
124
+ levels.pop()
125
+ if levels:
126
+ guide_style = levels[-1].style or null_style
127
+ levels[-1] = make_guide(FORK, guide_style)
128
+ guide_style_stack.pop()
129
+ style_stack.pop()
130
+ continue
131
+ push(stack_node)
132
+ if last:
133
+ levels[-1] = make_guide(END, levels[-1].style or null_style)
134
+
135
+ guide_style = guide_style_stack.current + get_style(node.guide_style)
136
+ style = style_stack.current + get_style(node.style)
137
+ prefix = levels[(2 if self.hide_root else 1) :]
138
+ renderable_lines = console.render_lines(
139
+ Styled(node.label, style),
140
+ options.update(
141
+ width=options.max_width
142
+ - sum(level.cell_length for level in prefix),
143
+ highlight=self.highlight,
144
+ height=None,
145
+ ),
146
+ pad=options.justify is not None,
147
+ )
148
+
149
+ if not (depth == 0 and self.hide_root):
150
+ for first, line in loop_first(renderable_lines):
151
+ if prefix:
152
+ yield from _Segment.apply_style(
153
+ prefix,
154
+ style.background_style,
155
+ post_style=remove_guide_styles,
156
+ )
157
+ yield from line
158
+ yield new_line
159
+ if first and prefix:
160
+ prefix[-1] = make_guide(
161
+ SPACE if last else CONTINUE, prefix[-1].style or null_style
162
+ )
163
+
164
+ if node.expanded and node.children:
165
+ levels[-1] = make_guide(
166
+ SPACE if last else CONTINUE, levels[-1].style or null_style
167
+ )
168
+ levels.append(
169
+ make_guide(END if len(node.children) == 1 else FORK, guide_style)
170
+ )
171
+ style_stack.push(get_style(node.style))
172
+ guide_style_stack.push(get_style(node.guide_style))
173
+ push(iter(loop_last(node.children)))
174
+ depth += 1
175
+
176
+ def __rich_measure__(
177
+ self, console: "Console", options: "ConsoleOptions"
178
+ ) -> "Measurement":
179
+ stack: List[Iterator[Tree]] = [iter([self])]
180
+ pop = stack.pop
181
+ push = stack.append
182
+ minimum = 0
183
+ maximum = 0
184
+ measure = Measurement.get
185
+ level = 0
186
+ while stack:
187
+ iter_tree = pop()
188
+ try:
189
+ tree = next(iter_tree)
190
+ except StopIteration:
191
+ level -= 1
192
+ continue
193
+ push(iter_tree)
194
+ min_measure, max_measure = measure(console, options, tree.label)
195
+ indent = level * 4
196
+ minimum = max(min_measure + indent, minimum)
197
+ maximum = max(max_measure + indent, maximum)
198
+ if tree.expanded and tree.children:
199
+ push(iter(tree.children))
200
+ level += 1
201
+ return Measurement(minimum, maximum)
202
+
203
+
204
+ if __name__ == "__main__": # pragma: no cover
205
+ from pip._vendor.rich.console import Group
206
+ from pip._vendor.rich.markdown import Markdown
207
+ from pip._vendor.rich.panel import Panel
208
+ from pip._vendor.rich.syntax import Syntax
209
+ from pip._vendor.rich.table import Table
210
+
211
+ table = Table(row_styles=["", "dim"])
212
+
213
+ table.add_column("Released", style="cyan", no_wrap=True)
214
+ table.add_column("Title", style="magenta")
215
+ table.add_column("Box Office", justify="right", style="green")
216
+
217
+ table.add_row("Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$952,110,690")
218
+ table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347")
219
+ table.add_row("Dec 15, 2017", "Star Wars Ep. V111: The Last Jedi", "$1,332,539,889")
220
+ table.add_row("Dec 16, 2016", "Rogue One: A Star Wars Story", "$1,332,439,889")
221
+
222
+ code = """\
223
+ class Segment(NamedTuple):
224
+ text: str = ""
225
+ style: Optional[Style] = None
226
+ is_control: bool = False
227
+ """
228
+ syntax = Syntax(code, "python", theme="monokai", line_numbers=True)
229
+
230
+ markdown = Markdown(
231
+ """\
232
+ ### example.md
233
+ > Hello, World!
234
+ >
235
+ > Markdown _all_ the things
236
+ """
237
+ )
238
+
239
+ root = Tree("🌲 [b green]Rich Tree", highlight=True, hide_root=True)
240
+
241
+ node = root.add(":file_folder: Renderables", guide_style="red")
242
+ simple_node = node.add(":file_folder: [bold yellow]Atomic", guide_style="uu green")
243
+ simple_node.add(Group("πŸ“„ Syntax", syntax))
244
+ simple_node.add(Group("πŸ“„ Markdown", Panel(markdown, border_style="green")))
245
+
246
+ containers_node = node.add(
247
+ ":file_folder: [bold magenta]Containers", guide_style="bold magenta"
248
+ )
249
+ containers_node.expanded = True
250
+ panel = Panel.fit("Just a panel", border_style="red")
251
+ containers_node.add(Group("πŸ“„ Panels", panel))
252
+
253
+ containers_node.add(Group("πŸ“„ [b magenta]Table", table))
254
+
255
+ console = Console()
256
+
257
+ console.print(root)