diff --git a/.context.yaml b/.context.yaml deleted file mode 100644 index 44362ef..0000000 --- a/.context.yaml +++ /dev/null @@ -1 +0,0 @@ -items: {} diff --git a/.gitignore b/.gitignore index e88c9fd..73e2a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ __pycache__/ -#.context.yaml build/ dist/ *.egg-info/ diff --git a/README.md b/README.md index 1773ddb..f929d2e 100644 --- a/README.md +++ b/README.md @@ -26,18 +26,128 @@ So a as an example an audio-file could be assigned to project `+album` and have $ uv tool install 'orvanitag[all]' ``` -The core only needs PyYAML and rich. Reading and writing embedded metadata uses optional extras: `audio` (pytaglib, needs the TagLib C library), `pdf` (pypdf), `office` (olefile, only for legacy `.doc`/`.xls`/`.ppt`) and `markdown` (python-frontmatter). Plugins whose extra is not installed are skipped. +Requires Python 3.11 or newer. The core only needs rich. Reading and writing embedded metadata uses optional extras: `audio` (pytaglib, needs the TagLib C library), `pdf` (pypdf), `office` (olefile, only for legacy `.doc`/`.xls`/`.ppt`) and `markdown` (python-frontmatter). Plugins whose extra is not installed are skipped. ## Command Line Tool -### Assigning Contextual Tags - -Let's ``` -$ otag add [contextual tags ...] +$ otag [arguments ...] [flags] ``` -Removing contextual tags from a file +Every command has a short alias, listed in brackets. `otag -h` prints an overview. Words starting with `+`, `@` or `#` become projects, contexts and tags; all other words form the note. Quote hashtags in the shell (`'#lofi'`), because an unquoted `#` starts a comment. + +### Tagging + +`add` (`a`) adds projects, contexts, tags and a note to an existing file or folder. Adding to an already tagged file merges the tags and replaces the note. + ``` -$ otag remove [contextual tags ...] -``` \ No newline at end of file +$ otag add song.mp3 +album @drums '#lofi' '#snare' first take +``` + +`remove` (`r`) removes the given projects, contexts and tags. Without any, it removes the whole entry. + +``` +$ otag remove song.mp3 '#snare' +$ otag remove song.mp3 +``` + +### Searching + +`list` (`ls`, `l`) searches the current directory tree and prints the matching files with their tags. Without a query it lists every tagged file. + +``` +$ otag ls '#lofi' @drums +``` + +A term with a prefix only matches that category; a term without a prefix matches any category and the note. Terms match partially (`lof` finds `#lofi`) and all terms have to match. + +| Flag | Effect | +|---|---| +| `-e`, `--exact` | Match whole terms only | +| `-or`, `--either` | Match any term instead of all | +| `--files` | Only show files | +| `-d`, `--dirs` | Only show folders | +| `-p`, `--path PATH` | Search another directory tree | +| `-r`, `--recursive` | Skip subdirectories (despite its name; subdirectories are included by default) | +| `-c`, `--cache` | Read the index from `.otag.cache.json`, which is rebuilt whenever an `.otag` file changed | +| `-dc`, `--delete-cache` | Delete `.otag.cache.json` before searching | + +### Copying, Moving and Deleting + +`copy` (`cp`) and `move` (`mv`) transfer the tags of a file to another path. By default only the tags are transferred; `-f` (`--file-operation`) also copies or moves the file itself. The destination needs a directory part, so write `./new.mp3` rather than `new.mp3`. With `-f`, a destination ending in `/` keeps the file name. + +``` +$ otag cp song.mp3 ./song-copy.mp3 +$ otag mv -f song.mp3 archive/ +``` + +`del` (`rm`) removes the entry of a file; `-f` also deletes the file. + +``` +$ otag rm -f song.mp3 +``` + +### Maintenance + +`clean` (`c`) removes entries whose files no longer exist, in the given folder (default: current) and its subdirectories. + +`purge` (`p`) deletes all `.otag` and `.otag.cache.json` files in the given folder and its subdirectories. This removes every tag in that tree and cannot be undone. + +``` +$ otag clean +$ otag purge old-project/ +``` + +### Embedded Metadata + +`scan` (`s`) reads tags that are embedded in files and adds them to their entries, in the given folder (default: current) and its subdirectories. + +`write` (`w`) writes the entry of a file into the file itself, using the named plugin. + +``` +$ otag scan music/ +$ otag write id3 song.mp3 +``` + +| Plugin | File types | Where the tags are stored | +|---|---|---| +| `id3` | `.mp3` `.wav` `.flac` `.ogg` | The comment tag | +| `pdf` | `.pdf` | The keywords field | +| `office` | `.docx` `.xlsx` `.pptx` `.odt` `.ods` `.odp`, reading also `.doc` `.xls` `.ppt` | The description field | +| `frontmatter` | `.md` `.txt` `.markdown` `.rst` | `projects`, `contexts`, `tags` and `note` keys of the YAML front matter | +| `hash//` | Source code such as `.py` `.js` `.c` `.rs`, plus `.md` `.txt` | A `#// +project @context #tag note` line within the first five lines | + +### Import and Export + +`export` (`e`) writes all entries of the file's directory tree to a text file (default: `context.txt`), one `path --- tags` line per file. `import` (`i`) reads such a file back and adds the tags that are missing. + +``` +$ otag export backup.txt +$ otag import backup.txt +``` + +## How Tags Are Stored + +Each folder keeps the entries of its files and subfolders in a plain text `.otag` file, so tags travel with the folder when it is copied, synced or archived. Every line holds one entry in the same syntax as the command line: the name, ` --- `, then projects, contexts, tags and the note. Folder names end with `/`. + +``` +Boombap Loop.wav --- +album @drums #boombap #lofi +song.mp3 --- +album @drums #lofi #snare first take +stems/ --- @archive +``` + +The file can be edited by hand. A line without ` --- ` stops otag with an error naming the file and line, so nothing gets overwritten until it is fixed. Note words starting with `+`, `@` or `#` are read as tags. + +An optional `.otag.toml` in the same folder configures `scan` and `write` there: + +```toml +plugins = ["id3", "pdf"] + +[id3] +types = [".mp3", ".flac"] + +[id3.map] +tags = "genre" +``` + +`plugins` limits which plugins run (`hash//` is listed as `hashdoubleslash`), `types` overrides the file types a plugin handles, and `id3.map` additionally reads an audio tag (here `GENRE`) into a category. diff --git a/orvanitag/orvani.py b/orvanitag/orvani.py index 6bc73e8..2f9ccef 100644 --- a/orvanitag/orvani.py +++ b/orvanitag/orvani.py @@ -1,27 +1,19 @@ import os import re -import yaml +import json import shutil +import tomllib from pathlib import Path from importlib import import_module from types import SimpleNamespace from pprint import pprint -# libyaml is much faster, but PyYAML can be built without it. -SafeLoader = getattr(yaml, 'CSafeLoader', yaml.SafeLoader) -SafeDumper = getattr(yaml, 'CSafeDumper', yaml.SafeDumper) - -class VerboseSafeDumper(SafeDumper): - def ignore_aliases(self, data): - return True - -def load_yaml(text: str): - return yaml.load(text, Loader=SafeLoader) - # Defaults -CONTEXT_FILE = '.context.yaml' -CACHE_FILE = '.index.yaml' +CONTEXT_FILE = '.otag' +CONFIG_FILE = '.otag.toml' +CACHE_FILE = '.otag.cache.json' +SEPARATOR = ' --- ' # between file name and contexts, in context files and exports CONTEXTS = { 'projects' : '+', 'contexts' : '@', @@ -63,12 +55,11 @@ class OrvaniTag: self.PLUGINS = list(plugins) # List of plugin names self.MODULES = None # Imported plugin modules, see __plugins() - self.FILENAME = os.path.basename(path) # folder context data filename ('.context.yaml') - self.CACHEFILE = cache # search index cache ('.index.yaml') + self.FILENAME = os.path.basename(path) # folder context data filename ('.otag') + self.CACHEFILE = cache # search index cache ('.otag.cache.json') self.SCHEMA = contexts # Default context schema self.DB = dict() # holds the folder context data self.CONFIG = dict() # Currently used configuration - self.LOCAL_CONFIG = None # The current folder's own config block, rewritten on save self.CONF_FILES = [] # List to keep track of config files in the directory tree self.FILE = '' # holds the folder context file path self.INDEX = self.__emptyindex() # our search index @@ -99,40 +90,42 @@ class OrvaniTag: common = '.' + os.path.commonpath([conf_file, str(path)]) if common == '.': common = './' if common == conf_file: - cfile = Path(conf_file) / self.FILENAME + cfile = Path(conf_file) / CONFIG_FILE if cfile.exists(): - conf = load_yaml(cfile.read_text()) - if 'config' in conf: - self.CONFIG = conf['config'] + self.CONFIG = tomllib.loads(cfile.read_text(encoding='utf-8')) continue else: # if there is no config up the tree, then use defaults self.CONFIG = dict() self.FILE = Path(str(path)) / self.FILENAME - self.LOCAL_CONFIG = None - if self.FILE.exists(): # is there a folder ocntext file? - y = load_yaml(self.FILE.read_text()) or {} - self.LOCAL_CONFIG = y.get('config') + self.DB = self.__read(self.FILE) if self.FILE.exists() else dict() - if 'items' in y: - self.DB = y['items'] or {} # load items to current context DB + cfile = Path(str(path)) / CONFIG_FILE + if cfile.exists(): # load optional local configuration + self.CONFIG = tomllib.loads(cfile.read_text(encoding='utf-8')) + self.CONF_FILES.append(str(path)) # and save it in our known files list + self.CONF_FILES = [x for x in self.CONF_FILES if x != ''] + self.CONF_FILES = sorted(list(set(self.CONF_FILES)), key=lambda x: x.count('/'), reverse=True) + elif config: + __config(path) - if 'config' in y: # load optional local configuration - self.CONFIG = y['config'] - self.CONF_FILES.append(str(path)) # and save it in our known files list - self.CONF_FILES = [x for x in self.CONF_FILES if x != ''] - self.CONF_FILES = sorted(list(set(self.CONF_FILES)), key=lambda x: x.count('/'), reverse=True) - else: - if config: - __config(path) - else: - self.DB = dict() - - else: - self.DB = dict() - if config: - __config(path) + def __read(self, file: Path) -> dict: + """ + Parses a context file: one `name --- +project @context #tag note` line per entry, + folder names end with a slash + """ + db = dict() + for num, line in enumerate(file.read_text(encoding='utf-8').splitlines(), start=1): + if not line.strip(): + continue + name, separator, string = line.partition(SEPARATOR) + if not separator or not name: + # Raising instead of skipping, since the next save would silently drop the line + raise ValueError(f'{file}:{num}: expected "name{SEPARATOR}contexts", got "{line}"') + name = name[:-1] if name.endswith('/') else name + db[name] = self.__context(string.split()) + return db def __save(self): @@ -140,14 +133,21 @@ class OrvaniTag: Save current folder context to file """ file = Path(self.FILE) - yf = { 'items' : self.DB } # load current context into dict - if self.LOCAL_CONFIG is not None: - yf['config'] = self.LOCAL_CONFIG + lines = [] + for name in sorted(self.DB): + contexts = ' '.join(self.__collect_contexts(self.DB[name])) + if contexts: # entries without any context are dropped + slash = '/' if (file.parent / name).is_dir() else '' + lines.append(f'{name}{slash}{SEPARATOR}{contexts}\n') + + if not lines: + file.unlink(missing_ok=True) + return self.FILE + # Swap in a finished temp file so a failed write never truncates the existing context. tmp = file.with_name(f'.{file.name}.{os.getpid()}.tmp') try: - with tmp.open('w') as data: - yaml.dump(yf, data, Dumper=VerboseSafeDumper) + tmp.write_text(''.join(lines), encoding='utf-8') if file.exists(): shutil.copymode(file, tmp) os.replace(tmp, file) @@ -223,8 +223,8 @@ class OrvaniTag: stat = os.stat(os.path.join(folder, self.FILENAME)) sources[folder] = [stat.st_mtime_ns, stat.st_size] if cachefile.is_file(): # load index from cache - cached = load_yaml(cachefile.read_text()) or {} - # Caches without matching 'sources' (older format or changed context files) are rebuilt + cached = json.loads(cachefile.read_text(encoding='utf-8')) + # A cache built from other or since changed context files is rebuilt if cached.get('sources') == sources and cached.get('recursive') == recursive: self.INDEX = cached['index'] return @@ -239,8 +239,7 @@ class OrvaniTag: self.INDEX['items'] = dict(sorted(self.INDEX['items'].items())) if cache: # If we just created an index, write it to cache - with open(cachefile, 'w+') as data: - yaml.dump({'recursive': recursive, 'sources': sources, 'index': self.INDEX}, data, Dumper=SafeDumper) + cachefile.write_text(json.dumps({'recursive': recursive, 'sources': sources, 'index': self.INDEX}), encoding='utf-8') def __indexfolder(self, sub: str): diff --git a/pyproject.toml b/pyproject.toml index 0a14b78..5abfb94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,13 +12,12 @@ readme = "README.md" license = "MIT" license-files = ["LICENSE"] authors = [{ name = "randogoth", email = "randogoth@posteo.org" }] -requires-python = ">=3.9" +requires-python = ">=3.11" classifiers = [ "Programming Language :: Python :: 3", "Operating System :: OS Independent", ] dependencies = [ - "PyYAML>=6.0", "rich>=13.4.2", ] diff --git a/tests/test_orvani.py b/tests/test_orvani.py index 8d58220..3e893cf 100644 --- a/tests/test_orvani.py +++ b/tests/test_orvani.py @@ -1,7 +1,6 @@ import os import pytest -import yaml import orvanitag.orvani as orvani from orvanitag.orvani import OrvaniTag, DEFAULT_PLUGINS @@ -21,8 +20,8 @@ def found(o, *query, either=False, path=''): return o.list(path, True, either, True, False, False, *query)['found'] -def items(path='.'): - return yaml.safe_load((path / orvani.CONTEXT_FILE).read_text())['items'] +def lines(path): + return (path / orvani.CONTEXT_FILE).read_text().splitlines() def test_and_search_within_one_category(tree): @@ -65,12 +64,12 @@ def test_empty_query_lists_everything(tree): def test_multi_word_note(tree): OrvaniTag().add('a.mp3', '#lofi', 'my', 'long', 'note') - assert items(tree)['a.mp3']['note'] == 'my long note' + assert lines(tree) == ['a.mp3 --- #lofi my long note'] def test_trailing_commas_are_stripped(tree): OrvaniTag().add('a.mp3', '#lofi,', '#snare') - assert items(tree)['a.mp3']['tags'] == ['lofi', 'snare'] + assert lines(tree) == ['a.mp3 --- #lofi #snare'] def test_clean_keeps_tagged_directories(tree): @@ -79,7 +78,7 @@ def test_clean_keeps_tagged_directories(tree): o.add('a.mp3', '#lofi') (tree / 'a.mp3').unlink() assert o.clean('', True)[2] == 1 - assert list(items(tree)) == ['sub'] + assert lines(tree) == ['sub/ --- #folder'] def test_instances_do_not_share_state(tree): @@ -106,16 +105,38 @@ def test_move_tagged_file(tree): o.add('a.mp3', '#lofi') assert o.move('a.mp3', 'sub/', False, True)[0] == 0 assert (tree / 'sub' / 'a.mp3').exists() - assert items(tree / 'sub')['a.mp3']['tags'] == ['lofi'] + assert lines(tree / 'sub') == ['a.mp3 --- #lofi'] assert not (tree / orvani.CONTEXT_FILE).exists() -def test_save_keeps_config(tree): - (tree / orvani.CONTEXT_FILE).write_text('config:\n plugins: [pdf]\nitems: {}\n') - OrvaniTag().add('a.mp3', '#lofi') - data = yaml.safe_load((tree / orvani.CONTEXT_FILE).read_text()) - assert data['config'] == {'plugins': ['pdf']} - assert data['items']['a.mp3']['tags'] == ['lofi'] +def test_config_without_tags(tree): + (tree / orvani.CONFIG_FILE).write_text('plugins = ["pdf"]\n') + assert OrvaniTag().CONFIG == {'plugins': ['pdf']} + + +def test_removing_last_entry_keeps_config(tree): + (tree / orvani.CONFIG_FILE).write_text('plugins = ["pdf"]\n') + o = OrvaniTag() + o.add('a.mp3', '#lofi') + o.delete('a.mp3') + assert not (tree / orvani.CONTEXT_FILE).exists() + assert (tree / orvani.CONFIG_FILE).exists() + + +def test_file_names_with_spaces_and_separator_in_note(tree): + (tree / 'My Track.flac').touch() + o = OrvaniTag() + o.add('My Track.flac', '#boombap', 'a', '---', 'b') + assert lines(tree) == ['My Track.flac --- #boombap a --- b'] + assert found(o, '#boombap') == ['./My Track.flac'] + assert o.index('')['items']['./My Track.flac']['note'] == 'a --- b' + + +def test_malformed_line_raises_and_keeps_file(tree): + (tree / orvani.CONTEXT_FILE).write_text('a.mp3 --- #lofi\nb.mp3 #broken\n') + with pytest.raises(ValueError, match=r'\.otag:2'): + OrvaniTag().add('c.mp3', '#new') + assert lines(tree) == ['a.mp3 --- #lofi', 'b.mp3 #broken'] def test_failed_save_keeps_old_file(tree, monkeypatch): @@ -123,9 +144,9 @@ def test_failed_save_keeps_old_file(tree, monkeypatch): o.add('a.mp3', '#lofi') before = (tree / orvani.CONTEXT_FILE).read_text() - def broken_dump(*args, **kwargs): + def broken_replace(*args, **kwargs): raise RuntimeError('disk full') - monkeypatch.setattr(orvani.yaml, 'dump', broken_dump) + monkeypatch.setattr(orvani.os, 'replace', broken_replace) with pytest.raises(RuntimeError): o.add('a.mp3', '#snare') @@ -141,7 +162,7 @@ def test_remove_saves_once(tree, monkeypatch): monkeypatch.setattr(o, '_OrvaniTag__save', lambda: saves.append(1) or save()) assert o.remove('a.mp3', '#lofi', '#snare')[0] == 0 assert len(saves) == 1 - assert items(tree)['a.mp3']['tags'] == ['keep'] + assert lines(tree) == ['a.mp3 --- #keep'] def test_cache_is_rebuilt_when_context_changes(tree): @@ -165,9 +186,8 @@ def test_import_untagged_files(tree): (tree / 'sub' / orvani.CONTEXT_FILE).unlink() assert OrvaniTag().load('context.txt') == [0, 'context.txt', 2] - assert items(tree)['a.mp3']['tags'] == ['lofi'] - assert items(tree)['a.mp3']['note'] == 'a note' - assert items(tree / 'sub')['d.txt']['contexts'] == ['docs'] + assert lines(tree) == ['a.mp3 --- #lofi a note'] + assert lines(tree / 'sub') == ['d.txt --- @docs'] def test_import_skips_known_tags_and_empty_lines(tree): @@ -175,5 +195,4 @@ def test_import_skips_known_tags_and_empty_lines(tree): o.add('a.mp3', '#lofi') (tree / 'context.txt').write_text('./a.mp3 --- #lofi #snare\n./b.mp3 --- \n') assert OrvaniTag().load('context.txt') == [0, 'context.txt', 1] - assert items(tree)['a.mp3']['tags'] == ['lofi', 'snare'] - assert 'b.mp3' not in items(tree) + assert lines(tree) == ['a.mp3 --- #lofi #snare'] diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 17edc81..1320bd1 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -2,7 +2,6 @@ import sys import zipfile import pytest -import yaml from pypdf import PdfReader, PdfWriter import orvanitag.orvani as orvani @@ -48,10 +47,7 @@ def roundtrip(cwd, name): assert o.write_metadata(name, 'office')[0] == 0 (cwd / orvani.CONTEXT_FILE).unlink() OrvaniTag().read_metadata(name) - entry = yaml.safe_load((cwd / orvani.CONTEXT_FILE).read_text())['items'][name] - assert entry['tags'] == ['lofi'] - assert entry['projects'] == ['proj'] - assert entry['note'] == 'R&B C:\\1' + assert (cwd / orvani.CONTEXT_FILE).read_text() == f'{name} --- +proj #lofi R&B C:\\1\n' assert not list(cwd.glob('unzip__*')) @@ -86,8 +82,7 @@ def test_pdf_roundtrip(cwd): (cwd / orvani.CONTEXT_FILE).unlink() OrvaniTag().read_metadata('doc.pdf') - entry = yaml.safe_load((cwd / orvani.CONTEXT_FILE).read_text())['items']['doc.pdf'] - assert entry == {'projects': [], 'contexts': ['desk'], 'tags': ['lofi'], 'note': 'a note'} + assert (cwd / orvani.CONTEXT_FILE).read_text() == 'doc.pdf --- @desk #lofi a note\n' def test_cmd_write(cwd, monkeypatch): @@ -101,9 +96,9 @@ def test_cmd_write(cwd, monkeypatch): def test_cmd_prints_errors(cwd, monkeypatch, capsys): (cwd / 'a.mp3').touch() - (cwd / orvani.CONTEXT_FILE).write_text('items: [unclosed') + (cwd / orvani.CONTEXT_FILE).write_text('a.mp3 #broken\n') monkeypatch.setattr(sys, 'argv', ['otag', 'a', 'a.mp3', '#lofi']) with pytest.raises(SystemExit) as exit: main() assert exit.value.code == 1 - assert 'expected' in capsys.readouterr().out + assert '.otag:1' in capsys.readouterr().out diff --git a/uv.lock b/uv.lock index 868b821..c48f9f2 100644 --- a/uv.lock +++ b/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.10'", - "python_full_version < '3.10'", -] +requires-python = ">=3.11" [[package]] name = "colorama" @@ -15,64 +11,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "exceptiongroup" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, -] - [[package]] name = "iniconfig" version = "2.3.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] sdist = { url = "https://files.pythonhosted.org/packages/01/e1/2069291243c926a2ff1cd706c7f3eeb9b62144bf60f77c9fb9ff2fb26bd3/iniconfig-2.3.1.tar.gz", hash = "sha256:67f4b9c50da0dedf52af349e7749a80a9057a5031199791b906c3bb3ae878960", size = 21209, upload-time = "2026-10-06T22:48:38.076Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" }, ] -[[package]] -name = "markdown-it-py" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, -] - [[package]] name = "markdown-it-py" version = "4.2.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] dependencies = [ { name = "mdurl" }, ] @@ -104,7 +55,6 @@ name = "orvanitag" version = "1.1.0" source = { editable = "." } dependencies = [ - { name = "pyyaml" }, { name = "rich" }, ] @@ -112,18 +62,14 @@ dependencies = [ all = [ { name = "olefile" }, { name = "pypdf" }, - { name = "pytaglib", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytaglib", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "python-frontmatter", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "python-frontmatter", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pytaglib" }, + { name = "python-frontmatter" }, ] audio = [ - { name = "pytaglib", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytaglib", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pytaglib" }, ] markdown = [ - { name = "python-frontmatter", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "python-frontmatter", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "python-frontmatter" }, ] office = [ { name = "olefile" }, @@ -135,8 +81,7 @@ pdf = [ [package.dev-dependencies] dev = [ { name = "orvanitag", extra = ["markdown", "office", "pdf"] }, - { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest", version = "9.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pytest" }, ] [package.metadata] @@ -146,7 +91,6 @@ requires-dist = [ { name = "pypdf", marker = "extra == 'pdf'", specifier = ">=4.0" }, { name = "pytaglib", marker = "extra == 'audio'", specifier = ">=2.0.0" }, { name = "python-frontmatter", marker = "extra == 'markdown'", specifier = ">=1.0" }, - { name = "pyyaml", specifier = ">=6.0" }, { name = "rich", specifier = ">=13.4.2" }, ] provides-extras = ["audio", "pdf", "office", "markdown", "all"] @@ -166,25 +110,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, ] -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - [[package]] name = "pluggy" version = "1.7.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] sdist = { url = "https://files.pythonhosted.org/packages/bf/db/7fc19e6f2dc92a966727031389fc2e08b558f0f25eb7403c1119ad4713cd/pluggy-1.7.0.tar.gz", hash = "sha256:d1eaa46ebb595891b860ab086b4d09c8588af65ebd4361b8e8f4bb8920b90ba8", size = 123304, upload-time = "2026-10-15T09:50:58.343Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/40/9e/2b38731e0fc536806f16490e1a12d7f0dc2a1235aa8cc07bcc75416a7daa/pluggy-1.7.0-py3-none-any.whl", hash = "sha256:7dd7b0d8832ba3cb632c306926ded123429211b83641b35dc5c41ad2d34f9bec", size = 27082, upload-time = "2026-10-15T09:50:56.808Z" }, @@ -203,69 +132,17 @@ wheels = [ name = "pypdf" version = "6.21.2" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] sdist = { url = "https://files.pythonhosted.org/packages/06/28/081f1cbcca7042441dafc8de00f48ba60853f89e5bff92c5f26477346d81/pypdf-6.21.2.tar.gz", hash = "sha256:0a3e1c5c886a1be03646c16a04827cc166c2a0575c971b26a4bf89686551c2d4", size = 7144571, upload-time = "2026-10-21T16:44:55.272Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1b/4d/c9d2d67f204eff463237a1a8f5e25a6923b7b1043982b91fcaf104c8ef60/pypdf-6.21.2-py3-none-any.whl", hash = "sha256:1d44d1a3a200f25062adff0085b02040e4646431ac2ccac22e42679e91466084", size = 407766, upload-time = "2026-10-21T16:44:53.626Z" }, ] -[[package]] -name = "pytaglib" -version = "3.1.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/c3/47/8c191b92368d853a63ddda3fb13e4556458a0f22b7bbbbdbc91db59b7206/pytaglib-3.1.0.tar.gz", hash = "sha256:42447797fc7019d7f007ed4d6ef46650310e382a8920508d56262eb93e0e79d6", size = 511317, upload-time = "2025-11-19T08:05:17.645Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/98/5b15e2ab399f0b9c4c02ee0d7046154e6a22f988f3e609ffc32350512207/pytaglib-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:176f34fc49d526f41b2a0aec338d95769df944d7328902a1ee67a47f143aff0f", size = 800283, upload-time = "2025-11-19T08:04:32.066Z" }, - { url = "https://files.pythonhosted.org/packages/43/3c/f55465b4699f5351993757afdc275bc46eaadd9944745b842e701814f4f1/pytaglib-3.1.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad9f2aee7021f0ed915f5f0fdc08b25adfd451ea7e59338b1f7cad0e4aea2396", size = 1800317, upload-time = "2025-11-19T08:04:33.683Z" }, - { url = "https://files.pythonhosted.org/packages/6c/02/681a96d1e483dabf1906f66c4d24d59c9976f5e1ed45ffc064a396e193ee/pytaglib-3.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0a2527aca436bc31eb0c28b32e41310b67daac5467071680f2c80bfc8c563dd5", size = 2844506, upload-time = "2025-11-19T08:04:35.293Z" }, - { url = "https://files.pythonhosted.org/packages/a3/db/060450446a474ddddecc58634b162c704d3eef47b05673ac063a16cebb44/pytaglib-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:701653bbdea2a5bf4e8fe49ba4138477eee21a096a8adf49faa536faeff2d4de", size = 262284, upload-time = "2025-11-19T08:04:36.715Z" }, - { url = "https://files.pythonhosted.org/packages/60/d7/ff7596e919e36c1349b820becefbaafa94c6942491e02714930597390add/pytaglib-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:359f428c956d0c1585ceeaea464f8affb56f4fb142fce8a184a76b7fb6b03706", size = 741013, upload-time = "2025-11-19T08:04:37.704Z" }, - { url = "https://files.pythonhosted.org/packages/2f/32/b6bbd8a08cd38d64e8926e41743325af8c659693944898342ad0c9590097/pytaglib-3.1.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d84ed18e3c5ee136a0162cb89ea48575a9fd986b37ab42bb79e6fd0580d484a7", size = 1810673, upload-time = "2025-11-19T08:04:38.736Z" }, - { url = "https://files.pythonhosted.org/packages/f4/b2/a5cc5630b7f9a80622cef7aa48a606d8d0f92d455c988b53b67a5bc58e0d/pytaglib-3.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:12587361eeaa0a463d2d51951b997e035a39631f0536663c1124531618d0931e", size = 2857613, upload-time = "2025-11-19T08:04:39.94Z" }, - { url = "https://files.pythonhosted.org/packages/f1/85/b78035f6092c7d9aef0fcb13b8b288653388b4accd315ddb9cc0c66c21ba/pytaglib-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:4b8037e132d0b69a72559438dec8860e1e979b5703bdc4aae785427be4d1679f", size = 262430, upload-time = "2025-11-19T08:04:41.165Z" }, - { url = "https://files.pythonhosted.org/packages/ae/b4/0076810b778f98cbf57c9c2250d7f5ace67e2dda0178c7af2639767922bd/pytaglib-3.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:638a45a184d1ebdf92a4f9ec86dae5cde5188d45b1b7510fe5c2d426e6a3eae8", size = 800185, upload-time = "2025-11-19T08:04:42.157Z" }, - { url = "https://files.pythonhosted.org/packages/3f/14/dd3068d2e284601528ec37a62adceaaacb3e7a6c9ad38b986abbf94f6c9b/pytaglib-3.1.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ce55efefb208757d0cdc07664c21e732e7137fb42cf42bb5a763b47a4a413c0", size = 1823009, upload-time = "2025-11-19T08:04:43.228Z" }, - { url = "https://files.pythonhosted.org/packages/07/44/49bd29aab93b3b5c1797461640cef9a72165888d60ec20d136f06556b80c/pytaglib-3.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:706dd821a9b1605bad551de01a569e5536bd7016dc6e02b7f3d1481c2bc852ba", size = 2866705, upload-time = "2025-11-19T08:04:44.837Z" }, - { url = "https://files.pythonhosted.org/packages/4d/0f/dc833b1556e40fe9b6b05ec275519ed5e5470459a2271dbc6d2b73c5fe43/pytaglib-3.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d487b85805d34146acedf5cba85f4a021005ce8eeafeba3b78ba14a89ca6e44e", size = 263031, upload-time = "2025-11-19T08:04:45.939Z" }, - { url = "https://files.pythonhosted.org/packages/e9/db/833fbbb0c2f9d810ee2bd224b2cefe6a04700dc3d375a0649a30eb852b9a/pytaglib-3.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:066d5b4bec56af5421c5b8948104ee4889d040076a7dd3e50ecd7a4ef4c286a0", size = 799498, upload-time = "2025-11-19T08:04:47.316Z" }, - { url = "https://files.pythonhosted.org/packages/af/ec/34a6e1965bf1ffdb9600a5e0283c2ff6da351f923b506ce8dd52b34edb50/pytaglib-3.1.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:991162647e94c857ff18340e49b75100d52056aadd0cd3583c97da119404cc46", size = 1815486, upload-time = "2025-11-19T08:04:48.496Z" }, - { url = "https://files.pythonhosted.org/packages/70/c3/e540c6a6dbf61a1183edfa838f8068ee080b23aa8e7e597a526ece5b3650/pytaglib-3.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7e36de34055d27ab6295e1e18321e2c34cd0f110cc788da092da694c88c2f678", size = 2861253, upload-time = "2025-11-19T08:04:50.07Z" }, - { url = "https://files.pythonhosted.org/packages/6e/45/b9ffb54812b4017de0c627c29d26d7afdbe9327653da11c6883b7cdcb83e/pytaglib-3.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:fe16dd56b5bd7364481fa5b3b989af291f9f6519466843becef7c4649294d7cf", size = 262780, upload-time = "2025-11-19T08:04:51.197Z" }, - { url = "https://files.pythonhosted.org/packages/c0/78/9ba99907289f89bf01099f6e94014446872ba96728ddf1445522e5f34c74/pytaglib-3.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1f3503eef78034c0e9f630637c3f591b58390c41ac55e58a2e1688d8779d5bc7", size = 799897, upload-time = "2025-11-19T08:04:52.239Z" }, - { url = "https://files.pythonhosted.org/packages/8e/94/e687af0a228baf7108267a11e4d4cb0662c35fd72244ccb3fb88791ad0bf/pytaglib-3.1.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96c378342fc11976ade773e07d4054ed0e34b10968125a31338544bae799aad7", size = 1813402, upload-time = "2025-11-19T08:04:53.42Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2f/4b54fa9e8f0a49512cd4e830db96a2063d67979d03e662839306c9c3b9ff/pytaglib-3.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:202e16709d3c6f67d271c1138034a8d95716853252cc9222ac8b98b6f4e9d243", size = 2859615, upload-time = "2025-11-19T08:04:55.233Z" }, - { url = "https://files.pythonhosted.org/packages/6e/bd/e9849aa333654a3080262a2046e433d31c870ae0169aae1523a181d99c7e/pytaglib-3.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:f8a312de13b898e91f1a72c585eab996f2614e24352b6eca2807e07ac9811250", size = 271022, upload-time = "2025-11-19T08:04:56.736Z" }, - { url = "https://files.pythonhosted.org/packages/23/6c/bd6ce628c027997a6059ff45d01552c1776811282a8452f22281b354a6ad/pytaglib-3.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1878f4371427f2dc6fc849645bc316ecd3ab13f2aa9d3be2781ad0d57d313440", size = 802537, upload-time = "2025-11-19T08:04:57.687Z" }, - { url = "https://files.pythonhosted.org/packages/2b/ba/0127f98c7105d5e1290e8a25c9ab1a94fa66db88770216038bebb2cc9442/pytaglib-3.1.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7f261af6c47a8d923bec1329a04d64d94c79f23eb86f8f58eae0c132b311d192", size = 1866541, upload-time = "2025-11-19T08:05:00.671Z" }, - { url = "https://files.pythonhosted.org/packages/33/c6/7999c3f04c0c2147b207e7a962d851a770b96c8080a220915538f8c287c8/pytaglib-3.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d28566068a4ee39864e08da6f5b9717d9ee2fe084cd6a3ffa9dd165a99891da2", size = 2912249, upload-time = "2025-11-19T08:05:02.249Z" }, - { url = "https://files.pythonhosted.org/packages/d4/a0/150f2191b50a943445858219701c206a993896b6efadbd96aa2347ad2d45/pytaglib-3.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:157811dce2523e6f37c1dc3cc2c2606354ace44b90577d266451965ba8f16223", size = 276748, upload-time = "2025-11-19T08:05:04.85Z" }, - { url = "https://files.pythonhosted.org/packages/18/b3/23622caed022fec878ddd887a7c61d0ad64ec1a9c1961a50c818f61ae0c6/pytaglib-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:152a061ca9088825b6ac5ff66788b81c1bb20fac55908ca81b093a0c4e2e230b", size = 800581, upload-time = "2025-11-19T08:05:05.868Z" }, - { url = "https://files.pythonhosted.org/packages/39/5b/666896733205167494803a5526b5f36a96df6053e1fe211cd823d6dc1dd2/pytaglib-3.1.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40327186ee675bfde7a82d8c6b0b3a2163db45bdf2147410d13d9446b1f8dbc6", size = 1800485, upload-time = "2025-11-19T08:05:09.389Z" }, - { url = "https://files.pythonhosted.org/packages/40/6c/02ef464f4cd427707e11259cdd57669b9a364a1cf2685c6346b4051d1487/pytaglib-3.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5123b7e3ee2dd901da01443b53033f37671344a09e904589fea6c9451e326398", size = 2844429, upload-time = "2025-11-19T08:05:11.15Z" }, - { url = "https://files.pythonhosted.org/packages/61/c2/faff4f5bb022c203d205b92bccf94421cb564add6c4b8f8033c4aa7b2472/pytaglib-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:da00e730d6de490c3ed7549244f464e93a0cdfde17c70916f328440816715086", size = 262710, upload-time = "2025-11-19T08:05:12.282Z" }, - { url = "https://files.pythonhosted.org/packages/11/2e/db464ee3d4f57ae51cd34ddc411a89c932d814ffd436003df3a49a9bd87d/pytaglib-3.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:58b3adc0439f3e8e9411ef57b7bd96c8873042174494217717ebda166baf5ab1", size = 793806, upload-time = "2025-11-19T08:05:13.279Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e8/9d9065ffa13e9bdbd853d54584e526ebb109c98388a5baa439d17a274ff5/pytaglib-3.1.0-pp311-pypy311_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26e3b2b55224b3e630bba3aa6958740e6b5f9fe40c0052965a13fbe6a9015c32", size = 1348097, upload-time = "2025-11-19T08:05:15.15Z" }, - { url = "https://files.pythonhosted.org/packages/40/82/5d5476f9dfad232a7b5ad5872de134777bd271faab56ec6da0728f138c70/pytaglib-3.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4c2d79bb0cb03e538a2d904b71f3b1eb727ce34d606b8daea15faf71e1a74ac2", size = 259743, upload-time = "2025-11-19T08:05:16.644Z" }, -] - [[package]] name = "pytaglib" version = "3.2.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] sdist = { url = "https://files.pythonhosted.org/packages/c3/ff/4e81cc7aae32c85eaaad614defe6fa9d4da82ea9dc452db9001036acfa64/pytaglib-3.2.0.tar.gz", hash = "sha256:964e32e86edcda107eb3821dd4ca226de04f7f0f99bb4c18737e138b4ed3313f", size = 568593, upload-time = "2026-02-04T14:14:18.069Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/05/dbc7d00826b9f81663efda0d528e5888fcb1be05c471282b80f406b1ab11/pytaglib-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b6963b0d2b13472cb4dacf808dfc3bf230d2095a9255071ca08795e2fe6d4ffe", size = 765726, upload-time = "2026-02-04T14:13:34.561Z" }, - { url = "https://files.pythonhosted.org/packages/29/ae/258758464caf3fecc45987739a0af3f1b5b84b09b68c664427be98d5a266/pytaglib-3.2.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da54d6d6dcd729c244d0099b2b9f747d1af27b140b81e1c4535045e79ac28c8e", size = 2043765, upload-time = "2026-02-04T14:13:36.168Z" }, - { url = "https://files.pythonhosted.org/packages/84/f6/559fad5d14fa35a2f845868e668390cf16574873dc3dc7d80e4f6fec0c04/pytaglib-3.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:106d2c4ba3ea40f350fd349c66e71f02751391037e6e327498bae93e94c22646", size = 3084639, upload-time = "2026-02-04T14:13:38.453Z" }, - { url = "https://files.pythonhosted.org/packages/44/33/411e3d4663645b10509fd33995652f45666f93ec5ac4b01e0ddf61dd5184/pytaglib-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:934b42c3fed36943fdfbd3896f562fe5d019ed5a67546dbe63550fc249d14573", size = 280764, upload-time = "2026-02-04T14:13:40.064Z" }, { url = "https://files.pythonhosted.org/packages/14/79/3b0599ac49907522f1b4f83ddfd3238b3a46d87a309cb74fe95b99a1f316/pytaglib-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b1737ee5fa109634fdba6bdbe93f3aab999e44579f0c10b4d0af6062132e9f", size = 823360, upload-time = "2026-02-04T14:13:41.379Z" }, { url = "https://files.pythonhosted.org/packages/cd/71/4616eed72da73a83c356e3e074985062c37da5efe45240f300b459e9fd32/pytaglib-3.2.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3415cc1116399eac2c7c5a8817d5fbc5f5927fbb3438a954a14fd5359c209929", size = 2055246, upload-time = "2026-02-04T14:13:43.236Z" }, { url = "https://files.pythonhosted.org/packages/f2/8e/bad886628059b1c1baae87eda3df3f04c181e9f011be9116d825cbb5c807/pytaglib-3.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:973fa0d997e19de20fd154d0a4f595ac68241c6202a9dc25f23f601c4087a7dc", size = 3097109, upload-time = "2026-02-04T14:13:44.794Z" }, @@ -291,70 +168,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/e9/e826e2381536e5d8166f39bd7a63102f1411340889c86bed35e24655a69e/pytaglib-3.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a3a073bae8ce0d76f99f8f3fd91fe5d1fd355710721c3a3a135c29bebcc3df3f", size = 276240, upload-time = "2026-02-04T14:14:16.815Z" }, ] -[[package]] -name = "pytest" -version = "8.4.2" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup" }, - { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } }, - { name = "packaging" }, - { name = "pluggy", version = "1.6.0", source = { registry = "https://pypi.org/simple" } }, - { name = "pygments" }, - { name = "tomli" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, -] - [[package]] name = "pytest" version = "9.1.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "iniconfig", version = "2.3.1", source = { registry = "https://pypi.org/simple" } }, + { name = "iniconfig" }, { name = "packaging" }, - { name = "pluggy", version = "1.7.0", source = { registry = "https://pypi.org/simple" } }, + { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] -[[package]] -name = "python-frontmatter" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e9/21/88aefb4f1de6661b5a003175e21e4a5ad94f5e52b2abf4170a11883c7d81/python_frontmatter-1.2.0.tar.gz", hash = "sha256:5b26ccd3cb85af77feb11d83b922c7bb5aeccb0c9d3fb236b938c600b6322984", size = 16890, upload-time = "2026-05-17T23:42:05.493Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/b1/ec12e3e746234006b77dec69d53878253b1da09dbb55fa3cb456083d9069/python_frontmatter-1.2.0-py3-none-any.whl", hash = "sha256:e1ee1d4300450a2f84e778eb4f70edf573da6cd7d463801066f05edc4e819c78", size = 10396, upload-time = "2026-05-17T23:42:04.637Z" }, -] - [[package]] name = "python-frontmatter" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] dependencies = [ { name = "pyyaml" }, ] @@ -369,15 +202,6 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, - { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, - { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, - { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, - { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, - { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, @@ -425,15 +249,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, - { url = "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" }, - { url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" }, - { url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" }, - { url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" }, - { url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" }, - { url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" }, - { url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" }, - { url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" }, - { url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" }, ] [[package]] @@ -441,92 +256,10 @@ name = "rich" version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "markdown-it-py" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, ] - -[[package]] -name = "tomli" -version = "2.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/78/9ad63712633ed3ab5cc1a648d863d7e7da371e9425e209555a0fe711b695/tomli-2.5.0.tar.gz", hash = "sha256:264507556cd8b8c8e7c6ee037cdf443a463f03f4c958e57195e3d369711b8ff6", size = 17662, upload-time = "2026-10-07T12:23:37.892Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/ab99b60ee52acd949684febabc3005d0045d0f66bebd9cdebd67372d26dd/tomli-2.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c4dc1c1781f2f716de763d1e9a7b34c6a894e167e291c7c5d16c72f7a9538545", size = 163901, upload-time = "2026-10-07T12:22:15.601Z" }, - { url = "https://files.pythonhosted.org/packages/bc/00/ee01b7ed4579180fff07142d290257f25ba786f23f3ec6005f620933c2f5/tomli-2.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eff8babca5a7999bc137acbc7482a8b7e17ffca5075ab41f5d770ab408c7bfef", size = 163756, upload-time = "2026-10-07T12:22:16.957Z" }, - { url = "https://files.pythonhosted.org/packages/72/c2/4efebf65372f6583185f79799312109dddb61102d47e5c33dcfd1a297aca/tomli-2.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86665cee9c4835b7a7f1e8ec2c719b5258d4dc782887aded5a8ae7352a96843b", size = 268038, upload-time = "2026-10-07T12:22:18.135Z" }, - { url = "https://files.pythonhosted.org/packages/53/07/5850468e925d898abb36038666f9c333a94d2a223e802a8ba5b6d319d23f/tomli-2.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e369fd63331746182360977b1892bfc215476a30d61612d732425311639f56", size = 276422, upload-time = "2026-10-07T12:22:19.567Z" }, - { url = "https://files.pythonhosted.org/packages/b4/87/f293984cdcf83c054196d4fd3dad44fc68ae55b4b8c44bc76cef360c3150/tomli-2.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ad1ea345759240d6463efa0ed1c704402752e49aa21476620738d74d72d8aa1", size = 272616, upload-time = "2026-10-07T12:22:20.794Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ce/db582886b3c1219d3fec93ebd669332482e5aee7a91e0f7838d84f2d1759/tomli-2.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:96243987194634bd411066ce40c952e108f86af04db533ecd8ac3ff2a85b1885", size = 276593, upload-time = "2026-10-07T12:22:22.12Z" }, - { url = "https://files.pythonhosted.org/packages/bf/72/7619b87dea4261fc27dd7b54c4461c129c1f7d9bb7ba3aec89c797a431b8/tomli-2.5.0-cp311-cp311-win32.whl", hash = "sha256:610b27d99f28ec5f191c7064a48f3ddb179a1fe6ca73d571483ae859f57b605e", size = 101830, upload-time = "2026-10-07T12:22:23.651Z" }, - { url = "https://files.pythonhosted.org/packages/1e/74/220106da34502304b6751a2a9b8a9fbca6c3fd47e737a2e2e3da7c61c9db/tomli-2.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:c804ae44fe7b4bab5da295e4f980a1ff04670bca9d23fe0a4e887e08ebd741a8", size = 112742, upload-time = "2026-10-07T12:22:24.972Z" }, - { url = "https://files.pythonhosted.org/packages/27/99/7d9c8b41837a7773613e169504147375c157a290167aa59ad74a085f521f/tomli-2.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:cfac177ebd6236003846ea339981f71457cb6eb748f23381eb257e45092e3980", size = 109332, upload-time = "2026-10-07T12:22:26.117Z" }, - { url = "https://files.pythonhosted.org/packages/52/ed/7baa86f87493646a594de388c7c1c40a39dd0461f7e9c0359cbeefc91fe8/tomli-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f4a40d03fb9f63424f0979855bdeaf44dd7696b8d59501822c10ed30ba532df", size = 164854, upload-time = "2026-10-07T12:22:27.444Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b1/44c0341f2224397855723c7a8a39f718ea6fcbcc3dacc66e5aeca0f334e3/tomli-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9ebf8d19b17bd0daeb7b7dec81a946a439b753942fd0210d6e96c532249eea6b", size = 164074, upload-time = "2026-10-07T12:22:28.679Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e2d5b7d3fba47adedb23de616c16d428ea076c79a3d8e1d95d649ffe197e/tomli-2.5.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf0b5e8e0f68ebb494356e577c06c139161efd8d3b9050f93b39b7c26cc54ff0", size = 274274, upload-time = "2026-10-07T12:22:29.804Z" }, - { url = "https://files.pythonhosted.org/packages/43/90/6090e706ff27a6f89f4a40578e3324b95c3cd8c4150868aabf33a8f414c3/tomli-2.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cf74416bdc94ae458b14e37286c1073081850ac8459a00d0c5efef5d44294c6", size = 286435, upload-time = "2026-10-07T12:22:31.297Z" }, - { url = "https://files.pythonhosted.org/packages/0a/9e/a2c40768df16c408f22430afb0a73e9d7e5f79c950884954649d1146b74d/tomli-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:61ea1ebe1e55a34ea8199cc8dbff398d35027b82271c8ac4802fd3a1fd5b1bcc", size = 278119, upload-time = "2026-10-07T12:22:32.601Z" }, - { url = "https://files.pythonhosted.org/packages/12/25/3c0cb485b98e9cfac495629b1c93c87ccf0b72fbe9d2689fd8fe62c6d5a3/tomli-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed53f7e89bb04f6d9e8e7799112360b0c4d5cbff067de0814c98c37c39b920f7", size = 286177, upload-time = "2026-10-07T12:22:33.745Z" }, - { url = "https://files.pythonhosted.org/packages/77/8b/0144c65f0e37e51c18d04ae15c21b19431c165002d0131fe9aa8b0b8b1e8/tomli-2.5.0-cp312-cp312-win32.whl", hash = "sha256:e7ad033e27a516a233bea839cdb77b80146facb3b4f40bf02cd0cac165cdd5c2", size = 102760, upload-time = "2026-10-07T12:22:34.887Z" }, - { url = "https://files.pythonhosted.org/packages/de/32/5d6d8f42fc9a05fce69354e00ff256484192f5f2fc9a2165718fa0de61ec/tomli-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd05de8c1698f8413dd7d869492693a0bf2211543b787ac78cd5e7536af1a6d7", size = 112722, upload-time = "2026-10-07T12:22:36.162Z" }, - { url = "https://files.pythonhosted.org/packages/30/65/df18032218db0fb9b769fb23c8039a051f15c811993995ea04c350273a32/tomli-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:069435bd5480429b98c5e5afb02ab21c219b6f0064680671c6dc0d46817346ea", size = 109534, upload-time = "2026-10-07T12:22:37.296Z" }, - { url = "https://files.pythonhosted.org/packages/42/e5/51736d70da209350969e15aca5c5ab6e2ce1ea87a0a892a6c13aec172a86/tomli-2.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:943276cf269e0071948d9ff697159c1735e623c1151d88abb09b74659ef0cbea", size = 163328, upload-time = "2026-10-07T12:22:38.373Z" }, - { url = "https://files.pythonhosted.org/packages/ec/55/086f80dab4ab497602644274e6dea7ec5dd0b4e262e443a8ad3bb7edee2d/tomli-2.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:463b16086865b97facd8d0b3fb4cb7c544e3f58d2a69dc3113d6db9653fdb043", size = 162246, upload-time = "2026-10-07T12:22:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/aa/eb/3ecc94459f3635c92321f4e7bde571323fdb2267c50e19e3188a281eae3b/tomli-2.5.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1245a6638fc4bb0a60af38a7d45413db34a13842027c77597c712c998c62fdf0", size = 272655, upload-time = "2026-10-07T12:22:41.08Z" }, - { url = "https://files.pythonhosted.org/packages/c0/d7/494fd1f0c37a621f1ad9975c2efadb523e8101f144ed6edb2e7fe64738f2/tomli-2.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d8bac3d603c97e6854424e5b2b5b741bdbde387e09f162fb0446812b4a8362b", size = 283595, upload-time = "2026-10-07T12:22:42.222Z" }, - { url = "https://files.pythonhosted.org/packages/70/51/bb8d62b1317e6640866f6949b2d5855e5300f2c99d46de1cd245570bba65/tomli-2.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:21e4cae4114aba25aa0d4f85cdf486d290fb35c0954d7bba536248da64d43066", size = 276253, upload-time = "2026-10-07T12:22:43.625Z" }, - { url = "https://files.pythonhosted.org/packages/66/f4/f46bd7f0763cd47de2db697dca9257c6a4adfd1a93b018cc75c8190ed5a8/tomli-2.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bbaefc84548d754be821bba7c4141c4787dda182f9e77f2f87b71213529efa7b", size = 283582, upload-time = "2026-10-07T12:22:44.983Z" }, - { url = "https://files.pythonhosted.org/packages/ac/03/70f2bcb2923a6db37818d917e124270a7f4cfd38ea576f5aa753a91c0ef5/tomli-2.5.0-cp313-cp313-win32.whl", hash = "sha256:abdbf6313b8d9efe157edeb7ab6eae4de064b1300ad31abf73755154b30abe68", size = 102628, upload-time = "2026-10-07T12:22:46.508Z" }, - { url = "https://files.pythonhosted.org/packages/dc/98/d52024bb5b0ff68b4f0d276d867f634c84a67319a7e9f6b7708a37742333/tomli-2.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd4dc129784e0c5335bd4e61dfcc4487499a013419e655cf2da1d091b7e0efdc", size = 113301, upload-time = "2026-10-07T12:22:47.647Z" }, - { url = "https://files.pythonhosted.org/packages/6f/f2/540db3a70572a8c23a28aba3e9c358ce0ffffbafc990905c1343aa265b31/tomli-2.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:69491c143d2fe063046e0301e62a810bed338fa4d1ce0fd870c27dc1e09b0d84", size = 109744, upload-time = "2026-10-07T12:22:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/e4/49/caf6b307766eb9567664a8707e9d6be5fcc0e8903f18781c6677a60d80c7/tomli-2.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d3182ee2d887e507bd67319a0a61105d1dd33facc111329559a233b772c1a105", size = 162899, upload-time = "2026-10-07T12:22:50.088Z" }, - { url = "https://files.pythonhosted.org/packages/d3/c8/68cfce773a2733a49c74f99d627fb461bd990756860099eac25617889585/tomli-2.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:521345fd1f19d45b8df87657aaa38b6f2ca3800059fadf428e7ebf479a383646", size = 162080, upload-time = "2026-10-07T12:22:51.558Z" }, - { url = "https://files.pythonhosted.org/packages/7e/b2/e5bb8651fdad593f670501a7d718b1a7f73f064d44dea15e04c04dfef45d/tomli-2.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e95c7614e705bfe2b04b27aa124adec59752d15813df37e2156747cab3a006b", size = 273380, upload-time = "2026-10-07T12:22:52.918Z" }, - { url = "https://files.pythonhosted.org/packages/8d/d2/9e2d7f8b1dfe0e2b34c245986ebd55c4c553ea4ce6c47c443b332673253f/tomli-2.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ac2027d37c3afbdf4bdd377f2676f6f1d2122a5be1f1137b49dced590b37e75", size = 283228, upload-time = "2026-10-07T12:22:54.173Z" }, - { url = "https://files.pythonhosted.org/packages/ba/df/ec7b876b7b1a2718bd74a3743c076fff565b04029ba33e8f61fac262739f/tomli-2.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c414be4ed9d3cac80c42e348fa5a956117d1a48227f48026e31f59cb4a7671eb", size = 277189, upload-time = "2026-10-07T12:22:55.342Z" }, - { url = "https://files.pythonhosted.org/packages/7d/7b/e192d9eed0b9cb80da799f4d77052297fb9a2c3cc9b19f571f56ea88add6/tomli-2.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9b03d7dc168353b4132965bde20feceabaa470e570c6f59660dfae59b1f9eeb3", size = 283632, upload-time = "2026-10-07T12:22:56.735Z" }, - { url = "https://files.pythonhosted.org/packages/84/50/ff94454e75461d75623e47401ed323d65c10aab8fe9033242c20cd2fdf32/tomli-2.5.0-cp314-cp314-win32.whl", hash = "sha256:6f041843c4d3a37245c0c056fd955b186bf8b1fb85690cbe40b81230891dc34b", size = 103535, upload-time = "2026-10-07T12:22:58.084Z" }, - { url = "https://files.pythonhosted.org/packages/54/0b/bdacf05f963bd6026ebf6eeb0beda847d1d60e03e440725c64a4e08a0afd/tomli-2.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:f4b653094e18f9031102d3a1da5c729c8f222d85225b18037dac621695e46e1a", size = 114621, upload-time = "2026-10-07T12:22:59.2Z" }, - { url = "https://files.pythonhosted.org/packages/61/99/53f438fa6ae4f9d4ed0ddde3e7242b3bdc34b48c8f9948b72b9e9b127676/tomli-2.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:3f89d10c1ff6a38d992c27fc8a4816af71a909e08a40ec66934240b1e74347c3", size = 111572, upload-time = "2026-10-07T12:23:00.479Z" }, - { url = "https://files.pythonhosted.org/packages/b9/20/1f88f19427d380a40e90a770e087489eaafe4aeee070ae88ed2bbec00acd/tomli-2.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:e9e15b4a6c7dd6b85b5fbab29488a73f1f70de516942308daa266bf0e0aeb0d4", size = 171814, upload-time = "2026-10-07T12:23:01.914Z" }, - { url = "https://files.pythonhosted.org/packages/d0/56/cbe5079c9f9a54b9b3e27fc82f08f3cb36edee75561679f53d2380c801d6/tomli-2.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e12bbcd32897272fb05929110362ae9ff4c1b9bb26bd9e971e71dcd3275b4c3d", size = 171324, upload-time = "2026-10-07T12:23:03.18Z" }, - { url = "https://files.pythonhosted.org/packages/2b/30/1d53fd3b0f1cb3ba542e345ec32c26aefdddc4e829e4f3429af8a4f27782/tomli-2.5.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20aa36de8f2cf87237143bc1fa1aae8d6612c09118f4da21c6a684db5dd1f6f9", size = 297441, upload-time = "2026-10-07T12:23:04.345Z" }, - { url = "https://files.pythonhosted.org/packages/66/d9/0800acb6a111686f764c1b91ef15cc42a20a66a46013bb42220f1d2c61c1/tomli-2.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22185fad8a1e622f064e78008018a0dd3323550dcb479cb7a1d296888d74024f", size = 307476, upload-time = "2026-10-07T12:23:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/e8/63/30a8f3cd51b5bec37f04744bad0b0dc6160df84aad4f27b0e9283d66f221/tomli-2.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:984012f71908165449a951de2050d52f276bfe3aa5d5f570f63ddad814370374", size = 296113, upload-time = "2026-10-07T12:23:07.202Z" }, - { url = "https://files.pythonhosted.org/packages/ab/18/0b9ffc597e69c5a1e20a7823cb60d54b39a9f54e91edcb8574f022186758/tomli-2.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f79203b3965b4000e91808aaa7c040206093f2b8bf86f455982f2274c9ccf442", size = 307725, upload-time = "2026-10-07T12:23:08.508Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c7/18f8baae0b5607a60e8e19b4a7fedee43a8ff6458e3896dcbbadeeac9c22/tomli-2.5.0-cp314-cp314t-win32.whl", hash = "sha256:91294a9fb94a75542f6e46e4a2ae709bd8d9b51134098cae5cf3bea5478b6d03", size = 108546, upload-time = "2026-10-07T12:23:09.956Z" }, - { url = "https://files.pythonhosted.org/packages/72/34/4cca9739254130627bde87500b3f2b512154fe2f278efa7e2a5e10ad4bcb/tomli-2.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f15e3e0b835a6d68b10c86bf80a3149780498d6911c93c3ffd1861d19f9200f1", size = 117814, upload-time = "2026-10-07T12:23:11.486Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fb/afa530d47dd80a78fce43beac6bc6e00f84558eafcffbc6f37b21e80d056/tomli-2.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6664b7ae7af7294256c53960a6103077f4914cec8ff98479c352f622c6f6b2f0", size = 115188, upload-time = "2026-10-07T12:23:12.728Z" }, - { url = "https://files.pythonhosted.org/packages/66/98/316fdc00f8c0939e6fe50461dd343c162d3ad51d1286eb25b7db54361d50/tomli-2.5.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:a525685c2f97da40762b8695eb7aa0af4c8344ca1905c73e4e29cb04d34607dc", size = 162775, upload-time = "2026-10-07T12:23:13.941Z" }, - { url = "https://files.pythonhosted.org/packages/c5/22/7b10fa5bb01c9539f53f69b619361b19350acc73657772ea7ac70ba309a8/tomli-2.5.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:9dbb18c1cfb2f6517942fc9314437f66aa06d94436ffb1f06102ef3572f35276", size = 161406, upload-time = "2026-10-07T12:23:15.215Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e7/1a069d86dfd20f1f84f71c63faed9f83c1d890bc06c27d82dc7d888fb573/tomli-2.5.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:752e8b1aa6a4367ef8bf6a1a1e005540f7ed055ba36d7193796812ca5404eb52", size = 273855, upload-time = "2026-10-07T12:23:16.471Z" }, - { url = "https://files.pythonhosted.org/packages/ae/83/d1ef43d1687d092ab9c235455c76e6e709483b346b056f086095c7c263a5/tomli-2.5.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c47300f9bf791808f77d82747691c4bb09cb14bdf3060cca99b42cdc4361d5a7", size = 284910, upload-time = "2026-10-07T12:23:18.166Z" }, - { url = "https://files.pythonhosted.org/packages/cc/05/f4d9cf7de61822ece0c3873f30d291e324911c71a378b8bfe5ced13fd9f5/tomli-2.5.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:19b0dd8749f4ea2f112c5fcfb3c5248390c899d7e2e173f1d91abee1fa0ff391", size = 277723, upload-time = "2026-10-07T12:23:19.355Z" }, - { url = "https://files.pythonhosted.org/packages/42/28/78262493141fa543151cf005760c3cb01d09fc28a11f993c05109902cb8c/tomli-2.5.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:57b1c3b01fab802e2899bc3d168dca320e14165e2fd9fd584760fb4ca5826859", size = 285115, upload-time = "2026-10-07T12:23:20.698Z" }, - { url = "https://files.pythonhosted.org/packages/1a/b9/e1dab9a30bcb677b5cc5cee810609cfd64f24306a3055767dd3fda00b1e0/tomli-2.5.0-cp315-cp315-win32.whl", hash = "sha256:667e521b37a6c5ccaa044202c235b530f90177ffe2cd4a64ecc213c7dd535feb", size = 103475, upload-time = "2026-10-07T12:23:21.941Z" }, - { url = "https://files.pythonhosted.org/packages/4c/bd/31a3790c11d6ea95fcf5e6022ac0f8d0543c9b61120b730fc481bd43d3b4/tomli-2.5.0-cp315-cp315-win_amd64.whl", hash = "sha256:d747252933c8a65ef6bd8da0fbb7ce28a90eb6119d8cd00772cd528aa07b68d5", size = 114589, upload-time = "2026-10-07T12:23:23.098Z" }, - { url = "https://files.pythonhosted.org/packages/47/a2/4f6310fa699364f0e3af7ee3af88dddd9af066d33e716a0265bbe2b3ea84/tomli-2.5.0-cp315-cp315-win_arm64.whl", hash = "sha256:75dbcde8751b0a960aa3de173aa5e894d590755c6d7758b7e774c06f1dc3cbdd", size = 111493, upload-time = "2026-10-07T12:23:24.233Z" }, - { url = "https://files.pythonhosted.org/packages/68/14/00853f0b396d8971107ae1921bb5b322fdee1650d2f16bf06c20adb532e5/tomli-2.5.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:2419c2a189551987b59d80e63ec355671283336f41c6b9b89462df679c7d0c57", size = 171380, upload-time = "2026-10-07T12:23:25.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/ad/fa6949321dadee46b27363974fb197b94c911c3b0f7a5fd26d7dc18fc2a0/tomli-2.5.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:0dc598040da8d42cf20f0be588ed7004f46db12a0ac6c32e03a59dccedaaadcd", size = 170553, upload-time = "2026-10-07T12:23:26.855Z" }, - { url = "https://files.pythonhosted.org/packages/53/aa/3056c919eb3e084df3752b2cf5f865dcc04af0b27dba2f66d7b28af4633a/tomli-2.5.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49096930c8d886c9bbdab62d2d0d17ce823ddeea522309a190b36245d5b49e01", size = 294428, upload-time = "2026-10-07T12:23:28.132Z" }, - { url = "https://files.pythonhosted.org/packages/96/b2/faeeb5d8769ea3832021d73e892c8391eae7b4b4f8b55a789127bd8b18a9/tomli-2.5.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8ade5023067f99fe72b88accd30d0ea05a158e9e32a11f124e731ea9695313f", size = 304909, upload-time = "2026-10-07T12:23:29.381Z" }, - { url = "https://files.pythonhosted.org/packages/f6/52/f094c09e73fb654b621716d019acb5d29bdfd1be01df80c281d552bda48d/tomli-2.5.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b69564772b5c8f22ea5f498dff08cfa825045b4d4c4400529000bdf818aa3b2a", size = 293220, upload-time = "2026-10-07T12:23:30.608Z" }, - { url = "https://files.pythonhosted.org/packages/86/f5/0c30541078ca4b505ce3bd76ed931facbfec524dd018535d691d1af0a6d2/tomli-2.5.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:8ff3a2ca028c7eee0c777f9a092038d0a594a9fa04e215f929a22c329e2cb142", size = 305705, upload-time = "2026-10-07T12:23:32.181Z" }, - { url = "https://files.pythonhosted.org/packages/05/74/590e7d19d6a118fc5cc5704ff358e21d95b8573f6b9443b1519f29ca8825/tomli-2.5.0-cp315-cp315t-win32.whl", hash = "sha256:62fc1bc8eb03e3a9cadfca713d65614ed8e09d974a283295ffe3a831976b4dc5", size = 108432, upload-time = "2026-10-07T12:23:33.496Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b8/63a75cfb27a17c38550e44025d3a6e7be64516fd8608a3b75703bf37d81b/tomli-2.5.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f3fcbc57b1791fa6cbe5d8434179d51de12be1a4811469529f47f6e7487a2571", size = 117281, upload-time = "2026-10-07T12:23:34.648Z" }, - { url = "https://files.pythonhosted.org/packages/72/01/e8c1debb2173973372934c68fc8e46170ab60ef23ed4592dff4dec6e8993/tomli-2.5.0-cp315-cp315t-win_arm64.whl", hash = "sha256:d2ba24db8a9376921b5e87b4762b9adb0f3f1deaea68f2b8b0bb2c11efb9c3e7", size = 115069, upload-time = "2026-10-07T12:23:35.77Z" }, - { url = "https://files.pythonhosted.org/packages/60/3f/3e3f8fd0919249b0200c80fbc4f9a1e70be19f9883da71dfb7f8b9ab8aca/tomli-2.5.0-py3-none-any.whl", hash = "sha256:32a7b79ac57a2e83670ce329ccf675798bc5a2094783a63676866b70503f2e2b", size = 14765, upload-time = "2026-10-07T12:23:36.875Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, -]