From db47addc645a859938468e484fbdf0f9ecd539b6 Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 10:38:59 +0200 Subject: [PATCH 1/6] moved to uv with pyproject.toml, added pre-commit hooks, fixed documentation and lots of style issues --- .coveragerc | 10 - Changelog.md | 6 +- MANIFEST.in | 30 -- README.md | 22 +- appveyor.yml | 30 -- dev/generate_doc | 167 +++++++---- docs/conf.py | 36 ++- docs/index.rst | 5 +- examples/pya-example-Amfcc.ipynb | 99 +------ examples/pya-examples.ipynb | 357 ++++++++++++++---------- pya/__init__.py | 22 +- pya/amfcc.py | 129 ++++++--- pya/arecorder.py | 48 +++- pya/aserver.py | 99 ++++--- pya/asig.py | 427 ++++++++++++++++++----------- pya/aspec.py | 67 +++-- pya/astft.py | 168 ++++++++---- pya/backend/Dummy.py | 62 +++-- pya/backend/Jupyter.py | 57 ++-- pya/backend/PyAudio.py | 56 ++-- pya/backend/__init__.py | 16 +- pya/backend/base.py | 4 +- pya/helper/__init__.py | 5 +- pya/helper/backend.py | 35 ++- pya/helper/codec.py | 49 +++- pya/helper/helpers.py | 104 ++++--- pya/helper/visualization.py | 75 +++-- pya/ugen.py | 162 ++++++++--- requirements.txt | 4 - requirements_doc.txt | 4 - requirements_pyaudio.txt | 2 - requirements_remote.txt | 3 - requirements_test.txt | 3 - setup.cfg | 7 - setup.py | 52 ---- tests/test_amfcc.py | 22 +- tests/test_arecorder.py | 121 ++++---- tests/test_aserver.py | 21 +- tests/test_asig.py | 167 +++++++---- tests/test_aspec.py | 19 +- tests/test_astft.py | 19 +- tests/test_backend.py | 13 +- tests/test_class_transformation.py | 10 +- tests/test_codestyle.py | 21 -- tests/test_file_loader_codec.py | 10 +- tests/test_find_events.py | 18 +- tests/test_getitem.py | 38 ++- tests/test_helpers.py | 112 +++++--- tests/test_play.py | 44 +-- tests/test_routeNpan.py | 22 +- tests/test_setitem.py | 66 +++-- tests/test_ugen.py | 8 +- tests/test_visualization.py | 13 +- tox.ini | 77 ++++-- 54 files changed, 1937 insertions(+), 1306 deletions(-) delete mode 100644 .coveragerc delete mode 100644 MANIFEST.in delete mode 100644 appveyor.yml delete mode 100644 requirements.txt delete mode 100644 requirements_doc.txt delete mode 100644 requirements_pyaudio.txt delete mode 100644 requirements_remote.txt delete mode 100644 requirements_test.txt delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 tests/test_codestyle.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 872e8627..00000000 --- a/.coveragerc +++ /dev/null @@ -1,10 +0,0 @@ -[run] -source = pya - -[report] -exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - - # Don't complain if tests don't hit defensive assertion code: - raise NotImplementedError diff --git a/Changelog.md b/Changelog.md index dd49c6a7..17ddb126 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Changelog +## 0.6.0 +* changed project management and build system to use `uv`. Most of the configuration is now gathered in the `pyproject.toml`. +* added pre-commit hooks + + ## 0.5.2 (Nov 2023) * #82, `pyaudio` is now optional: If you plan to use `PyAudioBackend`, install `pya` with `pip install pya[pyaudio]`. * Fix audio device bug @@ -86,4 +91,3 @@ ## 0.2 (August 2019) * First official PyPI release - diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 740025af..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,30 +0,0 @@ -include *.md -include *.txt -include *.yml -include .coveragerc -include .pylintrc -include LICENSE -include MANIFEST -include tox.ini -include binder/environment.yml -include binder/postBuild -include dev/generate_doc - -recursive-include docs Makefile -recursive-include docs *.bat -recursive-include docs *.html -recursive-include docs *.py -recursive-include docs *.rst - -recursive-include examples *.aif -recursive-include examples *.ipynb -recursive-include examples *.mp3 -recursive-include examples *.py -recursive-include examples *.wav -recursive-exclude examples .ipynb_checkpoints/*.ipynb - -recursive-include tests *.py -recursive-include pya *.py -recursive-include dev *.md -recursive-include dev *.py -recursive-include ci *.yml diff --git a/README.md b/README.md index 2374d45d..5ce717c6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ [![PyPI](https://img.shields.io/pypi/v/pya.svg)](https://pypi.org/project/pya) -[![License](https://img.shields.io/github/license/interactive-sonification/pya.svg)](LICENSE) +[![License](https://img.shields.io/github/license/interactive-sonification/pya.svg)](../LICENSE) # pya -|Branch|`master`|`develop`| + + +|Branch|`main`|`develop`| |------:|--------:|---------:| -|[CI-Linux/MacOS](https://github.com/interactive-sonification/pya/actions/workflows/pya-ci.yaml) | [![Build Status Master](https://github.com/interactive-sonification/pya/actions/workflows/pya-ci.yaml/badge.svg?branch=master)](https://github.com/interactive-sonification/pya/actions/workflows/pya-ci.yaml?query=branch%3Amaster) | [![Build Status Develop](https://github.com/interactive-sonification/pya/actions/workflows/pya-ci.yaml/badge.svg?branch=develop)](https://github.com/interactive-sonification/pya/actions/workflows/pya-ci.yaml?query=branch%3Adevelop) | -|[CI-Windows](https://ci.appveyor.com/project/aleneum/pya-b7gkx/)| ![Build status AppVeyor](https://ci.appveyor.com/api/projects/status/vn61qeri0uyxeedv/branch/master?svg=true) | ![Build status AppVeyor](https://ci.appveyor.com/api/projects/status/vn61qeri0uyxeedv/branch/develop?svg=true) | |Changes|[![GitHub commits](https://img.shields.io/github/commits-since/interactive-sonification/pya/v0.5.0/master.svg)](https://github.com/interactive-sonification/pya/compare/v0.5.0...master) | [![GitHub commits](https://img.shields.io/github/commits-since/interactive-sonification/pya/v0.5.0/develop.svg)](https://github.com/interactive-sonification/pya/compare/v0.5.0...develop) | |Binder|[![Master Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/interactive-sonification/pya/master?filepath=examples%2Fpya-examples.ipynb) | [![Develop Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/interactive-sonification/pya/develop?filepath=examples%2Fpya-examples.ipynb) | @@ -40,9 +41,14 @@ At this time pya is more suitable for offline rendering than realtime. ## Authors and Contributors -* [Thomas](https://github.com/thomas-hermann) (author, maintainer) -* [Jiajun](https://github.com/wiccy46) (co-author, maintainer) -* [Alexander](https://github.com/aleneum) (maintainer) +* [Thomas Hermann](https://github.com/thomas-hermann) (author, maintainer) +* [Jiajun Yang](https://github.com/wiccy46) (co-author, maintainer) +* [Alexander Neumann](https://github.com/aleneum) (maintainer) + +* [Luka Born]() (Contributor) +* [Jannis Müller]() (Contributor) +* [Fabian Hommel]() (Maintainer) + * Contributors will be acknowledged here, contributions are welcome. ## Installation @@ -269,4 +275,4 @@ ch.setLevel(logging.INFO) formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) -``` \ No newline at end of file +``` diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index c6b94ef3..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,30 +0,0 @@ -# no dedicated build phase needed so far -build: false -version: "0.3.2-{build}" - -branches: - only: - - master - - develop - - dev-appveyor - -environment: - matrix: - - PYTHON_VERSION: 3.10 - MINICONDA: C:\Miniconda3-x64 - -init: - - "ECHO %PYTHON_VERSION% %MINICONDA%" - -install: - - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%MINICONDA%\\Library\\bin;%PATH%" - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda info -a - - conda config --append channels conda-forge - - "conda create -q -n test-environment python=%PYTHON_VERSION% ffmpeg coverage --file=requirements_remote.txt --file=requirements_test.txt" - - activate test-environment - - "pip install -r requirements.txt -r requirements_pyaudio.txt" - -test_script: - - pytest diff --git a/dev/generate_doc b/dev/generate_doc index 6ae18af4..07680d5c 100755 --- a/dev/generate_doc +++ b/dev/generate_doc @@ -1,12 +1,12 @@ #!/usr/bin/env python import argparse -import sys -import os -import subprocess +import os import shutil +import subprocess +import sys +from os.path import basename, dirname, exists from sys import platform -from os.path import exists, dirname, basename SILENCE = "> /dev/null 2>&1" @@ -14,19 +14,41 @@ SILENCE = "> /dev/null 2>&1" # you usually want to run: # python dev/generate_doc --doctree --publish --clean --no-show + def generate(): - git_root = subprocess.check_output(f'git -C {dirname(__file__)} rev-parse --show-toplevel'.split(' ')) - git_root = str(git_root, 'utf-8').strip() + git_root = subprocess.check_output( + f"git -C {dirname(__file__)} rev-parse --show-toplevel".split(" ") + ) + git_root = str(git_root, "utf-8").strip() parser = argparse.ArgumentParser(description="Generates Sphinx documentation") - parser.add_argument('--doctree', action='store_true', help='build complete doctree') - parser.add_argument('--publish', action='store_true', help='build and publish doctree') - parser.add_argument('--no-show', action='store_true', help='do not open browser after build') - parser.add_argument('--branches', nargs='*', default=['master', 'develop'], help='limit doctree to these branches') - parser.add_argument('--tags', nargs='*', default=False, help='limit doctree to these tags') - parser.add_argument('--input', default=f"{git_root}/docs", help='input folder (ignored for doctree)') - parser.add_argument('--out', default=f"{git_root}/build", help='output folder') - parser.add_argument('--template-folder', default=f"{git_root}/docs/_templates", help="templates used for doctree") - parser.add_argument('--clean', action='store_true', help="removes out folder before building doc") + parser.add_argument("--doctree", action="store_true", help="build complete doctree") + parser.add_argument( + "--publish", action="store_true", help="build and publish doctree" + ) + parser.add_argument( + "--no-show", action="store_true", help="do not open browser after build" + ) + parser.add_argument( + "--branches", + nargs="*", + default=["master", "develop"], + help="limit doctree to these branches", + ) + parser.add_argument( + "--tags", nargs="*", default=False, help="limit doctree to these tags" + ) + parser.add_argument( + "--input", default=f"{git_root}/docs", help="input folder (ignored for doctree)" + ) + parser.add_argument("--out", default=f"{git_root}/build", help="output folder") + parser.add_argument( + "--template-folder", + default=f"{git_root}/docs/_templates", + help="templates used for doctree", + ) + parser.add_argument( + "--clean", action="store_true", help="removes out folder before building doc" + ) args = parser.parse_args() args.doctree = args.doctree if not args.publish else True if args.clean and exists(args.out): @@ -35,39 +57,60 @@ def generate(): if not args.doctree: generate_local(doc=args.input, out=args.out, show=not args.no_show) else: - generate_tree(out_folder=args.out, publish=args.publish, branches=args.branches, - tags=args.tags, template_folder=args.template_folder, show=not args.no_show) - - -def generate_local(doc, out, show, target='html'): - os.system(f'sphinx-build -b {target} {doc} {out}/{target}') + generate_tree( + out_folder=args.out, + publish=args.publish, + branches=args.branches, + tags=args.tags, + template_folder=args.template_folder, + show=not args.no_show, + ) + + +def generate_local(doc, out, show, target="html"): + os.system(f"sphinx-build -b {target} {doc} {out}/{target}") if show: - url = f'{out}/{target}/index.{target}' - if platform == 'darwin': - os.system(f'open {url}') - elif platform == 'win32': + url = f"{out}/{target}/index.{target}" + if platform == "darwin": + os.system(f"open {url}") + elif platform == "win32": os.startfile(url) else: raise NotImplementedError("'show' is not available for your platform") -def generate_tree(out_folder, publish=False, branches=['master', 'develop'], tags=None, template_folder=None, show=False): +def generate_tree( + out_folder, + publish=False, + branches=["master", "develop"], + tags=None, + template_folder=None, + show=False, +): doctree_root = f"{out_folder}/doctree/pya" build_folder = f"{out_folder}/tmp" os.makedirs(build_folder, exist_ok=True) if not exists(doctree_root): - os.system(f'git clone https://github.com/interactive-sonification/pya.git {doctree_root}') + os.system( + f"git clone https://github.com/interactive-sonification/pya.git {doctree_root}" + ) else: # os.system(f'git -C {doctree_root} fetch --all') - os.system(f'git -C {doctree_root} pull --all') + os.system(f"git -C {doctree_root} pull --all") if tags is False: - out = subprocess.check_output(f"git -C {doctree_root} show-ref --tags -d".split(' ')) - tags = [str(line.split(b' ')[1].split(b'/')[2], 'utf-8') for line in out.split(b'\n')[::-1] if len(line)] + out = subprocess.check_output( + f"git -C {doctree_root} show-ref --tags -d".split(" ") + ) + tags = [ + str(line.split(b" ")[1].split(b"/")[2], "utf-8") + for line in out.split(b"\n")[::-1] + if len(line) + ] # first, check which documentation to generate branches = [b for b in branches if _has_docs(b, doctree_root)] - tags = [t for t in tags if _has_docs('tags/' + t, doctree_root)] + tags = [t for t in tags if _has_docs("tags/" + t, doctree_root)] print(f"Will generate documentation for:\nBranches: {branches}\nTags: {tags}") # fix order of dropdown elements (most recent tag first, then branches and older tags) @@ -76,28 +119,37 @@ def generate_tree(out_folder, publish=False, branches=['master', 'develop'], tag # generate documentation; all versions have to be known for the dropdown menu for d in doclist: print(f"Generating documentation for {d} ...") - target = d if d in branches else 'tags/' + d - res = os.system(f'git -C {doctree_root} checkout {target} -f' + SILENCE) + target = d if d in branches else "tags/" + d + res = os.system(f"git -C {doctree_root} checkout {target} -f" + SILENCE) if res != 0: - raise RuntimeError(f'Could not checkout {d}. Git returned status code {res}!') - os.system(f'cp {template_folder}/../conf.py {doctree_root}/docs/') + raise RuntimeError( + f"Could not checkout {d}. Git returned status code {res}!" + ) + os.system(f"cp {template_folder}/../conf.py {doctree_root}/docs/") if template_folder: - os.system(f'cp {template_folder}/* {doctree_root}/docs/_templates') + os.system(f"cp {template_folder}/* {doctree_root}/docs/_templates") # override index and config for versions older than 0.5.0 - if d[0] == 'v' and d[1] == '0' and int(d[3]) < 5: - os.system(f'cp {template_folder}/../conf.py {template_folder}/../index.rst {doctree_root}/docs') + if d[0] == "v" and d[1] == "0" and int(d[3]) < 5: + os.system( + f"cp {template_folder}/../conf.py {template_folder}/../index.rst {doctree_root}/docs" + ) # PYTHONDONTWRITEBYTECODE=1 prevents __pycache__ files which we don't need when code runs only once. - call = f'PYTHONDONTWRITEBYTECODE=1 sphinx-build -b html -D version={d} -A versions={",".join(doclist)} {doctree_root}/docs {build_folder}/{d}' + SILENCE + call = ( + f"PYTHONDONTWRITEBYTECODE=1 sphinx-build -b html -D version={d} -A versions={','.join(doclist)} {doctree_root}/docs {build_folder}/{d}" + + SILENCE + ) print(call) res = os.system(call) if res != 0: - raise RuntimeError(f'Could not generate documentation for {d}. Sphinx returned status code {res}!') + raise RuntimeError( + f"Could not generate documentation for {d}. Sphinx returned status code {res}!" + ) # create index html to forward to last tagged version if doclist: - with open(f'{build_folder}/index.html', 'w') as fp: + with open(f"{build_folder}/index.html", "w") as fp: fp.write(f""" @@ -108,48 +160,53 @@ def generate_tree(out_folder, publish=False, branches=['master', 'develop'], tag # prepare gh-pages print("Merging documentation...") - os.system(f'git -C {doctree_root} checkout gh-pages -f' + SILENCE) - os.system(f'cp -r {build_folder}/* {doctree_root}') + os.system(f"git -C {doctree_root} checkout gh-pages -f" + SILENCE) + os.system(f"cp -r {build_folder}/* {doctree_root}") print("Current differences in 'gh-branch':") - os.system(f'git -C {doctree_root} status') + os.system(f"git -C {doctree_root} status") print(f"Documentation tree has been written to {doctree_root}") # commit and push changes when publish has been passed if publish: - os.system(f'git -C {doctree_root} add -A') + os.system(f"git -C {doctree_root} add -A") os.system(f'git -C {doctree_root} commit -a -m "update doctree"') - os.system(f'git -C {doctree_root} push') + os.system(f"git -C {doctree_root} push") if show: _run_webserver(doctree_root) + def _has_docs(name, doctree_root): - os.system(f'git -C {doctree_root} checkout {name}' + SILENCE) - return exists(f'{doctree_root}/docs') + os.system(f"git -C {doctree_root} checkout {name}" + SILENCE) + return exists(f"{doctree_root}/docs") + def _run_webserver(root): - import threading - import time import http.server import socketserver + import threading + import time def _delayed_open(): - url = f'http://localhost:8181/{basename(root)}/index.html' + url = f"http://localhost:8181/{basename(root)}/index.html" time.sleep(0.2) - if sys.platform == 'darwin': - os.system(f'open {url}') - elif sys.platform == 'win32': + if sys.platform == "darwin": + os.system(f"open {url}") + elif sys.platform == "win32": os.startfile(url) else: raise NotImplementedError("'show' is not available for your platform") t = threading.Thread(target=_delayed_open) t.start() + class Handler(http.server.SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): - super().__init__(*args, directory=root + '/../', **kwargs) + super().__init__(*args, directory=root + "/../", **kwargs) + def log_message(self, format, *args): pass + socketserver.TCPServer.allow_reuse_address = True with socketserver.TCPServer(("", 8181), Handler) as httpd: try: diff --git a/docs/conf.py b/docs/conf.py index b760e30b..d9a8f9f6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,17 +30,31 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.napoleon', - 'sphinx_mdinclude', - 'autoapi.extension'] +extensions = [ + 'sphinx.ext.napoleon', + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'myst_parser', +] + +# Napoleon settings +napoleon_numpy_docstring = True +napoleon_google_docstring = False + +# Autodoc settings +autodoc_default_options = { + 'members': True, + 'undoc-members': True, + 'show-inheritance': True, +} source_suffix = ['.rst', '.md'] -autoapi_type = 'python' -autoapi_dirs = ['../pya'] -autoapi_ignore = ['*/version.py'] -autoapi_add_toctree_entry = False + autosectionlabel_prefix_document = True +# Autosummary settings +autosummary_generate = True # auto-generates stub RST files + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -61,11 +75,3 @@ # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = [] - - -def setup(app): - config = { - # 'url_resolver': lambda url: github_doc_root + url, - 'auto_toc_tree_section': 'Contents', - 'enable_eval_rst': True, - } diff --git a/docs/index.rst b/docs/index.rst index e56f79ce..1b7ac1af 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,12 +1,13 @@ .. toctree:: :maxdepth: 2 -.. mdinclude:: ../README.md + readme + api Indices and tables ================== -* :doc:`API Reference ` +* :doc:`API Reference ` * :ref:`genindex` * :ref:`modindex` * :ref:`search` diff --git a/examples/pya-example-Amfcc.ipynb b/examples/pya-example-Amfcc.ipynb index b71d0dd3..e511040f 100644 --- a/examples/pya-example-Amfcc.ipynb +++ b/examples/pya-example-Amfcc.ipynb @@ -11,95 +11,44 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This part only makes sure that the repository version of pya is used for this notebook ...\n", - "import os, sys, inspect, io\n", + "import inspect\n", + "import os\n", + "import sys\n", "\n", "cmd_folder = os.path.realpath(\n", " os.path.dirname(\n", - " os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0])))\n", + " os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0])\n", + " )\n", + ")\n", "\n", "if cmd_folder not in sys.path:\n", " sys.path.insert(0, cmd_folder)\n", "\n", "# ... the part relevant for pya usage starts here\n", - "from pya import Asig, Amfcc" + "from pya import Asig" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Asig('word'): 1 x 87040 @ 44100Hz = 1.974s cn=['0']" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Load a sample audio\n", - "aword = Asig(\"samples/sonification.wav\", label='word')\n", + "aword = Asig(\"samples/sonification.wav\", label=\"word\")\n", "aword.plot()" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ -9.17548107 -15.13285146 5.73257773 ... -3.2166908 -10.76164443\n", - " 1.32956441]\n", - " [ -9.14692637 -16.17379626 5.54862945 ... -7.32108897 -11.65220551\n", - " -0.88169502]\n", - " [ -9.18433397 -13.87876107 6.81787026 ... 2.94985548 -14.60185015\n", - " -4.87923131]\n", - " ...\n", - " [ -9.07456594 -15.13518397 11.04234605 ... -1.4942507 -5.81623361\n", - " -1.79442066]\n", - " [ -9.03225387 -13.53938344 11.99418285 ... 4.10384531 1.00526457\n", - " 1.34213652]\n", - " [ -9.28960578 -14.93989893 8.99820526 ... -1.09119139 -10.48636787\n", - " 3.15961457]]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "amfcc = aword.to_mfcc()\n", "amfcc.plot()\n", @@ -162,29 +111,11 @@ " An array of mel filters\n", " cepstra : numpy.ndarray\n", " An array of the MFCC coeffcient, size: nframes x ncep\n", - "\"\"\"\n" + "\"\"\"" ] } ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.7" - } - }, + "metadata": {}, "nbformat": 4, "nbformat_minor": 4 } diff --git a/examples/pya-examples.ipynb b/examples/pya-examples.ipynb index 08df7a9d..04639bfe 100644 --- a/examples/pya-examples.ipynb +++ b/examples/pya-examples.ipynb @@ -15,7 +15,8 @@ "outputs": [], "source": [ "# This part only makes sure that the repository version of pya is used for this notebook ...\n", - "import os, sys, inspect, io\n", + "import os\n", + "import sys\n", "\n", "cmd_folder = os.path.abspath(sys.path[0] + \"/../\")\n", "\n", @@ -23,8 +24,9 @@ " sys.path.insert(0, cmd_folder)\n", "\n", "# ... the part relevant for pya usage starts here\n", - "from pya import *\n", - "from pyamapping import dbamp, ampdb" + "from pyamapping import ampdb\n", + "\n", + "from pya import *" ] }, { @@ -64,7 +66,7 @@ "metadata": {}, "outputs": [], "source": [ - "# To check all available devices \n", + "# To check all available devices\n", "device_info();" ] }, @@ -76,14 +78,16 @@ "source": [ "# header - imports\n", "import time\n", + "\n", + "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import scipy\n", - "import matplotlib.pyplot as plt\n", - "from ipywidgets import interact, fixed, widgets\n", + "from ipywidgets import interact\n", + "\n", "# plot graphs right into the notebook\n", "%matplotlib inline \n", "# for dedicated GUI windows with Qt5, uncomment the following line:\n", - "# %matplotlib qt5 " + "# %matplotlib qt5" ] }, { @@ -205,7 +209,7 @@ "metadata": {}, "outputs": [], "source": [ - "asnap = Asig(\"samples/snap.wav\", label='snap')\n", + "asnap = Asig(\"samples/snap.wav\", label=\"snap\")\n", "asnap" ] }, @@ -231,7 +235,7 @@ "metadata": {}, "outputs": [], "source": [ - "aping = Asig(\"samples/ping.mp3\", label='ping')\n", + "aping = Asig(\"samples/ping.mp3\", label=\"ping\")\n", "aping" ] }, @@ -251,7 +255,7 @@ "outputs": [], "source": [ "# load a speech sample\n", - "aword = Asig(\"samples/sonification.wav\", label='word')\n", + "aword = Asig(\"samples/sonification.wav\", label=\"word\")\n", "aword" ] }, @@ -271,7 +275,7 @@ "outputs": [], "source": [ "# create a signal from data\n", - "anoise = Asig(np.random.randn(44100), sr=44100, label='noise')\n", + "anoise = Asig(np.random.randn(44100), sr=44100, label=\"noise\")\n", "anoise" ] }, @@ -281,8 +285,8 @@ "metadata": {}, "outputs": [], "source": [ - "# record() helper function is currently removed until future release. \n", - "# Use Arecorder() for recording. \n", + "# record() helper function is currently removed until future release.\n", + "# Use Arecorder() for recording.\n", "# # record an audio signal, follow with a normalization\n", "# arec = Asig(record(2.0), label='rec').norm()" ] @@ -294,7 +298,7 @@ "outputs": [], "source": [ "# create 2s silence at default sr\n", - "Asig(2.0, label='sonification')" + "Asig(2.0, label=\"sonification\")" ] }, { @@ -303,8 +307,10 @@ "metadata": {}, "outputs": [], "source": [ - "# create a 44100 x 4 signal at 22050 sr, give the channel names cn \n", - "asignal = Asig(44100, sr=44100//2, label='silence', channels=4, cn=['a', 'b', 'c', 'd'])" + "# create a 44100 x 4 signal at 22050 sr, give the channel names cn\n", + "asignal = Asig(\n", + " 44100, sr=44100 // 2, label=\"silence\", channels=4, cn=[\"a\", \"b\", \"c\", \"d\"]\n", + ")" ] }, { @@ -320,7 +326,7 @@ "metadata": {}, "outputs": [], "source": [ - "asignal.sig # signal array " + "asignal.sig # signal array" ] }, { @@ -329,7 +335,7 @@ "metadata": {}, "outputs": [], "source": [ - "asignal.samples # nr of samples on each channels" + "asignal.samples # nr of samples on each channels" ] }, { @@ -347,7 +353,7 @@ "metadata": {}, "outputs": [], "source": [ - "asignal.sr # sampling rate" + "asignal.sr # sampling rate" ] }, { @@ -356,7 +362,7 @@ "metadata": {}, "outputs": [], "source": [ - "asignal.label # asig label " + "asignal.label # asig label" ] }, { @@ -365,7 +371,7 @@ "metadata": {}, "outputs": [], "source": [ - "asignal.cn # channel name list" + "asignal.cn # channel name list" ] }, { @@ -489,11 +495,11 @@ "source": [ "print(\"Length in second: \", asnap.get_duration(), aword.get_duration())\n", "try:\n", - " (asnap + aword).play() \n", + " (asnap + aword).play()\n", "except ValueError:\n", " print(\"asnap and aword are different in size\")\n", "\n", - "(asnap.x + aword).play() # same as (asnap.extend + aword).play() \n" + "(asnap.x + aword).play() # same as (asnap.extend + aword).play()" ] }, { @@ -525,10 +531,9 @@ "metadata": {}, "outputs": [], "source": [ - "import time\n", "t0 = time.time()\n", - "asnap.play(onset=t0+0.75)\n", - "aword.play(onset=t0+0.1)" + "asnap.play(onset=t0 + 0.75)\n", + "aword.play(onset=t0 + 0.1)" ] }, { @@ -562,7 +567,7 @@ "metadata": {}, "outputs": [], "source": [ - "aword.plot(lambda x: ampdb(abs(x)+0.01), lw=0.5, color=\"r\") # try also with arg 'db'" + "aword.plot(lambda x: ampdb(abs(x) + 0.01), lw=0.5, color=\"r\") # try also with arg 'db'" ] }, { @@ -571,8 +576,8 @@ "metadata": {}, "outputs": [], "source": [ - "aword.plot(lambda x: ampdb(abs(x)*1e2+1), lw=0.15)\n", - "aword.plot(lambda x: 100*abs(x)**2, color='red', lw=0.25)" + "aword.plot(lambda x: ampdb(abs(x) * 1e2 + 1), lw=0.15)\n", + "aword.plot(lambda x: 100 * abs(x) ** 2, color=\"red\", lw=0.25)" ] }, { @@ -599,7 +604,7 @@ "metadata": {}, "outputs": [], "source": [ - "aword.play(1.)" + "aword.play(1.0)" ] }, { @@ -609,8 +614,10 @@ "outputs": [], "source": [ "# demonstrate plot() and play() daisy-chained and subsequent access to the _ dict\n", - "asnap.plot(marker='o', mfc='r', ms=7, lw=0.1).play(server=s)._['plot'][0].set_markevery((700, 200))\n", - "plt.xlim(0, 0.2);\n", + "asnap.plot(marker=\"o\", mfc=\"r\", ms=7, lw=0.1).play(server=s)._[\"plot\"][0].set_markevery(\n", + " (700, 200)\n", + ")\n", + "plt.xlim(0, 0.2)\n", "asnap._" ] }, @@ -639,7 +646,9 @@ "outputs": [], "source": [ "b = Ugen().sine(freq=100, sr=1000, dur=0.6).fade_in(0.3).fade_out(0.2)\n", - "b *= 0.5+0.2*np.sin(2*np.pi*15*b.get_times()) # AM, note that you can directly apply arithemetics to Asig rather than Asig.sig\n", + "b *= 0.5 + 0.2 * np.sin(\n", + " 2 * np.pi * 15 * b.get_times()\n", + ") # AM, note that you can directly apply arithemetics to Asig rather than Asig.sig\n", "b.plot().norm().play()\n", "# note that repeated cell executions changes signal more and more" ] @@ -677,7 +686,9 @@ "source": [ "def test_stride(stride=2):\n", " aword[0:40000:stride].play()\n", - "interact(test_stride, stride=(1,20,1));" + "\n", + "\n", + "interact(test_stride, stride=(1, 20, 1));" ] }, { @@ -706,10 +717,10 @@ "outputs": [], "source": [ "# create a 4-channel sine\n", - "amultichan = Ugen().sine(freq=200, sr=2000, channels=4, cn=['a','b','c','d']) \n", + "amultichan = Ugen().sine(freq=200, sr=2000, channels=4, cn=[\"a\", \"b\", \"c\", \"d\"])\n", "\n", "# create a 1-channel sawtooth\n", - "amono = Ugen().sawtooth(freq=40, sr=2000, channels=1) " + "amono = Ugen().sawtooth(freq=40, sr=2000, channels=1)" ] }, { @@ -719,8 +730,8 @@ "outputs": [], "source": [ "# use index list to create a subset of samples\n", - "amono[[3, 30, 300]].sig \n", - "amultichan[[3, 30, 300], :].sig " + "amono[[3, 30, 300]].sig\n", + "amultichan[[3, 30, 300], :].sig" ] }, { @@ -730,8 +741,8 @@ "outputs": [], "source": [ "# channel selection based on channel name cn, using a list\n", - "amultichan[:, ['a']]\n", - "amultichan[:, ['a', 'd']]" + "amultichan[:, [\"a\"]]\n", + "amultichan[:, [\"a\", \"d\"]]" ] }, { @@ -750,8 +761,10 @@ "outputs": [], "source": [ "# You can use a dictionary for time slicing. {start:end}\n", - "amultichan[{0.2:0.6}] # from 0.2 to 0.6 second\n", - "amono[{0.2:-0.4}] # This results the same as above, start at 0.2, end at 0.4 to the end. " + "amultichan[{0.2: 0.6}] # from 0.2 to 0.6 second\n", + "amono[\n", + " {0.2: -0.4}\n", + "] # This results the same as above, start at 0.2, end at 0.4 to the end." ] }, { @@ -760,7 +773,7 @@ "metadata": {}, "outputs": [], "source": [ - "amultichan[0:amultichan.samples:4, ['a', 'c']] # a rough down-sampling" + "amultichan[0 : amultichan.samples : 4, [\"a\", \"c\"]] # a rough down-sampling" ] }, { @@ -793,8 +806,10 @@ "metadata": {}, "outputs": [], "source": [ - "# create some test signals \n", - "amultichan = Ugen().sine(freq=200, sr=2000, channels=4, cn=['a','b','c','d']) # create a 4-channel sine\n", + "# create some test signals\n", + "amultichan = Ugen().sine(\n", + " freq=200, sr=2000, channels=4, cn=[\"a\", \"b\", \"c\", \"d\"]\n", + ") # create a 4-channel sine\n", "amono = Ugen().sawtooth(freq=40, sr=2000, channels=1) # create a 1-channel sawtooth\n", "anoise = Ugen().noise(sr=2000, channels=1) # create a 1-channel white noise" ] @@ -813,8 +828,10 @@ "outputs": [], "source": [ "amono[3:6] = [1.0, -1.0, 0.5] # set three samples explicitly with values\n", - "amono[20:40] = np.zeros(20) # set 20 samples to zero\n", - "amono[{0.5: 0.7}] = anoise[{0.2: 0.4}] # set a 200ms-segment to noise, requiring length match" + "amono[20:40] = np.zeros(20) # set 20 samples to zero\n", + "amono[{0.5: 0.7}] = anoise[\n", + " {0.2: 0.4}\n", + "] # set a 200ms-segment to noise, requiring length match" ] }, { @@ -841,7 +858,7 @@ "try:\n", " amono[-10:] = np.ones(20) # This won't not work and raise the exception\n", "except ValueError:\n", - " amono.b[-10:] = np.arange(20) # The first 10 elements will be assigned. \n", + " amono.b[-10:] = np.arange(20) # The first 10 elements will be assigned.\n", "amono[-10:].sig" ] }, @@ -866,11 +883,13 @@ "metadata": {}, "outputs": [], "source": [ - "a = Asig(0.8, sr=1000, channels=4, cn=['a', 'b', 'c', 'd'], label='x-demosig')\n", + "a = Asig(0.8, sr=1000, channels=4, cn=[\"a\", \"b\", \"c\", \"d\"], label=\"x-demosig\")\n", "b = Ugen().sine(freq=100, sr=1000, dur=0.6).fade_in(0.3).fade_out(0.2)\n", - "a.x[:, 'a'] = 0.2 * b # no need to extend as len(src) 0: nframes, ncoeff = np.shape(cepstra) n = np.arange(ncoeff) - lift = 1 + (L / 2.) * np.sin(np.pi * n / L) + lift = 1 + (L / 2.0) * np.sin(np.pi * n / L) return lift * cepstra else: # values of L <= 0, do nothing return cepstra - def plot(self, show_bar: bool = True, offset: int = 0, scale: float = 1., - xlim: Optional[float] = None, ylim: Optional[float] = None, - x_as_time: bool = True, nxlabel: int = 8, ax=None, **kwargs): + def plot( + self, + show_bar: bool = True, + offset: int = 0, + scale: float = 1.0, + xlim: Optional[float] = None, + ylim: Optional[float] = None, + x_as_time: bool = True, + nxlabel: int = 8, + ax=None, + **kwargs, + ): """Plot Amfcc.features via matshow, x is frames/time, y is the MFCCs Parameters @@ -332,7 +359,8 @@ def plot(self, show_bar: bool = True, offset: int = 0, scale: float = 1., show_bar : bool, optional Default is True, show colorbar. offset: int - It is the spacing between channel, without setting it every channel will be overlayed onto each other. + It is the spacing between channel, + without setting it every channel will be overlayed onto each other. scale: float Visual scaling for improve visibility xlim: float, optional @@ -343,21 +371,32 @@ def plot(self, show_bar: bool = True, offset: int = 0, scale: float = 1., The amountt of labels on the x axis. Default is 8 . """ if self.channels > 1: - warn("Multichannel mfcc is not yet implemented. Please use " - "mono signal for now, no plot is made") + warn( + "Multichannel mfcc is not yet implemented. Please use " + "mono signal for now, no plot is made" + ) return self - im, ax = basicplot(self.cepstra.T, None, - channels=self.channels, - cn=self.cn, offset=offset, scale=scale, - ax=ax, typ='mfcc', show_bar=show_bar, - xlabel='time', xlim=xlim, ylim=ylim, **kwargs) + im, ax = basicplot( + self.cepstra.T, + None, + channels=self.channels, + cn=self.cn, + offset=offset, + scale=scale, + ax=ax, + typ="mfcc", + show_bar=show_bar, + xlabel="time", + xlim=xlim, + ylim=ylim, + **kwargs, + ) self.im = im xticks = np.linspace(0, self.nframes, nxlabel, dtype=int) ax.set_xticks(xticks) # ax.set_("MFCC Coefficient") if x_as_time: - xlabels = np.round(np.linspace(0, self.duration, nxlabel), - decimals=2) + xlabels = np.round(np.linspace(0, self.duration, nxlabel), decimals=2) # Replace x ticks with timestamps ax.set_xticklabels(xlabels) ax.xaxis.tick_bottom() diff --git a/pya/arecorder.py b/pya/arecorder.py index 5676d44f..c0f9c8f1 100644 --- a/pya/arecorder.py +++ b/pya/arecorder.py @@ -5,10 +5,10 @@ from typing import Optional, Union import numpy as np -from . import Asig -from . import Aserver from pyamapping import db_to_amp +from pya.aserver import Aserver +from pya.asig import Asig _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) @@ -35,16 +35,26 @@ class Arecorder(Aserver): ... ar.stop() """ - def __init__(self, sr: int = 44100, bs: int = 256, device: Optional[int] = None, - channels: Optional[int] = None, backend=None, **kwargs): - super().__init__(sr=sr, bs=bs, device=device, - backend=backend, **kwargs) + def __init__( + self, + sr: int = 44100, + bs: int = 256, + device: Optional[int] = None, + channels: Optional[int] = None, + backend=None, + **kwargs, + ): + super().__init__(sr=sr, bs=bs, device=device, backend=backend, **kwargs) self.record_buffer = [] self.recordings = [] # store recorded Asigs, time stamp in label self._recording = False self._record_all = True self.tracks = slice(None) - self._device = self.backend.get_default_input_device_info()['index'] if device is None else device + self._device = ( + self.backend.get_default_input_device_info()["index"] + if device is None + else device + ) self._channels = channels or self.max_in_chn self.gains = np.ones(self._channels) @@ -61,7 +71,9 @@ def channels(self, val: int): raise ValueError(f"AServer: channels {val} > max {self.max_in_chn}") self._channels = val - def set_tracks(self, tracks: Union[list, np.ndarray], gains: Union[list, np.ndarray]): + def set_tracks( + self, tracks: Union[list, np.ndarray], gains: Union[list, np.ndarray] + ): """Define the number of track to be recorded and their gains. parameters @@ -94,20 +106,28 @@ def boot(self): # self.block_cnt = 0 self.record_buffer = [] self._recording = False - self.stream = self.backend.open(rate=self.sr, channels=self.channels, frames_per_buffer=self.bs, - input_device_index=self.device, output_flag=False, - input_flag=True, stream_callback=self._recorder_callback) + self.stream = self.backend.open( + rate=self.sr, + channels=self.channels, + frames_per_buffer=self.bs, + input_device_index=self.device, + output_flag=False, + input_flag=True, + stream_callback=self._recorder_callback, + ) _LOGGER.info("Server Booted") return self def _recorder_callback(self, in_data, frame_count, time_info, flag): - """Callback function during streaming. """ + """Callback function during streaming.""" # self.block_cnt += 1 if self._recording: sigar = np.frombuffer(in_data, dtype=self.backend.dtype) # (chunk length, chns) data_float = np.reshape(sigar, (len(sigar) // self.channels, self.channels)) - data_float = data_float[:, self.tracks] * self.gains # apply channel selection and gains. + data_float = ( + data_float[:, self.tracks] * self.gains + ) # apply channel selection and gains. # if not self._record_all self.record_buffer.append(data_float) # E = 10 * np.log10(np.mean(data_float ** 2)) # energy in dB @@ -137,6 +157,6 @@ def __repr__(self): if self.stream: state = self.stream.is_active() msg = f"""Arecorder: sr: {self.sr}, blocksize: {self.bs}, Stream Active: {state} - Input: {self.device_dict['name']}, Index: {self.device_dict['index']} + Input: {self.device_dict["name"]}, Index: {self.device_dict["index"]} """ return msg diff --git a/pya/aserver.py b/pya/aserver.py index 223d944b..ffc5b5c5 100644 --- a/pya/aserver.py +++ b/pya/aserver.py @@ -1,4 +1,3 @@ -from .helper.backend import determine_backend import copy import logging import time @@ -7,13 +6,15 @@ import numpy as np +from .helper.backend import determine_backend _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) class Aserver: - """Pya audio server + """ + Pya audio server Based on pyaudio, works as a FIFO style audio stream pipeline, allowing Asig.play() to send audio segement into the stream. @@ -27,7 +28,8 @@ class Aserver: >>> asine = Ugen().sine() >>> asine.play(server=ser) Asig('sine'): 1 x 44100 @ 44100Hz = 1.000s cn=['0'] - >>> ser.quit() # Important to call quit() to close the stream when you are done. Or use context manager. + >>> ser.quit() # Important to call quit() to close the stream when you are done. + Or use context manager. """ default = None # that's the default Aserver if Asigs play via it @@ -52,9 +54,15 @@ def shutdown_default_server(): else: warn("Aserver:shutdown_default_server: no default_server to shutdown") - def __init__(self, sr: int = 44100, bs: Optional[int] = None, - device: Optional[int] = None, channels: Optional[int] = None, - backend=None, **kwargs): + def __init__( + self, + sr: int = 44100, + bs: Optional[int] = None, + device: Optional[int] = None, + channels: Optional[int] = None, + backend=None, + **kwargs, + ): """Aserver manages an pyaudio stream, using its aserver callback to feed dispatched signals to output at the right time. @@ -65,7 +73,7 @@ def __init__(self, sr: int = 44100, bs: Optional[int] = None, bs : int Override block size or buffer size set by chosen backend device : int - The device index based on pya.device_info(), default is None which will set + The device index based on pya.device_info(), default is None which will set the default device from PyAudio channels : int number of channel, default is the max output channels of the device @@ -85,12 +93,16 @@ def __init__(self, sr: int = 44100, bs: Optional[int] = None, self.input_devices = [] self.output_devices = [] for i in range(self.backend.get_device_count()): - if int(self.backend.get_device_info_by_index(i)['maxInputChannels']) > 0: + if int(self.backend.get_device_info_by_index(i)["maxInputChannels"]) > 0: self.input_devices.append(self.backend.get_device_info_by_index(i)) - if int(self.backend.get_device_info_by_index(i)['maxOutputChannels']) > 0: + if int(self.backend.get_device_info_by_index(i)["maxOutputChannels"]) > 0: self.output_devices.append(self.backend.get_device_info_by_index(i)) - self._device = self.backend.get_default_output_device_info()['index'] if device is None else device + self._device = ( + self.backend.get_default_output_device_info()["index"] + if device is None + else device + ) self._channels = channels or self.max_out_chn self.gain = 1.0 @@ -125,11 +137,11 @@ def device_dict(self): @property def max_out_chn(self) -> int: - return int(self.device_dict['maxOutputChannels']) + return int(self.device_dict["maxOutputChannels"]) @property def max_in_chn(self) -> int: - return int(self.device_dict['maxInputChannels']) + return int(self.device_dict["maxInputChannels"]) @property def is_active(self) -> bool: @@ -141,30 +153,47 @@ def device(self): @device.setter def device(self, val): - self._device = val if val is not None else self.backend.get_default_output_device_info()['index'] + self._device = ( + val + if val is not None + else self.backend.get_default_output_device_info()["index"] + ) if self.max_out_chn < self.channels: - warn(f"Aserver: warning: {self.channels}>{self.max_out_chn} channels requested - truncated.") + warn( + f"Aserver: warning: {self.channels}>{self.max_out_chn} channels requested - truncated." # noqa E501 + ) self.channels = self.max_out_chn def __repr__(self): msg = f"""AServer: sr: {self.sr}, blocksize: {self.bs}, - Stream Active: {self.is_active}, Device: {self.device_dict['name']}, Index: {self.device_dict['index']}""" + Stream Active: {self.is_active}, Device: {self.device_dict["name"]}, + Index: {self.device_dict["index"]} + """ return msg def get_devices(self, verbose: bool = False): """Return (and optionally print) available input and output device""" if verbose: print("Input Devices: ") - [print(f"Index: {i['index']}, Name: {i['name']}, Channels: {i['maxInputChannels']}") - for i in self.input_devices] + [ + print( + f"Index: {i['index']}, Name: {i['name']}, Channels: {i['maxInputChannels']}" # noqa E501 + ) + for i in self.input_devices + ] print("Output Devices: ") - [print(f"Index: {i['index']}, Name: {i['name']}, Channels: {i['maxOutputChannels']}") - for i in self.output_devices] + [ + print( + f"Index: {i['index']}, Name: {i['name']}, Channels: {i['maxOutputChannels']}" # noqa E501 + ) + for i in self.output_devices + ] return self.input_devices, self.output_devices def set_device(self, idx: int, reboot: bool = True): - """Set audio device, an alternative way is to direct set the device property, i.e. Aserver.device = 1, - but that will not reboot the server. + """ + Set audio device, an alternative way is to direct set the device property, + i.e. Aserver.device = 1, but that will not reboot the server. Parameters ---------- @@ -192,11 +221,15 @@ def boot(self): self.boot_time = time.time() self.block_time = self.boot_time self.block_cnt = 0 - self.stream = self.backend.open(channels=self.channels, rate=self.sr, - input_flag=False, output_flag=True, - frames_per_buffer=self.bs, - output_device_index=self.device, - stream_callback=self._play_callback) + self.stream = self.backend.open( + channels=self.channels, + rate=self.sr, + input_flag=False, + output_flag=True, + frames_per_buffer=self.bs, + output_device_index=self.device, + stream_callback=self._play_callback, + ) self._is_active = self.stream.is_active() _LOGGER.info("Server Booted") return self @@ -242,7 +275,9 @@ def play(self, asig, onset: Union[int, float] = 0, out: int = 0, **kwargs): asig = copy.copy(asig) asig.sig = asig.sig.astype(self.backend.dtype) # copy only relevant channels... - nchn = min(asig.channels, self.channels - out) # max number of copyable channels + nchn = min( + asig.channels, self.channels - out + ) # max number of copyable channels # in: [:nchn] out: [out:out+nchn] if id(asig) == sigid: asig = copy.copy(asig) @@ -254,7 +289,7 @@ def play(self, asig, onset: Union[int, float] = 0, out: int = 0, **kwargs): self.srv_asigs.insert(idx, asig) self.srv_curpos.insert(idx, 0) self.srv_outs.insert(idx, out) - if 'block' in kwargs and kwargs['block']: + if "block" in kwargs and kwargs["block"]: if onset > 0: # here really omset and not rt_onset! _LOGGER.warning("blocking inactive with play(onset>0)") else: @@ -294,11 +329,11 @@ def _play_callback(self, in_data, frame_count, time_info, flag): io0 = int((t - tnow) * self.sr) else: io0 = 0 - tmpsig = a.sig[c:c + self.bs - io0] + tmpsig = a.sig[c : c + self.bs - io0] n, nch = tmpsig.shape out = self.srv_outs[i] # .reshape(n, nch) not needed as moved to play - data[io0:io0 + n, out:out + nch] += tmpsig + data[io0 : io0 + n, out : out + nch] += tmpsig self.srv_curpos[i] += n if self.srv_curpos[i] >= a.samples: dellist.append(i) # store for deletion @@ -324,9 +359,9 @@ def __exit__(self, exc_type, exc_value, traceback): def __del__(self): """Backup cleanup, only if context manager wasn't used""" - if hasattr(self, 'stream') and self.stream is not None: + if hasattr(self, "stream") and self.stream is not None: try: self.quit() self.backend.terminate() - except: + except Exception: pass # Ignore cleanup errors during shutdown diff --git a/pya/asig.py b/pya/asig.py index 820267fc..05ede9e6 100644 --- a/pya/asig.py +++ b/pya/asig.py @@ -1,28 +1,25 @@ -from itertools import compress -import numbers import logging -from typing import Iterable -from typing import Optional -from typing import Union +import numbers +from itertools import compress +from typing import Iterable, Optional, Union from warnings import warn -import numpy as np import matplotlib.pyplot as plt +import numpy as np import scipy.interpolate import scipy.signal -from scipy.io import wavfile - from pyamapping import amp_to_db, db_to_amp, linlin -from .helper import spectrum, audio_from_file, padding -from .helper import basicplot +from scipy.io import wavfile +from .helper import audio_from_file, basicplot, padding, spectrum _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) class Asig: - """Audio signal class. + """ + Audio signal class. Asig enables manipulation of audio signals in the style of numpy and more. Asig offer functions for plotting (via matplotlib) and playing audio (using the pya.Aserver class) @@ -54,20 +51,29 @@ class Asig: the .bound, .extend and .overwrite properties. """ - def __init__(self, sig: Union[str, int, float, np.ndarray], sr: int = 44100, - label: str = "", channels: int = 1, cn: Optional[list] = None): - """__init__ method + def __init__( + self, + sig: Union[str, int, float, np.ndarray], + sr: int = 44100, + label: str = "", + channels: int = 1, + cn: Optional[list] = None, + ): + """ + Constructor method Parameters ---------- sig: numpy.array or int or float or str - This is a multiple type argument, which all results in Asig.sig being a numpy.array to + This is a multiple type argument, + which all results in Asig.sig being a numpy.array to represent the audio signal. numpy.array for audio signal, str for filepath. Currently support two types of audio loader: - 1) Standard library for .wav, .aiff, and 2) ffmpeg for other such as .mp3. + 1) Standard library for .wav, .aiff + 2) ffmpeg for other such as .mp3. int create x samples of silence, @@ -104,8 +110,7 @@ def __init__(self, sig: Union[str, int, float, np.ndarray], sr: int = 44100, if channels == 1: self.sig = np.zeros(int(sig * sr)).astype(self.dtype) else: - self.sig = np.zeros( - (int(sig * sr), channels)).astype(self.dtype) + self.sig = np.zeros((int(sig * sr), channels)).astype(self.dtype) else: self.sig = np.array(sig).astype(self.dtype) self.cn = cn @@ -140,12 +145,10 @@ def cn(self, val): if all(isinstance(x, str) for x in val): self._cn = val else: - raise TypeError( - "channel names cn need to be a list of string(s).") + raise TypeError("channel names cn need to be a list of string(s).") else: raise ValueError( - "list size doesn't match channel numbers {}".format( - self.channels) + "list size doesn't match channel numbers {}".format(self.channels) ) @property @@ -163,7 +166,8 @@ def dur(self) -> float: return self.samples / self.sr def save_wavfile(self, fname: str = "asig.wav", dtype: str = "float32"): - """Save signal as .wav file, return self. + """ + Save signal as .wav file, return self. Parameters ---------- @@ -193,7 +197,8 @@ def _set_col_names(self): raise TypeError("column names need to be a list of strings") def __getitem__(self, index): - """ Accessing array elements through slicing. + """ + Accessing array elements through slicing. * int, get signal row asig[4]; * slice, range and step slicing asig[4:40:2] # from 4 to 40 every 2 samples; @@ -260,8 +265,7 @@ def __getitem__(self, index): stop = None ridx = slice(start, stop, 1) sr = self.sr - _LOGGER.debug("Time slicing, start: %s, stop: %s", - str(start), str(stop)) + _LOGGER.debug("Time slicing, start: %s, stop: %s", str(start), str(stop)) else: # Dont think there is a usecase. ridx = rindex sr = self.sr @@ -273,8 +277,7 @@ def __getitem__(self, index): cidx = [self.col_name.get(s) for s in cindex] if cidx is None: _LOGGER.error("Input column names does not exist") - cn_new = [self.cn[i] - for i in cidx] if self.cn is not None else None + cn_new = [self.cn[i] for i in cidx] if self.cn is not None else None elif isinstance(cindex[0], bool): cidx = cindex cn_new = list(compress(self.cn, cindex)) @@ -282,8 +285,7 @@ def __getitem__(self, index): try: cidx = list(cindex) cn_new = ( - [self.cn[i] - for i in cindex] if self.cn is not None else None + [self.cn[i] for i in cindex] if self.cn is not None else None ) except (TypeError, ValueError): cidx = slice(0, 0, 0) @@ -314,8 +316,7 @@ def __getitem__(self, index): if sig.ndim == 2 and sig.shape[1] == 1: # Hot fix this to be consistent with bool slciing if not isinstance(cindex[0], bool): - _LOGGER.debug( - "ndim is 2 and channel num is 1, performa np.squeeze") + _LOGGER.debug("ndim is 2 and channel num is 1, performa np.squeeze") sig = np.squeeze(sig) if isinstance(sig, numbers.Number): _LOGGER.debug("signal is scalar, convert to array") @@ -327,8 +328,10 @@ def __getitem__(self, index): @property def x(self): - """Extend mode: this mode allows destination - sig size in assignment to be extended through setitem""" + """ + Extend mode: this mode allows destination + sig size in assignment to be extended through setitem + """ # Set setitem mode to extend self.mix_mode = "extend" return self @@ -337,8 +340,10 @@ def x(self): @property def b(self): - """Bound mode: this mode allows to truncate a source signal - in assignment to a limited destination in setitem.""" + """ + Bound mode: this mode allows to truncate a source signal + in assignment to a limited destination in setitem. + """ # Set setitem mode to bound self.mix_mode = "bound" return self @@ -347,15 +352,18 @@ def b(self): @property def o(self): - """Overwrite mode: this mode cuts and replaces target - selection by source signal on assignment via setitem""" + """ + Overwrite mode: this mode cuts and replaces target + selection by source signal on assignment via setitem + """ self.mix_mode = "overwrite" return self overwrite = o def __setitem__(self, index, value): - """setitem: asig[index] = value. This allows all the methods from getitem: + """ + setitem: asig[index] = value. This allows all the methods from getitem: * numpy style slicing * string/string_list for subsetting based on channel name * time slicing (unit seconds) via dict. @@ -496,24 +504,18 @@ def __setitem__(self, index, value): dn = dshape[0] # ToDo: howto get that faster from ridx alone? sn = src.shape[0] if sn > dn: - self.sig[final_index] = src[:dn] if len( - dshape) == 1 else src[:dn, :] + self.sig[final_index] = src[:dn] if len(dshape) == 1 else src[:dn, :] else: - self.sig[final_index][:sn] = src if len( - dshape) == 1 else src[:, :] + self.sig[final_index][:sn] = src if len(dshape) == 1 else src[:, :] elif mode == "extend": _LOGGER.debug("setitem extend mode") if isinstance(ridx, list): - _LOGGER.error( - "Extend mode not available for row index list" - ) + _LOGGER.error("Extend mode not available for row index list") return self if isinstance(ridx, slice): if ridx.step not in [1, None]: - raise AttributeError( - "Extend mode only available for step-1 slices" - ) + raise AttributeError("Extend mode only available for step-1 slices") if ridx.stop is not None and ridx.stop < self.samples: raise AttributeError( "The current slice does not stop at the end of array." @@ -523,8 +525,7 @@ def __setitem__(self, index, value): dn = dshape[0] sn = src.shape[0] if sn <= dn: # same as bound, since src fits in - self.sig[final_index][:sn] = np.broadcast_to( - src, (sn,) + dshape[1:]) + self.sig[final_index][:sn] = np.broadcast_to(src, (sn,) + dshape[1:]) elif sn > dn: self.sig[final_index] = src[:dn] # now extend by nn = sn-dn additional rows @@ -542,8 +543,7 @@ def __setitem__(self, index, value): nn = ridx.start + sn self.sig = np.r_[ self.sig, - np.zeros( - (nn - self.sig.shape[0],) + self.sig.shape[1:]), + np.zeros((nn - self.sig.shape[0],) + self.sig.shape[1:]), ].astype(self.dtype) if self.sig.ndim == 1: self.sig[-sn:] = src @@ -581,8 +581,9 @@ def __setitem__(self, index, value): self.sig = sig # Update self.sig return self - def resample(self, target_sr: int = 44100, rate: float = 1., kind: str = "linear"): - """Resample signal based on interpolation, can process multichannel signals. + def resample(self, target_sr: int = 44100, rate: float = 1.0, kind: str = "linear"): + """ + Resample signal based on interpolation, can process multichannel signals. Parameters ---------- @@ -599,8 +600,11 @@ def resample(self, target_sr: int = 44100, rate: float = 1., kind: str = "linear Asig with resampled signal. """ times = np.arange(self.samples) / self.sr - tsel = (np.arange(np.floor(self.samples / self.sr * - target_sr / rate)) * rate / target_sr) + tsel = ( + np.arange(np.floor(self.samples / self.sr * target_sr / rate)) + * rate + / target_sr + ) if self.channels == 1: interp_fn = scipy.interpolate.interp1d( times, @@ -611,12 +615,12 @@ def resample(self, target_sr: int = 44100, rate: float = 1., kind: str = "linear fill_value=self.sig[-1], ) return Asig( - interp_fn(tsel), target_sr, - label=self.label + "_resampled", cn=self.cn + interp_fn(tsel), target_sr, label=self.label + "_resampled", cn=self.cn ) else: new_sig = np.ndarray( - shape=(int(self.samples / self.sr * target_sr / rate), self.channels)) + shape=(int(self.samples / self.sr * target_sr / rate), self.channels) + ) for i in range(self.channels): interp_fn = scipy.interpolate.interp1d( times, @@ -629,8 +633,9 @@ def resample(self, target_sr: int = 44100, rate: float = 1., kind: str = "linear new_sig[:, i] = interp_fn(tsel) return Asig(new_sig, target_sr, label=self.label + "_resampled", cn=self.cn) - def play(self, rate: float = 1., server=None, onset=0, channel=0, block=False): - """Play Asig audio via Aserver, using Aserver.default (if existing) + def play(self, rate: float = 1.0, server=None, onset=0, channel=0, block=False): + """ + Play Asig audio via Aserver, using Aserver.default (if existing) kwargs are propagated to Aserver:play(onset=0, out=0) Parameters @@ -639,7 +644,8 @@ def play(self, rate: float = 1., server=None, onset=0, channel=0, block=False): Playback rate (Default value = 1) **kwargs : str 'server' : Aserver - Set which server to play. e.g. s = Aserver(); s.boot(); asig.play(server=s) + Set which server to play. + e.g. s = Aserver(); s.boot(); asig.play(server=s) Returns ------- @@ -647,6 +653,7 @@ def play(self, rate: float = 1., server=None, onset=0, channel=0, block=False): return self """ import pya.aserver + if server is None: server = pya.aserver.Aserver.default if rate == 1 and self.sr == server.sr: @@ -657,10 +664,15 @@ def play(self, rate: float = 1., server=None, onset=0, channel=0, block=False): return self def shift_channel(self, shift: int = 0): - """Shift signal to other channels. This is particular useful for assigning a mono signal to a specific channel. - * shift = 0: does nothing as the same signal is being routed to the same position - * shift > 0: shift channels of self.sig 'right', i.e. from [0,..channels-1] to channels [shift,shift+1,...] - * shift < 0: shift channels of self.sig 'left', i.e. the first shift channels will be discarded. + """ + Shift signal to other channels. + This is particular useful for assigning a mono signal to a specific channel. + * shift = 0: does nothing as the same signal + is being routed to the same position + * shift > 0: shift channels of self.sig 'right', + i.e. from [0,..channels-1] to channels [shift,shift+1,...] + * shift < 0: shift channels of self.sig 'left', + i.e. the first shift channels will be discarded. Parameters ---------- @@ -682,7 +694,7 @@ def shift_channel(self, shift: int = 0): if self.channels == 1: new_sig[:, shift] = self.sig elif shift > 0: - new_sig[:, shift: (shift + self.channels)] = self.sig + new_sig[:, shift : (shift + self.channels)] = self.sig elif shift < 0: new_sig[:] = self.sig[:, -shift:] if self.cn is None: @@ -699,7 +711,8 @@ def shift_channel(self, shift: int = 0): return Asig(new_sig, self.sr, label=self.label + "_routed", cn=new_cn) def mono(self, blend: Optional[list] = None): - """Mix channels to mono signal. Perform sig = np.sum(self.sig_copy * blend, axis=1) + """ + Mix channels to mono signal. Perform sig = np.sum(self.sig_copy * blend, axis=1) Parameters ---------- @@ -722,26 +735,37 @@ def mono(self, blend: Optional[list] = None): raise AttributeError("len(blend) != self.channels") else: sig = np.sum(self.sig * blend, axis=1) - col_names = [ - self.cn[np.argmax(blend)]] if self.cn is not None else None + col_names = [self.cn[np.argmax(blend)]] if self.cn is not None else None return Asig(sig, self.sr, label=self.label + "_blended", cn=col_names) def stereo(self, blend: Optional[list] = None): - """Blend all channels of the signal to stereo. Applicable for any single-/ or multi-channel Asig. + """ + Blend all channels of the signal to stereo. + Applicable for any single-/ or multi-channel Asig. Parameters ---------- blend : list or None - Usage: For mono, blend=(g1, g2), the channel will be broadcated to left, right with g1, g2 gains. + Usage: For mono, blend=(g1, g2), + the channel will be broadcated to left, right with g1, g2 gains. + For stereo signal, blend=(g1, g2), each channel is gain adjusted by g1, g2. - For multichannel: blend = [[list of gains for left channel], [list of gains for right channel]] - Default value = None, resulting in equal distribution to left and right channel + + For multichannel: + blend = [ + [list of gains for left channel], + [list of gains for right channel] + ] + + Default value = None, + resulting in equal distribution to left and right channel Example ------- asig[:,['c1','c2','c3']].stereo[[1, 0.707, 0], [0, 0.707, 1]] mixes channel 'c1' to left, 'c2' to center and 'c3' to right channel - of a new stereo asig. Note that for equal loudness left**2+right**2=1 should be used + of a new stereo asig. + Note that for equal loudness left**2+right**2=1 should be used Returns ------- @@ -766,9 +790,10 @@ def stereo(self, blend: Optional[list] = None): left_sig = np.sum(self.sig * left, axis=1) right_sig = np.sum(self.sig * right, axis=1) else: - msg = """For signal channels > 2, argument blend should be a tuple of two lists, - each list contains the gain for each channel to be mixed. - """ + msg = """ + For signal channels > 2, argument blend should be a tuple of two lists, + each list contains the gain for each channel to be mixed. + """ raise AttributeError(msg) sig = np.stack((left_sig, right_sig), axis=1) @@ -785,7 +810,8 @@ def rewire(self, dic): Example ------- - {(0, 1): 0.2, (5, 0): 0.4}: rewire channel 0 to 1 with gain 0.2, and 5 to 1 with gain 2 + {(0, 1): 0.2, (5, 0): 0.4}: + rewire channel 0 to 1 with gain 0.2, and 5 to 1 with gain 2 leaving other channels unmodified Returns @@ -808,7 +834,8 @@ def pan2(self, pan: float = 0.0): Panning is based on constant power panning, see pan below Behavior depends on nr of channels self.channels * multi-channel signals (self.channels>2) are cut back to stereo and treated as - * stereo signals (self.channels==2) are channelwise attenuated using cos(angle), sin(angle) + * stereo signals (self.channels==2) + are channelwise attenuated using cos(angle), sin(angle) * mono signals (self.channels==1) result in stereo output asigs. Parameters @@ -865,7 +892,7 @@ def remove_DC(self): sig = self.sig - np.mean(self.sig, 0) return Asig(sig, sr=self.sr, label=self.label + "_DCfree", cn=self.cn) - def norm(self, norm: float = 1., in_db: bool = False, dcflag: bool = False): + def norm(self, norm: float = 1.0, in_db: bool = False, dcflag: bool = False): # ToDO add channel_wise argument . default True, currently it is the false. """Normalize signal @@ -894,8 +921,11 @@ def norm(self, norm: float = 1., in_db: bool = False, dcflag: bool = False): return Asig(sig, self.sr, label=self.label + "_normalised", cn=self.cn) def gain(self, amp: Optional[float] = None, db: Optional[numbers.Number] = None): - """Apply gain in amplitude or dB, only use one or the other arguments. Argument can be either a scalar - or a list (to apply individual gain to each channel). The method returns a new asig with gain applied. + """ + Apply gain in amplitude or dB, only use one or the other arguments. + Argument can be either a scalar or a list + (to apply individual gain to each channel). + The method returns a new asig with gain applied. Parameters ---------- @@ -964,7 +994,7 @@ def plot( if fn == "db": def fn(x): - return np.sign(x) * amp_to_db((abs(x) * 2 ** 16 + 1)) + return np.sign(x) * amp_to_db((abs(x) * 2**16 + 1)) elif not callable(fn): msg = "Asig.plot: fn is neither keyword nor function" @@ -1002,7 +1032,10 @@ def get_times(self): return np.linspace(0, (self.samples - 1) / self.sr, self.samples) def __eq__(self, other): - """Check if two asig objects have the same signal. But does not care about sr and others""" + """ + Check if two asig objects have the same signal. + But does not care about sr and others + """ sig_eq = np.array_equal(self.sig, other.sig) sr_eq = self.sr == other.sr return sig_eq and sr_eq @@ -1019,10 +1052,14 @@ def __repr__(self): ) def __mul__(self, other): - """Magic method for multiplying. You can either multiply a scalar or an Asig object. If muliplying an Asig, - you don't always need to have same size arrays as audio signals may different in length. If mix_mode - is set to 'bound' the size is fixed to respect self. If not, the result will respect to whichever the - bigger array is.""" + """ + Magic method for multiplying. + You can either multiply a scalar or an Asig object. + If muliplying an Asig, you don't always need to have same size arrays + as audio signals may different in length. If mix_mode is set to 'bound' the size + is fixed to respect self. If not, the result will respect to whichever the + bigger array is. + """ selfsig = self.sig othersig = other.sig if isinstance(other, Asig) else other if isinstance(othersig, numbers.Number): @@ -1060,13 +1097,16 @@ def __rmul__(self, other): ) def __truediv__(self, other): - """Magic method for division. You can either divide a scalar or an Asig object. + """ + Magic method for division. You can either divide a scalar or an Asig object. Use division with caution, audio signal is common to reach 0 or near, avoid zero division or extremely large result. - If dividing an Asig, you don't always need to have same size arrays as audio signals - may different in length. If mix_mode is set to 'bound' the size is fixed to respect self. - If not, the result will respect to whichever the bigger array is.""" + If dividing an Asig, you don't always need to have same size arrays + as audio signals may different in length. If mix_mode is set to 'bound' the size + is fixed to respect self. If not, the result will respect to whichever + the bigger array is. + """ selfsig = self.sig othersig = other.sig if isinstance(other, Asig) else other if isinstance(othersig, numbers.Number): @@ -1106,10 +1146,13 @@ def __rtruediv__(self, other): ) def __add__(self, other): - """Magic method for adding. You can either add a scalar or an Asig object. If adding an Asig, - you don't always need to have same size arrays as audio signals may different in length. If mix_mode - is set to 'bound' the size is fixed to respect self. If not, the result will respect to whichever the - bigger array is.""" + """ + Magic method for adding. You can either add a scalar or an Asig object. + If adding an Asig, you don't always need to have same size arrays + as audio signals may different in length. If mix_mode is set to 'bound' the size + is fixed to respect self. If not, the result will respect to whichever the + bigger array is. + """ selfsig = self.sig othersig = other.sig if isinstance(other, Asig) else other if isinstance(othersig, numbers.Number): # When other is just a scalar @@ -1146,10 +1189,13 @@ def __radd__(self, other): return Asig(other + self.sig, self.sr, label=self.label + "_added", cn=self.cn) def __sub__(self, other): - """Magic method for subtraction. You can either minus a scalar or an Asig object. If subtracting an Asig, - you don't always need to have same size arrays as audio signals may different in length. If mix_mode - is set to 'bound' the size is fixed to respect self. If not, the result will respect to whichever the - bigger array is.""" + """ + Magic method for subtraction. You can either minus a scalar or an Asig object. + If subtracting an Asig, you don't always need to have same size arrays + as audio signals may different in length. If mix_mode is set to 'bound' the size + is fixed to respect self. If not, the result will respect to whichever the + bigger array is. + """ selfsig = self.sig othersig = other.sig if isinstance(other, Asig) else other if isinstance(othersig, numbers.Number): # When other is just a scalar @@ -1200,7 +1246,9 @@ def find_events( sil_min_dur: float = 0.1, sil_pad: list = [0.001, 0.1], ): - """Locate meaningful 'events' in the signal and create event list. Onset detection. + """ + Locate meaningful 'events' in the signal and create event list. + Onset detection. Parameters ---------- @@ -1214,13 +1262,15 @@ def find_events( minimum duration to be counted as silent (Default value = 0.1) sil_pad : list this allows you to add a small duration before and after the actual - found event locations to the event ranges. If it is a list, you can set the padding (Default value = [0.001) + found event locations to the event ranges. + If it is a list, you can set the padding (Default value = [0.001) 0.1] : Returns ------- _ : Asig - This method returns self. But the list of events can be accessed through self._['events'] + This method returns self. But the list of events + can be accessed through self._['events'] """ if self.channels > 1: msg = """warning: works only with single channel. @@ -1240,7 +1290,7 @@ def find_events( sil_pad_samples = (int(sil_pad * self.sr),) * 2 event_list = [] for i in range(0, self.samples, step_samples): - rms = self[i: i + step_samples].rms() + rms = self[i : i + step_samples].rms() if sil_flag: if rms > sil_thr_amp: # event found sil_flag = False @@ -1256,9 +1306,14 @@ def find_events( if sil_count > sil_min_steps: # event ended # The below line is new. if event_end - event_begin >= evt_min_steps: - event_list.append([event_begin - sil_pad_samples[0], - event_end - step_samples * sil_min_steps + sil_pad_samples[1], ] - ) + event_list.append( + [ + event_begin - sil_pad_samples[0], + event_end + - step_samples * sil_min_steps + + sil_pad_samples[1], + ] + ) sil_flag = True self._["events"] = np.array(event_list) return self @@ -1302,8 +1357,7 @@ def plot_events(self): plt.axvline(x=event[0]) plt.axvline(x=event[1], color="r") except KeyError: - raise ValueError( - "No events found, use find_events() before plotting.") + raise ValueError("No events found, use find_events() before plotting.") def fade_in(self, dur: float = 0.1, curve: float = 1): """Fade in the signal at the beginning @@ -1324,7 +1378,8 @@ def fade_in(self, dur: float = 0.1, curve: float = 1): if nsamp > self.samples: nsamp = self.samples warn("warning: Asig too short for fade_in - adapting fade_in time") - # TODO simplify this if we decide to make mono signal with dimension 1 instead of None. + # TODO simplify this if we decide to make mono signal + # with dimension 1 instead of None. if self.channels == 1: ramp = np.linspace(0, 1, nsamp, dtype="float32") ** curve return Asig( @@ -1335,8 +1390,7 @@ def fade_in(self, dur: float = 0.1, curve: float = 1): ) else: ramp = np.meshgrid( - np.linspace(0, 1, nsamp, dtype="float32"), np.zeros( - self.channels) + np.linspace(0, 1, nsamp, dtype="float32"), np.zeros(self.channels) )[0].T return Asig( np.vstack((self.sig[:nsamp] * ramp, self.sig[nsamp:])), @@ -1364,7 +1418,8 @@ def fade_out(self, dur: float = 0.1, curve: float = 1): if nsamp > self.samples: nsamp = self.samples warn("Asig too short for fade_out - adapting fade_out time") - # TODO simplify this if we decide to make mono signal with dimension 1 instead of None. + # TODO simplify this if we decide to make mono signal + # with dimension 1 instead of None. if self.channels == 1: ramp = np.linspace(1, 0, nsamp, dtype="float32") ** curve return Asig( @@ -1375,8 +1430,7 @@ def fade_out(self, dur: float = 0.1, curve: float = 1): ) else: ramp = np.meshgrid( - np.linspace(1, 0, nsamp, dtype="float32"), np.zeros( - self.channels) + np.linspace(1, 0, nsamp, dtype="float32"), np.zeros(self.channels) )[0].T return Asig( np.vstack((self.sig[:-nsamp], self.sig[-nsamp:] * ramp)), @@ -1404,28 +1458,33 @@ def iirfilter( btype : str Filter type (Default value = 'bandpass') ftype : str - Tthe type of IIR filter. e.g. 'butter', 'cheby1', 'cheby2', 'elip', 'bessel' (Default value = 'butter') + Tthe type of IIR filter. e.g. 'butter', 'cheby1', 'cheby2', 'elip', 'bessel' + (Default value = 'butter') order : int Filter order (Default value = 4) filter : str - The scipy.signal method to call when applying the filter coeffs to the signal. + The scipy.signal method to call + when applying the filter coeffs to the signal. by default it is set to scipy.signal.lfilter (one-dimensional). rp : float - For Chebyshev and elliptic filters, provides the maximum ripple in the passband. (dB) (Default value = None) + For Chebyshev and elliptic filters, + provides the maximum ripple in the passband. (dB) (Default value = None) rs : float - For Chebyshev and elliptic filters, provides the minimum attenuation in the stop band. (dB) (Default value = None) + For Chebyshev and elliptic filters, + provides the minimum attenuation in the stop band. (dB) + (Default value = None) Returns ------- _ : Asig - new Asig with the filter applied. also you can access b, a coefficients by doing self._['b'] + new Asig with the filter applied. + also you can access b, a coefficients by doing self._['b'] and self._['a'] """ # TODO scipy.signal.__getattribute__ error Wn = np.array(cutoff_freqs) * 2 / self.sr - b, a = scipy.signal.iirfilter( - order, Wn, rp=rp, rs=rs, btype=btype, ftype=ftype) + b, a = scipy.signal.iirfilter(order, Wn, rp=rp, rs=rs, btype=btype, ftype=ftype) y = scipy.signal.__getattribute__(filter)(b, a, self.sig, axis=0) aout = Asig(y, self.sr, label=self.label + "_iir") aout._["b"] = b @@ -1434,7 +1493,9 @@ def iirfilter( return aout def plot_freqz(self, worN, **kwargs): - """Plot the frequency response of a digital filter. Perform scipy.signal.freqz then plot the response. + """ + Plot the frequency response of a digital filter. + Perform scipy.signal.freqz then plot the response. TODO Parameters @@ -1475,7 +1536,7 @@ def envelope(self, amps, ts=None, curve=1, kind="linear"): nsteps = len(amps) duration = self.samples / self.sr if nsteps == self.samples: - sig_new = self.sig * amps ** curve + sig_new = self.sig * amps**curve else: if not ts: given_ts = np.linspace(0, duration, nsteps) @@ -1498,13 +1559,22 @@ def envelope(self, amps, ts=None, curve=1, kind="linear"): raise AttributeError("Asig.envelope error: ts not sorted") given_ts = ts if nsteps != self.samples: - interp_fn = scipy.interpolate.interp1d( - given_ts, amps, kind=kind) - sig_new = (self.sig * interp_fn(np.linspace(0, duration, self.samples)) ** curve) + interp_fn = scipy.interpolate.interp1d(given_ts, amps, kind=kind) + sig_new = ( + self.sig + * interp_fn(np.linspace(0, duration, self.samples)) ** curve + ) return Asig(sig_new, self.sr, label=self.label + "_enveloped", cn=self.cn) - def adsr(self, att: float = 0, dec: float = 0.1, sus: float = 0.7, rel: float = 0.1, - curve: int = 1, kind: str = "linear"): + def adsr( + self, + att: float = 0, + dec: float = 0.1, + sus: float = 0.7, + rel: float = 0.1, + curve: int = 1, + kind: str = "linear", + ): """Create and applied a ADSR evelope to signal. Parameters @@ -1542,7 +1612,8 @@ def window(self, win: str = "triang", **kwargs): Parameters ---------- win : str - Type of window check scipy.signal.get_window for avaiable types. (Default value = 'triang') + Type of window check scipy.signal.get_window for avaiable types. + (Default value = 'triang') **kwargs : keyword arguments for scipy.signal.get_window() @@ -1558,12 +1629,15 @@ def window(self, win: str = "triang", **kwargs): if isinstance(winstr, tuple): winstr = win[0] if self.channels == 1: - return Asig(self.sig * scipy.signal.get_window(win, self.samples, **kwargs), - self.sr, label=self.label + "_" + winstr, cn=self.cn) + return Asig( + self.sig * scipy.signal.get_window(win, self.samples, **kwargs), + self.sr, + label=self.label + "_" + winstr, + cn=self.cn, + ) else: for i in range(self.channels): - self.sig[:, - i] *= scipy.signal.get_window(win, self.samples, **kwargs) + self.sig[:, i] *= scipy.signal.get_window(win, self.samples, **kwargs) return Asig(self.sig, self.sr, label=self.label + "_" + winstr, cn=self.cn) def window_op(self, nperseg=64, stride=32, win=None, fn="rms", pad="mirror"): @@ -1680,12 +1754,17 @@ def overlap_add( def to_spec(self): """Return Aspec object which is the rfft of the signal.""" import pya.aspec + return pya.aspec.Aspec(self) def to_stft(self, **kwargs): - """Return Astft object which is the stft of the signal. Keyword arguments are the arguments for - scipy.signal.stft(). """ + """ + Return Astft object which is the stft of the signal. + Keyword arguments are the arguments for + scipy.signal.stft(). + """ import pya.astft + return pya.astft.Astft(self, **kwargs) def to_mfcc( @@ -1700,8 +1779,9 @@ def to_mfcc( preemph=0.95, append_energy=True, ): - """Return Amfcc object. """ + """Return Amfcc object.""" import pya.amfcc + return pya.amfcc.Amfcc( self, label=self.label, @@ -1717,7 +1797,13 @@ def to_mfcc( cn=self.cn, ) - def plot_spectrum(self, offset: float = 0, scale: float = 1.0, xlim: Optional[Iterable] = None, **kwargs): + def plot_spectrum( + self, + offset: float = 0, + scale: float = 1.0, + xlim: Optional[Iterable] = None, + **kwargs, + ): """Plot spectrum of the signal Parameters @@ -1783,10 +1869,11 @@ def plot_spectrum(self, offset: float = 0, scale: float = 1.0, xlim: Optional[It return self def spectrogram(self, *argv, **kvarg): - """Perform sicpy.signal.spectrogram and returns: frequencies, array of times, spectrogram """ - freqs, times, Sxx = scipy.signal.spectrogram( - self.sig, self.sr, *argv, **kvarg) + Perform sicpy.signal.spectrogram and returns: + frequencies, array of times, spectrogram + """ + freqs, times, Sxx = scipy.signal.spectrogram(self.sig, self.sr, *argv, **kvarg) return freqs, times, Sxx def get_size(self): @@ -1794,7 +1881,9 @@ def get_size(self): return self.sig.shape, self.sig.shape[0] / self.sr def append(self, asig, amp=1): - """Apppend an asig with another. Conditions: the appended asig should have the same channels. If + """ + Apppend an asig with another. Conditions: the appended asig + should have the same channels. If appended asig has a different sampling rate, resample it to match the orginal. Parameters @@ -1856,7 +1945,8 @@ def add(self, sig, pos=None, amp=1, onset=None): raise AttributeError("Argument asig has different channels.!") if sr != self.sr: raise AttributeError( - "Dangerous operation, samping rate (sr) not matched. Use resample() first." + "Dangerous operation, samping rate (sr) not matched. " + "Use resample() first." ) else: n = np.shape(sig)[0] @@ -1883,7 +1973,9 @@ def flatten(self): cn=None, ) - def pad(self, width: int = 0, tail: bool = True, constant_values: Union[int, float] = 0): + def pad( + self, width: int = 0, tail: bool = True, constant_values: Union[int, float] = 0 + ): """Pads the signal Parameters @@ -1923,22 +2015,29 @@ def convolve(self, sig, mode: str = "full", method: str = "fft", norm: str = "am mode : str {'full', 'valid', 'same'} A string indicating the size of the output: full - The output is the full discrete linear convolution of the inputs. (Default) + The output is the full discrete linear convolution of the inputs. + (Default) valid - The output consists only of those elements that do not rely on the zero-padding. - self.sr or ins must be at least as large as the other in every dimension. + The output consists only of those elements + that do not rely on the zero-padding. + self.sr or ins must be at least as large + as the other in every dimension. same - The output is the same size as self.sr, centered with respect to the full output. + The output is the same size as self.sr, + centered with respect to the full output. method : str {'auto', 'direct', 'fft'} A string indicating which method to use to calculate the convolution direct Compute directly from sums, the definition of convolution fft (default) - The Fourier Transform is used to perform the convolution by calling fftconvolve + The Fourier Transform is used to perform the convolution + by calling fftconvolve auto - Automatically chooses direct or Fourier method based on an estimate of which is faster. + Automatically chooses direct or Fourier method + based on an estimate of which is faster. norm : str - If "amp" (default value), the result signal will have the same peak as the original signal. + If "amp" (default value), the result signal + will have the same peak as the original signal. Otherwise, no normalization is applied. Returns @@ -1948,8 +2047,7 @@ def convolve(self, sig, mode: str = "full", method: str = "fft", norm: str = "am """ if isinstance(sig, Asig): if sig.sr != self.sr: - _LOGGER.warning( - "sampling rate not matched, perform resampling...") + _LOGGER.warning("sampling rate not matched, perform resampling...") sig = sig.resample(target_sr=self.sr) sig_array = sig.sig sig_size = sig.samples @@ -1959,34 +2057,33 @@ def convolve(self, sig, mode: str = "full", method: str = "fft", norm: str = "am sig_size = len(sig) sig_channels = 1 if sig_array.ndim == 1 else sig_array.shape[1] else: - raise TypeError( - "Illegal type. ir must be an Asig object or an array.") + raise TypeError("Illegal type. ir must be an Asig object or an array.") # Compare size of A B, and pad zeros if needed. if self.samples > sig_size: # pad ir sig_array = padding(sig_array, width=self.samples - sig_size) else: + # TODO somehow, this code is not doing anything? # pad source - asig = padding(self.sig, width=sig_size - self.samples) + _ = padding(self.sig, width=sig_size - self.samples) # Now perform convolution if self.channels == 1: # If sig is a mono signal: result = np.array( - scipy.signal.convolve( - self.sig, sig_array, mode=mode, method=method) + scipy.signal.convolve(self.sig, sig_array, mode=mode, method=method) ) else: if sig_channels > 1 and self.channels != sig_channels: raise ValueError( - "input signal needs to have the same amount of channels as self.sig." + "input signal needs to have the same " + "amount of channels as self.sig." ) # Perform conv on each channel. for i in range(self.channels): a = self.sig[:, i] b = sig_array if sig_channels == 1 else sig_array[:, i] - r_1ch = np.array(scipy.signal.convolve( - a, b, mode=mode, method=method)) + r_1ch = np.array(scipy.signal.convolve(a, b, mode=mode, method=method)) if i == 0: result = np.zeros((len(r_1ch), self.channels)) result[:, i] = r_1ch @@ -2014,4 +2111,6 @@ def apply(self, fn): """ vecfn = np.vectorize(fn) sig_out = vecfn(self.sig) - return Asig(sig_out, sr=self.sr, label=self.label, channels=self.channels, cn=self.cn) + return Asig( + sig_out, sr=self.sr, label=self.label, channels=self.channels, cn=self.cn + ) diff --git a/pya/aspec.py b/pya/aspec.py index 25849b55..8b65973d 100644 --- a/pya/aspec.py +++ b/pya/aspec.py @@ -1,12 +1,12 @@ import logging -from typing import Union, Optional +from typing import Optional, Union import numpy as np import scipy.interpolate import pya.asig -from .helper import basicplot +from .helper import basicplot _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) @@ -14,8 +14,14 @@ class Aspec: """Audio spectrum class using rfft""" - def __init__(self, x: Union[pya.asig.Asig, np.ndarray], sr: int = 44100, - label: Optional[str] = None, cn: Optional[list] = None): + + def __init__( + self, + x: Union[pya.asig.Asig, np.ndarray], + sr: int = 44100, + label: Optional[str] = None, + cn: Optional[list] = None, + ): """__init__() method Parameters ---------- @@ -36,7 +42,8 @@ def __init__(self, x: Union[pya.asig.Asig, np.ndarray], sr: int = 44100, self.channels = x.channels self.cn = cn or x.cn elif isinstance(x, np.ndarray): - # TODO. This is in the assumption x is spec. which is wrong. We define x to be the audio signals instead. + # TODO. This is in the assumption x is spec. which is wrong. + # We define x to be the audio signals instead. self.rfftspec = np.array(x) self.sr = sr self.samples = (len(x) - 1) * 2 @@ -57,10 +64,14 @@ def get_duration(self): def to_sig(self): """Convert Aspec into Asig""" - return pya.asig.Asig(np.fft.irfft(self.rfftspec), - sr=self.sr, label=self.label + '_2sig', cn=self.cn) - - def weight(self, weights: list, freqs=None, curve=1, kind='linear'): + return pya.asig.Asig( + np.fft.irfft(self.rfftspec), + sr=self.sr, + label=self.label + "_2sig", + cn=self.cn, + ) + + def weight(self, weights: list, freqs=None, curve=1, kind="linear"): """TODO Parameters @@ -96,18 +107,16 @@ def weight(self, weights: list, freqs=None, curve=1, kind='linear'): weights = np.insert(np.array(weights), -1, weights[-1]) given_freqs = freqs if nfreqs != self.nr_freqs: - interp_fn = scipy.interpolate.interp1d(given_freqs, - weights, kind=kind) + interp_fn = scipy.interpolate.interp1d(given_freqs, weights, kind=kind) # ToDo: curve segmentwise!!! rfft_new = self.rfftspec * interp_fn(self.freqs) ** curve else: - rfft_new = self.rfftspec * weights ** curve - return Aspec(rfft_new, self.sr, - label=self.label + "_weighted", cn=self.cn) + rfft_new = self.rfftspec * weights**curve + return Aspec(rfft_new, self.sr, label=self.label + "_weighted", cn=self.cn) - def plot(self, fn=np.abs, ax=None, - offset=0, scale=1, - xlim=None, ylim=None, **kwargs): + def plot( + self, fn=np.abs, ax=None, offset=0, scale=1, xlim=None, ylim=None, **kwargs + ): """Plot spectrum Parameters @@ -132,14 +141,24 @@ def plot(self, fn=np.abs, ax=None, _ : Asig self """ - _, ax = basicplot(fn(self.rfftspec), self.freqs, channels=self.channels, - cn=self.cn, offset=offset, scale=scale, - ax=ax, typ='plot', - xlabel='freq (Hz)', ylabel=f'{fn.__name__}(freq)', - xlim=xlim, ylim=ylim, **kwargs) + _, ax = basicplot( + fn(self.rfftspec), + self.freqs, + channels=self.channels, + cn=self.cn, + offset=offset, + scale=scale, + ax=ax, + typ="plot", + xlabel="freq (Hz)", + ylabel=f"{fn.__name__}(freq)", + xlim=xlim, + ylim=ylim, + **kwargs, + ) return self def __repr__(self): return "Aspec('{}'): {} x {} @ {} Hz = {:.3f} s".format( - self.label, self.channels, self.samples, - self.sr, self.samples / self.sr) + self.label, self.channels, self.samples, self.sr, self.samples / self.sr + ) diff --git a/pya/astft.py b/pya/astft.py index 379d9085..53064733 100644 --- a/pya/astft.py +++ b/pya/astft.py @@ -1,13 +1,14 @@ from __future__ import absolute_import + import logging -from typing import Union, Optional +from typing import Optional, Union import numpy as np -from scipy.signal import stft, istft +from scipy.signal import istft, stft import pya.asig -from .helper import basicplot +from .helper import basicplot _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) @@ -15,15 +16,26 @@ # TODO, check with multichannel class Astft: - """Audio spectrogram (STFT) class, attributes refers to scipy.signal.stft. With an addition - attribute cn being the list of channel names, and label being the name of the Asig + """Audio spectrogram (STFT) class, attributes refers to scipy.signal.stft. + With an addition attribute cn being the list of channel names, + and label being the name of the Asig """ - def __init__(self, x: Union[pya.asig.Asig, np.ndarray], sr: Optional[int] = None, label: str = "STFT", - window: str = 'hann', nperseg: int = 256, noverlap: Optional[int] = None, - nfft: Optional[int] = None, detrend: bool = False, - return_onesided: bool = True, boundary: str = 'zeros', - padded: bool = True, cn: Optional[list] = None): + def __init__( + self, + x: Union[pya.asig.Asig, np.ndarray], + sr: Optional[int] = None, + label: str = "STFT", + window: str = "hann", + nperseg: int = 256, + noverlap: Optional[int] = None, + nfft: Optional[int] = None, + detrend: bool = False, + return_onesided: bool = True, + boundary: str = "zeros", + padded: bool = True, + cn: Optional[list] = None, + ): """__init__() method Parameters @@ -45,26 +57,37 @@ def __init__(self, x: Union[pya.asig.Asig, np.ndarray], sr: Optional[int] = None `None`, the FFT length is `nperseg`. Defaults to `None`. detrend : str or function or bool Specifies how to detrend each segment. If detrend is a string, - it is passed as the type argument to the detrend function. If it is a function, + it is passed as the type argument to the detrend function. + If it is a function, it takes a segment and returns a detrended segment. If detrend is False, no detrending is done. (Default value = False). return_onesided : bool - If True, return a one-sided spectrum for real data. If False return a two-sided spectrum. - Defaults to True, but for complex data, a two-sided spectrum is always returned. (Default value = True) + If True, return a one-sided spectrum for real data. + If False return a two-sided spectrum. + Defaults to True, but for complex data, + a two-sided spectrum is always returned. (Default value = True) boundary : str or None - Specifies whether the input signal is extended at both ends, and how to generate the new values, + Specifies whether the input signal is extended at both ends, + and how to generate the new values, in order to center the first windowed segment on the first input point. This has the benefit of enabling reconstruction of the first input point when the employed window function starts at zero. - Valid options are ['even', 'odd', 'constant', 'zeros', None]. Defaults to ‘zeros’, - for zero padding extension. I.e. [1, 2, 3, 4] is extended to [0, 1, 2, 3, 4, 0] for nperseg=3. (Default value = 'zeros') + Valid options are ['even', 'odd', 'constant', 'zeros', None]. + Defaults to ‘zeros’, + for zero padding extension. + I.e. [1, 2, 3, 4] is extended to [0, 1, 2, 3, 4, 0] for nperseg=3. + (Default value = 'zeros') padded : bool - Specifies whether the input signal is zero-padded at the end to make the signal fit exactly into - an integer number of window segments, so that all of the signal is included in the output. - Defaults to True. Padding occurs after boundary extension, if boundary is not None, and padded is True, + Specifies whether the input signal is zero-padded at the end + to make the signal fit exactly into + an integer number of window segments, + so that all of the signal is included in the output. + Defaults to True. Padding occurs after boundary extension, + if boundary is not None, and padded is True, as is the default. (Default value = True) cn : list, optional - Channel names of the Asig, this will be used for the Astft for consistency. (Default value = None) + Channel names of the Asig, this will be used for the Astft for consistency. + (Default value = None) """ self.window = window self.nperseg = nperseg @@ -91,22 +114,35 @@ def __init__(self, x: Union[pya.asig.Asig, np.ndarray], sr: Optional[int] = None # x is a numpy array instead of asig. self.channels = x.ndim self.samples = len(x) - self.label = 'stft' + self.label = "stft" self.cn = [] if sr is None: - raise AttributeError("sr (sampling rate) is required as an argument if input is a numpy array rather than Asig.") + raise AttributeError( + "sr (sampling rate) is required as an argument " + "if input is a numpy array rather than Asig." + ) else: self.sr = sr sig = x else: - raise TypeError("Unknown data type x, x should be either Asig or numpy.ndarray") - - self.freqs, self.times, self.stft = \ - stft(sig, fs=self.sr, window=window, nperseg=nperseg, - noverlap=noverlap, nfft=nfft, detrend=detrend, - return_onesided=return_onesided, boundary=boundary, - padded=padded, axis=0) + raise TypeError( + "Unknown data type x, x should be either Asig or numpy.ndarray" + ) + + self.freqs, self.times, self.stft = stft( + sig, + fs=self.sr, + window=window, + nperseg=nperseg, + noverlap=noverlap, + nfft=nfft, + detrend=detrend, + return_onesided=return_onesided, + boundary=boundary, + padded=padded, + axis=0, + ) if cn: if len(cn) == self.channels: @@ -131,26 +167,43 @@ def to_sig(self, **kwargs): _ : Asig Asig """ - for k in ['sr', 'window', 'nperseg', 'noverlap', - 'nfft', 'input_onesided', 'boundary']: + for k in [ + "sr", + "window", + "nperseg", + "noverlap", + "nfft", + "input_onesided", + "boundary", + ]: if k in kwargs.keys(): kwargs[k] = self.__getattribute__(k) - if 'sr' in kwargs.keys(): - kwargs['fs'] = kwargs['sr'] - del kwargs['sr'] + if "sr" in kwargs.keys(): + kwargs["fs"] = kwargs["sr"] + del kwargs["sr"] if self.channels == 1: # _ since 1st return value 'times' unused _, sig = istft(self.stft, **kwargs) - return pya.asig.Asig(sig, sr=self.sr, - label=self.label + '_2sig', cn=self.cn) + return pya.asig.Asig( + sig, sr=self.sr, label=self.label + "_2sig", cn=self.cn + ) else: _, sig = istft(self.stft, **kwargs) - return pya.asig.Asig(np.transpose(sig), - sr=self.sr, label=self.label + '_2sig', cn=self.cn) - - def plot(self, fn=lambda x: x, ax=None, - offset=0, scale=1., xlim=None, ylim=None, - show_bar=True, **kwargs): + return pya.asig.Asig( + np.transpose(sig), sr=self.sr, label=self.label + "_2sig", cn=self.cn + ) + + def plot( + self, + fn=lambda x: x, + ax=None, + offset=0, + scale=1.0, + xlim=None, + ylim=None, + show_bar=True, + **kwargs, + ): """Plot spectrogram Parameters @@ -173,15 +226,30 @@ def plot(self, fn=lambda x: x, ax=None, _ : Asig self """ - self.im, ax = basicplot(fn(np.abs(self.stft)), (self.times, self.freqs), - channels=self.channels, - cn=self.cn, offset=offset, scale=scale, - ax=ax, typ='spectrogram', show_bar=show_bar, - xlabel='time', xlim=xlim, ylim=ylim, **kwargs) - ax.set_ylabel('freq') + self.im, ax = basicplot( + fn(np.abs(self.stft)), + (self.times, self.freqs), + channels=self.channels, + cn=self.cn, + offset=offset, + scale=scale, + ax=ax, + typ="spectrogram", + show_bar=show_bar, + xlabel="time", + xlim=xlim, + ylim=ylim, + **kwargs, + ) + ax.set_ylabel("freq") return self def __repr__(self): return "Astft('{}'): {} x {} @ {} Hz = {:.3f} s cn={}".format( - self.label, self.channels, self.samples, - self.sr, self.samples / self.sr, self.cn) + self.label, + self.channels, + self.samples, + self.sr, + self.samples / self.sr, + self.cn, + ) diff --git a/pya/backend/Dummy.py b/pya/backend/Dummy.py index 96c35d0d..9a4ccf19 100644 --- a/pya/backend/Dummy.py +++ b/pya/backend/Dummy.py @@ -1,17 +1,22 @@ -from .base import BackendBase, StreamBase -import numpy as np -from threading import Thread import time +from threading import Thread +import numpy as np -class DummyBackend(BackendBase): +from pya.backend.base import BackendBase, StreamBase - dtype = 'float32' +__all__ = ["DummyBackend", "DummyStream"] + + +class DummyBackend(BackendBase): + dtype = "float32" range = 1 bs = 256 def __init__(self): - self.dummy_devices = [dict(maxInputChannels=10, maxOutputChannels=10, index=0, name="DummyDevice")] + self.dummy_devices = [ + dict(maxInputChannels=10, maxOutputChannels=10, index=0, name="DummyDevice") + ] def get_device_count(self): return len(self.dummy_devices) @@ -25,13 +30,28 @@ def get_default_input_device_info(self): def get_default_output_device_info(self): return self.dummy_devices[0] - def open(self, *args, input_flag, output_flag, rate, frames_per_buffer, channels, stream_callback=None, **kwargs): - checker = 'maxInputChannels' if input_flag else 'maxOutputChannels' + def open( + self, + *args, + input_flag, + output_flag, + rate, + frames_per_buffer, + channels, + stream_callback=None, + **kwargs, + ): + checker = "maxInputChannels" if input_flag else "maxOutputChannels" if channels > self.dummy_devices[0][checker]: raise OSError("[Errno -9998] Invalid number of channels") - stream = DummyStream(input_flag=input_flag, output_flag=output_flag, - rate=rate, frames_per_buffer=frames_per_buffer, channels=channels, - stream_callback=stream_callback) + stream = DummyStream( + input_flag=input_flag, + output_flag=output_flag, + rate=rate, + frames_per_buffer=frames_per_buffer, + channels=channels, + stream_callback=stream_callback, + ) stream.start_stream() return stream @@ -43,8 +63,15 @@ def terminate(self): class DummyStream(StreamBase): - - def __init__(self, input_flag, output_flag, frames_per_buffer, rate, channels, stream_callback): + def __init__( + self, + input_flag, + output_flag, + frames_per_buffer, + rate, + channels, + stream_callback, + ): self.input_flag = input_flag self.output_flag = output_flag self.rate = rate @@ -58,8 +85,9 @@ def __init__(self, input_flag, output_flag, frames_per_buffer, rate, channels, s def stop_stream(self): self._is_active = False - while (self.in_thread and self.in_thread.is_alive()) or \ - (self.out_thread and self.out_thread.is_alive()): + while (self.in_thread and self.in_thread.is_alive()) or ( + self.out_thread and self.out_thread.is_alive() + ): time.sleep(0.1) def close(self): @@ -67,7 +95,9 @@ def close(self): def _generate_data(self): while self._is_active: - sig = np.zeros(self.frames_per_buffer * self.channels, dtype=DummyBackend.dtype) + sig = np.zeros( + self.frames_per_buffer * self.channels, dtype=DummyBackend.dtype + ) self.stream_callback(sig, frame_count=None, time_info=None, flag=None) time.sleep(0.05) diff --git a/pya/backend/Jupyter.py b/pya/backend/Jupyter.py index 710871ae..e9e9159d 100644 --- a/pya/backend/Jupyter.py +++ b/pya/backend/Jupyter.py @@ -1,28 +1,35 @@ -from .base import BackendBase, StreamBase - import asyncio import threading -from functools import partial -from IPython.display import Javascript, HTML, display + +from IPython.display import HTML, Javascript, display + +from pya.backend.base import BackendBase, StreamBase try: import websockets except ImportError: websockets = None +__all__ = ["JupyterBackend", "JupyterStream"] -class JupyterBackend(BackendBase): - dtype = 'float32' +class JupyterBackend(BackendBase): + dtype = "float32" range = 1 bs = 4096 # streaming introduces lack which has to be covered by the buffer def __init__(self, port=8765, proxy_suffix=None): if not websockets: - raise Exception("JupyterBackend requires 'websockets' but it could not be imported. " - "Did you miss installing optional 'remote' requirements?") - - self.dummy_devices = [dict(maxInputChannels=0, maxOutputChannels=2, index=0, name="JupyterBackend")] + raise Exception( + "JupyterBackend requires 'websockets' but it could not be imported. " + "Did you miss installing optional 'remote' requirements?" + ) + + self.dummy_devices = [ + dict( + maxInputChannels=0, maxOutputChannels=2, index=0, name="JupyterBackend" + ) + ] self.port = port self.proxy_suffix = proxy_suffix if self.proxy_suffix is not None: @@ -41,11 +48,20 @@ def get_default_output_device_info(self): return self.dummy_devices[0] def open(self, *args, channels, rate, stream_callback=None, **kwargs): - display(HTML("
You are using the experimental Jupyter backend. " - "Note that this backend is not feature complete and does not support recording so far. " - "User experience may vary depending on the network latency.
")) - stream = JupyterStream(channels=channels, rate=rate, stream_callback=stream_callback, port=self.port, - proxy_suffix=self.proxy_suffix) + display( + HTML( + '
You are using the experimental Jupyter backend. ' # noqa E501 + "Note that this backend is not feature complete and does not support recording so far. " # noqa E501 + "User experience may vary depending on the network latency.
" + ) + ) + stream = JupyterStream( + channels=channels, + rate=rate, + stream_callback=stream_callback, + port=self.port, + proxy_suffix=self.proxy_suffix, + ) stream.start_stream() return stream @@ -57,7 +73,6 @@ def terminate(self): class JupyterStream(StreamBase): - def __init__(self, channels, rate, stream_callback, port, proxy_suffix): self.rate = rate self.channels = channels @@ -69,7 +84,7 @@ async def bridge(websocket): async for _ in websocket: buffer = self.stream_callback(None, None, None, None) # print(buffer) - await websocket.send(buffer.reshape(-1, 1, order='F').tobytes()) + await websocket.send(buffer.reshape(-1, 1, order="F").tobytes()) async def ws_runner(): async with websockets.serve(bridge, "0.0.0.0", 8765): @@ -85,9 +100,10 @@ def loop_thread(loop): self.loop = asyncio.new_event_loop() self.thread = threading.Thread(target=loop_thread, args=(self.loop,)) - # self.thread.daemon = True # allow program to shutdown even if the thread is alive + # allow program to shutdown even if the thread is alive + # self.thread.daemon = True - url_suffix = f':{port}' if proxy_suffix is None else proxy_suffix + url_suffix = f":{port}" if proxy_suffix is None else proxy_suffix self.client = Javascript( f""" @@ -191,7 +207,8 @@ def loop_thread(loop): } console.log("PyaJSClient: Websocket client loaded.") - """) + """ # noqa E501 + ) @staticmethod def set_buffer_threshold(buffer_limit): diff --git a/pya/backend/PyAudio.py b/pya/backend/PyAudio.py index df9b83ff..47547eaa 100644 --- a/pya/backend/PyAudio.py +++ b/pya/backend/PyAudio.py @@ -1,11 +1,15 @@ -from .base import BackendBase +import time import pyaudio -import time +from pya.backend.base import BackendBase -class PyAudioBackend(BackendBase): +__all__ = [ + "PyAudioBackend", +] + +class PyAudioBackend(BackendBase): _boot_delay = 0.5 # a short delay to prevent PyAudio racing conditions bs = 512 @@ -13,13 +17,15 @@ def __init__(self, format=pyaudio.paFloat32): self.pa = pyaudio.PyAudio() self.format = format if format == pyaudio.paInt16: - self.dtype = 'int16' + self.dtype = "int16" self.range = 32767 elif format == pyaudio.paFloat32: - self.dtype = 'float32' # for pyaudio.paFloat32 + self.dtype = "float32" # for pyaudio.paFloat32 self.range = 1.0 else: - raise AttributeError(f"Aserver: currently unsupported pyaudio format {self.format}") + raise AttributeError( + f"Aserver: currently unsupported pyaudio format {self.format}" + ) def get_device_count(self): return self.pa.get_device_count() @@ -33,16 +39,34 @@ def get_default_input_device_info(self): def get_default_output_device_info(self): return self.pa.get_default_output_device_info() - def open(self, rate, channels, input_flag, output_flag, frames_per_buffer, - input_device_index=None, output_device_index=None, start=True, - input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, - stream_callback=None): - stream = self.pa.open(rate=rate, channels=channels, format=self.format, input=input_flag, output=output_flag, - input_device_index=input_device_index, output_device_index=output_device_index, - frames_per_buffer=frames_per_buffer, start=start, - input_host_api_specific_stream_info=input_host_api_specific_stream_info, - output_host_api_specific_stream_info=output_host_api_specific_stream_info, - stream_callback=stream_callback) + def open( + self, + rate, + channels, + input_flag, + output_flag, + frames_per_buffer, + input_device_index=None, + output_device_index=None, + start=True, + input_host_api_specific_stream_info=None, + output_host_api_specific_stream_info=None, + stream_callback=None, + ): + stream = self.pa.open( + rate=rate, + channels=channels, + format=self.format, + input=input_flag, + output=output_flag, + input_device_index=input_device_index, + output_device_index=output_device_index, + frames_per_buffer=frames_per_buffer, + start=start, + input_host_api_specific_stream_info=input_host_api_specific_stream_info, + output_host_api_specific_stream_info=output_host_api_specific_stream_info, + stream_callback=stream_callback, + ) time.sleep(self._boot_delay) # give stream some time to be opened completely return stream diff --git a/pya/backend/__init__.py b/pya/backend/__init__.py index b2ec81ce..60c44580 100644 --- a/pya/backend/__init__.py +++ b/pya/backend/__init__.py @@ -1,21 +1,25 @@ -from .Dummy import DummyBackend import logging +from pya.backend.Dummy import DummyBackend +from pya.helper.backend import determine_backend + _LOGGER = logging.getLogger(__name__) _LOGGER.addHandler(logging.NullHandler()) +__all__ = ["DummyBackend", "determine_backend"] try: - from .Jupyter import JupyterBackend + from pya.backend.Jupyter import JupyterBackend as JupyterBackend + + __all__.append("JupyterBackend") except ImportError: # pragma: no cover _LOGGER.warning("Jupyter backend not found.") pass try: - from .PyAudio import PyAudioBackend + from pya.backend.PyAudio import PyAudioBackend as PyAudioBackend + + __all__.append("PyAudioBackend") except ImportError: # pragma: no cover _LOGGER.warning("PyAudio backend not found.") pass - - -from ..helper.backend import determine_backend diff --git a/pya/backend/base.py b/pya/backend/base.py index c773b8a8..e38cb4ea 100644 --- a/pya/backend/base.py +++ b/pya/backend/base.py @@ -1,8 +1,7 @@ -from abc import abstractmethod, ABC +from abc import ABC, abstractmethod class BackendBase(ABC): - @abstractmethod def get_device_count(self): raise NotImplementedError @@ -33,7 +32,6 @@ def process_buffer(self, *args, **kwargs): class StreamBase(ABC): - @abstractmethod def is_active(self): raise NotImplementedError diff --git a/pya/helper/__init__.py b/pya/helper/__init__.py index 1c37b5cf..2873b81a 100644 --- a/pya/helper/__init__.py +++ b/pya/helper/__init__.py @@ -1,5 +1,6 @@ # from .helpers import audio_from_file, buf_to_float, spectrum, audio_from_file # from .helpers import normalize, device_info, find_device # from .helpers import padding, shift_bit_length -from .helpers import * -from .visualization import basicplot, gridplot +from .helpers import * # noqa: F403 +from .visualization import basicplot as basicplot +from .visualization import gridplot as gridplot diff --git a/pya/helper/backend.py b/pya/helper/backend.py index 47162f24..3f7424b7 100644 --- a/pya/helper/backend.py +++ b/pya/helper/backend.py @@ -1,26 +1,35 @@ -from typing import Optional, TYPE_CHECKING +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from pya.backend.base import BackendBase - from pya.backend.PyAudio import PyAudioBackend from pya.backend.Jupyter import JupyterBackend + from pya.backend.PyAudio import PyAudioBackend + + +__all__ = [ + "get_server_info", + "try_pyaudio_backend", + "try_jupyter_backend", + "determine_backend", +] def get_server_info(): - import re import json - import requests + import re + import ipykernel import notebook.notebookapp + import requests + kernel_id = re.search( - "kernel-(.*).json", - ipykernel.connect.get_connection_file() + "kernel-(.*).json", ipykernel.connect.get_connection_file() ).group(1) servers = notebook.notebookapp.list_running_servers() for s in servers: response = requests.get( requests.compat.urljoin(s["url"], "api/sessions"), - params={"token": s.get("token", "")} + params={"token": s.get("token", "")}, ) for n in json.loads(response.text): if n["kernel"]["id"] == kernel_id: @@ -31,6 +40,7 @@ def get_server_info(): def try_pyaudio_backend(**kwargs) -> Optional["PyAudioBackend"]: try: from pya.backend.PyAudio import PyAudioBackend + return PyAudioBackend(**kwargs) except ImportError: return None @@ -38,11 +48,18 @@ def try_pyaudio_backend(**kwargs) -> Optional["PyAudioBackend"]: def try_jupyter_backend(port, **kwargs) -> Optional["JupyterBackend"]: import os + from pya.backend.Jupyter import JupyterBackend + server_info = get_server_info() - if server_info is None or (server_info['hostname'] in ['localhost', '127.0.0.1'] and not force_webaudio): + if server_info is None or ( + server_info["hostname"] in ["localhost", "127.0.0.1"] + # TODO commented out the `force_webaudio` condition below, + # because it was undefined + # `and not force_webaudio` + ): return None # use default local backend - if os.environ.get('BINDER_SERVICE_HOST'): + if os.environ.get("BINDER_SERVICE_HOST"): return JupyterBackend(port=port, proxy_suffix=f"/proxy/{port}", **kwargs) else: return JupyterBackend(port=port, **kwargs) diff --git a/pya/helper/codec.py b/pya/helper/codec.py index b6ea021c..40d4f502 100644 --- a/pya/helper/codec.py +++ b/pya/helper/codec.py @@ -1,19 +1,39 @@ """ -Audio codec module supporting high-quality audio file reading with consistent float32 output. -Supports WAV, AIFF, FLAC (via SoundFile) and MP3 (via FFmpeg) while maintaining maximum precision. +Audio codec module supporting high-quality audio file reading +with consistent float32 output. +Supports WAV, AIFF, FLAC (via SoundFile) and MP3 (via FFmpeg) +while maintaining maximum precision. """ -import sys -import subprocess -import re -import time import os -import threading -from warnings import warn import queue +import re +import subprocess +import sys +import threading +import time -import soundfile as sf import numpy as np +import soundfile as sf + +__all__ = [ + "DecodeError", + "NoFileError", + "NoBackendError", + "UnsupportedError", + "BitWidthError", + "FFmpegError", + "FFmpegNotInstalledError", + "FFmpegReadTimeoutError", + "CommunicationError", + "BaseAudioFile", + "SoundFileAudioFile", + "QueueReaderThread", + "popen_multiple", + "ffmpeg_available", + "FFmpegAudioFile", + "audio_read", +] COMMANDS = ("ffmpeg", "avconv") @@ -296,7 +316,7 @@ def __init__(self, filename, block_size=4096): @property def raw_str_info(self) -> str: - """Example info: 'duration: 00:00:00.81, start: 0.025057, bitrate: 84 kb/sstream #0:0: audio: mp3 (mp3float), 44100 hz, mono, fltp, 82 kb/s'""" + """Example info: 'duration: 00:00:00.81, start: 0.025057, bitrate: 84 kb/sstream #0:0: audio: mp3 (mp3float), 44100 hz, mono, fltp, 82 kb/s'""" # noqa: E501 return self._raw_str_info def _get_info(self): @@ -329,7 +349,7 @@ def _parse_info(self, str_info): """Given relevant data from the ffmpeg output, set audio parameter fields on this object. Example: 'duration: 00:00:00.81, start: 0.025057, bitrate: 84 kb/sstream #0:0: audio: mp3 (mp3float), 44100 hz, mono, fltp, 82 kb/s' - """ + """ # noqa: E501 # Sample rate. match = re.search(r"(\d+) hz", str_info) if match: @@ -356,7 +376,12 @@ def _parse_info(self, str_info): match = re.search(r"duration: (\d+):(\d+):(\d+).(\d)", str_info) if match: durparts = list(map(int, match.groups())) - self._duration = (durparts[0] * 60 * 60 + durparts[1] * 60 + durparts[2] + float(durparts[3]) / 10) + self._duration = ( + durparts[0] * 60 * 60 + + durparts[1] * 60 + + durparts[2] + + float(durparts[3]) / 10 + ) else: self._duration = 0 diff --git a/pya/helper/helpers.py b/pya/helper/helpers.py index f0b3c0d3..e9df1779 100644 --- a/pya/helper/helpers.py +++ b/pya/helper/helpers.py @@ -1,18 +1,36 @@ # Collection of small helper functions -import numpy as np -from scipy.fftpack import fft -from .codec import audio_read -import logging import decimal +import logging import math +import numpy as np +from scipy.fftpack import fft + +from .codec import audio_read -class _error(Exception): - pass +__all__ = [ + "spectrum", + "normalize", + "audio_from_file", + "buf_to_float", + "_try_initializing_pyaudio", + "device_info", + "find_device", + "padding", + "is_pow2", + "next_pow2", + "round_half_up", + "rolling_window", + "signal_to_frame", + "magspec", + "powspec", +] def spectrum(sig, samples, channels, sr): - """Return spectrum of a given signal. This method return spectrum matrix if input signal is multi-channels. + """ + Return spectrum of a given signal. + This method return spectrum matrix if input signal is multi-channels. Parameters ---------- @@ -52,9 +70,9 @@ def normalize(d): def audio_from_file(path: str): - '''Load an audio buffer using audio_read. + """Load an audio buffer using audio_read. Returns a tuple of (samples, samplerate) where samples is a numpy float32 array. - ''' + """ y = [] with audio_read(path) as input_file: sr_native = input_file.samplerate @@ -91,9 +109,9 @@ def buf_to_float(x, n_bytes=2, dtype=np.float32): The input data buffer cast to floating point """ # Invert the scale of the data - scale = 1. / float(1 << ((8 * n_bytes) - 1)) + scale = 1.0 / float(1 << ((8 * n_bytes) - 1)) # Construct the format string - fmt = '= min_input and dev['maxOutputChannels'] >= min_output: + if ( + dev["maxInputChannels"] >= min_input + and dev["maxOutputChannels"] >= min_output + ): res.append(dev) return res def padding(x, width, tail=True, constant_values=0): - """Pad signal with certain width, support 1-3D tensors. + """Pad signal with certain width, support 1-3D tensors. Use it to add silence to a signal TODO: CHECK pad array @@ -148,7 +167,7 @@ def padding(x, width, tail=True, constant_values=0): x : np.ndarray A numpy array width : int - The amount of padding. + The amount of padding. tail : bool If true pad to the tail, else pad to the start. constant_values : int or float or None @@ -161,13 +180,19 @@ def padding(x, width, tail=True, constant_values=0): """ pad = (0, width) if tail else (width, 0) if x.ndim == 1: - return np.pad(x, (pad), mode='constant', constant_values=constant_values) + return np.pad(x, (pad), mode="constant", constant_values=constant_values) elif x.ndim == 2: - return np.pad(x, (pad, (0, 0)), mode='constant', constant_values=constant_values) + return np.pad( + x, (pad, (0, 0)), mode="constant", constant_values=constant_values + ) elif x.ndim == 3: - return np.pad(x, ((0, 0), pad, (0, 0)), mode='constant', constant_values=constant_values) + return np.pad( + x, ((0, 0), pad, (0, 0)), mode="constant", constant_values=constant_values + ) else: - raise AttributeError("only support ndim 1 or 2, 3. For higher please just use np.pad ") + raise AttributeError( + "only support ndim 1 or 2, 3. For higher please just use np.pad " + ) def is_pow2(val): @@ -176,7 +201,7 @@ def is_pow2(val): def next_pow2(x): - """Find the closest pow of 2 that is great or equal or x, + """Find the closest pow of 2 that is great or equal or x, based on shift_bit_length Parameters @@ -196,7 +221,11 @@ def next_pow2(x): def round_half_up(number): """Round up if >= .5""" - return int(decimal.Decimal(number).quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)) + return int( + decimal.Decimal(number).quantize( + decimal.Decimal("1"), rounding=decimal.ROUND_HALF_UP + ) + ) def rolling_window(a, window, step=1): @@ -215,7 +244,8 @@ def signal_to_frame(sig, n_per_frame, frame_step, window=None, stride_trick=True n_per_frame : int Number of samples each frame frame_step : int - Number of samples after the start of the previous frame that the next frame should begin. + Number of samples after the start of the previous + frame that the next frame should begin. window : numpy.ndarray or None A window array, e.g, stride_trick : bool @@ -243,8 +273,12 @@ def signal_to_frame(sig, n_per_frame, frame_step, window=None, stride_trick=True win = np.ones(n_per_frame) frames = rolling_window(padsignal, window=n_per_frame, step=frame_step) else: - indices = np.tile(np.arange(0, n_per_frame), (numframes, 1)) + np.tile( - np.arange(0, numframes * frame_step, frame_step), (n_per_frame, 1)).T + indices = ( + np.tile(np.arange(0, n_per_frame), (numframes, 1)) + + np.tile( + np.arange(0, numframes * frame_step, frame_step), (n_per_frame, 1) + ).T + ) indices = np.array(indices, dtype=np.int32) frames = padsignal[indices] if window is not None: @@ -273,14 +307,16 @@ def magspec(frames, NFFT): Each row will be the magnitude spectrum of the corresponding frame. """ if np.shape(frames)[1] > NFFT: - logging.warning(f'frame length {np.shape(frames)[1]} is greater than FFT size {NFFT}, ' - f'frame will be truncated. Increase NFFT to avoid.') + logging.warning( + f"frame length {np.shape(frames)[1]} is greater than FFT size {NFFT}, " + f"frame will be truncated. Increase NFFT to avoid." + ) complex_spec = np.fft.rfft(frames, NFFT) return np.abs(complex_spec) def powspec(frames, NFFT): - """Compute the power spectrum of each frame in frames, + """Compute the power spectrum of each frame in frames, first comeputer the magnitude spectrum Parameters @@ -293,7 +329,7 @@ def powspec(frames, NFFT): Returns ------- _ : numpy array - Power spectrum of the framed signal. + Power spectrum of the framed signal. Each row has the size of NFFT / 2 + 1 due to rfft. """ return 1.0 / NFFT * np.square(magspec(frames, NFFT)) diff --git a/pya/helper/visualization.py b/pya/helper/visualization.py index 92f1c5eb..028c860e 100644 --- a/pya/helper/visualization.py +++ b/pya/helper/visualization.py @@ -1,19 +1,35 @@ from __future__ import absolute_import -import matplotlib.pyplot as plt + import math -import numpy as np + import matplotlib.gridspec as grd +import matplotlib.pyplot as plt +import numpy as np from mpl_toolkits.axes_grid1 import make_axes_locatable +__all__ = ["basicplot", "gridplot"] -def basicplot(data: np.ndarray, ticks, channels, offset=0, scale=1, - cn=None, ax=None, typ='plot', cmap='inferno', - xlim=None, ylim=None, xlabel='', ylabel='', - show_bar=False, - **kwargs): + +def basicplot( + data: np.ndarray, + ticks, + channels, + offset=0, + scale=1, + cn=None, + ax=None, + typ="plot", + cmap="inferno", + xlim=None, + ylim=None, + xlabel="", + ylabel="", + show_bar=False, + **kwargs, +): """Basic version of the plot for pya, this can be directly used by Asig. Aspec/Astft/Amfcc will have different extra setting - and type. + and type. Parameters ---------- @@ -34,27 +50,32 @@ def basicplot(data: np.ndarray, ticks, channels, offset=0, scale=1, # offset is the spacing between channel, # scale is can shrink the signal just for visualization purpose. # Plot everything on top of each other. - if typ == 'plot': + if typ == "plot": p = ax.plot(ticks, data, **kwargs) # return p, ax - elif typ == 'spectrogram': + elif typ == "spectrogram": # ticks is (times, freqs) - p = ax.pcolormesh(ticks[0], ticks[1], data, - cmap=plt.get_cmap(cmap), **kwargs) - elif typ == 'mfcc': + p = ax.pcolormesh( + ticks[0], ticks[1], data, cmap=plt.get_cmap(cmap), **kwargs + ) + elif typ == "mfcc": p = ax.pcolormesh(data, cmap=plt.get_cmap(cmap), **kwargs) else: - if typ == 'plot': + if typ == "plot": for idx, val in enumerate(data.T): p = ax.plot(ticks, idx * offset + val * scale, **kwargs) ax.set_xlabel(xlabel) if cn: ax.text(0, (idx + 0.1) * offset, cn[idx]) - elif typ == 'spectrogram': + elif typ == "spectrogram": for idx in range(data.shape[1]): - p = ax.pcolormesh(ticks[0], idx * offset + scale * ticks[1], - data[:, idx, :], cmap=plt.get_cmap(cmap), - **kwargs) + p = ax.pcolormesh( + ticks[0], + idx * offset + scale * ticks[1], + data[:, idx, :], + cmap=plt.get_cmap(cmap), + **kwargs, + ) if cn: ax.text(0, (idx + 0.1) * offset, cn[idx]) ax.set_yticklabels([]) @@ -66,7 +87,7 @@ def basicplot(data: np.ndarray, ticks, channels, offset=0, scale=1, # Colorbar if show_bar: divider = make_axes_locatable(ax) - cax = divider.append_axes('right', size="2%", pad=0.03) + cax = divider.append_axes("right", size="2%", pad=0.03) _ = plt.colorbar(p, cax=cax) # Add return p, ax @@ -83,7 +104,7 @@ def gridplot(pya_objects, colwrap=1, cbar_ratio=0.04, figsize=None): # plot all 4 different pya objects in 1 column, amfcc and astft use pcolormesh so colorbar will # be displayed as well - gridplot([asig, amfcc, aspec, astft], colwrap=2, + gridplot([asig, amfcc, aspec, astft], colwrap=2, cbar_ratio=0.08, figsize=[10, 10]); Parameters @@ -105,7 +126,8 @@ def gridplot(pya_objects, colwrap=1, cbar_ratio=0.04, figsize=None): fig : plt.figure() The plt.figure() object """ - from .. import Asig, Amfcc, Astft, Aspec + from .. import Amfcc, Asig, Aspec, Astft + nplots = len(pya_objects) if colwrap > nplots: @@ -125,8 +147,7 @@ def gridplot(pya_objects, colwrap=1, cbar_ratio=0.04, figsize=None): wratio.append(odd_weight) if i % 2 else wratio.append(even_weight) fig = plt.figure(figsize=figsize, constrained_layout=True) - grid = grd.GridSpec(nrow, ncol, - figure=fig, width_ratios=wratio, wspace=0.01) + grid = grd.GridSpec(nrow, ncol, figure=fig, width_ratios=wratio, wspace=0.01) total_idx = ncol * nrow for i in range(total_idx): @@ -135,9 +156,13 @@ def gridplot(pya_objects, colwrap=1, cbar_ratio=0.04, figsize=None): if idx < nplots: ax = plt.subplot(grid[i]) # Title is object type + label - title = pya_objects[idx].__repr__().split('(')[0] + ': ' + pya_objects[idx].label + title = ( + pya_objects[idx].__repr__().split("(")[0] + + ": " + + pya_objects[idx].label + ) # Truncate if str too long - title = (title[:30] + "..." if len(title) > 30 else title) + title = title[:30] + "..." if len(title) > 30 else title ax.set_title(title) if isinstance(pya_objects[idx], Asig): pya_objects[idx].plot(ax=ax) diff --git a/pya/ugen.py b/pya/ugen.py index e7e18b1e..06772bac 100644 --- a/pya/ugen.py +++ b/pya/ugen.py @@ -1,14 +1,19 @@ +from typing import Optional, Union + import numpy as np from scipy import signal -from typing import Optional, Union from . import Asig from .helper import normalize def get_num_of_rows(dur: Optional[float], n_rows: Optional[int], sr: int): - """Return total number of samples. If dur is set, return dur*sr, if num_samples is set, return num_samples, - if both set, raise an AttributeError. Only use one of the two. + """ + Return total number of samples. + If dur is set, return dur*sr, + if num_samples is set, return num_samples, + if both set, raise an AttributeError. + Only use one of the two. """ if dur and n_rows is None: return int(dur * sr) @@ -17,7 +22,9 @@ def get_num_of_rows(dur: Optional[float], n_rows: Optional[int], sr: int): elif n_rows and dur is None: return int(n_rows) else: - raise AttributeError("Only use either dur or n_rows to specify the number of rows of the signal.") + raise AttributeError( + "Only use either dur or n_rows to specify the number of rows of the signal." + ) class Ugen(Asig): @@ -38,12 +45,21 @@ class Ugen(Asig): >>> # Make a white noise, another option is 'pink', at 44100Hz for 1second. >>> noi = Ugen().noise(type='white') """ + def __init__(self): pass - def sine(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, - dur: Optional[float] = None, n_rows: Optional[int] = None, - sr: int = 44100, channels: int = 1, cn: Optional[list] = None, label: str = "sine"): + def sine( + self, + freq: Union[int, float] = 440, + amp: Union[int, float] = 1.0, + dur: Optional[float] = None, + n_rows: Optional[int] = None, + sr: int = 44100, + channels: int = 1, + cn: Optional[list] = None, + label: str = "sine", + ): """Generate Sine signal Asig object. Parameters @@ -53,15 +69,18 @@ def sine(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, amp : int, float signal amplitude (Default value = 1.0) dur : float - duration in second. dur and n_rows only use one of the two. (Default value = 1.0) + duration in second. dur and n_rows only use one of the two. + (Default value = 1.0) n_rows : int - number of rows (samples). dur and n_rows only use one of the two(Default value = None) + number of rows (samples). dur and n_rows only use one of the two + (Default value = None) sr : int sampling rate (Default value = 44100) channels : int number of channels (Default value = 1) cn : list of string - channel names as a list. The size needs to match the number of channels (Default value = None) + channel names as a list. The size needs to match the number of channels + (Default value = None) label : string identifier of the object (Default value = "sine") @@ -70,15 +89,25 @@ def sine(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, Asig """ length = get_num_of_rows(dur, n_rows, sr) - sig = amp * np.sin(2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False)) + sig = amp * np.sin( + 2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False) + ) if channels > 1: sig = np.repeat(sig, channels) sig = sig.reshape((length, channels)) return Asig(sig, sr=sr, label=label, channels=channels, cn=cn) - def cos(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, - dur: Optional[float] = None, n_rows: Optional[int] = None, - sr: int = 44100, channels: int = 1, cn: Optional[list] = None, label: str = "cosine"): + def cos( + self, + freq: Union[int, float] = 440, + amp: Union[int, float] = 1.0, + dur: Optional[float] = None, + n_rows: Optional[int] = None, + sr: int = 44100, + channels: int = 1, + cn: Optional[list] = None, + label: str = "cosine", + ): """Generate Cosine signal Asig object. Parameters @@ -88,15 +117,18 @@ def cos(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, amp : int, float signal amplitude (Default value = 1.0) dur : int, float - duration in second. dur and num_rows only use one of the two. (Default value = 1.0) + duration in second. dur and num_rows only use one of the two. + (Default value = 1.0) n_rows : int - number of rows (samples). dur and num_rows only use one of the two(Default value = None) + number of rows (samples). dur and num_rows only use one of the two + (Default value = None) sr : int sampling rate (Default value = 44100) channels : int number of channels (Default value = 1) cn : list of string - channel names as a list. The size needs to match the number of channels (Default value = None) + channel names as a list. The size needs to match the number of channels + (Default value = None) label : string identifier of the object (Default value = "cosine") @@ -105,15 +137,27 @@ def cos(self, freq: Union[int, float] = 440, amp: Union[int, float] = 1.0, Asig """ length = get_num_of_rows(dur, n_rows, sr) - sig = amp * np.cos(2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False)) + sig = amp * np.cos( + 2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False) + ) if channels > 1: sig = np.repeat(sig, channels) sig = sig.reshape((length, channels)) return Asig(sig, sr=sr, label=label, channels=channels, cn=cn) - def square(self, freq=440, amp=1.0, dur=None, n_rows=None, - duty=0.5, sr=44100, sample_shift=0.5, - channels=1, cn=None, label="square"): + def square( + self, + freq=440, + amp=1.0, + dur=None, + n_rows=None, + duty=0.5, + sr=44100, + sample_shift=0.5, + channels=1, + cn=None, + label="square", + ): """Generate square wave signal Asig object. Parameters @@ -123,9 +167,11 @@ def square(self, freq=440, amp=1.0, dur=None, n_rows=None, amp : int, float signal amplitude (Default value = 1.0) dur : int, float - duration in second. dur and num_rows only use one of the two. (Default value = 1.0) + duration in second. dur and num_rows only use one of the two. + (Default value = 1.0) num_rows : int - number of row (samples). dur and num_rows only use one of the two(Default value = None) + number of row (samples). dur and num_rows only use one of the two + (Default value = None) duty : float duty cycle (Default value = 0.4) sr : int @@ -133,7 +179,8 @@ def square(self, freq=440, amp=1.0, dur=None, n_rows=None, channels : int number of channels (Default value = 1) cn : list of string - channel names as a list. The size needs to match the number of channels (Default value = None) + channel names as a list. The size needs to match the number of channels + (Default value = None) label : string identifier of the object (Default value = "square") @@ -143,15 +190,32 @@ def square(self, freq=440, amp=1.0, dur=None, n_rows=None, """ length = get_num_of_rows(dur, n_rows, sr) sig = amp * signal.square( - 2 * np.pi * freq * ((sample_shift / length) + np.linspace(0, length / sr, length, endpoint=False)), - duty=duty) + 2 + * np.pi + * freq + * ( + (sample_shift / length) + + np.linspace(0, length / sr, length, endpoint=False) + ), + duty=duty, + ) if channels > 1: sig = np.repeat(sig, channels) sig = sig.reshape((length, channels)) return Asig(sig, sr=sr, label=label, channels=channels, cn=cn) - def sawtooth(self, freq=440, amp=1.0, dur=None, n_rows=None, - width=1., sr=44100, channels=1, cn=None, label="sawtooth"): + def sawtooth( + self, + freq=440, + amp=1.0, + dur=None, + n_rows=None, + width=1.0, + sr=44100, + channels=1, + cn=None, + label="sawtooth", + ): """Generate sawtooth wave signal Asig object. Parameters @@ -161,9 +225,11 @@ def sawtooth(self, freq=440, amp=1.0, dur=None, n_rows=None, amp : int, float signal amplitude (Default value = 1.0) dur : int, float - duration in second. dur and num_rows only use one of the two. (Default value = 1.0) + duration in second. dur and num_rows only use one of the two. + (Default value = 1.0) num_rows : int - number of rows (samples). dur and num_rows only use one of the two(Default value = None) + number of rows (samples). dur and num_rows only use one of the two. + (Default value = None) width : float tooth width (Default value = 1.0) sr : int @@ -171,7 +237,8 @@ def sawtooth(self, freq=440, amp=1.0, dur=None, n_rows=None, channels : int number of channels (Default value = 1) cn : list of string - channel names as a list. The size needs to match the number of channels (Default value = None) + channel names as a list. The size needs to match the number of channels + (Default value = None) label : string identifier of the object (Default value = "sawtooth") @@ -180,33 +247,48 @@ def sawtooth(self, freq=440, amp=1.0, dur=None, n_rows=None, Asig """ length = get_num_of_rows(dur, n_rows, sr) - sig = amp * signal.sawtooth(2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False), - width=width) + sig = amp * signal.sawtooth( + 2 * np.pi * freq * np.linspace(0, length / sr, length, endpoint=False), + width=width, + ) if channels > 1: sig = np.repeat(sig, channels) sig = sig.reshape((length, channels)) return Asig(sig, sr=sr, label=label, channels=channels, cn=cn) - def noise(self, type="white", amp=1.0, dur=None, n_rows=None, - sr=44100, channels=1, cn=None, label="noise"): + def noise( + self, + type="white", + amp=1.0, + dur=None, + n_rows=None, + sr=44100, + channels=1, + cn=None, + label="noise", + ): """Generate noise signal Asig object. Parameters ---------- type : string - type of noise, currently available: 'white' and 'pink' (Default value = 'white') + type of noise, currently available: 'white' and 'pink' + (Default value = 'white') amp : int, float signal amplitude (Default value = 1.0) dur : int, float - duration in second. dur and num_rows only use one of the two. (Default value = 1.0) + duration in second. dur and num_rows only use one of the two. + (Default value = 1.0) num_rows : int - number of rows (samples). dur and num_rows only use one of the two(Default value = None) + number of rows (samples). dur and num_rows only use one of the two + (Default value = None) sr : int sampling rate (Default value = 44100) channels : int number of channels (Default value = 1) cn : list of string - channel names as a list. The size needs to match the number of channels (Default value = None) + channel names as a list. The size needs to match the number of channels + (Default value = None) label : string identifier of the object (Default value = "square") @@ -217,7 +299,7 @@ def noise(self, type="white", amp=1.0, dur=None, n_rows=None, length = get_num_of_rows(dur, n_rows, sr) # Question is that will be that be too slow.] if type == "white" or type == "white_noise": - sig = (np.random.rand(length) - 0.5) * 2. * amp + sig = (np.random.rand(length) - 0.5) * 2.0 * amp elif type == "pink" or type == "pink_noise": # Based on Paul Kellet's method diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 3f59cf94..00000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -pyamapping -scipy>=1.7.3 -matplotlib>=3.5.3 -soundfile>=0.13.0 diff --git a/requirements_doc.txt b/requirements_doc.txt deleted file mode 100644 index 5cfe83a1..00000000 --- a/requirements_doc.txt +++ /dev/null @@ -1,4 +0,0 @@ -Sphinx==7.2.6 -sphinx-autoapi==3.0.0 -sphinx-rtd-theme==2.0.0 -sphinx-mdinclude diff --git a/requirements_pyaudio.txt b/requirements_pyaudio.txt deleted file mode 100644 index 3d851244..00000000 --- a/requirements_pyaudio.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyaudio>=0.2.12; python_version >= '3.10' -pyaudio>=0.2.11; python_version < '3.10' diff --git a/requirements_remote.txt b/requirements_remote.txt deleted file mode 100644 index 3e82c3ce..00000000 --- a/requirements_remote.txt +++ /dev/null @@ -1,3 +0,0 @@ -notebook -websockets -ipywidgets diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100644 index 3cdea4b6..00000000 --- a/requirements_test.txt +++ /dev/null @@ -1,3 +0,0 @@ -pytest -pytest-cov -pycodestyle diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index df4ba59e..00000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[metadata] -description-file = README.md - -[check-manifest] -ignore = - .travis.yml - pya/notes.md diff --git a/setup.py b/setup.py deleted file mode 100644 index c6559caa..00000000 --- a/setup.py +++ /dev/null @@ -1,52 +0,0 @@ -from setuptools import setup, find_packages -import os -import codecs -from os.path import join - -project_root = os.path.dirname(os.path.abspath(__file__)) - -version = {} -REQUIRED_EXTRAS = {} -with open(join(project_root, 'pya/version.py')) as read_file: - exec(read_file.read(), version) - -with open(join(project_root, 'requirements.txt')) as read_file: - REQUIRED = read_file.read().splitlines() - -with open(join(project_root, 'requirements_remote.txt')) as read_file: - REQUIRED_EXTRAS['remote'] = read_file.read().splitlines() - -with open(join(project_root, 'requirements_pyaudio.txt')) as read_file: - REQUIRED_EXTRAS['pyaudio'] = read_file.read().splitlines() - -with open(join(project_root, 'requirements_test.txt')) as read_file: - REQUIRED_TEST = read_file.read().splitlines() - -with codecs.open(join(project_root, 'README.md'), 'r', 'utf-8') as f: - long_description = ''.join(f.readlines()) - -setup( - name='pya', - version=version['__version__'], - description='Python audio coding classes - for dsp and sonification', - long_description=long_description, - long_description_content_type="text/markdown", - license='MIT', - packages=find_packages(exclude=["tests"]), - install_requires=REQUIRED, - extras_require=REQUIRED_EXTRAS, - tests_require=REQUIRED_TEST, - author='Thomas Hermann', - author_email='thermann@techfak.uni-bielefeld.de', - keywords=['sonification, sound synthesis'], - url='https://github.com/interactive-sonification/pya', - classifiers=[ - "Programming Language :: Python :: 3", - "Development Status :: 4 - Beta", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - "Topic :: Multimedia :: Sound/Audio", - "Topic :: Multimedia :: Sound/Audio :: Analysis", - "Topic :: Multimedia :: Sound/Audio :: Sound Synthesis" - ], -) diff --git a/tests/test_amfcc.py b/tests/test_amfcc.py index 06606a46..424f6691 100644 --- a/tests/test_amfcc.py +++ b/tests/test_amfcc.py @@ -1,8 +1,10 @@ # from pya import Amfcc -from pya import Asig, Ugen, Amfcc +import warnings from unittest import TestCase + import numpy as np -import warnings + +from pya import Amfcc, Ugen class TestAmfcc(TestCase): @@ -16,7 +18,7 @@ def tearDown(self): def test_construct(self): # If x is asig, it will ignore sr but use x.sr instead. amfcc = Amfcc(self.test_asig, sr=45687) - self.assertEqual(amfcc.sr, 8000, msg='sr does not match.') + self.assertEqual(amfcc.sr, 8000, msg="sr does not match.") # if x is ndarray and sr is not given with self.assertRaises(AttributeError): @@ -37,11 +39,11 @@ def test_get_attributes(self): def test_hopsize_greater_than_npframe(self): with warnings.catch_warnings(record=True): - amfcc = Amfcc(self.test_asig, hopsize=100, n_per_frame=50) + _ = Amfcc(self.test_asig, hopsize=100, n_per_frame=50) def test_nfft_not_pow2(self): with warnings.catch_warnings(record=True): - amfcc = Amfcc(self.test_asig, nfft=23) + _ = Amfcc(self.test_asig, nfft=23) def test_nowindowing(self): amfcc = Amfcc(self.test_asig, window=False) @@ -49,8 +51,12 @@ def test_nowindowing(self): self.assertTrue(np.array_equal(result, amfcc.window)) def test_preemphasis(self): - self.assertTrue(np.array_equal(np.array([0., 1., 1.5, 2., 2.5]), - Amfcc.preemphasis(np.arange(5), coeff=0.5))) + self.assertTrue( + np.array_equal( + np.array([0.0, 1.0, 1.5, 2.0, 2.5]), + Amfcc.preemphasis(np.arange(5), coeff=0.5), + ) + ) def test_melfb(self): fb = Amfcc.mel_filterbanks(8000) # Using default @@ -68,4 +74,4 @@ def test_plot_with_multichannel(self): asig = Ugen().sine(channels=2) amfcc = asig.to_mfcc() with warnings.catch_warnings(record=True): - amfcc.plot() \ No newline at end of file + amfcc.plot() diff --git a/tests/test_arecorder.py b/tests/test_arecorder.py index 27718dbc..9298f81b 100644 --- a/tests/test_arecorder.py +++ b/tests/test_arecorder.py @@ -1,52 +1,56 @@ # Test arecorder class. -import time -from pya import Arecorder, Aserver, find_device +import importlib.util from unittest import TestCase, mock -import pytest + import numpy as np +import pytest -try: - import pyaudio - has_pyaudio = True -except ImportError: - has_pyaudio = False - - -FAKE_INPUT = {'index': 0, - 'structVersion': 2, - 'name': 'Mock Input', - 'hostApi': 0, - 'maxInputChannels': 1, - 'maxOutputChannels': 0, - 'defaultLowInputLatency': 0.04852607709750567, - 'defaultLowOutputLatency': 0.01, - 'defaultHighInputLatency': 0.05868480725623583, - 'defaultHighOutputLatency': 0.1, - 'defaultSampleRate': 44100.0} - -FAKE_OUTPUT = {'index': 1, - 'structVersion': 2, - 'name': 'Mock Output', - 'hostApi': 0, - 'maxInputChannels': 2, - 'maxOutputChannels': 0, - 'defaultLowInputLatency': 0.01, - 'defaultLowOutputLatency': 0.02, - 'defaultHighInputLatency': 0.03, - 'defaultHighOutputLatency': 0.04, - 'defaultSampleRate': 44100.0} - -FAKE_AUDIO_INTERFACE = {'index': 2, - 'structVersion': 2, - 'name': 'Mock Audio Interface', - 'hostApi': 0, - 'maxInputChannels': 14, - 'maxOutputChannels': 14, - 'defaultLowInputLatency': 0.01, - 'defaultLowOutputLatency': 0.02, - 'defaultHighInputLatency': 0.03, - 'defaultHighOutputLatency': 0.04, - 'defaultSampleRate': 48000.0} +from pya import Arecorder + +has_pyaudio = importlib.util.find_spec("pyaudio") is not None + + +FAKE_INPUT = { + "index": 0, + "structVersion": 2, + "name": "Mock Input", + "hostApi": 0, + "maxInputChannels": 1, + "maxOutputChannels": 0, + "defaultLowInputLatency": 0.04852607709750567, + "defaultLowOutputLatency": 0.01, + "defaultHighInputLatency": 0.05868480725623583, + "defaultHighOutputLatency": 0.1, + "defaultSampleRate": 44100.0, +} + +FAKE_OUTPUT = { + "index": 1, + "structVersion": 2, + "name": "Mock Output", + "hostApi": 0, + "maxInputChannels": 2, + "maxOutputChannels": 0, + "defaultLowInputLatency": 0.01, + "defaultLowOutputLatency": 0.02, + "defaultHighInputLatency": 0.03, + "defaultHighOutputLatency": 0.04, + "defaultSampleRate": 44100.0, +} + +FAKE_AUDIO_INTERFACE = { + "index": 2, + "structVersion": 2, + "name": "Mock Audio Interface", + "hostApi": 0, + "maxInputChannels": 14, + "maxOutputChannels": 14, + "defaultLowInputLatency": 0.01, + "defaultLowOutputLatency": 0.02, + "defaultHighInputLatency": 0.03, + "defaultHighOutputLatency": 0.04, + "defaultSampleRate": 48000.0, +} class MockRecorder(mock.MagicMock): @@ -74,14 +78,17 @@ def get_default_output_device_info(self): class MockBackend: """Mock audio backend for testing""" + def __init__(self, **kwargs): - self.dummy_devices = [{ - 'index': 0, - 'maxInputChannels': 2, - 'maxOutputChannels': 2, - 'defaultSampleRate': 44100 - }] - self.dtype = 'float32' + self.dummy_devices = [ + { + "index": 0, + "maxInputChannels": 2, + "maxOutputChannels": 2, + "defaultSampleRate": 44100, + } + ] + self.dtype = "float32" self.range = 1.0 self.bs = 256 @@ -106,6 +113,7 @@ def terminate(self): class MockStream: """Mock audio stream for testing""" + def __init__(self): self._active = True @@ -148,15 +156,14 @@ class TestArecorder(TestArecorderBase): class TestMockArecorder(TestCase): - @pytest.mark.skipif(not has_pyaudio, reason="requires pyaudio to be installed") def test_mock_arecorder(self): mock_recorder = MockRecorder() - with mock.patch('pyaudio.PyAudio', return_value=mock_recorder): + with mock.patch("pyaudio.PyAudio", return_value=mock_recorder): ar = Arecorder() self.assertEqual( - "Mock Input", - ar.backend.get_default_input_device_info()['name']) + "Mock Input", ar.backend.get_default_input_device_info()["name"] + ) ar.boot() self.assertTrue(mock_recorder.open.called) ar.record() @@ -168,6 +175,6 @@ def test_mock_arecorder(self): # ar.stop() # Dont know how to mock the stop. # TODO How to mock a result. - # Mock multiple input devices. + # Mock multiple input devices. ar.set_device(2, reboot=True) # Set to multiple device self.assertEqual(ar.max_in_chn, 14) diff --git a/tests/test_aserver.py b/tests/test_aserver.py index 1c6a9f60..bd5f24a9 100644 --- a/tests/test_aserver.py +++ b/tests/test_aserver.py @@ -1,16 +1,19 @@ +import time from unittest import TestCase -from pya import * + import numpy as np -import time +from pya.aserver import Aserver +from pya.asig import Asig +from pya.backend.Dummy import DummyBackend -class TestAserver(TestCase): +class TestAserver(TestCase): def setUp(self) -> None: self.backend = DummyBackend() self.sig = np.sin(2 * np.pi * 440 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.max_channels = self.backend.dummy_devices[0]['maxOutputChannels'] + self.max_channels = self.backend.dummy_devices[0]["maxOutputChannels"] def test_default_server(self): Aserver.startup_default_server(backend=self.backend, bs=512, channels=4) @@ -38,7 +41,10 @@ def test_custom_channels(self): self.assertFalse(s.is_active) def test_invalid_channels(self): - """Raise an exception if booting with channels greater than max channels of the device. Dummy has 10""" + """ + Raise an exception if booting with channels greater than max channels of the + device. Dummy has 10 + """ ch = 100 s = Aserver(device=0, channels=ch, backend=self.backend) with self.assertRaises(OSError): @@ -114,9 +120,10 @@ def test_quit_not_booted(self): def test_incompatible_backend(self): s = Aserver(backend=self.backend) - sig = np.sin(2 * np.pi * 440 * np.linspace(0, 1, 44100) * np.iinfo(np.int16).max).astype(np.int16) + sig = np.sin( + 2 * np.pi * 440 * np.linspace(0, 1, 44100) * np.iinfo(np.int16).max + ).astype(np.int16) asine = Asig(sig, sr=44100) s.boot() asine.play(server=s) s.quit() - diff --git a/tests/test_asig.py b/tests/test_asig.py index 2f5643ea..100aedb4 100644 --- a/tests/test_asig.py +++ b/tests/test_asig.py @@ -1,22 +1,23 @@ +from math import inf from unittest import TestCase, mock -from unittest.mock import patch -from pya import Asig + import numpy as np -from math import inf -import os + +from pya import Asig class TestAsig(TestCase): """Unit Tests for Asig""" + def setUp(self): self.sig = np.sin(2 * np.pi * 100 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=['sine']) + self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=["sine"]) self.sig2ch = np.repeat(self.sig, 2).reshape((44100, 2)) - self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", cn=['l', 'r']) + self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", cn=["l", "r"]) self.sig16ch = np.repeat(self.sig, 16).reshape((44100, 16)) self.asine16ch = Asig(self.sig16ch, sr=44100, label="test_sine_16ch") - self.asigconst = Asig(1.0, sr=100, label="constant signal", cn=['0']) + 0.5 + self.asigconst = Asig(1.0, sr=100, label="constant signal", cn=["0"]) + 0.5 def tearDown(self): pass @@ -30,17 +31,22 @@ def test_asig_constructor(self): def test_asig_plot(self): self.asine.plot() - self.astereo.plot(offset=1., scale=0.5) + self.astereo.plot(offset=1.0, scale=0.5) def test_duration(self): - self.assertEqual(self.asine.get_duration(), 1.) - get_time = self.asine.get_times() - self.assertTrue(np.array_equal(np.linspace(0, - (self.asine.samples - 1) / self.asine.sr, - self.asine.samples), self.asine.get_times())) + self.assertEqual(self.asine.get_duration(), 1.0) + _ = self.asine.get_times() + self.assertTrue( + np.array_equal( + np.linspace( + 0, (self.asine.samples - 1) / self.asine.sr, self.asine.samples + ), + self.asine.get_times(), + ) + ) def test_dur_property(self): - self.assertEqual(self.asine.dur, 1.) + self.assertEqual(self.asine.dur, 1.0) def test_fader(self): result = self.asine.fade_in(dur=0.2) @@ -59,19 +65,19 @@ def test_channels(self): self.assertEqual(4, as1.channels) def test_cn(self): - self.assertEqual(self.astereo.cn, ['l', 'r']) - self.astereo.cn = ['left', 'right'] # Test changing the cn - self.assertEqual(self.astereo.cn, ['left', 'right']) + self.assertEqual(self.astereo.cn, ["l", "r"]) + self.astereo.cn = ["left", "right"] # Test changing the cn + self.assertEqual(self.astereo.cn, ["left", "right"]) with self.assertRaises(ValueError): - self.astereo.cn = ['left', 'right', 'middle'] + self.astereo.cn = ["left", "right", "middle"] with self.assertRaises(TypeError): # If list is not string only, TypeError self.astereo.cn = ["b", 10] with self.assertRaises(TypeError): # If list is not string only, TypeError - asig = Asig(1000, channels=3, cn=3) + _ = Asig(1000, channels=3, cn=3) - self.assertEqual(self.astereo.cn, ['left', 'right']) + self.assertEqual(self.astereo.cn, ["left", "right"]) def test_remove_DC(self): result = self.asigconst.remove_DC() @@ -79,11 +85,11 @@ def test_remove_DC(self): result = Asig(100, channels=2) + 0.25 result[:, 1] = 0.5 self.assertEqual([0.25, 0.5], list(np.max(result.sig, 0))) - self.assertEqual([0., 0.], list(result.remove_DC().sig.max(axis=0))) + self.assertEqual([0.0, 0.0], list(result.remove_DC().sig.max(axis=0))) def test_norm(self): result = self.astereo.norm() - result = self.astereo.norm(norm=1., dcflag=True) + result = self.astereo.norm(norm=1.0, dcflag=True) self.assertEqual(1, np.max(result.sig)) result = self.astereo.norm(norm=2, dcflag=True) self.assertEqual(2, np.max(result.sig)) @@ -96,24 +102,28 @@ def test_gain(self): current_max_amplitude = np.max(self.astereo.sig) result = self.astereo.gain() # by default amp=1. nothing change. - self.assertEqual(current_max_amplitude, np.max(result.sig), "gain() should not change anything") + self.assertEqual( + current_max_amplitude, + np.max(result.sig), + "gain() should not change anything", + ) - result = self.astereo.gain(amp=2.) + result = self.astereo.gain(amp=2.0) self.assertEqual(2, np.max(result.sig)) - result = self.astereo.gain(db=3.) + result = self.astereo.gain(db=3.0) with self.assertRaises(AttributeError): - _ = self.astereo.gain(amp=1, db=3.) + _ = self.astereo.gain(amp=1, db=3.0) - result = self.astereo.gain(amp=0.) + result = self.astereo.gain(amp=0.0) self.assertEqual(0, np.max(result.sig), "amp 0 should result in 0") def test_rms(self): - result = self.asine16ch.rms() + _ = self.asine16ch.rms() def test_plot(self): self.asine.plot(xlim=(0, 1), ylim=(-1, 1)) - self.asine.plot(fn='db') + self.asine.plot(fn="db") self.astereo.plot(offset=1) self.asine16ch.plot(offset=1, scale=0.5) @@ -126,8 +136,10 @@ def test_add(self): self.assertIsInstance(adding, Asig) self.assertTrue(np.array_equal([10, 12, 14, 16], adding.sig)) - # asig + ndarray actually we don't encourage that. Because of sampling rate may differ - # also because ndarray + asig works. so it is strongly against adding asig with ndarray. + # asig + ndarray actually we don't encourage that. + # Because of sampling rate may differ + # also because ndarray + asig works. + # so it is strongly against adding asig with ndarray. # just maker another asig and add both together. adding = a + b0 self.assertIsInstance(adding, Asig) @@ -162,14 +174,16 @@ def test_mul(self): # Testing multiplication beween asig and asig, or asig with a scalar. a = Asig(np.arange(4), sr=2) a2 = Asig(np.arange(8), sr=2) - a4ch = Asig(np.ones((4, 4)), sr=2) - a4ch2 = Asig(np.ones((8, 4)), sr=2) + _ = Asig(np.ones((4, 4)), sr=2) + _ = Asig(np.ones((8, 4)), sr=2) self.assertTrue(np.array_equal([0, 4, 8, 12], (a * 4).sig)) self.assertTrue(np.array_equal([0, 4, 8, 12], (4 * a).sig)) self.assertTrue(np.array_equal([0, 1, 4, 9], (a * a).sig)) self.assertTrue(np.array_equal([0, 1, 4, 9], (a.bound * a2).sig)) - self.assertTrue(np.array_equal([0., 1., 4., 9., 4., 5., 6., 7.], (a.x * a2).sig)) + self.assertTrue( + np.array_equal([0.0, 1.0, 4.0, 9.0, 4.0, 5.0, 6.0, 7.0], (a.x * a2).sig) + ) def test_subtract(self): a = Asig(np.arange(4), sr=2) @@ -182,16 +196,16 @@ def test_subtract(self): b = Asig(np.ones(6), sr=2) self.assertTrue(np.array_equal([-1, 0, 1, 2], (a.bound - b).sig)) with self.assertRaises(ValueError): - adding = a - b + _ = a - b self.assertTrue(np.array_equal([-1, 0, 1, 2, -1, -1], (a.x - b).sig)) def test_division(self): # Testing multiplication beween asig and asig, or asig with a scalar. # a = Asig(np.arange(4), sr=2) - a2 = Asig(np.arange(8), sr=2) + _ = Asig(np.arange(8), sr=2) a4ch = Asig(np.ones((4, 4)), sr=2) - a4ch2 = Asig(np.ones((8, 4)), sr=2) + _ = Asig(np.ones((8, 4)), sr=2) self.assertTrue(np.array_equal([0, 0.25, 0.5, 0.75], (a / 4).sig)) self.assertTrue(np.allclose([inf, 4, 2, 1.33333333], (4 / a).sig)) @@ -199,37 +213,75 @@ def test_division(self): def test_windowing(self): asig = Asig(np.ones(10), sr=2) - asig_windowed = asig.window_op(nperseg=2, stride=1, - win='hann', fn='rms', pad='mirror') - self.assertTrue(np.allclose([1., 0.70710677, 0.70710677, 0.70710677, - 0.70710677, 0.70710677, 0.70710677, - 0.70710677, 0.70710677, 1.], - asig_windowed.sig)) + asig_windowed = asig.window_op( + nperseg=2, stride=1, win="hann", fn="rms", pad="mirror" + ) + self.assertTrue( + np.allclose( + [ + 1.0, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 1.0, + ], + asig_windowed.sig, + ) + ) asig2ch = Asig(np.ones((10, 2)), sr=2) - asig2ch.window_op(nperseg=2, stride=1, win='hann', fn='rms', pad='mirror') - a = [1., 0.70710677, 0.70710677, 0.70710677, - 0.70710677, 0.70710677, 0.70710677, - 0.70710677, 0.70710677, 1.] - res = np.array([a, a]).T + asig2ch.window_op(nperseg=2, stride=1, win="hann", fn="rms", pad="mirror") + a = [ + 1.0, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 0.70710677, + 1.0, + ] + _ = np.array([a, a]).T self.assertTrue(np.allclose(a, asig_windowed.sig)) def test_convolve(self): - # Do self autocorrelatin, the middle point should always have a corr val near 1.0 + # Do self autocorrelation, the middle point + # should always have a corr val near 1.0 test = Asig(np.sin(np.arange(0, 21)), sr=21) - result = test.convolve(test.sig[::-1], mode='same') + result = test.convolve(test.sig[::-1], mode="same") # The middle point should have high corr - self.assertTrue(result.sig[10] > 0.99, msg="middle point of a self correlation should always has high corr val.") + self.assertTrue( + result.sig[10] > 0.99, + msg="middle point of a self correlation should always has high corr val.", + ) # Test different modes - self.assertEqual(result.samples, test.samples, msg="'same' mode should result in the same size") - result = test.convolve(test.sig[::-1], mode='full') - - self.assertEqual(result.samples, test.samples * 2 - 1, msg="full mode should have 2x - 1 samples.") + self.assertEqual( + result.samples, + test.samples, + msg="'same' mode should result in the same size", + ) + result = test.convolve(test.sig[::-1], mode="full") + + self.assertEqual( + result.samples, + test.samples * 2 - 1, + msg="full mode should have 2x - 1 samples.", + ) # Test input type ir = Asig(test.sig[::-1], sr=21) - result = test.convolve(ir, mode='same') - self.assertTrue(result.sig[10] > 0.99, msg="middle point of a self correlation should always has high corr val.") + result = test.convolve(ir, mode="same") + self.assertTrue( + result.sig[10] > 0.99, + msg="middle point of a self correlation should always has high corr val.", + ) with self.assertRaises(TypeError, msg="ins can only be array or Asig"): result = test.convolve("string input") @@ -256,7 +308,6 @@ def test_append(self): # # At the top I import Asig by: from pya import Asig @mock.patch("pya.asig.wavfile") def test_save_wavefile(self, mock_wavfile): - test = Asig(np.array([0, 0.2, 0.4, 0.6, 0.8, 1.0]), sr=6) test.save_wavfile(fname="mock save") mock_wavfile.write.assert_called_once() diff --git a/tests/test_aspec.py b/tests/test_aspec.py index a11c9d68..4de7276e 100644 --- a/tests/test_aspec.py +++ b/tests/test_aspec.py @@ -1,14 +1,13 @@ -from unittest import TestCase -from pya import Ugen, Aspec, Asig import warnings -import numpy as np +from unittest import TestCase +from pya import Aspec, Ugen -class TestAspec(TestCase): +class TestAspec(TestCase): def setUp(self): self.asig = Ugen().sine() - self.asig2 = Ugen().sine(channels=2, cn=['a', 'b']) + self.asig2 = Ugen().sine(channels=2, cn=["a", "b"]) self.asig_no_name = Ugen().sine(channels=3) def tearDown(self): @@ -21,18 +20,18 @@ def test_constructor(self): self.assertEqual(aspec.cn, self.asig2.cn) # The input can also be just an numpy array sig = Ugen().square().sig - aspec = Aspec(sig, sr=400, label='square', cn=['a']) + aspec = Aspec(sig, sr=400, label="square", cn=["a"]) self.assertEqual(aspec.sr, 400) - self.assertEqual(aspec.label, 'square') - self.assertEqual(aspec.cn, ['a']) + self.assertEqual(aspec.label, "square") + self.assertEqual(aspec.cn, ["a"]) with self.assertRaises(TypeError): _ = Aspec(x=3) print(aspec) def test_plot(self): self.asig.to_spec().plot() - self.asig.to_spec().plot(xlim=(0, 0.5), ylim=(0., 1.0)) + self.asig.to_spec().plot(xlim=(0, 0.5), ylim=(0.0, 1.0)) def test_cn_conflict(self): with warnings.catch_warnings(record=True): - _ = Aspec(self.asig, cn=['jf', 'dj']) + _ = Aspec(self.asig, cn=["jf", "dj"]) diff --git a/tests/test_astft.py b/tests/test_astft.py index 5b88538d..3980e996 100644 --- a/tests/test_astft.py +++ b/tests/test_astft.py @@ -1,17 +1,18 @@ from unittest import TestCase, mock -from pya import Ugen, Astft + import numpy as np +from pya import Astft, Ugen + class MockPlot(mock.MagicMock): pass class TestAstft(TestCase): - def setUp(self): self.asig = Ugen().sine() - self.asig2 = Ugen().sine(channels=2, cn=['a', 'b']) + self.asig2 = Ugen().sine(channels=2, cn=["a", "b"]) self.asig_no_name = Ugen().sine(channels=3) def tearDown(self): @@ -22,15 +23,15 @@ def test_input_as_asig(self): self.assertEqual(astft.sr, 44100) astft = self.asig.to_stft(sr=2000) self.assertEqual(astft.sr, 2000) - signal = self.asig2.sig + _ = self.asig2.sig def test_wrong_input_type(self): with self.assertRaises(TypeError): - asig = Astft(x=3, sr=500) + _ = Astft(x=3, sr=500) def test_multichannel_asig(self): - # Test conversion of a multi channel asig's astft. - asine = Ugen().sawtooth(channels=3, cn=['a', 'b', 'c']) + # Test conversion of a multi channel asig's astft. + asine = Ugen().sawtooth(channels=3, cn=["a", "b", "c"]) astft = asine.to_stft() self.assertEqual(astft.channels, 3) self.assertEqual(len(astft.cn), 3) @@ -46,7 +47,7 @@ def test_input_as_stft(self): noise = np.random.normal(scale=np.sqrt(noise_power), size=time.shape) noise *= np.exp(-time / 5) x = carrier + noise - astft = Astft(x, sr, label="test") + _ = Astft(x, sr, label="test") def test_plot(self): - self.asig.to_stft().plot() \ No newline at end of file + self.asig.to_stft().plot() diff --git a/tests/test_backend.py b/tests/test_backend.py index 594f661a..ef07db7b 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -1,26 +1,21 @@ -from .helpers import wait -from .test_play import TestPlayBase -from .test_arecorder import TestArecorderBase -from pya import Arecorder from pya.backend import DummyBackend -from unittest import TestCase, skipUnless + +from .test_arecorder import TestArecorderBase +from .test_play import TestPlayBase try: - from pya.backend import JupyterBackend has_j_backend = True -except: +except Exception: has_j_backend = False # check if we have an output device class TestDummyBackendPlay(TestPlayBase): - __test__ = True backend = DummyBackend() class TestDummyBackendRecord(TestArecorderBase): - __test__ = True backend = DummyBackend() diff --git a/tests/test_class_transformation.py b/tests/test_class_transformation.py index 86897240..5159e04d 100644 --- a/tests/test_class_transformation.py +++ b/tests/test_class_transformation.py @@ -1,10 +1,10 @@ -# Test change between asig, astft and aspec. -from pya import Asig, Aspec, Astft, Ugen +# Test change between asig, astft and aspec. from unittest import TestCase +from pya import Asig, Aspec, Astft, Ugen + class TestClassTransform(TestCase): - def setUp(self): pass @@ -12,7 +12,7 @@ def tearDown(self): pass def test_asig_aspec(self): - # Create a signale with 3 sine waves and gaps inbetween, + # Create a signale with 3 sine waves and gaps inbetween, # So that it will finds 3 events a = Ugen().sine() a_spec = a.to_spec() @@ -27,4 +27,4 @@ def test_asig_astf(self): a_sig_from_stft = a_stft.to_sig() self.assertIsInstance(a, Asig) self.assertIsInstance(a_stft, Astft) - self.assertIsInstance(a_sig_from_stft, Asig) \ No newline at end of file + self.assertIsInstance(a_sig_from_stft, Asig) diff --git a/tests/test_codestyle.py b/tests/test_codestyle.py deleted file mode 100644 index 4c5bb354..00000000 --- a/tests/test_codestyle.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest -import pycodestyle - - -class TestCodeFormat(unittest.TestCase): - - def test_conformance(self): - """Test that we conform to PEP-8.""" - # E731 ignores lamda, W291 trailing whitespace - # W391 blank line at end of file - # W292 no newline at end of file - # E722 bare except - style = pycodestyle.StyleGuide(quiet=False, - ignore=['E501', 'E731', 'W291', 'W504', - 'W391', 'W292', 'E722', 'E402']) - # style.input_dir('../../pya') - style.input_dir('./pya') - style.input_dir('./tests') - result = style.check_files() - self.assertEqual(0, result.total_errors, - "Found code style errors (and warnings).") diff --git a/tests/test_file_loader_codec.py b/tests/test_file_loader_codec.py index 92fedaf5..83b6d36c 100644 --- a/tests/test_file_loader_codec.py +++ b/tests/test_file_loader_codec.py @@ -1,11 +1,13 @@ -from unittest import TestCase import os +from unittest import TestCase + import numpy as np + from pya.helper.codec import ( - audio_read, - SoundFileAudioFile, FFmpegAudioFile, + SoundFileAudioFile, UnsupportedError, + audio_read, ) @@ -96,7 +98,7 @@ def test_data_reading(self): # TODO: Add a flac file for testing # def test_high_resolution(self): # """Test handling of high resolution audio (24-bit, high sample rate)""" - # with audio_read(self.test_files['flac']) as audio: # Assuming 24-bit/96kHz FLAC + # with audio_read(self.test_files['flac']) as audio:# Assuming 24-bit/96kHz FLAC # data = next(audio.read_data()) # self.assertTrue(np.max(np.abs(data)) <= 1.0) # Check normalization # self.assertEqual(np.float32, data.dtype) diff --git a/tests/test_find_events.py b/tests/test_find_events.py index 6d59b58a..9140f762 100644 --- a/tests/test_find_events.py +++ b/tests/test_find_events.py @@ -1,9 +1,9 @@ -from pya import Asig, Ugen from unittest import TestCase +from pya import Asig, Ugen + class TestFindEvents(TestCase): - def setUp(self): pass @@ -11,13 +11,13 @@ def tearDown(self): pass def test_events(self): - # Create a signale with 3 sine waves and + # Create a signale with 3 sine waves and # gaps inbetween, So that it will finds 3 events""" a = Ugen().sine() - a.x[a.samples:] = Asig(0.2) - a.x[a.samples:] = Ugen().sine(freq=200) - a.x[a.samples:] = Asig(0.2) - a.x[a.samples:] = Ugen().sine(freq=20) - a.x[a.samples:] = Asig(0.2) + a.x[a.samples :] = Asig(0.2) + a.x[a.samples :] = Ugen().sine(freq=200) + a.x[a.samples :] = Asig(0.2) + a.x[a.samples :] = Ugen().sine(freq=20) + a.x[a.samples :] = Asig(0.2) a.find_events(sil_thr=-30, evt_min_dur=0.2, sil_min_dur=0.04) - self.assertEqual(3, a._['events'].shape[0]) + self.assertEqual(3, a._["events"].shape[0]) diff --git a/tests/test_getitem.py b/tests/test_getitem.py index 75626c86..c0289146 100644 --- a/tests/test_getitem.py +++ b/tests/test_getitem.py @@ -1,19 +1,23 @@ from unittest import TestCase -from pya import * + import numpy as np + +from pya.asig import Asig + # import logging # logging.basicConfig(level=logging.DEBUG) class TestSlicing(TestCase): - def setUp(self): self.sig = np.sin(2 * np.pi * 100 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.sig4 = np.sin(2 * np.pi * 100 * np.linspace(0, 4, 44100 * 4)) # 4second sine + self.sig4 = np.sin( + 2 * np.pi * 100 * np.linspace(0, 4, 44100 * 4) + ) # 4second sine self.asine4 = Asig(self.sig4, sr=44100, label="test_sine") self.sig2ch = np.repeat(self.sig, 2).reshape((44100, 2)) - self.astereo = Asig(self.sig2ch, sr=44100, label="stereo", cn=['l', 'r']) + self.astereo = Asig(self.sig2ch, sr=44100, label="stereo", cn=["l", "r"]) def tearDown(self): pass @@ -55,7 +59,7 @@ def test_timeSlicing(self): # Check negative time work""" result2 = self.asine4[{1: -1}] # Play from 1s. to the last 1.s - expect2 = self.asine4[44100: -44100] + expect2 = self.asine4[44100:-44100] self.assertEqual(expect2, result2) def test_tuple(self): @@ -64,32 +68,36 @@ def test_tuple(self): expected_sig = self.astereo.sig[0:44100:2, 0] self.assertTrue(np.array_equal(result.sig, expected_sig)) - result = self.astereo[0:10:2, ['l']] + result = self.astereo[0:10:2, ["l"]] expected_sig = self.astereo.sig[0:10:2, 0] - self.assertTrue(np.array_equal(result.sig, expected_sig)) # Check if signal equal - self.assertEqual(result.cn, ['l']) # Check whether the new column name is correct + self.assertTrue( + np.array_equal(result.sig, expected_sig) + ) # Check if signal equal + self.assertEqual( + result.cn, ["l"] + ) # Check whether the new column name is correct # channel name slice as list. # ("both channels using col_name") - result = self.astereo[0:44100:2, ['l', 'r']] + result = self.astereo[0:44100:2, ["l", "r"]] expected_sig = self.astereo.sig[0:44100:2, :] self.assertTrue(np.array_equal(result.sig, expected_sig)) # Bool slice # ("bool list channel selection") - # This is a special case for scling as numpy return (n, 1) rather than (n,) if we use - # bool list to single out a channel. + # This is a special case for scling as numpy return (n, 1) rather than (n,) + # if we use bool list to single out a channel. result = self.astereo[360:368, [False, True]] expected_sig = self.astereo.sig[360:368:1, [False, True]] self.assertTrue(np.array_equal(result.sig, expected_sig)) # time slicing result = self.astereo[{1: -1}, 0] # Play from 1s. to the last 1.s - expect = self.astereo[44100: -44100, 0] + expect = self.astereo[44100:-44100, 0] self.assertEqual(expect, result) # time slicing # ("time slicing.") - time_range = {1: -1} # first to last second. - result = self.astereo[time_range, :] # Play from 1s. to the last 1.s - expect = self.astereo[44100: -44100, :] + time_range = {1: -1} # first to last second. + result = self.astereo[time_range, :] # Play from 1s. to the last 1.s + expect = self.astereo[44100:-44100, :] self.assertEqual(expect, result) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 41224a90..9e61b88c 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,34 +1,45 @@ from unittest import TestCase -from pya import Asig, Ugen -from pya.helper import spectrum, padding, next_pow2, is_pow2 -from pya.helper import signal_to_frame, magspec, powspec import numpy as np +from pya import Asig, Ugen +from pya.helper import ( + is_pow2, + magspec, + next_pow2, + padding, + powspec, + signal_to_frame, + spectrum, +) + class TestHelpers(TestCase): - """Test helper functions - """ + """Test helper functions""" def setUp(self): self.sig = np.sin(2 * np.pi * 100 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.asineWithName = Asig(self.sig, sr=44100, - label="test_sine", cn=['sine']) + self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=["sine"]) self.sig2ch = np.repeat(self.sig, 2).reshape((44100, 2)) - self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", - cn=['l', 'r']) + self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", cn=["l", "r"]) self.sig16ch = np.repeat(self.sig, 16).reshape((44100, 16)) - self.asine16ch = Asig(self.sig16ch, sr=44100, - label="test_sine_16ch") + self.asine16ch = Asig(self.sig16ch, sr=44100, label="test_sine_16ch") def tearDown(self): pass def test_spectrum(self): # Not tested expected outcome yet. - frq, Y = spectrum(self.asine.sig, self.asine.samples, self.asine.channels, self.asine.sr) - frqs, Ys = spectrum(self.astereo.sig, self.astereo.samples, self.astereo.channels, self.astereo.sr) + frq, Y = spectrum( + self.asine.sig, self.asine.samples, self.asine.channels, self.asine.sr + ) + frqs, Ys = spectrum( + self.astereo.sig, + self.astereo.samples, + self.astereo.channels, + self.astereo.sr, + ) def test_padding(self): """Pad silence to signal. Support 1-3D tensors.""" @@ -40,32 +51,61 @@ def test_padding(self): tensor2 = np.ones((3, 3)) padded = padding(tensor2, 2, tail=True) - self.assertTrue(np.array_equal(padded, np.array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.], - [0., 0., 0.], [0., 0., 0.]]))) + self.assertTrue( + np.array_equal( + padded, + np.array( + [ + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + ] + ), + ) + ) padded = padding(tensor2, 2, tail=False, constant_values=5) - self.assertTrue(np.array_equal(padded, np.array([[5., 5., 5.], [5., 5., 5.], - [1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]))) + self.assertTrue( + np.array_equal( + padded, + np.array( + [ + [5.0, 5.0, 5.0], + [5.0, 5.0, 5.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + ] + ), + ) + ) tensor3 = np.ones((2, 2, 2)) padded = padding(tensor3, 2) - self.assertTrue(np.array_equal(padded, np.array([[[1., 1.], - [1., 1.], - [0., 0.], - [0., 0.]], - [[1., 1.], - [1., 1.], - [0., 0.], - [0., 0.]]]))) + self.assertTrue( + np.array_equal( + padded, + np.array( + [ + [[1.0, 1.0], [1.0, 1.0], [0.0, 0.0], [0.0, 0.0]], + [[1.0, 1.0], [1.0, 1.0], [0.0, 0.0], [0.0, 0.0]], + ] + ), + ) + ) padded = padding(tensor3, 2, tail=False) - self.assertTrue(np.array_equal(padded, np.array([[[0., 0.], - [0., 0.], - [1., 1.], - [1., 1.] - ], - [[0., 0.], - [0., 0.], - [1., 1.], - [1., 1.]]]))) + self.assertTrue( + np.array_equal( + padded, + np.array( + [ + [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]], + [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]], + ] + ), + ) + ) def test_next_pow2(self): next = next_pow2(255) @@ -101,7 +141,7 @@ def test_magspec_pspec(self): frames = signal_to_frame(sq.sig, 400, 400) mag = magspec(frames, 512) self.assertEqual(mag.shape, (20, 257)) - self.assertTrue((mag >= 0.).all()) # All elements should be non-negative + self.assertTrue((mag >= 0.0).all()) # All elements should be non-negative ps = powspec(frames, 512) self.assertEqual(ps.shape, (20, 257)) - self.assertTrue((ps >= 0.).all()) # All elements should be non-negative + self.assertTrue((ps >= 0.0).all()) # All elements should be non-negative diff --git a/tests/test_play.py b/tests/test_play.py index 39659da2..985c12b4 100644 --- a/tests/test_play.py +++ b/tests/test_play.py @@ -1,11 +1,13 @@ -from .helpers import check_for_output import time -from unittest import TestCase, skipUnless, mock -from pya import * +from unittest import TestCase, mock, skipUnless + import numpy as np -import warnings import pytest +from pya.aserver import Aserver +from pya.asig import Asig + +from .helpers import check_for_output # check if we have an output device has_output = check_for_output() @@ -16,23 +18,29 @@ class MockAudio(mock.MagicMock): channels_out = 4 def get_device_info_by_index(self, *args): - return {'maxInputChannels': self.channels_in, 'maxOutputChannels': self.channels_out, - 'name': 'MockAudio', 'index': 42} + return { + "maxInputChannels": self.channels_in, + "maxOutputChannels": self.channels_out, + "name": "MockAudio", + "index": 42, + } class TestPlayBase(TestCase): - __test__ = False # important, makes sure tests are not run on base class backend = None # will be overridden by backend tests def setUp(self): self.sig = np.sin(2 * np.pi * 440 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=['sine']) + self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=["sine"]) self.sig2ch = np.repeat(self.sig, 2).reshape((44100, 2)) - self.astereo = Asig(self.sig2ch, sr=44100, label="stereo", cn=['l', 'r']) + self.astereo = Asig(self.sig2ch, sr=44100, label="stereo", cn=["l", "r"]) - @pytest.mark.xfail(reason="Test may get affect with PortAudio bug or potential unsuitable audio device.") + @pytest.mark.xfail( + reason="Test may get affect with PortAudio bug " + "or potential unsuitable audio device." + ) def test_play_and_stop(self): ser = Aserver(backend=self.backend) ser.boot() @@ -44,21 +52,25 @@ def test_play_and_stop(self): def test_gain(self): result = (self.asine * 0.2).sig expected = self.asine.sig * 0.2 - self.assertTrue(np.allclose(result, expected)) # float32 should use allclose for more forgiving precision + self.assertTrue( + np.allclose(result, expected) + ) # float32 should use allclose for more forgiving precision expected = self.sig * self.sig result = (self.asine * self.asine).sig self.assertTrue(np.allclose(result, expected)) def test_resample(self): - # This test currently only check if there is error running the code, but not whether resampling is correct - result = self.asine.resample(target_sr=44100 // 2, rate=1, kind='linear') + """ + This test currently only check if there is error + running the code, but not whether resampling is correct + """ + result = self.asine.resample(target_sr=44100 // 2, rate=1, kind="linear") self.assertIsInstance(result, Asig) @skipUnless(has_output, "PyAudio found no output device.") class TestPlay(TestPlayBase): - __test__ = True @@ -72,7 +84,8 @@ class TestPlay(TestPlayBase): # s = Aserver() # s.boot() # assert mock_audio.open.called -# # since default AServer channel output is stereo we expect open to be called with +# # since default AServer channel output is stereo we expect open to be +# # called with # # channels=2 # self.assertEqual(mock_audio.open.call_args_list[0][1]["channels"], 2) # d1 = np.linspace(0, 1, 44100) @@ -87,4 +100,3 @@ class TestPlay(TestPlayBase): # s.boot() # assert mock_audio.open.call_count == 2 # self.assertEqual(mock_audio.open.call_args_list[1][1]["channels"], 6) - diff --git a/tests/test_routeNpan.py b/tests/test_routeNpan.py index 9305cc31..273760cf 100644 --- a/tests/test_routeNpan.py +++ b/tests/test_routeNpan.py @@ -1,7 +1,10 @@ -from unittest import TestCase import warnings +from unittest import TestCase + import numpy as np -from pya import * + +from pya.asig import Asig + # import logging # logging.basicConfig(level=logging.DEBUG) @@ -12,9 +15,9 @@ class TestRoutePan(TestCase): def setUp(self): self.sig = np.sin(2 * np.pi * 100 * np.linspace(0, 1, 44100)) self.asine = Asig(self.sig, sr=44100, label="test_sine") - self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=['sine']) + self.asineWithName = Asig(self.sig, sr=44100, label="test_sine", cn=["sine"]) self.sig2ch = np.repeat(self.sig, 2).reshape((44100, 2)) - self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", cn=['l', 'r']) + self.astereo = Asig(self.sig2ch, sr=44100, label="sterep", cn=["l", "r"]) self.sig16ch = np.repeat(self.sig, 16).reshape((44100, 16)) self.asine16ch = Asig(self.sig16ch, sr=44100, label="test_sine_16ch") @@ -51,8 +54,7 @@ def test_stereo(self): def test_rewire(self): # Rewire channels, e.g. move 0 to 1 with a gain of 0.5""" - result = self.astereo.rewire({(0, 1): 0.5, - (1, 0): 0.5}) + result = self.astereo.rewire({(0, 1): 0.5, (1, 0): 0.5}) temp = self.astereo.sig expect = temp.copy() expect[:, 0] = temp[:, 1] * 0.5 @@ -60,14 +62,14 @@ def test_rewire(self): self.assertTrue(np.allclose(expect[1000:10010, 1], result.sig[1000:10010, 1])) def test_pan2(self): - pan2 = self.astereo.pan2(-1.) + pan2 = self.astereo.pan2(-1.0) self.assertAlmostEqual(0, pan2.sig[:, 1].sum()) - pan2 = self.astereo.pan2(1.) + pan2 = self.astereo.pan2(1.0) self.assertAlmostEqual(0, pan2.sig[:, 0].sum()) pan2 = self.asine.pan2(-0.5) self.assertEqual(pan2.channels, 2) with self.assertRaises(TypeError): - self.astereo.pan2([2., 4.]) + self.astereo.pan2([2.0, 4.0]) with self.assertRaises(ValueError): - self.astereo.pan2(3.) \ No newline at end of file + self.astereo.pan2(3.0) diff --git a/tests/test_setitem.py b/tests/test_setitem.py index 0d2a0483..c6ceadd7 100644 --- a/tests/test_setitem.py +++ b/tests/test_setitem.py @@ -1,36 +1,42 @@ from unittest import TestCase -from pya import * + import numpy as np + +from pya.asig import Asig + # import logging # logging.basicConfig(level=logging.DEBUG) class TestSetitem(TestCase): - def setUp(self): self.dur = 3.5 self.sr = 1000 self.ts = np.linspace(0, self.dur, int(self.dur * self.sr)) - self.sig = np.sin(2 * np.pi * 50 * self.ts ** 1.9) - self.a1 = Asig(self.sig, sr=self.sr, channels=1, cn=['a'], label='1ch-sig') - self.ak = Asig(np.tile(self.sig.reshape(3500, 1), (1, 4)), sr=self.sr, - label='4ch-sig', cn=['a', 'b', 'c', 'd']) + self.sig = np.sin(2 * np.pi * 50 * self.ts**1.9) + self.a1 = Asig(self.sig, sr=self.sr, channels=1, cn=["a"], label="1ch-sig") + self.ak = Asig( + np.tile(self.sig.reshape(3500, 1), (1, 4)), + sr=self.sr, + label="4ch-sig", + cn=["a", "b", "c", "d"], + ) self.one = np.ones(self.sr) - self.aones = Asig(self.one, sr=self.sr, cn=['o'], label='ones') + self.aones = Asig(self.one, sr=self.sr, cn=["o"], label="ones") self.zero = np.zeros(self.sr) - self.azeros = Asig(self.zero, sr=self.sr, cn=['z'], label='zeros') + self.azeros = Asig(self.zero, sr=self.sr, cn=["z"], label="zeros") self.noise = np.random.random(self.sr) - self.anoise = Asig(self.noise, sr=self.sr, cn=['n'], label='noise') - self.aramp = Asig(np.arange(1000), sr=self.sr, label='ramp') + self.anoise = Asig(self.noise, sr=self.sr, cn=["n"], label="noise") + self.aramp = Asig(np.arange(1000), sr=self.sr, label="ramp") def tearDown(self): pass def test_default(self): # Testing of default mode, which should behave as Numpy should.""" - self.azeros[10] = self.aones[10].sig # value as asig + self.azeros[10] = self.aones[10].sig # value as asig self.assertEqual(self.aones[10], self.azeros[10]) - self.azeros[2] = self.aones[4].sig # value as ndarray + self.azeros[2] = self.aones[4].sig # value as ndarray self.assertEqual(self.aones[4], self.azeros[2]) self.azeros[3:6] = [1, 2, 3] # value as list self.assertTrue(np.array_equal(self.azeros[3:6].sig, [1, 2, 3])) @@ -40,8 +46,8 @@ def test_default(self): r = self.azeros[:10] # value as asig self.assertTrue(r, self.azeros[:10]) self.azeros[{0.2: 0.4}] = self.anoise[{0.5: 0.7}] - self.ak[{1: 2}, ['d']] = self.ak[{0: 1}, ['a']] - self.assertTrue(np.array_equal(self.ak[{1: 2}, ['d']], self.ak[{0: 1}, ['a']])) + self.ak[{1: 2}, ["d"]] = self.ak[{0: 1}, ["a"]] + self.assertTrue(np.array_equal(self.ak[{1: 2}, ["d"]], self.ak[{0: 1}, ["a"]])) def test_bound(self): # Testing of bound mode. Redundant array will not be assigned""" @@ -55,19 +61,21 @@ def test_bound(self): result = np.arange(1000)[-10:] + np.arange(10) self.assertTrue(np.array_equal(subject[-10:].sig, result)) - subject = Asig(np.arange(1000), sr=self.sr, label='ramp') - subject.b[-10:] *= 2 # Test __mul__ also. + subject = Asig(np.arange(1000), sr=self.sr, label="ramp") + subject.b[-10:] *= 2 # Test __mul__ also. result = np.arange(1000)[-10:] * 2 self.assertTrue(np.array_equal(subject[-10:].sig, result)) # # Multi channel case - self.ak.b[{2: None}, ['a', 'b']] = np.zeros(shape=(3000, 2)) - result = np.sum(self.ak[{2: None}, ['a', 'b']].sig) + self.ak.b[{2: None}, ["a", "b"]] = np.zeros(shape=(3000, 2)) + result = np.sum(self.ak[{2: None}, ["a", "b"]].sig) self.assertEqual(result, 0.0) def test_extend(self): - # Testing of extend mode, longer array will force the taker to extend its shape.""" - a = Asig(0.8, sr=1000, channels=4, cn=['a', 'b', 'c', 'd']) + """ + Testing of extend mode, longer array will force the taker to extend its shape. + """ + a = Asig(0.8, sr=1000, channels=4, cn=["a", "b", "c", "d"]) b = np.sin(2 * np.pi * 100 * np.linspace(0, 0.6, int(1000 * 0.6))) b = Asig(b) # test with extend set mono signal to a, initially only 0.8secs long... @@ -75,12 +83,12 @@ def test_extend(self): self.assertEqual(a.samples, 800) a.x[300:, 1] = 0.5 * b self.assertEqual(a.samples, 900) - a.x[1300:, 'c'] = 0.2 * b[::2] # compressed sig in ch 'c' + a.x[1300:, "c"] = 0.2 * b[::2] # compressed sig in ch 'c' self.assertEqual(a.samples, 1600) a.x[1900:, 3] = 0.2 * b[300:] # only end of tone in ch 'd' self.assertEqual(a.samples, 2200) - a = Asig(0.8, sr=1000, channels=1, cn=['a']) # Test with mono signal + a = Asig(0.8, sr=1000, channels=1, cn=["a"]) # Test with mono signal b = np.sin(2 * np.pi * 100 * np.linspace(0, 0.6, int(1000 * 0.6))) b = Asig(b) a.x[:, 0] = 0.2 * b # this fits in without need to extend @@ -92,19 +100,25 @@ def test_replace(self): a = Asig(a) a.overwrite[40:50] = b self.assertEqual(a.samples, 100 - 10 + 290) # First make sure size is correct - c = np.sum(a[50:60].sig) # Then make sure replace value is correct + c = np.sum(a[50:60].sig) # Then make sure replace value is correct self.assertEqual(c, 10) with self.assertRaises(ValueError): # Passing 2 chan to 4 chan asig should raise ValueError - self.ak.overwrite[{1.: 1.5}] = np.zeros((int(44100 * 0.6), 2)) + self.ak.overwrite[{1.0: 1.5}] = np.zeros((int(44100 * 0.6), 2)) def test_numpy_index(self): self.azeros[np.arange(0, 10)] = np.ones(10) - self.assertTrue(np.array_equal(self.azeros[np.arange(0, 10)].sig, self.aones[np.arange(0, 10)].sig)) + self.assertTrue( + np.array_equal( + self.azeros[np.arange(0, 10)].sig, self.aones[np.arange(0, 10)].sig + ) + ) def test_byte_index(self): self.azeros[bytes([0, 1, 2])] = np.ones(3) - self.assertTrue(np.array_equal(self.azeros[[0, 1, 2]].sig, self.aones[[0, 1, 2]].sig)) + self.assertTrue( + np.array_equal(self.azeros[[0, 1, 2]].sig, self.aones[[0, 1, 2]].sig) + ) def test_asig_index(self): self.azeros[self.aones.sig.astype(bool)] = self.aones.sig diff --git a/tests/test_ugen.py b/tests/test_ugen.py index d549ff97..1fce246e 100644 --- a/tests/test_ugen.py +++ b/tests/test_ugen.py @@ -1,7 +1,9 @@ from unittest import TestCase -from pya import * + import numpy as np +from pya.ugen import Ugen + class TestUgen(TestCase): def setUp(self): @@ -50,7 +52,7 @@ def test_noise(self): white = Ugen().noise( type="white", amp=0.2, dur=1.0, sr=1000, cn=["white"], label="white_noise" ) - pink = Ugen().noise(type="pink") + _ = Ugen().noise(type="pink") self.assertEqual(white.sr, 1000) self.assertEqual(white.cn, ["white"]) self.assertEqual(white.label, "white_noise") @@ -60,4 +62,4 @@ def test_noise(self): def test_dur_n_rows_exception(self): # An exception should be raised if both dur and n_rows are define. with self.assertRaises(AttributeError): - asig = Ugen().sine(dur=1.0, n_rows=400) + _ = Ugen().sine(dur=1.0, n_rows=400) diff --git a/tests/test_visualization.py b/tests/test_visualization.py index 6903c2eb..68c077de 100644 --- a/tests/test_visualization.py +++ b/tests/test_visualization.py @@ -1,9 +1,10 @@ from unittest import TestCase -from pya import * +from pya.helper.visualization import gridplot +from pya.ugen import Ugen -class TestVisualization(TestCase): +class TestVisualization(TestCase): def setUp(self): self.asig = Ugen().sine() self.aspec = self.asig.to_spec() @@ -21,21 +22,21 @@ def test_asig_plot_args(self): self.asig.plot(xlim=(0, 100), ylim=(0, 100)) def test_asig_fn_db(self): - self.asig.plot(fn='db') + self.asig.plot(fn="db") def test_asig_fn_nocallable(self): with self.assertRaises(AttributeError): - self.asig.plot(fn='something') + self.asig.plot(fn="something") def test_asig_multichannels(self): - sig2d = Ugen().sine(channels=4, cn=['a', 'b', 'c', 'd']) + sig2d = Ugen().sine(channels=4, cn=["a", "b", "c", "d"]) sig2d.plot() def test_aspec_plot(self): self.aspec.plot() def tesst_aspec_plot_lim(self): - self.aspect.plot(xlim=(0, 1.), ylim=(0, 100)) + self.aspect.plot(xlim=(0, 1.0), ylim=(0, 100)) def test_gridplot(self): _ = gridplot(self.alst) diff --git a/tox.ini b/tox.ini index 6361cbc8..d49c3769 100644 --- a/tox.ini +++ b/tox.ini @@ -1,17 +1,62 @@ +# Tox configuration file +# Read more under https://tox.wiki/ + [tox] -envlist = py3, check-manifest - -[testenv] -passenv = PULSE_SERVER -deps= - -rrequirements.txt - -rrequirements_pyaudio.txt - -rrequirements_remote.txt - -rrequirements_test.txt - coverage -commands= - pytest --doctest-modules --cov pya/ {posargs} - -[testenv:check-manifest] -deps = check-manifest -commands = check-manifest +minversion = 3.24 +envlist = default + + +[testenv:{tests}] +description = Invoke pytest to run automated tests +setenv = + TOXINIDIR = {toxinidir} +skip_install = true +allowlist_externals = uv +commands = + uv run pytest {posargs} + +[testenv:{build,clean}] +description = + build: Build the package in isolation according to PEP517, see https://github.com/pypa/build + clean: Remove old distribution files and temporary build artifacts (./build and ./dist) +# https://setuptools.pypa.io/en/stable/build_meta.html#how-to-use-it +skip_install = True +allowlist_externals = uv +changedir = {toxinidir} +commands = + clean: python -c 'import shutil; [shutil.rmtree(p, True) for p in ("build", "dist", "docs/_build")]' + clean: python -c 'import pathlib, shutil; [shutil.rmtree(p, True) for p in pathlib.Path("src").glob("*.egg-info")]' + build: uv build {posargs} + + +[testenv:{docs,doctests,linkcheck}] +description = + docs: Invoke sphinx-build to build the docs + doctests: Invoke sphinx-build to run doctests + linkcheck: Check for broken links in the documentation +allowlist_externals = uv +setenv = + DOCSDIR = {toxinidir}/docs + BUILDDIR = {toxinidir}/docs/_build + docs: BUILD = html + doctests: BUILD = doctest + linkcheck: BUILD = linkcheck + # ^ requirements.txt shared with Read The Docs +commands = + uv run sphinx-build -v --color -b {env:BUILD} -d "{env:BUILDDIR}/doctrees" "{env:DOCSDIR}" "{env:BUILDDIR}/{env:BUILD}" {posargs} + + +[testenv:publish] +description = + Publish the package you have been developing to a package index server. + By default, it uses testpypi. If you really want to publish your package + to be publicly accessible in PyPI, use the `-- --repository pypi` option. +skip_install = True +allowlist_externals = uv +changedir = {toxinidir} +passenv = + UV_PUBLISH_USERNAME + UV_PUBLISH_PASSWORD + UV_PUBLISH_URL +commands = + uv publish {posargs} From 4b3fed9aae23ff149fa9a8e62342f110cc690c43 Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 12:05:03 +0200 Subject: [PATCH 2/6] Updated github actions --- .github/workflows/pya-ci.yaml | 153 +++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 39 deletions(-) diff --git a/.github/workflows/pya-ci.yaml b/.github/workflows/pya-ci.yaml index 766bac75..8fc10202 100644 --- a/.github/workflows/pya-ci.yaml +++ b/.github/workflows/pya-ci.yaml @@ -1,51 +1,126 @@ -name: Pya +name: test-and-publish -on: - push: - branches: - - master - - develop - pull_request: - branches: - - master - - develop +push: + # Avoid using all the resources/limits available by checking only + # relevant branches and tags. Other branches can be checked via PRs. + branches: [main] + tags: ['v[0-9]*', '[0-9]+.[0-9]+*'] # Match tags that resemble a version + pull_request: # Run in every PR + workflow_dispatch: # Allow manually triggering the workflow + schedule: + # Run roughly every 15 days at 00:00 UTC + # (useful to check if updates on dependencies break the package) + - cron: '0 0 1,16 * *' + +permissions: + contents: read + +concurrency: + group: >- + ${{ github.workflow }}-${{ github.ref_type }}- + ${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true jobs: - unit-test: - runs-on: ${{ matrix.os }} - timeout-minutes: 120 + prepare: + runs-on: ubuntu-latest + outputs: + wheel-distribution: ${{ steps.wheel-distribution.outputs.path }} + steps: + - uses: actions/checkout@v5 + with: {fetch-depth: 0} # deep clone for hatch-scm + - uses: astral-sh/setup-uv@v8.1.0 + - name: Run static analysis and format checkers + run: uv run pre-commit run --all-files --show-diff-on-failure + - name: Build package distribution files + run: uv run tox -e clean,build + - name: Record the path of wheel distribution + id: wheel-distribution + run: echo "path=$(ls dist/*.whl)" >> $GITHUB_OUTPUT + - name: Store the distribution files for use in other stages + # `tests` and `publish` will use the same pre-built distributions, + # so we make sure to release the exact same package that was tested + uses: actions/upload-artifact@v4 + with: + name: python-distribution-files + path: dist/ + retention-days: 1 + + test: + needs: prepare strategy: matrix: - os: ["ubuntu-latest", "macos-latest"] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python: + - "3.10" + - "3.11" # oldest Python supported by PSF + - "3.12" # oldest Python supported by PSF + - "3.13" # oldest Python supported by PSF + - "3.14" # newest Python that is stable + platform: + - ubuntu-latest + - macos-latest + - windows-latest + runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 + - uses: astral-sh/setup-uv@v8.1.0 + with: + python-version: ${{ matrix.python }} - name: Install portaudio Ubuntu - if: matrix.os == 'ubuntu-latest' + if: matrix.platform == 'ubuntu-latest' shell: bash -l {0} run: sudo apt-get install portaudio19-dev - name: Install portaudio MacOS - if: matrix.os == 'macos-latest' + if: matrix.platform == 'macos-latest' shell: bash -l {0} run: brew install portaudio - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - activate-environment: test-env - environment-file: ci/test-environment.yml - python-version: ${{ matrix.python-version }} - auto-activate-base: false - - name: Set up depen - shell: bash -l {0} - run: | - conda init bash - conda config --add channels defaults - conda activate test-env - conda install ffmpeg coverage python-coveralls --file=requirements_remote.txt --file=requirements_test.txt - # pyaudio is not yet available on conda - pip install -r requirements.txt - - name: Run tests - shell: bash -l {0} - run: | - conda activate test-env - pytest --cov pya/ + - name: Retrieve pre-built distribution files + uses: actions/download-artifact@v4 + with: {name: python-distribution-files, path: dist/} + - name: Run tests + run: >- + uv run tox --installpkg '${{ needs.prepare.outputs.wheel-distribution }}' + -- -rFEx --durations 10 --color yes # pytest args + - name: Upload partial coverage report + uses: coverallsapp/github-action@master + with: + path-to-lcov: coverage.lcov + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: ${{ matrix.platform }} - py${{ matrix.python }} + parallel: true + + finalize: + needs: test + runs-on: ubuntu-latest + steps: + - name: Finalize coverage report + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true + - name: debug + run: echo "ref=${{ github.ref }} event=${{ github.event_name }}" + + + + publish: + needs: finalize + if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && contains(github.ref, 'refs/tags/') }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v5 + - uses: astral-sh/setup-uv@v8.1.0 + - name: Retrieve pre-built distribution files + uses: actions/download-artifact@v4 + with: {name: python-distribution-files, path: dist/} + - name: Publish Package + env: + # TODO: Set your PYPI_TOKEN as a secret using GitHub UI + # - https://pypi.org/help/#apitoken + # - https://docs.github.com/en/actions/security-guides/encrypted-secrets + UV_PUBLISH_URL: https://upload.pypi.org/legacy/ + UV_PUBLISH_USERNAME: __token__ + UV_PUBLISH_PASSWORD: ${{ secrets.PYPI_TOKEN }} + run: uv run tox -e publish From 1f81f5a13f99a8e84e8c818da926445e437da3e1 Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 12:07:28 +0200 Subject: [PATCH 3/6] Updated github actions --- .github/workflows/pya-ci.yaml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pya-ci.yaml b/.github/workflows/pya-ci.yaml index 8fc10202..725035ea 100644 --- a/.github/workflows/pya-ci.yaml +++ b/.github/workflows/pya-ci.yaml @@ -1,6 +1,7 @@ name: test-and-publish -push: +on: + push: # Avoid using all the resources/limits available by checking only # relevant branches and tags. Other branches can be checked via PRs. branches: [main] @@ -66,14 +67,14 @@ jobs: - uses: astral-sh/setup-uv@v8.1.0 with: python-version: ${{ matrix.python }} - - name: Install portaudio Ubuntu - if: matrix.platform == 'ubuntu-latest' - shell: bash -l {0} - run: sudo apt-get install portaudio19-dev - - name: Install portaudio MacOS - if: matrix.platform == 'macos-latest' - shell: bash -l {0} - run: brew install portaudio + - name: Install portaudio Ubuntu + if: matrix.platform == 'ubuntu-latest' + shell: bash -l {0} + run: sudo apt-get install portaudio19-dev + - name: Install portaudio MacOS + if: matrix.platform == 'macos-latest' + shell: bash -l {0} + run: brew install portaudio - name: Retrieve pre-built distribution files uses: actions/download-artifact@v4 with: {name: python-distribution-files, path: dist/} From 281350a98290bbfa887a61d7ee36909e75d3f6bc Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 12:13:24 +0200 Subject: [PATCH 4/6] Updated Changelog --- Changelog.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 17ddb126..c2b263a6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,9 @@ ## 0.6.0 * changed project management and build system to use `uv`. Most of the configuration is now gathered in the `pyproject.toml`. -* added pre-commit hooks +* added pre-commit hooks and executed a lot of internal "form" refactoring to modern ruff standards (imports, documentation) +* updated the github CI/CD pipelines to execute matrix testing for Ubuntu, MacOS and Windows + ## 0.5.2 (Nov 2023) From e23a8bb4f73db0ab72ac91f6ec0675c47b6a48a2 Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 12:21:43 +0200 Subject: [PATCH 5/6] Updated dev dependencies for sphinx and added tracking for missing files --- .pre-commit-config.yaml | 37 + coverage.lcov | 2632 +++++++++++++++ docs/_autosummary/pya.amfcc.rst | 26 + docs/_autosummary/pya.arecorder.rst | 26 + docs/_autosummary/pya.aserver.rst | 26 + docs/_autosummary/pya.asig.rst | 26 + docs/_autosummary/pya.aspec.rst | 26 + docs/_autosummary/pya.astft.rst | 26 + docs/_autosummary/pya.backend.Dummy.rst | 27 + docs/_autosummary/pya.backend.base.rst | 27 + docs/_autosummary/pya.backend.rst | 29 + docs/_autosummary/pya.helper.backend.rst | 29 + docs/_autosummary/pya.helper.codec.rst | 51 + docs/_autosummary/pya.helper.helpers.rst | 39 + docs/_autosummary/pya.helper.rst | 33 + .../_autosummary/pya.helper.visualization.rst | 27 + docs/_autosummary/pya.rst | 46 + docs/_autosummary/pya.ugen.rst | 32 + docs/_autosummary/pya.version.rst | 20 + docs/api.rst | 8 + docs/readme.rst | 2 + pyproject.toml | 91 + uv.lock | 2998 +++++++++++++++++ 23 files changed, 6284 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100644 coverage.lcov create mode 100644 docs/_autosummary/pya.amfcc.rst create mode 100644 docs/_autosummary/pya.arecorder.rst create mode 100644 docs/_autosummary/pya.aserver.rst create mode 100644 docs/_autosummary/pya.asig.rst create mode 100644 docs/_autosummary/pya.aspec.rst create mode 100644 docs/_autosummary/pya.astft.rst create mode 100644 docs/_autosummary/pya.backend.Dummy.rst create mode 100644 docs/_autosummary/pya.backend.base.rst create mode 100644 docs/_autosummary/pya.backend.rst create mode 100644 docs/_autosummary/pya.helper.backend.rst create mode 100644 docs/_autosummary/pya.helper.codec.rst create mode 100644 docs/_autosummary/pya.helper.helpers.rst create mode 100644 docs/_autosummary/pya.helper.rst create mode 100644 docs/_autosummary/pya.helper.visualization.rst create mode 100644 docs/_autosummary/pya.rst create mode 100644 docs/_autosummary/pya.ugen.rst create mode 100644 docs/_autosummary/pya.version.rst create mode 100644 docs/api.rst create mode 100644 docs/readme.rst create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..76d97eb9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,37 @@ +exclude: '^docs/conf.py|^uv\.lock$' + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-added-large-files + exclude: uv.lock + - id: check-ast + - id: check-json + - id: check-merge-conflict + - id: check-xml + - id: check-yaml + - id: end-of-file-fixer + exclude: "uv.lock" + - id: mixed-line-ending + exclude: "uv.lock" + args: ['--fix=auto'] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows + +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.0 # check latest + hooks: + - id: ruff # replaces isort + flake8 + args: [--fix] # auto-fix where possible + - id: ruff-format # replaces black + +- repo: https://github.com/kynan/nbstripout + rev: 0.8.1 + hooks: + - id: nbstripout + args: [--extra-keys=metadata.kernelspec metadata.language_info] + + +- repo: https://github.com/astral-sh/uv-pre-commit + rev: 0.6.0 # check latest + hooks: + - id: uv-lock # updates uv.lock when pyproject.toml changes diff --git a/coverage.lcov b/coverage.lcov new file mode 100644 index 00000000..19b76047 --- /dev/null +++ b/coverage.lcov @@ -0,0 +1,2632 @@ +SF:pya/__init__.py +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:14,1 +DA:17,1 +DA:18,0 +DA:21,1 +DA:22,0 +LF:15 +LH:13 +FN:17,18,startup +FNDA:0,startup +FN:21,22,shutdown +FNDA:0,shutdown +FNF:2 +FNH:0 +end_of_record +SF:pya/amfcc.py +DA:1,1 +DA:2,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:24,1 +DA:77,1 +DA:134,1 +DA:135,1 +DA:136,1 +DA:137,1 +DA:138,1 +DA:139,1 +DA:140,1 +DA:141,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:151,1 +DA:152,1 +DA:153,1 +DA:155,1 +DA:156,1 +DA:159,1 +DA:161,1 +DA:162,1 +DA:163,1 +DA:164,1 +DA:165,1 +DA:166,1 +DA:167,1 +DA:168,1 +DA:169,1 +DA:170,1 +DA:172,1 +DA:173,1 +DA:174,1 +DA:175,1 +DA:179,1 +DA:180,1 +DA:186,1 +DA:187,1 +DA:190,1 +DA:192,1 +DA:198,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:208,1 +DA:210,1 +DA:213,1 +DA:214,1 +DA:216,1 +DA:217,1 +DA:218,1 +DA:220,1 +DA:221,1 +DA:222,1 +DA:224,1 +DA:225,1 +DA:227,1 +DA:229,1 +DA:230,1 +DA:232,1 +DA:233,1 +DA:252,1 +DA:254,1 +DA:255,1 +DA:285,1 +DA:288,1 +DA:289,1 +DA:290,1 +DA:293,1 +DA:295,1 +DA:296,1 +DA:297,1 +DA:298,1 +DA:299,1 +DA:300,1 +DA:301,1 +DA:303,1 +DA:304,1 +DA:334,1 +DA:335,1 +DA:336,1 +DA:337,1 +DA:338,1 +DA:341,1 +DA:343,1 +DA:373,1 +DA:374,1 +DA:378,1 +DA:379,1 +DA:394,1 +DA:395,1 +DA:396,1 +DA:398,1 +DA:399,1 +DA:401,1 +DA:402,1 +DA:404,1 +LF:108 +LH:108 +FN:77,214,Amfcc.__init__ +FNDA:1,Amfcc.__init__ +FN:217,218,Amfcc.nframes +FNDA:1,Amfcc.nframes +FN:221,222,Amfcc.timestamp +FNDA:1,Amfcc.timestamp +FN:225,227,Amfcc.features +FNDA:1,Amfcc.features +FN:229,230,Amfcc.__repr__ +FNDA:1,Amfcc.__repr__ +FN:233,252,Amfcc.preemphasis +FNDA:1,Amfcc.preemphasis +FN:255,301,Amfcc.mel_filterbanks +FNDA:1,Amfcc.mel_filterbanks +FN:304,341,Amfcc.lifter +FNDA:1,Amfcc.lifter +FN:343,404,Amfcc.plot +FNDA:1,Amfcc.plot +FNF:9 +FNH:9 +end_of_record +SF:pya/arecorder.py +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:7,1 +DA:8,1 +DA:10,1 +DA:11,1 +DA:13,1 +DA:14,1 +DA:17,1 +DA:38,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:58,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:65,1 +DA:66,1 +DA:70,0 +DA:71,0 +DA:72,0 +DA:74,1 +DA:86,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:97,0 +DA:99,1 +DA:100,0 +DA:101,0 +DA:103,1 +DA:104,1 +DA:105,1 +DA:107,1 +DA:108,1 +DA:109,1 +DA:118,1 +DA:119,1 +DA:121,1 +DA:124,0 +DA:125,0 +DA:127,0 +DA:128,0 +DA:132,0 +DA:135,0 +DA:137,1 +DA:139,1 +DA:141,1 +DA:143,0 +DA:145,1 +DA:147,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:151,1 +DA:153,0 +DA:155,1 +DA:156,0 +DA:157,0 +DA:158,0 +DA:159,0 +DA:162,0 +LF:76 +LH:47 +FN:38,59,Arecorder.__init__ +FNDA:1,Arecorder.__init__ +FN:62,63,Arecorder.channels +FNDA:1,Arecorder.channels +FN:66,72,Arecorder.channels +FNDA:0,Arecorder.channels +FN:74,97,Arecorder.set_tracks +FNDA:0,Arecorder.set_tracks +FN:99,101,Arecorder.reset +FNDA:0,Arecorder.reset +FN:103,119,Arecorder.boot +FNDA:1,Arecorder.boot +FN:121,135,Arecorder._recorder_callback +FNDA:0,Arecorder._recorder_callback +FN:137,139,Arecorder.record +FNDA:1,Arecorder.record +FN:141,143,Arecorder.pause +FNDA:0,Arecorder.pause +FN:145,153,Arecorder.stop +FNDA:1,Arecorder.stop +FN:155,162,Arecorder.__repr__ +FNDA:0,Arecorder.__repr__ +FNF:11 +FNH:5 +end_of_record +SF:pya/aserver.py +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:12,1 +DA:15,1 +DA:35,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:45,0 +DA:46,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:55,0 +DA:57,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:101,1 +DA:106,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,1 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:121,1 +DA:122,1 +DA:123,1 +DA:125,1 +DA:126,1 +DA:130,0 +DA:131,0 +DA:132,0 +DA:134,1 +DA:135,1 +DA:136,1 +DA:138,1 +DA:139,1 +DA:140,1 +DA:142,1 +DA:143,1 +DA:144,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:150,1 +DA:151,1 +DA:152,1 +DA:154,1 +DA:155,1 +DA:156,0 +DA:161,0 +DA:162,0 +DA:165,0 +DA:167,1 +DA:168,1 +DA:172,1 +DA:174,1 +DA:176,1 +DA:177,1 +DA:178,1 +DA:184,1 +DA:185,1 +DA:191,1 +DA:193,1 +DA:205,0 +DA:206,0 +DA:207,0 +DA:208,0 +DA:209,0 +DA:210,0 +DA:211,0 +DA:212,0 +DA:213,0 +DA:214,0 +DA:216,1 +DA:218,1 +DA:219,1 +DA:220,1 +DA:221,1 +DA:222,1 +DA:223,1 +DA:224,1 +DA:233,1 +DA:234,1 +DA:235,1 +DA:237,1 +DA:239,1 +DA:240,1 +DA:241,1 +DA:242,1 +DA:243,1 +DA:244,1 +DA:245,1 +DA:246,1 +DA:247,0 +DA:248,0 +DA:249,1 +DA:251,1 +DA:261,1 +DA:263,1 +DA:264,1 +DA:265,0 +DA:266,1 +DA:267,1 +DA:269,0 +DA:270,1 +DA:271,1 +DA:272,1 +DA:273,0 +DA:274,0 +DA:275,0 +DA:276,0 +DA:278,1 +DA:282,1 +DA:283,1 +DA:284,1 +DA:285,1 +DA:286,1 +DA:289,1 +DA:290,1 +DA:291,1 +DA:292,1 +DA:293,1 +DA:294,0 +DA:296,1 +DA:297,1 +DA:299,1 +DA:301,1 +DA:302,1 +DA:305,1 +DA:306,1 +DA:307,1 +DA:308,1 +DA:309,1 +DA:311,1 +DA:312,1 +DA:313,1 +DA:314,0 +DA:315,0 +DA:316,0 +DA:317,0 +DA:318,0 +DA:319,1 +DA:321,1 +DA:322,1 +DA:323,1 +DA:324,1 +DA:325,1 +DA:326,1 +DA:327,1 +DA:328,1 +DA:329,1 +DA:331,1 +DA:332,1 +DA:333,1 +DA:334,1 +DA:336,1 +DA:337,1 +DA:338,1 +DA:339,0 +DA:341,1 +DA:342,0 +DA:343,0 +DA:344,0 +DA:345,0 +DA:346,1 +DA:348,1 +DA:349,1 +DA:351,1 +DA:352,1 +DA:354,1 +DA:356,1 +DA:357,1 +DA:358,1 +DA:360,1 +DA:362,1 +DA:363,0 +DA:364,0 +DA:365,0 +DA:366,0 +DA:367,0 +LF:210 +LH:167 +FN:38,46,Aserver.startup_default_server +FNDA:1,Aserver.startup_default_server +FN:49,55,Aserver.shutdown_default_server +FNDA:1,Aserver.shutdown_default_server +FN:57,119,Aserver.__init__ +FNDA:1,Aserver.__init__ +FN:122,123,Aserver.channels +FNDA:1,Aserver.channels +FN:126,132,Aserver.channels +FNDA:0,Aserver.channels +FN:135,136,Aserver.device_dict +FNDA:1,Aserver.device_dict +FN:139,140,Aserver.max_out_chn +FNDA:1,Aserver.max_out_chn +FN:143,144,Aserver.max_in_chn +FNDA:1,Aserver.max_in_chn +FN:147,148,Aserver.is_active +FNDA:1,Aserver.is_active +FN:151,152,Aserver.device +FNDA:1,Aserver.device +FN:155,165,Aserver.device +FNDA:0,Aserver.device +FN:167,172,Aserver.__repr__ +FNDA:1,Aserver.__repr__ +FN:174,191,Aserver.get_devices +FNDA:1,Aserver.get_devices +FN:193,214,Aserver.set_device +FNDA:0,Aserver.set_device +FN:216,235,Aserver.boot +FNDA:1,Aserver.boot +FN:237,249,Aserver.quit +FNDA:1,Aserver.quit +FN:251,297,Aserver.play +FNDA:1,Aserver.play +FN:299,346,Aserver._play_callback +FNDA:1,Aserver._play_callback +FN:348,349,Aserver.stop +FNDA:1,Aserver.stop +FN:351,352,Aserver.__enter__ +FNDA:1,Aserver.__enter__ +FN:354,358,Aserver.__exit__ +FNDA:1,Aserver.__exit__ +FN:360,367,Aserver.__del__ +FNDA:1,Aserver.__del__ +FNF:22 +FNH:19 +end_of_record +SF:pya/asig.py +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:14,1 +DA:16,1 +DA:17,1 +DA:20,1 +DA:54,1 +DA:92,1 +DA:93,1 +DA:95,0 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:101,0 +DA:102,0 +DA:103,0 +DA:104,1 +DA:105,1 +DA:106,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:113,1 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,0 +DA:122,1 +DA:124,1 +DA:125,1 +DA:127,1 +DA:128,1 +DA:129,1 +DA:130,1 +DA:132,1 +DA:133,1 +DA:135,1 +DA:137,1 +DA:138,1 +DA:140,1 +DA:141,1 +DA:143,1 +DA:145,1 +DA:146,1 +DA:148,1 +DA:150,1 +DA:154,1 +DA:155,1 +DA:159,1 +DA:161,1 +DA:162,1 +DA:166,1 +DA:168,1 +DA:179,1 +DA:180,1 +DA:181,1 +DA:182,0 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:187,1 +DA:188,1 +DA:190,1 +DA:191,1 +DA:192,1 +DA:194,1 +DA:195,1 +DA:197,0 +DA:199,1 +DA:226,1 +DA:227,1 +DA:228,1 +DA:229,1 +DA:230,1 +DA:231,0 +DA:234,0 +DA:237,1 +DA:238,1 +DA:242,1 +DA:243,1 +DA:244,1 +DA:245,1 +DA:246,1 +DA:247,1 +DA:248,1 +DA:249,1 +DA:250,1 +DA:251,1 +DA:252,1 +DA:253,1 +DA:254,1 +DA:255,1 +DA:256,1 +DA:257,1 +DA:258,1 +DA:259,1 +DA:260,0 +DA:261,0 +DA:262,1 +DA:263,1 +DA:264,1 +DA:265,1 +DA:266,1 +DA:267,1 +DA:268,1 +DA:270,1 +DA:271,1 +DA:274,1 +DA:275,1 +DA:276,1 +DA:277,1 +DA:278,1 +DA:279,0 +DA:280,1 +DA:281,1 +DA:282,1 +DA:283,1 +DA:285,1 +DA:286,1 +DA:287,1 +DA:290,0 +DA:291,0 +DA:292,0 +DA:293,1 +DA:294,1 +DA:295,1 +DA:296,1 +DA:297,1 +DA:298,1 +DA:299,1 +DA:300,1 +DA:302,1 +DA:303,0 +DA:304,0 +DA:305,0 +DA:307,1 +DA:308,1 +DA:310,1 +DA:316,1 +DA:318,1 +DA:319,1 +DA:320,1 +DA:321,1 +DA:322,1 +DA:323,1 +DA:325,1 +DA:326,1 +DA:327,1 +DA:329,1 +DA:330,1 +DA:336,1 +DA:337,1 +DA:339,1 +DA:341,1 +DA:342,1 +DA:348,1 +DA:349,1 +DA:351,1 +DA:353,1 +DA:354,1 +DA:359,1 +DA:360,1 +DA:362,1 +DA:364,1 +DA:410,1 +DA:411,1 +DA:413,1 +DA:414,1 +DA:415,1 +DA:417,1 +DA:418,1 +DA:420,1 +DA:421,1 +DA:422,1 +DA:424,1 +DA:425,1 +DA:426,1 +DA:427,0 +DA:428,0 +DA:429,1 +DA:430,1 +DA:431,1 +DA:432,1 +DA:433,1 +DA:434,1 +DA:435,1 +DA:437,1 +DA:440,1 +DA:441,1 +DA:442,1 +DA:443,1 +DA:445,0 +DA:446,0 +DA:447,0 +DA:448,0 +DA:450,1 +DA:451,1 +DA:453,1 +DA:454,0 +DA:456,1 +DA:458,1 +DA:459,1 +DA:460,1 +DA:462,1 +DA:465,1 +DA:466,1 +DA:467,1 +DA:469,1 +DA:471,1 +DA:472,1 +DA:474,1 +DA:475,1 +DA:476,1 +DA:478,1 +DA:481,1 +DA:482,1 +DA:483,1 +DA:485,1 +DA:486,1 +DA:487,1 +DA:488,1 +DA:489,1 +DA:492,1 +DA:494,1 +DA:495,1 +DA:498,0 +DA:499,0 +DA:501,1 +DA:502,1 +DA:503,1 +DA:504,1 +DA:505,1 +DA:506,1 +DA:507,1 +DA:509,1 +DA:511,1 +DA:512,1 +DA:513,1 +DA:514,0 +DA:515,0 +DA:516,1 +DA:517,1 +DA:518,0 +DA:519,1 +DA:520,0 +DA:523,1 +DA:525,1 +DA:526,1 +DA:527,1 +DA:528,1 +DA:529,1 +DA:530,1 +DA:532,1 +DA:533,1 +DA:535,1 +DA:538,1 +DA:539,0 +DA:541,1 +DA:543,1 +DA:544,1 +DA:548,1 +DA:549,1 +DA:551,1 +DA:553,1 +DA:556,1 +DA:557,1 +DA:560,1 +DA:563,1 +DA:566,1 +DA:572,1 +DA:573,1 +DA:574,1 +DA:575,0 +DA:576,1 +DA:578,1 +DA:580,1 +DA:581,1 +DA:582,1 +DA:584,1 +DA:602,1 +DA:603,1 +DA:608,1 +DA:609,1 +DA:617,1 +DA:621,0 +DA:624,0 +DA:625,0 +DA:633,0 +DA:634,0 +DA:636,1 +DA:655,1 +DA:657,1 +DA:658,1 +DA:659,1 +DA:660,1 +DA:662,0 +DA:663,1 +DA:664,1 +DA:666,1 +DA:687,1 +DA:688,0 +DA:690,1 +DA:691,1 +DA:694,1 +DA:695,1 +DA:696,0 +DA:697,0 +DA:698,0 +DA:699,0 +DA:700,1 +DA:701,0 +DA:703,1 +DA:704,1 +DA:705,1 +DA:706,1 +DA:708,0 +DA:709,0 +DA:710,0 +DA:711,1 +DA:713,1 +DA:729,1 +DA:730,1 +DA:731,1 +DA:732,1 +DA:733,0 +DA:734,1 +DA:735,0 +DA:737,1 +DA:738,1 +DA:739,1 +DA:741,1 +DA:775,1 +DA:776,1 +DA:777,1 +DA:779,1 +DA:780,1 +DA:782,1 +DA:783,1 +DA:784,1 +DA:785,1 +DA:786,1 +DA:787,1 +DA:789,1 +DA:790,1 +DA:791,1 +DA:793,0 +DA:797,0 +DA:799,1 +DA:800,1 +DA:802,1 +DA:822,1 +DA:823,1 +DA:824,0 +DA:825,0 +DA:827,1 +DA:828,1 +DA:829,1 +DA:830,1 +DA:832,1 +DA:851,1 +DA:853,1 +DA:854,1 +DA:855,1 +DA:856,1 +DA:858,1 +DA:859,1 +DA:860,1 +DA:861,1 +DA:869,1 +DA:876,1 +DA:878,1 +DA:880,1 +DA:892,1 +DA:893,1 +DA:895,1 +DA:914,1 +DA:915,1 +DA:916,1 +DA:917,1 +DA:919,1 +DA:920,1 +DA:921,1 +DA:923,1 +DA:942,1 +DA:943,1 +DA:944,1 +DA:945,1 +DA:946,1 +DA:947,1 +DA:948,1 +DA:950,1 +DA:958,1 +DA:960,1 +DA:993,1 +DA:994,1 +DA:996,1 +DA:997,1 +DA:999,1 +DA:1000,1 +DA:1001,1 +DA:1002,1 +DA:1004,1 +DA:1005,1 +DA:1011,1 +DA:1024,1 +DA:1026,1 +DA:1028,1 +DA:1030,1 +DA:1032,1 +DA:1034,1 +DA:1039,1 +DA:1040,1 +DA:1041,1 +DA:1043,1 +DA:1045,1 +DA:1054,1 +DA:1063,1 +DA:1064,1 +DA:1065,1 +DA:1066,1 +DA:1073,1 +DA:1074,1 +DA:1075,0 +DA:1076,1 +DA:1077,1 +DA:1078,1 +DA:1079,1 +DA:1080,1 +DA:1081,1 +DA:1082,0 +DA:1083,0 +DA:1085,1 +DA:1086,1 +DA:1087,1 +DA:1089,0 +DA:1091,1 +DA:1092,1 +DA:1094,1 +DA:1095,1 +DA:1099,1 +DA:1110,1 +DA:1111,1 +DA:1112,1 +DA:1113,1 +DA:1120,0 +DA:1121,0 +DA:1122,0 +DA:1123,0 +DA:1124,0 +DA:1125,0 +DA:1126,0 +DA:1127,0 +DA:1128,0 +DA:1129,0 +DA:1130,0 +DA:1132,0 +DA:1134,0 +DA:1135,0 +DA:1136,0 +DA:1138,0 +DA:1140,0 +DA:1141,0 +DA:1143,1 +DA:1144,1 +DA:1148,1 +DA:1156,1 +DA:1157,1 +DA:1158,1 +DA:1159,1 +DA:1163,1 +DA:1164,1 +DA:1165,1 +DA:1166,1 +DA:1167,1 +DA:1168,1 +DA:1169,0 +DA:1170,0 +DA:1171,1 +DA:1172,1 +DA:1173,1 +DA:1175,1 +DA:1176,0 +DA:1177,0 +DA:1179,1 +DA:1180,1 +DA:1181,1 +DA:1183,1 +DA:1185,1 +DA:1186,1 +DA:1188,1 +DA:1189,0 +DA:1191,1 +DA:1199,1 +DA:1200,1 +DA:1201,1 +DA:1202,1 +DA:1209,1 +DA:1210,1 +DA:1211,1 +DA:1212,0 +DA:1213,1 +DA:1214,1 +DA:1215,0 +DA:1216,0 +DA:1217,1 +DA:1218,1 +DA:1219,1 +DA:1221,1 +DA:1222,0 +DA:1223,0 +DA:1225,1 +DA:1227,1 +DA:1228,1 +DA:1229,1 +DA:1231,0 +DA:1233,1 +DA:1234,1 +DA:1236,1 +DA:1237,1 +DA:1241,1 +DA:1275,1 +DA:1276,0 +DA:1279,0 +DA:1280,0 +DA:1281,1 +DA:1282,1 +DA:1283,1 +DA:1284,1 +DA:1285,1 +DA:1286,1 +DA:1287,1 +DA:1288,1 +DA:1290,0 +DA:1291,1 +DA:1292,1 +DA:1293,1 +DA:1294,1 +DA:1295,1 +DA:1296,1 +DA:1297,1 +DA:1298,1 +DA:1299,1 +DA:1301,1 +DA:1302,1 +DA:1303,1 +DA:1305,1 +DA:1306,1 +DA:1308,1 +DA:1309,1 +DA:1317,1 +DA:1318,1 +DA:1319,1 +DA:1321,1 +DA:1336,0 +DA:1337,0 +DA:1338,0 +DA:1339,0 +DA:1340,0 +DA:1341,0 +DA:1342,0 +DA:1343,0 +DA:1344,0 +DA:1350,0 +DA:1351,0 +DA:1353,1 +DA:1354,0 +DA:1355,0 +DA:1356,0 +DA:1357,0 +DA:1358,0 +DA:1359,0 +DA:1360,0 +DA:1362,1 +DA:1377,1 +DA:1378,1 +DA:1379,0 +DA:1380,0 +DA:1383,1 +DA:1384,1 +DA:1385,1 +DA:1392,0 +DA:1395,0 +DA:1402,1 +DA:1417,1 +DA:1418,1 +DA:1419,0 +DA:1420,0 +DA:1423,1 +DA:1424,1 +DA:1425,1 +DA:1432,0 +DA:1435,0 +DA:1442,1 +DA:1486,0 +DA:1487,0 +DA:1488,0 +DA:1489,0 +DA:1490,0 +DA:1491,0 +DA:1492,0 +DA:1493,0 +DA:1495,1 +DA:1512,0 +DA:1513,0 +DA:1515,1 +DA:1536,0 +DA:1537,0 +DA:1538,0 +DA:1539,0 +DA:1541,0 +DA:1542,0 +DA:1544,0 +DA:1545,0 +DA:1546,0 +DA:1547,0 +DA:1550,0 +DA:1553,0 +DA:1554,0 +DA:1555,0 +DA:1556,0 +DA:1557,0 +DA:1559,0 +DA:1560,0 +DA:1561,0 +DA:1562,0 +DA:1563,0 +DA:1567,0 +DA:1569,1 +DA:1601,0 +DA:1602,0 +DA:1609,1 +DA:1626,1 +DA:1627,0 +DA:1628,1 +DA:1629,1 +DA:1630,0 +DA:1631,1 +DA:1632,1 +DA:1639,1 +DA:1640,1 +DA:1641,1 +DA:1643,1 +DA:1663,1 +DA:1664,1 +DA:1667,1 +DA:1672,1 +DA:1673,1 +DA:1674,1 +DA:1675,1 +DA:1676,1 +DA:1677,1 +DA:1678,1 +DA:1679,1 +DA:1680,1 +DA:1681,1 +DA:1683,0 +DA:1685,1 +DA:1686,1 +DA:1688,0 +DA:1689,1 +DA:1693,1 +DA:1729,0 +DA:1735,0 +DA:1736,0 +DA:1737,0 +DA:1738,0 +DA:1739,0 +DA:1740,0 +DA:1741,0 +DA:1742,0 +DA:1743,0 +DA:1744,0 +DA:1745,0 +DA:1746,0 +DA:1747,0 +DA:1748,0 +DA:1749,0 +DA:1750,0 +DA:1751,0 +DA:1752,0 +DA:1754,1 +DA:1756,1 +DA:1758,1 +DA:1760,1 +DA:1766,1 +DA:1768,1 +DA:1770,1 +DA:1783,1 +DA:1785,1 +DA:1800,1 +DA:1826,0 +DA:1827,0 +DA:1828,0 +DA:1829,0 +DA:1830,0 +DA:1831,0 +DA:1832,0 +DA:1833,0 +DA:1834,0 +DA:1835,0 +DA:1839,0 +DA:1840,0 +DA:1841,0 +DA:1842,0 +DA:1844,0 +DA:1849,0 +DA:1850,0 +DA:1851,0 +DA:1852,0 +DA:1853,0 +DA:1854,0 +DA:1855,0 +DA:1856,0 +DA:1857,0 +DA:1865,0 +DA:1866,0 +DA:1867,0 +DA:1868,0 +DA:1869,0 +DA:1871,1 +DA:1876,0 +DA:1877,0 +DA:1879,1 +DA:1881,0 +DA:1883,1 +DA:1901,1 +DA:1902,1 +DA:1903,1 +DA:1904,0 +DA:1905,0 +DA:1907,1 +DA:1908,1 +DA:1909,1 +DA:1911,1 +DA:1912,1 +DA:1919,1 +DA:1940,0 +DA:1941,0 +DA:1942,0 +DA:1943,0 +DA:1944,0 +DA:1945,0 +DA:1946,0 +DA:1947,0 +DA:1952,0 +DA:1953,0 +DA:1954,0 +DA:1955,0 +DA:1956,0 +DA:1957,0 +DA:1958,0 +DA:1959,0 +DA:1960,0 +DA:1961,0 +DA:1962,0 +DA:1963,0 +DA:1964,0 +DA:1966,1 +DA:1968,0 +DA:1976,1 +DA:1995,0 +DA:2003,1 +DA:2005,0 +DA:2006,0 +DA:2008,1 +DA:2048,1 +DA:2049,1 +DA:2050,0 +DA:2051,0 +DA:2052,1 +DA:2053,1 +DA:2054,1 +DA:2055,1 +DA:2056,1 +DA:2057,1 +DA:2058,1 +DA:2060,1 +DA:2062,1 +DA:2064,0 +DA:2067,1 +DA:2070,1 +DA:2072,1 +DA:2076,1 +DA:2077,0 +DA:2082,1 +DA:2083,1 +DA:2084,1 +DA:2085,1 +DA:2086,1 +DA:2087,1 +DA:2088,1 +DA:2090,1 +DA:2091,1 +DA:2094,1 +DA:2098,1 +DA:2111,0 +DA:2112,0 +DA:2113,0 +LF:812 +LH:572 +FN:54,122,Asig.__init__ +FNDA:1,Asig.__init__ +FN:125,130,Asig.channels +FNDA:1,Asig.channels +FN:133,135,Asig.cn +FNDA:1,Asig.cn +FN:138,152,Asig.cn +FNDA:1,Asig.cn +FN:155,159,Asig.samples +FNDA:1,Asig.samples +FN:162,166,Asig.dur +FNDA:1,Asig.dur +FN:168,188,Asig.save_wavfile +FNDA:1,Asig.save_wavfile +FN:190,197,Asig._set_col_names +FNDA:1,Asig._set_col_names +FN:199,327,Asig.__getitem__ +FNDA:1,Asig.__getitem__ +FN:330,337,Asig.x +FNDA:1,Asig.x +FN:342,349,Asig.b +FNDA:1,Asig.b +FN:354,360,Asig.o +FNDA:1,Asig.o +FN:364,582,Asig.__setitem__ +FNDA:1,Asig.__setitem__ +FN:584,634,Asig.resample +FNDA:1,Asig.resample +FN:636,664,Asig.play +FNDA:1,Asig.play +FN:666,711,Asig.shift_channel +FNDA:1,Asig.shift_channel +FN:713,739,Asig.mono +FNDA:1,Asig.mono +FN:741,800,Asig.stereo +FNDA:1,Asig.stereo +FN:802,830,Asig.rewire +FNDA:1,Asig.rewire +FN:832,878,Asig.pan2 +FNDA:1,Asig.pan2 +FN:880,893,Asig.remove_DC +FNDA:1,Asig.remove_DC +FN:895,921,Asig.norm +FNDA:1,Asig.norm +FN:923,948,Asig.gain +FNDA:1,Asig.gain +FN:950,958,Asig.rms +FNDA:1,Asig.rms +FN:960,1024,Asig.plot +FNDA:1,Asig.plot +FN:996,997,Asig.plot.fn +FNDA:1,Asig.plot.fn +FN:1026,1028,Asig.get_duration +FNDA:1,Asig.get_duration +FN:1030,1032,Asig.get_times +FNDA:1,Asig.get_times +FN:1034,1041,Asig.__eq__ +FNDA:1,Asig.__eq__ +FN:1043,1052,Asig.__repr__ +FNDA:1,Asig.__repr__ +FN:1054,1092,Asig.__mul__ +FNDA:1,Asig.__mul__ +FN:1094,1097,Asig.__rmul__ +FNDA:1,Asig.__rmul__ +FN:1099,1141,Asig.__truediv__ +FNDA:1,Asig.__truediv__ +FN:1143,1146,Asig.__rtruediv__ +FNDA:1,Asig.__rtruediv__ +FN:1148,1186,Asig.__add__ +FNDA:1,Asig.__add__ +FN:1188,1189,Asig.__radd__ +FNDA:0,Asig.__radd__ +FN:1191,1234,Asig.__sub__ +FNDA:1,Asig.__sub__ +FN:1236,1239,Asig.__rsub__ +FNDA:1,Asig.__rsub__ +FN:1241,1319,Asig.find_events +FNDA:1,Asig.find_events +FN:1321,1351,Asig.select_event +FNDA:0,Asig.select_event +FN:1353,1360,Asig.plot_events +FNDA:0,Asig.plot_events +FN:1362,1400,Asig.fade_in +FNDA:1,Asig.fade_in +FN:1402,1440,Asig.fade_out +FNDA:1,Asig.fade_out +FN:1442,1493,Asig.iirfilter +FNDA:0,Asig.iirfilter +FN:1495,1513,Asig.plot_freqz +FNDA:0,Asig.plot_freqz +FN:1515,1567,Asig.envelope +FNDA:0,Asig.envelope +FN:1569,1607,Asig.adsr +FNDA:0,Asig.adsr +FN:1609,1641,Asig.window +FNDA:1,Asig.window +FN:1643,1691,Asig.window_op +FNDA:1,Asig.window_op +FN:1693,1752,Asig.overlap_add +FNDA:0,Asig.overlap_add +FN:1754,1758,Asig.to_spec +FNDA:1,Asig.to_spec +FN:1760,1768,Asig.to_stft +FNDA:1,Asig.to_stft +FN:1770,1798,Asig.to_mfcc +FNDA:1,Asig.to_mfcc +FN:1800,1869,Asig.plot_spectrum +FNDA:0,Asig.plot_spectrum +FN:1871,1877,Asig.spectrogram +FNDA:0,Asig.spectrogram +FN:1879,1881,Asig.get_size +FNDA:0,Asig.get_size +FN:1883,1917,Asig.append +FNDA:1,Asig.append +FN:1919,1964,Asig.add +FNDA:0,Asig.add +FN:1966,1974,Asig.flatten +FNDA:0,Asig.flatten +FN:1976,2001,Asig.pad +FNDA:0,Asig.pad +FN:2003,2006,Asig.custom +FNDA:0,Asig.custom +FN:2008,2096,Asig.convolve +FNDA:1,Asig.convolve +FN:2098,2115,Asig.apply +FNDA:0,Asig.apply +FNF:63 +FNH:47 +end_of_record +SF:pya/aspec.py +DA:1,1 +DA:2,1 +DA:4,1 +DA:5,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:12,1 +DA:15,1 +DA:18,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:61,1 +DA:63,0 +DA:65,1 +DA:67,1 +DA:74,1 +DA:92,0 +DA:93,0 +DA:94,0 +DA:96,0 +DA:97,0 +DA:99,0 +DA:100,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:112,0 +DA:114,0 +DA:115,0 +DA:117,1 +DA:144,1 +DA:159,1 +DA:161,1 +DA:162,1 +LF:59 +LH:39 +FN:18,59,Aspec.__init__ +FNDA:1,Aspec.__init__ +FN:61,63,Aspec.get_duration +FNDA:0,Aspec.get_duration +FN:65,72,Aspec.to_sig +FNDA:1,Aspec.to_sig +FN:74,115,Aspec.weight +FNDA:0,Aspec.weight +FN:117,159,Aspec.plot +FNDA:1,Aspec.plot +FN:161,164,Aspec.__repr__ +FNDA:1,Aspec.__repr__ +FNF:6 +FNH:4 +end_of_record +SF:pya/astft.py +DA:1,1 +DA:3,1 +DA:4,1 +DA:6,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:13,1 +DA:14,1 +DA:18,1 +DA:24,1 +DA:92,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:101,1 +DA:103,1 +DA:104,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:113,1 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:120,0 +DA:125,1 +DA:126,1 +DA:129,1 +DA:133,1 +DA:147,1 +DA:148,0 +DA:149,0 +DA:151,0 +DA:153,1 +DA:170,1 +DA:179,1 +DA:180,0 +DA:181,1 +DA:182,0 +DA:183,0 +DA:184,1 +DA:186,1 +DA:187,1 +DA:191,0 +DA:192,0 +DA:196,1 +DA:229,1 +DA:244,1 +DA:245,1 +DA:247,1 +DA:248,1 +LF:62 +LH:53 +FN:24,151,Astft.__init__ +FNDA:1,Astft.__init__ +FN:153,194,Astft.to_sig +FNDA:1,Astft.to_sig +FN:196,245,Astft.plot +FNDA:1,Astft.plot +FN:247,255,Astft.__repr__ +FNDA:1,Astft.__repr__ +FNF:4 +FNH:4 +end_of_record +SF:pya/backend/Dummy.py +DA:1,1 +DA:2,1 +DA:4,1 +DA:6,1 +DA:8,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:16,1 +DA:17,1 +DA:21,1 +DA:22,1 +DA:24,1 +DA:25,1 +DA:27,1 +DA:28,0 +DA:30,1 +DA:31,1 +DA:33,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:55,1 +DA:56,1 +DA:58,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:65,1 +DA:66,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:91,1 +DA:93,1 +DA:94,1 +DA:96,1 +DA:97,0 +DA:98,0 +DA:101,0 +DA:102,0 +DA:104,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,1 +DA:109,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,1 +DA:118,1 +DA:119,1 +DA:120,1 +DA:122,1 +DA:123,1 +LF:71 +LH:63 +FN:16,19,DummyBackend.__init__ +FNDA:1,DummyBackend.__init__ +FN:21,22,DummyBackend.get_device_count +FNDA:1,DummyBackend.get_device_count +FN:24,25,DummyBackend.get_device_info_by_index +FNDA:1,DummyBackend.get_device_info_by_index +FN:27,28,DummyBackend.get_default_input_device_info +FNDA:0,DummyBackend.get_default_input_device_info +FN:30,31,DummyBackend.get_default_output_device_info +FNDA:1,DummyBackend.get_default_output_device_info +FN:33,56,DummyBackend.open +FNDA:1,DummyBackend.open +FN:58,59,DummyBackend.process_buffer +FNDA:1,DummyBackend.process_buffer +FN:61,62,DummyBackend.terminate +FNDA:1,DummyBackend.terminate +FN:66,84,DummyStream.__init__ +FNDA:1,DummyStream.__init__ +FN:86,91,DummyStream.stop_stream +FNDA:1,DummyStream.stop_stream +FN:93,94,DummyStream.close +FNDA:1,DummyStream.close +FN:96,102,DummyStream._generate_data +FNDA:0,DummyStream._generate_data +FN:104,109,DummyStream._process_data +FNDA:1,DummyStream._process_data +FN:111,120,DummyStream.start_stream +FNDA:1,DummyStream.start_stream +FN:122,123,DummyStream.is_active +FNDA:1,DummyStream.is_active +FNF:15 +FNH:13 +end_of_record +SF:pya/backend/Jupyter.py +DA:1,1 +DA:2,1 +DA:4,1 +DA:6,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:13,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:28,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:41,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:51,0 +DA:58,0 +DA:65,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:71,0 +DA:72,0 +DA:75,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:81,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:87,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:93,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 +DA:101,0 +DA:102,0 +DA:106,0 +DA:108,0 +DA:213,0 +DA:214,0 +DA:215,0 +DA:217,0 +DA:218,0 +DA:219,0 +DA:220,0 +DA:222,0 +DA:223,0 +DA:224,0 +DA:226,0 +DA:227,0 +DA:228,0 +DA:229,0 +DA:231,0 +DA:232,0 +LF:77 +LH:3 +FN:21,36,JupyterBackend.__init__ +FNDA:0,JupyterBackend.__init__ +FN:38,39,JupyterBackend.get_device_count +FNDA:0,JupyterBackend.get_device_count +FN:41,42,JupyterBackend.get_device_info_by_index +FNDA:0,JupyterBackend.get_device_info_by_index +FN:44,45,JupyterBackend.get_default_input_device_info +FNDA:0,JupyterBackend.get_default_input_device_info +FN:47,48,JupyterBackend.get_default_output_device_info +FNDA:0,JupyterBackend.get_default_output_device_info +FN:50,66,JupyterBackend.open +FNDA:0,JupyterBackend.open +FN:68,69,JupyterBackend.process_buffer +FNDA:0,JupyterBackend.process_buffer +FN:71,72,JupyterBackend.terminate +FNDA:0,JupyterBackend.terminate +FN:76,211,JupyterStream.__init__ +FNDA:0,JupyterStream.__init__ +FN:83,87,JupyterStream.__init__.bridge +FNDA:0,JupyterStream.__init__.bridge +FN:89,91,JupyterStream.__init__.ws_runner +FNDA:0,JupyterStream.__init__.ws_runner +FN:93,99,JupyterStream.__init__.loop_thread +FNDA:0,JupyterStream.__init__.loop_thread +FN:214,215,JupyterStream.set_buffer_threshold +FNDA:0,JupyterStream.set_buffer_threshold +FN:217,220,JupyterStream.stop_stream +FNDA:0,JupyterStream.stop_stream +FN:222,224,JupyterStream.close +FNDA:0,JupyterStream.close +FN:226,229,JupyterStream.start_stream +FNDA:0,JupyterStream.start_stream +FN:231,232,JupyterStream.is_active +FNDA:0,JupyterStream.is_active +FNF:17 +FNH:0 +end_of_record +SF:pya/backend/PyAudio.py +DA:1,1 +DA:3,1 +DA:5,0 +DA:7,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:26,0 +DA:30,0 +DA:31,0 +DA:33,0 +DA:34,0 +DA:36,0 +DA:37,0 +DA:39,0 +DA:40,0 +DA:42,0 +DA:56,0 +DA:70,0 +DA:71,0 +DA:73,0 +DA:74,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +LF:35 +LH:2 +FN:16,28,PyAudioBackend.__init__ +FNDA:0,PyAudioBackend.__init__ +FN:30,31,PyAudioBackend.get_device_count +FNDA:0,PyAudioBackend.get_device_count +FN:33,34,PyAudioBackend.get_device_info_by_index +FNDA:0,PyAudioBackend.get_device_info_by_index +FN:36,37,PyAudioBackend.get_default_input_device_info +FNDA:0,PyAudioBackend.get_default_input_device_info +FN:39,40,PyAudioBackend.get_default_output_device_info +FNDA:0,PyAudioBackend.get_default_output_device_info +FN:42,71,PyAudioBackend.open +FNDA:0,PyAudioBackend.open +FN:73,74,PyAudioBackend.process_buffer +FNDA:0,PyAudioBackend.process_buffer +FN:76,79,PyAudioBackend.terminate +FNDA:0,PyAudioBackend.terminate +FNF:8 +FNH:0 +end_of_record +SF:pya/backend/__init__.py +DA:1,1 +DA:3,1 +DA:4,1 +DA:6,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:12,1 +DA:14,0 +DA:19,1 +DA:20,1 +DA:22,0 +LF:12 +LH:10 +end_of_record +SF:pya/backend/base.py +DA:1,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:9,1 +DA:10,1 +DA:13,1 +DA:14,1 +DA:17,1 +DA:18,1 +DA:21,1 +DA:22,1 +DA:25,1 +DA:26,1 +DA:29,1 +DA:30,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:39,1 +DA:40,1 +DA:43,1 +DA:44,1 +DA:47,1 +DA:48,1 +LF:25 +LH:25 +FN:6,7,BackendBase.get_device_count +FNDA:0,BackendBase.get_device_count +FN:10,11,BackendBase.get_device_info_by_index +FNDA:0,BackendBase.get_device_info_by_index +FN:14,15,BackendBase.get_default_output_device_info +FNDA:0,BackendBase.get_default_output_device_info +FN:18,19,BackendBase.get_default_input_device_info +FNDA:0,BackendBase.get_default_input_device_info +FN:22,23,BackendBase.open +FNDA:0,BackendBase.open +FN:26,27,BackendBase.terminate +FNDA:0,BackendBase.terminate +FN:30,31,BackendBase.process_buffer +FNDA:0,BackendBase.process_buffer +FN:36,37,StreamBase.is_active +FNDA:0,StreamBase.is_active +FN:40,41,StreamBase.start_stream +FNDA:0,StreamBase.start_stream +FN:44,45,StreamBase.stop_stream +FNDA:0,StreamBase.stop_stream +FN:48,49,StreamBase.close +FNDA:0,StreamBase.close +FNF:11 +FNH:0 +end_of_record +SF:pya/helper/__init__.py +DA:4,1 +DA:5,1 +DA:6,1 +LF:3 +LH:3 +end_of_record +SF:pya/helper/backend.py +DA:1,1 +DA:3,1 +DA:4,0 +DA:5,0 +DA:6,0 +DA:9,1 +DA:17,1 +DA:18,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:25,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:40,1 +DA:41,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:49,1 +DA:50,0 +DA:52,0 +DA:54,0 +DA:55,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:65,0 +DA:68,1 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:98,0 +LF:42 +LH:7 +FN:17,37,get_server_info +FNDA:0,get_server_info +FN:40,46,try_pyaudio_backend +FNDA:0,try_pyaudio_backend +FN:49,65,try_jupyter_backend +FNDA:0,try_jupyter_backend +FN:68,98,determine_backend +FNDA:0,determine_backend +FNF:4 +FNH:0 +end_of_record +SF:pya/helper/codec.py +DA:8,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:16,1 +DA:17,1 +DA:19,1 +DA:38,1 +DA:40,1 +DA:41,0 +DA:43,1 +DA:46,1 +DA:50,1 +DA:54,1 +DA:60,1 +DA:64,1 +DA:68,1 +DA:72,1 +DA:76,1 +DA:80,1 +DA:84,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:94,1 +DA:95,1 +DA:97,1 +DA:99,1 +DA:100,1 +DA:102,1 +DA:104,1 +DA:105,1 +DA:107,0 +DA:109,1 +DA:124,1 +DA:128,1 +DA:129,1 +DA:131,1 +DA:132,1 +DA:133,1 +DA:135,1 +DA:136,0 +DA:139,1 +DA:142,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:151,1 +DA:153,1 +DA:154,1 +DA:156,1 +DA:158,1 +DA:165,1 +DA:167,1 +DA:169,1 +DA:170,0 +DA:171,0 +DA:173,1 +DA:175,1 +DA:176,1 +DA:177,1 +DA:178,1 +DA:180,1 +DA:181,1 +DA:182,1 +DA:184,1 +DA:186,1 +DA:187,1 +DA:190,1 +DA:194,1 +DA:195,1 +DA:196,1 +DA:197,1 +DA:198,1 +DA:199,1 +DA:200,1 +DA:202,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:206,1 +DA:207,1 +DA:208,1 +DA:211,1 +DA:219,1 +DA:220,1 +DA:221,1 +DA:222,1 +DA:223,0 +DA:224,0 +DA:226,0 +DA:229,1 +DA:231,1 +DA:232,1 +DA:239,0 +DA:240,0 +DA:242,1 +DA:243,1 +DA:248,1 +DA:251,1 +DA:254,1 +DA:255,1 +DA:260,1 +DA:262,1 +DA:263,0 +DA:264,0 +DA:265,0 +DA:269,0 +DA:272,0 +DA:275,1 +DA:276,1 +DA:278,1 +DA:287,0 +DA:288,0 +DA:294,1 +DA:295,0 +DA:296,0 +DA:298,0 +DA:300,0 +DA:304,1 +DA:305,1 +DA:308,1 +DA:309,1 +DA:314,1 +DA:315,1 +DA:317,1 +DA:318,1 +DA:320,0 +DA:322,1 +DA:324,1 +DA:325,1 +DA:326,1 +DA:327,1 +DA:329,0 +DA:331,1 +DA:332,1 +DA:334,1 +DA:336,1 +DA:337,0 +DA:338,1 +DA:339,0 +DA:340,1 +DA:341,1 +DA:342,1 +DA:343,1 +DA:344,1 +DA:345,1 +DA:346,1 +DA:348,1 +DA:354,1 +DA:355,1 +DA:356,1 +DA:358,0 +DA:361,1 +DA:362,1 +DA:363,1 +DA:364,1 +DA:365,0 +DA:367,1 +DA:368,1 +DA:369,0 +DA:371,1 +DA:373,0 +DA:376,1 +DA:377,1 +DA:378,1 +DA:379,1 +DA:386,0 +DA:388,1 +DA:390,1 +DA:392,1 +DA:393,1 +DA:394,1 +DA:395,1 +DA:396,0 +DA:399,1 +DA:401,1 +DA:402,0 +DA:404,1 +DA:406,1 +DA:407,0 +DA:408,0 +DA:409,0 +DA:414,0 +DA:416,1 +DA:418,1 +DA:423,1 +DA:426,1 +DA:427,1 +DA:428,1 +DA:432,1 +DA:433,1 +DA:434,1 +DA:435,1 +DA:440,1 +DA:441,1 +DA:444,1 +DA:445,1 +DA:448,1 +DA:467,1 +DA:468,1 +DA:470,1 +DA:471,1 +DA:474,1 +DA:475,1 +DA:477,1 +LF:217 +LH:181 +FN:87,92,BaseAudioFile.__init__ +FNDA:1,BaseAudioFile.__init__ +FN:95,97,BaseAudioFile.channels +FNDA:1,BaseAudioFile.channels +FN:100,102,BaseAudioFile.samplerate +FNDA:1,BaseAudioFile.samplerate +FN:105,107,BaseAudioFile.duration +FNDA:0,BaseAudioFile.duration +FN:109,122,BaseAudioFile.read_data +FNDA:0,BaseAudioFile.read_data +FN:124,126,BaseAudioFile.close +FNDA:0,BaseAudioFile.close +FN:128,129,BaseAudioFile.__enter__ +FNDA:1,BaseAudioFile.__enter__ +FN:131,133,BaseAudioFile.__exit__ +FNDA:1,BaseAudioFile.__exit__ +FN:135,136,BaseAudioFile.__iter__ +FNDA:0,BaseAudioFile.__iter__ +FN:142,154,SoundFileAudioFile.__init__ +FNDA:1,SoundFileAudioFile.__init__ +FN:156,165,SoundFileAudioFile._get_bytes_per_sample +FNDA:1,SoundFileAudioFile._get_bytes_per_sample +FN:167,171,SoundFileAudioFile._check +FNDA:1,SoundFileAudioFile._check +FN:173,182,SoundFileAudioFile.read_data +FNDA:1,SoundFileAudioFile.read_data +FN:184,187,SoundFileAudioFile.close +FNDA:1,SoundFileAudioFile.close +FN:194,200,QueueReaderThread.__init__ +FNDA:1,QueueReaderThread.__init__ +FN:202,208,QueueReaderThread.run +FNDA:1,QueueReaderThread.run +FN:211,226,popen_multiple +FNDA:1,popen_multiple +FN:229,243,ffmpeg_available +FNDA:1,ffmpeg_available +FN:254,315,FFmpegAudioFile.__init__ +FNDA:1,FFmpegAudioFile.__init__ +FN:318,320,FFmpegAudioFile.raw_str_info +FNDA:0,FFmpegAudioFile.raw_str_info +FN:322,346,FFmpegAudioFile._get_info +FNDA:1,FFmpegAudioFile._get_info +FN:348,386,FFmpegAudioFile._parse_info +FNDA:1,FFmpegAudioFile._parse_info +FN:388,414,FFmpegAudioFile.read_data +FNDA:1,FFmpegAudioFile.read_data +FN:416,445,FFmpegAudioFile.close +FNDA:1,FFmpegAudioFile.close +FN:448,477,audio_read +FNDA:1,audio_read +FNF:25 +FNH:20 +end_of_record +SF:pya/helper/helpers.py +DA:2,1 +DA:3,1 +DA:4,1 +DA:6,1 +DA:7,1 +DA:9,1 +DA:11,1 +DA:30,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:64,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:72,1 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:82,0 +DA:83,0 +DA:85,0 +DA:86,0 +DA:88,0 +DA:91,1 +DA:112,0 +DA:114,0 +DA:116,0 +DA:119,1 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:126,0 +DA:129,1 +DA:131,0 +DA:132,0 +DA:133,0 +DA:134,0 +DA:135,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:146,1 +DA:147,0 +DA:148,0 +DA:149,0 +DA:150,0 +DA:151,0 +DA:155,0 +DA:156,0 +DA:159,1 +DA:181,1 +DA:182,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:188,1 +DA:189,1 +DA:193,0 +DA:198,1 +DA:200,1 +DA:203,1 +DA:217,1 +DA:218,1 +DA:219,1 +DA:222,1 +DA:224,1 +DA:231,1 +DA:232,1 +DA:233,1 +DA:234,1 +DA:237,1 +DA:259,1 +DA:260,1 +DA:261,1 +DA:262,1 +DA:263,0 +DA:265,1 +DA:266,1 +DA:267,1 +DA:269,1 +DA:270,1 +DA:271,1 +DA:273,1 +DA:274,1 +DA:276,0 +DA:282,0 +DA:283,0 +DA:284,0 +DA:285,0 +DA:287,0 +DA:288,0 +DA:289,1 +DA:292,1 +DA:309,1 +DA:310,1 +DA:314,1 +DA:315,1 +DA:318,1 +DA:335,1 +LF:114 +LH:66 +FN:30,61,spectrum +FNDA:1,spectrum +FN:64,69,normalize +FNDA:1,normalize +FN:72,88,audio_from_file +FNDA:0,audio_from_file +FN:91,116,buf_to_float +FNDA:0,buf_to_float +FN:119,126,_try_initializing_pyaudio +FNDA:0,_try_initializing_pyaudio +FN:129,143,device_info +FNDA:0,device_info +FN:146,156,find_device +FNDA:0,find_device +FN:159,195,padding +FNDA:1,padding +FN:198,200,is_pow2 +FNDA:1,is_pow2 +FN:203,219,next_pow2 +FNDA:1,next_pow2 +FN:222,228,round_half_up +FNDA:1,round_half_up +FN:231,234,rolling_window +FNDA:1,rolling_window +FN:237,289,signal_to_frame +FNDA:1,signal_to_frame +FN:292,315,magspec +FNDA:1,magspec +FN:318,335,powspec +FNDA:1,powspec +FNF:15 +FNH:10 +end_of_record +SF:pya/helper/visualization.py +DA:1,1 +DA:3,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:10,1 +DA:13,1 +DA:47,1 +DA:48,1 +DA:53,1 +DA:54,1 +DA:56,1 +DA:58,1 +DA:61,1 +DA:62,1 +DA:64,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,0 +DA:71,0 +DA:72,0 +DA:79,0 +DA:80,0 +DA:81,0 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:95,1 +DA:129,1 +DA:131,1 +DA:133,1 +DA:134,1 +DA:135,1 +DA:136,1 +DA:138,1 +DA:140,1 +DA:141,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:149,1 +DA:150,1 +DA:152,1 +DA:153,1 +DA:154,1 +DA:155,1 +DA:156,1 +DA:157,1 +DA:159,1 +DA:165,1 +DA:166,1 +DA:167,1 +DA:168,1 +DA:169,1 +DA:170,1 +DA:171,1 +DA:172,1 +DA:173,1 +DA:174,1 +DA:175,1 +DA:176,1 +DA:177,1 +DA:178,1 +DA:179,1 +LF:77 +LH:71 +FN:13,92,basicplot +FNDA:1,basicplot +FN:95,179,gridplot +FNDA:1,gridplot +FNF:2 +FNH:2 +end_of_record +SF:pya/ugen.py +DA:1,1 +DA:3,1 +DA:4,1 +DA:6,1 +DA:7,1 +DA:10,1 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:25,1 +DA:30,1 +DA:49,1 +DA:50,1 +DA:52,1 +DA:91,1 +DA:92,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:100,1 +DA:139,1 +DA:140,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:148,1 +DA:191,1 +DA:192,1 +DA:202,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:207,1 +DA:249,1 +DA:250,1 +DA:254,1 +DA:255,1 +DA:256,1 +DA:257,1 +DA:259,1 +DA:299,1 +DA:301,1 +DA:302,1 +DA:304,1 +DA:306,1 +DA:307,1 +DA:308,1 +DA:309,1 +DA:310,1 +DA:311,1 +DA:312,1 +DA:313,1 +DA:314,1 +DA:315,1 +DA:316,1 +DA:317,1 +DA:318,1 +DA:319,1 +DA:320,1 +DA:321,1 +DA:322,1 +LF:66 +LH:66 +FN:10,27,get_num_of_rows +FNDA:1,get_num_of_rows +FN:49,50,Ugen.__init__ +FNDA:1,Ugen.__init__ +FN:52,98,Ugen.sine +FNDA:1,Ugen.sine +FN:100,146,Ugen.cos +FNDA:1,Ugen.cos +FN:148,205,Ugen.square +FNDA:1,Ugen.square +FN:207,257,Ugen.sawtooth +FNDA:1,Ugen.sawtooth +FN:259,322,Ugen.noise +FNDA:1,Ugen.noise +FNF:7 +FNH:7 +end_of_record +SF:pya/version.py +DA:1,1 +LF:1 +LH:1 +end_of_record diff --git a/docs/_autosummary/pya.amfcc.rst b/docs/_autosummary/pya.amfcc.rst new file mode 100644 index 00000000..8183fafb --- /dev/null +++ b/docs/_autosummary/pya.amfcc.rst @@ -0,0 +1,26 @@ +pya.amfcc +========= + +.. automodule:: pya.amfcc + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Amfcc + + + + + + diff --git a/docs/_autosummary/pya.arecorder.rst b/docs/_autosummary/pya.arecorder.rst new file mode 100644 index 00000000..263fc55f --- /dev/null +++ b/docs/_autosummary/pya.arecorder.rst @@ -0,0 +1,26 @@ +pya.arecorder +============= + +.. automodule:: pya.arecorder + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Arecorder + + + + + + diff --git a/docs/_autosummary/pya.aserver.rst b/docs/_autosummary/pya.aserver.rst new file mode 100644 index 00000000..9509f076 --- /dev/null +++ b/docs/_autosummary/pya.aserver.rst @@ -0,0 +1,26 @@ +pya.aserver +=========== + +.. automodule:: pya.aserver + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Aserver + + + + + + diff --git a/docs/_autosummary/pya.asig.rst b/docs/_autosummary/pya.asig.rst new file mode 100644 index 00000000..fa46fd36 --- /dev/null +++ b/docs/_autosummary/pya.asig.rst @@ -0,0 +1,26 @@ +pya.asig +======== + +.. automodule:: pya.asig + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Asig + + + + + + diff --git a/docs/_autosummary/pya.aspec.rst b/docs/_autosummary/pya.aspec.rst new file mode 100644 index 00000000..a1c9e217 --- /dev/null +++ b/docs/_autosummary/pya.aspec.rst @@ -0,0 +1,26 @@ +pya.aspec +========= + +.. automodule:: pya.aspec + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Aspec + + + + + + diff --git a/docs/_autosummary/pya.astft.rst b/docs/_autosummary/pya.astft.rst new file mode 100644 index 00000000..5aacb4f9 --- /dev/null +++ b/docs/_autosummary/pya.astft.rst @@ -0,0 +1,26 @@ +pya.astft +========= + +.. automodule:: pya.astft + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + Astft + + + + + + diff --git a/docs/_autosummary/pya.backend.Dummy.rst b/docs/_autosummary/pya.backend.Dummy.rst new file mode 100644 index 00000000..08963929 --- /dev/null +++ b/docs/_autosummary/pya.backend.Dummy.rst @@ -0,0 +1,27 @@ +pya.backend.Dummy +================= + +.. automodule:: pya.backend.Dummy + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + DummyBackend + DummyStream + + + + + + diff --git a/docs/_autosummary/pya.backend.base.rst b/docs/_autosummary/pya.backend.base.rst new file mode 100644 index 00000000..899d98af --- /dev/null +++ b/docs/_autosummary/pya.backend.base.rst @@ -0,0 +1,27 @@ +pya.backend.base +================ + +.. automodule:: pya.backend.base + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + + BackendBase + StreamBase + + + + + + diff --git a/docs/_autosummary/pya.backend.rst b/docs/_autosummary/pya.backend.rst new file mode 100644 index 00000000..00e396c3 --- /dev/null +++ b/docs/_autosummary/pya.backend.rst @@ -0,0 +1,29 @@ +pya.backend +=========== + +.. automodule:: pya.backend + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + determine_backend + get_server_info + try_jupyter_backend + try_pyaudio_backend + + + + + + + + + + diff --git a/docs/_autosummary/pya.helper.backend.rst b/docs/_autosummary/pya.helper.backend.rst new file mode 100644 index 00000000..f9ac5e11 --- /dev/null +++ b/docs/_autosummary/pya.helper.backend.rst @@ -0,0 +1,29 @@ +pya.helper.backend +================== + +.. automodule:: pya.helper.backend + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + determine_backend + get_server_info + try_jupyter_backend + try_pyaudio_backend + + + + + + + + + + diff --git a/docs/_autosummary/pya.helper.codec.rst b/docs/_autosummary/pya.helper.codec.rst new file mode 100644 index 00000000..1f9cb354 --- /dev/null +++ b/docs/_autosummary/pya.helper.codec.rst @@ -0,0 +1,51 @@ +pya.helper.codec +================ + +.. automodule:: pya.helper.codec + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + audio_read + ffmpeg_available + popen_multiple + + + + + + .. rubric:: Classes + + .. autosummary:: + + BaseAudioFile + FFmpegAudioFile + QueueReaderThread + SoundFileAudioFile + + + + + + .. rubric:: Exceptions + + .. autosummary:: + + BitWidthError + CommunicationError + DecodeError + FFmpegError + FFmpegNotInstalledError + FFmpegReadTimeoutError + NoBackendError + NoFileError + UnsupportedError + + diff --git a/docs/_autosummary/pya.helper.helpers.rst b/docs/_autosummary/pya.helper.helpers.rst new file mode 100644 index 00000000..85eb4ea3 --- /dev/null +++ b/docs/_autosummary/pya.helper.helpers.rst @@ -0,0 +1,39 @@ +pya.helper.helpers +================== + +.. automodule:: pya.helper.helpers + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + audio_from_file + buf_to_float + device_info + find_device + is_pow2 + magspec + next_pow2 + normalize + padding + powspec + rolling_window + round_half_up + signal_to_frame + spectrum + + + + + + + + + + diff --git a/docs/_autosummary/pya.helper.rst b/docs/_autosummary/pya.helper.rst new file mode 100644 index 00000000..32e92b39 --- /dev/null +++ b/docs/_autosummary/pya.helper.rst @@ -0,0 +1,33 @@ +pya.helper +========== + +.. automodule:: pya.helper + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + pya.helper.backend + pya.helper.codec + pya.helper.helpers + pya.helper.visualization diff --git a/docs/_autosummary/pya.helper.visualization.rst b/docs/_autosummary/pya.helper.visualization.rst new file mode 100644 index 00000000..73bc171e --- /dev/null +++ b/docs/_autosummary/pya.helper.visualization.rst @@ -0,0 +1,27 @@ +pya.helper.visualization +======================== + +.. automodule:: pya.helper.visualization + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + basicplot + gridplot + + + + + + + + + + diff --git a/docs/_autosummary/pya.rst b/docs/_autosummary/pya.rst new file mode 100644 index 00000000..aa599b55 --- /dev/null +++ b/docs/_autosummary/pya.rst @@ -0,0 +1,46 @@ +pya +=== + +.. automodule:: pya + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + shutdown + startup + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + pya.amfcc + pya.arecorder + pya.aserver + pya.asig + pya.aspec + pya.astft + pya.backend + pya.helper + pya.ugen + pya.version diff --git a/docs/_autosummary/pya.ugen.rst b/docs/_autosummary/pya.ugen.rst new file mode 100644 index 00000000..ecf8966a --- /dev/null +++ b/docs/_autosummary/pya.ugen.rst @@ -0,0 +1,32 @@ +pya.ugen +======== + +.. automodule:: pya.ugen + + + + + + + + .. rubric:: Functions + + .. autosummary:: + + get_num_of_rows + + + + + + .. rubric:: Classes + + .. autosummary:: + + Ugen + + + + + + diff --git a/docs/_autosummary/pya.version.rst b/docs/_autosummary/pya.version.rst new file mode 100644 index 00000000..79dcd917 --- /dev/null +++ b/docs/_autosummary/pya.version.rst @@ -0,0 +1,20 @@ +pya.version +=========== + +.. automodule:: pya.version + + + + + + + + + + + + + + + + diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 00000000..f6eec178 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,8 @@ +API Reference +============= + +.. autosummary:: + :toctree: _autosummary + :recursive: + + pya diff --git a/docs/readme.rst b/docs/readme.rst new file mode 100644 index 00000000..339dc8f4 --- /dev/null +++ b/docs/readme.rst @@ -0,0 +1,2 @@ +.. include:: ../README.md + :parser: myst_parser.sphinx_ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..1b42236e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,91 @@ +[project] +name = "pya" +version = "0.5.2" +description = 'Python audio coding classes - for dsp, sound synthesis and and sonification' +authors = [ + { name = "Thomas Hermann", email = "thermann@techfak.uni-bielefeld.de"}, + { name = "Jiajun Yang", email = ""}, + { name = "Alexander Neumann ...", email = ""}, + + { name = "Dennis Reinsch", email = "dreinsch@techfak.uni-bielefeld.de"}, + { name = "Jannis Müller", email = ""}, +] +maintainers = [ + {name = "Fabian Hommel", email = "fhommel@techfak.uni-bielefeld.de"} +] +readme = "README.md" +keywords=["sonification", "sound synthesis"] +requires-python = ">=3.11" +license = "MIT" +license-files = ["LICEN[CS]E*"] +classifiers = [ + "Programming Language :: Python :: 3", + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Topic :: Multimedia :: Sound/Audio", + "Topic :: Multimedia :: Sound/Audio :: Analysis", + "Topic :: Multimedia :: Sound/Audio :: Sound Synthesis" +] +dependencies = [ + "pyamapping", + "scipy>=1.7.3", + "matplotlib>=3.5.3", + "soundfile>=0.13.0" +] + +[project.urls] +github = "https://github.com/interactive-sonification/pya" + + + +[project.optional-dependencies] +example-notebooks = ["notebook"] +pyaudio = [ "pyaudio>=0.2.12" ] +remote = [ "notebook", "websocket", "ipywidgets" ] + +[tool.uv] +dev-dependencies = [ + "tox", + "pytest", + "pytest-cov", + "pre-commit", + "sphinx==7.2.6", + "sphinx-rtd-theme==2.0.0", + "myst-parser", + "pydocstyle", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["pya"] + +[tool.ruff] +line-length = 88 +exclude = ["examples/", "dev/"] + +[tool.ruff.lint] +select = ["E", "F", "I", "T10"] # E/F = flake8, I = isort +ignore = ["E702"] + +[tool.ruff.lint.isort] +known-first-party = ["pya"] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" + +[tool.pytest.ini_options] +addopts = "--cov=pya --cov-report=lcov --cov-report=term-missing" +testpaths = ["tests"] + +[tool.coverage.run] +source = ["pya"] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "raise NotImplementedError", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..b6dd1e93 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2998 @@ +version = 1 +revision = 1 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version >= '3.12' and python_full_version < '3.14'", + "python_full_version < '3.12'", +] + +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353 }, +] + +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, +] + +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657 }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393 }, + { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328 }, + { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269 }, + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558 }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364 }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637 }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934 }, + { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158 }, + { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597 }, + { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231 }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121 }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177 }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090 }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246 }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126 }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343 }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777 }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180 }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715 }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149 }, +] + +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797 }, +] + +[[package]] +name = "asttokens" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047 }, +] + +[[package]] +name = "async-lru" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403 }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548 }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721 }, +] + +[[package]] +name = "bleach" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437 }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + +[[package]] +name = "cachetools" +version = "7.0.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/7b/1755ed2c6bfabd1d98b37ae73152f8dcf94aa40fee119d163c19ed484704/cachetools-7.0.6.tar.gz", hash = "sha256:e5d524d36d65703a87243a26ff08ad84f73352adbeafb1cde81e207b456aaf24", size = 37526 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/c4/cf76242a5da1410917107ff14551764aa405a5fd10cd10cf9a5ca8fa77f4/cachetools-7.0.6-py3-none-any.whl", hash = "sha256:4e94956cfdd3086f12042cdd29318f5ced3893014f7d0d059bf3ead3f85b7f8b", size = 13976 }, +] + +[[package]] +name = "certifi" +version = "2026.4.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707 }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344 }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560 }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613 }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476 }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374 }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597 }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574 }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971 }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972 }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078 }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076 }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820 }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635 }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271 }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048 }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529 }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097 }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983 }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519 }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572 }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963 }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361 }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932 }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557 }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762 }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230 }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043 }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446 }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101 }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948 }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422 }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499 }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928 }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302 }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909 }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402 }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780 }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320 }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487 }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049 }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793 }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300 }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244 }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828 }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926 }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328 }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650 }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687 }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773 }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013 }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593 }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354 }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480 }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584 }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443 }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437 }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487 }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726 }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195 }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705 }, + { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419 }, + { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901 }, + { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742 }, + { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061 }, + { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239 }, + { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173 }, + { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841 }, + { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304 }, + { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455 }, + { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036 }, + { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739 }, + { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277 }, + { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819 }, + { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281 }, + { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843 }, + { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328 }, + { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061 }, + { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031 }, + { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239 }, + { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589 }, + { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733 }, + { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652 }, + { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229 }, + { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552 }, + { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806 }, + { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316 }, + { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274 }, + { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468 }, + { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460 }, + { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330 }, + { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828 }, + { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627 }, + { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008 }, + { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303 }, + { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282 }, + { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595 }, + { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986 }, + { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711 }, + { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036 }, + { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998 }, + { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056 }, + { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537 }, + { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176 }, + { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723 }, + { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085 }, + { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819 }, + { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915 }, + { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234 }, + { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042 }, + { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706 }, + { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727 }, + { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882 }, + { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860 }, + { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564 }, + { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276 }, + { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238 }, + { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189 }, + { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352 }, + { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024 }, + { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869 }, + { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541 }, + { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634 }, + { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384 }, + { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133 }, + { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257 }, + { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851 }, + { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393 }, + { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251 }, + { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609 }, + { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014 }, + { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979 }, + { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238 }, + { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110 }, + { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824 }, + { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103 }, + { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194 }, + { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827 }, + { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168 }, + { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018 }, + { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294 }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773 }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149 }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222 }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234 }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555 }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238 }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218 }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867 }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677 }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234 }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123 }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419 }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979 }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653 }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536 }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397 }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601 }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288 }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386 }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018 }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567 }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655 }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257 }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034 }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672 }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234 }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169 }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859 }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062 }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932 }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024 }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578 }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524 }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730 }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897 }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751 }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486 }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106 }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548 }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297 }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023 }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157 }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570 }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713 }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189 }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251 }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810 }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871 }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264 }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819 }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650 }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833 }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692 }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424 }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300 }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769 }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892 }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748 }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554 }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118 }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555 }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295 }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027 }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428 }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331 }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831 }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809 }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593 }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202 }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207 }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315 }, +] + +[[package]] +name = "coverage" +version = "7.13.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hash = "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", size = 915967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d", size = 219381 }, + { url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587", size = 219880 }, + { url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642", size = 250303 }, + { url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b", size = 252218 }, + { url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686", size = 254326 }, + { url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743", size = 256267 }, + { url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75", size = 250430 }, + { url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209", size = 252017 }, + { url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a", size = 250080 }, + { url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e", size = 253843 }, + { url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd", size = 249802 }, + { url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8", size = 250707 }, + { url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl", hash = "sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf", size = 221880 }, + { url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9", size = 222816 }, + { url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl", hash = "sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028", size = 221483 }, + { url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01", size = 219554 }, + { url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422", size = 219908 }, + { url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f", size = 251419 }, + { url = "https://files.pythonhosted.org/packages/8c/49/cd14b789536ac6a4778c453c6a2338bc0a2fb60c5a5a41b4008328b9acc1/coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5", size = 254159 }, + { url = "https://files.pythonhosted.org/packages/9d/00/7b0edcfe64e2ed4c0340dac14a52ad0f4c9bd0b8b5e531af7d55b703db7c/coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376", size = 255270 }, + { url = "https://files.pythonhosted.org/packages/93/89/7ffc4ba0f5d0a55c1e84ea7cee39c9fc06af7b170513d83fbf3bbefce280/coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256", size = 257538 }, + { url = "https://files.pythonhosted.org/packages/81/bd/73ddf85f93f7e6fa83e77ccecb6162d9415c79007b4bc124008a4995e4a7/coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c", size = 251821 }, + { url = "https://files.pythonhosted.org/packages/a0/81/278aff4e8dec4926a0bcb9486320752811f543a3ce5b602cc7a29978d073/coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5", size = 253191 }, + { url = "https://files.pythonhosted.org/packages/70/ee/fe1621488e2e0a58d7e94c4800f0d96f79671553488d401a612bebae324b/coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09", size = 251337 }, + { url = "https://files.pythonhosted.org/packages/37/a6/f79fb37aa104b562207cc23cb5711ab6793608e246cae1e93f26b2236ed9/coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9", size = 255404 }, + { url = "https://files.pythonhosted.org/packages/75/f0/ed15262a58ec81ce457ceb717b7f78752a1713556b19081b76e90896e8d4/coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf", size = 250903 }, + { url = "https://files.pythonhosted.org/packages/0f/e9/9129958f20e7e9d4d56d51d42ccf708d15cac355ff4ac6e736e97a9393d2/coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c", size = 252780 }, + { url = "https://files.pythonhosted.org/packages/a4/d7/0ad9b15812d81272db94379fe4c6df8fd17781cc7671fdfa30c76ba5ff7b/coverage-7.13.5-cp312-cp312-win32.whl", hash = "sha256:bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf", size = 222093 }, + { url = "https://files.pythonhosted.org/packages/29/3d/821a9a5799fac2556bcf0bd37a70d1d11fa9e49784b6d22e92e8b2f85f18/coverage-7.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810", size = 222900 }, + { url = "https://files.pythonhosted.org/packages/d4/fa/2238c2ad08e35cf4f020ea721f717e09ec3152aea75d191a7faf3ef009a8/coverage-7.13.5-cp312-cp312-win_arm64.whl", hash = "sha256:bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de", size = 221515 }, + { url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1", size = 219576 }, + { url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3", size = 219942 }, + { url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26", size = 250935 }, + { url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3", size = 253541 }, + { url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b", size = 254780 }, + { url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a", size = 256912 }, + { url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969", size = 251165 }, + { url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161", size = 252908 }, + { url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15", size = 250873 }, + { url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1", size = 255030 }, + { url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6", size = 250694 }, + { url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17", size = 252469 }, + { url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl", hash = "sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85", size = 222112 }, + { url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b", size = 222923 }, + { url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl", hash = "sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664", size = 221540 }, + { url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d", size = 220262 }, + { url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0", size = 220617 }, + { url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806", size = 261912 }, + { url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3", size = 263987 }, + { url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9", size = 266416 }, + { url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd", size = 267558 }, + { url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606", size = 261163 }, + { url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e", size = 263981 }, + { url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0", size = 261604 }, + { url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87", size = 265321 }, + { url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479", size = 260502 }, + { url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2", size = 262688 }, + { url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl", hash = "sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a", size = 222788 }, + { url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl", hash = "sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819", size = 223851 }, + { url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl", hash = "sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911", size = 222104 }, + { url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f", size = 219621 }, + { url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e", size = 219953 }, + { url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a", size = 250992 }, + { url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510", size = 253503 }, + { url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247", size = 254852 }, + { url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6", size = 257161 }, + { url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0", size = 251021 }, + { url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882", size = 252858 }, + { url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740", size = 250823 }, + { url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16", size = 255099 }, + { url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0", size = 250638 }, + { url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0", size = 252295 }, + { url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl", hash = "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc", size = 222360 }, + { url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633", size = 223174 }, + { url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl", hash = "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8", size = 221739 }, + { url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b", size = 220351 }, + { url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c", size = 220612 }, + { url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9", size = 261985 }, + { url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29", size = 264107 }, + { url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607", size = 266513 }, + { url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90", size = 267650 }, + { url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3", size = 261089 }, + { url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab", size = 263982 }, + { url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562", size = 261579 }, + { url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2", size = 265316 }, + { url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea", size = 260427 }, + { url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a", size = 262745 }, + { url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl", hash = "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215", size = 223146 }, + { url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43", size = 224254 }, + { url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl", hash = "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45", size = 222276 }, + { url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, +] + +[[package]] +name = "debugpy" +version = "1.8.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/56/c3baf5cbe4dd77427fd9aef99fcdade259ad128feeb8a786c246adb838e5/debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b", size = 2208318 }, + { url = "https://files.pythonhosted.org/packages/9a/7d/4fa79a57a8e69fe0d9763e98d1110320f9ecd7f1f362572e3aafd7417c9d/debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344", size = 3171493 }, + { url = "https://files.pythonhosted.org/packages/7d/f2/1e8f8affe51e12a26f3a8a8a4277d6e60aa89d0a66512f63b1e799d424a4/debugpy-1.8.20-cp311-cp311-win32.whl", hash = "sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec", size = 5209240 }, + { url = "https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl", hash = "sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb", size = 5233481 }, + { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686 }, + { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588 }, + { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372 }, + { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835 }, + { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560 }, + { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272 }, + { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208 }, + { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930 }, + { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066 }, + { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425 }, + { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407 }, + { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521 }, + { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658 }, +] + +[[package]] +name = "decorator" +version = "5.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190 }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604 }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047 }, +] + +[[package]] +name = "docutils" +version = "0.20.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/53/a5da4f2c5739cf66290fac1431ee52aff6851c7c8ffd8264f13affd7bcdd/docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b", size = 2058365 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/87/f238c0670b94533ac0353a4e2a1a771a0cc73277b88bff23d3ae35a256c1/docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", size = 572666 }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317 }, +] + +[[package]] +name = "fastjsonschema" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024 }, +] + +[[package]] +name = "filelock" +version = "3.29.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/fe/997687a931ab51049acce6fa1f23e8f01216374ea81374ddee763c493db5/filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90", size = 57571 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812 }, +] + +[[package]] +name = "fonttools" +version = "4.62.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7", size = 2871039 }, + { url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14", size = 2416346 }, + { url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7", size = 5100897 }, + { url = "https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b", size = 5071078 }, + { url = "https://files.pythonhosted.org/packages/e3/be/d378fca4c65ea1956fee6d90ace6e861776809cbbc5af22388a090c3c092/fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1", size = 5076908 }, + { url = "https://files.pythonhosted.org/packages/f8/d9/ae6a1d0693a4185a84605679c8a1f719a55df87b9c6e8e817bfdd9ef5936/fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416", size = 5202275 }, + { url = "https://files.pythonhosted.org/packages/54/6c/af95d9c4efb15cabff22642b608342f2bd67137eea6107202d91b5b03184/fonttools-4.62.1-cp311-cp311-win32.whl", hash = "sha256:942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53", size = 2293075 }, + { url = "https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2", size = 2344593 }, + { url = "https://files.pythonhosted.org/packages/47/d4/dbacced3953544b9a93088cc10ef2b596d348c983d5c67a404fa41ec51ba/fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974", size = 2870219 }, + { url = "https://files.pythonhosted.org/packages/66/9e/a769c8e99b81e5a87ab7e5e7236684de4e96246aae17274e5347d11ebd78/fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9", size = 2414891 }, + { url = "https://files.pythonhosted.org/packages/69/64/f19a9e3911968c37e1e620e14dfc5778299e1474f72f4e57c5ec771d9489/fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936", size = 5033197 }, + { url = "https://files.pythonhosted.org/packages/9b/8a/99c8b3c3888c5c474c08dbfd7c8899786de9604b727fcefb055b42c84bba/fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:149f7d84afca659d1a97e39a4778794a2f83bf344c5ee5134e09995086cc2392", size = 4988768 }, + { url = "https://files.pythonhosted.org/packages/d1/c6/0f904540d3e6ab463c1243a0d803504826a11604c72dd58c2949796a1762/fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0aa72c43a601cfa9273bb1ae0518f1acadc01ee181a6fc60cd758d7fdadffc04", size = 4971512 }, + { url = "https://files.pythonhosted.org/packages/29/0b/5cbef6588dc9bd6b5c9ad6a4d5a8ca384d0cea089da31711bbeb4f9654a6/fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:19177c8d96c7c36359266e571c5173bcee9157b59cfc8cb0153c5673dc5a3a7d", size = 5122723 }, + { url = "https://files.pythonhosted.org/packages/4a/47/b3a5342d381595ef439adec67848bed561ab7fdb1019fa522e82101b7d9c/fonttools-4.62.1-cp312-cp312-win32.whl", hash = "sha256:a24decd24d60744ee8b4679d38e88b8303d86772053afc29b19d23bb8207803c", size = 2281278 }, + { url = "https://files.pythonhosted.org/packages/28/b1/0c2ab56a16f409c6c8a68816e6af707827ad5d629634691ff60a52879792/fonttools-4.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e7863e10b3de72376280b515d35b14f5eeed639d1aa7824f4cf06779ec65e42", size = 2331414 }, + { url = "https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79", size = 2865155 }, + { url = "https://files.pythonhosted.org/packages/03/c5/0e3966edd5ec668d41dfe418787726752bc07e2f5fd8c8f208615e61fa89/fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe", size = 2412802 }, + { url = "https://files.pythonhosted.org/packages/52/94/e6ac4b44026de7786fe46e3bfa0c87e51d5d70a841054065d49cd62bb909/fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68", size = 5013926 }, + { url = "https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1", size = 4964575 }, + { url = "https://files.pythonhosted.org/packages/46/76/7d051671e938b1881670528fec69cc4044315edd71a229c7fd712eaa5119/fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069", size = 4953693 }, + { url = "https://files.pythonhosted.org/packages/1f/ae/b41f8628ec0be3c1b934fc12b84f4576a5c646119db4d3bdd76a217c90b5/fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9", size = 5094920 }, + { url = "https://files.pythonhosted.org/packages/f2/f6/53a1e9469331a23dcc400970a27a4caa3d9f6edbf5baab0260285238b884/fonttools-4.62.1-cp313-cp313-win32.whl", hash = "sha256:93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24", size = 2279928 }, + { url = "https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056", size = 2330514 }, + { url = "https://files.pythonhosted.org/packages/36/f0/2888cdac391807d68d90dcb16ef858ddc1b5309bfc6966195a459dd326e2/fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca", size = 2864442 }, + { url = "https://files.pythonhosted.org/packages/4b/b2/e521803081f8dc35990816b82da6360fa668a21b44da4b53fc9e77efcd62/fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca", size = 2410901 }, + { url = "https://files.pythonhosted.org/packages/00/a4/8c3511ff06e53110039358dbbdc1a65d72157a054638387aa2ada300a8b8/fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782", size = 4999608 }, + { url = "https://files.pythonhosted.org/packages/28/63/cd0c3b26afe60995a5295f37c246a93d454023726c3261cfbb3559969bb9/fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae", size = 4912726 }, + { url = "https://files.pythonhosted.org/packages/70/b9/ac677cb07c24c685cf34f64e140617d58789d67a3dd524164b63648c6114/fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7", size = 4951422 }, + { url = "https://files.pythonhosted.org/packages/e6/10/11c08419a14b85b7ca9a9faca321accccc8842dd9e0b1c8a72908de05945/fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a", size = 5060979 }, + { url = "https://files.pythonhosted.org/packages/4e/3c/12eea4a4cf054e7ab058ed5ceada43b46809fce2bf319017c4d63ae55bb4/fonttools-4.62.1-cp314-cp314-win32.whl", hash = "sha256:49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800", size = 2283733 }, + { url = "https://files.pythonhosted.org/packages/6b/67/74b070029043186b5dd13462c958cb7c7f811be0d2e634309d9a1ffb1505/fonttools-4.62.1-cp314-cp314-win_amd64.whl", hash = "sha256:1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e", size = 2335663 }, + { url = "https://files.pythonhosted.org/packages/42/c5/4d2ed3ca6e33617fc5624467da353337f06e7f637707478903c785bd8e20/fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82", size = 2947288 }, + { url = "https://files.pythonhosted.org/packages/1f/e9/7ab11ddfda48ed0f89b13380e5595ba572619c27077be0b2c447a63ff351/fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260", size = 2449023 }, + { url = "https://files.pythonhosted.org/packages/b2/10/a800fa090b5e8819942e54e19b55fc7c21fe14a08757c3aa3ca8db358939/fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4", size = 5137599 }, + { url = "https://files.pythonhosted.org/packages/37/dc/8ccd45033fffd74deb6912fa1ca524643f584b94c87a16036855b498a1ed/fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b", size = 4920933 }, + { url = "https://files.pythonhosted.org/packages/99/eb/e618adefb839598d25ac8136cd577925d6c513dc0d931d93b8af956210f0/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87", size = 5016232 }, + { url = "https://files.pythonhosted.org/packages/d9/5f/9b5c9bfaa8ec82def8d8168c4f13615990d6ce5996fe52bd49bfb5e05134/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c", size = 5042987 }, + { url = "https://files.pythonhosted.org/packages/90/aa/dfbbe24c6a6afc5c203d90cc0343e24bcbb09e76d67c4d6eef8c2558d7ba/fonttools-4.62.1-cp314-cp314t-win32.whl", hash = "sha256:b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a", size = 2348021 }, + { url = "https://files.pythonhosted.org/packages/13/6f/ae9c4e4dd417948407b680855c2c7790efb52add6009aaecff1e3bc50e8e/fonttools-4.62.1-cp314-cp314t-win_amd64.whl", hash = "sha256:59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e", size = 2414147 }, + { url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd", size = 1152647 }, +] + +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, +] + +[[package]] +name = "gevent" +version = "26.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation == 'CPython' and sys_platform == 'win32'" }, + { name = "greenlet", marker = "platform_python_implementation == 'CPython'" }, + { name = "zope-event" }, + { name = "zope-interface" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/27/1062fa31333dc3428a1f5f33cd6598b0552165ba679ca3ba116de42c9e8e/gevent-26.4.0.tar.gz", hash = "sha256:288d03addfccf0d1c67268358b6759b04392bf3bc35d26f3d9a45c82899c292d", size = 6242440 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/0e/330c4788860520850b7f4c6f84dd8591df5172cfd3f2796c046704ee879e/gevent-26.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:201323a5fb9a0646a0c7b384395ca55d60ee83200677919229df0648c4b78e6c", size = 1767278 }, + { url = "https://files.pythonhosted.org/packages/cf/27/717593d7cce74a2fd6bee0713793518e0398132303d5267f02dd587c5945/gevent-26.4.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:82d68a60a4207826db295b4e80a204c9d392ce78ccc15679195faeb9e29d8388", size = 1861609 }, + { url = "https://files.pythonhosted.org/packages/fb/af/ce6d4d554d9afc354b46b78eccb032f6add4d27c3eadaa0201ee103fa831/gevent-26.4.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:35b037b415ed38369717800250fe5974249525953b46026bef9def20f946dfb0", size = 1803675 }, + { url = "https://files.pythonhosted.org/packages/57/09/909166fff7d2ab9523e93bbd56e863df79a856b2857350218be83aef119d/gevent-26.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:6d973735d2067607a32cd182893978755eee829a0dc268087592d3b715e63fad", size = 2118034 }, + { url = "https://files.pythonhosted.org/packages/83/6b/ab68e1cc09fd6dd7adb9e1c54a47c6328df20aa012ed75526a3244f2ad05/gevent-26.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fbd3ff28a7babbfee750684c4f46ba6eedb3bce69365dd146726986b79fa6c1", size = 1777768 }, + { url = "https://files.pythonhosted.org/packages/ff/d3/b75568e7206ea4b89a7e21750381aa4a6f9afcced41d5a80a72b5fcc6b87/gevent-26.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f0a03650ca60c4c5774cbe21333905b95f2f5abd98ea5a3dbf28d93f2a7a5a84", size = 2144355 }, + { url = "https://files.pythonhosted.org/packages/f7/32/5f795143351bfbecd05467deec48ea75416bb90eb7a6dd042c7d7e5ec594/gevent-26.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d00d8c4ca1afab90e478b79679dd53787082c6da8d2f4fdc7667a4440d1e1a7a", size = 1676684 }, + { url = "https://files.pythonhosted.org/packages/3d/16/131d3874f50974b355c90a061a12d3fe2292cde0f875a1fa3d8b224f1251/gevent-26.4.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:318a0a73f664113e8d86d0cb0e328e7650e2d7d9c2e045418ab6fb1285831ad3", size = 2928699 }, + { url = "https://files.pythonhosted.org/packages/ea/8b/199e59b303adaff7f7365def9ab569c7ecd863363c974548bce3ddc2c89d/gevent-26.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:ce7aa033a3f68beb6732d1450a80c1af29e63e0c2d01abad7918cf2507f72fa6", size = 1783821 }, + { url = "https://files.pythonhosted.org/packages/e2/2d/b8249c9bd3f386191311c3a9bec4068e192a3f9df2fad92a71a15265ba15/gevent-26.4.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:a1b897c952baefd72232efaeb3bdb1ca2fa7ae94cbfe68ac21201b03e843190a", size = 1879424 }, + { url = "https://files.pythonhosted.org/packages/ef/89/59216985c1f2c11f2f28bbc88e583588ad44cdde823c530ad4e307be6612/gevent-26.4.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:7eef2ea508ce41795e20587a5fc868ae4919543097c81a40fbdfd65bc479f54f", size = 1830575 }, + { url = "https://files.pythonhosted.org/packages/ee/a9/2d67d2b0aa0ca9d7bb7fe73c3bbb97b3695cb15c338a6ea7734f58da9add/gevent-26.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f7e12fdd28cc9f39a463d8df5172d698c64a8ed385a21d98e7092fd8308a139a", size = 2113898 }, + { url = "https://files.pythonhosted.org/packages/95/a3/457d58d9b3e7da17c8456d841c37a32af8d231a1d71237ad201b19129317/gevent-26.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d48e3ee13d7678c24c22f19d441ad6bc220a79f23662d03ff36fae0d62efdb59", size = 1795890 }, + { url = "https://files.pythonhosted.org/packages/a7/cc/cbe78f2626643b20275aaa41cd2cc45ba75056e3665bde36bc190af3cae0/gevent-26.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c58c8e034f94329be4dc0979fba3301005a433dbab42cea0b2c33fd736946872", size = 2139791 }, + { url = "https://files.pythonhosted.org/packages/f6/df/7875e08b06a95f4577b71708ec470d029fadf873a66eb813a2861d79dfb5/gevent-26.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1c737e6ac6ce1398df0e3f41c58d982e397c993cbe73ac05b7edbe39e128c9cb", size = 1680530 }, + { url = "https://files.pythonhosted.org/packages/3d/be/51809d98bb00846d7756a0b82625024f9302145f3d024846b43f05efeddb/gevent-26.4.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1fe581d41c63cd1d8b12c69561ce53a48ad0d8763b254740d7bfea997335a38c", size = 2951507 }, + { url = "https://files.pythonhosted.org/packages/d6/86/89325a62a4e8cc1934e155b383b66491ed21d1e774b13d5054d51fa0ac81/gevent-26.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c503b0c0a681e795255a13e5bb4e41615c3b020c1db93b8dfa04cfeb8f19d5a9", size = 1786029 }, + { url = "https://files.pythonhosted.org/packages/a3/ea/04d112844aa992da583cbd280f17a4ba097da338dab347efd0aa5e235645/gevent-26.4.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:684256c29e3e5d4d0c4d06b772d00574d0dc859dfbb2fd13d318c512b16e1f89", size = 1881326 }, + { url = "https://files.pythonhosted.org/packages/a1/33/71900c5ba442f5df89456b6d9fdaa43da2ae7cdd937d8c5667b49323ceb4/gevent-26.4.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:73eafd06b158d511f1ec6e5902a45e0ae3b48e745f35e9df97d25f809f537d88", size = 1833123 }, + { url = "https://files.pythonhosted.org/packages/d0/af/7df19c92e56842921f34787e1168c7afc52a23b0d1253bba99344809a935/gevent-26.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1a18e543c830a1c07a2efeb33786a57ccac360af70cb42bbaf5a6f5f7ca49300", size = 2114330 }, + { url = "https://files.pythonhosted.org/packages/ca/0e/202694960f8d4dda68fd2a73bbcb8251e2d5308339924310ff1fff31bf7c/gevent-26.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:74f1e3a460c43aefcb4ff9ef91aac15abc0b42e5233771e1956574d14ba9cac6", size = 1798427 }, + { url = "https://files.pythonhosted.org/packages/75/69/2d056b2a4e3ef1f65f94002725572d1e99163ff79231dbb68ad529e7cb9d/gevent-26.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:954258873ae0bcc97fb41e48db25284fb73454bfefe27db8ceb89225da5502fb", size = 2140100 }, + { url = "https://files.pythonhosted.org/packages/fe/a0/1a7f64aa2476c2b44abaecca919a6561bda85234f99fc7ac3c66bcb93050/gevent-26.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:4a9a64c064457c1afaf93ee2815fe0f38be6ecbb92806a6a712f12afc3e26cf5", size = 1680206 }, + { url = "https://files.pythonhosted.org/packages/7e/f3/64638a941988f09aa1816e2674eb1efb215b6fa64a97edef6e25177b0845/gevent-26.4.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:7ab0f183a6fd2369eef619832eef14f1f2f69c605163c3f2dc41deb799af4a71", size = 2967206 }, + { url = "https://files.pythonhosted.org/packages/f6/70/a86be65a51d3ebb92c82a70adc9c5c32b1a9d9579120d0be1db7cf534ce0/gevent-26.4.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:7e5906860e632bf965e1966c57e6bfc19dcb79dc262f04fdb0a9d7c12147bf69", size = 1792916 }, + { url = "https://files.pythonhosted.org/packages/40/92/18fdb4b28f20129395f1c041773adee99e7fc2bcfff216df93bfb80787d5/gevent-26.4.0-cp314-cp314-manylinux_2_28_ppc64le.whl", hash = "sha256:297a361071dc6708115d4544859321e93b02a6cd5823ba02c0a909530a519d45", size = 1886617 }, + { url = "https://files.pythonhosted.org/packages/af/c9/d02222ecf79d10c8a0c2755661485395b58c4bfffaafd88bcc230ce392de/gevent-26.4.0-cp314-cp314-manylinux_2_28_s390x.whl", hash = "sha256:7e74f59e5c9011afa2a9cb7106bb9a59f2a1f74c3d7b272c1b852eb0bc0b8f90", size = 1837660 }, + { url = "https://files.pythonhosted.org/packages/46/85/9376d125fa4f7b0f269925d0d622eda0ff8f8dfc8d0c097a096c511fc738/gevent-26.4.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:45d6010a6a981f5a2b3411c4e38fbe305a1b46e4b12db3b4914775927dea7ba4", size = 2119342 }, + { url = "https://files.pythonhosted.org/packages/b1/c4/1fe2817daca8e97c365fd739dd4057f71cce26ef600fb8465deb8060c83c/gevent-26.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dc38137ba2f43794c488615aafa2eefd0cc142f484a8274d4c827ed7a031a1e2", size = 1805672 }, + { url = "https://files.pythonhosted.org/packages/e7/cc/ccbcbd56e7e85482291fbb90a317f5febf630ec4174a91506f4167ba0912/gevent-26.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:29a225d2d4da37e20c7a246754a64442d0e43e4534b8cc764f89530bb22a4237", size = 2145594 }, + { url = "https://files.pythonhosted.org/packages/8e/b9/7dd37b6001d16f692b1bfb6e68cad642beb38b34a753c29bbff312f46e4b/gevent-26.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:d1c08bc9bb6bd79732a26710a99588b5e9b67b668e165dd609704b876f41baab", size = 1703189 }, +] + +[[package]] +name = "greenlet" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/3f/dbf99fb14bfeb88c28f16729215478c0e265cacd6dc22270c8f31bb6892f/greenlet-3.5.0.tar.gz", hash = "sha256:d419647372241bc68e957bf38d5c1f98852155e4146bd1e4121adea81f4f01e4", size = 196995 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/0f/a91f143f356523ff682309732b175765a9bc2836fd7c081c2c67fedc1ad4/greenlet-3.5.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8f1cc966c126639cd152fdaa52624d2655f492faa79e013fea161de3e6dda082", size = 284726 }, + { url = "https://files.pythonhosted.org/packages/95/82/800646c7ffc5dbabd75ddd2f6b519bb898c0c9c969e5d0473bfe5d20bcce/greenlet-3.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:362624e6a8e5bca3b8233e45eef33903a100e9539a2b995c364d595dbc4018b3", size = 604264 }, + { url = "https://files.pythonhosted.org/packages/ca/ac/354867c0bba812fc33b15bc55aedafedd0aee3c7dd91dfca22444157dc0c/greenlet-3.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5ecd83806b0f4c2f53b1018e0005cd82269ea01d42befc0368730028d850ed1c", size = 616099 }, + { url = "https://files.pythonhosted.org/packages/c9/ab/192090c4a5b30df148c22bf4b8895457d739a7c7c5a7b9c41e5dd7f537f2/greenlet-3.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa94cb2288681e3a11645958f1871d48ee9211bd2f66628fdace505927d6e564", size = 623976 }, + { url = "https://files.pythonhosted.org/packages/ff/b0/815bece7399e01cadb69014219eebd0042339875c59a59b0820a46ece356/greenlet-3.5.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ff251e9a0279522e62f6176412869395a64ddf2b5c5f782ff609a8216a4e662", size = 615198 }, + { url = "https://files.pythonhosted.org/packages/24/11/05eb2b9b188c6df7d68a89c99134d644a7af616a40b9808e8e6ced315d5d/greenlet-3.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:64d6ac45f7271f48e45f67c95b54ef73534c52ec041fcda8edf520c6d811f4bc", size = 418379 }, + { url = "https://files.pythonhosted.org/packages/10/80/3b2c0a895d6698f6ddb31b07942ebfa982f3e30888bc5546a5b5990de8b2/greenlet-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d874e79afd41a96e11ff4c5d0bc90a80973e476fda1c2c64985667397df432b", size = 1574927 }, + { url = "https://files.pythonhosted.org/packages/44/0e/f354af514a4c61454dbc68e44d47544a5a4d6317e30b77ddfa3a09f4c5f3/greenlet-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0ed006e4b86c59de7467eb2601cd1b77b5a7d657d1ee55e30fe30d76451edba4", size = 1642683 }, + { url = "https://files.pythonhosted.org/packages/fa/6a/87f38255201e993a1915265ebb80cd7c2c78b04a45744995abbf6b259fd8/greenlet-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:703cb211b820dbffbbc55a16bfc6e4583a6e6e990f33a119d2cc8b83211119c8", size = 238115 }, + { url = "https://files.pythonhosted.org/packages/e3/f8/450fe3c5938fa737ea4d22699772e6e34e8e24431a47bf4e8a1ceed4a98e/greenlet-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:6c18dfb59c70f5a94acd271c72e90128c3c776e41e5f07767908c8c1b74ad339", size = 235017 }, + { url = "https://files.pythonhosted.org/packages/ef/32/f2ce6d4cac3e55bc6173f92dbe627e782e1850f89d986c3606feb63aafa7/greenlet-3.5.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:db2910d3c809444e0a20147361f343fe2798e106af8d9d8506f5305302655a9f", size = 286228 }, + { url = "https://files.pythonhosted.org/packages/b7/aa/caed9e5adf742315fc7be2a84196373aab4816e540e38ba0d76cb7584d68/greenlet-3.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ec9ea74e7268ace7f9aab1b1a4e730193fc661b39a993cd91c606c32d4a3628", size = 601775 }, + { url = "https://files.pythonhosted.org/packages/c7/af/90ae08497400a941595d12774447f752d3dfe0fbb012e35b76bc5c0ff37e/greenlet-3.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54d243512da35485fc7a6bf3c178fdda6327a9d6506fcdd62b1abd1e41b2927b", size = 614436 }, + { url = "https://files.pythonhosted.org/packages/3f/e9/4eeadf8cb3403ac274245ba75f07844abc7fa5f6787583fc9156ba741e0f/greenlet-3.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:41353ec2ecedf7aa8f682753a41919f8718031a6edac46b8d3dc7ed9e1ceb136", size = 620610 }, + { url = "https://files.pythonhosted.org/packages/2b/e0/2e13df68f367e2f9960616927d60857dd7e56aaadd59a47c644216b2f920/greenlet-3.5.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d280a7f5c331622c69f97eb167f33577ff2d1df282c41cd15907fc0a3ca198c", size = 611388 }, + { url = "https://files.pythonhosted.org/packages/ee/ef/f913b3c0eb7d26d86a2401c5e1546c9d46b657efee724b06f6f4ac5d8824/greenlet-3.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:58c1c374fe2b3d852f9b6b11a7dff4c85404e51b9a596fd9e89cf904eb09866d", size = 422775 }, + { url = "https://files.pythonhosted.org/packages/82/f7/393c64055132ac0d488ef6be549253b7e6274194863967ddc0bc8f5b87b8/greenlet-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1eb67d5adefb5bd2e182d42678a328979a209e4e82eb93575708185d31d1f588", size = 1570768 }, + { url = "https://files.pythonhosted.org/packages/b8/4b/eaf7735253522cf56d1b74d672a58f54fc114702ceaf05def59aae72f6e1/greenlet-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2628d6c86f6cb0cb45e0c3c54058bbec559f57eaae699447748cb3928150577e", size = 1635983 }, + { url = "https://files.pythonhosted.org/packages/4c/fe/4fb3a0805bd5165da5ebf858da7cc01cce8061674106d2cf5bdab32cbfde/greenlet-3.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:d4d9f0624c775f2dfc56ba54d515a8c771044346852a918b405914f6b19d7fd8", size = 238840 }, + { url = "https://files.pythonhosted.org/packages/cb/cb/baa584cb00532126ffe12d9787db0a60c5a4f55c27bfe2666df5d4c30a32/greenlet-3.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:83ed9f27f1680b50e89f40f6df348a290ea234b249a4003d366663a12eab94f2", size = 235615 }, + { url = "https://files.pythonhosted.org/packages/0c/58/fc576f99037ce19c5aa16628e4c3226b6d1419f72a62c79f5f40576e6eb3/greenlet-3.5.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:5a5ed18de6a0f6cc7087f1563f6bd93fc7df1c19165ca01e9bde5a5dc281d106", size = 285066 }, + { url = "https://files.pythonhosted.org/packages/4a/ba/b28ddbe6bfad6a8ac196ef0e8cff37bc65b79735995b9e410923fffeeb70/greenlet-3.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a717fbc46d8a354fa675f7c1e813485b6ba3885f9bef0cd56e5ba27d758ff5b", size = 604414 }, + { url = "https://files.pythonhosted.org/packages/09/06/4b69f8f0b67603a8be2790e55107a190b376f2627fe0eaf5695d85ffb3cd/greenlet-3.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ddc090c5c1792b10246a78e8c2163ebbe04cf877f9d785c230a7b27b39ad038e", size = 617349 }, + { url = "https://files.pythonhosted.org/packages/6a/15/a643b4ecd09969e30b8a150d5919960caae0abe4f5af75ab040b1ab85e78/greenlet-3.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4964101b8585c144cbda5532b1aa644255126c08a265dae90c16e7a0e63aaa9d", size = 623234 }, + { url = "https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13", size = 613927 }, + { url = "https://files.pythonhosted.org/packages/77/18/3b13d5ef1275b0ffaf933b05efa21408ac4ca95823c7411d79682e4fdcff/greenlet-3.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:7022615368890680e67b9965d33f5773aade330d5343bbe25560135aaa849eae", size = 425243 }, + { url = "https://files.pythonhosted.org/packages/ee/e1/bd0af6213c7dd33175d8a462d4c1fe1175124ebed4855bc1475a5b5242c2/greenlet-3.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5e05ba267789ea87b5a155cf0e810b1ab88bf18e9e8740813945ceb8ee4350ba", size = 1570893 }, + { url = "https://files.pythonhosted.org/packages/9b/2a/0789702f864f5382cb476b93d7a9c823c10472658102ccd65f415747d2e2/greenlet-3.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0ecec963079cd58cbd14723582384f11f166fd58883c15dcbfb342e0bc9b5846", size = 1636060 }, + { url = "https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5", size = 238740 }, + { url = "https://files.pythonhosted.org/packages/b6/b7/9c5c3d653bd4ff614277c049ac676422e2c557db47b4fe43e6313fc005dc/greenlet-3.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:47422135b1d308c14b2c6e758beedb1acd33bb91679f5670edf77bf46244722b", size = 235525 }, + { url = "https://files.pythonhosted.org/packages/94/5e/a70f31e3e8d961c4ce589c15b28e4225d63704e431a23932a3808cbcc867/greenlet-3.5.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:f35807464c4c58c55f0d31dfa83c541a5615d825c2fe3d2b95360cf7c4e3c0a8", size = 285564 }, + { url = "https://files.pythonhosted.org/packages/af/a6/046c0a28e21833e4086918218cfb3d8bed51c075a1b700f20b9d7861c0f4/greenlet-3.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55fa7ea52771be44af0de27d8b80c02cd18c2c3cddde6c847ecebdf72418b6a1", size = 651166 }, + { url = "https://files.pythonhosted.org/packages/47/f8/4af27f71c5ff32a7fbc516adb46370d9c4ae2bc7bd3dc7d066ac542b4b15/greenlet-3.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a97e4821aa710603f94de0da25f25096454d78ffdace5dc77f3a006bc01abba3", size = 663792 }, + { url = "https://files.pythonhosted.org/packages/fb/89/2dadb89793c37ee8b4c237857188293e9060dc085f19845c292e00f8e091/greenlet-3.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bf2d8a80bec89ab46221ae45c5373d5ba0bd36c19aa8508e85c6cd7e5106cd37", size = 668086 }, + { url = "https://files.pythonhosted.org/packages/a3/59/1bd6d7428d6ed9106efbb8c52310c60fd04f6672490f452aeaa3829aa436/greenlet-3.5.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f52a464e4ed91780bdfbbdd2b97197f3accaa629b98c200f4dffada759f3ae7", size = 660933 }, + { url = "https://files.pythonhosted.org/packages/82/35/75722be7e26a2af4cbd2dc35b0ed382dacf9394b7e75551f76ed1abe87f2/greenlet-3.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:1bae92a1dd94c5f9d9493c3a212dd874c202442047cf96446412c862feca83a2", size = 470799 }, + { url = "https://files.pythonhosted.org/packages/83/e4/b903e5a5fae1e8a28cdd32a0cfbfd560b668c25b692f67768822ddc5f40f/greenlet-3.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:762612baf1161ccb8437c0161c668a688223cba28e1bf038f4eb47b13e39ccdf", size = 1618401 }, + { url = "https://files.pythonhosted.org/packages/0e/e3/5ec408a329acb854fb607a122e1ee5fb3ff649f9a97952948a90803c0d8e/greenlet-3.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:57a43c6079a89713522bc4bcb9f75070ecf5d3dbad7792bfe42239362cbf2a16", size = 1682038 }, + { url = "https://files.pythonhosted.org/packages/91/20/6b165108058767ee643c55c5c4904d591a830ee2b3c7dbd359828fbc829f/greenlet-3.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:3bc59be3945ae9750b9e7d45067d01ae3fe90ea5f9ade99239dabdd6e28a5033", size = 239835 }, + { url = "https://files.pythonhosted.org/packages/4e/62/1c498375cee177b55d980c1db319f26470e5309e54698c8f8fc06c0fd539/greenlet-3.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:a96fcee45e03fe30a62669fd16ab5c9d3c172660d3085605cb1e2d1280d3c988", size = 236862 }, + { url = "https://files.pythonhosted.org/packages/78/a8/4522939255bb5409af4e87132f915446bf3622c2c292d14d3c38d128ae82/greenlet-3.5.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:a10a732421ab4fec934783ce3e54763470d0181db6e3468f9103a275c3ed1853", size = 293614 }, + { url = "https://files.pythonhosted.org/packages/15/5e/8744c52e2c027b5a8772a01561934c8835f869733e101f62075c60430340/greenlet-3.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7fc391b1566f2907d17aaebe78f8855dc45675159a775fcf9e61f8ee0078e87f", size = 650723 }, + { url = "https://files.pythonhosted.org/packages/00/ef/7b4c39c03cf46ceca512c5d3f914afd85aa30b2cc9a93015b0dd73e4be6c/greenlet-3.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:680bd0e7ad5e8daa8a4aa89f68fd6adc834b8a8036dc256533f7e08f4a4b01f7", size = 656529 }, + { url = "https://files.pythonhosted.org/packages/5f/5c/0602239503b124b70e39355cbdb39361ecfe65b87a5f2f63752c32f5286f/greenlet-3.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1aa4ce8debcd4ea7fb2e150f3036588c41493d1d52c43538924ae1819003f4ce", size = 657015 }, + { url = "https://files.pythonhosted.org/packages/0b/b5/c7768f352f5c010f92064d0063f987e7dc0cd290a6d92a34109015ce4aa1/greenlet-3.5.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddb36c7d6c9c0a65f18c7258634e0c416c6ab59caac8c987b96f80c2ebda0112", size = 654364 }, + { url = "https://files.pythonhosted.org/packages/38/51/8699f865f125dc952384cb432b0f7138aa4d8f2969a7d12d0df5b94d054d/greenlet-3.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:728a73687e39ae9ca34e4694cbf2f049d3fbc7174639468d0f67200a97d8f9e2", size = 488275 }, + { url = "https://files.pythonhosted.org/packages/ef/d0/079ebe12e4b1fc758857ce5be1a5e73f06870f2101e52611d1e71925ce54/greenlet-3.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e5ddf316ced87539144621453c3aef229575825fe60c604e62bedc4003f372b2", size = 1614204 }, + { url = "https://files.pythonhosted.org/packages/6d/89/6c2fb63df3596552d20e58fb4d96669243388cf680cff222758812c7bfaa/greenlet-3.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4a448128607be0de65342dc9b31be7f948ef4cc0bc8832069350abefd310a8f2", size = 1675480 }, + { url = "https://files.pythonhosted.org/packages/15/32/77ee8a6c1564fc345a491a4e85b3bf360e4cf26eac98c4532d2fdb96e01f/greenlet-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d60097128cb0a1cab9ea541186ea13cd7b847b8449a7787c2e2350da0cb82d86", size = 245324 }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397 }, +] + +[[package]] +name = "idna" +version = "3.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629 }, +] + +[[package]] +name = "imagesize" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/e6/7bf14eeb8f8b7251141944835abd42eb20a658d89084b7e1f3e5fe394090/imagesize-2.0.0.tar.gz", hash = "sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3", size = 1773045 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl", hash = "sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96", size = 9441 }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 }, +] + +[[package]] +name = "ipykernel" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788 }, +] + +[[package]] +name = "ipython" +version = "9.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "psutil" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/87cda5842cf5c31837c06ddb588e11c3c35d8ece89b7a0108c06b8c9b00a/ipython-9.13.0.tar.gz", hash = "sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967", size = 4430549 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/86/3060e8029b7cc505cce9a0137431dda81d0a3fde93a8f0f50ee0bf37a795/ipython-9.13.0-py3-none-any.whl", hash = "sha256:57f9d4639e20818d328d287c7b549af3d05f12486ea8f2e7f73e52a36ec4d201", size = 627274 }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074 }, +] + +[[package]] +name = "ipywidgets" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm" }, + { name = "ipython" }, + { name = "jupyterlab-widgets" }, + { name = "traitlets" }, + { name = "widgetsnbextension" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668", size = 116739 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808 }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, +] + +[[package]] +name = "json5" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/4b/6f8906aaf67d501e259b0adab4d312945bb7211e8b8d4dcc77c92320edaa/json5-0.14.0.tar.gz", hash = "sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb", size = 52656 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/42/cf027b4ac873b076189d935b135397675dac80cb29acb13e1ab86ad6c631/json5-0.14.0-py3-none-any.whl", hash = "sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a", size = 36271 }, +] + +[[package]] +name = "jsonpointer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659 }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630 }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437 }, +] + +[[package]] +name = "jupyter-client" +version = "8.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371 }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032 }, +] + +[[package]] +name = "jupyter-events" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "packaging" }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/f8/475c4241b2b75af0deaae453ed003c6c851766dbc44d332d8baf245dc931/jupyter_events-0.12.1.tar.gz", hash = "sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3", size = 62854 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/6c/6fcde0c8f616ed360ffd3587f7db9e225a7e62b583a04494d2f069cf64ea/jupyter_events-0.12.1-py3-none-any.whl", hash = "sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf", size = 19512 }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/ff/1e4a61f5170a9a1d978f3ac3872449de6c01fc71eaf89657824c878b1549/jupyter_lsp-2.3.1.tar.gz", hash = "sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6", size = 55677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/e8/9d61dcbd1dce8ef418f06befd4ac084b4720429c26b0b1222bc218685eff/jupyter_lsp-2.3.1-py3-none-any.whl", hash = "sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81", size = 77513 }, +] + +[[package]] +name = "jupyter-server" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "overrides", marker = "python_full_version < '3.12'" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/ac/e040ec363d7b6b1f11304cc9f209dac4517ece5d5e01821366b924a64a50/jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5", size = 731949 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f", size = 388221 }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/bcd0a9b0cbba88986fe944aaaf91bfda603e5a50bda8ed15123f381a3b2f/jupyter_server_terminals-0.5.4.tar.gz", hash = "sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5", size = 31770 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl", hash = "sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14", size = 13704 }, +] + +[[package]] +name = "jupyterlab" +version = "4.5.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "setuptools" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/22/8440ec827762146e7cdecf04335bd348795899d29dc6ae82238707353a2c/jupyterlab-4.5.7.tar.gz", hash = "sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0", size = 23992763 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/aa/537b8f7d80e799af19af35fb3ddfc970b951088a13c57dd9387dcfbb7f61/jupyterlab-4.5.7-py3-none-any.whl", hash = "sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d", size = 12450123 }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830 }, +] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926 }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/dd/a495a9c104be1c476f0386e714252caf2b7eca883915422a64c50b88c6f5/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c", size = 122798 }, + { url = "https://files.pythonhosted.org/packages/11/60/37b4047a2af0cf5ef6d8b4b26e91829ae6fc6a2d1f74524bcb0e7cd28a32/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb", size = 66216 }, + { url = "https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac", size = 63911 }, + { url = "https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27", size = 1438209 }, + { url = "https://files.pythonhosted.org/packages/fd/d6/76621246f5165e5372f02f5e6f3f48ea336a8f9e96e43997d45b240ed8cd/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398", size = 1248888 }, + { url = "https://files.pythonhosted.org/packages/b2/c1/31559ec6fb39a5b48035ce29bb63ade628f321785f38c384dee3e2c08bc1/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db", size = 1266304 }, + { url = "https://files.pythonhosted.org/packages/5e/ef/1cb8276f2d29cc6a41e0a042f27946ca347d3a4a75acf85d0a16aa6dcc82/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc", size = 1319650 }, + { url = "https://files.pythonhosted.org/packages/4c/e4/5ba3cecd7ce6236ae4a80f67e5d5531287337d0e1f076ca87a5abe4cd5d0/kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679", size = 970949 }, + { url = "https://files.pythonhosted.org/packages/5a/69/dc61f7ae9a2f071f26004ced87f078235b5507ab6e5acd78f40365655034/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309", size = 2199125 }, + { url = "https://files.pythonhosted.org/packages/e5/7b/abbe0f1b5afa85f8d084b73e90e5f801c0939eba16ac2e49af7c61a6c28d/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2", size = 2293783 }, + { url = "https://files.pythonhosted.org/packages/8a/80/5908ae149d96d81580d604c7f8aefd0e98f4fd728cf172f477e9f2a81744/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c", size = 1960726 }, + { url = "https://files.pythonhosted.org/packages/84/08/a78cb776f8c085b7143142ce479859cfec086bd09ee638a317040b6ef420/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08", size = 2464738 }, + { url = "https://files.pythonhosted.org/packages/b1/e1/65584da5356ed6cb12c63791a10b208860ac40a83de165cb6a6751a686e3/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4", size = 2270718 }, + { url = "https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b", size = 73480 }, + { url = "https://files.pythonhosted.org/packages/d8/0e/2ee5debc4f77a625778fec5501ff3e8036fe361b7ee28ae402a485bb9694/kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac", size = 64930 }, + { url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9", size = 123158 }, + { url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588", size = 66388 }, + { url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819", size = 64068 }, + { url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f", size = 1477934 }, + { url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf", size = 1278537 }, + { url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d", size = 1296685 }, + { url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083", size = 1346024 }, + { url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6", size = 987241 }, + { url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1", size = 2227742 }, + { url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0", size = 2323966 }, + { url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15", size = 1977417 }, + { url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314", size = 2491238 }, + { url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9", size = 2294947 }, + { url = "https://files.pythonhosted.org/packages/ad/cf/0348374369ca588f8fe9c338fae49fa4e16eeb10ffb3d012f23a54578a9e/kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384", size = 73569 }, + { url = "https://files.pythonhosted.org/packages/28/26/192b26196e2316e2bd29deef67e37cdf9870d9af8e085e521afff0fed526/kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7", size = 64997 }, + { url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09", size = 123166 }, + { url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3", size = 66395 }, + { url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd", size = 64065 }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903 }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751 }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793 }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041 }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292 }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865 }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369 }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989 }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645 }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237 }, + { url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276", size = 73573 }, + { url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c", size = 64998 }, + { url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1", size = 125700 }, + { url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e", size = 67537 }, + { url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7", size = 65514 }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848 }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542 }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447 }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918 }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856 }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580 }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018 }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804 }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482 }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328 }, + { url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53", size = 68410 }, + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231 }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489 }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063 }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913 }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782 }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815 }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925 }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322 }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857 }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376 }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549 }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680 }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905 }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086 }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577 }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794 }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646 }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511 }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858 }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539 }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310 }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244 }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154 }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377 }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288 }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158 }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260 }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403 }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687 }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032 }, + { url = "https://files.pythonhosted.org/packages/e9/eb/5fcbbbf9a0e2c3a35effb88831a483345326bbc3a030a3b5b69aee647f84/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232", size = 59532 }, + { url = "https://files.pythonhosted.org/packages/c3/9b/e17104555bb4db148fd52327feea1e96be4b88e8e008b029002c281a21ab/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a", size = 57420 }, + { url = "https://files.pythonhosted.org/packages/48/44/2b5b95b7aa39fb2d8d9d956e0f3d5d45aef2ae1d942d4c3ffac2f9cfed1a/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737", size = 79892 }, + { url = "https://files.pythonhosted.org/packages/52/7d/7157f9bba6b455cfb4632ed411e199fc8b8977642c2b12082e1bd9e6d173/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16", size = 77603 }, + { url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558 }, +] + +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +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 } +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 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631 }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058 }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287 }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940 }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887 }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692 }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471 }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923 }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572 }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077 }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876 }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615 }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020 }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332 }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947 }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962 }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760 }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529 }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015 }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540 }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105 }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906 }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619 }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408 }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005 }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048 }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821 }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606 }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043 }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747 }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341 }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073 }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661 }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069 }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670 }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598 }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261 }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835 }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733 }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672 }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819 }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426 }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, +] + +[[package]] +name = "matplotlib" +version = "3.10.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/8c/290f021104741fea63769c31494f5324c0cd249bf536a65a4350767b1f22/matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb", size = 8306860 }, + { url = "https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb", size = 8199254 }, + { url = "https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb", size = 8777092 }, + { url = "https://files.pythonhosted.org/packages/55/fa/3ce7adfe9ba101748f465211660d9c6374c876b671bdb8c2bb6d347e8b94/matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9", size = 9595691 }, + { url = "https://files.pythonhosted.org/packages/36/c4/6960a76686ed668f2c60f84e9799ba4c0d56abdb36b1577b60c1d061d1ec/matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb", size = 9659771 }, + { url = "https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f", size = 8205112 }, + { url = "https://files.pythonhosted.org/packages/e2/ee/cb57ad4754f3e7b9174ce6ce66d9205fb827067e48a9f58ac09d7e7d6b77/matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80", size = 8132310 }, + { url = "https://files.pythonhosted.org/packages/35/c6/5581e26c72233ebb2a2a6fed2d24fb7c66b4700120b813f51b0555acf0b6/matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1", size = 8319908 }, + { url = "https://files.pythonhosted.org/packages/b7/18/4880dd762e40cd360c1bf06e890c5a97b997e91cb324602b1a19950ad5ce/matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320", size = 8216016 }, + { url = "https://files.pythonhosted.org/packages/32/91/d024616abdba99e83120e07a20658976f6a343646710760c4a51df126029/matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285", size = 8789336 }, + { url = "https://files.pythonhosted.org/packages/5c/04/030a2f61ef2158f5e4c259487a92ac877732499fb33d871585d89e03c42d/matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2", size = 9604602 }, + { url = "https://files.pythonhosted.org/packages/fc/c2/541e4d09d87bb6b5830fc28b4c887a9a8cf4e1c6cee698a8c05552ae2003/matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf", size = 9670966 }, + { url = "https://files.pythonhosted.org/packages/04/a1/4571fc46e7702de8d0c2dc54ad1b2f8e29328dea3ee90831181f7353d93c/matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6", size = 8217462 }, + { url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688 }, + { url = "https://files.pythonhosted.org/packages/aa/d3/8d4f6afbecb49fc04e060a57c0fce39ea51cc163a6bd87303ccd698e4fa6/matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f", size = 8320331 }, + { url = "https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e", size = 8216461 }, + { url = "https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f", size = 8790091 }, + { url = "https://files.pythonhosted.org/packages/3e/0b/322aeec06dd9b91411f92028b37d447342770a24392aa4813e317064dad5/matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838", size = 9605027 }, + { url = "https://files.pythonhosted.org/packages/74/88/5f13482f55e7b00bcfc09838b093c2456e1379978d2a146844aae05350ad/matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2", size = 9671269 }, + { url = "https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921", size = 8217588 }, + { url = "https://files.pythonhosted.org/packages/47/b9/d706d06dd605c49b9f83a2aed8c13e3e5db70697d7a80b7e3d7915de6b17/matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8", size = 8136913 }, + { url = "https://files.pythonhosted.org/packages/9b/45/6e32d96978264c8ca8c4b1010adb955a1a49cfaf314e212bbc8908f04a61/matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9", size = 8368019 }, + { url = "https://files.pythonhosted.org/packages/86/0a/c8e3d3bba245f0f7fc424937f8ff7ef77291a36af3edb97ccd78aa93d84f/matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4", size = 8264645 }, + { url = "https://files.pythonhosted.org/packages/3d/aa/5bf5a14fe4fed73a4209a155606f8096ff797aad89c6c35179026571133e/matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc", size = 8802194 }, + { url = "https://files.pythonhosted.org/packages/dd/5e/b4be852d6bba6fd15893fadf91ff26ae49cb91aac789e95dde9d342e664f/matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99", size = 9622684 }, + { url = "https://files.pythonhosted.org/packages/4c/3d/ed428c971139112ef730f62770654d609467346d09d4b62617e1afd68a5a/matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d", size = 9680790 }, + { url = "https://files.pythonhosted.org/packages/e7/09/052e884aaf2b985c63cb79f715f1d5b6a3eaa7de78f6a52b9dbc077d5b53/matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8", size = 8287571 }, + { url = "https://files.pythonhosted.org/packages/f4/38/ae27288e788c35a4250491422f3db7750366fc8c97d6f36fbdecfc1f5518/matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38", size = 8188292 }, + { url = "https://files.pythonhosted.org/packages/d6/e6/3bd8afd04949f02eabc1c17115ea5255e19cacd4d06fc5abdde4eeb0052c/matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d", size = 8321276 }, + { url = "https://files.pythonhosted.org/packages/41/86/86231232fff41c9f8e4a1a7d7a597d349a02527109c3af7d618366122139/matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f", size = 8218218 }, + { url = "https://files.pythonhosted.org/packages/85/8f/becc9722cafc64f5d2eb0b7c1bf5f585271c618a45dbd8fabeb021f898b6/matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b", size = 9608145 }, + { url = "https://files.pythonhosted.org/packages/32/5d/f7e914f7d9325abff4057cee62c0fa70263683189f774473cbfb534cd13b/matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2", size = 9885085 }, + { url = "https://files.pythonhosted.org/packages/a5/fd/fa69f2221534e80cc5772ac2b7d222011a2acafc2ec7216d5dd174c864ae/matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716", size = 9672358 }, + { url = "https://files.pythonhosted.org/packages/ab/1a/5a4f747a8b271cbb024946d2dd3c913ab5032ba430626f8c3528ada96b4b/matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f", size = 8349970 }, + { url = "https://files.pythonhosted.org/packages/64/dc/95d60ecaefe30680a154b52ea96ab4b0dab547f1fd6aa12f5fb655e89cae/matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456", size = 8272785 }, + { url = "https://files.pythonhosted.org/packages/70/a0/005d68bc8b8418300ce6591f18586910a8526806e2ab663933d9f20a41e9/matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe", size = 8367999 }, + { url = "https://files.pythonhosted.org/packages/22/05/1236cc9290be70b2498af20ca348add76e3fffe7f67b477db5133a84f3ea/matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6", size = 8264543 }, + { url = "https://files.pythonhosted.org/packages/cd/c2/071f5a5ff6c5bd63aaaf2f45c811d9bf2ced94bde188d9e1a519e21d0cba/matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c", size = 9622800 }, + { url = "https://files.pythonhosted.org/packages/95/57/da7d1f10a85624b9e7db68e069dd94e58dc41dbf9463c5921632ecbe3661/matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4", size = 9888561 }, + { url = "https://files.pythonhosted.org/packages/67/b2/ef8d6bb59b0edb6c16c968b70f548aa13b54348972def5aa6ac85df67145/matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf", size = 9680884 }, + { url = "https://files.pythonhosted.org/packages/61/1c/d21bfeb9931881ebe96bcfcff27c7ae4b160ae0ec291a714c42641a56d75/matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39", size = 8432333 }, + { url = "https://files.pythonhosted.org/packages/78/23/92493c3e6e1b635ccfff146f7b99e674808787915420373ac399283764c2/matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c", size = 8324785 }, + { url = "https://files.pythonhosted.org/packages/63/e2/9f66ca6a651a52abfe0d4964ce01439ed34f3f1e119de10ff3a07f403043/matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20", size = 8304420 }, + { url = "https://files.pythonhosted.org/packages/e8/e8/467c03568218792906aa87b5e7bb379b605e056ed0c74fe00c051786d925/matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba", size = 8197981 }, + { url = "https://files.pythonhosted.org/packages/6f/87/afead29192170917537934c6aff4b008c805fff7b1ccea0c79120d96beda/matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4", size = 8774002 }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516 }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "mistune" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/55/d01f0c4b45ade6536c51170b9043db8b2ec6ddf4a35c7ea3f5f559ac935b/mistune-3.2.0.tar.gz", hash = "sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a", size = 95467 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl", hash = "sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1", size = 53598 }, +] + +[[package]] +name = "myst-parser" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579 }, +] + +[[package]] +name = "nbclient" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465 }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927 }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438 }, +] + +[[package]] +name = "notebook" +version = "7.5.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/6d/41052c48d6f6349ca0a7c4d1f6a78464de135e6d18f5829ba2510e62184c/notebook-7.5.5.tar.gz", hash = "sha256:dc0bfab0f2372c8278c457423d3256c34154ac2cc76bf20e9925260c461013c3", size = 14169167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/aa/cbd1deb9f07446241e88f8d5fecccd95b249bca0b4e5482214a4d1714c49/notebook-7.5.5-py3-none-any.whl", hash = "sha256:a7c14dbeefa6592e87f72290ca982e0c10f5bbf3786be2a600fda9da2764a2b8", size = 14578929 }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, +] + +[[package]] +name = "numpy" +version = "2.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/c6/4218570d8c8ecc9704b5157a3348e486e84ef4be0ed3e38218ab473c83d2/numpy-2.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", size = 16976799 }, + { url = "https://files.pythonhosted.org/packages/dd/92/b4d922c4a5f5dab9ed44e6153908a5c665b71acf183a83b93b690996e39b/numpy-2.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", size = 14971552 }, + { url = "https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", size = 5476566 }, + { url = "https://files.pythonhosted.org/packages/28/34/b3fdcec6e725409223dd27356bdf5a3c2cc2282e428218ecc9cb7acc9763/numpy-2.4.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", size = 6806482 }, + { url = "https://files.pythonhosted.org/packages/68/62/63417c13aa35d57bee1337c67446761dc25ea6543130cf868eace6e8157b/numpy-2.4.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", size = 15973376 }, + { url = "https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", size = 16925137 }, + { url = "https://files.pythonhosted.org/packages/7e/43/80020edacb3f84b9efdd1591120a4296462c23fd8db0dde1666f6ef66f13/numpy-2.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", size = 17329414 }, + { url = "https://files.pythonhosted.org/packages/fd/06/af0658593b18a5f73532d377188b964f239eb0894e664a6c12f484472f97/numpy-2.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", size = 18658397 }, + { url = "https://files.pythonhosted.org/packages/e6/ce/13a09ed65f5d0ce5c7dd0669250374c6e379910f97af2c08c57b0608eee4/numpy-2.4.4-cp311-cp311-win32.whl", hash = "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", size = 6239499 }, + { url = "https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", size = 12614257 }, + { url = "https://files.pythonhosted.org/packages/87/c5/8168052f080c26fa984c413305012be54741c9d0d74abd7fbeeccae3889f/numpy-2.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e", size = 10486775 }, + { url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272 }, + { url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573 }, + { url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782 }, + { url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038 }, + { url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480 }, + { url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036 }, + { url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643 }, + { url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117 }, + { url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584 }, + { url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450 }, + { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933 }, + { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532 }, + { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661 }, + { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539 }, + { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806 }, + { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682 }, + { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810 }, + { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394 }, + { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556 }, + { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311 }, + { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060 }, + { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302 }, + { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407 }, + { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631 }, + { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691 }, + { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241 }, + { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767 }, + { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169 }, + { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477 }, + { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487 }, + { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002 }, + { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353 }, + { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914 }, + { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005 }, + { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974 }, + { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591 }, + { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700 }, + { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781 }, + { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959 }, + { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768 }, + { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181 }, + { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035 }, + { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958 }, + { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020 }, + { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758 }, + { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948 }, + { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325 }, + { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883 }, + { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474 }, + { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500 }, + { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755 }, + { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643 }, + { url = "https://files.pythonhosted.org/packages/6b/33/8fae8f964a4f63ed528264ddf25d2b683d0b663e3cba26961eb838a7c1bd/numpy-2.4.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", size = 16854491 }, + { url = "https://files.pythonhosted.org/packages/bc/d0/1aabee441380b981cf8cdda3ae7a46aa827d1b5a8cce84d14598bc94d6d9/numpy-2.4.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", size = 14895830 }, + { url = "https://files.pythonhosted.org/packages/a5/b8/aafb0d1065416894fccf4df6b49ef22b8db045187949545bced89c034b8e/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", size = 5400927 }, + { url = "https://files.pythonhosted.org/packages/d6/77/063baa20b08b431038c7f9ff5435540c7b7265c78cf56012a483019ca72d/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", size = 6715557 }, + { url = "https://files.pythonhosted.org/packages/c7/a8/379542d45a14f149444c5c4c4e7714707239ce9cc1de8c2803958889da14/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", size = 15804253 }, + { url = "https://files.pythonhosted.org/packages/a2/c8/f0a45426d6d21e7ea3310a15cf90c43a14d9232c31a837702dba437f3373/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", size = 16753552 }, + { url = "https://files.pythonhosted.org/packages/04/74/f4c001f4714c3ad9ce037e18cf2b9c64871a84951eaa0baf683a9ca9301c/numpy-2.4.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", size = 12509075 }, +] + +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195 }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663 }, +] + +[[package]] +name = "parso" +version = "0.8.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/76/a1e769043c0c0c9fe391b702539d594731a4362334cdf4dc25d0c09761e7/parso-0.8.6.tar.gz", hash = "sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd", size = 401621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl", hash = "sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff", size = 106894 }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, +] + +[[package]] +name = "pillow" +version = "12.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/e1/748f5663efe6edcfc4e74b2b93edfb9b8b99b67f21a854c3ae416500a2d9/pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab", size = 5354347 }, + { url = "https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65", size = 4695873 }, + { url = "https://files.pythonhosted.org/packages/df/21/e3fbdf54408a973c7f7f89a23b2cb97a7ef30c61ab4142af31eee6aebc88/pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7", size = 6280168 }, + { url = "https://files.pythonhosted.org/packages/d3/f1/00b7278c7dd52b17ad4329153748f87b6756ec195ff786c2bdf12518337d/pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e", size = 8088188 }, + { url = "https://files.pythonhosted.org/packages/ad/cf/220a5994ef1b10e70e85748b75649d77d506499352be135a4989c957b701/pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705", size = 6394401 }, + { url = "https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176", size = 7079655 }, + { url = "https://files.pythonhosted.org/packages/6b/3d/45132c57d5fb4b5744567c3817026480ac7fc3ce5d4c47902bc0e7f6f853/pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b", size = 6503105 }, + { url = "https://files.pythonhosted.org/packages/7d/2e/9df2fc1e82097b1df3dce58dc43286aa01068e918c07574711fcc53e6fb4/pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909", size = 7203402 }, + { url = "https://files.pythonhosted.org/packages/bd/2e/2941e42858ebb67e50ae741473de81c2984e6eff7b397017623c676e2e8d/pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808", size = 6378149 }, + { url = "https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60", size = 7082626 }, + { url = "https://files.pythonhosted.org/packages/c2/88/549194b5d6f1f494b485e493edc6693c0a16f4ada488e5bd974ed1f42fad/pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe", size = 2463531 }, + { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279 }, + { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490 }, + { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462 }, + { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744 }, + { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371 }, + { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215 }, + { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783 }, + { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112 }, + { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489 }, + { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129 }, + { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612 }, + { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837 }, + { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528 }, + { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401 }, + { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094 }, + { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402 }, + { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005 }, + { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669 }, + { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194 }, + { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423 }, + { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667 }, + { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580 }, + { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896 }, + { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266 }, + { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508 }, + { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927 }, + { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624 }, + { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252 }, + { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550 }, + { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114 }, + { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667 }, + { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966 }, + { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241 }, + { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592 }, + { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542 }, + { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765 }, + { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848 }, + { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515 }, + { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159 }, + { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185 }, + { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386 }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384 }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599 }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021 }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360 }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628 }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321 }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723 }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400 }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835 }, + { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225 }, + { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541 }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251 }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807 }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935 }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720 }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498 }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413 }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084 }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152 }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579 }, + { url = "https://files.pythonhosted.org/packages/4e/b7/2437044fb910f499610356d1352e3423753c98e34f915252aafecc64889f/pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f", size = 5273969 }, + { url = "https://files.pythonhosted.org/packages/f6/f4/8316e31de11b780f4ac08ef3654a75555e624a98db1056ecb2122d008d5a/pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d", size = 4659674 }, + { url = "https://files.pythonhosted.org/packages/d4/37/664fca7201f8bb2aa1d20e2c3d5564a62e6ae5111741966c8319ca802361/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f", size = 5288479 }, + { url = "https://files.pythonhosted.org/packages/49/62/5b0ed78fce87346be7a5cfcfaaad91f6a1f98c26f86bdbafa2066c647ef6/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e", size = 7032230 }, + { url = "https://files.pythonhosted.org/packages/c3/28/ec0fc38107fc32536908034e990c47914c57cd7c5a3ece4d8d8f7ffd7e27/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0", size = 5355404 }, + { url = "https://files.pythonhosted.org/packages/5e/8b/51b0eddcfa2180d60e41f06bd6d0a62202b20b59c68f5a132e615b75aecf/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1", size = 6002215 }, + { url = "https://files.pythonhosted.org/packages/bc/60/5382c03e1970de634027cee8e1b7d39776b778b81812aaf45b694dfe9e28/pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e", size = 7080946 }, +] + +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348 }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, +] + +[[package]] +name = "pre-commit" +version = "4.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/2de9408ac81acbb8a7d05d4cc064a152ccf33b3d480ebe0cd292153db239/pre_commit-4.6.0.tar.gz", hash = "sha256:718d2208cef53fdc38206e40524a6d4d9576d103eb16f0fec11c875e7716e9d9", size = 198525 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472 }, +] + +[[package]] +name = "prometheus-client" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/fb/d9aa83ffe43ce1f19e557c0971d04b90561b0cfd50762aafb01968285553/prometheus_client-0.25.0.tar.gz", hash = "sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28", size = 86035 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/9b/d4b1e644385499c8346fa9b622a3f030dce14cd6ef8a1871c221a17a67e7/prometheus_client-0.25.0-py3-none-any.whl", hash = "sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1", size = 64154 }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431 }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595 }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082 }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476 }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062 }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893 }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589 }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664 }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087 }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383 }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210 }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228 }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284 }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090 }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859 }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560 }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997 }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972 }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266 }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737 }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617 }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, +] + +[[package]] +name = "pya" +version = "0.5.2" +source = { editable = "." } +dependencies = [ + { name = "matplotlib" }, + { name = "pyamapping" }, + { name = "scipy" }, + { name = "soundfile" }, +] + +[package.optional-dependencies] +example-notebooks = [ + { name = "notebook" }, +] +pyaudio = [ + { name = "pyaudio" }, +] +remote = [ + { name = "ipywidgets" }, + { name = "notebook" }, + { name = "websocket" }, +] + +[package.dev-dependencies] +dev = [ + { name = "myst-parser" }, + { name = "pre-commit" }, + { name = "pydocstyle" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "sphinx" }, + { name = "sphinx-rtd-theme" }, + { name = "tox" }, +] + +[package.metadata] +requires-dist = [ + { name = "ipywidgets", marker = "extra == 'remote'" }, + { name = "matplotlib", specifier = ">=3.5.3" }, + { name = "notebook", marker = "extra == 'example-notebooks'" }, + { name = "notebook", marker = "extra == 'remote'" }, + { name = "pyamapping" }, + { name = "pyaudio", marker = "extra == 'pyaudio'", specifier = ">=0.2.12" }, + { name = "scipy", specifier = ">=1.7.3" }, + { name = "soundfile", specifier = ">=0.13.0" }, + { name = "websocket", marker = "extra == 'remote'" }, +] +provides-extras = ["example-notebooks", "pyaudio", "remote"] + +[package.metadata.requires-dev] +dev = [ + { name = "myst-parser" }, + { name = "pre-commit" }, + { name = "pydocstyle" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "sphinx", specifier = "==7.2.6" }, + { name = "sphinx-rtd-theme", specifier = "==2.0.0" }, + { name = "tox" }, +] + +[[package]] +name = "pyamapping" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/fa/500657cf5b6f446b93d8492c1af728a0896283a256785a354d670bee15ec/pyamapping-0.1.0.tar.gz", hash = "sha256:20f75d8fc0f2fb9cd953954f3f7e8ecbea171a71fb7aef2d11b7824fba65c7ae", size = 22581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/9b/bf0a5232859bf0f71a413bdac166d767a5148cc05e09a4450dc6e3ae5bce/pyamapping-0.1.0-py3-none-any.whl", hash = "sha256:1d11c926df305c85325c6fb3e78848f614631d62d4c384e559adb455e9551b12", size = 4908 }, +] + +[[package]] +name = "pyaudio" +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/1d/8878c7752febb0f6716a7e1a52cb92ac98871c5aa522cba181878091607c/PyAudio-0.2.14.tar.gz", hash = "sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87", size = 47066 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/f0/b0eab89eafa70a86b7b566a4df2f94c7880a2d483aa8de1c77d335335b5b/PyAudio-0.2.14-cp311-cp311-win32.whl", hash = "sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289", size = 144624 }, + { url = "https://files.pythonhosted.org/packages/82/d8/f043c854aad450a76e476b0cf9cda1956419e1dacf1062eb9df3c0055abe/PyAudio-0.2.14-cp311-cp311-win_amd64.whl", hash = "sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903", size = 164070 }, + { url = "https://files.pythonhosted.org/packages/8d/45/8d2b76e8f6db783f9326c1305f3f816d4a12c8eda5edc6a2e1d03c097c3b/PyAudio-0.2.14-cp312-cp312-win32.whl", hash = "sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b", size = 144750 }, + { url = "https://files.pythonhosted.org/packages/b0/6a/d25812e5f79f06285767ec607b39149d02aa3b31d50c2269768f48768930/PyAudio-0.2.14-cp312-cp312-win_amd64.whl", hash = "sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3", size = 164126 }, + { url = "https://files.pythonhosted.org/packages/3a/77/66cd37111a87c1589b63524f3d3c848011d21ca97828422c7fde7665ff0d/PyAudio-0.2.14-cp313-cp313-win32.whl", hash = "sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497", size = 150982 }, + { url = "https://files.pythonhosted.org/packages/a5/8b/7f9a061c1cc2b230f9ac02a6003fcd14c85ce1828013aecbaf45aa988d20/PyAudio-0.2.14-cp313-cp313-win_amd64.whl", hash = "sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69", size = 173655 }, +] + +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140 }, +] + +[[package]] +name = "pydocstyle" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "snowballstemmer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/d5385ca59fd065e3c6a5fe19f9bc9d5ea7f2509fa8c9c22fb6b2031dd953/pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1", size = 36796 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/ea/99ddefac41971acad68f14114f38261c1f27dac0b3ec529824ebc739bdaa/pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019", size = 38038 }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151 }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781 }, +] + +[[package]] +name = "pyproject-api" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/45/7b/c0e1333b61d41c69e59e5366e727b18c4992688caf0de1be10b3e5265f6b/pyproject_api-1.10.0.tar.gz", hash = "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330", size = 22785 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl", hash = "sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09", size = 13218 }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249 }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "python-discovery" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894 }, +] + +[[package]] +name = "python-json-logger" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ff/3cc9165fd44106973cd7ac9facb674a65ed853494592541d339bdc9a30eb/python_json_logger-4.1.0.tar.gz", hash = "sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195", size = 17573 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/be/0631a861af4d1c875f096c07d34e9a63639560a717130e7a87cbc82b7e3f/python_json_logger-4.1.0-py3-none-any.whl", hash = "sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2", size = 15021 }, +] + +[[package]] +name = "pywinpty" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/54/37c7370ba91f579235049dc26cd2c5e657d2a943e01820844ffc81f32176/pywinpty-3.0.3.tar.gz", hash = "sha256:523441dc34d231fb361b4b00f8c99d3f16de02f5005fd544a0183112bcc22412", size = 31309 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/c3/3e75075c7f71735f22b66fab0481f2c98e3a4d58cba55cb50ba29114bcf6/pywinpty-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:dff25a9a6435f527d7c65608a7e62783fc12076e7d44487a4911ee91be5a8ac8", size = 2114430 }, + { url = "https://files.pythonhosted.org/packages/8d/1e/8a54166a8c5e4f5cb516514bdf4090be4d51a71e8d9f6d98c0aa00fe45d4/pywinpty-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:fbc1e230e5b193eef4431cba3f39996a288f9958f9c9f092c8a961d930ee8f68", size = 236191 }, + { url = "https://files.pythonhosted.org/packages/7c/d4/aeb5e1784d2c5bff6e189138a9ca91a090117459cea0c30378e1f2db3d54/pywinpty-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c9081df0e49ffa86d15db4a6ba61530630e48707f987df42c9d3313537e81fc0", size = 2113098 }, + { url = "https://files.pythonhosted.org/packages/b9/53/7278223c493ccfe4883239cf06c823c56460a8010e0fc778eef67858dc14/pywinpty-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:15e79d870e18b678fb8a5a6105fd38496b55697c66e6fc0378236026bc4d59e9", size = 234901 }, + { url = "https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab", size = 2112686 }, + { url = "https://files.pythonhosted.org/packages/fd/50/724ed5c38c504d4e58a88a072776a1e880d970789deaeb2b9f7bd9a5141a/pywinpty-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:fe1f7911805127c94cf51f89ab14096c6f91ffdcacf993d2da6082b2142a2523", size = 234591 }, + { url = "https://files.pythonhosted.org/packages/f7/ad/90a110538696b12b39fd8758a06d70ded899308198ad2305ac68e361126e/pywinpty-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:3f07a6cf1c1d470d284e614733c3d0f726d2c85e78508ea10a403140c3c0c18a", size = 2112360 }, + { url = "https://files.pythonhosted.org/packages/44/0f/7ffa221757a220402bc79fda44044c3f2cc57338d878ab7d622add6f4581/pywinpty-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:15c7c0b6f8e9d87aabbaff76468dabf6e6121332c40fc1d83548d02a9d6a3759", size = 233107 }, + { url = "https://files.pythonhosted.org/packages/28/88/2ff917caff61e55f38bcdb27de06ee30597881b2cae44fbba7627be015c4/pywinpty-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:d4b6b7b0fe0cdcd02e956bd57cfe9f4e5a06514eecf3b5ae174da4f951b58be9", size = 2113282 }, + { url = "https://files.pythonhosted.org/packages/63/32/40a775343ace542cc43ece3f1d1fce454021521ecac41c4c4573081c2336/pywinpty-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:34789d685fc0d547ce0c8a65e5a70e56f77d732fa6e03c8f74fefb8cbb252019", size = 234207 }, + { url = "https://files.pythonhosted.org/packages/8d/54/5d5e52f4cb75028104ca6faf36c10f9692389b1986d34471663b4ebebd6d/pywinpty-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:0c37e224a47a971d1a6e08649a1714dac4f63c11920780977829ed5c8cadead1", size = 2112910 }, + { url = "https://files.pythonhosted.org/packages/0a/44/dcd184824e21d4620b06c7db9fbb15c3ad0a0f1fa2e6de79969fb82647ec/pywinpty-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c4e9c3dff7d86ba81937438d5819f19f385a39d8f592d4e8af67148ceb4f6ab5", size = 233425 }, +] + +[[package]] +name = "pyyaml" +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 } +wheels = [ + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114 }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638 }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463 }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986 }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543 }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763 }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063 }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973 }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116 }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011 }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870 }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089 }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181 }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658 }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003 }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344 }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 }, +] + +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328 }, + { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803 }, + { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836 }, + { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038 }, + { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531 }, + { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786 }, + { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220 }, + { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155 }, + { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428 }, + { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497 }, + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279 }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645 }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574 }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995 }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070 }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121 }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550 }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184 }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480 }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993 }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436 }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301 }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197 }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275 }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469 }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961 }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282 }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468 }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394 }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964 }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029 }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541 }, + { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197 }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175 }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427 }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929 }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193 }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388 }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316 }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472 }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401 }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170 }, + { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265 }, + { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208 }, + { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747 }, + { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371 }, + { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862 }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766 }, +] + +[[package]] +name = "requests" +version = "2.33.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947 }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046 }, +] + +[[package]] +name = "rpds-py" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157 }, + { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676 }, + { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938 }, + { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932 }, + { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830 }, + { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033 }, + { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828 }, + { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683 }, + { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583 }, + { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496 }, + { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669 }, + { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011 }, + { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406 }, + { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024 }, + { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069 }, + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086 }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053 }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763 }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951 }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622 }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492 }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080 }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680 }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589 }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289 }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737 }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120 }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782 }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463 }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868 }, + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887 }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904 }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945 }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783 }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021 }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589 }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025 }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895 }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799 }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731 }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027 }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020 }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139 }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224 }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645 }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443 }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375 }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850 }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812 }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841 }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149 }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843 }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507 }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949 }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790 }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217 }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806 }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341 }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768 }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099 }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192 }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080 }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841 }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670 }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005 }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112 }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049 }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661 }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606 }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126 }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371 }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298 }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604 }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391 }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868 }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747 }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795 }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330 }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194 }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340 }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765 }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834 }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470 }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630 }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148 }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030 }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570 }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532 }, + { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292 }, + { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128 }, + { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542 }, + { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004 }, + { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063 }, + { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099 }, + { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177 }, + { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015 }, + { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736 }, + { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981 }, + { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782 }, + { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191 }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", size = 31613675 }, + { url = "https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", size = 28162057 }, + { url = "https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", size = 20334032 }, + { url = "https://files.pythonhosted.org/packages/ec/e6/cef1cf3557f0c54954198554a10016b6a03b2ec9e22a4e1df734936bd99c/scipy-1.17.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", size = 22709533 }, + { url = "https://files.pythonhosted.org/packages/4d/60/8804678875fc59362b0fb759ab3ecce1f09c10a735680318ac30da8cd76b/scipy-1.17.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", size = 33062057 }, + { url = "https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", size = 35349300 }, + { url = "https://files.pythonhosted.org/packages/b4/3d/7ccbbdcbb54c8fdc20d3b6930137c782a163fa626f0aef920349873421ba/scipy-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", size = 35127333 }, + { url = "https://files.pythonhosted.org/packages/e8/19/f926cb11c42b15ba08e3a71e376d816ac08614f769b4f47e06c3580c836a/scipy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", size = 37741314 }, + { url = "https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", size = 36607512 }, + { url = "https://files.pythonhosted.org/packages/68/7f/bdd79ceaad24b671543ffe0ef61ed8e659440eb683b66f033454dcee90eb/scipy-1.17.1-cp311-cp311-win_arm64.whl", hash = "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", size = 24599248 }, + { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954 }, + { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662 }, + { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366 }, + { url = "https://files.pythonhosted.org/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017 }, + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842 }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890 }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557 }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856 }, + { url = "https://files.pythonhosted.org/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682 }, + { url = "https://files.pythonhosted.org/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340 }, + { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199 }, + { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001 }, + { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719 }, + { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429 }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952 }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063 }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449 }, + { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943 }, + { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621 }, + { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708 }, + { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135 }, + { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977 }, + { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601 }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667 }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159 }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771 }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910 }, + { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980 }, + { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543 }, + { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510 }, + { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131 }, + { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032 }, + { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766 }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007 }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333 }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066 }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763 }, + { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984 }, + { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877 }, + { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750 }, + { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858 }, + { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723 }, + { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098 }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397 }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163 }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291 }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317 }, + { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327 }, + { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165 }, +] + +[[package]] +name = "send2trash" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/f0/184b4b5f8d00f2a92cf96eec8967a3d550b52cf94362dad1100df9e48d57/send2trash-2.1.0.tar.gz", hash = "sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459", size = 17255 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610 }, +] + +[[package]] +name = "setuptools" +version = "82.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "snowballstemmer" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274 }, +] + +[[package]] +name = "soundfile" +version = "0.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/41/9b873a8c055582859b239be17902a85339bec6a30ad162f98c9b0288a2cc/soundfile-0.13.1.tar.gz", hash = "sha256:b2c68dab1e30297317080a5b43df57e302584c49e2942defdde0acccc53f0e5b", size = 46156 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/28/e2a36573ccbcf3d57c00626a21fe51989380636e821b341d36ccca0c1c3a/soundfile-0.13.1-py2.py3-none-any.whl", hash = "sha256:a23c717560da2cf4c7b5ae1142514e0fd82d6bbd9dfc93a50423447142f2c445", size = 25751 }, + { url = "https://files.pythonhosted.org/packages/ea/ab/73e97a5b3cc46bba7ff8650a1504348fa1863a6f9d57d7001c6b67c5f20e/soundfile-0.13.1-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:82dc664d19831933fe59adad199bf3945ad06d84bc111a5b4c0d3089a5b9ec33", size = 1142250 }, + { url = "https://files.pythonhosted.org/packages/a0/e5/58fd1a8d7b26fc113af244f966ee3aecf03cb9293cb935daaddc1e455e18/soundfile-0.13.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:743f12c12c4054921e15736c6be09ac26b3b3d603aef6fd69f9dde68748f2593", size = 1101406 }, + { url = "https://files.pythonhosted.org/packages/58/ae/c0e4a53d77cf6e9a04179535766b3321b0b9ced5f70522e4caf9329f0046/soundfile-0.13.1-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9c9e855f5a4d06ce4213f31918653ab7de0c5a8d8107cd2427e44b42df547deb", size = 1235729 }, + { url = "https://files.pythonhosted.org/packages/57/5e/70bdd9579b35003a489fc850b5047beeda26328053ebadc1fb60f320f7db/soundfile-0.13.1-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:03267c4e493315294834a0870f31dbb3b28a95561b80b134f0bd3cf2d5f0e618", size = 1313646 }, + { url = "https://files.pythonhosted.org/packages/fe/df/8c11dc4dfceda14e3003bb81a0d0edcaaf0796dd7b4f826ea3e532146bba/soundfile-0.13.1-py2.py3-none-win32.whl", hash = "sha256:c734564fab7c5ddf8e9be5bf70bab68042cd17e9c214c06e365e20d64f9a69d5", size = 899881 }, + { url = "https://files.pythonhosted.org/packages/14/e9/6b761de83277f2f02ded7e7ea6f07828ec78e4b229b80e4ca55dd205b9dc/soundfile-0.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:1e70a05a0626524a69e9f0f4dd2ec174b4e9567f4d8b6c11d38b5c289be36ee9", size = 1019162 }, +] + +[[package]] +name = "soupsieve" +version = "2.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016 }, +] + +[[package]] +name = "sphinx" +version = "7.2.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/8e/6e51da4b26665b4b92b1944ea18b2d9c825e753e19180cc5bdc818d0ed3b/sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5", size = 7015183 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/b6/8ed35256aa530a9d3da15d20bdc0ba888d5364441bb50a5a83ee7827affe/sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560", size = 3207959 }, +] + +[[package]] +name = "sphinx-rtd-theme" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "sphinx" }, + { name = "sphinxcontrib-jquery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/33/2a35a9cdbfda9086bda11457bcc872173ab3565b16b6d7f6b3efaa6dc3d6/sphinx_rtd_theme-2.0.0.tar.gz", hash = "sha256:bd5d7b80622406762073a04ef8fadc5f9151261563d47027de09910ce03afe6b", size = 2785005 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/46/00fda84467815c29951a9c91e3ae7503c409ddad04373e7cfc78daad4300/sphinx_rtd_theme-2.0.0-py2.py3-none-any.whl", hash = "sha256:ec93d0856dc280cf3aee9a4c9807c60e027c7f7b461b77aeffed682e68f0e586", size = 2824721 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/f3/aa67467e051df70a6330fe7770894b3e4f09436dea6881ae0b4f3d87cad8/sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a", size = 122331 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/85/749bd22d1a68db7291c89e2ebca53f4306c3f205853cf31e9de279034c3c/sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae", size = 121104 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, +] + +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, +] + +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704 }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454 }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561 }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824 }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227 }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859 }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204 }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084 }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285 }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924 }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018 }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948 }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341 }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159 }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290 }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141 }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847 }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088 }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866 }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887 }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704 }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628 }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180 }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674 }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976 }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755 }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265 }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726 }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859 }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713 }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084 }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973 }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223 }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973 }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082 }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490 }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263 }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736 }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717 }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461 }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855 }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144 }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683 }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196 }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393 }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583 }, +] + +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675 }, +] + +[[package]] +name = "tornado" +version = "6.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983 }, + { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246 }, + { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229 }, + { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192 }, + { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039 }, + { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445 }, + { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582 }, + { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990 }, + { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016 }, +] + +[[package]] +name = "tox" +version = "4.53.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "colorama" }, + { name = "filelock" }, + { name = "packaging" }, + { name = "platformdirs" }, + { name = "pluggy" }, + { name = "pyproject-api" }, + { name = "python-discovery" }, + { name = "tomli-w" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/01/d87a00063fa670ce4c48a9706b615a95ddf2c9ef5558d43af6071f166fd4/tox-4.53.0.tar.gz", hash = "sha256:62c780e42f87d34ee60f2ea20342156253794fdcbd6885fd797d98ee05009f22", size = 274048 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/03/02e2a03f3756cfb66e7e1bac41b06953f12cec75ddb961d56695d4d43dc4/tox-4.53.0-py3-none-any.whl", hash = "sha256:cc4e716d18c4889aa179d785175c438fa60c35deef20ce689ec288d8fb656096", size = 212164 }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, +] + +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584 }, +] + +[[package]] +name = "virtualenv" +version = "21.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/8b/6331f7a7fe70131c301106ec1e7cf23e2501bf7d4ca3636805801ca191bb/virtualenv-21.3.0.tar.gz", hash = "sha256:733750db978ec95c2d8eb4feadaa57091002bce404cb39ba69899cf7bd28944e", size = 7614069 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/eb/03bfb1299d4c4510329e470f13f9a4ce793df7fcb5a2fd3510f911066f61/virtualenv-21.3.0-py3-none-any.whl", hash = "sha256:4d28ee41f6d9ec8f1f00cd472b9ffbcedda1b3d3b9a575b5c94a2d004fd51bd7", size = 7594690 }, +] + +[[package]] +name = "wcwidth" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189 }, +] + +[[package]] +name = "webcolors" +version = "25.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "websocket" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gevent" }, + { name = "greenlet" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/6d/a60d620ea575c885510c574909d2e3ed62129b121fa2df00ca1c81024c87/websocket-0.2.1.tar.gz", hash = "sha256:42b506fae914ac5ed654e23ba9742e6a342b1a1c3eb92632b6166c65256469a4", size = 195339 } + +[[package]] +name = "websocket-client" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616 }, +] + +[[package]] +name = "widgetsnbextension" +version = "4.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b7404b7aefcd7569a9c0d6bd071299bf4198ae7a5d95/widgetsnbextension-4.0.15.tar.gz", hash = "sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9", size = 1097402 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503 }, +] + +[[package]] +name = "zope-event" +version = "6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/93/41/faa10af34d48d9cd6fa0249a1162943ad84a9590bd1a06939981e6640416/zope_event-6.2.tar.gz", hash = "sha256:b97d5d6327067ee6b9dfcbdf606ade9ade70991e19c162e808ea39e5fcf0f8d3", size = 18958 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/33/848922889e946d4befc415c219fe516af75c49555d8e736e183bfd30db42/zope_event-6.2-py3-none-any.whl", hash = "sha256:5e755153ac4faf64c10a4b6dd3307680166a3edf65b38df22df592610f8fa874", size = 6525 }, +] + +[[package]] +name = "zope-interface" +version = "8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/65/34a6e6e4dfa260c4c55ee02bb2fc53625e126ff0181485286cf0c9d453d6/zope_interface-8.4.tar.gz", hash = "sha256:9dbee7925a23aa6349738892c911019d4095a96cff487b743482073ecbc174a8", size = 257736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/11/bd982648e1e62d7c06a56017fd88d1beea2ebc8d7a5972cce137e774aff2/zope_interface-8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8b733af6e89a2b0b8edf5ff7a37988fe4e1788806e84e72127b88c47858f0da6", size = 210908 }, + { url = "https://files.pythonhosted.org/packages/2d/4f/fa87d3bd69d22b93fa5b968597a3dd0a297e44aa87e4611b0ca74c4aeec1/zope_interface-8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:265bad2df2ec070f23ff863249a89b408b11908fd4207662781fd18e3c6fc912", size = 211235 }, + { url = "https://files.pythonhosted.org/packages/eb/74/67379f7df4400ee45299c5200f17ec6c493e8a120ff4e5e9d26b09e32956/zope_interface-8.4-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:e195e76767847afb5379ffd67690c17d3c6efdab58dc0e477cf81ac94d5a5a15", size = 259918 }, + { url = "https://files.pythonhosted.org/packages/b2/4e/c5106672b5c0b9071ce988d54124277762c3085cf1bc72e965e7173f1c26/zope_interface-8.4-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5ec1a56b6cf9a757cbbce9da38284a01473b92b96c1517eabd99150f51f1bb69", size = 264343 }, + { url = "https://files.pythonhosted.org/packages/fe/49/270c11e54e01b96d2efc59acbeb006a4171b8fafb75926c27d2184c32949/zope_interface-8.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:04c2c9b58e9c177628715d85e94834efa807c1f9f0a2f57ae0f7b553e8266ac4", size = 265629 }, + { url = "https://files.pythonhosted.org/packages/b9/03/4ef05ada2230f05f08f579c45b60f127cce2bf379148cb7c21401052ca9d/zope_interface-8.4-cp311-cp311-win_amd64.whl", hash = "sha256:376d0ef005a131b349e2088e302aa094fa23c826d2ec8a7db4b00fb33c71e0d9", size = 214595 }, + { url = "https://files.pythonhosted.org/packages/6a/f6/22a304f4061d7ec02e20816d804ab0e844564055b25d471371173c44d73e/zope_interface-8.4-cp311-cp311-win_arm64.whl", hash = "sha256:caffd033b27e311b45e15f01923cc9e73c6bfd8e843b4532e29b59ee432bf893", size = 212904 }, + { url = "https://files.pythonhosted.org/packages/b8/96/0017b980424125cf98a9851d8fd3e24939818b7a82ecdd19ae672bb2413f/zope_interface-8.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:84064876ed96ddd0744e3ad5d37134c758d77885e54113567792671405a02bac", size = 211604 }, + { url = "https://files.pythonhosted.org/packages/59/4c/2cf5c45477fdd58a2c786d0c0d1817cbaaff8743d98ae72c643c4fe3be7b/zope_interface-8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:81ed23698bfb588c48b1756129814b890febac971ff6c8a414f82601773145bb", size = 211783 }, + { url = "https://files.pythonhosted.org/packages/fa/8c/efabdafc25ed44ef9c1084aad9870bb6c2c9b78e542684efe6865c0f0067/zope_interface-8.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:e0b9d7e958657fad414f8272afcdf0b8a873fbbb2bb6a6287232d2f11a232bf8", size = 264752 }, + { url = "https://files.pythonhosted.org/packages/53/5a/c4d52c58d5fee4ff67cc02f0dec24d0e84428520f67a52f1e4086f0e7779/zope_interface-8.4-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eef0a49e041f4dc4d2a6ab894b4fd0c5354e0e8037e731fb953531e59b0d3d33", size = 269829 }, + { url = "https://files.pythonhosted.org/packages/16/d2/df8f339c93bb5adee695546ba90d0daa2917338a4792281f6b8e652a9328/zope_interface-8.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b302f955c36e924e1f4fe70dd9105ff06235857861c6ae72c3b10b016aeee99", size = 269452 }, + { url = "https://files.pythonhosted.org/packages/17/4b/bd97b1a21bb2c16d66a42f6c7a43c0a5afcfaf14c68d3b7d2ee6afb28e52/zope_interface-8.4-cp312-cp312-win_amd64.whl", hash = "sha256:4ae6a1e111642dbf724f635424dcaf5a5c8abbde49eac3f452f5323ffaa10232", size = 214420 }, + { url = "https://files.pythonhosted.org/packages/7d/85/1477f23cf3b0476608ca987b4338f91439abb5b96564ac26b26d2cde38fd/zope_interface-8.4-cp312-cp312-win_arm64.whl", hash = "sha256:2e9e4aa33b76877af903d5532545e64d24ade0f6f80d9d1a31e6efcea76a60bc", size = 212992 }, + { url = "https://files.pythonhosted.org/packages/8e/6a/a08c62bc1fa0e34fe7b8b401646cba4817427c716bfbef6cc88937cd327f/zope_interface-8.4-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:cd55965d715413038774aead54851bc3dbdd74a69f3ce30252182a94407b9905", size = 211924 }, + { url = "https://files.pythonhosted.org/packages/50/30/2011f17e00ff078658bc317e1f7eccd7843fc1ce60695b665b0a52c45c1b/zope_interface-8.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0d88c1f106a4f06e074a3ada2d20f4a602e3f2871c4f55726ed5d91e94ec19b1", size = 211995 }, + { url = "https://files.pythonhosted.org/packages/25/f3/a16fe884571cfa89271412dbb40def6d6865824428d1e14785a82795100c/zope_interface-8.4-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:36c575356732d59ffd3279ad67e302a6fe517e67db5b061b36b377ee0fa016c4", size = 264443 }, + { url = "https://files.pythonhosted.org/packages/83/88/e08923fcd8a8c8704af05a90418b07cd897ac90865925b37d7ad8139adfa/zope_interface-8.4-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:29f09ec8bda65f7b30294328070070a2590b90f252f834ee0817cdb0e2c35f6a", size = 269626 }, + { url = "https://files.pythonhosted.org/packages/27/67/96c94cd307f9946d0b0f03402a335f7aae7b4f0b129b5734cc56cc78cb65/zope_interface-8.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2bc388cebcb753d21eaf2a0481fd6f0ce6840a47300a40dcec0b56bac27d0f97", size = 269583 }, + { url = "https://files.pythonhosted.org/packages/e2/d4/7e9fcc8bb0dba5d023b9fca92035d68c018457cc550e9d51746670b76a6b/zope_interface-8.4-cp313-cp313-win_amd64.whl", hash = "sha256:3e5866917ccb57d929e515a1136d729bd3fa4f367965fb16e38a4bc72cb05521", size = 214422 }, + { url = "https://files.pythonhosted.org/packages/16/26/b0bcde302f6a4c155d047a8ab5cba1003363031919d6e8f3bcdc139c28a6/zope_interface-8.4-cp313-cp313-win_arm64.whl", hash = "sha256:f1f854bef8bc137519e4413bcc1322d55faad28b20b3ca39f7bec49d2f1b26df", size = 213029 }, + { url = "https://files.pythonhosted.org/packages/f6/d5/ca60c8b404b303d9490e1417430a5198a77557dbeb17c1cb31616e432318/zope_interface-8.4-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:7cbb887fdbfaacb4c362dbb487033551646e28013ad5ffe72e96eb260003a1a1", size = 212012 }, + { url = "https://files.pythonhosted.org/packages/83/64/6bb9f54250c817e24b39e986f173b6cd21ff658bec6c6cc0baad05d761e4/zope_interface-8.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a5638c6be715116d3453e6d099c299c6844d54810de7445ce116424e905ede06", size = 212071 }, + { url = "https://files.pythonhosted.org/packages/c6/cf/42851262e102723058019dc7d0b48210b85a935f79ae32ce60ddccc2e8fb/zope_interface-8.4-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b8147b40bfcd53803870a9519e0879ff066aeecc2fcff8295663c1b17fc38dc2", size = 266075 }, + { url = "https://files.pythonhosted.org/packages/d2/a7/e48c79b836f6f0a2c219288e2ec343517f90e95c93de5435a8a23918bf20/zope_interface-8.4-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:049ba3c7b38cc400ae08e011617635706e0f442e1d075db1b015246fcbf6091e", size = 269127 }, + { url = "https://files.pythonhosted.org/packages/6a/40/0e26f24d3a2f34f0de2cfeaab6458a865284d9d1fa317ab78913aa1f7322/zope_interface-8.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9c4ac009c2c8e43283842f80387c4d4b41bcbc293391c3b9ab71532ae1ccc301", size = 269446 }, + { url = "https://files.pythonhosted.org/packages/91/d5/20310601450367fc35fa28b0544c98d0347b8cc25eaf106a2c4cc36841e1/zope_interface-8.4-cp314-cp314-win_amd64.whl", hash = "sha256:4713bf651ec36e7eea49d2ace4f0e89bec2b33a339674874b1121f2537edc62a", size = 215199 }, + { url = "https://files.pythonhosted.org/packages/5b/00/0d22ce75126e31f81baa5889e2a40aad37c8e34d1220cf8b18d744f2b5d9/zope_interface-8.4-cp314-cp314-win_arm64.whl", hash = "sha256:d934497c4b72d5f528d2b5ebe9b8b5a7004b5877948ebd4ea00c2432fb27178f", size = 213178 }, +] From 7232e99bf3d11347ac5ff0110ca995a99a87401a Mon Sep 17 00:00:00 2001 From: Fabian Hommel Date: Tue, 12 May 2026 12:48:32 +0200 Subject: [PATCH 6/6] Updated versions for github workflow matrix test --- .github/workflows/pya-ci.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pya-ci.yaml b/.github/workflows/pya-ci.yaml index 725035ea..9ec602d0 100644 --- a/.github/workflows/pya-ci.yaml +++ b/.github/workflows/pya-ci.yaml @@ -52,11 +52,10 @@ jobs: strategy: matrix: python: - - "3.10" - - "3.11" # oldest Python supported by PSF - - "3.12" # oldest Python supported by PSF - - "3.13" # oldest Python supported by PSF - - "3.14" # newest Python that is stable + - "3.11" + - "3.12" + - "3.13" + - "3.14" platform: - ubuntu-latest - macos-latest