ZAIDX11 commited on
Commit
09d99cd
·
verified ·
1 Parent(s): e9673ce

Add files using upload-large-folder tool

Browse files
Files changed (20) hide show
  1. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/__init__.py +15 -0
  2. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_elffile.py +109 -0
  3. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_manylinux.py +262 -0
  4. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_musllinux.py +85 -0
  5. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_parser.py +353 -0
  6. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_structures.py +61 -0
  7. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_tokenizer.py +195 -0
  8. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/licenses/__init__.py +145 -0
  9. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/licenses/_spdx.py +759 -0
  10. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/utils.py +163 -0
  11. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/version.py +582 -0
  12. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py +0 -0
  13. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +631 -0
  14. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/android.py +249 -0
  15. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/api.py +299 -0
  16. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/macos.py +144 -0
  17. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/py.typed +0 -0
  18. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/unix.py +272 -0
  19. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/version.py +21 -0
  20. external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/windows.py +272 -0
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ __title__ = "packaging"
6
+ __summary__ = "Core utilities for Python packages"
7
+ __uri__ = "https://github.com/pypa/packaging"
8
+
9
+ __version__ = "25.0"
10
+
11
+ __author__ = "Donald Stufft and individual contributors"
12
+ __email__ = "donald@stufft.io"
13
+
14
+ __license__ = "BSD-2-Clause or Apache-2.0"
15
+ __copyright__ = f"2014 {__author__}"
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_elffile.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ELF file parser.
3
+
4
+ This provides a class ``ELFFile`` that parses an ELF executable in a similar
5
+ interface to ``ZipFile``. Only the read interface is implemented.
6
+
7
+ Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca
8
+ ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import enum
14
+ import os
15
+ import struct
16
+ from typing import IO
17
+
18
+
19
+ class ELFInvalid(ValueError):
20
+ pass
21
+
22
+
23
+ class EIClass(enum.IntEnum):
24
+ C32 = 1
25
+ C64 = 2
26
+
27
+
28
+ class EIData(enum.IntEnum):
29
+ Lsb = 1
30
+ Msb = 2
31
+
32
+
33
+ class EMachine(enum.IntEnum):
34
+ I386 = 3
35
+ S390 = 22
36
+ Arm = 40
37
+ X8664 = 62
38
+ AArc64 = 183
39
+
40
+
41
+ class ELFFile:
42
+ """
43
+ Representation of an ELF executable.
44
+ """
45
+
46
+ def __init__(self, f: IO[bytes]) -> None:
47
+ self._f = f
48
+
49
+ try:
50
+ ident = self._read("16B")
51
+ except struct.error as e:
52
+ raise ELFInvalid("unable to parse identification") from e
53
+ magic = bytes(ident[:4])
54
+ if magic != b"\x7fELF":
55
+ raise ELFInvalid(f"invalid magic: {magic!r}")
56
+
57
+ self.capacity = ident[4] # Format for program header (bitness).
58
+ self.encoding = ident[5] # Data structure encoding (endianness).
59
+
60
+ try:
61
+ # e_fmt: Format for program header.
62
+ # p_fmt: Format for section header.
63
+ # p_idx: Indexes to find p_type, p_offset, and p_filesz.
64
+ e_fmt, self._p_fmt, self._p_idx = {
65
+ (1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB.
66
+ (1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB.
67
+ (2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB.
68
+ (2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB.
69
+ }[(self.capacity, self.encoding)]
70
+ except KeyError as e:
71
+ raise ELFInvalid(
72
+ f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})"
73
+ ) from e
74
+
75
+ try:
76
+ (
77
+ _,
78
+ self.machine, # Architecture type.
79
+ _,
80
+ _,
81
+ self._e_phoff, # Offset of program header.
82
+ _,
83
+ self.flags, # Processor-specific flags.
84
+ _,
85
+ self._e_phentsize, # Size of section.
86
+ self._e_phnum, # Number of sections.
87
+ ) = self._read(e_fmt)
88
+ except struct.error as e:
89
+ raise ELFInvalid("unable to parse machine and section information") from e
90
+
91
+ def _read(self, fmt: str) -> tuple[int, ...]:
92
+ return struct.unpack(fmt, self._f.read(struct.calcsize(fmt)))
93
+
94
+ @property
95
+ def interpreter(self) -> str | None:
96
+ """
97
+ The path recorded in the ``PT_INTERP`` section header.
98
+ """
99
+ for index in range(self._e_phnum):
100
+ self._f.seek(self._e_phoff + self._e_phentsize * index)
101
+ try:
102
+ data = self._read(self._p_fmt)
103
+ except struct.error:
104
+ continue
105
+ if data[self._p_idx[0]] != 3: # Not PT_INTERP.
106
+ continue
107
+ self._f.seek(data[self._p_idx[1]])
108
+ return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0")
109
+ return None
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_manylinux.py ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import collections
4
+ import contextlib
5
+ import functools
6
+ import os
7
+ import re
8
+ import sys
9
+ import warnings
10
+ from typing import Generator, Iterator, NamedTuple, Sequence
11
+
12
+ from ._elffile import EIClass, EIData, ELFFile, EMachine
13
+
14
+ EF_ARM_ABIMASK = 0xFF000000
15
+ EF_ARM_ABI_VER5 = 0x05000000
16
+ EF_ARM_ABI_FLOAT_HARD = 0x00000400
17
+
18
+
19
+ # `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
20
+ # as the type for `path` until then.
21
+ @contextlib.contextmanager
22
+ def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]:
23
+ try:
24
+ with open(path, "rb") as f:
25
+ yield ELFFile(f)
26
+ except (OSError, TypeError, ValueError):
27
+ yield None
28
+
29
+
30
+ def _is_linux_armhf(executable: str) -> bool:
31
+ # hard-float ABI can be detected from the ELF header of the running
32
+ # process
33
+ # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
34
+ with _parse_elf(executable) as f:
35
+ return (
36
+ f is not None
37
+ and f.capacity == EIClass.C32
38
+ and f.encoding == EIData.Lsb
39
+ and f.machine == EMachine.Arm
40
+ and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5
41
+ and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD
42
+ )
43
+
44
+
45
+ def _is_linux_i686(executable: str) -> bool:
46
+ with _parse_elf(executable) as f:
47
+ return (
48
+ f is not None
49
+ and f.capacity == EIClass.C32
50
+ and f.encoding == EIData.Lsb
51
+ and f.machine == EMachine.I386
52
+ )
53
+
54
+
55
+ def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
56
+ if "armv7l" in archs:
57
+ return _is_linux_armhf(executable)
58
+ if "i686" in archs:
59
+ return _is_linux_i686(executable)
60
+ allowed_archs = {
61
+ "x86_64",
62
+ "aarch64",
63
+ "ppc64",
64
+ "ppc64le",
65
+ "s390x",
66
+ "loongarch64",
67
+ "riscv64",
68
+ }
69
+ return any(arch in allowed_archs for arch in archs)
70
+
71
+
72
+ # If glibc ever changes its major version, we need to know what the last
73
+ # minor version was, so we can build the complete list of all versions.
74
+ # For now, guess what the highest minor version might be, assume it will
75
+ # be 50 for testing. Once this actually happens, update the dictionary
76
+ # with the actual value.
77
+ _LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50)
78
+
79
+
80
+ class _GLibCVersion(NamedTuple):
81
+ major: int
82
+ minor: int
83
+
84
+
85
+ def _glibc_version_string_confstr() -> str | None:
86
+ """
87
+ Primary implementation of glibc_version_string using os.confstr.
88
+ """
89
+ # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
90
+ # to be broken or missing. This strategy is used in the standard library
91
+ # platform module.
92
+ # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
93
+ try:
94
+ # Should be a string like "glibc 2.17".
95
+ version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION")
96
+ assert version_string is not None
97
+ _, version = version_string.rsplit()
98
+ except (AssertionError, AttributeError, OSError, ValueError):
99
+ # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
100
+ return None
101
+ return version
102
+
103
+
104
+ def _glibc_version_string_ctypes() -> str | None:
105
+ """
106
+ Fallback implementation of glibc_version_string using ctypes.
107
+ """
108
+ try:
109
+ import ctypes
110
+ except ImportError:
111
+ return None
112
+
113
+ # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
114
+ # manpage says, "If filename is NULL, then the returned handle is for the
115
+ # main program". This way we can let the linker do the work to figure out
116
+ # which libc our process is actually using.
117
+ #
118
+ # We must also handle the special case where the executable is not a
119
+ # dynamically linked executable. This can occur when using musl libc,
120
+ # for example. In this situation, dlopen() will error, leading to an
121
+ # OSError. Interestingly, at least in the case of musl, there is no
122
+ # errno set on the OSError. The single string argument used to construct
123
+ # OSError comes from libc itself and is therefore not portable to
124
+ # hard code here. In any case, failure to call dlopen() means we
125
+ # can proceed, so we bail on our attempt.
126
+ try:
127
+ process_namespace = ctypes.CDLL(None)
128
+ except OSError:
129
+ return None
130
+
131
+ try:
132
+ gnu_get_libc_version = process_namespace.gnu_get_libc_version
133
+ except AttributeError:
134
+ # Symbol doesn't exist -> therefore, we are not linked to
135
+ # glibc.
136
+ return None
137
+
138
+ # Call gnu_get_libc_version, which returns a string like "2.5"
139
+ gnu_get_libc_version.restype = ctypes.c_char_p
140
+ version_str: str = gnu_get_libc_version()
141
+ # py2 / py3 compatibility:
142
+ if not isinstance(version_str, str):
143
+ version_str = version_str.decode("ascii")
144
+
145
+ return version_str
146
+
147
+
148
+ def _glibc_version_string() -> str | None:
149
+ """Returns glibc version string, or None if not using glibc."""
150
+ return _glibc_version_string_confstr() or _glibc_version_string_ctypes()
151
+
152
+
153
+ def _parse_glibc_version(version_str: str) -> tuple[int, int]:
154
+ """Parse glibc version.
155
+
156
+ We use a regexp instead of str.split because we want to discard any
157
+ random junk that might come after the minor version -- this might happen
158
+ in patched/forked versions of glibc (e.g. Linaro's version of glibc
159
+ uses version strings like "2.20-2014.11"). See gh-3588.
160
+ """
161
+ m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
162
+ if not m:
163
+ warnings.warn(
164
+ f"Expected glibc version with 2 components major.minor, got: {version_str}",
165
+ RuntimeWarning,
166
+ stacklevel=2,
167
+ )
168
+ return -1, -1
169
+ return int(m.group("major")), int(m.group("minor"))
170
+
171
+
172
+ @functools.lru_cache
173
+ def _get_glibc_version() -> tuple[int, int]:
174
+ version_str = _glibc_version_string()
175
+ if version_str is None:
176
+ return (-1, -1)
177
+ return _parse_glibc_version(version_str)
178
+
179
+
180
+ # From PEP 513, PEP 600
181
+ def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
182
+ sys_glibc = _get_glibc_version()
183
+ if sys_glibc < version:
184
+ return False
185
+ # Check for presence of _manylinux module.
186
+ try:
187
+ import _manylinux
188
+ except ImportError:
189
+ return True
190
+ if hasattr(_manylinux, "manylinux_compatible"):
191
+ result = _manylinux.manylinux_compatible(version[0], version[1], arch)
192
+ if result is not None:
193
+ return bool(result)
194
+ return True
195
+ if version == _GLibCVersion(2, 5):
196
+ if hasattr(_manylinux, "manylinux1_compatible"):
197
+ return bool(_manylinux.manylinux1_compatible)
198
+ if version == _GLibCVersion(2, 12):
199
+ if hasattr(_manylinux, "manylinux2010_compatible"):
200
+ return bool(_manylinux.manylinux2010_compatible)
201
+ if version == _GLibCVersion(2, 17):
202
+ if hasattr(_manylinux, "manylinux2014_compatible"):
203
+ return bool(_manylinux.manylinux2014_compatible)
204
+ return True
205
+
206
+
207
+ _LEGACY_MANYLINUX_MAP = {
208
+ # CentOS 7 w/ glibc 2.17 (PEP 599)
209
+ (2, 17): "manylinux2014",
210
+ # CentOS 6 w/ glibc 2.12 (PEP 571)
211
+ (2, 12): "manylinux2010",
212
+ # CentOS 5 w/ glibc 2.5 (PEP 513)
213
+ (2, 5): "manylinux1",
214
+ }
215
+
216
+
217
+ def platform_tags(archs: Sequence[str]) -> Iterator[str]:
218
+ """Generate manylinux tags compatible to the current platform.
219
+
220
+ :param archs: Sequence of compatible architectures.
221
+ The first one shall be the closest to the actual architecture and be the part of
222
+ platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
223
+ The ``linux_`` prefix is assumed as a prerequisite for the current platform to
224
+ be manylinux-compatible.
225
+
226
+ :returns: An iterator of compatible manylinux tags.
227
+ """
228
+ if not _have_compatible_abi(sys.executable, archs):
229
+ return
230
+ # Oldest glibc to be supported regardless of architecture is (2, 17).
231
+ too_old_glibc2 = _GLibCVersion(2, 16)
232
+ if set(archs) & {"x86_64", "i686"}:
233
+ # On x86/i686 also oldest glibc to be supported is (2, 5).
234
+ too_old_glibc2 = _GLibCVersion(2, 4)
235
+ current_glibc = _GLibCVersion(*_get_glibc_version())
236
+ glibc_max_list = [current_glibc]
237
+ # We can assume compatibility across glibc major versions.
238
+ # https://sourceware.org/bugzilla/show_bug.cgi?id=24636
239
+ #
240
+ # Build a list of maximum glibc versions so that we can
241
+ # output the canonical list of all glibc from current_glibc
242
+ # down to too_old_glibc2, including all intermediary versions.
243
+ for glibc_major in range(current_glibc.major - 1, 1, -1):
244
+ glibc_minor = _LAST_GLIBC_MINOR[glibc_major]
245
+ glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor))
246
+ for arch in archs:
247
+ for glibc_max in glibc_max_list:
248
+ if glibc_max.major == too_old_glibc2.major:
249
+ min_minor = too_old_glibc2.minor
250
+ else:
251
+ # For other glibc major versions oldest supported is (x, 0).
252
+ min_minor = -1
253
+ for glibc_minor in range(glibc_max.minor, min_minor, -1):
254
+ glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
255
+ tag = "manylinux_{}_{}".format(*glibc_version)
256
+ if _is_compatible(arch, glibc_version):
257
+ yield f"{tag}_{arch}"
258
+ # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
259
+ if glibc_version in _LEGACY_MANYLINUX_MAP:
260
+ legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
261
+ if _is_compatible(arch, glibc_version):
262
+ yield f"{legacy_tag}_{arch}"
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_musllinux.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """PEP 656 support.
2
+
3
+ This module implements logic to detect if the currently running Python is
4
+ linked against musl, and what musl version is used.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import functools
10
+ import re
11
+ import subprocess
12
+ import sys
13
+ from typing import Iterator, NamedTuple, Sequence
14
+
15
+ from ._elffile import ELFFile
16
+
17
+
18
+ class _MuslVersion(NamedTuple):
19
+ major: int
20
+ minor: int
21
+
22
+
23
+ def _parse_musl_version(output: str) -> _MuslVersion | None:
24
+ lines = [n for n in (n.strip() for n in output.splitlines()) if n]
25
+ if len(lines) < 2 or lines[0][:4] != "musl":
26
+ return None
27
+ m = re.match(r"Version (\d+)\.(\d+)", lines[1])
28
+ if not m:
29
+ return None
30
+ return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
31
+
32
+
33
+ @functools.lru_cache
34
+ def _get_musl_version(executable: str) -> _MuslVersion | None:
35
+ """Detect currently-running musl runtime version.
36
+
37
+ This is done by checking the specified executable's dynamic linking
38
+ information, and invoking the loader to parse its output for a version
39
+ string. If the loader is musl, the output would be something like::
40
+
41
+ musl libc (x86_64)
42
+ Version 1.2.2
43
+ Dynamic Program Loader
44
+ """
45
+ try:
46
+ with open(executable, "rb") as f:
47
+ ld = ELFFile(f).interpreter
48
+ except (OSError, TypeError, ValueError):
49
+ return None
50
+ if ld is None or "musl" not in ld:
51
+ return None
52
+ proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)
53
+ return _parse_musl_version(proc.stderr)
54
+
55
+
56
+ def platform_tags(archs: Sequence[str]) -> Iterator[str]:
57
+ """Generate musllinux tags compatible to the current platform.
58
+
59
+ :param archs: Sequence of compatible architectures.
60
+ The first one shall be the closest to the actual architecture and be the part of
61
+ platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
62
+ The ``linux_`` prefix is assumed as a prerequisite for the current platform to
63
+ be musllinux-compatible.
64
+
65
+ :returns: An iterator of compatible musllinux tags.
66
+ """
67
+ sys_musl = _get_musl_version(sys.executable)
68
+ if sys_musl is None: # Python not dynamically linked against musl.
69
+ return
70
+ for arch in archs:
71
+ for minor in range(sys_musl.minor, -1, -1):
72
+ yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
73
+
74
+
75
+ if __name__ == "__main__": # pragma: no cover
76
+ import sysconfig
77
+
78
+ plat = sysconfig.get_platform()
79
+ assert plat.startswith("linux-"), "not linux"
80
+
81
+ print("plat:", plat)
82
+ print("musl:", _get_musl_version(sys.executable))
83
+ print("tags:", end=" ")
84
+ for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):
85
+ print(t, end="\n ")
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_parser.py ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Handwritten parser of dependency specifiers.
2
+
3
+ The docstring for each __parse_* function contains EBNF-inspired grammar representing
4
+ the implementation.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import ast
10
+ from typing import NamedTuple, Sequence, Tuple, Union
11
+
12
+ from ._tokenizer import DEFAULT_RULES, Tokenizer
13
+
14
+
15
+ class Node:
16
+ def __init__(self, value: str) -> None:
17
+ self.value = value
18
+
19
+ def __str__(self) -> str:
20
+ return self.value
21
+
22
+ def __repr__(self) -> str:
23
+ return f"<{self.__class__.__name__}('{self}')>"
24
+
25
+ def serialize(self) -> str:
26
+ raise NotImplementedError
27
+
28
+
29
+ class Variable(Node):
30
+ def serialize(self) -> str:
31
+ return str(self)
32
+
33
+
34
+ class Value(Node):
35
+ def serialize(self) -> str:
36
+ return f'"{self}"'
37
+
38
+
39
+ class Op(Node):
40
+ def serialize(self) -> str:
41
+ return str(self)
42
+
43
+
44
+ MarkerVar = Union[Variable, Value]
45
+ MarkerItem = Tuple[MarkerVar, Op, MarkerVar]
46
+ MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]]
47
+ MarkerList = Sequence[Union["MarkerList", MarkerAtom, str]]
48
+
49
+
50
+ class ParsedRequirement(NamedTuple):
51
+ name: str
52
+ url: str
53
+ extras: list[str]
54
+ specifier: str
55
+ marker: MarkerList | None
56
+
57
+
58
+ # --------------------------------------------------------------------------------------
59
+ # Recursive descent parser for dependency specifier
60
+ # --------------------------------------------------------------------------------------
61
+ def parse_requirement(source: str) -> ParsedRequirement:
62
+ return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES))
63
+
64
+
65
+ def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement:
66
+ """
67
+ requirement = WS? IDENTIFIER WS? extras WS? requirement_details
68
+ """
69
+ tokenizer.consume("WS")
70
+
71
+ name_token = tokenizer.expect(
72
+ "IDENTIFIER", expected="package name at the start of dependency specifier"
73
+ )
74
+ name = name_token.text
75
+ tokenizer.consume("WS")
76
+
77
+ extras = _parse_extras(tokenizer)
78
+ tokenizer.consume("WS")
79
+
80
+ url, specifier, marker = _parse_requirement_details(tokenizer)
81
+ tokenizer.expect("END", expected="end of dependency specifier")
82
+
83
+ return ParsedRequirement(name, url, extras, specifier, marker)
84
+
85
+
86
+ def _parse_requirement_details(
87
+ tokenizer: Tokenizer,
88
+ ) -> tuple[str, str, MarkerList | None]:
89
+ """
90
+ requirement_details = AT URL (WS requirement_marker?)?
91
+ | specifier WS? (requirement_marker)?
92
+ """
93
+
94
+ specifier = ""
95
+ url = ""
96
+ marker = None
97
+
98
+ if tokenizer.check("AT"):
99
+ tokenizer.read()
100
+ tokenizer.consume("WS")
101
+
102
+ url_start = tokenizer.position
103
+ url = tokenizer.expect("URL", expected="URL after @").text
104
+ if tokenizer.check("END", peek=True):
105
+ return (url, specifier, marker)
106
+
107
+ tokenizer.expect("WS", expected="whitespace after URL")
108
+
109
+ # The input might end after whitespace.
110
+ if tokenizer.check("END", peek=True):
111
+ return (url, specifier, marker)
112
+
113
+ marker = _parse_requirement_marker(
114
+ tokenizer, span_start=url_start, after="URL and whitespace"
115
+ )
116
+ else:
117
+ specifier_start = tokenizer.position
118
+ specifier = _parse_specifier(tokenizer)
119
+ tokenizer.consume("WS")
120
+
121
+ if tokenizer.check("END", peek=True):
122
+ return (url, specifier, marker)
123
+
124
+ marker = _parse_requirement_marker(
125
+ tokenizer,
126
+ span_start=specifier_start,
127
+ after=(
128
+ "version specifier"
129
+ if specifier
130
+ else "name and no valid version specifier"
131
+ ),
132
+ )
133
+
134
+ return (url, specifier, marker)
135
+
136
+
137
+ def _parse_requirement_marker(
138
+ tokenizer: Tokenizer, *, span_start: int, after: str
139
+ ) -> MarkerList:
140
+ """
141
+ requirement_marker = SEMICOLON marker WS?
142
+ """
143
+
144
+ if not tokenizer.check("SEMICOLON"):
145
+ tokenizer.raise_syntax_error(
146
+ f"Expected end or semicolon (after {after})",
147
+ span_start=span_start,
148
+ )
149
+ tokenizer.read()
150
+
151
+ marker = _parse_marker(tokenizer)
152
+ tokenizer.consume("WS")
153
+
154
+ return marker
155
+
156
+
157
+ def _parse_extras(tokenizer: Tokenizer) -> list[str]:
158
+ """
159
+ extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)?
160
+ """
161
+ if not tokenizer.check("LEFT_BRACKET", peek=True):
162
+ return []
163
+
164
+ with tokenizer.enclosing_tokens(
165
+ "LEFT_BRACKET",
166
+ "RIGHT_BRACKET",
167
+ around="extras",
168
+ ):
169
+ tokenizer.consume("WS")
170
+ extras = _parse_extras_list(tokenizer)
171
+ tokenizer.consume("WS")
172
+
173
+ return extras
174
+
175
+
176
+ def _parse_extras_list(tokenizer: Tokenizer) -> list[str]:
177
+ """
178
+ extras_list = identifier (wsp* ',' wsp* identifier)*
179
+ """
180
+ extras: list[str] = []
181
+
182
+ if not tokenizer.check("IDENTIFIER"):
183
+ return extras
184
+
185
+ extras.append(tokenizer.read().text)
186
+
187
+ while True:
188
+ tokenizer.consume("WS")
189
+ if tokenizer.check("IDENTIFIER", peek=True):
190
+ tokenizer.raise_syntax_error("Expected comma between extra names")
191
+ elif not tokenizer.check("COMMA"):
192
+ break
193
+
194
+ tokenizer.read()
195
+ tokenizer.consume("WS")
196
+
197
+ extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma")
198
+ extras.append(extra_token.text)
199
+
200
+ return extras
201
+
202
+
203
+ def _parse_specifier(tokenizer: Tokenizer) -> str:
204
+ """
205
+ specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
206
+ | WS? version_many WS?
207
+ """
208
+ with tokenizer.enclosing_tokens(
209
+ "LEFT_PARENTHESIS",
210
+ "RIGHT_PARENTHESIS",
211
+ around="version specifier",
212
+ ):
213
+ tokenizer.consume("WS")
214
+ parsed_specifiers = _parse_version_many(tokenizer)
215
+ tokenizer.consume("WS")
216
+
217
+ return parsed_specifiers
218
+
219
+
220
+ def _parse_version_many(tokenizer: Tokenizer) -> str:
221
+ """
222
+ version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)?
223
+ """
224
+ parsed_specifiers = ""
225
+ while tokenizer.check("SPECIFIER"):
226
+ span_start = tokenizer.position
227
+ parsed_specifiers += tokenizer.read().text
228
+ if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):
229
+ tokenizer.raise_syntax_error(
230
+ ".* suffix can only be used with `==` or `!=` operators",
231
+ span_start=span_start,
232
+ span_end=tokenizer.position + 1,
233
+ )
234
+ if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
235
+ tokenizer.raise_syntax_error(
236
+ "Local version label can only be used with `==` or `!=` operators",
237
+ span_start=span_start,
238
+ span_end=tokenizer.position,
239
+ )
240
+ tokenizer.consume("WS")
241
+ if not tokenizer.check("COMMA"):
242
+ break
243
+ parsed_specifiers += tokenizer.read().text
244
+ tokenizer.consume("WS")
245
+
246
+ return parsed_specifiers
247
+
248
+
249
+ # --------------------------------------------------------------------------------------
250
+ # Recursive descent parser for marker expression
251
+ # --------------------------------------------------------------------------------------
252
+ def parse_marker(source: str) -> MarkerList:
253
+ return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES))
254
+
255
+
256
+ def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList:
257
+ retval = _parse_marker(tokenizer)
258
+ tokenizer.expect("END", expected="end of marker expression")
259
+ return retval
260
+
261
+
262
+ def _parse_marker(tokenizer: Tokenizer) -> MarkerList:
263
+ """
264
+ marker = marker_atom (BOOLOP marker_atom)+
265
+ """
266
+ expression = [_parse_marker_atom(tokenizer)]
267
+ while tokenizer.check("BOOLOP"):
268
+ token = tokenizer.read()
269
+ expr_right = _parse_marker_atom(tokenizer)
270
+ expression.extend((token.text, expr_right))
271
+ return expression
272
+
273
+
274
+ def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom:
275
+ """
276
+ marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS?
277
+ | WS? marker_item WS?
278
+ """
279
+
280
+ tokenizer.consume("WS")
281
+ if tokenizer.check("LEFT_PARENTHESIS", peek=True):
282
+ with tokenizer.enclosing_tokens(
283
+ "LEFT_PARENTHESIS",
284
+ "RIGHT_PARENTHESIS",
285
+ around="marker expression",
286
+ ):
287
+ tokenizer.consume("WS")
288
+ marker: MarkerAtom = _parse_marker(tokenizer)
289
+ tokenizer.consume("WS")
290
+ else:
291
+ marker = _parse_marker_item(tokenizer)
292
+ tokenizer.consume("WS")
293
+ return marker
294
+
295
+
296
+ def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem:
297
+ """
298
+ marker_item = WS? marker_var WS? marker_op WS? marker_var WS?
299
+ """
300
+ tokenizer.consume("WS")
301
+ marker_var_left = _parse_marker_var(tokenizer)
302
+ tokenizer.consume("WS")
303
+ marker_op = _parse_marker_op(tokenizer)
304
+ tokenizer.consume("WS")
305
+ marker_var_right = _parse_marker_var(tokenizer)
306
+ tokenizer.consume("WS")
307
+ return (marker_var_left, marker_op, marker_var_right)
308
+
309
+
310
+ def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
311
+ """
312
+ marker_var = VARIABLE | QUOTED_STRING
313
+ """
314
+ if tokenizer.check("VARIABLE"):
315
+ return process_env_var(tokenizer.read().text.replace(".", "_"))
316
+ elif tokenizer.check("QUOTED_STRING"):
317
+ return process_python_str(tokenizer.read().text)
318
+ else:
319
+ tokenizer.raise_syntax_error(
320
+ message="Expected a marker variable or quoted string"
321
+ )
322
+
323
+
324
+ def process_env_var(env_var: str) -> Variable:
325
+ if env_var in ("platform_python_implementation", "python_implementation"):
326
+ return Variable("platform_python_implementation")
327
+ else:
328
+ return Variable(env_var)
329
+
330
+
331
+ def process_python_str(python_str: str) -> Value:
332
+ value = ast.literal_eval(python_str)
333
+ return Value(str(value))
334
+
335
+
336
+ def _parse_marker_op(tokenizer: Tokenizer) -> Op:
337
+ """
338
+ marker_op = IN | NOT IN | OP
339
+ """
340
+ if tokenizer.check("IN"):
341
+ tokenizer.read()
342
+ return Op("in")
343
+ elif tokenizer.check("NOT"):
344
+ tokenizer.read()
345
+ tokenizer.expect("WS", expected="whitespace after 'not'")
346
+ tokenizer.expect("IN", expected="'in' after 'not'")
347
+ return Op("not in")
348
+ elif tokenizer.check("OP"):
349
+ return Op(tokenizer.read().text)
350
+ else:
351
+ return tokenizer.raise_syntax_error(
352
+ "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in"
353
+ )
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_structures.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+
6
+ class InfinityType:
7
+ def __repr__(self) -> str:
8
+ return "Infinity"
9
+
10
+ def __hash__(self) -> int:
11
+ return hash(repr(self))
12
+
13
+ def __lt__(self, other: object) -> bool:
14
+ return False
15
+
16
+ def __le__(self, other: object) -> bool:
17
+ return False
18
+
19
+ def __eq__(self, other: object) -> bool:
20
+ return isinstance(other, self.__class__)
21
+
22
+ def __gt__(self, other: object) -> bool:
23
+ return True
24
+
25
+ def __ge__(self, other: object) -> bool:
26
+ return True
27
+
28
+ def __neg__(self: object) -> "NegativeInfinityType":
29
+ return NegativeInfinity
30
+
31
+
32
+ Infinity = InfinityType()
33
+
34
+
35
+ class NegativeInfinityType:
36
+ def __repr__(self) -> str:
37
+ return "-Infinity"
38
+
39
+ def __hash__(self) -> int:
40
+ return hash(repr(self))
41
+
42
+ def __lt__(self, other: object) -> bool:
43
+ return True
44
+
45
+ def __le__(self, other: object) -> bool:
46
+ return True
47
+
48
+ def __eq__(self, other: object) -> bool:
49
+ return isinstance(other, self.__class__)
50
+
51
+ def __gt__(self, other: object) -> bool:
52
+ return False
53
+
54
+ def __ge__(self, other: object) -> bool:
55
+ return False
56
+
57
+ def __neg__(self: object) -> InfinityType:
58
+ return Infinity
59
+
60
+
61
+ NegativeInfinity = NegativeInfinityType()
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/_tokenizer.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import re
5
+ from dataclasses import dataclass
6
+ from typing import Iterator, NoReturn
7
+
8
+ from .specifiers import Specifier
9
+
10
+
11
+ @dataclass
12
+ class Token:
13
+ name: str
14
+ text: str
15
+ position: int
16
+
17
+
18
+ class ParserSyntaxError(Exception):
19
+ """The provided source text could not be parsed correctly."""
20
+
21
+ def __init__(
22
+ self,
23
+ message: str,
24
+ *,
25
+ source: str,
26
+ span: tuple[int, int],
27
+ ) -> None:
28
+ self.span = span
29
+ self.message = message
30
+ self.source = source
31
+
32
+ super().__init__()
33
+
34
+ def __str__(self) -> str:
35
+ marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^"
36
+ return "\n ".join([self.message, self.source, marker])
37
+
38
+
39
+ DEFAULT_RULES: dict[str, str | re.Pattern[str]] = {
40
+ "LEFT_PARENTHESIS": r"\(",
41
+ "RIGHT_PARENTHESIS": r"\)",
42
+ "LEFT_BRACKET": r"\[",
43
+ "RIGHT_BRACKET": r"\]",
44
+ "SEMICOLON": r";",
45
+ "COMMA": r",",
46
+ "QUOTED_STRING": re.compile(
47
+ r"""
48
+ (
49
+ ('[^']*')
50
+ |
51
+ ("[^"]*")
52
+ )
53
+ """,
54
+ re.VERBOSE,
55
+ ),
56
+ "OP": r"(===|==|~=|!=|<=|>=|<|>)",
57
+ "BOOLOP": r"\b(or|and)\b",
58
+ "IN": r"\bin\b",
59
+ "NOT": r"\bnot\b",
60
+ "VARIABLE": re.compile(
61
+ r"""
62
+ \b(
63
+ python_version
64
+ |python_full_version
65
+ |os[._]name
66
+ |sys[._]platform
67
+ |platform_(release|system)
68
+ |platform[._](version|machine|python_implementation)
69
+ |python_implementation
70
+ |implementation_(name|version)
71
+ |extras?
72
+ |dependency_groups
73
+ )\b
74
+ """,
75
+ re.VERBOSE,
76
+ ),
77
+ "SPECIFIER": re.compile(
78
+ Specifier._operator_regex_str + Specifier._version_regex_str,
79
+ re.VERBOSE | re.IGNORECASE,
80
+ ),
81
+ "AT": r"\@",
82
+ "URL": r"[^ \t]+",
83
+ "IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
84
+ "VERSION_PREFIX_TRAIL": r"\.\*",
85
+ "VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
86
+ "WS": r"[ \t]+",
87
+ "END": r"$",
88
+ }
89
+
90
+
91
+ class Tokenizer:
92
+ """Context-sensitive token parsing.
93
+
94
+ Provides methods to examine the input stream to check whether the next token
95
+ matches.
96
+ """
97
+
98
+ def __init__(
99
+ self,
100
+ source: str,
101
+ *,
102
+ rules: dict[str, str | re.Pattern[str]],
103
+ ) -> None:
104
+ self.source = source
105
+ self.rules: dict[str, re.Pattern[str]] = {
106
+ name: re.compile(pattern) for name, pattern in rules.items()
107
+ }
108
+ self.next_token: Token | None = None
109
+ self.position = 0
110
+
111
+ def consume(self, name: str) -> None:
112
+ """Move beyond provided token name, if at current position."""
113
+ if self.check(name):
114
+ self.read()
115
+
116
+ def check(self, name: str, *, peek: bool = False) -> bool:
117
+ """Check whether the next token has the provided name.
118
+
119
+ By default, if the check succeeds, the token *must* be read before
120
+ another check. If `peek` is set to `True`, the token is not loaded and
121
+ would need to be checked again.
122
+ """
123
+ assert self.next_token is None, (
124
+ f"Cannot check for {name!r}, already have {self.next_token!r}"
125
+ )
126
+ assert name in self.rules, f"Unknown token name: {name!r}"
127
+
128
+ expression = self.rules[name]
129
+
130
+ match = expression.match(self.source, self.position)
131
+ if match is None:
132
+ return False
133
+ if not peek:
134
+ self.next_token = Token(name, match[0], self.position)
135
+ return True
136
+
137
+ def expect(self, name: str, *, expected: str) -> Token:
138
+ """Expect a certain token name next, failing with a syntax error otherwise.
139
+
140
+ The token is *not* read.
141
+ """
142
+ if not self.check(name):
143
+ raise self.raise_syntax_error(f"Expected {expected}")
144
+ return self.read()
145
+
146
+ def read(self) -> Token:
147
+ """Consume the next token and return it."""
148
+ token = self.next_token
149
+ assert token is not None
150
+
151
+ self.position += len(token.text)
152
+ self.next_token = None
153
+
154
+ return token
155
+
156
+ def raise_syntax_error(
157
+ self,
158
+ message: str,
159
+ *,
160
+ span_start: int | None = None,
161
+ span_end: int | None = None,
162
+ ) -> NoReturn:
163
+ """Raise ParserSyntaxError at the given position."""
164
+ span = (
165
+ self.position if span_start is None else span_start,
166
+ self.position if span_end is None else span_end,
167
+ )
168
+ raise ParserSyntaxError(
169
+ message,
170
+ source=self.source,
171
+ span=span,
172
+ )
173
+
174
+ @contextlib.contextmanager
175
+ def enclosing_tokens(
176
+ self, open_token: str, close_token: str, *, around: str
177
+ ) -> Iterator[None]:
178
+ if self.check(open_token):
179
+ open_position = self.position
180
+ self.read()
181
+ else:
182
+ open_position = None
183
+
184
+ yield
185
+
186
+ if open_position is None:
187
+ return
188
+
189
+ if not self.check(close_token):
190
+ self.raise_syntax_error(
191
+ f"Expected matching {close_token} for {open_token}, after {around}",
192
+ span_start=open_position,
193
+ )
194
+
195
+ self.read()
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/licenses/__init__.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #######################################################################################
2
+ #
3
+ # Adapted from:
4
+ # https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py
5
+ #
6
+ # MIT License
7
+ #
8
+ # Copyright (c) 2017-present Ofek Lev <oss@ofek.dev>
9
+ #
10
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this
11
+ # software and associated documentation files (the "Software"), to deal in the Software
12
+ # without restriction, including without limitation the rights to use, copy, modify,
13
+ # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to the following
15
+ # conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be included in all copies
18
+ # or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22
+ # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
24
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25
+ # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+ #
28
+ # With additional allowance of arbitrary `LicenseRef-` identifiers, not just
29
+ # `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`.
30
+ #
31
+ #######################################################################################
32
+ from __future__ import annotations
33
+
34
+ import re
35
+ from typing import NewType, cast
36
+
37
+ from pip._vendor.packaging.licenses._spdx import EXCEPTIONS, LICENSES
38
+
39
+ __all__ = [
40
+ "InvalidLicenseExpression",
41
+ "NormalizedLicenseExpression",
42
+ "canonicalize_license_expression",
43
+ ]
44
+
45
+ license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$")
46
+
47
+ NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str)
48
+
49
+
50
+ class InvalidLicenseExpression(ValueError):
51
+ """Raised when a license-expression string is invalid
52
+
53
+ >>> canonicalize_license_expression("invalid")
54
+ Traceback (most recent call last):
55
+ ...
56
+ packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid'
57
+ """
58
+
59
+
60
+ def canonicalize_license_expression(
61
+ raw_license_expression: str,
62
+ ) -> NormalizedLicenseExpression:
63
+ if not raw_license_expression:
64
+ message = f"Invalid license expression: {raw_license_expression!r}"
65
+ raise InvalidLicenseExpression(message)
66
+
67
+ # Pad any parentheses so tokenization can be achieved by merely splitting on
68
+ # whitespace.
69
+ license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ")
70
+ licenseref_prefix = "LicenseRef-"
71
+ license_refs = {
72
+ ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :]
73
+ for ref in license_expression.split()
74
+ if ref.lower().startswith(licenseref_prefix.lower())
75
+ }
76
+
77
+ # Normalize to lower case so we can look up licenses/exceptions
78
+ # and so boolean operators are Python-compatible.
79
+ license_expression = license_expression.lower()
80
+
81
+ tokens = license_expression.split()
82
+
83
+ # Rather than implementing boolean logic, we create an expression that Python can
84
+ # parse. Everything that is not involved with the grammar itself is treated as
85
+ # `False` and the expression should evaluate as such.
86
+ python_tokens = []
87
+ for token in tokens:
88
+ if token not in {"or", "and", "with", "(", ")"}:
89
+ python_tokens.append("False")
90
+ elif token == "with":
91
+ python_tokens.append("or")
92
+ elif token == "(" and python_tokens and python_tokens[-1] not in {"or", "and"}:
93
+ message = f"Invalid license expression: {raw_license_expression!r}"
94
+ raise InvalidLicenseExpression(message)
95
+ else:
96
+ python_tokens.append(token)
97
+
98
+ python_expression = " ".join(python_tokens)
99
+ try:
100
+ invalid = eval(python_expression, globals(), locals())
101
+ except Exception:
102
+ invalid = True
103
+
104
+ if invalid is not False:
105
+ message = f"Invalid license expression: {raw_license_expression!r}"
106
+ raise InvalidLicenseExpression(message) from None
107
+
108
+ # Take a final pass to check for unknown licenses/exceptions.
109
+ normalized_tokens = []
110
+ for token in tokens:
111
+ if token in {"or", "and", "with", "(", ")"}:
112
+ normalized_tokens.append(token.upper())
113
+ continue
114
+
115
+ if normalized_tokens and normalized_tokens[-1] == "WITH":
116
+ if token not in EXCEPTIONS:
117
+ message = f"Unknown license exception: {token!r}"
118
+ raise InvalidLicenseExpression(message)
119
+
120
+ normalized_tokens.append(EXCEPTIONS[token]["id"])
121
+ else:
122
+ if token.endswith("+"):
123
+ final_token = token[:-1]
124
+ suffix = "+"
125
+ else:
126
+ final_token = token
127
+ suffix = ""
128
+
129
+ if final_token.startswith("licenseref-"):
130
+ if not license_ref_allowed.match(final_token):
131
+ message = f"Invalid licenseref: {final_token!r}"
132
+ raise InvalidLicenseExpression(message)
133
+ normalized_tokens.append(license_refs[final_token] + suffix)
134
+ else:
135
+ if final_token not in LICENSES:
136
+ message = f"Unknown license: {final_token!r}"
137
+ raise InvalidLicenseExpression(message)
138
+ normalized_tokens.append(LICENSES[final_token]["id"] + suffix)
139
+
140
+ normalized_expression = " ".join(normalized_tokens)
141
+
142
+ return cast(
143
+ NormalizedLicenseExpression,
144
+ normalized_expression.replace("( ", "(").replace(" )", ")"),
145
+ )
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/licenses/_spdx.py ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from __future__ import annotations
3
+
4
+ from typing import TypedDict
5
+
6
+ class SPDXLicense(TypedDict):
7
+ id: str
8
+ deprecated: bool
9
+
10
+ class SPDXException(TypedDict):
11
+ id: str
12
+ deprecated: bool
13
+
14
+
15
+ VERSION = '3.25.0'
16
+
17
+ LICENSES: dict[str, SPDXLicense] = {
18
+ '0bsd': {'id': '0BSD', 'deprecated': False},
19
+ '3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False},
20
+ 'aal': {'id': 'AAL', 'deprecated': False},
21
+ 'abstyles': {'id': 'Abstyles', 'deprecated': False},
22
+ 'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False},
23
+ 'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False},
24
+ 'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False},
25
+ 'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False},
26
+ 'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False},
27
+ 'adsl': {'id': 'ADSL', 'deprecated': False},
28
+ 'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False},
29
+ 'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False},
30
+ 'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False},
31
+ 'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False},
32
+ 'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False},
33
+ 'afmparse': {'id': 'Afmparse', 'deprecated': False},
34
+ 'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True},
35
+ 'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False},
36
+ 'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False},
37
+ 'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True},
38
+ 'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False},
39
+ 'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False},
40
+ 'aladdin': {'id': 'Aladdin', 'deprecated': False},
41
+ 'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False},
42
+ 'amdplpa': {'id': 'AMDPLPA', 'deprecated': False},
43
+ 'aml': {'id': 'AML', 'deprecated': False},
44
+ 'aml-glslang': {'id': 'AML-glslang', 'deprecated': False},
45
+ 'ampas': {'id': 'AMPAS', 'deprecated': False},
46
+ 'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False},
47
+ 'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False},
48
+ 'any-osi': {'id': 'any-OSI', 'deprecated': False},
49
+ 'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False},
50
+ 'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False},
51
+ 'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False},
52
+ 'apafml': {'id': 'APAFML', 'deprecated': False},
53
+ 'apl-1.0': {'id': 'APL-1.0', 'deprecated': False},
54
+ 'app-s2p': {'id': 'App-s2p', 'deprecated': False},
55
+ 'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False},
56
+ 'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False},
57
+ 'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False},
58
+ 'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False},
59
+ 'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False},
60
+ 'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False},
61
+ 'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False},
62
+ 'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False},
63
+ 'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False},
64
+ 'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False},
65
+ 'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False},
66
+ 'baekmuk': {'id': 'Baekmuk', 'deprecated': False},
67
+ 'bahyph': {'id': 'Bahyph', 'deprecated': False},
68
+ 'barr': {'id': 'Barr', 'deprecated': False},
69
+ 'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False},
70
+ 'beerware': {'id': 'Beerware', 'deprecated': False},
71
+ 'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False},
72
+ 'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False},
73
+ 'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False},
74
+ 'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False},
75
+ 'blessing': {'id': 'blessing', 'deprecated': False},
76
+ 'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False},
77
+ 'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False},
78
+ 'borceux': {'id': 'Borceux', 'deprecated': False},
79
+ 'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False},
80
+ 'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False},
81
+ 'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False},
82
+ 'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False},
83
+ 'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False},
84
+ 'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False},
85
+ 'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True},
86
+ 'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True},
87
+ 'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False},
88
+ 'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False},
89
+ 'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False},
90
+ 'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False},
91
+ 'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False},
92
+ 'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False},
93
+ 'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False},
94
+ 'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False},
95
+ 'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False},
96
+ 'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False},
97
+ 'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False},
98
+ 'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False},
99
+ 'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False},
100
+ 'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False},
101
+ 'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False},
102
+ 'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False},
103
+ 'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False},
104
+ 'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False},
105
+ 'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False},
106
+ 'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False},
107
+ 'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False},
108
+ 'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False},
109
+ 'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False},
110
+ 'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False},
111
+ 'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False},
112
+ 'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False},
113
+ 'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False},
114
+ 'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False},
115
+ 'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False},
116
+ 'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False},
117
+ 'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False},
118
+ 'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True},
119
+ 'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False},
120
+ 'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False},
121
+ 'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False},
122
+ 'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False},
123
+ 'caldera': {'id': 'Caldera', 'deprecated': False},
124
+ 'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False},
125
+ 'catharon': {'id': 'Catharon', 'deprecated': False},
126
+ 'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False},
127
+ 'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False},
128
+ 'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False},
129
+ 'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False},
130
+ 'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False},
131
+ 'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False},
132
+ 'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False},
133
+ 'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False},
134
+ 'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False},
135
+ 'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False},
136
+ 'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False},
137
+ 'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False},
138
+ 'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False},
139
+ 'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False},
140
+ 'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False},
141
+ 'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False},
142
+ 'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False},
143
+ 'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False},
144
+ 'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False},
145
+ 'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False},
146
+ 'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False},
147
+ 'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False},
148
+ 'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False},
149
+ 'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False},
150
+ 'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False},
151
+ 'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False},
152
+ 'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False},
153
+ 'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False},
154
+ 'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False},
155
+ 'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False},
156
+ 'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False},
157
+ 'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False},
158
+ 'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False},
159
+ 'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False},
160
+ 'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False},
161
+ 'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False},
162
+ 'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False},
163
+ 'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False},
164
+ 'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False},
165
+ 'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False},
166
+ 'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False},
167
+ 'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False},
168
+ 'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False},
169
+ 'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False},
170
+ 'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False},
171
+ 'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False},
172
+ 'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False},
173
+ 'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False},
174
+ 'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False},
175
+ 'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False},
176
+ 'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False},
177
+ 'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False},
178
+ 'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False},
179
+ 'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False},
180
+ 'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False},
181
+ 'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False},
182
+ 'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False},
183
+ 'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False},
184
+ 'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False},
185
+ 'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False},
186
+ 'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False},
187
+ 'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False},
188
+ 'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False},
189
+ 'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False},
190
+ 'cecill-b': {'id': 'CECILL-B', 'deprecated': False},
191
+ 'cecill-c': {'id': 'CECILL-C', 'deprecated': False},
192
+ 'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False},
193
+ 'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False},
194
+ 'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False},
195
+ 'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False},
196
+ 'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False},
197
+ 'cfitsio': {'id': 'CFITSIO', 'deprecated': False},
198
+ 'check-cvs': {'id': 'check-cvs', 'deprecated': False},
199
+ 'checkmk': {'id': 'checkmk', 'deprecated': False},
200
+ 'clartistic': {'id': 'ClArtistic', 'deprecated': False},
201
+ 'clips': {'id': 'Clips', 'deprecated': False},
202
+ 'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False},
203
+ 'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False},
204
+ 'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False},
205
+ 'cnri-python': {'id': 'CNRI-Python', 'deprecated': False},
206
+ 'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False},
207
+ 'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False},
208
+ 'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False},
209
+ 'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False},
210
+ 'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False},
211
+ 'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False},
212
+ 'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False},
213
+ 'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False},
214
+ 'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False},
215
+ 'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False},
216
+ 'cronyx': {'id': 'Cronyx', 'deprecated': False},
217
+ 'crossword': {'id': 'Crossword', 'deprecated': False},
218
+ 'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False},
219
+ 'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False},
220
+ 'cube': {'id': 'Cube', 'deprecated': False},
221
+ 'curl': {'id': 'curl', 'deprecated': False},
222
+ 'cve-tou': {'id': 'cve-tou', 'deprecated': False},
223
+ 'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False},
224
+ 'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False},
225
+ 'diffmark': {'id': 'diffmark', 'deprecated': False},
226
+ 'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False},
227
+ 'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False},
228
+ 'doc': {'id': 'DOC', 'deprecated': False},
229
+ 'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False},
230
+ 'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False},
231
+ 'dotseqn': {'id': 'Dotseqn', 'deprecated': False},
232
+ 'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False},
233
+ 'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False},
234
+ 'dsdp': {'id': 'DSDP', 'deprecated': False},
235
+ 'dtoa': {'id': 'dtoa', 'deprecated': False},
236
+ 'dvipdfm': {'id': 'dvipdfm', 'deprecated': False},
237
+ 'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False},
238
+ 'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False},
239
+ 'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True},
240
+ 'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False},
241
+ 'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False},
242
+ 'egenix': {'id': 'eGenix', 'deprecated': False},
243
+ 'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False},
244
+ 'entessa': {'id': 'Entessa', 'deprecated': False},
245
+ 'epics': {'id': 'EPICS', 'deprecated': False},
246
+ 'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False},
247
+ 'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False},
248
+ 'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False},
249
+ 'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False},
250
+ 'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False},
251
+ 'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False},
252
+ 'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False},
253
+ 'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False},
254
+ 'eurosym': {'id': 'Eurosym', 'deprecated': False},
255
+ 'fair': {'id': 'Fair', 'deprecated': False},
256
+ 'fbm': {'id': 'FBM', 'deprecated': False},
257
+ 'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False},
258
+ 'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False},
259
+ 'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False},
260
+ 'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False},
261
+ 'freeimage': {'id': 'FreeImage', 'deprecated': False},
262
+ 'fsfap': {'id': 'FSFAP', 'deprecated': False},
263
+ 'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False},
264
+ 'fsful': {'id': 'FSFUL', 'deprecated': False},
265
+ 'fsfullr': {'id': 'FSFULLR', 'deprecated': False},
266
+ 'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False},
267
+ 'ftl': {'id': 'FTL', 'deprecated': False},
268
+ 'furuseth': {'id': 'Furuseth', 'deprecated': False},
269
+ 'fwlw': {'id': 'fwlw', 'deprecated': False},
270
+ 'gcr-docs': {'id': 'GCR-docs', 'deprecated': False},
271
+ 'gd': {'id': 'GD', 'deprecated': False},
272
+ 'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True},
273
+ 'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False},
274
+ 'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False},
275
+ 'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False},
276
+ 'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False},
277
+ 'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False},
278
+ 'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False},
279
+ 'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True},
280
+ 'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False},
281
+ 'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False},
282
+ 'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False},
283
+ 'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False},
284
+ 'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False},
285
+ 'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False},
286
+ 'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True},
287
+ 'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False},
288
+ 'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False},
289
+ 'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False},
290
+ 'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False},
291
+ 'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False},
292
+ 'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False},
293
+ 'giftware': {'id': 'Giftware', 'deprecated': False},
294
+ 'gl2ps': {'id': 'GL2PS', 'deprecated': False},
295
+ 'glide': {'id': 'Glide', 'deprecated': False},
296
+ 'glulxe': {'id': 'Glulxe', 'deprecated': False},
297
+ 'glwtpl': {'id': 'GLWTPL', 'deprecated': False},
298
+ 'gnuplot': {'id': 'gnuplot', 'deprecated': False},
299
+ 'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True},
300
+ 'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True},
301
+ 'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False},
302
+ 'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False},
303
+ 'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True},
304
+ 'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True},
305
+ 'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False},
306
+ 'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False},
307
+ 'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True},
308
+ 'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True},
309
+ 'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True},
310
+ 'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True},
311
+ 'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True},
312
+ 'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True},
313
+ 'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True},
314
+ 'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False},
315
+ 'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False},
316
+ 'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True},
317
+ 'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True},
318
+ 'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False},
319
+ 'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False},
320
+ 'gtkbook': {'id': 'gtkbook', 'deprecated': False},
321
+ 'gutmann': {'id': 'Gutmann', 'deprecated': False},
322
+ 'haskellreport': {'id': 'HaskellReport', 'deprecated': False},
323
+ 'hdparm': {'id': 'hdparm', 'deprecated': False},
324
+ 'hidapi': {'id': 'HIDAPI', 'deprecated': False},
325
+ 'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False},
326
+ 'hp-1986': {'id': 'HP-1986', 'deprecated': False},
327
+ 'hp-1989': {'id': 'HP-1989', 'deprecated': False},
328
+ 'hpnd': {'id': 'HPND', 'deprecated': False},
329
+ 'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False},
330
+ 'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False},
331
+ 'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False},
332
+ 'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False},
333
+ 'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False},
334
+ 'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False},
335
+ 'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False},
336
+ 'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False},
337
+ 'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False},
338
+ 'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False},
339
+ 'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False},
340
+ 'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False},
341
+ 'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False},
342
+ 'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False},
343
+ 'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False},
344
+ 'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False},
345
+ 'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False},
346
+ 'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False},
347
+ 'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False},
348
+ 'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False},
349
+ 'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False},
350
+ 'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False},
351
+ 'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False},
352
+ 'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False},
353
+ 'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False},
354
+ 'icu': {'id': 'ICU', 'deprecated': False},
355
+ 'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False},
356
+ 'ijg': {'id': 'IJG', 'deprecated': False},
357
+ 'ijg-short': {'id': 'IJG-short', 'deprecated': False},
358
+ 'imagemagick': {'id': 'ImageMagick', 'deprecated': False},
359
+ 'imatix': {'id': 'iMatix', 'deprecated': False},
360
+ 'imlib2': {'id': 'Imlib2', 'deprecated': False},
361
+ 'info-zip': {'id': 'Info-ZIP', 'deprecated': False},
362
+ 'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False},
363
+ 'intel': {'id': 'Intel', 'deprecated': False},
364
+ 'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False},
365
+ 'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False},
366
+ 'ipa': {'id': 'IPA', 'deprecated': False},
367
+ 'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False},
368
+ 'isc': {'id': 'ISC', 'deprecated': False},
369
+ 'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False},
370
+ 'jam': {'id': 'Jam', 'deprecated': False},
371
+ 'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False},
372
+ 'jpl-image': {'id': 'JPL-image', 'deprecated': False},
373
+ 'jpnic': {'id': 'JPNIC', 'deprecated': False},
374
+ 'json': {'id': 'JSON', 'deprecated': False},
375
+ 'kastrup': {'id': 'Kastrup', 'deprecated': False},
376
+ 'kazlib': {'id': 'Kazlib', 'deprecated': False},
377
+ 'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False},
378
+ 'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False},
379
+ 'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False},
380
+ 'latex2e': {'id': 'Latex2e', 'deprecated': False},
381
+ 'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False},
382
+ 'leptonica': {'id': 'Leptonica', 'deprecated': False},
383
+ 'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True},
384
+ 'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True},
385
+ 'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False},
386
+ 'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False},
387
+ 'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True},
388
+ 'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True},
389
+ 'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False},
390
+ 'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False},
391
+ 'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True},
392
+ 'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True},
393
+ 'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False},
394
+ 'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False},
395
+ 'lgpllr': {'id': 'LGPLLR', 'deprecated': False},
396
+ 'libpng': {'id': 'Libpng', 'deprecated': False},
397
+ 'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False},
398
+ 'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False},
399
+ 'libtiff': {'id': 'libtiff', 'deprecated': False},
400
+ 'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False},
401
+ 'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False},
402
+ 'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False},
403
+ 'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False},
404
+ 'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False},
405
+ 'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False},
406
+ 'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False},
407
+ 'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False},
408
+ 'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False},
409
+ 'loop': {'id': 'LOOP', 'deprecated': False},
410
+ 'lpd-document': {'id': 'LPD-document', 'deprecated': False},
411
+ 'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False},
412
+ 'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False},
413
+ 'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False},
414
+ 'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False},
415
+ 'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False},
416
+ 'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False},
417
+ 'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False},
418
+ 'lsof': {'id': 'lsof', 'deprecated': False},
419
+ 'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False},
420
+ 'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False},
421
+ 'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False},
422
+ 'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False},
423
+ 'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False},
424
+ 'magaz': {'id': 'magaz', 'deprecated': False},
425
+ 'mailprio': {'id': 'mailprio', 'deprecated': False},
426
+ 'makeindex': {'id': 'MakeIndex', 'deprecated': False},
427
+ 'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False},
428
+ 'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False},
429
+ 'metamail': {'id': 'metamail', 'deprecated': False},
430
+ 'minpack': {'id': 'Minpack', 'deprecated': False},
431
+ 'miros': {'id': 'MirOS', 'deprecated': False},
432
+ 'mit': {'id': 'MIT', 'deprecated': False},
433
+ 'mit-0': {'id': 'MIT-0', 'deprecated': False},
434
+ 'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False},
435
+ 'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False},
436
+ 'mit-enna': {'id': 'MIT-enna', 'deprecated': False},
437
+ 'mit-feh': {'id': 'MIT-feh', 'deprecated': False},
438
+ 'mit-festival': {'id': 'MIT-Festival', 'deprecated': False},
439
+ 'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False},
440
+ 'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False},
441
+ 'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False},
442
+ 'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False},
443
+ 'mit-wu': {'id': 'MIT-Wu', 'deprecated': False},
444
+ 'mitnfa': {'id': 'MITNFA', 'deprecated': False},
445
+ 'mmixware': {'id': 'MMIXware', 'deprecated': False},
446
+ 'motosoto': {'id': 'Motosoto', 'deprecated': False},
447
+ 'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False},
448
+ 'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False},
449
+ 'mpich2': {'id': 'mpich2', 'deprecated': False},
450
+ 'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False},
451
+ 'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False},
452
+ 'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False},
453
+ 'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False},
454
+ 'mplus': {'id': 'mplus', 'deprecated': False},
455
+ 'ms-lpl': {'id': 'MS-LPL', 'deprecated': False},
456
+ 'ms-pl': {'id': 'MS-PL', 'deprecated': False},
457
+ 'ms-rl': {'id': 'MS-RL', 'deprecated': False},
458
+ 'mtll': {'id': 'MTLL', 'deprecated': False},
459
+ 'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False},
460
+ 'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False},
461
+ 'multics': {'id': 'Multics', 'deprecated': False},
462
+ 'mup': {'id': 'Mup', 'deprecated': False},
463
+ 'naist-2003': {'id': 'NAIST-2003', 'deprecated': False},
464
+ 'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False},
465
+ 'naumen': {'id': 'Naumen', 'deprecated': False},
466
+ 'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False},
467
+ 'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False},
468
+ 'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False},
469
+ 'ncl': {'id': 'NCL', 'deprecated': False},
470
+ 'ncsa': {'id': 'NCSA', 'deprecated': False},
471
+ 'net-snmp': {'id': 'Net-SNMP', 'deprecated': True},
472
+ 'netcdf': {'id': 'NetCDF', 'deprecated': False},
473
+ 'newsletr': {'id': 'Newsletr', 'deprecated': False},
474
+ 'ngpl': {'id': 'NGPL', 'deprecated': False},
475
+ 'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False},
476
+ 'nist-pd': {'id': 'NIST-PD', 'deprecated': False},
477
+ 'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False},
478
+ 'nist-software': {'id': 'NIST-Software', 'deprecated': False},
479
+ 'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False},
480
+ 'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False},
481
+ 'nlpl': {'id': 'NLPL', 'deprecated': False},
482
+ 'nokia': {'id': 'Nokia', 'deprecated': False},
483
+ 'nosl': {'id': 'NOSL', 'deprecated': False},
484
+ 'noweb': {'id': 'Noweb', 'deprecated': False},
485
+ 'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False},
486
+ 'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False},
487
+ 'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False},
488
+ 'nrl': {'id': 'NRL', 'deprecated': False},
489
+ 'ntp': {'id': 'NTP', 'deprecated': False},
490
+ 'ntp-0': {'id': 'NTP-0', 'deprecated': False},
491
+ 'nunit': {'id': 'Nunit', 'deprecated': True},
492
+ 'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False},
493
+ 'oar': {'id': 'OAR', 'deprecated': False},
494
+ 'occt-pl': {'id': 'OCCT-PL', 'deprecated': False},
495
+ 'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False},
496
+ 'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False},
497
+ 'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False},
498
+ 'offis': {'id': 'OFFIS', 'deprecated': False},
499
+ 'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False},
500
+ 'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False},
501
+ 'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False},
502
+ 'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False},
503
+ 'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False},
504
+ 'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False},
505
+ 'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False},
506
+ 'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False},
507
+ 'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False},
508
+ 'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False},
509
+ 'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False},
510
+ 'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False},
511
+ 'ogtsl': {'id': 'OGTSL', 'deprecated': False},
512
+ 'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False},
513
+ 'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False},
514
+ 'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False},
515
+ 'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False},
516
+ 'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False},
517
+ 'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False},
518
+ 'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False},
519
+ 'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False},
520
+ 'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False},
521
+ 'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False},
522
+ 'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False},
523
+ 'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False},
524
+ 'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False},
525
+ 'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False},
526
+ 'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False},
527
+ 'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False},
528
+ 'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False},
529
+ 'oml': {'id': 'OML', 'deprecated': False},
530
+ 'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False},
531
+ 'openssl': {'id': 'OpenSSL', 'deprecated': False},
532
+ 'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False},
533
+ 'openvision': {'id': 'OpenVision', 'deprecated': False},
534
+ 'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False},
535
+ 'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False},
536
+ 'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False},
537
+ 'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False},
538
+ 'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False},
539
+ 'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False},
540
+ 'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False},
541
+ 'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False},
542
+ 'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False},
543
+ 'padl': {'id': 'PADL', 'deprecated': False},
544
+ 'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False},
545
+ 'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False},
546
+ 'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False},
547
+ 'php-3.0': {'id': 'PHP-3.0', 'deprecated': False},
548
+ 'php-3.01': {'id': 'PHP-3.01', 'deprecated': False},
549
+ 'pixar': {'id': 'Pixar', 'deprecated': False},
550
+ 'pkgconf': {'id': 'pkgconf', 'deprecated': False},
551
+ 'plexus': {'id': 'Plexus', 'deprecated': False},
552
+ 'pnmstitch': {'id': 'pnmstitch', 'deprecated': False},
553
+ 'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False},
554
+ 'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False},
555
+ 'postgresql': {'id': 'PostgreSQL', 'deprecated': False},
556
+ 'ppl': {'id': 'PPL', 'deprecated': False},
557
+ 'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False},
558
+ 'psfrag': {'id': 'psfrag', 'deprecated': False},
559
+ 'psutils': {'id': 'psutils', 'deprecated': False},
560
+ 'python-2.0': {'id': 'Python-2.0', 'deprecated': False},
561
+ 'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False},
562
+ 'python-ldap': {'id': 'python-ldap', 'deprecated': False},
563
+ 'qhull': {'id': 'Qhull', 'deprecated': False},
564
+ 'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False},
565
+ 'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False},
566
+ 'radvd': {'id': 'radvd', 'deprecated': False},
567
+ 'rdisc': {'id': 'Rdisc', 'deprecated': False},
568
+ 'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False},
569
+ 'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False},
570
+ 'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False},
571
+ 'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False},
572
+ 'rsa-md': {'id': 'RSA-MD', 'deprecated': False},
573
+ 'rscpl': {'id': 'RSCPL', 'deprecated': False},
574
+ 'ruby': {'id': 'Ruby', 'deprecated': False},
575
+ 'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False},
576
+ 'sax-pd': {'id': 'SAX-PD', 'deprecated': False},
577
+ 'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False},
578
+ 'saxpath': {'id': 'Saxpath', 'deprecated': False},
579
+ 'scea': {'id': 'SCEA', 'deprecated': False},
580
+ 'schemereport': {'id': 'SchemeReport', 'deprecated': False},
581
+ 'sendmail': {'id': 'Sendmail', 'deprecated': False},
582
+ 'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False},
583
+ 'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False},
584
+ 'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False},
585
+ 'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False},
586
+ 'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False},
587
+ 'sgp4': {'id': 'SGP4', 'deprecated': False},
588
+ 'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False},
589
+ 'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False},
590
+ 'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False},
591
+ 'sissl': {'id': 'SISSL', 'deprecated': False},
592
+ 'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False},
593
+ 'sl': {'id': 'SL', 'deprecated': False},
594
+ 'sleepycat': {'id': 'Sleepycat', 'deprecated': False},
595
+ 'smlnj': {'id': 'SMLNJ', 'deprecated': False},
596
+ 'smppl': {'id': 'SMPPL', 'deprecated': False},
597
+ 'snia': {'id': 'SNIA', 'deprecated': False},
598
+ 'snprintf': {'id': 'snprintf', 'deprecated': False},
599
+ 'softsurfer': {'id': 'softSurfer', 'deprecated': False},
600
+ 'soundex': {'id': 'Soundex', 'deprecated': False},
601
+ 'spencer-86': {'id': 'Spencer-86', 'deprecated': False},
602
+ 'spencer-94': {'id': 'Spencer-94', 'deprecated': False},
603
+ 'spencer-99': {'id': 'Spencer-99', 'deprecated': False},
604
+ 'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False},
605
+ 'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False},
606
+ 'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False},
607
+ 'ssh-short': {'id': 'SSH-short', 'deprecated': False},
608
+ 'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False},
609
+ 'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False},
610
+ 'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True},
611
+ 'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False},
612
+ 'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False},
613
+ 'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False},
614
+ 'sunpro': {'id': 'SunPro', 'deprecated': False},
615
+ 'swl': {'id': 'SWL', 'deprecated': False},
616
+ 'swrule': {'id': 'swrule', 'deprecated': False},
617
+ 'symlinks': {'id': 'Symlinks', 'deprecated': False},
618
+ 'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False},
619
+ 'tcl': {'id': 'TCL', 'deprecated': False},
620
+ 'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False},
621
+ 'termreadkey': {'id': 'TermReadKey', 'deprecated': False},
622
+ 'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False},
623
+ 'threeparttable': {'id': 'threeparttable', 'deprecated': False},
624
+ 'tmate': {'id': 'TMate', 'deprecated': False},
625
+ 'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False},
626
+ 'tosl': {'id': 'TOSL', 'deprecated': False},
627
+ 'tpdl': {'id': 'TPDL', 'deprecated': False},
628
+ 'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False},
629
+ 'ttwl': {'id': 'TTWL', 'deprecated': False},
630
+ 'ttyp0': {'id': 'TTYP0', 'deprecated': False},
631
+ 'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False},
632
+ 'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False},
633
+ 'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False},
634
+ 'ucar': {'id': 'UCAR', 'deprecated': False},
635
+ 'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False},
636
+ 'ulem': {'id': 'ulem', 'deprecated': False},
637
+ 'umich-merit': {'id': 'UMich-Merit', 'deprecated': False},
638
+ 'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False},
639
+ 'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False},
640
+ 'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False},
641
+ 'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False},
642
+ 'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False},
643
+ 'unlicense': {'id': 'Unlicense', 'deprecated': False},
644
+ 'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False},
645
+ 'urt-rle': {'id': 'URT-RLE', 'deprecated': False},
646
+ 'vim': {'id': 'Vim', 'deprecated': False},
647
+ 'vostrom': {'id': 'VOSTROM', 'deprecated': False},
648
+ 'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False},
649
+ 'w3c': {'id': 'W3C', 'deprecated': False},
650
+ 'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False},
651
+ 'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False},
652
+ 'w3m': {'id': 'w3m', 'deprecated': False},
653
+ 'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False},
654
+ 'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False},
655
+ 'wsuipa': {'id': 'Wsuipa', 'deprecated': False},
656
+ 'wtfpl': {'id': 'WTFPL', 'deprecated': False},
657
+ 'wxwindows': {'id': 'wxWindows', 'deprecated': True},
658
+ 'x11': {'id': 'X11', 'deprecated': False},
659
+ 'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False},
660
+ 'x11-swapped': {'id': 'X11-swapped', 'deprecated': False},
661
+ 'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False},
662
+ 'xerox': {'id': 'Xerox', 'deprecated': False},
663
+ 'xfig': {'id': 'Xfig', 'deprecated': False},
664
+ 'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False},
665
+ 'xinetd': {'id': 'xinetd', 'deprecated': False},
666
+ 'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False},
667
+ 'xlock': {'id': 'xlock', 'deprecated': False},
668
+ 'xnet': {'id': 'Xnet', 'deprecated': False},
669
+ 'xpp': {'id': 'xpp', 'deprecated': False},
670
+ 'xskat': {'id': 'XSkat', 'deprecated': False},
671
+ 'xzoom': {'id': 'xzoom', 'deprecated': False},
672
+ 'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False},
673
+ 'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False},
674
+ 'zed': {'id': 'Zed', 'deprecated': False},
675
+ 'zeeff': {'id': 'Zeeff', 'deprecated': False},
676
+ 'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False},
677
+ 'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False},
678
+ 'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False},
679
+ 'zlib': {'id': 'Zlib', 'deprecated': False},
680
+ 'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False},
681
+ 'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False},
682
+ 'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False},
683
+ 'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False},
684
+ }
685
+
686
+ EXCEPTIONS: dict[str, SPDXException] = {
687
+ '389-exception': {'id': '389-exception', 'deprecated': False},
688
+ 'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False},
689
+ 'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False},
690
+ 'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False},
691
+ 'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False},
692
+ 'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False},
693
+ 'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False},
694
+ 'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False},
695
+ 'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False},
696
+ 'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False},
697
+ 'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False},
698
+ 'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False},
699
+ 'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False},
700
+ 'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False},
701
+ 'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False},
702
+ 'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False},
703
+ 'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False},
704
+ 'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False},
705
+ 'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False},
706
+ 'fmt-exception': {'id': 'fmt-exception', 'deprecated': False},
707
+ 'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False},
708
+ 'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False},
709
+ 'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False},
710
+ 'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False},
711
+ 'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False},
712
+ 'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False},
713
+ 'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False},
714
+ 'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False},
715
+ 'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False},
716
+ 'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False},
717
+ 'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False},
718
+ 'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False},
719
+ 'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False},
720
+ 'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False},
721
+ 'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False},
722
+ 'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False},
723
+ 'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False},
724
+ 'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False},
725
+ 'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False},
726
+ 'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False},
727
+ 'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False},
728
+ 'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False},
729
+ 'llgpl': {'id': 'LLGPL', 'deprecated': False},
730
+ 'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False},
731
+ 'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False},
732
+ 'mif-exception': {'id': 'mif-exception', 'deprecated': False},
733
+ 'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True},
734
+ 'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False},
735
+ 'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False},
736
+ 'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False},
737
+ 'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False},
738
+ 'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False},
739
+ 'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False},
740
+ 'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False},
741
+ 'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False},
742
+ 'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False},
743
+ 'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False},
744
+ 'romic-exception': {'id': 'romic-exception', 'deprecated': False},
745
+ 'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False},
746
+ 'sane-exception': {'id': 'SANE-exception', 'deprecated': False},
747
+ 'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False},
748
+ 'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False},
749
+ 'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False},
750
+ 'swi-exception': {'id': 'SWI-exception', 'deprecated': False},
751
+ 'swift-exception': {'id': 'Swift-exception', 'deprecated': False},
752
+ 'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False},
753
+ 'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False},
754
+ 'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False},
755
+ 'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False},
756
+ 'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False},
757
+ 'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False},
758
+ 'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False},
759
+ }
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/utils.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ from __future__ import annotations
6
+
7
+ import functools
8
+ import re
9
+ from typing import NewType, Tuple, Union, cast
10
+
11
+ from .tags import Tag, parse_tag
12
+ from .version import InvalidVersion, Version, _TrimmedRelease
13
+
14
+ BuildTag = Union[Tuple[()], Tuple[int, str]]
15
+ NormalizedName = NewType("NormalizedName", str)
16
+
17
+
18
+ class InvalidName(ValueError):
19
+ """
20
+ An invalid distribution name; users should refer to the packaging user guide.
21
+ """
22
+
23
+
24
+ class InvalidWheelFilename(ValueError):
25
+ """
26
+ An invalid wheel filename was found, users should refer to PEP 427.
27
+ """
28
+
29
+
30
+ class InvalidSdistFilename(ValueError):
31
+ """
32
+ An invalid sdist filename was found, users should refer to the packaging user guide.
33
+ """
34
+
35
+
36
+ # Core metadata spec for `Name`
37
+ _validate_regex = re.compile(
38
+ r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
39
+ )
40
+ _canonicalize_regex = re.compile(r"[-_.]+")
41
+ _normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
42
+ # PEP 427: The build number must start with a digit.
43
+ _build_tag_regex = re.compile(r"(\d+)(.*)")
44
+
45
+
46
+ def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
47
+ if validate and not _validate_regex.match(name):
48
+ raise InvalidName(f"name is invalid: {name!r}")
49
+ # This is taken from PEP 503.
50
+ value = _canonicalize_regex.sub("-", name).lower()
51
+ return cast(NormalizedName, value)
52
+
53
+
54
+ def is_normalized_name(name: str) -> bool:
55
+ return _normalized_regex.match(name) is not None
56
+
57
+
58
+ @functools.singledispatch
59
+ def canonicalize_version(
60
+ version: Version | str, *, strip_trailing_zero: bool = True
61
+ ) -> str:
62
+ """
63
+ Return a canonical form of a version as a string.
64
+
65
+ >>> canonicalize_version('1.0.1')
66
+ '1.0.1'
67
+
68
+ Per PEP 625, versions may have multiple canonical forms, differing
69
+ only by trailing zeros.
70
+
71
+ >>> canonicalize_version('1.0.0')
72
+ '1'
73
+ >>> canonicalize_version('1.0.0', strip_trailing_zero=False)
74
+ '1.0.0'
75
+
76
+ Invalid versions are returned unaltered.
77
+
78
+ >>> canonicalize_version('foo bar baz')
79
+ 'foo bar baz'
80
+ """
81
+ return str(_TrimmedRelease(str(version)) if strip_trailing_zero else version)
82
+
83
+
84
+ @canonicalize_version.register
85
+ def _(version: str, *, strip_trailing_zero: bool = True) -> str:
86
+ try:
87
+ parsed = Version(version)
88
+ except InvalidVersion:
89
+ # Legacy versions cannot be normalized
90
+ return version
91
+ return canonicalize_version(parsed, strip_trailing_zero=strip_trailing_zero)
92
+
93
+
94
+ def parse_wheel_filename(
95
+ filename: str,
96
+ ) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]:
97
+ if not filename.endswith(".whl"):
98
+ raise InvalidWheelFilename(
99
+ f"Invalid wheel filename (extension must be '.whl'): {filename!r}"
100
+ )
101
+
102
+ filename = filename[:-4]
103
+ dashes = filename.count("-")
104
+ if dashes not in (4, 5):
105
+ raise InvalidWheelFilename(
106
+ f"Invalid wheel filename (wrong number of parts): {filename!r}"
107
+ )
108
+
109
+ parts = filename.split("-", dashes - 2)
110
+ name_part = parts[0]
111
+ # See PEP 427 for the rules on escaping the project name.
112
+ if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
113
+ raise InvalidWheelFilename(f"Invalid project name: {filename!r}")
114
+ name = canonicalize_name(name_part)
115
+
116
+ try:
117
+ version = Version(parts[1])
118
+ except InvalidVersion as e:
119
+ raise InvalidWheelFilename(
120
+ f"Invalid wheel filename (invalid version): {filename!r}"
121
+ ) from e
122
+
123
+ if dashes == 5:
124
+ build_part = parts[2]
125
+ build_match = _build_tag_regex.match(build_part)
126
+ if build_match is None:
127
+ raise InvalidWheelFilename(
128
+ f"Invalid build number: {build_part} in {filename!r}"
129
+ )
130
+ build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
131
+ else:
132
+ build = ()
133
+ tags = parse_tag(parts[-1])
134
+ return (name, version, build, tags)
135
+
136
+
137
+ def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
138
+ if filename.endswith(".tar.gz"):
139
+ file_stem = filename[: -len(".tar.gz")]
140
+ elif filename.endswith(".zip"):
141
+ file_stem = filename[: -len(".zip")]
142
+ else:
143
+ raise InvalidSdistFilename(
144
+ f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
145
+ f" {filename!r}"
146
+ )
147
+
148
+ # We are requiring a PEP 440 version, which cannot contain dashes,
149
+ # so we split on the last dash.
150
+ name_part, sep, version_part = file_stem.rpartition("-")
151
+ if not sep:
152
+ raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
153
+
154
+ name = canonicalize_name(name_part)
155
+
156
+ try:
157
+ version = Version(version_part)
158
+ except InvalidVersion as e:
159
+ raise InvalidSdistFilename(
160
+ f"Invalid sdist filename (invalid version): {filename!r}"
161
+ ) from e
162
+
163
+ return (name, version)
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/packaging/version.py ADDED
@@ -0,0 +1,582 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+ """
5
+ .. testsetup::
6
+
7
+ from pip._vendor.packaging.version import parse, Version
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import itertools
13
+ import re
14
+ from typing import Any, Callable, NamedTuple, SupportsInt, Tuple, Union
15
+
16
+ from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType
17
+
18
+ __all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "parse"]
19
+
20
+ LocalType = Tuple[Union[int, str], ...]
21
+
22
+ CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, Tuple[str, int]]
23
+ CmpLocalType = Union[
24
+ NegativeInfinityType,
25
+ Tuple[Union[Tuple[int, str], Tuple[NegativeInfinityType, Union[int, str]]], ...],
26
+ ]
27
+ CmpKey = Tuple[
28
+ int,
29
+ Tuple[int, ...],
30
+ CmpPrePostDevType,
31
+ CmpPrePostDevType,
32
+ CmpPrePostDevType,
33
+ CmpLocalType,
34
+ ]
35
+ VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool]
36
+
37
+
38
+ class _Version(NamedTuple):
39
+ epoch: int
40
+ release: tuple[int, ...]
41
+ dev: tuple[str, int] | None
42
+ pre: tuple[str, int] | None
43
+ post: tuple[str, int] | None
44
+ local: LocalType | None
45
+
46
+
47
+ def parse(version: str) -> Version:
48
+ """Parse the given version string.
49
+
50
+ >>> parse('1.0.dev1')
51
+ <Version('1.0.dev1')>
52
+
53
+ :param version: The version string to parse.
54
+ :raises InvalidVersion: When the version string is not a valid version.
55
+ """
56
+ return Version(version)
57
+
58
+
59
+ class InvalidVersion(ValueError):
60
+ """Raised when a version string is not a valid version.
61
+
62
+ >>> Version("invalid")
63
+ Traceback (most recent call last):
64
+ ...
65
+ packaging.version.InvalidVersion: Invalid version: 'invalid'
66
+ """
67
+
68
+
69
+ class _BaseVersion:
70
+ _key: tuple[Any, ...]
71
+
72
+ def __hash__(self) -> int:
73
+ return hash(self._key)
74
+
75
+ # Please keep the duplicated `isinstance` check
76
+ # in the six comparisons hereunder
77
+ # unless you find a way to avoid adding overhead function calls.
78
+ def __lt__(self, other: _BaseVersion) -> bool:
79
+ if not isinstance(other, _BaseVersion):
80
+ return NotImplemented
81
+
82
+ return self._key < other._key
83
+
84
+ def __le__(self, other: _BaseVersion) -> bool:
85
+ if not isinstance(other, _BaseVersion):
86
+ return NotImplemented
87
+
88
+ return self._key <= other._key
89
+
90
+ def __eq__(self, other: object) -> bool:
91
+ if not isinstance(other, _BaseVersion):
92
+ return NotImplemented
93
+
94
+ return self._key == other._key
95
+
96
+ def __ge__(self, other: _BaseVersion) -> bool:
97
+ if not isinstance(other, _BaseVersion):
98
+ return NotImplemented
99
+
100
+ return self._key >= other._key
101
+
102
+ def __gt__(self, other: _BaseVersion) -> bool:
103
+ if not isinstance(other, _BaseVersion):
104
+ return NotImplemented
105
+
106
+ return self._key > other._key
107
+
108
+ def __ne__(self, other: object) -> bool:
109
+ if not isinstance(other, _BaseVersion):
110
+ return NotImplemented
111
+
112
+ return self._key != other._key
113
+
114
+
115
+ # Deliberately not anchored to the start and end of the string, to make it
116
+ # easier for 3rd party code to reuse
117
+ _VERSION_PATTERN = r"""
118
+ v?
119
+ (?:
120
+ (?:(?P<epoch>[0-9]+)!)? # epoch
121
+ (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
122
+ (?P<pre> # pre-release
123
+ [-_\.]?
124
+ (?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
125
+ [-_\.]?
126
+ (?P<pre_n>[0-9]+)?
127
+ )?
128
+ (?P<post> # post release
129
+ (?:-(?P<post_n1>[0-9]+))
130
+ |
131
+ (?:
132
+ [-_\.]?
133
+ (?P<post_l>post|rev|r)
134
+ [-_\.]?
135
+ (?P<post_n2>[0-9]+)?
136
+ )
137
+ )?
138
+ (?P<dev> # dev release
139
+ [-_\.]?
140
+ (?P<dev_l>dev)
141
+ [-_\.]?
142
+ (?P<dev_n>[0-9]+)?
143
+ )?
144
+ )
145
+ (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
146
+ """
147
+
148
+ VERSION_PATTERN = _VERSION_PATTERN
149
+ """
150
+ A string containing the regular expression used to match a valid version.
151
+
152
+ The pattern is not anchored at either end, and is intended for embedding in larger
153
+ expressions (for example, matching a version number as part of a file name). The
154
+ regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
155
+ flags set.
156
+
157
+ :meta hide-value:
158
+ """
159
+
160
+
161
+ class Version(_BaseVersion):
162
+ """This class abstracts handling of a project's versions.
163
+
164
+ A :class:`Version` instance is comparison aware and can be compared and
165
+ sorted using the standard Python interfaces.
166
+
167
+ >>> v1 = Version("1.0a5")
168
+ >>> v2 = Version("1.0")
169
+ >>> v1
170
+ <Version('1.0a5')>
171
+ >>> v2
172
+ <Version('1.0')>
173
+ >>> v1 < v2
174
+ True
175
+ >>> v1 == v2
176
+ False
177
+ >>> v1 > v2
178
+ False
179
+ >>> v1 >= v2
180
+ False
181
+ >>> v1 <= v2
182
+ True
183
+ """
184
+
185
+ _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
186
+ _key: CmpKey
187
+
188
+ def __init__(self, version: str) -> None:
189
+ """Initialize a Version object.
190
+
191
+ :param version:
192
+ The string representation of a version which will be parsed and normalized
193
+ before use.
194
+ :raises InvalidVersion:
195
+ If the ``version`` does not conform to PEP 440 in any way then this
196
+ exception will be raised.
197
+ """
198
+
199
+ # Validate the version and parse it into pieces
200
+ match = self._regex.search(version)
201
+ if not match:
202
+ raise InvalidVersion(f"Invalid version: {version!r}")
203
+
204
+ # Store the parsed out pieces of the version
205
+ self._version = _Version(
206
+ epoch=int(match.group("epoch")) if match.group("epoch") else 0,
207
+ release=tuple(int(i) for i in match.group("release").split(".")),
208
+ pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
209
+ post=_parse_letter_version(
210
+ match.group("post_l"), match.group("post_n1") or match.group("post_n2")
211
+ ),
212
+ dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
213
+ local=_parse_local_version(match.group("local")),
214
+ )
215
+
216
+ # Generate a key which will be used for sorting
217
+ self._key = _cmpkey(
218
+ self._version.epoch,
219
+ self._version.release,
220
+ self._version.pre,
221
+ self._version.post,
222
+ self._version.dev,
223
+ self._version.local,
224
+ )
225
+
226
+ def __repr__(self) -> str:
227
+ """A representation of the Version that shows all internal state.
228
+
229
+ >>> Version('1.0.0')
230
+ <Version('1.0.0')>
231
+ """
232
+ return f"<Version('{self}')>"
233
+
234
+ def __str__(self) -> str:
235
+ """A string representation of the version that can be round-tripped.
236
+
237
+ >>> str(Version("1.0a5"))
238
+ '1.0a5'
239
+ """
240
+ parts = []
241
+
242
+ # Epoch
243
+ if self.epoch != 0:
244
+ parts.append(f"{self.epoch}!")
245
+
246
+ # Release segment
247
+ parts.append(".".join(str(x) for x in self.release))
248
+
249
+ # Pre-release
250
+ if self.pre is not None:
251
+ parts.append("".join(str(x) for x in self.pre))
252
+
253
+ # Post-release
254
+ if self.post is not None:
255
+ parts.append(f".post{self.post}")
256
+
257
+ # Development release
258
+ if self.dev is not None:
259
+ parts.append(f".dev{self.dev}")
260
+
261
+ # Local version segment
262
+ if self.local is not None:
263
+ parts.append(f"+{self.local}")
264
+
265
+ return "".join(parts)
266
+
267
+ @property
268
+ def epoch(self) -> int:
269
+ """The epoch of the version.
270
+
271
+ >>> Version("2.0.0").epoch
272
+ 0
273
+ >>> Version("1!2.0.0").epoch
274
+ 1
275
+ """
276
+ return self._version.epoch
277
+
278
+ @property
279
+ def release(self) -> tuple[int, ...]:
280
+ """The components of the "release" segment of the version.
281
+
282
+ >>> Version("1.2.3").release
283
+ (1, 2, 3)
284
+ >>> Version("2.0.0").release
285
+ (2, 0, 0)
286
+ >>> Version("1!2.0.0.post0").release
287
+ (2, 0, 0)
288
+
289
+ Includes trailing zeroes but not the epoch or any pre-release / development /
290
+ post-release suffixes.
291
+ """
292
+ return self._version.release
293
+
294
+ @property
295
+ def pre(self) -> tuple[str, int] | None:
296
+ """The pre-release segment of the version.
297
+
298
+ >>> print(Version("1.2.3").pre)
299
+ None
300
+ >>> Version("1.2.3a1").pre
301
+ ('a', 1)
302
+ >>> Version("1.2.3b1").pre
303
+ ('b', 1)
304
+ >>> Version("1.2.3rc1").pre
305
+ ('rc', 1)
306
+ """
307
+ return self._version.pre
308
+
309
+ @property
310
+ def post(self) -> int | None:
311
+ """The post-release number of the version.
312
+
313
+ >>> print(Version("1.2.3").post)
314
+ None
315
+ >>> Version("1.2.3.post1").post
316
+ 1
317
+ """
318
+ return self._version.post[1] if self._version.post else None
319
+
320
+ @property
321
+ def dev(self) -> int | None:
322
+ """The development number of the version.
323
+
324
+ >>> print(Version("1.2.3").dev)
325
+ None
326
+ >>> Version("1.2.3.dev1").dev
327
+ 1
328
+ """
329
+ return self._version.dev[1] if self._version.dev else None
330
+
331
+ @property
332
+ def local(self) -> str | None:
333
+ """The local version segment of the version.
334
+
335
+ >>> print(Version("1.2.3").local)
336
+ None
337
+ >>> Version("1.2.3+abc").local
338
+ 'abc'
339
+ """
340
+ if self._version.local:
341
+ return ".".join(str(x) for x in self._version.local)
342
+ else:
343
+ return None
344
+
345
+ @property
346
+ def public(self) -> str:
347
+ """The public portion of the version.
348
+
349
+ >>> Version("1.2.3").public
350
+ '1.2.3'
351
+ >>> Version("1.2.3+abc").public
352
+ '1.2.3'
353
+ >>> Version("1!1.2.3dev1+abc").public
354
+ '1!1.2.3.dev1'
355
+ """
356
+ return str(self).split("+", 1)[0]
357
+
358
+ @property
359
+ def base_version(self) -> str:
360
+ """The "base version" of the version.
361
+
362
+ >>> Version("1.2.3").base_version
363
+ '1.2.3'
364
+ >>> Version("1.2.3+abc").base_version
365
+ '1.2.3'
366
+ >>> Version("1!1.2.3dev1+abc").base_version
367
+ '1!1.2.3'
368
+
369
+ The "base version" is the public version of the project without any pre or post
370
+ release markers.
371
+ """
372
+ parts = []
373
+
374
+ # Epoch
375
+ if self.epoch != 0:
376
+ parts.append(f"{self.epoch}!")
377
+
378
+ # Release segment
379
+ parts.append(".".join(str(x) for x in self.release))
380
+
381
+ return "".join(parts)
382
+
383
+ @property
384
+ def is_prerelease(self) -> bool:
385
+ """Whether this version is a pre-release.
386
+
387
+ >>> Version("1.2.3").is_prerelease
388
+ False
389
+ >>> Version("1.2.3a1").is_prerelease
390
+ True
391
+ >>> Version("1.2.3b1").is_prerelease
392
+ True
393
+ >>> Version("1.2.3rc1").is_prerelease
394
+ True
395
+ >>> Version("1.2.3dev1").is_prerelease
396
+ True
397
+ """
398
+ return self.dev is not None or self.pre is not None
399
+
400
+ @property
401
+ def is_postrelease(self) -> bool:
402
+ """Whether this version is a post-release.
403
+
404
+ >>> Version("1.2.3").is_postrelease
405
+ False
406
+ >>> Version("1.2.3.post1").is_postrelease
407
+ True
408
+ """
409
+ return self.post is not None
410
+
411
+ @property
412
+ def is_devrelease(self) -> bool:
413
+ """Whether this version is a development release.
414
+
415
+ >>> Version("1.2.3").is_devrelease
416
+ False
417
+ >>> Version("1.2.3.dev1").is_devrelease
418
+ True
419
+ """
420
+ return self.dev is not None
421
+
422
+ @property
423
+ def major(self) -> int:
424
+ """The first item of :attr:`release` or ``0`` if unavailable.
425
+
426
+ >>> Version("1.2.3").major
427
+ 1
428
+ """
429
+ return self.release[0] if len(self.release) >= 1 else 0
430
+
431
+ @property
432
+ def minor(self) -> int:
433
+ """The second item of :attr:`release` or ``0`` if unavailable.
434
+
435
+ >>> Version("1.2.3").minor
436
+ 2
437
+ >>> Version("1").minor
438
+ 0
439
+ """
440
+ return self.release[1] if len(self.release) >= 2 else 0
441
+
442
+ @property
443
+ def micro(self) -> int:
444
+ """The third item of :attr:`release` or ``0`` if unavailable.
445
+
446
+ >>> Version("1.2.3").micro
447
+ 3
448
+ >>> Version("1").micro
449
+ 0
450
+ """
451
+ return self.release[2] if len(self.release) >= 3 else 0
452
+
453
+
454
+ class _TrimmedRelease(Version):
455
+ @property
456
+ def release(self) -> tuple[int, ...]:
457
+ """
458
+ Release segment without any trailing zeros.
459
+
460
+ >>> _TrimmedRelease('1.0.0').release
461
+ (1,)
462
+ >>> _TrimmedRelease('0.0').release
463
+ (0,)
464
+ """
465
+ rel = super().release
466
+ nonzeros = (index for index, val in enumerate(rel) if val)
467
+ last_nonzero = max(nonzeros, default=0)
468
+ return rel[: last_nonzero + 1]
469
+
470
+
471
+ def _parse_letter_version(
472
+ letter: str | None, number: str | bytes | SupportsInt | None
473
+ ) -> tuple[str, int] | None:
474
+ if letter:
475
+ # We consider there to be an implicit 0 in a pre-release if there is
476
+ # not a numeral associated with it.
477
+ if number is None:
478
+ number = 0
479
+
480
+ # We normalize any letters to their lower case form
481
+ letter = letter.lower()
482
+
483
+ # We consider some words to be alternate spellings of other words and
484
+ # in those cases we want to normalize the spellings to our preferred
485
+ # spelling.
486
+ if letter == "alpha":
487
+ letter = "a"
488
+ elif letter == "beta":
489
+ letter = "b"
490
+ elif letter in ["c", "pre", "preview"]:
491
+ letter = "rc"
492
+ elif letter in ["rev", "r"]:
493
+ letter = "post"
494
+
495
+ return letter, int(number)
496
+
497
+ assert not letter
498
+ if number:
499
+ # We assume if we are given a number, but we are not given a letter
500
+ # then this is using the implicit post release syntax (e.g. 1.0-1)
501
+ letter = "post"
502
+
503
+ return letter, int(number)
504
+
505
+ return None
506
+
507
+
508
+ _local_version_separators = re.compile(r"[\._-]")
509
+
510
+
511
+ def _parse_local_version(local: str | None) -> LocalType | None:
512
+ """
513
+ Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
514
+ """
515
+ if local is not None:
516
+ return tuple(
517
+ part.lower() if not part.isdigit() else int(part)
518
+ for part in _local_version_separators.split(local)
519
+ )
520
+ return None
521
+
522
+
523
+ def _cmpkey(
524
+ epoch: int,
525
+ release: tuple[int, ...],
526
+ pre: tuple[str, int] | None,
527
+ post: tuple[str, int] | None,
528
+ dev: tuple[str, int] | None,
529
+ local: LocalType | None,
530
+ ) -> CmpKey:
531
+ # When we compare a release version, we want to compare it with all of the
532
+ # trailing zeros removed. So we'll use a reverse the list, drop all the now
533
+ # leading zeros until we come to something non zero, then take the rest
534
+ # re-reverse it back into the correct order and make it a tuple and use
535
+ # that for our sorting key.
536
+ _release = tuple(
537
+ reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
538
+ )
539
+
540
+ # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
541
+ # We'll do this by abusing the pre segment, but we _only_ want to do this
542
+ # if there is not a pre or a post segment. If we have one of those then
543
+ # the normal sorting rules will handle this case correctly.
544
+ if pre is None and post is None and dev is not None:
545
+ _pre: CmpPrePostDevType = NegativeInfinity
546
+ # Versions without a pre-release (except as noted above) should sort after
547
+ # those with one.
548
+ elif pre is None:
549
+ _pre = Infinity
550
+ else:
551
+ _pre = pre
552
+
553
+ # Versions without a post segment should sort before those with one.
554
+ if post is None:
555
+ _post: CmpPrePostDevType = NegativeInfinity
556
+
557
+ else:
558
+ _post = post
559
+
560
+ # Versions without a development segment should sort after those with one.
561
+ if dev is None:
562
+ _dev: CmpPrePostDevType = Infinity
563
+
564
+ else:
565
+ _dev = dev
566
+
567
+ if local is None:
568
+ # Versions without a local segment should sort before those with one.
569
+ _local: CmpLocalType = NegativeInfinity
570
+ else:
571
+ # Versions with a local segment need that segment parsed to implement
572
+ # the sorting rules in PEP440.
573
+ # - Alpha numeric segments sort before numeric segments
574
+ # - Alpha numeric segments sort lexicographically
575
+ # - Numeric segments sort numerically
576
+ # - Shorter versions sort before longer versions when the prefixes
577
+ # match exactly
578
+ _local = tuple(
579
+ (i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local
580
+ )
581
+
582
+ return epoch, _release, _pre, _post, _dev, _local
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py ADDED
The diff for this file is too large to render. See raw diff
 
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/__init__.py ADDED
@@ -0,0 +1,631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Utilities for determining application-specific dirs.
3
+
4
+ See <https://github.com/platformdirs/platformdirs> for details and usage.
5
+
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ import sys
12
+ from typing import TYPE_CHECKING
13
+
14
+ from .api import PlatformDirsABC
15
+ from .version import __version__
16
+ from .version import __version_tuple__ as __version_info__
17
+
18
+ if TYPE_CHECKING:
19
+ from pathlib import Path
20
+ from typing import Literal
21
+
22
+ if sys.platform == "win32":
23
+ from pip._vendor.platformdirs.windows import Windows as _Result
24
+ elif sys.platform == "darwin":
25
+ from pip._vendor.platformdirs.macos import MacOS as _Result
26
+ else:
27
+ from pip._vendor.platformdirs.unix import Unix as _Result
28
+
29
+
30
+ def _set_platform_dir_class() -> type[PlatformDirsABC]:
31
+ if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system":
32
+ if os.getenv("SHELL") or os.getenv("PREFIX"):
33
+ return _Result
34
+
35
+ from pip._vendor.platformdirs.android import _android_folder # noqa: PLC0415
36
+
37
+ if _android_folder() is not None:
38
+ from pip._vendor.platformdirs.android import Android # noqa: PLC0415
39
+
40
+ return Android # return to avoid redefinition of a result
41
+
42
+ return _Result
43
+
44
+
45
+ if TYPE_CHECKING:
46
+ # Work around mypy issue: https://github.com/python/mypy/issues/10962
47
+ PlatformDirs = _Result
48
+ else:
49
+ PlatformDirs = _set_platform_dir_class() #: Currently active platform
50
+ AppDirs = PlatformDirs #: Backwards compatibility with appdirs
51
+
52
+
53
+ def user_data_dir(
54
+ appname: str | None = None,
55
+ appauthor: str | Literal[False] | None = None,
56
+ version: str | None = None,
57
+ roaming: bool = False, # noqa: FBT001, FBT002
58
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
59
+ ) -> str:
60
+ """
61
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
62
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
63
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
64
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
65
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
66
+ :returns: data directory tied to the user
67
+ """
68
+ return PlatformDirs(
69
+ appname=appname,
70
+ appauthor=appauthor,
71
+ version=version,
72
+ roaming=roaming,
73
+ ensure_exists=ensure_exists,
74
+ ).user_data_dir
75
+
76
+
77
+ def site_data_dir(
78
+ appname: str | None = None,
79
+ appauthor: str | Literal[False] | None = None,
80
+ version: str | None = None,
81
+ multipath: bool = False, # noqa: FBT001, FBT002
82
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
83
+ ) -> str:
84
+ """
85
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
86
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
87
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
88
+ :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
89
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
90
+ :returns: data directory shared by users
91
+ """
92
+ return PlatformDirs(
93
+ appname=appname,
94
+ appauthor=appauthor,
95
+ version=version,
96
+ multipath=multipath,
97
+ ensure_exists=ensure_exists,
98
+ ).site_data_dir
99
+
100
+
101
+ def user_config_dir(
102
+ appname: str | None = None,
103
+ appauthor: str | Literal[False] | None = None,
104
+ version: str | None = None,
105
+ roaming: bool = False, # noqa: FBT001, FBT002
106
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
107
+ ) -> str:
108
+ """
109
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
110
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
111
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
112
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
113
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
114
+ :returns: config directory tied to the user
115
+ """
116
+ return PlatformDirs(
117
+ appname=appname,
118
+ appauthor=appauthor,
119
+ version=version,
120
+ roaming=roaming,
121
+ ensure_exists=ensure_exists,
122
+ ).user_config_dir
123
+
124
+
125
+ def site_config_dir(
126
+ appname: str | None = None,
127
+ appauthor: str | Literal[False] | None = None,
128
+ version: str | None = None,
129
+ multipath: bool = False, # noqa: FBT001, FBT002
130
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
131
+ ) -> str:
132
+ """
133
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
134
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
135
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
136
+ :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
137
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
138
+ :returns: config directory shared by the users
139
+ """
140
+ return PlatformDirs(
141
+ appname=appname,
142
+ appauthor=appauthor,
143
+ version=version,
144
+ multipath=multipath,
145
+ ensure_exists=ensure_exists,
146
+ ).site_config_dir
147
+
148
+
149
+ def user_cache_dir(
150
+ appname: str | None = None,
151
+ appauthor: str | Literal[False] | None = None,
152
+ version: str | None = None,
153
+ opinion: bool = True, # noqa: FBT001, FBT002
154
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
155
+ ) -> str:
156
+ """
157
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
158
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
159
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
160
+ :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
161
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
162
+ :returns: cache directory tied to the user
163
+ """
164
+ return PlatformDirs(
165
+ appname=appname,
166
+ appauthor=appauthor,
167
+ version=version,
168
+ opinion=opinion,
169
+ ensure_exists=ensure_exists,
170
+ ).user_cache_dir
171
+
172
+
173
+ def site_cache_dir(
174
+ appname: str | None = None,
175
+ appauthor: str | Literal[False] | None = None,
176
+ version: str | None = None,
177
+ opinion: bool = True, # noqa: FBT001, FBT002
178
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
179
+ ) -> str:
180
+ """
181
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
182
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
183
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
184
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
185
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
186
+ :returns: cache directory tied to the user
187
+ """
188
+ return PlatformDirs(
189
+ appname=appname,
190
+ appauthor=appauthor,
191
+ version=version,
192
+ opinion=opinion,
193
+ ensure_exists=ensure_exists,
194
+ ).site_cache_dir
195
+
196
+
197
+ def user_state_dir(
198
+ appname: str | None = None,
199
+ appauthor: str | Literal[False] | None = None,
200
+ version: str | None = None,
201
+ roaming: bool = False, # noqa: FBT001, FBT002
202
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
203
+ ) -> str:
204
+ """
205
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
206
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
207
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
208
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
209
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
210
+ :returns: state directory tied to the user
211
+ """
212
+ return PlatformDirs(
213
+ appname=appname,
214
+ appauthor=appauthor,
215
+ version=version,
216
+ roaming=roaming,
217
+ ensure_exists=ensure_exists,
218
+ ).user_state_dir
219
+
220
+
221
+ def user_log_dir(
222
+ appname: str | None = None,
223
+ appauthor: str | Literal[False] | None = None,
224
+ version: str | None = None,
225
+ opinion: bool = True, # noqa: FBT001, FBT002
226
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
227
+ ) -> str:
228
+ """
229
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
230
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
231
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
232
+ :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
233
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
234
+ :returns: log directory tied to the user
235
+ """
236
+ return PlatformDirs(
237
+ appname=appname,
238
+ appauthor=appauthor,
239
+ version=version,
240
+ opinion=opinion,
241
+ ensure_exists=ensure_exists,
242
+ ).user_log_dir
243
+
244
+
245
+ def user_documents_dir() -> str:
246
+ """:returns: documents directory tied to the user"""
247
+ return PlatformDirs().user_documents_dir
248
+
249
+
250
+ def user_downloads_dir() -> str:
251
+ """:returns: downloads directory tied to the user"""
252
+ return PlatformDirs().user_downloads_dir
253
+
254
+
255
+ def user_pictures_dir() -> str:
256
+ """:returns: pictures directory tied to the user"""
257
+ return PlatformDirs().user_pictures_dir
258
+
259
+
260
+ def user_videos_dir() -> str:
261
+ """:returns: videos directory tied to the user"""
262
+ return PlatformDirs().user_videos_dir
263
+
264
+
265
+ def user_music_dir() -> str:
266
+ """:returns: music directory tied to the user"""
267
+ return PlatformDirs().user_music_dir
268
+
269
+
270
+ def user_desktop_dir() -> str:
271
+ """:returns: desktop directory tied to the user"""
272
+ return PlatformDirs().user_desktop_dir
273
+
274
+
275
+ def user_runtime_dir(
276
+ appname: str | None = None,
277
+ appauthor: str | Literal[False] | None = None,
278
+ version: str | None = None,
279
+ opinion: bool = True, # noqa: FBT001, FBT002
280
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
281
+ ) -> str:
282
+ """
283
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
284
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
285
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
286
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
287
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
288
+ :returns: runtime directory tied to the user
289
+ """
290
+ return PlatformDirs(
291
+ appname=appname,
292
+ appauthor=appauthor,
293
+ version=version,
294
+ opinion=opinion,
295
+ ensure_exists=ensure_exists,
296
+ ).user_runtime_dir
297
+
298
+
299
+ def site_runtime_dir(
300
+ appname: str | None = None,
301
+ appauthor: str | Literal[False] | None = None,
302
+ version: str | None = None,
303
+ opinion: bool = True, # noqa: FBT001, FBT002
304
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
305
+ ) -> str:
306
+ """
307
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
308
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
309
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
310
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
311
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
312
+ :returns: runtime directory shared by users
313
+ """
314
+ return PlatformDirs(
315
+ appname=appname,
316
+ appauthor=appauthor,
317
+ version=version,
318
+ opinion=opinion,
319
+ ensure_exists=ensure_exists,
320
+ ).site_runtime_dir
321
+
322
+
323
+ def user_data_path(
324
+ appname: str | None = None,
325
+ appauthor: str | Literal[False] | None = None,
326
+ version: str | None = None,
327
+ roaming: bool = False, # noqa: FBT001, FBT002
328
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
329
+ ) -> Path:
330
+ """
331
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
332
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
333
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
334
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
335
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
336
+ :returns: data path tied to the user
337
+ """
338
+ return PlatformDirs(
339
+ appname=appname,
340
+ appauthor=appauthor,
341
+ version=version,
342
+ roaming=roaming,
343
+ ensure_exists=ensure_exists,
344
+ ).user_data_path
345
+
346
+
347
+ def site_data_path(
348
+ appname: str | None = None,
349
+ appauthor: str | Literal[False] | None = None,
350
+ version: str | None = None,
351
+ multipath: bool = False, # noqa: FBT001, FBT002
352
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
353
+ ) -> Path:
354
+ """
355
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
356
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
357
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
358
+ :param multipath: See `multipath <platformdirs.api.PlatformDirsABC.multipath>`.
359
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
360
+ :returns: data path shared by users
361
+ """
362
+ return PlatformDirs(
363
+ appname=appname,
364
+ appauthor=appauthor,
365
+ version=version,
366
+ multipath=multipath,
367
+ ensure_exists=ensure_exists,
368
+ ).site_data_path
369
+
370
+
371
+ def user_config_path(
372
+ appname: str | None = None,
373
+ appauthor: str | Literal[False] | None = None,
374
+ version: str | None = None,
375
+ roaming: bool = False, # noqa: FBT001, FBT002
376
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
377
+ ) -> Path:
378
+ """
379
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
380
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
381
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
382
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
383
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
384
+ :returns: config path tied to the user
385
+ """
386
+ return PlatformDirs(
387
+ appname=appname,
388
+ appauthor=appauthor,
389
+ version=version,
390
+ roaming=roaming,
391
+ ensure_exists=ensure_exists,
392
+ ).user_config_path
393
+
394
+
395
+ def site_config_path(
396
+ appname: str | None = None,
397
+ appauthor: str | Literal[False] | None = None,
398
+ version: str | None = None,
399
+ multipath: bool = False, # noqa: FBT001, FBT002
400
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
401
+ ) -> Path:
402
+ """
403
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
404
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
405
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
406
+ :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
407
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
408
+ :returns: config path shared by the users
409
+ """
410
+ return PlatformDirs(
411
+ appname=appname,
412
+ appauthor=appauthor,
413
+ version=version,
414
+ multipath=multipath,
415
+ ensure_exists=ensure_exists,
416
+ ).site_config_path
417
+
418
+
419
+ def site_cache_path(
420
+ appname: str | None = None,
421
+ appauthor: str | Literal[False] | None = None,
422
+ version: str | None = None,
423
+ opinion: bool = True, # noqa: FBT001, FBT002
424
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
425
+ ) -> Path:
426
+ """
427
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
428
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
429
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
430
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
431
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
432
+ :returns: cache directory tied to the user
433
+ """
434
+ return PlatformDirs(
435
+ appname=appname,
436
+ appauthor=appauthor,
437
+ version=version,
438
+ opinion=opinion,
439
+ ensure_exists=ensure_exists,
440
+ ).site_cache_path
441
+
442
+
443
+ def user_cache_path(
444
+ appname: str | None = None,
445
+ appauthor: str | Literal[False] | None = None,
446
+ version: str | None = None,
447
+ opinion: bool = True, # noqa: FBT001, FBT002
448
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
449
+ ) -> Path:
450
+ """
451
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
452
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
453
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
454
+ :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
455
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
456
+ :returns: cache path tied to the user
457
+ """
458
+ return PlatformDirs(
459
+ appname=appname,
460
+ appauthor=appauthor,
461
+ version=version,
462
+ opinion=opinion,
463
+ ensure_exists=ensure_exists,
464
+ ).user_cache_path
465
+
466
+
467
+ def user_state_path(
468
+ appname: str | None = None,
469
+ appauthor: str | Literal[False] | None = None,
470
+ version: str | None = None,
471
+ roaming: bool = False, # noqa: FBT001, FBT002
472
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
473
+ ) -> Path:
474
+ """
475
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
476
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
477
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
478
+ :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
479
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
480
+ :returns: state path tied to the user
481
+ """
482
+ return PlatformDirs(
483
+ appname=appname,
484
+ appauthor=appauthor,
485
+ version=version,
486
+ roaming=roaming,
487
+ ensure_exists=ensure_exists,
488
+ ).user_state_path
489
+
490
+
491
+ def user_log_path(
492
+ appname: str | None = None,
493
+ appauthor: str | Literal[False] | None = None,
494
+ version: str | None = None,
495
+ opinion: bool = True, # noqa: FBT001, FBT002
496
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
497
+ ) -> Path:
498
+ """
499
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
500
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
501
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
502
+ :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
503
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
504
+ :returns: log path tied to the user
505
+ """
506
+ return PlatformDirs(
507
+ appname=appname,
508
+ appauthor=appauthor,
509
+ version=version,
510
+ opinion=opinion,
511
+ ensure_exists=ensure_exists,
512
+ ).user_log_path
513
+
514
+
515
+ def user_documents_path() -> Path:
516
+ """:returns: documents a path tied to the user"""
517
+ return PlatformDirs().user_documents_path
518
+
519
+
520
+ def user_downloads_path() -> Path:
521
+ """:returns: downloads path tied to the user"""
522
+ return PlatformDirs().user_downloads_path
523
+
524
+
525
+ def user_pictures_path() -> Path:
526
+ """:returns: pictures path tied to the user"""
527
+ return PlatformDirs().user_pictures_path
528
+
529
+
530
+ def user_videos_path() -> Path:
531
+ """:returns: videos path tied to the user"""
532
+ return PlatformDirs().user_videos_path
533
+
534
+
535
+ def user_music_path() -> Path:
536
+ """:returns: music path tied to the user"""
537
+ return PlatformDirs().user_music_path
538
+
539
+
540
+ def user_desktop_path() -> Path:
541
+ """:returns: desktop path tied to the user"""
542
+ return PlatformDirs().user_desktop_path
543
+
544
+
545
+ def user_runtime_path(
546
+ appname: str | None = None,
547
+ appauthor: str | Literal[False] | None = None,
548
+ version: str | None = None,
549
+ opinion: bool = True, # noqa: FBT001, FBT002
550
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
551
+ ) -> Path:
552
+ """
553
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
554
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
555
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
556
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
557
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
558
+ :returns: runtime path tied to the user
559
+ """
560
+ return PlatformDirs(
561
+ appname=appname,
562
+ appauthor=appauthor,
563
+ version=version,
564
+ opinion=opinion,
565
+ ensure_exists=ensure_exists,
566
+ ).user_runtime_path
567
+
568
+
569
+ def site_runtime_path(
570
+ appname: str | None = None,
571
+ appauthor: str | Literal[False] | None = None,
572
+ version: str | None = None,
573
+ opinion: bool = True, # noqa: FBT001, FBT002
574
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
575
+ ) -> Path:
576
+ """
577
+ :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
578
+ :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
579
+ :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
580
+ :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
581
+ :param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
582
+ :returns: runtime path shared by users
583
+ """
584
+ return PlatformDirs(
585
+ appname=appname,
586
+ appauthor=appauthor,
587
+ version=version,
588
+ opinion=opinion,
589
+ ensure_exists=ensure_exists,
590
+ ).site_runtime_path
591
+
592
+
593
+ __all__ = [
594
+ "AppDirs",
595
+ "PlatformDirs",
596
+ "PlatformDirsABC",
597
+ "__version__",
598
+ "__version_info__",
599
+ "site_cache_dir",
600
+ "site_cache_path",
601
+ "site_config_dir",
602
+ "site_config_path",
603
+ "site_data_dir",
604
+ "site_data_path",
605
+ "site_runtime_dir",
606
+ "site_runtime_path",
607
+ "user_cache_dir",
608
+ "user_cache_path",
609
+ "user_config_dir",
610
+ "user_config_path",
611
+ "user_data_dir",
612
+ "user_data_path",
613
+ "user_desktop_dir",
614
+ "user_desktop_path",
615
+ "user_documents_dir",
616
+ "user_documents_path",
617
+ "user_downloads_dir",
618
+ "user_downloads_path",
619
+ "user_log_dir",
620
+ "user_log_path",
621
+ "user_music_dir",
622
+ "user_music_path",
623
+ "user_pictures_dir",
624
+ "user_pictures_path",
625
+ "user_runtime_dir",
626
+ "user_runtime_path",
627
+ "user_state_dir",
628
+ "user_state_path",
629
+ "user_videos_dir",
630
+ "user_videos_path",
631
+ ]
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/android.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Android."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import re
7
+ import sys
8
+ from functools import lru_cache
9
+ from typing import TYPE_CHECKING, cast
10
+
11
+ from .api import PlatformDirsABC
12
+
13
+
14
+ class Android(PlatformDirsABC):
15
+ """
16
+ Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_.
17
+
18
+ Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `version
19
+ <platformdirs.api.PlatformDirsABC.version>`, `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
20
+
21
+ """
22
+
23
+ @property
24
+ def user_data_dir(self) -> str:
25
+ """:return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""
26
+ return self._append_app_name_and_version(cast("str", _android_folder()), "files")
27
+
28
+ @property
29
+ def site_data_dir(self) -> str:
30
+ """:return: data directory shared by users, same as `user_data_dir`"""
31
+ return self.user_data_dir
32
+
33
+ @property
34
+ def user_config_dir(self) -> str:
35
+ """
36
+ :return: config directory tied to the user, e.g. \
37
+ ``/data/user/<userid>/<packagename>/shared_prefs/<AppName>``
38
+ """
39
+ return self._append_app_name_and_version(cast("str", _android_folder()), "shared_prefs")
40
+
41
+ @property
42
+ def site_config_dir(self) -> str:
43
+ """:return: config directory shared by the users, same as `user_config_dir`"""
44
+ return self.user_config_dir
45
+
46
+ @property
47
+ def user_cache_dir(self) -> str:
48
+ """:return: cache directory tied to the user, e.g.,``/data/user/<userid>/<packagename>/cache/<AppName>``"""
49
+ return self._append_app_name_and_version(cast("str", _android_folder()), "cache")
50
+
51
+ @property
52
+ def site_cache_dir(self) -> str:
53
+ """:return: cache directory shared by users, same as `user_cache_dir`"""
54
+ return self.user_cache_dir
55
+
56
+ @property
57
+ def user_state_dir(self) -> str:
58
+ """:return: state directory tied to the user, same as `user_data_dir`"""
59
+ return self.user_data_dir
60
+
61
+ @property
62
+ def user_log_dir(self) -> str:
63
+ """
64
+ :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it,
65
+ e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/log``
66
+ """
67
+ path = self.user_cache_dir
68
+ if self.opinion:
69
+ path = os.path.join(path, "log") # noqa: PTH118
70
+ return path
71
+
72
+ @property
73
+ def user_documents_dir(self) -> str:
74
+ """:return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents``"""
75
+ return _android_documents_folder()
76
+
77
+ @property
78
+ def user_downloads_dir(self) -> str:
79
+ """:return: downloads directory tied to the user e.g. ``/storage/emulated/0/Downloads``"""
80
+ return _android_downloads_folder()
81
+
82
+ @property
83
+ def user_pictures_dir(self) -> str:
84
+ """:return: pictures directory tied to the user e.g. ``/storage/emulated/0/Pictures``"""
85
+ return _android_pictures_folder()
86
+
87
+ @property
88
+ def user_videos_dir(self) -> str:
89
+ """:return: videos directory tied to the user e.g. ``/storage/emulated/0/DCIM/Camera``"""
90
+ return _android_videos_folder()
91
+
92
+ @property
93
+ def user_music_dir(self) -> str:
94
+ """:return: music directory tied to the user e.g. ``/storage/emulated/0/Music``"""
95
+ return _android_music_folder()
96
+
97
+ @property
98
+ def user_desktop_dir(self) -> str:
99
+ """:return: desktop directory tied to the user e.g. ``/storage/emulated/0/Desktop``"""
100
+ return "/storage/emulated/0/Desktop"
101
+
102
+ @property
103
+ def user_runtime_dir(self) -> str:
104
+ """
105
+ :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it,
106
+ e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp``
107
+ """
108
+ path = self.user_cache_dir
109
+ if self.opinion:
110
+ path = os.path.join(path, "tmp") # noqa: PTH118
111
+ return path
112
+
113
+ @property
114
+ def site_runtime_dir(self) -> str:
115
+ """:return: runtime directory shared by users, same as `user_runtime_dir`"""
116
+ return self.user_runtime_dir
117
+
118
+
119
+ @lru_cache(maxsize=1)
120
+ def _android_folder() -> str | None: # noqa: C901
121
+ """:return: base folder for the Android OS or None if it cannot be found"""
122
+ result: str | None = None
123
+ # type checker isn't happy with our "import android", just don't do this when type checking see
124
+ # https://stackoverflow.com/a/61394121
125
+ if not TYPE_CHECKING:
126
+ try:
127
+ # First try to get a path to android app using python4android (if available)...
128
+ from android import mActivity # noqa: PLC0415
129
+
130
+ context = cast("android.content.Context", mActivity.getApplicationContext()) # noqa: F821
131
+ result = context.getFilesDir().getParentFile().getAbsolutePath()
132
+ except Exception: # noqa: BLE001
133
+ result = None
134
+ if result is None:
135
+ try:
136
+ # ...and fall back to using plain pyjnius, if python4android isn't available or doesn't deliver any useful
137
+ # result...
138
+ from jnius import autoclass # noqa: PLC0415
139
+
140
+ context = autoclass("android.content.Context")
141
+ result = context.getFilesDir().getParentFile().getAbsolutePath()
142
+ except Exception: # noqa: BLE001
143
+ result = None
144
+ if result is None:
145
+ # and if that fails, too, find an android folder looking at path on the sys.path
146
+ # warning: only works for apps installed under /data, not adopted storage etc.
147
+ pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files")
148
+ for path in sys.path:
149
+ if pattern.match(path):
150
+ result = path.split("/files")[0]
151
+ break
152
+ else:
153
+ result = None
154
+ if result is None:
155
+ # one last try: find an android folder looking at path on the sys.path taking adopted storage paths into
156
+ # account
157
+ pattern = re.compile(r"/mnt/expand/[a-fA-F0-9-]{36}/(data|user/\d+)/(.+)/files")
158
+ for path in sys.path:
159
+ if pattern.match(path):
160
+ result = path.split("/files")[0]
161
+ break
162
+ else:
163
+ result = None
164
+ return result
165
+
166
+
167
+ @lru_cache(maxsize=1)
168
+ def _android_documents_folder() -> str:
169
+ """:return: documents folder for the Android OS"""
170
+ # Get directories with pyjnius
171
+ try:
172
+ from jnius import autoclass # noqa: PLC0415
173
+
174
+ context = autoclass("android.content.Context")
175
+ environment = autoclass("android.os.Environment")
176
+ documents_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOCUMENTS).getAbsolutePath()
177
+ except Exception: # noqa: BLE001
178
+ documents_dir = "/storage/emulated/0/Documents"
179
+
180
+ return documents_dir
181
+
182
+
183
+ @lru_cache(maxsize=1)
184
+ def _android_downloads_folder() -> str:
185
+ """:return: downloads folder for the Android OS"""
186
+ # Get directories with pyjnius
187
+ try:
188
+ from jnius import autoclass # noqa: PLC0415
189
+
190
+ context = autoclass("android.content.Context")
191
+ environment = autoclass("android.os.Environment")
192
+ downloads_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
193
+ except Exception: # noqa: BLE001
194
+ downloads_dir = "/storage/emulated/0/Downloads"
195
+
196
+ return downloads_dir
197
+
198
+
199
+ @lru_cache(maxsize=1)
200
+ def _android_pictures_folder() -> str:
201
+ """:return: pictures folder for the Android OS"""
202
+ # Get directories with pyjnius
203
+ try:
204
+ from jnius import autoclass # noqa: PLC0415
205
+
206
+ context = autoclass("android.content.Context")
207
+ environment = autoclass("android.os.Environment")
208
+ pictures_dir: str = context.getExternalFilesDir(environment.DIRECTORY_PICTURES).getAbsolutePath()
209
+ except Exception: # noqa: BLE001
210
+ pictures_dir = "/storage/emulated/0/Pictures"
211
+
212
+ return pictures_dir
213
+
214
+
215
+ @lru_cache(maxsize=1)
216
+ def _android_videos_folder() -> str:
217
+ """:return: videos folder for the Android OS"""
218
+ # Get directories with pyjnius
219
+ try:
220
+ from jnius import autoclass # noqa: PLC0415
221
+
222
+ context = autoclass("android.content.Context")
223
+ environment = autoclass("android.os.Environment")
224
+ videos_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DCIM).getAbsolutePath()
225
+ except Exception: # noqa: BLE001
226
+ videos_dir = "/storage/emulated/0/DCIM/Camera"
227
+
228
+ return videos_dir
229
+
230
+
231
+ @lru_cache(maxsize=1)
232
+ def _android_music_folder() -> str:
233
+ """:return: music folder for the Android OS"""
234
+ # Get directories with pyjnius
235
+ try:
236
+ from jnius import autoclass # noqa: PLC0415
237
+
238
+ context = autoclass("android.content.Context")
239
+ environment = autoclass("android.os.Environment")
240
+ music_dir: str = context.getExternalFilesDir(environment.DIRECTORY_MUSIC).getAbsolutePath()
241
+ except Exception: # noqa: BLE001
242
+ music_dir = "/storage/emulated/0/Music"
243
+
244
+ return music_dir
245
+
246
+
247
+ __all__ = [
248
+ "Android",
249
+ ]
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/api.py ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Base API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from abc import ABC, abstractmethod
7
+ from pathlib import Path
8
+ from typing import TYPE_CHECKING
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Iterator
12
+ from typing import Literal
13
+
14
+
15
+ class PlatformDirsABC(ABC): # noqa: PLR0904
16
+ """Abstract base class for platform directories."""
17
+
18
+ def __init__( # noqa: PLR0913, PLR0917
19
+ self,
20
+ appname: str | None = None,
21
+ appauthor: str | Literal[False] | None = None,
22
+ version: str | None = None,
23
+ roaming: bool = False, # noqa: FBT001, FBT002
24
+ multipath: bool = False, # noqa: FBT001, FBT002
25
+ opinion: bool = True, # noqa: FBT001, FBT002
26
+ ensure_exists: bool = False, # noqa: FBT001, FBT002
27
+ ) -> None:
28
+ """
29
+ Create a new platform directory.
30
+
31
+ :param appname: See `appname`.
32
+ :param appauthor: See `appauthor`.
33
+ :param version: See `version`.
34
+ :param roaming: See `roaming`.
35
+ :param multipath: See `multipath`.
36
+ :param opinion: See `opinion`.
37
+ :param ensure_exists: See `ensure_exists`.
38
+
39
+ """
40
+ self.appname = appname #: The name of application.
41
+ self.appauthor = appauthor
42
+ """
43
+ The name of the app author or distributing body for this application.
44
+
45
+ Typically, it is the owning company name. Defaults to `appname`. You may pass ``False`` to disable it.
46
+
47
+ """
48
+ self.version = version
49
+ """
50
+ An optional version path element to append to the path.
51
+
52
+ You might want to use this if you want multiple versions of your app to be able to run independently. If used,
53
+ this would typically be ``<major>.<minor>``.
54
+
55
+ """
56
+ self.roaming = roaming
57
+ """
58
+ Whether to use the roaming appdata directory on Windows.
59
+
60
+ That means that for users on a Windows network setup for roaming profiles, this user data will be synced on
61
+ login (see
62
+ `here <https://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>`_).
63
+
64
+ """
65
+ self.multipath = multipath
66
+ """
67
+ An optional parameter which indicates that the entire list of data dirs should be returned.
68
+
69
+ By default, the first item would only be returned.
70
+
71
+ """
72
+ self.opinion = opinion #: A flag to indicating to use opinionated values.
73
+ self.ensure_exists = ensure_exists
74
+ """
75
+ Optionally create the directory (and any missing parents) upon access if it does not exist.
76
+
77
+ By default, no directories are created.
78
+
79
+ """
80
+
81
+ def _append_app_name_and_version(self, *base: str) -> str:
82
+ params = list(base[1:])
83
+ if self.appname:
84
+ params.append(self.appname)
85
+ if self.version:
86
+ params.append(self.version)
87
+ path = os.path.join(base[0], *params) # noqa: PTH118
88
+ self._optionally_create_directory(path)
89
+ return path
90
+
91
+ def _optionally_create_directory(self, path: str) -> None:
92
+ if self.ensure_exists:
93
+ Path(path).mkdir(parents=True, exist_ok=True)
94
+
95
+ def _first_item_as_path_if_multipath(self, directory: str) -> Path:
96
+ if self.multipath:
97
+ # If multipath is True, the first path is returned.
98
+ directory = directory.split(os.pathsep)[0]
99
+ return Path(directory)
100
+
101
+ @property
102
+ @abstractmethod
103
+ def user_data_dir(self) -> str:
104
+ """:return: data directory tied to the user"""
105
+
106
+ @property
107
+ @abstractmethod
108
+ def site_data_dir(self) -> str:
109
+ """:return: data directory shared by users"""
110
+
111
+ @property
112
+ @abstractmethod
113
+ def user_config_dir(self) -> str:
114
+ """:return: config directory tied to the user"""
115
+
116
+ @property
117
+ @abstractmethod
118
+ def site_config_dir(self) -> str:
119
+ """:return: config directory shared by the users"""
120
+
121
+ @property
122
+ @abstractmethod
123
+ def user_cache_dir(self) -> str:
124
+ """:return: cache directory tied to the user"""
125
+
126
+ @property
127
+ @abstractmethod
128
+ def site_cache_dir(self) -> str:
129
+ """:return: cache directory shared by users"""
130
+
131
+ @property
132
+ @abstractmethod
133
+ def user_state_dir(self) -> str:
134
+ """:return: state directory tied to the user"""
135
+
136
+ @property
137
+ @abstractmethod
138
+ def user_log_dir(self) -> str:
139
+ """:return: log directory tied to the user"""
140
+
141
+ @property
142
+ @abstractmethod
143
+ def user_documents_dir(self) -> str:
144
+ """:return: documents directory tied to the user"""
145
+
146
+ @property
147
+ @abstractmethod
148
+ def user_downloads_dir(self) -> str:
149
+ """:return: downloads directory tied to the user"""
150
+
151
+ @property
152
+ @abstractmethod
153
+ def user_pictures_dir(self) -> str:
154
+ """:return: pictures directory tied to the user"""
155
+
156
+ @property
157
+ @abstractmethod
158
+ def user_videos_dir(self) -> str:
159
+ """:return: videos directory tied to the user"""
160
+
161
+ @property
162
+ @abstractmethod
163
+ def user_music_dir(self) -> str:
164
+ """:return: music directory tied to the user"""
165
+
166
+ @property
167
+ @abstractmethod
168
+ def user_desktop_dir(self) -> str:
169
+ """:return: desktop directory tied to the user"""
170
+
171
+ @property
172
+ @abstractmethod
173
+ def user_runtime_dir(self) -> str:
174
+ """:return: runtime directory tied to the user"""
175
+
176
+ @property
177
+ @abstractmethod
178
+ def site_runtime_dir(self) -> str:
179
+ """:return: runtime directory shared by users"""
180
+
181
+ @property
182
+ def user_data_path(self) -> Path:
183
+ """:return: data path tied to the user"""
184
+ return Path(self.user_data_dir)
185
+
186
+ @property
187
+ def site_data_path(self) -> Path:
188
+ """:return: data path shared by users"""
189
+ return Path(self.site_data_dir)
190
+
191
+ @property
192
+ def user_config_path(self) -> Path:
193
+ """:return: config path tied to the user"""
194
+ return Path(self.user_config_dir)
195
+
196
+ @property
197
+ def site_config_path(self) -> Path:
198
+ """:return: config path shared by the users"""
199
+ return Path(self.site_config_dir)
200
+
201
+ @property
202
+ def user_cache_path(self) -> Path:
203
+ """:return: cache path tied to the user"""
204
+ return Path(self.user_cache_dir)
205
+
206
+ @property
207
+ def site_cache_path(self) -> Path:
208
+ """:return: cache path shared by users"""
209
+ return Path(self.site_cache_dir)
210
+
211
+ @property
212
+ def user_state_path(self) -> Path:
213
+ """:return: state path tied to the user"""
214
+ return Path(self.user_state_dir)
215
+
216
+ @property
217
+ def user_log_path(self) -> Path:
218
+ """:return: log path tied to the user"""
219
+ return Path(self.user_log_dir)
220
+
221
+ @property
222
+ def user_documents_path(self) -> Path:
223
+ """:return: documents a path tied to the user"""
224
+ return Path(self.user_documents_dir)
225
+
226
+ @property
227
+ def user_downloads_path(self) -> Path:
228
+ """:return: downloads path tied to the user"""
229
+ return Path(self.user_downloads_dir)
230
+
231
+ @property
232
+ def user_pictures_path(self) -> Path:
233
+ """:return: pictures path tied to the user"""
234
+ return Path(self.user_pictures_dir)
235
+
236
+ @property
237
+ def user_videos_path(self) -> Path:
238
+ """:return: videos path tied to the user"""
239
+ return Path(self.user_videos_dir)
240
+
241
+ @property
242
+ def user_music_path(self) -> Path:
243
+ """:return: music path tied to the user"""
244
+ return Path(self.user_music_dir)
245
+
246
+ @property
247
+ def user_desktop_path(self) -> Path:
248
+ """:return: desktop path tied to the user"""
249
+ return Path(self.user_desktop_dir)
250
+
251
+ @property
252
+ def user_runtime_path(self) -> Path:
253
+ """:return: runtime path tied to the user"""
254
+ return Path(self.user_runtime_dir)
255
+
256
+ @property
257
+ def site_runtime_path(self) -> Path:
258
+ """:return: runtime path shared by users"""
259
+ return Path(self.site_runtime_dir)
260
+
261
+ def iter_config_dirs(self) -> Iterator[str]:
262
+ """:yield: all user and site configuration directories."""
263
+ yield self.user_config_dir
264
+ yield self.site_config_dir
265
+
266
+ def iter_data_dirs(self) -> Iterator[str]:
267
+ """:yield: all user and site data directories."""
268
+ yield self.user_data_dir
269
+ yield self.site_data_dir
270
+
271
+ def iter_cache_dirs(self) -> Iterator[str]:
272
+ """:yield: all user and site cache directories."""
273
+ yield self.user_cache_dir
274
+ yield self.site_cache_dir
275
+
276
+ def iter_runtime_dirs(self) -> Iterator[str]:
277
+ """:yield: all user and site runtime directories."""
278
+ yield self.user_runtime_dir
279
+ yield self.site_runtime_dir
280
+
281
+ def iter_config_paths(self) -> Iterator[Path]:
282
+ """:yield: all user and site configuration paths."""
283
+ for path in self.iter_config_dirs():
284
+ yield Path(path)
285
+
286
+ def iter_data_paths(self) -> Iterator[Path]:
287
+ """:yield: all user and site data paths."""
288
+ for path in self.iter_data_dirs():
289
+ yield Path(path)
290
+
291
+ def iter_cache_paths(self) -> Iterator[Path]:
292
+ """:yield: all user and site cache paths."""
293
+ for path in self.iter_cache_dirs():
294
+ yield Path(path)
295
+
296
+ def iter_runtime_paths(self) -> Iterator[Path]:
297
+ """:yield: all user and site runtime paths."""
298
+ for path in self.iter_runtime_dirs():
299
+ yield Path(path)
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/macos.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """macOS."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os.path
6
+ import sys
7
+ from typing import TYPE_CHECKING
8
+
9
+ from .api import PlatformDirsABC
10
+
11
+ if TYPE_CHECKING:
12
+ from pathlib import Path
13
+
14
+
15
+ class MacOS(PlatformDirsABC):
16
+ """
17
+ Platform directories for the macOS operating system.
18
+
19
+ Follows the guidance from
20
+ `Apple documentation <https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html>`_.
21
+ Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`,
22
+ `version <platformdirs.api.PlatformDirsABC.version>`,
23
+ `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
24
+
25
+ """
26
+
27
+ @property
28
+ def user_data_dir(self) -> str:
29
+ """:return: data directory tied to the user, e.g. ``~/Library/Application Support/$appname/$version``"""
30
+ return self._append_app_name_and_version(os.path.expanduser("~/Library/Application Support")) # noqa: PTH111
31
+
32
+ @property
33
+ def site_data_dir(self) -> str:
34
+ """
35
+ :return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``.
36
+ If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory
37
+ will be under the Homebrew prefix, e.g. ``/opt/homebrew/share/$appname/$version``.
38
+ If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled, and we're in Homebrew,
39
+ the response is a multi-path string separated by ":", e.g.
40
+ ``/opt/homebrew/share/$appname/$version:/Library/Application Support/$appname/$version``
41
+ """
42
+ is_homebrew = sys.prefix.startswith("/opt/homebrew")
43
+ path_list = [self._append_app_name_and_version("/opt/homebrew/share")] if is_homebrew else []
44
+ path_list.append(self._append_app_name_and_version("/Library/Application Support"))
45
+ if self.multipath:
46
+ return os.pathsep.join(path_list)
47
+ return path_list[0]
48
+
49
+ @property
50
+ def site_data_path(self) -> Path:
51
+ """:return: data path shared by users. Only return the first item, even if ``multipath`` is set to ``True``"""
52
+ return self._first_item_as_path_if_multipath(self.site_data_dir)
53
+
54
+ @property
55
+ def user_config_dir(self) -> str:
56
+ """:return: config directory tied to the user, same as `user_data_dir`"""
57
+ return self.user_data_dir
58
+
59
+ @property
60
+ def site_config_dir(self) -> str:
61
+ """:return: config directory shared by the users, same as `site_data_dir`"""
62
+ return self.site_data_dir
63
+
64
+ @property
65
+ def user_cache_dir(self) -> str:
66
+ """:return: cache directory tied to the user, e.g. ``~/Library/Caches/$appname/$version``"""
67
+ return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches")) # noqa: PTH111
68
+
69
+ @property
70
+ def site_cache_dir(self) -> str:
71
+ """
72
+ :return: cache directory shared by users, e.g. ``/Library/Caches/$appname/$version``.
73
+ If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory
74
+ will be under the Homebrew prefix, e.g. ``/opt/homebrew/var/cache/$appname/$version``.
75
+ If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled, and we're in Homebrew,
76
+ the response is a multi-path string separated by ":", e.g.
77
+ ``/opt/homebrew/var/cache/$appname/$version:/Library/Caches/$appname/$version``
78
+ """
79
+ is_homebrew = sys.prefix.startswith("/opt/homebrew")
80
+ path_list = [self._append_app_name_and_version("/opt/homebrew/var/cache")] if is_homebrew else []
81
+ path_list.append(self._append_app_name_and_version("/Library/Caches"))
82
+ if self.multipath:
83
+ return os.pathsep.join(path_list)
84
+ return path_list[0]
85
+
86
+ @property
87
+ def site_cache_path(self) -> Path:
88
+ """:return: cache path shared by users. Only return the first item, even if ``multipath`` is set to ``True``"""
89
+ return self._first_item_as_path_if_multipath(self.site_cache_dir)
90
+
91
+ @property
92
+ def user_state_dir(self) -> str:
93
+ """:return: state directory tied to the user, same as `user_data_dir`"""
94
+ return self.user_data_dir
95
+
96
+ @property
97
+ def user_log_dir(self) -> str:
98
+ """:return: log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``"""
99
+ return self._append_app_name_and_version(os.path.expanduser("~/Library/Logs")) # noqa: PTH111
100
+
101
+ @property
102
+ def user_documents_dir(self) -> str:
103
+ """:return: documents directory tied to the user, e.g. ``~/Documents``"""
104
+ return os.path.expanduser("~/Documents") # noqa: PTH111
105
+
106
+ @property
107
+ def user_downloads_dir(self) -> str:
108
+ """:return: downloads directory tied to the user, e.g. ``~/Downloads``"""
109
+ return os.path.expanduser("~/Downloads") # noqa: PTH111
110
+
111
+ @property
112
+ def user_pictures_dir(self) -> str:
113
+ """:return: pictures directory tied to the user, e.g. ``~/Pictures``"""
114
+ return os.path.expanduser("~/Pictures") # noqa: PTH111
115
+
116
+ @property
117
+ def user_videos_dir(self) -> str:
118
+ """:return: videos directory tied to the user, e.g. ``~/Movies``"""
119
+ return os.path.expanduser("~/Movies") # noqa: PTH111
120
+
121
+ @property
122
+ def user_music_dir(self) -> str:
123
+ """:return: music directory tied to the user, e.g. ``~/Music``"""
124
+ return os.path.expanduser("~/Music") # noqa: PTH111
125
+
126
+ @property
127
+ def user_desktop_dir(self) -> str:
128
+ """:return: desktop directory tied to the user, e.g. ``~/Desktop``"""
129
+ return os.path.expanduser("~/Desktop") # noqa: PTH111
130
+
131
+ @property
132
+ def user_runtime_dir(self) -> str:
133
+ """:return: runtime directory tied to the user, e.g. ``~/Library/Caches/TemporaryItems/$appname/$version``"""
134
+ return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches/TemporaryItems")) # noqa: PTH111
135
+
136
+ @property
137
+ def site_runtime_dir(self) -> str:
138
+ """:return: runtime directory shared by users, same as `user_runtime_dir`"""
139
+ return self.user_runtime_dir
140
+
141
+
142
+ __all__ = [
143
+ "MacOS",
144
+ ]
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/py.typed ADDED
File without changes
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/unix.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Unix."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+ from configparser import ConfigParser
8
+ from pathlib import Path
9
+ from typing import TYPE_CHECKING, NoReturn
10
+
11
+ from .api import PlatformDirsABC
12
+
13
+ if TYPE_CHECKING:
14
+ from collections.abc import Iterator
15
+
16
+ if sys.platform == "win32":
17
+
18
+ def getuid() -> NoReturn:
19
+ msg = "should only be used on Unix"
20
+ raise RuntimeError(msg)
21
+
22
+ else:
23
+ from os import getuid
24
+
25
+
26
+ class Unix(PlatformDirsABC): # noqa: PLR0904
27
+ """
28
+ On Unix/Linux, we follow the `XDG Basedir Spec <https://specifications.freedesktop.org/basedir-spec/basedir-spec-
29
+ latest.html>`_.
30
+
31
+ The spec allows overriding directories with environment variables. The examples shown are the default values,
32
+ alongside the name of the environment variable that overrides them. Makes use of the `appname
33
+ <platformdirs.api.PlatformDirsABC.appname>`, `version <platformdirs.api.PlatformDirsABC.version>`, `multipath
34
+ <platformdirs.api.PlatformDirsABC.multipath>`, `opinion <platformdirs.api.PlatformDirsABC.opinion>`, `ensure_exists
35
+ <platformdirs.api.PlatformDirsABC.ensure_exists>`.
36
+
37
+ """
38
+
39
+ @property
40
+ def user_data_dir(self) -> str:
41
+ """
42
+ :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or
43
+ ``$XDG_DATA_HOME/$appname/$version``
44
+ """
45
+ path = os.environ.get("XDG_DATA_HOME", "")
46
+ if not path.strip():
47
+ path = os.path.expanduser("~/.local/share") # noqa: PTH111
48
+ return self._append_app_name_and_version(path)
49
+
50
+ @property
51
+ def _site_data_dirs(self) -> list[str]:
52
+ path = os.environ.get("XDG_DATA_DIRS", "")
53
+ if not path.strip():
54
+ path = f"/usr/local/share{os.pathsep}/usr/share"
55
+ return [self._append_app_name_and_version(p) for p in path.split(os.pathsep)]
56
+
57
+ @property
58
+ def site_data_dir(self) -> str:
59
+ """
60
+ :return: data directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>` is
61
+ enabled and ``XDG_DATA_DIRS`` is set and a multi path the response is also a multi path separated by the
62
+ OS path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version``
63
+ """
64
+ # XDG default for $XDG_DATA_DIRS; only first, if multipath is False
65
+ dirs = self._site_data_dirs
66
+ if not self.multipath:
67
+ return dirs[0]
68
+ return os.pathsep.join(dirs)
69
+
70
+ @property
71
+ def user_config_dir(self) -> str:
72
+ """
73
+ :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or
74
+ ``$XDG_CONFIG_HOME/$appname/$version``
75
+ """
76
+ path = os.environ.get("XDG_CONFIG_HOME", "")
77
+ if not path.strip():
78
+ path = os.path.expanduser("~/.config") # noqa: PTH111
79
+ return self._append_app_name_and_version(path)
80
+
81
+ @property
82
+ def _site_config_dirs(self) -> list[str]:
83
+ path = os.environ.get("XDG_CONFIG_DIRS", "")
84
+ if not path.strip():
85
+ path = "/etc/xdg"
86
+ return [self._append_app_name_and_version(p) for p in path.split(os.pathsep)]
87
+
88
+ @property
89
+ def site_config_dir(self) -> str:
90
+ """
91
+ :return: config directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>`
92
+ is enabled and ``XDG_CONFIG_DIRS`` is set and a multi path the response is also a multi path separated by
93
+ the OS path separator), e.g. ``/etc/xdg/$appname/$version``
94
+ """
95
+ # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False
96
+ dirs = self._site_config_dirs
97
+ if not self.multipath:
98
+ return dirs[0]
99
+ return os.pathsep.join(dirs)
100
+
101
+ @property
102
+ def user_cache_dir(self) -> str:
103
+ """
104
+ :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or
105
+ ``~/$XDG_CACHE_HOME/$appname/$version``
106
+ """
107
+ path = os.environ.get("XDG_CACHE_HOME", "")
108
+ if not path.strip():
109
+ path = os.path.expanduser("~/.cache") # noqa: PTH111
110
+ return self._append_app_name_and_version(path)
111
+
112
+ @property
113
+ def site_cache_dir(self) -> str:
114
+ """:return: cache directory shared by users, e.g. ``/var/cache/$appname/$version``"""
115
+ return self._append_app_name_and_version("/var/cache")
116
+
117
+ @property
118
+ def user_state_dir(self) -> str:
119
+ """
120
+ :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or
121
+ ``$XDG_STATE_HOME/$appname/$version``
122
+ """
123
+ path = os.environ.get("XDG_STATE_HOME", "")
124
+ if not path.strip():
125
+ path = os.path.expanduser("~/.local/state") # noqa: PTH111
126
+ return self._append_app_name_and_version(path)
127
+
128
+ @property
129
+ def user_log_dir(self) -> str:
130
+ """:return: log directory tied to the user, same as `user_state_dir` if not opinionated else ``log`` in it"""
131
+ path = self.user_state_dir
132
+ if self.opinion:
133
+ path = os.path.join(path, "log") # noqa: PTH118
134
+ self._optionally_create_directory(path)
135
+ return path
136
+
137
+ @property
138
+ def user_documents_dir(self) -> str:
139
+ """:return: documents directory tied to the user, e.g. ``~/Documents``"""
140
+ return _get_user_media_dir("XDG_DOCUMENTS_DIR", "~/Documents")
141
+
142
+ @property
143
+ def user_downloads_dir(self) -> str:
144
+ """:return: downloads directory tied to the user, e.g. ``~/Downloads``"""
145
+ return _get_user_media_dir("XDG_DOWNLOAD_DIR", "~/Downloads")
146
+
147
+ @property
148
+ def user_pictures_dir(self) -> str:
149
+ """:return: pictures directory tied to the user, e.g. ``~/Pictures``"""
150
+ return _get_user_media_dir("XDG_PICTURES_DIR", "~/Pictures")
151
+
152
+ @property
153
+ def user_videos_dir(self) -> str:
154
+ """:return: videos directory tied to the user, e.g. ``~/Videos``"""
155
+ return _get_user_media_dir("XDG_VIDEOS_DIR", "~/Videos")
156
+
157
+ @property
158
+ def user_music_dir(self) -> str:
159
+ """:return: music directory tied to the user, e.g. ``~/Music``"""
160
+ return _get_user_media_dir("XDG_MUSIC_DIR", "~/Music")
161
+
162
+ @property
163
+ def user_desktop_dir(self) -> str:
164
+ """:return: desktop directory tied to the user, e.g. ``~/Desktop``"""
165
+ return _get_user_media_dir("XDG_DESKTOP_DIR", "~/Desktop")
166
+
167
+ @property
168
+ def user_runtime_dir(self) -> str:
169
+ """
170
+ :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or
171
+ ``$XDG_RUNTIME_DIR/$appname/$version``.
172
+
173
+ For FreeBSD/OpenBSD/NetBSD, it would return ``/var/run/user/$(id -u)/$appname/$version`` if
174
+ exists, otherwise ``/tmp/runtime-$(id -u)/$appname/$version``, if``$XDG_RUNTIME_DIR``
175
+ is not set.
176
+ """
177
+ path = os.environ.get("XDG_RUNTIME_DIR", "")
178
+ if not path.strip():
179
+ if sys.platform.startswith(("freebsd", "openbsd", "netbsd")):
180
+ path = f"/var/run/user/{getuid()}"
181
+ if not Path(path).exists():
182
+ path = f"/tmp/runtime-{getuid()}" # noqa: S108
183
+ else:
184
+ path = f"/run/user/{getuid()}"
185
+ return self._append_app_name_and_version(path)
186
+
187
+ @property
188
+ def site_runtime_dir(self) -> str:
189
+ """
190
+ :return: runtime directory shared by users, e.g. ``/run/$appname/$version`` or \
191
+ ``$XDG_RUNTIME_DIR/$appname/$version``.
192
+
193
+ Note that this behaves almost exactly like `user_runtime_dir` if ``$XDG_RUNTIME_DIR`` is set, but will
194
+ fall back to paths associated to the root user instead of a regular logged-in user if it's not set.
195
+
196
+ If you wish to ensure that a logged-in root user path is returned e.g. ``/run/user/0``, use `user_runtime_dir`
197
+ instead.
198
+
199
+ For FreeBSD/OpenBSD/NetBSD, it would return ``/var/run/$appname/$version`` if ``$XDG_RUNTIME_DIR`` is not set.
200
+ """
201
+ path = os.environ.get("XDG_RUNTIME_DIR", "")
202
+ if not path.strip():
203
+ if sys.platform.startswith(("freebsd", "openbsd", "netbsd")):
204
+ path = "/var/run"
205
+ else:
206
+ path = "/run"
207
+ return self._append_app_name_and_version(path)
208
+
209
+ @property
210
+ def site_data_path(self) -> Path:
211
+ """:return: data path shared by users. Only return the first item, even if ``multipath`` is set to ``True``"""
212
+ return self._first_item_as_path_if_multipath(self.site_data_dir)
213
+
214
+ @property
215
+ def site_config_path(self) -> Path:
216
+ """:return: config path shared by the users, returns the first item, even if ``multipath`` is set to ``True``"""
217
+ return self._first_item_as_path_if_multipath(self.site_config_dir)
218
+
219
+ @property
220
+ def site_cache_path(self) -> Path:
221
+ """:return: cache path shared by users. Only return the first item, even if ``multipath`` is set to ``True``"""
222
+ return self._first_item_as_path_if_multipath(self.site_cache_dir)
223
+
224
+ def iter_config_dirs(self) -> Iterator[str]:
225
+ """:yield: all user and site configuration directories."""
226
+ yield self.user_config_dir
227
+ yield from self._site_config_dirs
228
+
229
+ def iter_data_dirs(self) -> Iterator[str]:
230
+ """:yield: all user and site data directories."""
231
+ yield self.user_data_dir
232
+ yield from self._site_data_dirs
233
+
234
+
235
+ def _get_user_media_dir(env_var: str, fallback_tilde_path: str) -> str:
236
+ media_dir = _get_user_dirs_folder(env_var)
237
+ if media_dir is None:
238
+ media_dir = os.environ.get(env_var, "").strip()
239
+ if not media_dir:
240
+ media_dir = os.path.expanduser(fallback_tilde_path) # noqa: PTH111
241
+
242
+ return media_dir
243
+
244
+
245
+ def _get_user_dirs_folder(key: str) -> str | None:
246
+ """
247
+ Return directory from user-dirs.dirs config file.
248
+
249
+ See https://freedesktop.org/wiki/Software/xdg-user-dirs/.
250
+
251
+ """
252
+ user_dirs_config_path = Path(Unix().user_config_dir) / "user-dirs.dirs"
253
+ if user_dirs_config_path.exists():
254
+ parser = ConfigParser()
255
+
256
+ with user_dirs_config_path.open() as stream:
257
+ # Add fake section header, so ConfigParser doesn't complain
258
+ parser.read_string(f"[top]\n{stream.read()}")
259
+
260
+ if key not in parser["top"]:
261
+ return None
262
+
263
+ path = parser["top"][key].strip('"')
264
+ # Handle relative home paths
265
+ return path.replace("$HOME", os.path.expanduser("~")) # noqa: PTH111
266
+
267
+ return None
268
+
269
+
270
+ __all__ = [
271
+ "Unix",
272
+ ]
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/version.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
6
+ TYPE_CHECKING = False
7
+ if TYPE_CHECKING:
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
12
+ else:
13
+ VERSION_TUPLE = object
14
+
15
+ version: str
16
+ __version__: str
17
+ __version_tuple__: VERSION_TUPLE
18
+ version_tuple: VERSION_TUPLE
19
+
20
+ __version__ = version = '4.3.8'
21
+ __version_tuple__ = version_tuple = (4, 3, 8)
external/alphageometry/.venv-ag/Lib/site-packages/pip/_vendor/platformdirs/windows.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Windows."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+ from functools import lru_cache
8
+ from typing import TYPE_CHECKING
9
+
10
+ from .api import PlatformDirsABC
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Callable
14
+
15
+
16
+ class Windows(PlatformDirsABC):
17
+ """
18
+ `MSDN on where to store app data files <https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid>`_.
19
+
20
+ Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `appauthor
21
+ <platformdirs.api.PlatformDirsABC.appauthor>`, `version <platformdirs.api.PlatformDirsABC.version>`, `roaming
22
+ <platformdirs.api.PlatformDirsABC.roaming>`, `opinion <platformdirs.api.PlatformDirsABC.opinion>`, `ensure_exists
23
+ <platformdirs.api.PlatformDirsABC.ensure_exists>`.
24
+
25
+ """
26
+
27
+ @property
28
+ def user_data_dir(self) -> str:
29
+ """
30
+ :return: data directory tied to the user, e.g.
31
+ ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname`` (not roaming) or
32
+ ``%USERPROFILE%\\AppData\\Roaming\\$appauthor\\$appname`` (roaming)
33
+ """
34
+ const = "CSIDL_APPDATA" if self.roaming else "CSIDL_LOCAL_APPDATA"
35
+ path = os.path.normpath(get_win_folder(const))
36
+ return self._append_parts(path)
37
+
38
+ def _append_parts(self, path: str, *, opinion_value: str | None = None) -> str:
39
+ params = []
40
+ if self.appname:
41
+ if self.appauthor is not False:
42
+ author = self.appauthor or self.appname
43
+ params.append(author)
44
+ params.append(self.appname)
45
+ if opinion_value is not None and self.opinion:
46
+ params.append(opinion_value)
47
+ if self.version:
48
+ params.append(self.version)
49
+ path = os.path.join(path, *params) # noqa: PTH118
50
+ self._optionally_create_directory(path)
51
+ return path
52
+
53
+ @property
54
+ def site_data_dir(self) -> str:
55
+ """:return: data directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname``"""
56
+ path = os.path.normpath(get_win_folder("CSIDL_COMMON_APPDATA"))
57
+ return self._append_parts(path)
58
+
59
+ @property
60
+ def user_config_dir(self) -> str:
61
+ """:return: config directory tied to the user, same as `user_data_dir`"""
62
+ return self.user_data_dir
63
+
64
+ @property
65
+ def site_config_dir(self) -> str:
66
+ """:return: config directory shared by the users, same as `site_data_dir`"""
67
+ return self.site_data_dir
68
+
69
+ @property
70
+ def user_cache_dir(self) -> str:
71
+ """
72
+ :return: cache directory tied to the user (if opinionated with ``Cache`` folder within ``$appname``) e.g.
73
+ ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname\\Cache\\$version``
74
+ """
75
+ path = os.path.normpath(get_win_folder("CSIDL_LOCAL_APPDATA"))
76
+ return self._append_parts(path, opinion_value="Cache")
77
+
78
+ @property
79
+ def site_cache_dir(self) -> str:
80
+ """:return: cache directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname\\Cache\\$version``"""
81
+ path = os.path.normpath(get_win_folder("CSIDL_COMMON_APPDATA"))
82
+ return self._append_parts(path, opinion_value="Cache")
83
+
84
+ @property
85
+ def user_state_dir(self) -> str:
86
+ """:return: state directory tied to the user, same as `user_data_dir`"""
87
+ return self.user_data_dir
88
+
89
+ @property
90
+ def user_log_dir(self) -> str:
91
+ """:return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``Logs`` in it"""
92
+ path = self.user_data_dir
93
+ if self.opinion:
94
+ path = os.path.join(path, "Logs") # noqa: PTH118
95
+ self._optionally_create_directory(path)
96
+ return path
97
+
98
+ @property
99
+ def user_documents_dir(self) -> str:
100
+ """:return: documents directory tied to the user e.g. ``%USERPROFILE%\\Documents``"""
101
+ return os.path.normpath(get_win_folder("CSIDL_PERSONAL"))
102
+
103
+ @property
104
+ def user_downloads_dir(self) -> str:
105
+ """:return: downloads directory tied to the user e.g. ``%USERPROFILE%\\Downloads``"""
106
+ return os.path.normpath(get_win_folder("CSIDL_DOWNLOADS"))
107
+
108
+ @property
109
+ def user_pictures_dir(self) -> str:
110
+ """:return: pictures directory tied to the user e.g. ``%USERPROFILE%\\Pictures``"""
111
+ return os.path.normpath(get_win_folder("CSIDL_MYPICTURES"))
112
+
113
+ @property
114
+ def user_videos_dir(self) -> str:
115
+ """:return: videos directory tied to the user e.g. ``%USERPROFILE%\\Videos``"""
116
+ return os.path.normpath(get_win_folder("CSIDL_MYVIDEO"))
117
+
118
+ @property
119
+ def user_music_dir(self) -> str:
120
+ """:return: music directory tied to the user e.g. ``%USERPROFILE%\\Music``"""
121
+ return os.path.normpath(get_win_folder("CSIDL_MYMUSIC"))
122
+
123
+ @property
124
+ def user_desktop_dir(self) -> str:
125
+ """:return: desktop directory tied to the user, e.g. ``%USERPROFILE%\\Desktop``"""
126
+ return os.path.normpath(get_win_folder("CSIDL_DESKTOPDIRECTORY"))
127
+
128
+ @property
129
+ def user_runtime_dir(self) -> str:
130
+ """
131
+ :return: runtime directory tied to the user, e.g.
132
+ ``%USERPROFILE%\\AppData\\Local\\Temp\\$appauthor\\$appname``
133
+ """
134
+ path = os.path.normpath(os.path.join(get_win_folder("CSIDL_LOCAL_APPDATA"), "Temp")) # noqa: PTH118
135
+ return self._append_parts(path)
136
+
137
+ @property
138
+ def site_runtime_dir(self) -> str:
139
+ """:return: runtime directory shared by users, same as `user_runtime_dir`"""
140
+ return self.user_runtime_dir
141
+
142
+
143
+ def get_win_folder_from_env_vars(csidl_name: str) -> str:
144
+ """Get folder from environment variables."""
145
+ result = get_win_folder_if_csidl_name_not_env_var(csidl_name)
146
+ if result is not None:
147
+ return result
148
+
149
+ env_var_name = {
150
+ "CSIDL_APPDATA": "APPDATA",
151
+ "CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE",
152
+ "CSIDL_LOCAL_APPDATA": "LOCALAPPDATA",
153
+ }.get(csidl_name)
154
+ if env_var_name is None:
155
+ msg = f"Unknown CSIDL name: {csidl_name}"
156
+ raise ValueError(msg)
157
+ result = os.environ.get(env_var_name)
158
+ if result is None:
159
+ msg = f"Unset environment variable: {env_var_name}"
160
+ raise ValueError(msg)
161
+ return result
162
+
163
+
164
+ def get_win_folder_if_csidl_name_not_env_var(csidl_name: str) -> str | None:
165
+ """Get a folder for a CSIDL name that does not exist as an environment variable."""
166
+ if csidl_name == "CSIDL_PERSONAL":
167
+ return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Documents") # noqa: PTH118
168
+
169
+ if csidl_name == "CSIDL_DOWNLOADS":
170
+ return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Downloads") # noqa: PTH118
171
+
172
+ if csidl_name == "CSIDL_MYPICTURES":
173
+ return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Pictures") # noqa: PTH118
174
+
175
+ if csidl_name == "CSIDL_MYVIDEO":
176
+ return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Videos") # noqa: PTH118
177
+
178
+ if csidl_name == "CSIDL_MYMUSIC":
179
+ return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Music") # noqa: PTH118
180
+ return None
181
+
182
+
183
+ def get_win_folder_from_registry(csidl_name: str) -> str:
184
+ """
185
+ Get folder from the registry.
186
+
187
+ This is a fallback technique at best. I'm not sure if using the registry for these guarantees us the correct answer
188
+ for all CSIDL_* names.
189
+
190
+ """
191
+ shell_folder_name = {
192
+ "CSIDL_APPDATA": "AppData",
193
+ "CSIDL_COMMON_APPDATA": "Common AppData",
194
+ "CSIDL_LOCAL_APPDATA": "Local AppData",
195
+ "CSIDL_PERSONAL": "Personal",
196
+ "CSIDL_DOWNLOADS": "{374DE290-123F-4565-9164-39C4925E467B}",
197
+ "CSIDL_MYPICTURES": "My Pictures",
198
+ "CSIDL_MYVIDEO": "My Video",
199
+ "CSIDL_MYMUSIC": "My Music",
200
+ }.get(csidl_name)
201
+ if shell_folder_name is None:
202
+ msg = f"Unknown CSIDL name: {csidl_name}"
203
+ raise ValueError(msg)
204
+ if sys.platform != "win32": # only needed for mypy type checker to know that this code runs only on Windows
205
+ raise NotImplementedError
206
+ import winreg # noqa: PLC0415
207
+
208
+ key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
209
+ directory, _ = winreg.QueryValueEx(key, shell_folder_name)
210
+ return str(directory)
211
+
212
+
213
+ def get_win_folder_via_ctypes(csidl_name: str) -> str:
214
+ """Get folder with ctypes."""
215
+ # There is no 'CSIDL_DOWNLOADS'.
216
+ # Use 'CSIDL_PROFILE' (40) and append the default folder 'Downloads' instead.
217
+ # https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid
218
+
219
+ import ctypes # noqa: PLC0415
220
+
221
+ csidl_const = {
222
+ "CSIDL_APPDATA": 26,
223
+ "CSIDL_COMMON_APPDATA": 35,
224
+ "CSIDL_LOCAL_APPDATA": 28,
225
+ "CSIDL_PERSONAL": 5,
226
+ "CSIDL_MYPICTURES": 39,
227
+ "CSIDL_MYVIDEO": 14,
228
+ "CSIDL_MYMUSIC": 13,
229
+ "CSIDL_DOWNLOADS": 40,
230
+ "CSIDL_DESKTOPDIRECTORY": 16,
231
+ }.get(csidl_name)
232
+ if csidl_const is None:
233
+ msg = f"Unknown CSIDL name: {csidl_name}"
234
+ raise ValueError(msg)
235
+
236
+ buf = ctypes.create_unicode_buffer(1024)
237
+ windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker
238
+ windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
239
+
240
+ # Downgrade to short path name if it has high-bit chars.
241
+ if any(ord(c) > 255 for c in buf): # noqa: PLR2004
242
+ buf2 = ctypes.create_unicode_buffer(1024)
243
+ if windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
244
+ buf = buf2
245
+
246
+ if csidl_name == "CSIDL_DOWNLOADS":
247
+ return os.path.join(buf.value, "Downloads") # noqa: PTH118
248
+
249
+ return buf.value
250
+
251
+
252
+ def _pick_get_win_folder() -> Callable[[str], str]:
253
+ try:
254
+ import ctypes # noqa: PLC0415
255
+ except ImportError:
256
+ pass
257
+ else:
258
+ if hasattr(ctypes, "windll"):
259
+ return get_win_folder_via_ctypes
260
+ try:
261
+ import winreg # noqa: PLC0415, F401
262
+ except ImportError:
263
+ return get_win_folder_from_env_vars
264
+ else:
265
+ return get_win_folder_from_registry
266
+
267
+
268
+ get_win_folder = lru_cache(maxsize=None)(_pick_get_win_folder())
269
+
270
+ __all__ = [
271
+ "Windows",
272
+ ]