From d29653c46b2a71203eefbc3ce4acf6544e8b9746 Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Wed, 10 Dec 2025 10:32:17 +0900 Subject: [PATCH 1/6] feat: Add example CIF/JSON data, update dependencies, and modify I/O parsing utilities. --- example_mmjson/2hhb.cif.gz | Bin 0 -> 131968 bytes example_mmjson/2hhb.json.gz | Bin 0 -> 85741 bytes src/atomworks/io/parser.py | 13 +- src/atomworks/io/utils/io_utils.py | 53 +- uv.lock | 2896 ++++++++++++++++++++++++++++ 5 files changed, 2950 insertions(+), 12 deletions(-) create mode 100644 example_mmjson/2hhb.cif.gz create mode 100644 example_mmjson/2hhb.json.gz create mode 100644 uv.lock diff --git a/example_mmjson/2hhb.cif.gz b/example_mmjson/2hhb.cif.gz new file mode 100644 index 0000000000000000000000000000000000000000..19767c42f907f39b856ba9342aca7c6ee679d666 GIT binary patch literal 131968 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 Q6#66vCX~C@C&7OEUtKH1ZvX%Q literal 0 HcmV?d00001 diff --git a/src/atomworks/io/parser.py b/src/atomworks/io/parser.py index e539d353..d57e75fe 100644 --- a/src/atomworks/io/parser.py +++ b/src/atomworks/io/parser.py @@ -125,7 +125,7 @@ def _build_cache_file_path( def parse( filename: os.PathLike | io.StringIO | io.BytesIO, *, - file_type: Literal["cif", "pdb"] | None = None, + file_type: Literal["cif", "pdb", "mmjson"] | None = None, ccd_mirror_path: os.PathLike | None = CCD_MIRROR_PATH, cache_dir: os.PathLike | None = None, save_to_cache: bool = False, @@ -163,7 +163,7 @@ def parse( atomic-level structure (e.g. .cif, .bcif, .cif.gz, .pdb), although .cif files are strongly recommended. **Wrapper arguments:** - file_type (Literal["cif", "pdb"] | None, optional): The file type of the structure file. + file_type (Literal["cif", "pdb", "mmjson"] | None, optional): The file type of the structure file. If not provided, the file type will be inferred automatically. load_from_cache (bool, optional): Whether to load pre-compiled results from cache. Defaults to False. cache_dir (PathLike, optional): Directory path to save pre-compiled results. Defaults to None. @@ -329,9 +329,10 @@ def parse( build_assembly=build_assembly, extra_fields=extra_fields, ) - elif file_type in ("cif", "bcif"): + elif file_type in ("cif", "bcif", "mmjson"): result = _parse_from_cif( filename=filename, + file_type=file_type, ccd_mirror_path=ccd_mirror_path, add_missing_atoms=add_missing_atoms, add_id_and_entity_annotations=add_id_and_entity_annotations, @@ -684,7 +685,9 @@ def parse_atom_array( return data_dict -def _parse_from_cif(filename: os.PathLike | io.StringIO | io.BytesIO, **kwargs) -> dict[str, Any]: +def _parse_from_cif( + filename: os.PathLike | io.StringIO | io.BytesIO, file_type: str | None = None, **kwargs +) -> dict[str, Any]: """Parse the CIF file. Return chain information, residue information, atom array, and metadata. @@ -696,7 +699,7 @@ def _parse_from_cif(filename: os.PathLike | io.StringIO | io.BytesIO, **kwargs) data_dict = {"extra_info": {}} # ... read the CIF file into the dictionary (we will clean up the dictionary before returning) - cif_file = read_any(filename) + cif_file = read_any(filename, file_type=file_type) data_dict["cif_block"] = cif_file.block # ... load metadata into "metadata" key (either from RCSB standard fields, or from the custom `extra_metadata` field) diff --git a/src/atomworks/io/utils/io_utils.py b/src/atomworks/io/utils/io_utils.py index 3817f2a0..5d160f17 100644 --- a/src/atomworks/io/utils/io_utils.py +++ b/src/atomworks/io/utils/io_utils.py @@ -15,6 +15,7 @@ import gzip import io +import json import logging import os import re @@ -44,7 +45,7 @@ logger = logging.getLogger("atomworks.io") -CIF_LIKE_EXTENSIONS = {".cif", ".pdb", ".bcif", ".cif.gz", ".pdb.gz", ".bcif.gz"} +CIF_LIKE_EXTENSIONS = {".cif", ".pdb", ".bcif", ".cif.gz", ".pdb.gz", ".bcif.gz", ".json", ".json.gz"} @contextmanager @@ -86,7 +87,7 @@ def _get_logged_in_user() -> str: def load_any( file_or_buffer: os.PathLike | io.StringIO | io.BytesIO, - file_type: Literal["cif", "mmcif", "pdbx", "pdb", "pdb1", "bcif"] | None = None, + file_type: Literal["cif", "mmcif", "pdbx", "pdb", "pdb1", "bcif", "mmjson"] | None = None, *, extra_fields: list[str] | Literal["all"] = [], include_bonds: bool = True, @@ -320,7 +321,9 @@ def get_structure( return atom_array_stack -def infer_pdb_file_type(path_or_buffer: os.PathLike | io.StringIO | io.BytesIO) -> Literal["cif", "pdb", "bcif", "sdf"]: +def infer_pdb_file_type( + path_or_buffer: os.PathLike | io.StringIO | io.BytesIO, +) -> Literal["cif", "pdb", "bcif", "sdf", "mmjson"]: """ Infer the file type of a PDB file or buffer. """ @@ -337,7 +340,16 @@ def infer_pdb_file_type(path_or_buffer: os.PathLike | io.StringIO | io.BytesIO) path_or_buffer.readline() # Skip the first line second_line = path_or_buffer.readline().strip() path_or_buffer.seek(0) - return "cif" if second_line.startswith("#") else "pdb" + path_or_buffer.seek(0) + if second_line.startswith("#"): + return "cif" + # Check for JSON start + path_or_buffer.seek(0) + first_char = path_or_buffer.read(1) + path_or_buffer.seek(0) + if first_char == "{": + return "mmjson" + return "pdb" elif isinstance(path_or_buffer, Path): if path_or_buffer.suffix in (".gz", ".gzip"): inferred_file_type = Path(path_or_buffer.stem).suffix.lstrip(".") @@ -353,13 +365,32 @@ def infer_pdb_file_type(path_or_buffer: os.PathLike | io.StringIO | io.BytesIO) return "bcif" elif inferred_file_type == "sdf": return "sdf" + elif inferred_file_type == "json": + return "mmjson" else: raise ValueError(f"Unsupported file type: {inferred_file_type}") +def _read_mmjson(file_obj: io.StringIO | io.BytesIO | io.TextIOWrapper) -> pdbx.CIFFile: + """Read an mmjson file into a CIFFile object.""" + data = json.load(file_obj) + cif_file = pdbx.CIFFile() + for block_name, block_data in data.items(): + cif_block = pdbx.CIFBlock() + for cat_name, cat_data in block_data.items(): + cif_category = pdbx.CIFCategory() + for col_name, col_data in cat_data.items(): + # Convert None to "?" and ensure all elements are strings + processed_data = [str(x) if x is not None else "?" for x in col_data] + cif_category[col_name] = pdbx.CIFColumn(processed_data) + cif_block[cat_name] = cif_category + cif_file[block_name] = cif_block + return cif_file + + def read_any( path_or_buffer: os.PathLike | io.StringIO | io.BytesIO, - file_type: Literal["cif", "pdb", "bcif", "sdf"] | None = None, + file_type: Literal["cif", "pdb", "bcif", "sdf", "mmjson"] | None = None, ) -> pdbx.CIFFile | biotite_pdb.PDBFile | pdbx.BinaryCIFFile: """ Reads any of the allowed file types into the appropriate Biotite file object. @@ -367,7 +398,7 @@ def read_any( Args: path_or_buffer (PathLike | io.StringIO | io.BytesIO): The path to the file or a buffer to read from. If a buffer, it's highly recommended to specify the file_type. - file_type (Literal["cif", "pdb", "bcif"], optional): Type of the file. + file_type (Literal["cif", "pdb", "bcif", "mmjson"], optional): Type of the file. If None, it will be inferred from the file extension. When using a buffer, the file type must be specified. Returns: @@ -379,7 +410,8 @@ def read_any( # Determine file type if file_type is None: file_type = infer_pdb_file_type(path_or_buffer) - open_mode = "rb" if file_type == "bcif" else "rt" + + open_mode = "rb" if file_type == "bcif" else "rt" # Convert string paths to Path objects and decompress if necessary if isinstance(path_or_buffer, str | Path): @@ -398,6 +430,13 @@ def read_any( file_cls = pdbx.BinaryCIFFile elif file_type == "sdf": file_cls = mol.SDFile + elif file_type == "mmjson": + # Special handling for mmjson + if isinstance(path_or_buffer, io.StringIO | io.BytesIO): + return _read_mmjson(path_or_buffer) + else: + with open(path_or_buffer, "r") as f: + return _read_mmjson(f) else: raise ValueError(f"Unsupported file type: {file_type}") diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..b285e636 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2896 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version < '3.12'", +] + +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, +] + +[[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, upload-time = "2024-02-06T09:43:11.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, +] + +[[package]] +name = "ase" +version = "3.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib" }, + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/33/2ffa44950267450f6a5cdb711c68e12d0d72d626e246e5897e3bada7bac6/ase-3.26.0.tar.gz", hash = "sha256:a071a355775b0a8062d23e9266e9d811b19d9f6d9ec5215e8032f7d93dc65075", size = 2405567, upload-time = "2025-08-12T13:06:55.589Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/f0/6e52d797bee63530f4b778cb4cbb3a01970f104197c364a8ff51bc9f5a21/ase-3.26.0-py3-none-any.whl", hash = "sha256:77fd0e609bd3868006d4bb3bb95cdc4081d9e292ac84f6c9fb564b5751d2689e", size = 2946787, upload-time = "2025-08-12T13:06:53.316Z" }, +] + +[[package]] +name = "ase-db-backends" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ase" }, + { name = "cryptography" }, + { name = "lmdb" }, + { name = "numpy" }, + { name = "psycopg2-binary" }, + { name = "pymysql" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d5/c448e9c4470e4b8612154e13cd5369c8b8792a1bdf901a32a35e79408d20/ase_db_backends-0.11.0.tar.gz", hash = "sha256:8575938eaf7708a52eb951c6f955f39082fa79c8332f4568715dacb8e733717a", size = 35605, upload-time = "2025-11-12T08:02:50.328Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/24/35e57bdbd6d1c37ae889b669c4bf06b159fa275afe189a81460d392d187e/ase_db_backends-0.11.0-py3-none-any.whl", hash = "sha256:dd5959b9a3cbe3deb5726724afa0045d7d009e04e08be5f4b7ffae703a563a99", size = 44738, upload-time = "2025-11-12T08:02:49.215Z" }, +] + +[[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, upload-time = "2025-11-15T16:43:48.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, +] + +[[package]] +name = "atomworks" +version = "2.1.2" +source = { editable = "." } +dependencies = [ + { name = "biotite" }, + { name = "cython" }, + { name = "cytoolz" }, + { name = "hydride" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "py3dmol" }, + { name = "pyarrow" }, + { name = "pymol-remote" }, + { name = "rdkit" }, + { name = "scipy" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "zstandard" }, +] + +[package.optional-dependencies] +ase = [ + { name = "ase" }, + { name = "ase-db-backends" }, + { name = "lmdb" }, +] +dev = [ + { name = "ipykernel" }, + { name = "pytest" }, + { name = "pytest-benchmark" }, + { name = "pytest-cov" }, + { name = "pytest-dotenv" }, + { name = "pytest-testmon" }, + { name = "pytest-xdist" }, + { name = "ruff" }, +] +docs = [ + { name = "matplotlib" }, + { name = "pydata-sphinx-theme" }, + { name = "sphinx" }, + { name = "sphinx-gallery" }, +] +ml = [ + { name = "beartype" }, + { name = "einops" }, + { name = "jaxtyping" }, + { name = "torch" }, +] +openbabel = [ + { name = "openbabel-wheel" }, +] + +[package.dev-dependencies] +dev = [ + { name = "atomworks", extra = ["dev"] }, +] +docs = [ + { name = "atomworks", extra = ["docs"] }, +] +ml = [ + { name = "atomworks", extra = ["ml"] }, +] +openbabel = [ + { name = "atomworks", extra = ["openbabel"] }, +] + +[package.metadata] +requires-dist = [ + { name = "ase", marker = "extra == 'ase'", specifier = ">=3.22.0,<4" }, + { name = "ase-db-backends", marker = "extra == 'ase'", specifier = ">=0.10.0,<1" }, + { name = "beartype", marker = "extra == 'ml'", specifier = ">=0.18.0,<1" }, + { name = "biotite", specifier = "==1.4.0" }, + { name = "cython", specifier = ">=3.0.0,<4" }, + { name = "cytoolz", specifier = ">=0.12.3,<1" }, + { name = "einops", marker = "extra == 'ml'", specifier = ">=0.7.0,<1" }, + { name = "hydride", specifier = ">=1.2.3,<2" }, + { name = "ipykernel", marker = "extra == 'dev'", specifier = ">=6.28.0" }, + { name = "jaxtyping", marker = "extra == 'ml'", specifier = ">=0.2.17,<1" }, + { name = "lmdb", marker = "extra == 'ase'", specifier = ">=1.5.0,<2" }, + { name = "matplotlib", marker = "extra == 'docs'", specifier = ">=3.10.0,<4" }, + { name = "numpy", specifier = ">=1.25.0,<3" }, + { name = "openbabel-wheel", marker = "extra == 'openbabel'", specifier = "==3.1.1.22" }, + { name = "pandas", specifier = ">=2.2,<2.4" }, + { name = "py3dmol", specifier = ">=2.2.1,<3" }, + { name = "pyarrow", specifier = "==17.0.0" }, + { name = "pydata-sphinx-theme", marker = "extra == 'docs'", specifier = ">=0.16.1,<1" }, + { name = "pymol-remote", specifier = ">=0.0.5" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.2.0,<9" }, + { name = "pytest-benchmark", marker = "extra == 'dev'", specifier = ">=5.0.0,<6" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.1.0,<5" }, + { name = "pytest-dotenv", marker = "extra == 'dev'", specifier = ">=0.5.2,<1" }, + { name = "pytest-testmon", marker = "extra == 'dev'", specifier = ">=2.1.1,<3" }, + { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.6.1,<4" }, + { name = "rdkit", specifier = ">=2024.3.5,<2025.9" }, + { name = "ruff", marker = "extra == 'dev'", specifier = "==0.8.3" }, + { name = "scipy", specifier = ">=1.13.1,<2" }, + { name = "sphinx", marker = "extra == 'docs'", specifier = ">=8.0.0,<9" }, + { name = "sphinx-gallery", marker = "extra == 'docs'", specifier = ">=0.19.0,<1" }, + { name = "torch", marker = "extra == 'ml'", specifier = ">=2.2.0,<2.8" }, + { name = "tqdm", specifier = ">=4.65.0,<5" }, + { name = "typer", specifier = ">=0.12.5,<1" }, + { name = "zstandard", specifier = ">=0.21.0,<1" }, +] +provides-extras = ["ml", "ase", "openbabel", "dev", "docs"] + +[package.metadata.requires-dev] +dev = [{ name = "atomworks", extras = ["dev"] }] +docs = [{ name = "atomworks", extras = ["docs"] }] +ml = [{ name = "atomworks", extras = ["ml"] }] +openbabel = [{ name = "atomworks", extras = ["openbabel"] }] + +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, +] + +[[package]] +name = "beartype" +version = "0.22.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/1d/794ae2acaa67c8b216d91d5919da2606c2bb14086849ffde7f5555f3a3a5/beartype-0.22.8.tar.gz", hash = "sha256:b19b21c9359722ee3f7cc433f063b3e13997b27ae8226551ea5062e621f61165", size = 1602262, upload-time = "2025-12-03T05:11:10.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2a/fbcbf5a025d3e71ddafad7efd43e34ec4362f4d523c3c471b457148fb211/beartype-0.22.8-py3-none-any.whl", hash = "sha256:b832882d04e41a4097bab9f63e6992bc6de58c414ee84cba9b45b67314f5ab2e", size = 1331895, upload-time = "2025-12-03T05:11:08.373Z" }, +] + +[[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, upload-time = "2025-11-30T15:08:26.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, +] + +[[package]] +name = "biotite" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "biotraj" }, + { name = "msgpack" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/64/3526f99fe09add35decea977bd3049672fc0be689d7e0557b0564a55600e/biotite-1.4.0.tar.gz", hash = "sha256:0428427fff47e046a36ecdda1cbb38fc61e652e8df4339bf0a0b7a248a051a8b", size = 37035933, upload-time = "2025-07-07T12:08:53.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/9b/b1015d8a6c4fe2c13dd586f7b692264a902cbe53b61cb53a44802e94c851/biotite-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d937447eec6247b439d887a79e0dd94e5156a037fa5b399520ac8bee8b078103", size = 40205001, upload-time = "2025-07-07T12:08:15.177Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a8/8395bbe28f3286df2386ce0830bb168c9f7b0c4f6c6b3f994fd117485819/biotite-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a97562fd0341591f6eba58c001cec86cc6de2a45aa1e8d4349b4ff7d7b2cbe3a", size = 39991959, upload-time = "2025-07-07T12:08:18.461Z" }, + { url = "https://files.pythonhosted.org/packages/07/91/5ac386b325dc638eec21a68ef76a7ed6bb3a1fde0dbf8c7783a9545b7f21/biotite-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0813b424796dcc11bd2093a5e976c034c7190f3b2bedc503fb556119375977b1", size = 54434605, upload-time = "2025-07-07T12:08:22.278Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5d/34df5d5acb35f8d4b6bb8df4f73f50ec2a9aa2e419cdb5ab3e5c24012cd7/biotite-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cae4560fefd5583976d6434f647b73fe302864a1a7891e35cad4477309f58cce", size = 39884893, upload-time = "2025-07-07T12:08:25.461Z" }, + { url = "https://files.pythonhosted.org/packages/d2/a5/67c8808fe0935cfdf0f8bd993735595ed5110a6dbee98f84581b81066258/biotite-1.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:145f229f4262ab352eb5869f2ea56a5823911267abe7edca50ec6e5c90837097", size = 40144461, upload-time = "2025-07-07T12:08:28.358Z" }, + { url = "https://files.pythonhosted.org/packages/21/e0/64716fb2ce9d7749bb41cc932c667b0f6d478e09367b36d273b1f77b06f3/biotite-1.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:19b4cfbdbe1ad94319dfea61d3dcdb07d476ba5bf55fb507021d6a5a5d4762d8", size = 39924549, upload-time = "2025-07-07T12:08:31.139Z" }, + { url = "https://files.pythonhosted.org/packages/77/e4/eb18efca3bf159164144238ebfde8c064cfb122194183507b5dfcd690969/biotite-1.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d17dbcabf8dfce25fff50f2c31e03392f8bd66dce064379e5f4c03d28ad66fc6", size = 56284190, upload-time = "2025-07-07T12:08:34.406Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/c1f1ea1c4c407b24c1dd9a92b02c6babaa1800152693ae662c471daf6f95/biotite-1.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:3dcb2c88f5dcfce6fee94800be1a42aca82c468baea13f04701ebefd711d9438", size = 39803852, upload-time = "2025-07-07T12:08:37.68Z" }, + { url = "https://files.pythonhosted.org/packages/a1/38/7b6f69b3b5e6e3dbc0aabdd76c6f071a9e763d606f7b9a489cb95b92a000/biotite-1.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a2b85d704c7f24bd03a2023d122776443588c97cfcc2875eed9acb4e29ce36a5", size = 40130802, upload-time = "2025-07-07T12:08:40.942Z" }, + { url = "https://files.pythonhosted.org/packages/0d/5d/087d2bd4db67bebdc6d7500be671cf8dd7471d6b887456ecd5c47561986f/biotite-1.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e681619cc9712cee436950a66965791fd40548d0369ddc8dba2c52a4f1d26a95", size = 39912406, upload-time = "2025-07-07T12:08:43.839Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/aea1d77a3197d8f7caac0ffb19a6abdb3138ba69d90c8f74ef5a996d13a8/biotite-1.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96644d9bcf8b14f3ce7758c855f3773ddd5d95c06cba178847911d871b81b7d2", size = 56171242, upload-time = "2025-07-07T12:08:47.089Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b6/f81ab2e7b0ef3bb3dccd147cff8458e16ec36bf7b08901772075e872ce66/biotite-1.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:c9c214f56a4868f840dcbbac9ad75f507b9a87c978c68c321dda745cffecba4c", size = 39807120, upload-time = "2025-07-07T12:08:50.633Z" }, +] + +[[package]] +name = "biotraj" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/21/2287edfd0d2569639eea706e25c39e63b46a384cf1712db8ea05768317b0/biotraj-1.2.2.tar.gz", hash = "sha256:4bcba92101ed50f369cc1487fb5dfcfe1d8402ad47adaa9232b080553271663a", size = 3909030, upload-time = "2024-11-02T11:30:54.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/dd/4e257a394e4a686a5973d6238bc5fb6fa321423c9401e278a34c51a01425/biotraj-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8dc790c95f90760d08986c896783f3531cfd5feb3bd8496f07949ccccd8eafb3", size = 863170, upload-time = "2024-11-02T11:30:34.007Z" }, + { url = "https://files.pythonhosted.org/packages/a0/3e/90d2c50912df949c5731c564f5c7bf853378d7f2d31f276dd31eb42fb663/biotraj-1.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:39d1ce8d7c7e55c87bf35248c20f4d7ed09349b99ee090e61068c9c08d32b179", size = 835504, upload-time = "2024-11-02T11:30:35.878Z" }, + { url = "https://files.pythonhosted.org/packages/b5/86/d24589c5f8f6ef4685e6a8c8a670a9be17657677f793b48e19520ed08209/biotraj-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0accd626b3cb6b29fb4491d593c41daa694edddde8e8dc113228b1969a30c9f6", size = 2246778, upload-time = "2024-11-02T11:30:37.642Z" }, + { url = "https://files.pythonhosted.org/packages/3a/78/3cd3ca90490ff5730fffed57464c104a146a0c35280fc4bea2bfafb72b48/biotraj-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8fb09bf6f7cd44c9356880166e45fe1606b05113b4642b99f8b85c25f51699ba", size = 366212, upload-time = "2024-11-02T11:30:39.427Z" }, + { url = "https://files.pythonhosted.org/packages/e2/da/bf56c6cc27212ed2b5ad3beb1c399b74ac147236b22900a9434760ebfa27/biotraj-1.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b584c2da6d353c09f839e9b72fa243b6f45050b311cdcd5a0f3a44ced80d714e", size = 859982, upload-time = "2024-11-02T11:30:40.948Z" }, + { url = "https://files.pythonhosted.org/packages/c4/d2/369ed44ad23f8c0464f7b80d41143d717896097b39fe3dd3e07e6d162fef/biotraj-1.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7bab65f5e3975a844c1018ea5873acd7dd21a64e8ebf0c145635c1d2fb9ef9bd", size = 833765, upload-time = "2024-11-02T11:30:42.628Z" }, + { url = "https://files.pythonhosted.org/packages/80/cd/c607b6337ddcf55cc0249527819b727ef28481d7c56ace54cca69400c2b9/biotraj-1.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b449930fa70666db0f2e7b1e5f5dad65917086adc66a70f26db38d79b0171815", size = 2239973, upload-time = "2024-11-02T11:30:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/13/56/bed88eb34acb31855e7c82a1d68e58775c037ec66ccb2bb02ff310615240/biotraj-1.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:3427567cc0bd0e981bf7de1a6b65baf82984171852994d304b2f316a8926db83", size = 358790, upload-time = "2024-11-02T11:30:46.19Z" }, + { url = "https://files.pythonhosted.org/packages/1f/12/8f6a2b21a8b43a2bf85352c993afecb21d40eb3d7373b6242163a93f57e0/biotraj-1.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:31ed2a9e8a6436f5432f22883e68a36c223b98de0ab80225efbaf67da339a2b2", size = 856347, upload-time = "2024-11-02T11:30:47.431Z" }, + { url = "https://files.pythonhosted.org/packages/f6/4d/b1e792c01e61bbfe03b290a0805f0c7bc3949bf9cd4031bcdd183d2f2524/biotraj-1.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6a8c84ac95bf65b73928774ec46b72d62b0f30fa12eb8c56c78ed25235f0acf8", size = 832499, upload-time = "2024-11-02T11:30:49.363Z" }, + { url = "https://files.pythonhosted.org/packages/f0/6f/ab71525583a7824c70f71de387a1c5ceb27ddcb3fda2dacb734e5b875f14/biotraj-1.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dcfa4a4c755ddc206f81999fd47664747cd2e546e16a51d885332cd4c955f41", size = 2246545, upload-time = "2024-11-02T11:30:50.829Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9a/46d2d67b5b672d5d2ffbfb3551fc4b499b45d5edce2558e259f69b72a0d9/biotraj-1.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:e0ed1b586e23ad53e53fb42be8541fb964ec6c4183e6d500fef0bcc1bdcd7487", size = 359596, upload-time = "2024-11-02T11:30:52.876Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[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, upload-time = "2025-09-08T23:24:04.541Z" } +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, upload-time = "2025-09-08T23:22:26.456Z" }, + { 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, upload-time = "2025-09-08T23:22:28.197Z" }, + { 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, upload-time = "2025-09-08T23:22:29.475Z" }, + { 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, upload-time = "2025-09-08T23:22:31.063Z" }, + { 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, upload-time = "2025-09-08T23:22:32.507Z" }, + { 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, upload-time = "2025-09-08T23:22:34.132Z" }, + { 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, upload-time = "2025-09-08T23:22:35.443Z" }, + { 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, upload-time = "2025-09-08T23:22:36.805Z" }, + { 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, upload-time = "2025-09-08T23:22:38.436Z" }, + { 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, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { 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, upload-time = "2025-09-08T23:22:44.795Z" }, + { 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, upload-time = "2025-09-08T23:22:45.938Z" }, + { 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, upload-time = "2025-09-08T23:22:47.349Z" }, + { 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, upload-time = "2025-09-08T23:22:48.677Z" }, + { 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, upload-time = "2025-09-08T23:22:50.06Z" }, + { 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, upload-time = "2025-09-08T23:22:51.364Z" }, + { 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, upload-time = "2025-09-08T23:22:52.902Z" }, + { 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, upload-time = "2025-09-08T23:22:54.518Z" }, + { 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, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { 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, upload-time = "2025-09-08T23:23:00.879Z" }, + { 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, upload-time = "2025-09-08T23:23:02.231Z" }, + { 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, upload-time = "2025-09-08T23:23:03.472Z" }, + { 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, upload-time = "2025-09-08T23:23:04.792Z" }, + { 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, upload-time = "2025-09-08T23:23:06.127Z" }, + { 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, upload-time = "2025-09-08T23:23:07.753Z" }, + { 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, upload-time = "2025-09-08T23:23:09.648Z" }, + { 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, upload-time = "2025-09-08T23:23:10.928Z" }, + { 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, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { 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, upload-time = "2025-09-08T23:23:18.087Z" }, + { 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, upload-time = "2025-09-08T23:23:19.622Z" }, + { 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, upload-time = "2025-09-08T23:23:20.853Z" }, + { 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, upload-time = "2025-09-08T23:23:22.08Z" }, + { 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, upload-time = "2025-09-08T23:23:23.314Z" }, + { 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, upload-time = "2025-09-08T23:23:24.541Z" }, + { 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, upload-time = "2025-09-08T23:23:26.143Z" }, + { 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, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { 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, upload-time = "2025-09-08T23:23:29.347Z" }, + { 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, upload-time = "2025-09-08T23:23:30.63Z" }, + { 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, upload-time = "2025-09-08T23:23:31.91Z" }, + { 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, upload-time = "2025-09-08T23:23:33.214Z" }, + { 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, upload-time = "2025-09-08T23:23:34.495Z" }, + { 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, upload-time = "2025-09-08T23:23:36.096Z" }, + { 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, upload-time = "2025-09-08T23:23:37.328Z" }, + { 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, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[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, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "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, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + +[[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, upload-time = "2025-07-26T12:03:12.549Z" } +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, upload-time = "2025-07-26T12:01:02.277Z" }, + { 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, upload-time = "2025-07-26T12:01:04.072Z" }, + { 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, upload-time = "2025-07-26T12:01:05.688Z" }, + { 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, upload-time = "2025-07-26T12:01:07.054Z" }, + { 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, upload-time = "2025-07-26T12:01:08.801Z" }, + { 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, upload-time = "2025-07-26T12:01:10.319Z" }, + { 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, upload-time = "2025-07-26T12:01:12.659Z" }, + { 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, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { 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, upload-time = "2025-07-26T12:01:21.16Z" }, + { 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, upload-time = "2025-07-26T12:01:22.448Z" }, + { 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, upload-time = "2025-07-26T12:01:24.155Z" }, + { 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, upload-time = "2025-07-26T12:01:25.91Z" }, + { 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, upload-time = "2025-07-26T12:01:27.152Z" }, + { 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, upload-time = "2025-07-26T12:01:28.808Z" }, + { 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, upload-time = "2025-07-26T12:01:31.198Z" }, + { 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, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { 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, upload-time = "2025-07-26T12:01:39.367Z" }, + { 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, upload-time = "2025-07-26T12:01:40.645Z" }, + { 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, upload-time = "2025-07-26T12:01:41.942Z" }, + { 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, upload-time = "2025-07-26T12:01:43.499Z" }, + { 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, upload-time = "2025-07-26T12:01:45.219Z" }, + { 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, upload-time = "2025-07-26T12:01:46.519Z" }, + { 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, upload-time = "2025-07-26T12:01:48.964Z" }, + { 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, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { 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, upload-time = "2025-07-26T12:01:57.051Z" }, + { 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, upload-time = "2025-07-26T12:01:58.663Z" }, + { 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, upload-time = "2025-07-26T12:02:00.343Z" }, + { 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, upload-time = "2025-07-26T12:02:02.128Z" }, + { 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, upload-time = "2025-07-26T12:02:03.615Z" }, + { 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, upload-time = "2025-07-26T12:02:05.165Z" }, + { 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, upload-time = "2025-07-26T12:02:07.379Z" }, + { 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, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { 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, upload-time = "2025-07-26T12:02:16.095Z" }, + { 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, upload-time = "2025-07-26T12:02:17.524Z" }, + { 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, upload-time = "2025-07-26T12:02:18.9Z" }, + { 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, upload-time = "2025-07-26T12:02:20.418Z" }, + { 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, upload-time = "2025-07-26T12:02:21.916Z" }, + { 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, upload-time = "2025-07-26T12:02:23.759Z" }, + { 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, upload-time = "2025-07-26T12:02:26.181Z" }, + { 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, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { 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, upload-time = "2025-07-26T12:02:34.2Z" }, + { 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, upload-time = "2025-07-26T12:02:35.807Z" }, + { 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, upload-time = "2025-07-26T12:02:37.193Z" }, + { 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, upload-time = "2025-07-26T12:02:38.894Z" }, + { 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, upload-time = "2025-07-26T12:02:40.642Z" }, + { 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, upload-time = "2025-07-26T12:02:42.25Z" }, + { 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, upload-time = "2025-07-26T12:02:44.668Z" }, + { 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, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, + { 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, upload-time = "2025-07-26T12:02:52.74Z" }, + { 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, upload-time = "2025-07-26T12:02:54.037Z" }, + { 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, upload-time = "2025-07-26T12:02:55.947Z" }, + { 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, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, +] + +[[package]] +name = "coverage" +version = "7.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/45/2c665ca77ec32ad67e25c77daf1cee28ee4558f3bc571cdbaf88a00b9f23/coverage-7.13.0.tar.gz", hash = "sha256:a394aa27f2d7ff9bc04cf703817773a59ad6dfbd577032e690f961d2460ee936", size = 820905, upload-time = "2025-12-08T13:14:38.055Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/dc/888bf90d8b1c3d0b4020a40e52b9f80957d75785931ec66c7dfaccc11c7d/coverage-7.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0dfa3855031070058add1a59fdfda0192fd3e8f97e7c81de0596c145dea51820", size = 218104, upload-time = "2025-12-08T13:12:33.333Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ea/069d51372ad9c380214e86717e40d1a743713a2af191cfba30a0911b0a4a/coverage-7.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fdb6f54f38e334db97f72fa0c701e66d8479af0bc3f9bfb5b90f1c30f54500f", size = 218606, upload-time = "2025-12-08T13:12:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/68/09/77b1c3a66c2aa91141b6c4471af98e5b1ed9b9e6d17255da5eb7992299e3/coverage-7.13.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7e442c013447d1d8d195be62852270b78b6e255b79b8675bad8479641e21fd96", size = 248999, upload-time = "2025-12-08T13:12:36.02Z" }, + { url = "https://files.pythonhosted.org/packages/0a/32/2e2f96e9d5691eaf1181d9040f850b8b7ce165ea10810fd8e2afa534cef7/coverage-7.13.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ed5630d946859de835a85e9a43b721123a8a44ec26e2830b296d478c7fd4259", size = 250925, upload-time = "2025-12-08T13:12:37.221Z" }, + { url = "https://files.pythonhosted.org/packages/7b/45/b88ddac1d7978859b9a39a8a50ab323186148f1d64bc068f86fc77706321/coverage-7.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f15a931a668e58087bc39d05d2b4bf4b14ff2875b49c994bbdb1c2217a8daeb", size = 253032, upload-time = "2025-12-08T13:12:38.763Z" }, + { url = "https://files.pythonhosted.org/packages/71/cb/e15513f94c69d4820a34b6bf3d2b1f9f8755fa6021be97c7065442d7d653/coverage-7.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:30a3a201a127ea57f7e14ba43c93c9c4be8b7d17a26e03bb49e6966d019eede9", size = 249134, upload-time = "2025-12-08T13:12:40.382Z" }, + { url = "https://files.pythonhosted.org/packages/09/61/d960ff7dc9e902af3310ce632a875aaa7860f36d2bc8fc8b37ee7c1b82a5/coverage-7.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a485ff48fbd231efa32d58f479befce52dcb6bfb2a88bb7bf9a0b89b1bc8030", size = 250731, upload-time = "2025-12-08T13:12:41.992Z" }, + { url = "https://files.pythonhosted.org/packages/98/34/c7c72821794afc7c7c2da1db8f00c2c98353078aa7fb6b5ff36aac834b52/coverage-7.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22486cdafba4f9e471c816a2a5745337742a617fef68e890d8baf9f3036d7833", size = 248795, upload-time = "2025-12-08T13:12:43.331Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5b/e0f07107987a43b2def9aa041c614ddb38064cbf294a71ef8c67d43a0cdd/coverage-7.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:263c3dbccc78e2e331e59e90115941b5f53e85cfcc6b3b2fbff1fd4e3d2c6ea8", size = 248514, upload-time = "2025-12-08T13:12:44.546Z" }, + { url = "https://files.pythonhosted.org/packages/71/c2/c949c5d3b5e9fc6dd79e1b73cdb86a59ef14f3709b1d72bf7668ae12e000/coverage-7.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5330fa0cc1f5c3c4c3bb8e101b742025933e7848989370a1d4c8c5e401ea753", size = 249424, upload-time = "2025-12-08T13:12:45.759Z" }, + { url = "https://files.pythonhosted.org/packages/11/f1/bbc009abd6537cec0dffb2cc08c17a7f03de74c970e6302db4342a6e05af/coverage-7.13.0-cp311-cp311-win32.whl", hash = "sha256:0f4872f5d6c54419c94c25dd6ae1d015deeb337d06e448cd890a1e89a8ee7f3b", size = 220597, upload-time = "2025-12-08T13:12:47.378Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/d9977f2fb51c10fbaed0718ce3d0a8541185290b981f73b1d27276c12d91/coverage-7.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51a202e0f80f241ccb68e3e26e19ab5b3bf0f813314f2c967642f13ebcf1ddfe", size = 221536, upload-time = "2025-12-08T13:12:48.7Z" }, + { url = "https://files.pythonhosted.org/packages/be/ad/3fcf43fd96fb43e337a3073dea63ff148dcc5c41ba7a14d4c7d34efb2216/coverage-7.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:d2a9d7f1c11487b1c69367ab3ac2d81b9b3721f097aa409a3191c3e90f8f3dd7", size = 220206, upload-time = "2025-12-08T13:12:50.365Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f1/2619559f17f31ba00fc40908efd1fbf1d0a5536eb75dc8341e7d660a08de/coverage-7.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0b3d67d31383c4c68e19a88e28fc4c2e29517580f1b0ebec4a069d502ce1e0bf", size = 218274, upload-time = "2025-12-08T13:12:52.095Z" }, + { url = "https://files.pythonhosted.org/packages/2b/11/30d71ae5d6e949ff93b2a79a2c1b4822e00423116c5c6edfaeef37301396/coverage-7.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:581f086833d24a22c89ae0fe2142cfaa1c92c930adf637ddf122d55083fb5a0f", size = 218638, upload-time = "2025-12-08T13:12:53.418Z" }, + { url = "https://files.pythonhosted.org/packages/79/c2/fce80fc6ded8d77e53207489d6065d0fed75db8951457f9213776615e0f5/coverage-7.13.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0a3a30f0e257df382f5f9534d4ce3d4cf06eafaf5192beb1a7bd066cb10e78fb", size = 250129, upload-time = "2025-12-08T13:12:54.744Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b6/51b5d1eb6fcbb9a1d5d6984e26cbe09018475c2922d554fd724dd0f056ee/coverage-7.13.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:583221913fbc8f53b88c42e8dbb8fca1d0f2e597cb190ce45916662b8b9d9621", size = 252885, upload-time = "2025-12-08T13:12:56.401Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/972a5affea41de798691ab15d023d3530f9f56a72e12e243f35031846ff7/coverage-7.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f5d9bd30756fff3e7216491a0d6d520c448d5124d3d8e8f56446d6412499e74", size = 253974, upload-time = "2025-12-08T13:12:57.718Z" }, + { url = "https://files.pythonhosted.org/packages/8a/56/116513aee860b2c7968aa3506b0f59b22a959261d1dbf3aea7b4450a7520/coverage-7.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a23e5a1f8b982d56fa64f8e442e037f6ce29322f1f9e6c2344cd9e9f4407ee57", size = 250538, upload-time = "2025-12-08T13:12:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/d6/75/074476d64248fbadf16dfafbf93fdcede389ec821f74ca858d7c87d2a98c/coverage-7.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b01c22bc74a7fb44066aaf765224c0d933ddf1f5047d6cdfe4795504a4493f8", size = 251912, upload-time = "2025-12-08T13:13:00.604Z" }, + { url = "https://files.pythonhosted.org/packages/f2/d2/aa4f8acd1f7c06024705c12609d8698c51b27e4d635d717cd1934c9668e2/coverage-7.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:898cce66d0836973f48dda4e3514d863d70142bdf6dfab932b9b6a90ea5b222d", size = 250054, upload-time = "2025-12-08T13:13:01.892Z" }, + { url = "https://files.pythonhosted.org/packages/19/98/8df9e1af6a493b03694a1e8070e024e7d2cdc77adedc225a35e616d505de/coverage-7.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:3ab483ea0e251b5790c2aac03acde31bff0c736bf8a86829b89382b407cd1c3b", size = 249619, upload-time = "2025-12-08T13:13:03.236Z" }, + { url = "https://files.pythonhosted.org/packages/d8/71/f8679231f3353018ca66ef647fa6fe7b77e6bff7845be54ab84f86233363/coverage-7.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d84e91521c5e4cb6602fe11ece3e1de03b2760e14ae4fcf1a4b56fa3c801fcd", size = 251496, upload-time = "2025-12-08T13:13:04.511Z" }, + { url = "https://files.pythonhosted.org/packages/04/86/9cb406388034eaf3c606c22094edbbb82eea1fa9d20c0e9efadff20d0733/coverage-7.13.0-cp312-cp312-win32.whl", hash = "sha256:193c3887285eec1dbdb3f2bd7fbc351d570ca9c02ca756c3afbc71b3c98af6ef", size = 220808, upload-time = "2025-12-08T13:13:06.422Z" }, + { url = "https://files.pythonhosted.org/packages/1c/59/af483673df6455795daf5f447c2f81a3d2fcfc893a22b8ace983791f6f34/coverage-7.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:4f3e223b2b2db5e0db0c2b97286aba0036ca000f06aca9b12112eaa9af3d92ae", size = 221616, upload-time = "2025-12-08T13:13:07.95Z" }, + { url = "https://files.pythonhosted.org/packages/64/b0/959d582572b30a6830398c60dd419c1965ca4b5fb38ac6b7093a0d50ca8d/coverage-7.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:086cede306d96202e15a4b77ace8472e39d9f4e5f9fd92dd4fecdfb2313b2080", size = 220261, upload-time = "2025-12-08T13:13:09.581Z" }, + { url = "https://files.pythonhosted.org/packages/7c/cc/bce226595eb3bf7d13ccffe154c3c487a22222d87ff018525ab4dd2e9542/coverage-7.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:28ee1c96109974af104028a8ef57cec21447d42d0e937c0275329272e370ebcf", size = 218297, upload-time = "2025-12-08T13:13:10.977Z" }, + { url = "https://files.pythonhosted.org/packages/3b/9f/73c4d34600aae03447dff3d7ad1d0ac649856bfb87d1ca7d681cfc913f9e/coverage-7.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d1e97353dcc5587b85986cda4ff3ec98081d7e84dd95e8b2a6d59820f0545f8a", size = 218673, upload-time = "2025-12-08T13:13:12.562Z" }, + { url = "https://files.pythonhosted.org/packages/63/ab/8fa097db361a1e8586535ae5073559e6229596b3489ec3ef2f5b38df8cb2/coverage-7.13.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:99acd4dfdfeb58e1937629eb1ab6ab0899b131f183ee5f23e0b5da5cba2fec74", size = 249652, upload-time = "2025-12-08T13:13:13.909Z" }, + { url = "https://files.pythonhosted.org/packages/90/3a/9bfd4de2ff191feb37ef9465855ca56a6f2f30a3bca172e474130731ac3d/coverage-7.13.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff45e0cd8451e293b63ced93161e189780baf444119391b3e7d25315060368a6", size = 252251, upload-time = "2025-12-08T13:13:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/df/61/b5d8105f016e1b5874af0d7c67542da780ccd4a5f2244a433d3e20ceb1ad/coverage-7.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4f72a85316d8e13234cafe0a9f81b40418ad7a082792fa4165bd7d45d96066b", size = 253492, upload-time = "2025-12-08T13:13:16.849Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b8/0fad449981803cc47a4694768b99823fb23632150743f9c83af329bb6090/coverage-7.13.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11c21557d0e0a5a38632cbbaca5f008723b26a89d70db6315523df6df77d6232", size = 249850, upload-time = "2025-12-08T13:13:18.142Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e9/8d68337c3125014d918cf4327d5257553a710a2995a6a6de2ac77e5aa429/coverage-7.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76541dc8d53715fb4f7a3a06b34b0dc6846e3c69bc6204c55653a85dd6220971", size = 251633, upload-time = "2025-12-08T13:13:19.56Z" }, + { url = "https://files.pythonhosted.org/packages/55/14/d4112ab26b3a1bc4b3c1295d8452dcf399ed25be4cf649002fb3e64b2d93/coverage-7.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6e9e451dee940a86789134b6b0ffbe31c454ade3b849bb8a9d2cca2541a8e91d", size = 249586, upload-time = "2025-12-08T13:13:20.883Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a9/22b0000186db663b0d82f86c2f1028099ae9ac202491685051e2a11a5218/coverage-7.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5c67dace46f361125e6b9cace8fe0b729ed8479f47e70c89b838d319375c8137", size = 249412, upload-time = "2025-12-08T13:13:22.22Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2e/42d8e0d9e7527fba439acdc6ed24a2b97613b1dc85849b1dd935c2cffef0/coverage-7.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f59883c643cb19630500f57016f76cfdcd6845ca8c5b5ea1f6e17f74c8e5f511", size = 251191, upload-time = "2025-12-08T13:13:23.899Z" }, + { url = "https://files.pythonhosted.org/packages/a4/af/8c7af92b1377fd8860536aadd58745119252aaaa71a5213e5a8e8007a9f5/coverage-7.13.0-cp313-cp313-win32.whl", hash = "sha256:58632b187be6f0be500f553be41e277712baa278147ecb7559983c6d9faf7ae1", size = 220829, upload-time = "2025-12-08T13:13:25.182Z" }, + { url = "https://files.pythonhosted.org/packages/58/f9/725e8bf16f343d33cbe076c75dc8370262e194ff10072c0608b8e5cf33a3/coverage-7.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:73419b89f812f498aca53f757dd834919b48ce4799f9d5cad33ca0ae442bdb1a", size = 221640, upload-time = "2025-12-08T13:13:26.836Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ff/e98311000aa6933cc79274e2b6b94a2fe0fe3434fca778eba82003675496/coverage-7.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:eb76670874fdd6091eedcc856128ee48c41a9bbbb9c3f1c7c3cf169290e3ffd6", size = 220269, upload-time = "2025-12-08T13:13:28.116Z" }, + { url = "https://files.pythonhosted.org/packages/cf/cf/bbaa2e1275b300343ea865f7d424cc0a2e2a1df6925a070b2b2d5d765330/coverage-7.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6e63ccc6e0ad8986386461c3c4b737540f20426e7ec932f42e030320896c311a", size = 218990, upload-time = "2025-12-08T13:13:29.463Z" }, + { url = "https://files.pythonhosted.org/packages/21/1d/82f0b3323b3d149d7672e7744c116e9c170f4957e0c42572f0366dbb4477/coverage-7.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:494f5459ffa1bd45e18558cd98710c36c0b8fbfa82a5eabcbe671d80ecffbfe8", size = 219340, upload-time = "2025-12-08T13:13:31.524Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e3/fe3fd4702a3832a255f4d43013eacb0ef5fc155a5960ea9269d8696db28b/coverage-7.13.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:06cac81bf10f74034e055e903f5f946e3e26fc51c09fc9f584e4a1605d977053", size = 260638, upload-time = "2025-12-08T13:13:32.965Z" }, + { url = "https://files.pythonhosted.org/packages/ad/01/63186cb000307f2b4da463f72af9b85d380236965574c78e7e27680a2593/coverage-7.13.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f2ffc92b46ed6e6760f1d47a71e56b5664781bc68986dbd1836b2b70c0ce2071", size = 262705, upload-time = "2025-12-08T13:13:34.378Z" }, + { url = "https://files.pythonhosted.org/packages/7c/a1/c0dacef0cc865f2455d59eed3548573ce47ed603205ffd0735d1d78b5906/coverage-7.13.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0602f701057c6823e5db1b74530ce85f17c3c5be5c85fc042ac939cbd909426e", size = 265125, upload-time = "2025-12-08T13:13:35.73Z" }, + { url = "https://files.pythonhosted.org/packages/ef/92/82b99223628b61300bd382c205795533bed021505eab6dd86e11fb5d7925/coverage-7.13.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:25dc33618d45456ccb1d37bce44bc78cf269909aa14c4db2e03d63146a8a1493", size = 259844, upload-time = "2025-12-08T13:13:37.69Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2c/89b0291ae4e6cd59ef042708e1c438e2290f8c31959a20055d8768349ee2/coverage-7.13.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:71936a8b3b977ddd0b694c28c6a34f4fff2e9dd201969a4ff5d5fc7742d614b0", size = 262700, upload-time = "2025-12-08T13:13:39.525Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f9/a5f992efae1996245e796bae34ceb942b05db275e4b34222a9a40b9fbd3b/coverage-7.13.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:936bc20503ce24770c71938d1369461f0c5320830800933bc3956e2a4ded930e", size = 260321, upload-time = "2025-12-08T13:13:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/4c/89/a29f5d98c64fedbe32e2ac3c227fbf78edc01cc7572eee17d61024d89889/coverage-7.13.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:af0a583efaacc52ae2521f8d7910aff65cdb093091d76291ac5820d5e947fc1c", size = 259222, upload-time = "2025-12-08T13:13:43.282Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c3/940fe447aae302a6701ee51e53af7e08b86ff6eed7631e5740c157ee22b9/coverage-7.13.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f1c23e24a7000da892a312fb17e33c5f94f8b001de44b7cf8ba2e36fbd15859e", size = 261411, upload-time = "2025-12-08T13:13:44.72Z" }, + { url = "https://files.pythonhosted.org/packages/eb/31/12a4aec689cb942a89129587860ed4d0fd522d5fda81237147fde554b8ae/coverage-7.13.0-cp313-cp313t-win32.whl", hash = "sha256:5f8a0297355e652001015e93be345ee54393e45dc3050af4a0475c5a2b767d46", size = 221505, upload-time = "2025-12-08T13:13:46.332Z" }, + { url = "https://files.pythonhosted.org/packages/65/8c/3b5fe3259d863572d2b0827642c50c3855d26b3aefe80bdc9eba1f0af3b0/coverage-7.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6abb3a4c52f05e08460bd9acf04fec027f8718ecaa0d09c40ffbc3fbd70ecc39", size = 222569, upload-time = "2025-12-08T13:13:47.79Z" }, + { url = "https://files.pythonhosted.org/packages/b0/39/f71fa8316a96ac72fc3908839df651e8eccee650001a17f2c78cdb355624/coverage-7.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3ad968d1e3aa6ce5be295ab5fe3ae1bf5bb4769d0f98a80a0252d543a2ef2e9e", size = 220841, upload-time = "2025-12-08T13:13:49.243Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4b/9b54bedda55421449811dcd5263a2798a63f48896c24dfb92b0f1b0845bd/coverage-7.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:453b7ec753cf5e4356e14fe858064e5520c460d3bbbcb9c35e55c0d21155c256", size = 218343, upload-time = "2025-12-08T13:13:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/59/df/c3a1f34d4bba2e592c8979f924da4d3d4598b0df2392fbddb7761258e3dc/coverage-7.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:af827b7cbb303e1befa6c4f94fd2bf72f108089cfa0f8abab8f4ca553cf5ca5a", size = 218672, upload-time = "2025-12-08T13:13:52.284Z" }, + { url = "https://files.pythonhosted.org/packages/07/62/eec0659e47857698645ff4e6ad02e30186eb8afd65214fd43f02a76537cb/coverage-7.13.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9987a9e4f8197a1000280f7cc089e3ea2c8b3c0a64d750537809879a7b4ceaf9", size = 249715, upload-time = "2025-12-08T13:13:53.791Z" }, + { url = "https://files.pythonhosted.org/packages/23/2d/3c7ff8b2e0e634c1f58d095f071f52ed3c23ff25be524b0ccae8b71f99f8/coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19", size = 252225, upload-time = "2025-12-08T13:13:55.274Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ac/fb03b469d20e9c9a81093575003f959cf91a4a517b783aab090e4538764b/coverage-7.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2bdb3babb74079f021696cb46b8bb5f5661165c385d3a238712b031a12355be", size = 253559, upload-time = "2025-12-08T13:13:57.161Z" }, + { url = "https://files.pythonhosted.org/packages/29/62/14afa9e792383c66cc0a3b872a06ded6e4ed1079c7d35de274f11d27064e/coverage-7.13.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7464663eaca6adba4175f6c19354feea61ebbdd735563a03d1e472c7072d27bb", size = 249724, upload-time = "2025-12-08T13:13:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/31/b7/333f3dab2939070613696ab3ee91738950f0467778c6e5a5052e840646b7/coverage-7.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8069e831f205d2ff1f3d355e82f511eb7c5522d7d413f5db5756b772ec8697f8", size = 251582, upload-time = "2025-12-08T13:14:00.642Z" }, + { url = "https://files.pythonhosted.org/packages/81/cb/69162bda9381f39b2287265d7e29ee770f7c27c19f470164350a38318764/coverage-7.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6fb2d5d272341565f08e962cce14cdf843a08ac43bd621783527adb06b089c4b", size = 249538, upload-time = "2025-12-08T13:14:02.556Z" }, + { url = "https://files.pythonhosted.org/packages/e0/76/350387b56a30f4970abe32b90b2a434f87d29f8b7d4ae40d2e8a85aacfb3/coverage-7.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5e70f92ef89bac1ac8a99b3324923b4749f008fdbd7aa9cb35e01d7a284a04f9", size = 249349, upload-time = "2025-12-08T13:14:04.015Z" }, + { url = "https://files.pythonhosted.org/packages/86/0d/7f6c42b8d59f4c7e43ea3059f573c0dcfed98ba46eb43c68c69e52ae095c/coverage-7.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4b5de7d4583e60d5fd246dd57fcd3a8aa23c6e118a8c72b38adf666ba8e7e927", size = 251011, upload-time = "2025-12-08T13:14:05.505Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f1/4bb2dff379721bb0b5c649d5c5eaf438462cad824acf32eb1b7ca0c7078e/coverage-7.13.0-cp314-cp314-win32.whl", hash = "sha256:a6c6e16b663be828a8f0b6c5027d36471d4a9f90d28444aa4ced4d48d7d6ae8f", size = 221091, upload-time = "2025-12-08T13:14:07.127Z" }, + { url = "https://files.pythonhosted.org/packages/ba/44/c239da52f373ce379c194b0ee3bcc121020e397242b85f99e0afc8615066/coverage-7.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:0900872f2fdb3ee5646b557918d02279dc3af3dfb39029ac4e945458b13f73bc", size = 221904, upload-time = "2025-12-08T13:14:08.542Z" }, + { url = "https://files.pythonhosted.org/packages/89/1f/b9f04016d2a29c2e4a0307baefefad1a4ec5724946a2b3e482690486cade/coverage-7.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:3a10260e6a152e5f03f26db4a407c4c62d3830b9af9b7c0450b183615f05d43b", size = 220480, upload-time = "2025-12-08T13:14:10.958Z" }, + { url = "https://files.pythonhosted.org/packages/16/d4/364a1439766c8e8647860584171c36010ca3226e6e45b1753b1b249c5161/coverage-7.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9097818b6cc1cfb5f174e3263eba4a62a17683bcfe5c4b5d07f4c97fa51fbf28", size = 219074, upload-time = "2025-12-08T13:14:13.345Z" }, + { url = "https://files.pythonhosted.org/packages/ce/f4/71ba8be63351e099911051b2089662c03d5671437a0ec2171823c8e03bec/coverage-7.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0018f73dfb4301a89292c73be6ba5f58722ff79f51593352759c1790ded1cabe", size = 219342, upload-time = "2025-12-08T13:14:15.02Z" }, + { url = "https://files.pythonhosted.org/packages/5e/25/127d8ed03d7711a387d96f132589057213e3aef7475afdaa303412463f22/coverage-7.13.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:166ad2a22ee770f5656e1257703139d3533b4a0b6909af67c6b4a3adc1c98657", size = 260713, upload-time = "2025-12-08T13:14:16.907Z" }, + { url = "https://files.pythonhosted.org/packages/fd/db/559fbb6def07d25b2243663b46ba9eb5a3c6586c0c6f4e62980a68f0ee1c/coverage-7.13.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f6aaef16d65d1787280943f1c8718dc32e9cf141014e4634d64446702d26e0ff", size = 262825, upload-time = "2025-12-08T13:14:18.68Z" }, + { url = "https://files.pythonhosted.org/packages/37/99/6ee5bf7eff884766edb43bd8736b5e1c5144d0fe47498c3779326fe75a35/coverage-7.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e999e2dcc094002d6e2c7bbc1fb85b58ba4f465a760a8014d97619330cdbbbf3", size = 265233, upload-time = "2025-12-08T13:14:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/d8/90/92f18fe0356ea69e1f98f688ed80cec39f44e9f09a1f26a1bbf017cc67f2/coverage-7.13.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:00c3d22cf6fb1cf3bf662aaaa4e563be8243a5ed2630339069799835a9cc7f9b", size = 259779, upload-time = "2025-12-08T13:14:22.367Z" }, + { url = "https://files.pythonhosted.org/packages/90/5d/b312a8b45b37a42ea7d27d7d3ff98ade3a6c892dd48d1d503e773503373f/coverage-7.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22ccfe8d9bb0d6134892cbe1262493a8c70d736b9df930f3f3afae0fe3ac924d", size = 262700, upload-time = "2025-12-08T13:14:24.309Z" }, + { url = "https://files.pythonhosted.org/packages/63/f8/b1d0de5c39351eb71c366f872376d09386640840a2e09b0d03973d791e20/coverage-7.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9372dff5ea15930fea0445eaf37bbbafbc771a49e70c0aeed8b4e2c2614cc00e", size = 260302, upload-time = "2025-12-08T13:14:26.068Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7c/d42f4435bc40c55558b3109a39e2d456cddcec37434f62a1f1230991667a/coverage-7.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:69ac2c492918c2461bc6ace42d0479638e60719f2a4ef3f0815fa2df88e9f940", size = 259136, upload-time = "2025-12-08T13:14:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d3/23413241dc04d47cfe19b9a65b32a2edd67ecd0b817400c2843ebc58c847/coverage-7.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:739c6c051a7540608d097b8e13c76cfa85263ced467168dc6b477bae3df7d0e2", size = 261467, upload-time = "2025-12-08T13:14:29.09Z" }, + { url = "https://files.pythonhosted.org/packages/13/e6/6e063174500eee216b96272c0d1847bf215926786f85c2bd024cf4d02d2f/coverage-7.13.0-cp314-cp314t-win32.whl", hash = "sha256:fe81055d8c6c9de76d60c94ddea73c290b416e061d40d542b24a5871bad498b7", size = 221875, upload-time = "2025-12-08T13:14:31.106Z" }, + { url = "https://files.pythonhosted.org/packages/3b/46/f4fb293e4cbe3620e3ac2a3e8fd566ed33affb5861a9b20e3dd6c1896cbc/coverage-7.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:445badb539005283825959ac9fa4a28f712c214b65af3a2c464f1adc90f5fcbc", size = 222982, upload-time = "2025-12-08T13:14:33.1Z" }, + { url = "https://files.pythonhosted.org/packages/68/62/5b3b9018215ed9733fbd1ae3b2ed75c5de62c3b55377a52cae732e1b7805/coverage-7.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:de7f6748b890708578fc4b7bb967d810aeb6fcc9bff4bb77dbca77dab2f9df6a", size = 221016, upload-time = "2025-12-08T13:14:34.601Z" }, + { url = "https://files.pythonhosted.org/packages/8d/4c/1968f32fb9a2604645827e11ff84a31e59d532e01995f904723b4f5328b3/coverage-7.13.0-py3-none-any.whl", hash = "sha256:850d2998f380b1e266459ca5b47bc9e7daf9af1d070f66317972f382d46f1904", size = 210068, upload-time = "2025-12-08T13:14:36.236Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cryptography" +version = "46.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, + { url = "https://files.pythonhosted.org/packages/06/8a/e60e46adab4362a682cf142c7dcb5bf79b782ab2199b0dcb81f55970807f/cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea", size = 3698132, upload-time = "2025-10-15T23:18:17.056Z" }, + { url = "https://files.pythonhosted.org/packages/da/38/f59940ec4ee91e93d3311f7532671a5cef5570eb04a144bf203b58552d11/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b", size = 4243992, upload-time = "2025-10-15T23:18:18.695Z" }, + { url = "https://files.pythonhosted.org/packages/b0/0c/35b3d92ddebfdfda76bb485738306545817253d0a3ded0bfe80ef8e67aa5/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb", size = 4409944, upload-time = "2025-10-15T23:18:20.597Z" }, + { url = "https://files.pythonhosted.org/packages/99/55/181022996c4063fc0e7666a47049a1ca705abb9c8a13830f074edb347495/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717", size = 4242957, upload-time = "2025-10-15T23:18:22.18Z" }, + { url = "https://files.pythonhosted.org/packages/ba/af/72cd6ef29f9c5f731251acadaeb821559fe25f10852f44a63374c9ca08c1/cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9", size = 4409447, upload-time = "2025-10-15T23:18:24.209Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c3/e90f4a4feae6410f914f8ebac129b9ae7a8c92eb60a638012dde42030a9d/cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c", size = 3438528, upload-time = "2025-10-15T23:18:26.227Z" }, +] + +[[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, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "cython" +version = "3.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/29/17/55fc687ba986f2210298fa2f60fec265fa3004c3f9a1e958ea1fe2d4e061/cython-3.2.2.tar.gz", hash = "sha256:c3add3d483acc73129a61d105389344d792c17e7c1cee24863f16416bd071634", size = 3275797, upload-time = "2025-11-30T12:48:20.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/ba/d785f60564a43bddbb7316134252a55d67ff6f164f0be90c4bf31482da82/cython-3.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d140c2701cbb8cf960300cf1b67f3b4fa9d294d32e51b85f329bff56936a82fd", size = 2951181, upload-time = "2025-11-30T12:48:39.723Z" }, + { url = "https://files.pythonhosted.org/packages/8c/36/277ea908bd7a326adcce5f67581926783ec11a4402ead0719e72555da2e7/cython-3.2.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50bbaabee733fd2780985e459fc20f655e02def83e8eff10220ad88455a34622", size = 3243194, upload-time = "2025-11-30T12:48:41.862Z" }, + { url = "https://files.pythonhosted.org/packages/74/87/7776495bbff80bdd7754f4849bfde126b1d97741df5bc58a3a00af641747/cython-3.2.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9509f1e9c41c86b790cff745bb31927bbc861662a3b462596d71d3d2a578abb", size = 3378096, upload-time = "2025-11-30T12:48:43.584Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d0/fabb9f4767f7101f1c0d6b23116d6d250148f656dac152afd792756661a8/cython-3.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:034ab96cb8bc8e7432bc27491f8d66f51e435b1eb21ddc03aa844be8f21ad847", size = 2768932, upload-time = "2025-11-30T12:48:45.193Z" }, + { url = "https://files.pythonhosted.org/packages/57/0f/6fd78dc581373722bb9dedfc90c35b59ba88af988756315af227a877c7a2/cython-3.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:692a41c8fe06fb2dc55ca2c8d71c80c469fd16fe69486ed99f3b3cbb2d3af83f", size = 2968037, upload-time = "2025-11-30T12:48:47.279Z" }, + { url = "https://files.pythonhosted.org/packages/b0/52/50b6263c2fbad73aae8911ce54641ee1739d430a0592d3b3510591d7842b/cython-3.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:098590c1dc309f8a0406ade031963a95a87714296b425539f9920aebf924560d", size = 3223137, upload-time = "2025-11-30T12:48:48.951Z" }, + { url = "https://files.pythonhosted.org/packages/d6/44/4e34d161674c9162c6eb9ddef0cd69d41d92ae7e6dee3945fed3a6871ebe/cython-3.2.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3898c076e9c458bcb3e4936187919fda5f5365fe4c567d35d2b003444b6f3fe", size = 3390943, upload-time = "2025-11-30T12:48:51.125Z" }, + { url = "https://files.pythonhosted.org/packages/62/8a/ffc2df024c1341737008fbaf0fbea51ef983a7146b43b84a239f197cf005/cython-3.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:2b910b89a2a71004064c5e890b9512a251eda63fae252caa0feb9835057035f9", size = 2756403, upload-time = "2025-11-30T12:48:52.929Z" }, + { url = "https://files.pythonhosted.org/packages/a2/4f/b5355918962ec28b376eb8e357c718d58baf32d6df7017be8d147dd4ba29/cython-3.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa24cd0bdab27ca099b2467806c684404add597c1108e07ddf7b6471653c85d7", size = 2958578, upload-time = "2025-11-30T12:48:55.354Z" }, + { url = "https://files.pythonhosted.org/packages/46/21/a8038c8253e7a5241ed1db6d031bac586f7a502d92f487124abbc3f3e94f/cython-3.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60f4aa425e1ff98abf8d965ae7020f06dd2cbc01dbd945137d2f9cca4ff0524a", size = 3212479, upload-time = "2025-11-30T12:48:57.567Z" }, + { url = "https://files.pythonhosted.org/packages/57/c1/76928c07176a4402c74d5b304936ad8ee167dd04a07cf7dca545e8c25f9b/cython-3.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a473df474ba89e9fee81ee82b31062a267f9e598096b222783477e56d02ad12c", size = 3374773, upload-time = "2025-11-30T12:48:59.318Z" }, + { url = "https://files.pythonhosted.org/packages/fa/cb/ce641e07ba9c0cde8468e83e0214fb87020b74ba34dbb9dfe8d250a327f5/cython-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:b4df52101209817fde7284cf779156f79142fb639b1d7840f11680ff4bb30604", size = 2754492, upload-time = "2025-11-30T12:49:01.029Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f2/cd60f639f0fde38b71319d7b6808e1ff17a6fd7f3feaff475b866a5c0aef/cython-3.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:177faf4d61e9f2d4d2db61194ac9ec16d3fe3041c1b6830f871a01935319eeb3", size = 2969023, upload-time = "2025-11-30T12:49:02.734Z" }, + { url = "https://files.pythonhosted.org/packages/5d/45/6f155a9ad125536d8f30716c4d7571caae73ec811039d3ae33f9b535090d/cython-3.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8db28aef793c81dc69383b619ca508668998aaf099cd839d3cbae85184cce744", size = 3258270, upload-time = "2025-11-30T12:49:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/af/7e/022c25886fdc3ff6a005b6ae4a1c3d8522006bb738367aa5bd6c2590130b/cython-3.2.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3de43a5786033a27fae1c882feb5ff0d023c38b83356e6800c1be0bcd6cf9f11", size = 3384504, upload-time = "2025-11-30T12:49:07.078Z" }, + { url = "https://files.pythonhosted.org/packages/b6/07/1e3e4faf6f785d5ba053e9d6320b3f338162dc122c27a7c540b49615fc39/cython-3.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:fed44d0ab2d36f1b0301c770b0dafec23bcb9700d58e7769cd6d9136b3304c11", size = 2791504, upload-time = "2025-11-30T12:49:08.729Z" }, + { url = "https://files.pythonhosted.org/packages/f4/69/5430879d35235ec3d5ffd778862173b6419390509ae4e37a72bdd45d9e86/cython-3.2.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a6387e3ad31342443916db9a419509935fddd8d4cbac34aab9c895ae55326a56", size = 2874031, upload-time = "2025-11-30T12:49:18.34Z" }, + { url = "https://files.pythonhosted.org/packages/51/fa/584f4b56b35b3e7a43dc16603dd722cb5528484da67c27136534b782827b/cython-3.2.2-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:436eb562d0affbc0b959f62f3f9c1ed251b9499e4f29c1d19514ae859894b6bf", size = 3210813, upload-time = "2025-11-30T12:49:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d4/063c34a34d9ef54836a5dafb100b8f4fdbdaa63942913fe93f9eb93a11a2/cython-3.2.2-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f560ff3aea5b5df93853ec7bf1a1e9623d6d511f4192f197559aca18fca43392", size = 2855611, upload-time = "2025-11-30T12:49:22.303Z" }, + { url = "https://files.pythonhosted.org/packages/b9/44/c0b8854e0bf6d444c88cc2050f550d964596daea20eaf1bc592fcfde2782/cython-3.2.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d8c93fe128b58942832b1fcac96e48f93c2c69b569eff0d38d30fb5995fecfa0", size = 2992824, upload-time = "2025-11-30T12:49:24.02Z" }, + { url = "https://files.pythonhosted.org/packages/90/6f/741186935c52de99acf4d7fad5c3dcf28d980b4c95d171d9618f9c399316/cython-3.2.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b4fe499eed7cd70b2aa4e096b9ce2588f5e6fdf049b46d40a5e55efcde6e4904", size = 2890389, upload-time = "2025-11-30T12:49:25.783Z" }, + { url = "https://files.pythonhosted.org/packages/5c/79/3e487876addd0d69c148a529f3973c1942498ad39cede1e63565676064ed/cython-3.2.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:14432d7f207245a3c35556155873f494784169297b28978a6204f1c60d31553e", size = 3224881, upload-time = "2025-11-30T12:49:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/15/b9/d9a103feb74d04579c6bde7b0cad6d5f45c002d843ca70788a5758707b68/cython-3.2.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:820c4a99dbf6b3e6c0300be42b4040b501eff0e1feeb80cfa52c48a346fb0df2", size = 3114308, upload-time = "2025-11-30T12:49:29.292Z" }, + { url = "https://files.pythonhosted.org/packages/18/56/90445707cff62ab72136857a0134c5e50f9c73920c1a3af5218dfdae1c19/cython-3.2.2-cp39-abi3-win32.whl", hash = "sha256:826cad0ad43ab05a26e873b5d625f64d458dc739ec6fdeecab848b60a91c4252", size = 2435212, upload-time = "2025-11-30T12:49:32.179Z" }, + { url = "https://files.pythonhosted.org/packages/44/54/25a98c2731521ac9fc18e17d79a0e7d58164d4db398f09e1bd24cdd27ed1/cython-3.2.2-cp39-abi3-win_arm64.whl", hash = "sha256:5f818d40bbcf17e2089e2de7840f0de1c0ca527acf9b044aba79d5f5d8a5bdba", size = 2440536, upload-time = "2025-11-30T12:49:34.109Z" }, + { url = "https://files.pythonhosted.org/packages/76/f2/98fd8d0b514622a789fd2824b59bd6041b799aaeeba14a8d92d52f6654dd/cython-3.2.2-py3-none-any.whl", hash = "sha256:13b99ecb9482aff6a6c12d1ca6feef6940c507af909914b49f568de74fa965fb", size = 1255106, upload-time = "2025-11-30T12:48:18.454Z" }, +] + +[[package]] +name = "cytoolz" +version = "0.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "toolz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/70/d8/8df71050b214686591241a1826d2e6934b5c295c5bc57f643e4ed697f1eb/cytoolz-0.12.3.tar.gz", hash = "sha256:4503dc59f4ced53a54643272c61dc305d1dbbfbd7d6bdf296948de9f34c3a282", size = 625899, upload-time = "2024-01-25T01:39:13.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/8a/618a70326d4a52998a6bbb11ca019979891a51b85cbbfce8f9762eec5d2c/cytoolz-0.12.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ac4f2fb38bbc67ff1875b7d2f0f162a247f43bd28eb7c9d15e6175a982e558d", size = 416356, upload-time = "2024-01-25T01:36:30.344Z" }, + { url = "https://files.pythonhosted.org/packages/bb/17/542f708b9116aa8d8c9c5551500bfa6ab1bddd3edc11457070599a97c197/cytoolz-0.12.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0cf1e1e96dd86829a0539baf514a9c8473a58fbb415f92401a68e8e52a34ecd5", size = 398412, upload-time = "2024-01-25T01:36:32.628Z" }, + { url = "https://files.pythonhosted.org/packages/d6/9c/52a0460f2b59009da63794cfe11ad002d55fc88fced6ccc85f7ae10a3259/cytoolz-0.12.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08a438701c6141dd34eaf92e9e9a1f66e23a22f7840ef8a371eba274477de85d", size = 2090389, upload-time = "2024-01-25T01:36:34.398Z" }, + { url = "https://files.pythonhosted.org/packages/c7/6d/284d4a1f88b1e63b8a1c80162244ca5d4e0b31647c4f56186f3385fd0d0e/cytoolz-0.12.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6b6f11b0d7ed91be53166aeef2a23a799e636625675bb30818f47f41ad31821", size = 2187333, upload-time = "2024-01-25T01:36:36.099Z" }, + { url = "https://files.pythonhosted.org/packages/3e/44/44efcf2acf824aefab5f3fdb97235d360c216c2425db391a8dee687f1774/cytoolz-0.12.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fde09384d23048a7b4ac889063761e44b89a0b64015393e2d1d21d5c1f534a", size = 2173106, upload-time = "2024-01-25T01:36:37.827Z" }, + { url = "https://files.pythonhosted.org/packages/6f/74/7c2d5af25d51f481e9be771bda2cf5496631cd0fba876d2cc0086caa732d/cytoolz-0.12.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d3bfe45173cc8e6c76206be3a916d8bfd2214fb2965563e288088012f1dabfc", size = 2098805, upload-time = "2024-01-25T01:36:40.09Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/9995bf66caee139459ab70d8b5820c37718d5f7e7380481adb85ef522e4d/cytoolz-0.12.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27513a5d5b6624372d63313574381d3217a66e7a2626b056c695179623a5cb1a", size = 1995956, upload-time = "2024-01-25T01:36:41.741Z" }, + { url = "https://files.pythonhosted.org/packages/93/73/eee7a7f455d4691f1915b35d1713ba69c6851f940c6f8fffdd2efcbe4411/cytoolz-0.12.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d294e5e81ff094fe920fd545052ff30838ea49f9e91227a55ecd9f3ca19774a0", size = 2074891, upload-time = "2024-01-25T01:36:43.887Z" }, + { url = "https://files.pythonhosted.org/packages/a3/c7/6f0c60bbb911ee3f33b243a695e2fc944285a1865bbb1dfefee1b7c35d62/cytoolz-0.12.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:727b01a2004ddb513496507a695e19b5c0cfebcdfcc68349d3efd92a1c297bf4", size = 1980228, upload-time = "2024-01-25T01:36:45.42Z" }, + { url = "https://files.pythonhosted.org/packages/58/7c/d7524626b415d410208fd2774ff2824fab4dcbe4a496d53bdba85a1407df/cytoolz-0.12.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:fe1e1779a39dbe83f13886d2b4b02f8c4b10755e3c8d9a89b630395f49f4f406", size = 2147616, upload-time = "2024-01-25T01:36:47.06Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7b/9bdf8615e61958386f5c7108d857312214837ae3eacf3589873499d2f0aa/cytoolz-0.12.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:de74ef266e2679c3bf8b5fc20cee4fc0271ba13ae0d9097b1491c7a9bcadb389", size = 2148775, upload-time = "2024-01-25T01:36:48.813Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/b92ab0e29bf7cfaacfedc85391a0d0365a6ac74363f2532ba307a760db14/cytoolz-0.12.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e04d22049233394e0b08193aca9737200b4a2afa28659d957327aa780ddddf2", size = 2079810, upload-time = "2024-01-25T01:36:50.116Z" }, + { url = "https://files.pythonhosted.org/packages/2f/33/8204d65871fa639d1d3ae788e3afc187f610126f53f2324d4aa37caf0630/cytoolz-0.12.3-cp311-cp311-win32.whl", hash = "sha256:20d36430d8ac809186736fda735ee7d595b6242bdb35f69b598ef809ebfa5605", size = 320212, upload-time = "2024-01-25T01:36:51.73Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e3/7ce2efaf243c9ee75fc730cd018981788b56e7ad3767f24e7a9cd14831ac/cytoolz-0.12.3-cp311-cp311-win_amd64.whl", hash = "sha256:780c06110f383344d537f48d9010d79fa4f75070d214fc47f389357dd4f010b6", size = 363570, upload-time = "2024-01-25T01:36:53.371Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/b0feabefdff4707d0b96bf75e2298ecb209ba22c2e3fd15e5230dd68441a/cytoolz-0.12.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:86923d823bd19ce35805953b018d436f6b862edd6a7c8b747a13d52b39ed5716", size = 419825, upload-time = "2024-01-25T01:36:54.522Z" }, + { url = "https://files.pythonhosted.org/packages/54/82/795aa9f91ee81818732b435755559857a76e16b7e435e1de434b47ce72b9/cytoolz-0.12.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3e61acfd029bfb81c2c596249b508dfd2b4f72e31b7b53b62e5fb0507dd7293", size = 401673, upload-time = "2024-01-25T01:36:56.435Z" }, + { url = "https://files.pythonhosted.org/packages/23/f3/298f32b2e374f4f716ca74a9e46b64ee1df9f160de262391f7f9bc53ecca/cytoolz-0.12.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd728f4e6051af6af234651df49319da1d813f47894d4c3c8ab7455e01703a37", size = 2096352, upload-time = "2024-01-25T01:36:58.428Z" }, + { url = "https://files.pythonhosted.org/packages/39/44/49929b33bd0cdccc98b281e4ca11f0836b2963c6fdec8ebb7891807ed908/cytoolz-0.12.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe8c6267caa7ec67bcc37e360f0d8a26bc3bdce510b15b97f2f2e0143bdd3673", size = 2161581, upload-time = "2024-01-25T01:36:59.818Z" }, + { url = "https://files.pythonhosted.org/packages/e9/77/980a8bc123490dd7112e1e068da989932b7612504355ddd25593880c3156/cytoolz-0.12.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99462abd8323c52204a2a0ce62454ce8fa0f4e94b9af397945c12830de73f27e", size = 2178057, upload-time = "2024-01-25T01:37:02.23Z" }, + { url = "https://files.pythonhosted.org/packages/23/d9/2f7a4db7f92eab4b567e56cc2fc147fed1ef35f7968e44cefcbbfb366980/cytoolz-0.12.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da125221b1fa25c690fcd030a54344cecec80074df018d906fc6a99f46c1e3a6", size = 2130881, upload-time = "2024-01-25T01:37:03.703Z" }, + { url = "https://files.pythonhosted.org/packages/85/bf/1147229198a8fc3f2090d01263234d47b5b7f8c52c20090b1cceda0929cd/cytoolz-0.12.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c18e351956f70db9e2d04ff02f28e9a41839250d3f936a4c8a1eabd1c3094d2", size = 1979975, upload-time = "2024-01-25T01:37:06.277Z" }, + { url = "https://files.pythonhosted.org/packages/5b/53/b730e9f428e74971f934bf73f0868099d325ffbf0c080a201bb16b6ab508/cytoolz-0.12.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:921e6d2440ac758c4945c587b1d1d9b781b72737ac0c0ca5d5e02ca1db8bded2", size = 2086861, upload-time = "2024-01-25T01:37:07.869Z" }, + { url = "https://files.pythonhosted.org/packages/24/24/df510850c1c57ad69a23a2700083cfd285faf27d16e61f0e503eec122473/cytoolz-0.12.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1651a9bd591a8326329ce1d6336f3129161a36d7061a4d5ea9e5377e033364cf", size = 1973211, upload-time = "2024-01-25T01:37:10.036Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ad/a6e27924a6c8048b4f1ffbd8b9b0b871642bd94d3e457aa42a629c1f667b/cytoolz-0.12.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8893223b87c2782bd59f9c4bd5c7bf733edd8728b523c93efb91d7468b486528", size = 2133017, upload-time = "2024-01-25T01:37:11.684Z" }, + { url = "https://files.pythonhosted.org/packages/26/a3/f9dfb406232d0a100994a86c123259cd2ab023aa8ae325b0d9926f80091f/cytoolz-0.12.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:e4d2961644153c5ae186db964aa9f6109da81b12df0f1d3494b4e5cf2c332ee2", size = 2156771, upload-time = "2024-01-25T01:37:13.62Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bf/ce2c6f6175a29c830904b23faee557de8c167255dbb2bb84e04d7cf5605a/cytoolz-0.12.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:71b6eb97f6695f7ba8ce69c49b707a351c5f46fd97f5aeb5f6f2fb0d6e72b887", size = 2121104, upload-time = "2024-01-25T01:37:16.053Z" }, + { url = "https://files.pythonhosted.org/packages/bf/97/95a5fb2b5db9b1ea8856741a2a94741a71cb5640112403029beb7b3ef1df/cytoolz-0.12.3-cp312-cp312-win32.whl", hash = "sha256:cee3de65584e915053412cd178729ff510ad5f8f585c21c5890e91028283518f", size = 320537, upload-time = "2024-01-25T01:37:18.026Z" }, + { url = "https://files.pythonhosted.org/packages/0a/11/3e69585342ce4e6b7f2f6139c8aa235dab5a4fe5c76a051fe01696618bd0/cytoolz-0.12.3-cp312-cp312-win_amd64.whl", hash = "sha256:9eef0d23035fa4dcfa21e570961e86c375153a7ee605cdd11a8b088c24f707f6", size = 363238, upload-time = "2024-01-25T01:37:19.343Z" }, +] + +[[package]] +name = "debugpy" +version = "1.8.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/ad/71e708ff4ca377c4230530d6a7aa7992592648c122a2cd2b321cf8b35a76/debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e", size = 1644129, upload-time = "2025-09-17T16:33:20.633Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/53/3af72b5c159278c4a0cf4cffa518675a0e73bdb7d1cac0239b815502d2ce/debugpy-1.8.17-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:d3fce3f0e3de262a3b67e69916d001f3e767661c6e1ee42553009d445d1cd840", size = 2207154, upload-time = "2025-09-17T16:33:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6d/204f407df45600e2245b4a39860ed4ba32552330a0b3f5f160ae4cc30072/debugpy-1.8.17-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:c6bdf134457ae0cac6fb68205776be635d31174eeac9541e1d0c062165c6461f", size = 3170322, upload-time = "2025-09-17T16:33:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/f2/13/1b8f87d39cf83c6b713de2620c31205299e6065622e7dd37aff4808dd410/debugpy-1.8.17-cp311-cp311-win32.whl", hash = "sha256:e79a195f9e059edfe5d8bf6f3749b2599452d3e9380484cd261f6b7cd2c7c4da", size = 5155078, upload-time = "2025-09-17T16:33:33.331Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c5/c012c60a2922cc91caa9675d0ddfbb14ba59e1e36228355f41cab6483469/debugpy-1.8.17-cp311-cp311-win_amd64.whl", hash = "sha256:b532282ad4eca958b1b2d7dbcb2b7218e02cb934165859b918e3b6ba7772d3f4", size = 5179011, upload-time = "2025-09-17T16:33:35.711Z" }, + { url = "https://files.pythonhosted.org/packages/08/2b/9d8e65beb2751876c82e1aceb32f328c43ec872711fa80257c7674f45650/debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d", size = 2549522, upload-time = "2025-09-17T16:33:38.466Z" }, + { url = "https://files.pythonhosted.org/packages/b4/78/eb0d77f02971c05fca0eb7465b18058ba84bd957062f5eec82f941ac792a/debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc", size = 4309417, upload-time = "2025-09-17T16:33:41.299Z" }, + { url = "https://files.pythonhosted.org/packages/37/42/c40f1d8cc1fed1e75ea54298a382395b8b937d923fcf41ab0797a554f555/debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf", size = 5277130, upload-time = "2025-09-17T16:33:43.554Z" }, + { url = "https://files.pythonhosted.org/packages/72/22/84263b205baad32b81b36eac076de0cdbe09fe2d0637f5b32243dc7c925b/debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464", size = 5319053, upload-time = "2025-09-17T16:33:53.033Z" }, + { url = "https://files.pythonhosted.org/packages/50/76/597e5cb97d026274ba297af8d89138dfd9e695767ba0e0895edb20963f40/debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464", size = 2538386, upload-time = "2025-09-17T16:33:54.594Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/ce5c34fcdfec493701f9d1532dba95b21b2f6394147234dce21160bd923f/debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088", size = 4292100, upload-time = "2025-09-17T16:33:56.353Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/7873cf2146577ef71d2a20bf553f12df865922a6f87b9e8ee1df04f01785/debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83", size = 5277002, upload-time = "2025-09-17T16:33:58.231Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420", size = 5319047, upload-time = "2025-09-17T16:34:00.586Z" }, + { url = "https://files.pythonhosted.org/packages/de/45/115d55b2a9da6de812696064ceb505c31e952c5d89c4ed1d9bb983deec34/debugpy-1.8.17-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1", size = 2536899, upload-time = "2025-09-17T16:34:02.657Z" }, + { url = "https://files.pythonhosted.org/packages/5a/73/2aa00c7f1f06e997ef57dc9b23d61a92120bec1437a012afb6d176585197/debugpy-1.8.17-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f", size = 4268254, upload-time = "2025-09-17T16:34:04.486Z" }, + { url = "https://files.pythonhosted.org/packages/86/b5/ed3e65c63c68a6634e3ba04bd10255c8e46ec16ebed7d1c79e4816d8a760/debugpy-1.8.17-cp314-cp314-win32.whl", hash = "sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670", size = 5277203, upload-time = "2025-09-17T16:34:06.65Z" }, + { url = "https://files.pythonhosted.org/packages/b0/26/394276b71c7538445f29e792f589ab7379ae70fd26ff5577dfde71158e96/debugpy-1.8.17-cp314-cp314-win_amd64.whl", hash = "sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c", size = 5318493, upload-time = "2025-09-17T16:34:08.483Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef", size = 5283210, upload-time = "2025-09-17T16:34:25.835Z" }, +] + +[[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, upload-time = "2025-02-24T04:41:34.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, +] + +[[package]] +name = "einops" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/81/df4fbe24dff8ba3934af99044188e20a98ed441ad17a274539b74e82e126/einops-0.8.1.tar.gz", hash = "sha256:de5d960a7a761225532e0f1959e5315ebeafc0cd43394732f103ca44b9837e84", size = 54805, upload-time = "2025-02-09T03:17:00.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/62/9773de14fe6c45c23649e98b83231fffd7b9892b6cf863251dc2afa73643/einops-0.8.1-py3-none-any.whl", hash = "sha256:919387eb55330f5757c6bea9165c5ff5cfe63a642682ea788a6d472576d81737", size = 64359, upload-time = "2025-02-09T03:17:01.998Z" }, +] + +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[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, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "fonttools" +version = "4.61.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/f9/0e84d593c0e12244150280a630999835a64f2852276161b62a0f98318de0/fonttools-4.61.0.tar.gz", hash = "sha256:ec520a1f0c7758d7a858a00f090c1745f6cde6a7c5e76fb70ea4044a15f712e7", size = 3561884, upload-time = "2025-11-28T17:05:49.491Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/be/5aa89cdddf2863d8afbdc19eb8ec5d8d35d40eeeb8e6cf52c5ff1c2dbd33/fonttools-4.61.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a32a16951cbf113d38f1dd8551b277b6e06e0f6f776fece0f99f746d739e1be3", size = 2847553, upload-time = "2025-11-28T17:04:30.539Z" }, + { url = "https://files.pythonhosted.org/packages/0d/3e/6ff643b07cead1236a534f51291ae2981721cf419135af5b740c002a66dd/fonttools-4.61.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:328a9c227984bebaf69f3ac9062265f8f6acc7ddf2e4e344c63358579af0aa3d", size = 2388298, upload-time = "2025-11-28T17:04:32.161Z" }, + { url = "https://files.pythonhosted.org/packages/c3/15/fca8dfbe7b482e6f240b1aad0ed7c6e2e75e7a28efa3d3a03b570617b5e5/fonttools-4.61.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f0bafc8a3b3749c69cc610e5aa3da832d39c2a37a68f03d18ec9a02ecaac04a", size = 5054133, upload-time = "2025-11-28T17:04:34.035Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a2/821c61c691b21fd09e07528a9a499cc2b075ac83ddb644aa16c9875a64bc/fonttools-4.61.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b5ca59b7417d149cf24e4c1933c9f44b2957424fc03536f132346d5242e0ebe5", size = 5031410, upload-time = "2025-11-28T17:04:36.141Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f6/8b16339e93d03c732c8a23edefe3061b17a5f9107ddc47a3215ecd054cac/fonttools-4.61.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:df8cbce85cf482eb01f4551edca978c719f099c623277bda8332e5dbe7dba09d", size = 5030005, upload-time = "2025-11-28T17:04:38.314Z" }, + { url = "https://files.pythonhosted.org/packages/ac/eb/d4e150427bdaa147755239c931bbce829a88149ade5bfd8a327afe565567/fonttools-4.61.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7fb5b84f48a6a733ca3d7f41aa9551908ccabe8669ffe79586560abcc00a9cfd", size = 5154026, upload-time = "2025-11-28T17:04:40.34Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5f/3dd00ce0dba6759943c707b1830af8c0bcf6f8f1a9fe46cb82e7ac2aaa74/fonttools-4.61.0-cp311-cp311-win32.whl", hash = "sha256:787ef9dfd1ea9fe49573c272412ae5f479d78e671981819538143bec65863865", size = 2276035, upload-time = "2025-11-28T17:04:42.59Z" }, + { url = "https://files.pythonhosted.org/packages/4e/44/798c472f096ddf12955eddb98f4f7c906e7497695d04ce073ddf7161d134/fonttools-4.61.0-cp311-cp311-win_amd64.whl", hash = "sha256:14fafda386377b6131d9e448af42d0926bad47e038de0e5ba1d58c25d621f028", size = 2327290, upload-time = "2025-11-28T17:04:44.57Z" }, + { url = "https://files.pythonhosted.org/packages/00/5d/19e5939f773c7cb05480fe2e881d63870b63ee2b4bdb9a77d55b1d36c7b9/fonttools-4.61.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e24a1565c4e57111ec7f4915f8981ecbb61adf66a55f378fdc00e206059fcfef", size = 2846930, upload-time = "2025-11-28T17:04:46.639Z" }, + { url = "https://files.pythonhosted.org/packages/25/b2/0658faf66f705293bd7e739a4f038302d188d424926be9c59bdad945664b/fonttools-4.61.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2bfacb5351303cae9f072ccf3fc6ecb437a6f359c0606bae4b1ab6715201d87", size = 2383016, upload-time = "2025-11-28T17:04:48.525Z" }, + { url = "https://files.pythonhosted.org/packages/29/a3/1fa90b95b690f0d7541f48850adc40e9019374d896c1b8148d15012b2458/fonttools-4.61.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0bdcf2e29d65c26299cc3d502f4612365e8b90a939f46cd92d037b6cb7bb544a", size = 4949425, upload-time = "2025-11-28T17:04:50.482Z" }, + { url = "https://files.pythonhosted.org/packages/af/00/acf18c00f6c501bd6e05ee930f926186f8a8e268265407065688820f1c94/fonttools-4.61.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6cd0d9051b8ddaf7385f99dd82ec2a058e2b46cf1f1961e68e1ff20fcbb61af", size = 4999632, upload-time = "2025-11-28T17:04:52.508Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e0/19a2b86e54109b1d2ee8743c96a1d297238ae03243897bc5345c0365f34d/fonttools-4.61.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e074bc07c31406f45c418e17c1722e83560f181d122c412fa9e815df0ff74810", size = 4939438, upload-time = "2025-11-28T17:04:54.437Z" }, + { url = "https://files.pythonhosted.org/packages/04/35/7b57a5f57d46286360355eff8d6b88c64ab6331107f37a273a71c803798d/fonttools-4.61.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a9b78da5d5faa17e63b2404b77feeae105c1b7e75f26020ab7a27b76e02039f", size = 5088960, upload-time = "2025-11-28T17:04:56.348Z" }, + { url = "https://files.pythonhosted.org/packages/3e/0e/6c5023eb2e0fe5d1ababc7e221e44acd3ff668781489cc1937a6f83d620a/fonttools-4.61.0-cp312-cp312-win32.whl", hash = "sha256:9821ed77bb676736b88fa87a737c97b6af06e8109667e625a4f00158540ce044", size = 2264404, upload-time = "2025-11-28T17:04:58.149Z" }, + { url = "https://files.pythonhosted.org/packages/36/0b/63273128c7c5df19b1e4cd92e0a1e6ea5bb74a400c4905054c96ad60a675/fonttools-4.61.0-cp312-cp312-win_amd64.whl", hash = "sha256:0011d640afa61053bc6590f9a3394bd222de7cfde19346588beabac374e9d8ac", size = 2314427, upload-time = "2025-11-28T17:04:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/17/45/334f0d7f181e5473cfb757e1b60f4e60e7fc64f28d406e5d364a952718c0/fonttools-4.61.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba774b8cbd8754f54b8eb58124e8bd45f736b2743325ab1a5229698942b9b433", size = 2841801, upload-time = "2025-11-28T17:05:01.621Z" }, + { url = "https://files.pythonhosted.org/packages/cc/63/97b9c78e1f79bc741d4efe6e51f13872d8edb2b36e1b9fb2bab0d4491bb7/fonttools-4.61.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c84b430616ed73ce46e9cafd0bf0800e366a3e02fb7e1ad7c1e214dbe3862b1f", size = 2379024, upload-time = "2025-11-28T17:05:03.668Z" }, + { url = "https://files.pythonhosted.org/packages/4e/80/c87bc524a90dbeb2a390eea23eae448286983da59b7e02c67fa0ca96a8c5/fonttools-4.61.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b2b734d8391afe3c682320840c8191de9bd24e7eb85768dd4dc06ed1b63dbb1b", size = 4923706, upload-time = "2025-11-28T17:05:05.494Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f6/a3b0374811a1de8c3f9207ec88f61ad1bb96f938ed89babae26c065c2e46/fonttools-4.61.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5c5fff72bf31b0e558ed085e4fd7ed96eb85881404ecc39ed2a779e7cf724eb", size = 4979751, upload-time = "2025-11-28T17:05:07.665Z" }, + { url = "https://files.pythonhosted.org/packages/a5/3b/30f63b4308b449091573285f9d27619563a84f399946bca3eadc9554afbe/fonttools-4.61.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:14a290c5c93fcab76b7f451e6a4b7721b712d90b3b5ed6908f1abcf794e90d6d", size = 4921113, upload-time = "2025-11-28T17:05:09.551Z" }, + { url = "https://files.pythonhosted.org/packages/41/6c/58e6e9b7d9d8bf2d7010bd7bb493060b39b02a12d1cda64a8bfb116ce760/fonttools-4.61.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:13e3e20a5463bfeb77b3557d04b30bd6a96a6bb5c15c7b2e7908903e69d437a0", size = 5063183, upload-time = "2025-11-28T17:05:11.677Z" }, + { url = "https://files.pythonhosted.org/packages/3f/e3/52c790ab2b07492df059947a1fd7778e105aac5848c0473029a4d20481a2/fonttools-4.61.0-cp313-cp313-win32.whl", hash = "sha256:6781e7a4bb010be1cd69a29927b0305c86b843395f2613bdabe115f7d6ea7f34", size = 2263159, upload-time = "2025-11-28T17:05:13.292Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1f/116013b200fbeba871046554d5d2a45fefa69a05c40e9cdfd0d4fff53edc/fonttools-4.61.0-cp313-cp313-win_amd64.whl", hash = "sha256:c53b47834ae41e8e4829171cc44fec0fdf125545a15f6da41776b926b9645a9a", size = 2313530, upload-time = "2025-11-28T17:05:14.848Z" }, + { url = "https://files.pythonhosted.org/packages/d3/99/59b1e25987787cb714aa9457cee4c9301b7c2153f0b673e2b8679d37669d/fonttools-4.61.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:96dfc9bc1f2302224e48e6ee37e656eddbab810b724b52e9d9c13a57a6abad01", size = 2841429, upload-time = "2025-11-28T17:05:16.671Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/4c1911d4332c8a144bb3b44416e274ccca0e297157c971ea1b3fbb855590/fonttools-4.61.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3b2065d94e5d63aafc2591c8b6ccbdb511001d9619f1bca8ad39b745ebeb5efa", size = 2378987, upload-time = "2025-11-28T17:05:18.69Z" }, + { url = "https://files.pythonhosted.org/packages/24/b0/f442e90fde5d2af2ae0cb54008ab6411edc557ee33b824e13e1d04925ac9/fonttools-4.61.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0d87e81e4d869549585ba0beb3f033718501c1095004f5e6aef598d13ebc216", size = 4873270, upload-time = "2025-11-28T17:05:20.625Z" }, + { url = "https://files.pythonhosted.org/packages/bb/04/f5d5990e33053c8a59b90b1d7e10ad9b97a73f42c745304da0e709635fab/fonttools-4.61.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1cfa2eb9bae650e58f0e8ad53c49d19a844d6034d6b259f30f197238abc1ccee", size = 4968270, upload-time = "2025-11-28T17:05:22.515Z" }, + { url = "https://files.pythonhosted.org/packages/94/9f/2091402e0d27c9c8c4bab5de0e5cd146d9609a2d7d1c666bbb75c0011c1a/fonttools-4.61.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4238120002e68296d55e091411c09eab94e111c8ce64716d17df53fd0eb3bb3d", size = 4919799, upload-time = "2025-11-28T17:05:24.437Z" }, + { url = "https://files.pythonhosted.org/packages/a8/72/86adab22fde710b829f8ffbc8f264df01928e5b7a8f6177fa29979ebf256/fonttools-4.61.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b6ceac262cc62bec01b3bb59abccf41b24ef6580869e306a4e88b7e56bb4bdda", size = 5030966, upload-time = "2025-11-28T17:05:26.115Z" }, + { url = "https://files.pythonhosted.org/packages/e8/a7/7c8e31b003349e845b853f5e0a67b95ff6b052fa4f5224f8b72624f5ac69/fonttools-4.61.0-cp314-cp314-win32.whl", hash = "sha256:adbb4ecee1a779469a77377bbe490565effe8fce6fb2e6f95f064de58f8bac85", size = 2267243, upload-time = "2025-11-28T17:05:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/20/ee/f434fe7749360497c52b7dcbcfdbccdaab0a71c59f19d572576066717122/fonttools-4.61.0-cp314-cp314-win_amd64.whl", hash = "sha256:02bdf8e04d1a70476564b8640380f04bb4ac74edc1fc71f1bacb840b3e398ee9", size = 2318822, upload-time = "2025-11-28T17:05:29.882Z" }, + { url = "https://files.pythonhosted.org/packages/33/b3/c16255320255e5c1863ca2b2599bb61a46e2f566db0bbb9948615a8fe692/fonttools-4.61.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:627216062d90ab0d98215176d8b9562c4dd5b61271d35f130bcd30f6a8aaa33a", size = 2924917, upload-time = "2025-11-28T17:05:31.46Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b8/08067ae21de705a817777c02ef36ab0b953cbe91d8adf134f9c2da75ed6d/fonttools-4.61.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7b446623c9cd5f14a59493818eaa80255eec2468c27d2c01b56e05357c263195", size = 2413576, upload-time = "2025-11-28T17:05:33.343Z" }, + { url = "https://files.pythonhosted.org/packages/42/f1/96ff43f92addce2356780fdc203f2966206f3d22ea20e242c27826fd7442/fonttools-4.61.0-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:70e2a0c0182ee75e493ef33061bfebf140ea57e035481d2f95aa03b66c7a0e05", size = 4877447, upload-time = "2025-11-28T17:05:35.278Z" }, + { url = "https://files.pythonhosted.org/packages/d0/1e/a3d8e51ed9ccfd7385e239ae374b78d258a0fb82d82cab99160a014a45d1/fonttools-4.61.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9064b0f55b947e929ac669af5311ab1f26f750214db6dd9a0c97e091e918f486", size = 5095681, upload-time = "2025-11-28T17:05:37.142Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f6/d256bd6c1065c146a0bdddf1c62f542e08ae5b3405dbf3fcc52be272f674/fonttools-4.61.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cb5e45a824ce14b90510024d0d39dae51bd4fbb54c42a9334ea8c8cf4d95cbe", size = 4974140, upload-time = "2025-11-28T17:05:39.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0c/96633eb4b26f138cc48561c6e0c44b4ea48acea56b20b507d6b14f8e80ce/fonttools-4.61.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e5ca8c62efdec7972dfdfd454415c4db49b89aeaefaaacada432f3b7eea9866", size = 5001741, upload-time = "2025-11-28T17:05:41.424Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/3b536bad3be4f26186f296e749ff17bad3e6d57232c104d752d24b2e265b/fonttools-4.61.0-cp314-cp314t-win32.whl", hash = "sha256:63c7125d31abe3e61d7bb917329b5543c5b3448db95f24081a13aaf064360fc8", size = 2330707, upload-time = "2025-11-28T17:05:43.548Z" }, + { url = "https://files.pythonhosted.org/packages/18/ea/e6b9ac610451ee9f04477c311ad126de971f6112cb579fa391d2a8edb00b/fonttools-4.61.0-cp314-cp314t-win_amd64.whl", hash = "sha256:67d841aa272be5500de7f447c40d1d8452783af33b4c3599899319f6ef9ad3c1", size = 2395950, upload-time = "2025-11-28T17:05:45.638Z" }, + { url = "https://files.pythonhosted.org/packages/0c/14/634f7daea5ffe6a5f7a0322ba8e1a0e23c9257b80aa91458107896d1dfc7/fonttools-4.61.0-py3-none-any.whl", hash = "sha256:276f14c560e6f98d24ef7f5f44438e55ff5a67f78fa85236b218462c9f5d0635", size = 1144485, upload-time = "2025-11-28T17:05:47.573Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, +] + +[[package]] +name = "hydride" +version = "1.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "biotite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/a2/d600d62ea1f551002503066576cd45a7bc478da1acdc44c8796d5b05dc19/hydride-1.2.3.tar.gz", hash = "sha256:d1d06dcfb4c4957f109bd2445a115021cf69ff7c1639cb3f96961c58b38c6453", size = 293435, upload-time = "2024-11-04T11:37:06.648Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/5c/ad922192c64eada9bba98bd3a9255faf4faae78adfd4537d11eb2ed1b8e3/hydride-1.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b249a18109d60ce990c0a47d07620863dfe3f23495aa1e04ca15e9e086ffc9e", size = 452841, upload-time = "2024-11-04T11:36:52.47Z" }, + { url = "https://files.pythonhosted.org/packages/93/ec/0894ec1e38266e183db3e5ac148d7bddab4fda2f25447ec13716ec05d8fe/hydride-1.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f6ef6875d6f720de694fe53254648e886c83681d05fe4988a823a2dbd06d38fb", size = 441244, upload-time = "2024-11-04T11:36:53.951Z" }, + { url = "https://files.pythonhosted.org/packages/ed/28/c52153387c6efa7ac7d9c3c5df068aa686d8468c797f9a045d0993c77913/hydride-1.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c196b287c7dd6ceb6e98d52aec1f8755f9bd641146b55a3236bae58c48ddf6be", size = 1196593, upload-time = "2024-11-04T11:36:55.093Z" }, + { url = "https://files.pythonhosted.org/packages/ff/5a/2c72655c2554840081d61b5680a067f4b8c1bc746032ab8f355846aeb750/hydride-1.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:6220f9159bcb1a5e985382dff5d25fcf0c848896190265d4d43a0252a039691e", size = 425532, upload-time = "2024-11-04T11:36:56.907Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fb/6163b0f4f6b89daa9045bf15fd2546ce43e717614116a477c7a40b7d73b7/hydride-1.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3884f4969f2df7237e5bc8c82e47026b6c4ba91de3bbc546b5ac938b4365bac5", size = 451179, upload-time = "2024-11-04T11:36:58.665Z" }, + { url = "https://files.pythonhosted.org/packages/87/23/409e5c2b1cfaf918c4d9c84d7a3a9f930e293e05affc6b5d020d08b0a9de/hydride-1.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b7221eceb732539e42419c6612e5f9c6a33074ad0547e5048d0d5c38a23734c", size = 440277, upload-time = "2024-11-04T11:37:00.204Z" }, + { url = "https://files.pythonhosted.org/packages/73/d4/7ca768b20e6d62ee0c967c3e770ca9bf720b396f03111ccaf230e94a023c/hydride-1.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ecdf1cebe6042549fa4580ee829670c472563a8b66b25cb74c48d4e0f1e2d2", size = 1186352, upload-time = "2024-11-04T11:37:04.144Z" }, + { url = "https://files.pythonhosted.org/packages/a4/2e/9095f2ba3da50db53e21db7d93a85e8f96c0ebb7eb43f375e81596f46e32/hydride-1.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:051de12202d675e551b741e9f1734f375b504bd63486c5aa8b565f89d20c444d", size = 422029, upload-time = "2024-11-04T11:37:05.247Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026, upload-time = "2022-07-01T12:21:05.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, +] + +[[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, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "ipykernel" +version = "7.1.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/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, +] + +[[package]] +name = "ipython" +version = "9.8.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 = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/51/a703c030f4928646d390b4971af4938a1b10c9dfce694f0d99a0bb073cb2/ipython-9.8.0.tar.gz", hash = "sha256:8e4ce129a627eb9dd221c41b1d2cdaed4ef7c9da8c17c63f6f578fe231141f83", size = 4424940, upload-time = "2025-12-03T10:18:24.353Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/df/8ee1c5dd1e3308b5d5b2f2dfea323bb2f3827da8d654abb6642051199049/ipython-9.8.0-py3-none-any.whl", hash = "sha256:ebe6d1d58d7d988fbf23ff8ff6d8e1622cfdb194daf4b7b73b792c4ec3b85385", size = 621374, upload-time = "2025-12-03T10:18:22.335Z" }, +] + +[[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, upload-time = "2025-01-17T11:24:34.505Z" } +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, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "jaxtyping" +version = "0.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wadler-lindig" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/1e/827f9e17b26e21c7d4d934fd1a214284ad05663afedd37c21ed105db366b/jaxtyping-0.3.3.tar.gz", hash = "sha256:8003cfd16ba2ad9b47fdda1d982a575299a81ddfc7997ad0e917c87a0897ea86", size = 45484, upload-time = "2025-10-01T13:46:51.933Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/97/88264b1af140f66ba7ca6eb2f3a108be233ee278bb3f1d5c750243e7458a/jaxtyping-0.3.3-py3-none-any.whl", hash = "sha256:a1c2f0f4351a8deda84b0e3b5c5a50894a1cdae2b82d841279fce4393aff4a7c", size = 55926, upload-time = "2025-10-01T13:46:50.621Z" }, +] + +[[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, upload-time = "2024-11-11T01:41:42.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, +] + +[[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, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.7.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/a6/27/d10de45e8ad4ce872372c4a3a37b7b35b6b064f6f023a5c14ffcced4d59d/jupyter_client-8.7.0.tar.gz", hash = "sha256:3357212d9cbe01209e59190f67a3a7e1f387a4f4e88d1e0433ad84d7b262531d", size = 344691, upload-time = "2025-12-09T18:37:01.953Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f5/fddaec430367be9d62a7ed125530e133bfd4a1c0350fe221149ee0f2b526/jupyter_client-8.7.0-py3-none-any.whl", hash = "sha256:3671a94fd25e62f5f2f554f5e95389c2294d89822378a5f2dd24353e1494a9e0", size = 106215, upload-time = "2025-12-09T18:37:00.024Z" }, +] + +[[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, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.4.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/ab/c80b0d5a9d8a1a65f4f815f2afff9798b12c3b9f31f1d304dd233dd920e2/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16", size = 124167, upload-time = "2025-08-10T21:25:53.403Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089", size = 66579, upload-time = "2025-08-10T21:25:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543", size = 65309, upload-time = "2025-08-10T21:25:55.76Z" }, + { url = "https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61", size = 1435596, upload-time = "2025-08-10T21:25:56.861Z" }, + { url = "https://files.pythonhosted.org/packages/67/1e/51b73c7347f9aabdc7215aa79e8b15299097dc2f8e67dee2b095faca9cb0/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1", size = 1246548, upload-time = "2025-08-10T21:25:58.246Z" }, + { url = "https://files.pythonhosted.org/packages/21/aa/72a1c5d1e430294f2d32adb9542719cfb441b5da368d09d268c7757af46c/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872", size = 1263618, upload-time = "2025-08-10T21:25:59.857Z" }, + { url = "https://files.pythonhosted.org/packages/a3/af/db1509a9e79dbf4c260ce0cfa3903ea8945f6240e9e59d1e4deb731b1a40/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26", size = 1317437, upload-time = "2025-08-10T21:26:01.105Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f2/3ea5ee5d52abacdd12013a94130436e19969fa183faa1e7c7fbc89e9a42f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028", size = 2195742, upload-time = "2025-08-10T21:26:02.675Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9b/1efdd3013c2d9a2566aa6a337e9923a00590c516add9a1e89a768a3eb2fc/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771", size = 2290810, upload-time = "2025-08-10T21:26:04.009Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e5/cfdc36109ae4e67361f9bc5b41323648cb24a01b9ade18784657e022e65f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a", size = 2461579, upload-time = "2025-08-10T21:26:05.317Z" }, + { url = "https://files.pythonhosted.org/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload-time = "2025-08-10T21:26:06.686Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload-time = "2025-08-10T21:26:07.94Z" }, + { url = "https://files.pythonhosted.org/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload-time = "2025-08-10T21:26:09.048Z" }, + { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" }, + { url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" }, + { url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" }, + { url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" }, + { url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" }, + { url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" }, + { url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" }, + { url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" }, + { url = "https://files.pythonhosted.org/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload-time = "2025-08-10T21:26:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload-time = "2025-08-10T21:26:27.733Z" }, + { url = "https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload-time = "2025-08-10T21:26:28.729Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload-time = "2025-08-10T21:26:29.798Z" }, + { url = "https://files.pythonhosted.org/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload-time = "2025-08-10T21:26:31.401Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload-time = "2025-08-10T21:26:32.721Z" }, + { url = "https://files.pythonhosted.org/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload-time = "2025-08-10T21:26:34.032Z" }, + { url = "https://files.pythonhosted.org/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload-time = "2025-08-10T21:26:35.824Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload-time = "2025-08-10T21:26:37.534Z" }, + { url = "https://files.pythonhosted.org/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload-time = "2025-08-10T21:26:39.191Z" }, + { url = "https://files.pythonhosted.org/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload-time = "2025-08-10T21:26:40.828Z" }, + { url = "https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload-time = "2025-08-10T21:26:42.33Z" }, + { url = "https://files.pythonhosted.org/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload-time = "2025-08-10T21:26:43.889Z" }, + { url = "https://files.pythonhosted.org/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload-time = "2025-08-10T21:26:44.915Z" }, + { url = "https://files.pythonhosted.org/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload-time = "2025-08-10T21:26:45.934Z" }, + { url = "https://files.pythonhosted.org/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload-time = "2025-08-10T21:26:47.101Z" }, + { url = "https://files.pythonhosted.org/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload-time = "2025-08-10T21:26:48.665Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload-time = "2025-08-10T21:26:50.335Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload-time = "2025-08-10T21:26:51.867Z" }, + { url = "https://files.pythonhosted.org/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload-time = "2025-08-10T21:26:53.592Z" }, + { url = "https://files.pythonhosted.org/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload-time = "2025-08-10T21:26:55.051Z" }, + { url = "https://files.pythonhosted.org/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload-time = "2025-08-10T21:26:56.421Z" }, + { url = "https://files.pythonhosted.org/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload-time = "2025-08-10T21:26:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload-time = "2025-08-10T21:26:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload-time = "2025-08-10T21:27:00.52Z" }, + { url = "https://files.pythonhosted.org/packages/6b/32/6cc0fbc9c54d06c2969faa9c1d29f5751a2e51809dd55c69055e62d9b426/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386", size = 123806, upload-time = "2025-08-10T21:27:01.537Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/2bfb1d4a4823d92e8cbb420fe024b8d2167f72079b3bb941207c42570bdf/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552", size = 66605, upload-time = "2025-08-10T21:27:03.335Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/00aafdb4e4509c2ca6064646cba9cd4b37933898f426756adb2cb92ebbed/kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3", size = 64925, upload-time = "2025-08-10T21:27:04.339Z" }, + { url = "https://files.pythonhosted.org/packages/43/dc/51acc6791aa14e5cb6d8a2e28cefb0dc2886d8862795449d021334c0df20/kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58", size = 1472414, upload-time = "2025-08-10T21:27:05.437Z" }, + { url = "https://files.pythonhosted.org/packages/3d/bb/93fa64a81db304ac8a246f834d5094fae4b13baf53c839d6bb6e81177129/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4", size = 1281272, upload-time = "2025-08-10T21:27:07.063Z" }, + { url = "https://files.pythonhosted.org/packages/70/e6/6df102916960fb8d05069d4bd92d6d9a8202d5a3e2444494e7cd50f65b7a/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df", size = 1298578, upload-time = "2025-08-10T21:27:08.452Z" }, + { url = "https://files.pythonhosted.org/packages/7c/47/e142aaa612f5343736b087864dbaebc53ea8831453fb47e7521fa8658f30/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6", size = 1345607, upload-time = "2025-08-10T21:27:10.125Z" }, + { url = "https://files.pythonhosted.org/packages/54/89/d641a746194a0f4d1a3670fb900d0dbaa786fb98341056814bc3f058fa52/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5", size = 2230150, upload-time = "2025-08-10T21:27:11.484Z" }, + { url = "https://files.pythonhosted.org/packages/aa/6b/5ee1207198febdf16ac11f78c5ae40861b809cbe0e6d2a8d5b0b3044b199/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf", size = 2325979, upload-time = "2025-08-10T21:27:12.917Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ff/b269eefd90f4ae14dcc74973d5a0f6d28d3b9bb1afd8c0340513afe6b39a/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5", size = 2491456, upload-time = "2025-08-10T21:27:14.353Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d4/10303190bd4d30de547534601e259a4fbf014eed94aae3e5521129215086/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce", size = 2294621, upload-time = "2025-08-10T21:27:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/28/e0/a9a90416fce5c0be25742729c2ea52105d62eda6c4be4d803c2a7be1fa50/kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7", size = 75417, upload-time = "2025-08-10T21:27:17.436Z" }, + { url = "https://files.pythonhosted.org/packages/1f/10/6949958215b7a9a264299a7db195564e87900f709db9245e4ebdd3c70779/kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c", size = 66582, upload-time = "2025-08-10T21:27:18.436Z" }, + { url = "https://files.pythonhosted.org/packages/ec/79/60e53067903d3bc5469b369fe0dfc6b3482e2133e85dae9daa9527535991/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548", size = 126514, upload-time = "2025-08-10T21:27:19.465Z" }, + { url = "https://files.pythonhosted.org/packages/25/d1/4843d3e8d46b072c12a38c97c57fab4608d36e13fe47d47ee96b4d61ba6f/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d", size = 67905, upload-time = "2025-08-10T21:27:20.51Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ae/29ffcbd239aea8b93108de1278271ae764dfc0d803a5693914975f200596/kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c", size = 66399, upload-time = "2025-08-10T21:27:21.496Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ae/d7ba902aa604152c2ceba5d352d7b62106bedbccc8e95c3934d94472bfa3/kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122", size = 1582197, upload-time = "2025-08-10T21:27:22.604Z" }, + { url = "https://files.pythonhosted.org/packages/f2/41/27c70d427eddb8bc7e4f16420a20fefc6f480312122a59a959fdfe0445ad/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64", size = 1390125, upload-time = "2025-08-10T21:27:24.036Z" }, + { url = "https://files.pythonhosted.org/packages/41/42/b3799a12bafc76d962ad69083f8b43b12bf4fe78b097b12e105d75c9b8f1/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134", size = 1402612, upload-time = "2025-08-10T21:27:25.773Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b5/a210ea073ea1cfaca1bb5c55a62307d8252f531beb364e18aa1e0888b5a0/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370", size = 1453990, upload-time = "2025-08-10T21:27:27.089Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ce/a829eb8c033e977d7ea03ed32fb3c1781b4fa0433fbadfff29e39c676f32/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21", size = 2331601, upload-time = "2025-08-10T21:27:29.343Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4b/b5e97eb142eb9cd0072dacfcdcd31b1c66dc7352b0f7c7255d339c0edf00/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a", size = 2422041, upload-time = "2025-08-10T21:27:30.754Z" }, + { url = "https://files.pythonhosted.org/packages/40/be/8eb4cd53e1b85ba4edc3a9321666f12b83113a178845593307a3e7891f44/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f", size = 2594897, upload-time = "2025-08-10T21:27:32.803Z" }, + { url = "https://files.pythonhosted.org/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload-time = "2025-08-10T21:27:34.23Z" }, + { url = "https://files.pythonhosted.org/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload-time = "2025-08-10T21:27:35.587Z" }, + { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" }, + { url = "https://files.pythonhosted.org/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload-time = "2025-08-10T21:27:43.287Z" }, + { url = "https://files.pythonhosted.org/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload-time = "2025-08-10T21:27:44.314Z" }, + { url = "https://files.pythonhosted.org/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload-time = "2025-08-10T21:27:45.369Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/dbd2ecdce306f1d07a1aaf324817ee993aab7aee9db47ceac757deabafbe/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f", size = 78009, upload-time = "2025-08-10T21:27:46.376Z" }, + { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" }, +] + +[[package]] +name = "lmdb" +version = "1.7.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/a3/3756f2c6adba4a1413dba55e6c81a20b38a868656517308533e33cb59e1c/lmdb-1.7.5.tar.gz", hash = "sha256:f0604751762cb097059d5412444c4057b95f386c7ed958363cf63f453e5108da", size = 883490, upload-time = "2025-10-15T03:39:44.038Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/65/7a5776ae6b32e7a752c6df8112c8f9ae7f97d22d381c62a240fc464bc79c/lmdb-1.7.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b1a1be54f8c89f979c22c30b98ccb5d9478acdc9a0acb37f9a374a5adfd82e4b", size = 100773, upload-time = "2025-10-15T03:38:54.117Z" }, + { url = "https://files.pythonhosted.org/packages/60/93/ac197909df7bb7842d2d8020accea674e75ad70ddfabfbab2c9703241c58/lmdb-1.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:01907a5e9346d58fe29651f44119fe3aa33e1b248bb2ac27b48289cdfb552e68", size = 99294, upload-time = "2025-10-15T03:38:55.109Z" }, + { url = "https://files.pythonhosted.org/packages/95/4b/e0230ed03233732e5e87d6ebc0bd4e3a6ba463e33f3e1bc9d953e19ec765/lmdb-1.7.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bb5d820d528dc1ec73e5e4b6c8d9d54103779256d504c1a84261ca944e749160", size = 294350, upload-time = "2025-10-15T03:38:56.162Z" }, + { url = "https://files.pythonhosted.org/packages/b8/96/53cf72032516fd77b94ccbc00c92e58a220f5d9f7295672bc13e62e3adb6/lmdb-1.7.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:716c93d170be22630e2e560c67081f80095b951b32de032a876b9c20dff8cc07", size = 295126, upload-time = "2025-10-15T03:38:57.306Z" }, + { url = "https://files.pythonhosted.org/packages/02/4d/af393c476a630331d6b5fb27ed5fac20f1597c8dcef877f5ddcccc58b4e5/lmdb-1.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:2e0d17e917011fb303ece772e64adcbad409aea8ff4c53806511a6283290ae18", size = 99277, upload-time = "2025-10-15T03:38:58.428Z" }, + { url = "https://files.pythonhosted.org/packages/54/a9/82e506906f3fd7c12de97ac64f3b33f45fc8091ec6c915f58eb7660491bb/lmdb-1.7.5-cp311-cp311-win_arm64.whl", hash = "sha256:e6adff25d298df9bc1c9b9e9625a126d3b9e0c6b86c1d633d1a82152bcaf0afe", size = 94127, upload-time = "2025-10-15T03:38:59.789Z" }, + { url = "https://files.pythonhosted.org/packages/34/b4/8b862c4d7fd6f68cb33e2a919169fda8924121dc5ff61e3cc105304a6dd4/lmdb-1.7.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b48c2359eea876d7b634b49f84019ecc8c1626da97c795fc7b39a793676815df", size = 100910, upload-time = "2025-10-15T03:39:00.727Z" }, + { url = "https://files.pythonhosted.org/packages/27/64/8ab5da48180d5f13a293ea00a9f8758b1bee080e76ea0ab0d6be0d51b55f/lmdb-1.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f84793baeb430ba984eb6c1b4e08c0a508b1c03e79ce79fcda0f29ecc06a95a", size = 99376, upload-time = "2025-10-15T03:39:01.791Z" }, + { url = "https://files.pythonhosted.org/packages/43/e0/51bc942fe5ed3fce69c631b54f52d97785de3d94487376139be6de1e199a/lmdb-1.7.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68cc21314a33faac1b749645a976b7655e7fa7cc104a72365d2429d2db7f6342", size = 298556, upload-time = "2025-10-15T03:39:02.787Z" }, + { url = "https://files.pythonhosted.org/packages/66/c5/19ea75c88b91d12da5c6f4bbe2aca633047b6b270fd613d557583d32cc5c/lmdb-1.7.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f2d9b7e102fcfe5e0cfb3acdebd403eb55ccbe5f7202d8f49d60bdafb1546d1e", size = 299449, upload-time = "2025-10-15T03:39:03.903Z" }, + { url = "https://files.pythonhosted.org/packages/1b/74/365194203dbff47d3a1621366d6a1133cdcce261f4ac0e1d0496f01e6ace/lmdb-1.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:69de89cc79e03e191fc6f95797f1bef91b45c415d1ea9d38872b00b2d989a50f", size = 99328, upload-time = "2025-10-15T03:39:04.949Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3a/a441afebff5bd761f7f58d194fed7ac265279964957479a5c8a51c42f9ad/lmdb-1.7.5-cp312-cp312-win_arm64.whl", hash = "sha256:0c880ee4b309e900f2d58a710701f5e6316a351878588c6a95a9c0bcb640680b", size = 94191, upload-time = "2025-10-15T03:39:05.975Z" }, + { url = "https://files.pythonhosted.org/packages/38/f8/03275084218eacdbdf7e185d693e1db4cb79c35d18fac47fa0d388522a0d/lmdb-1.7.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:66ae02fa6179e46bb69fe446b7e956afe8706ae17ec1d4cd9f7056e161019156", size = 101508, upload-time = "2025-10-15T03:39:07.228Z" }, + { url = "https://files.pythonhosted.org/packages/20/b9/bc33ae2e4940359ba2fc412e6a755a2f126bc5062b4aaf35edd3a791f9a5/lmdb-1.7.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf65c573311ac8330c7908257f76b28ae3576020123400a81a6b650990dc028c", size = 100105, upload-time = "2025-10-15T03:39:08.491Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f6/22f84b776a64d3992f052ecb637c35f1764a39df4f2190ecc5a3a1295bd7/lmdb-1.7.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97bcb3fc12841a8828db918e494fe0fd016a73d2680ad830d75719bb3bf4e76a", size = 301500, upload-time = "2025-10-15T03:39:09.463Z" }, + { url = "https://files.pythonhosted.org/packages/2a/4d/8e6be8d7d5a30d47fa0ce4b55e3a8050ad689556e6e979d206b4ac67b733/lmdb-1.7.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:865f374f6206ab4aacb92ffb1dc612ee1a31a421db7c89733abe06b81ac87cb0", size = 302285, upload-time = "2025-10-15T03:39:10.856Z" }, + { url = "https://files.pythonhosted.org/packages/5e/dc/7e04fb31a8f88951db81ac677e3ccb3e09248eda40e6ad52f74fd9370c32/lmdb-1.7.5-cp313-cp313-win_amd64.whl", hash = "sha256:82a04d5ca2a6a799c8db7f209354c48aebb49ff338530f5813721fc4c68e4450", size = 99447, upload-time = "2025-10-15T03:39:12.151Z" }, + { url = "https://files.pythonhosted.org/packages/5b/50/e3f97efab17b3fad4afde99b3c957ecac4ffbefada6874a57ad0c695660a/lmdb-1.7.5-cp313-cp313-win_arm64.whl", hash = "sha256:0ad85a15acbfe8a42fdef92ee5e869610286d38507e976755f211be0fc905ca7", size = 94145, upload-time = "2025-10-15T03:39:13.461Z" }, + { url = "https://files.pythonhosted.org/packages/b9/03/4db578e0031fc4991b6e26ba023123d47a7f85614927cddc60c9c0e68249/lmdb-1.7.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f7407ad1c02fba22d0f9b68e40fef0099992fe0ec4ab0ab0ccbe69f4ffea2f61", size = 101626, upload-time = "2025-10-15T03:39:14.386Z" }, + { url = "https://files.pythonhosted.org/packages/d1/79/e3572dd9f04eb9c68066ba158ea4f32754728882a6f2e7891cdb5b41691e/lmdb-1.7.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7553ef5fa6ffa5c7476b5d9a2415137b6b05a7456d1c94b51630d89e89e1c21", size = 100221, upload-time = "2025-10-15T03:39:15.653Z" }, + { url = "https://files.pythonhosted.org/packages/c3/4b/af08cf9930afa504011b73c4470788f63a2d1500f413c4d88e12d9f07194/lmdb-1.7.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cef75c5a21cb6fa53e766396ab71b0d10efbedd61e80018666cd26ee099f1c13", size = 301179, upload-time = "2025-10-15T03:39:16.995Z" }, + { url = "https://files.pythonhosted.org/packages/28/5a/ff0cb35519e991dd1737e45d50e16e356b49c4c6d5de3f8915644f9f667d/lmdb-1.7.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f201190ce528bf6e6ce564dae56bc235358df83099a55a9ec3f5f9c2e97d50d6", size = 303089, upload-time = "2025-10-15T03:39:18.369Z" }, + { url = "https://files.pythonhosted.org/packages/c6/49/a9bd905b4aaf71e251175f66d84235a777b349ef6e7c74d0d9f1eb8cd8ba/lmdb-1.7.5-cp314-cp314-win_amd64.whl", hash = "sha256:4121908b2a635aac71c9ca80a45233829223d07d0265801f629c3bd275d1614c", size = 101159, upload-time = "2025-10-15T03:39:19.516Z" }, + { url = "https://files.pythonhosted.org/packages/06/a9/1d26d67c78f154d954b8af49045b5cae587b5209b82c0fe49ce1a6f3f0db/lmdb-1.7.5-cp314-cp314-win_arm64.whl", hash = "sha256:8ee77e98ae968d29d254b0b609708aa03b1277ceb4d95711495faf9993e755a9", size = 96439, upload-time = "2025-10-15T03:39:20.502Z" }, + { url = "https://files.pythonhosted.org/packages/5b/41/0ab869d5fcfbc52a6eef3728a787d84a207c6b931cfa954c07495e7928e3/lmdb-1.7.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:db041344512fa8b7c78dcb97fd5d01ffd280bf408a400db6934688ff4216aed5", size = 102816, upload-time = "2025-10-15T03:39:21.788Z" }, + { url = "https://files.pythonhosted.org/packages/9b/0f/11ab447366d55f2d5ae7f70e8cbb1b84501fdea455a5dd1c382abaa03852/lmdb-1.7.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:484b3ff676a78f7a33aaeca35e273634a093da282e0eb0a9e9c4f69cfe28d702", size = 101136, upload-time = "2025-10-15T03:39:23.078Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8d/b02f5d7b6ea08dfa847bb27c839d98e248ed5bb7f6211731dece78526ee9/lmdb-1.7.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a73e8b7a748c0bbfeecf7d9be19da1d207736f7d613102c364512674390e6189", size = 321282, upload-time = "2025-10-15T03:39:24.085Z" }, + { url = "https://files.pythonhosted.org/packages/ab/55/31f2b31ab67f5af46121f2fbb123f97bdf01677af30320e3740a751d0961/lmdb-1.7.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0beb884f9af290efade5043899fc60a0b2b7c64fd1c2fde663cf584f7953fd7", size = 320360, upload-time = "2025-10-15T03:39:25.231Z" }, + { url = "https://files.pythonhosted.org/packages/4e/b5/8e762c972817669967146425fcd34bedaa169badda8ae7a1fbf630ef9ec5/lmdb-1.7.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8770d57233853eaa6ccc16b0ff885f7b7af0c2618a5f0cc3e90370b78a4399a", size = 100947, upload-time = "2025-10-15T03:39:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c0/dc66cd1981de260ce14815a6821e33caf9003c206f43d50ae09052edb311/lmdb-1.7.5-cp314-cp314t-win_arm64.whl", hash = "sha256:742ed8fba936a10d13c72e5b168736c3d51656bd7b054d931daea17bcfcd7b41", size = 96895, upload-time = "2025-10-15T03:39:27.685Z" }, + { url = "https://files.pythonhosted.org/packages/bd/2c/982cb5afed533d0cb8038232b40c19b5b85a2d887dec74dfd39e8351ef4b/lmdb-1.7.5-py3-none-any.whl", hash = "sha256:fc344bb8bc0786c87c4ccb19b31f09a38c08bd159ada6f037d669426fea06f03", size = 148539, upload-time = "2025-10-15T03:39:42.982Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[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, upload-time = "2025-09-27T18:37:40.426Z" } +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, upload-time = "2025-09-27T18:36:18.185Z" }, + { 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, upload-time = "2025-09-27T18:36:19.444Z" }, + { 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, upload-time = "2025-09-27T18:36:20.768Z" }, + { 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, upload-time = "2025-09-27T18:36:22.249Z" }, + { 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, upload-time = "2025-09-27T18:36:23.535Z" }, + { 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, upload-time = "2025-09-27T18:36:24.823Z" }, + { 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, upload-time = "2025-09-27T18:36:25.95Z" }, + { 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, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { 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, upload-time = "2025-09-27T18:36:30.854Z" }, + { 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, upload-time = "2025-09-27T18:36:31.971Z" }, + { 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, upload-time = "2025-09-27T18:36:32.813Z" }, + { 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, upload-time = "2025-09-27T18:36:33.86Z" }, + { 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, upload-time = "2025-09-27T18:36:35.099Z" }, + { 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, upload-time = "2025-09-27T18:36:36.001Z" }, + { 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, upload-time = "2025-09-27T18:36:36.906Z" }, + { 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, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { 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, upload-time = "2025-09-27T18:36:41.777Z" }, + { 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, upload-time = "2025-09-27T18:36:43.257Z" }, + { 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, upload-time = "2025-09-27T18:36:44.508Z" }, + { 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, upload-time = "2025-09-27T18:36:45.385Z" }, + { 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, upload-time = "2025-09-27T18:36:46.916Z" }, + { 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, upload-time = "2025-09-27T18:36:47.884Z" }, + { 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, upload-time = "2025-09-27T18:36:48.82Z" }, + { 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, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { 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, upload-time = "2025-09-27T18:36:54.819Z" }, + { 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, upload-time = "2025-09-27T18:36:55.714Z" }, + { 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, upload-time = "2025-09-27T18:36:56.908Z" }, + { 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, upload-time = "2025-09-27T18:36:57.913Z" }, + { 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, upload-time = "2025-09-27T18:36:58.833Z" }, + { 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, upload-time = "2025-09-27T18:36:59.739Z" }, + { 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, upload-time = "2025-09-27T18:37:00.719Z" }, + { 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, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { 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, upload-time = "2025-09-27T18:37:06.342Z" }, + { 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, upload-time = "2025-09-27T18:37:07.213Z" }, + { 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, upload-time = "2025-09-27T18:37:09.572Z" }, + { 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, upload-time = "2025-09-27T18:37:10.58Z" }, + { 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, upload-time = "2025-09-27T18:37:11.547Z" }, + { 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, upload-time = "2025-09-27T18:37:12.48Z" }, + { 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, upload-time = "2025-09-27T18:37:13.485Z" }, + { 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, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { 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, upload-time = "2025-09-27T18:37:18.453Z" }, + { 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, upload-time = "2025-09-27T18:37:19.332Z" }, + { 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, upload-time = "2025-09-27T18:37:20.245Z" }, + { 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, upload-time = "2025-09-27T18:37:21.177Z" }, + { 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, upload-time = "2025-09-27T18:37:22.167Z" }, + { 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, upload-time = "2025-09-27T18:37:23.296Z" }, + { 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, upload-time = "2025-09-27T18:37:24.237Z" }, + { 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, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.10.7" +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/ae/e2/d2d5295be2f44c678ebaf3544ba32d20c1f9ef08c49fe47f496180e1db15/matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7", size = 34804865, upload-time = "2025-10-09T00:28:00.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/bc/0fb489005669127ec13f51be0c6adc074d7cf191075dab1da9fe3b7a3cfc/matplotlib-3.10.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:53b492410a6cd66c7a471de6c924f6ede976e963c0f3097a3b7abfadddc67d0a", size = 8257507, upload-time = "2025-10-09T00:26:19.073Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6a/d42588ad895279ff6708924645b5d2ed54a7fb2dc045c8a804e955aeace1/matplotlib-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9749313deb729f08207718d29c86246beb2ea3fdba753595b55901dee5d2fd6", size = 8119565, upload-time = "2025-10-09T00:26:21.023Z" }, + { url = "https://files.pythonhosted.org/packages/10/b7/4aa196155b4d846bd749cf82aa5a4c300cf55a8b5e0dfa5b722a63c0f8a0/matplotlib-3.10.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2222c7ba2cbde7fe63032769f6eb7e83ab3227f47d997a8453377709b7fe3a5a", size = 8692668, upload-time = "2025-10-09T00:26:22.967Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e7/664d2b97016f46683a02d854d730cfcf54ff92c1dafa424beebef50f831d/matplotlib-3.10.7-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e91f61a064c92c307c5a9dc8c05dc9f8a68f0a3be199d9a002a0622e13f874a1", size = 9521051, upload-time = "2025-10-09T00:26:25.041Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a3/37aef1404efa615f49b5758a5e0261c16dd88f389bc1861e722620e4a754/matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc", size = 9576878, upload-time = "2025-10-09T00:26:27.478Z" }, + { url = "https://files.pythonhosted.org/packages/33/cd/b145f9797126f3f809d177ca378de57c45413c5099c5990de2658760594a/matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e", size = 8115142, upload-time = "2025-10-09T00:26:29.774Z" }, + { url = "https://files.pythonhosted.org/packages/2e/39/63bca9d2b78455ed497fcf51a9c71df200a11048f48249038f06447fa947/matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9", size = 7992439, upload-time = "2025-10-09T00:26:40.32Z" }, + { url = "https://files.pythonhosted.org/packages/be/b3/09eb0f7796932826ec20c25b517d568627754f6c6462fca19e12c02f2e12/matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748", size = 8272389, upload-time = "2025-10-09T00:26:42.474Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/1ae80ddafb8652fd8046cb5c8460ecc8d4afccb89e2c6d6bec61e04e1eaf/matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f", size = 8128247, upload-time = "2025-10-09T00:26:44.77Z" }, + { url = "https://files.pythonhosted.org/packages/7d/18/95ae2e242d4a5c98bd6e90e36e128d71cf1c7e39b0874feaed3ef782e789/matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0", size = 8696996, upload-time = "2025-10-09T00:26:46.792Z" }, + { url = "https://files.pythonhosted.org/packages/7e/3d/5b559efc800bd05cb2033aa85f7e13af51958136a48327f7c261801ff90a/matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695", size = 9530153, upload-time = "2025-10-09T00:26:49.07Z" }, + { url = "https://files.pythonhosted.org/packages/88/57/eab4a719fd110312d3c220595d63a3c85ec2a39723f0f4e7fa7e6e3f74ba/matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65", size = 9593093, upload-time = "2025-10-09T00:26:51.067Z" }, + { url = "https://files.pythonhosted.org/packages/31/3c/80816f027b3a4a28cd2a0a6ef7f89a2db22310e945cd886ec25bfb399221/matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee", size = 8122771, upload-time = "2025-10-09T00:26:53.296Z" }, + { url = "https://files.pythonhosted.org/packages/de/77/ef1fc78bfe99999b2675435cc52120887191c566b25017d78beaabef7f2d/matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8", size = 7992812, upload-time = "2025-10-09T00:26:54.882Z" }, + { url = "https://files.pythonhosted.org/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f", size = 8273212, upload-time = "2025-10-09T00:26:56.752Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c", size = 8128713, upload-time = "2025-10-09T00:26:59.001Z" }, + { url = "https://files.pythonhosted.org/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1", size = 8698527, upload-time = "2025-10-09T00:27:00.69Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7f/ccdca06f4c2e6c7989270ed7829b8679466682f4cfc0f8c9986241c023b6/matplotlib-3.10.7-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22df30ffaa89f6643206cf13877191c63a50e8f800b038bc39bee9d2d4957632", size = 9529690, upload-time = "2025-10-09T00:27:02.664Z" }, + { url = "https://files.pythonhosted.org/packages/b8/95/b80fc2c1f269f21ff3d193ca697358e24408c33ce2b106a7438a45407b63/matplotlib-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b69676845a0a66f9da30e87f48be36734d6748024b525ec4710be40194282c84", size = 9593732, upload-time = "2025-10-09T00:27:04.653Z" }, + { url = "https://files.pythonhosted.org/packages/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815", size = 8122727, upload-time = "2025-10-09T00:27:06.814Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a6/2faaf48133b82cf3607759027f82b5c702aa99cdfcefb7f93d6ccf26a424/matplotlib-3.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:fba2974df0bf8ce3c995fa84b79cde38326e0f7b5409e7a3a481c1141340bcf7", size = 7992958, upload-time = "2025-10-09T00:27:08.567Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f0/b018fed0b599bd48d84c08794cb242227fe3341952da102ee9d9682db574/matplotlib-3.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:932c55d1fa7af4423422cb6a492a31cbcbdbe68fd1a9a3f545aa5e7a143b5355", size = 8316849, upload-time = "2025-10-09T00:27:10.254Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b7/bb4f23856197659f275e11a2a164e36e65e9b48ea3e93c4ec25b4f163198/matplotlib-3.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e38c2d581d62ee729a6e144c47a71b3f42fb4187508dbbf4fe71d5612c3433b", size = 8178225, upload-time = "2025-10-09T00:27:12.241Z" }, + { url = "https://files.pythonhosted.org/packages/62/56/0600609893ff277e6f3ab3c0cef4eafa6e61006c058e84286c467223d4d5/matplotlib-3.10.7-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:786656bb13c237bbcebcd402f65f44dd61ead60ee3deb045af429d889c8dbc67", size = 8711708, upload-time = "2025-10-09T00:27:13.879Z" }, + { url = "https://files.pythonhosted.org/packages/d8/1a/6bfecb0cafe94d6658f2f1af22c43b76cf7a1c2f0dc34ef84cbb6809617e/matplotlib-3.10.7-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d7945a70ea43bf9248f4b6582734c2fe726723204a76eca233f24cffc7ef67", size = 9541409, upload-time = "2025-10-09T00:27:15.684Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/95122a407d7f2e446fd865e2388a232a23f2b81934960ea802f3171518e4/matplotlib-3.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0b181e9fa8daf1d9f2d4c547527b167cb8838fc587deabca7b5c01f97199e84", size = 9594054, upload-time = "2025-10-09T00:27:17.547Z" }, + { url = "https://files.pythonhosted.org/packages/13/76/75b194a43b81583478a81e78a07da8d9ca6ddf50dd0a2ccabf258059481d/matplotlib-3.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:31963603041634ce1a96053047b40961f7a29eb8f9a62e80cc2c0427aa1d22a2", size = 8200100, upload-time = "2025-10-09T00:27:20.039Z" }, + { url = "https://files.pythonhosted.org/packages/f5/9e/6aefebdc9f8235c12bdeeda44cc0383d89c1e41da2c400caf3ee2073a3ce/matplotlib-3.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:aebed7b50aa6ac698c90f60f854b47e48cd2252b30510e7a1feddaf5a3f72cbf", size = 8042131, upload-time = "2025-10-09T00:27:21.608Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4b/e5bc2c321b6a7e3a75638d937d19ea267c34bd5a90e12bee76c4d7c7a0d9/matplotlib-3.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d883460c43e8c6b173fef244a2341f7f7c0e9725c7fe68306e8e44ed9c8fb100", size = 8273787, upload-time = "2025-10-09T00:27:23.27Z" }, + { url = "https://files.pythonhosted.org/packages/86/ad/6efae459c56c2fbc404da154e13e3a6039129f3c942b0152624f1c621f05/matplotlib-3.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07124afcf7a6504eafcb8ce94091c5898bbdd351519a1beb5c45f7a38c67e77f", size = 8131348, upload-time = "2025-10-09T00:27:24.926Z" }, + { url = "https://files.pythonhosted.org/packages/a6/5a/a4284d2958dee4116359cc05d7e19c057e64ece1b4ac986ab0f2f4d52d5a/matplotlib-3.10.7-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c17398b709a6cce3d9fdb1595c33e356d91c098cd9486cb2cc21ea2ea418e715", size = 9533949, upload-time = "2025-10-09T00:27:26.704Z" }, + { url = "https://files.pythonhosted.org/packages/de/ff/f3781b5057fa3786623ad8976fc9f7b0d02b2f28534751fd5a44240de4cf/matplotlib-3.10.7-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7146d64f561498764561e9cd0ed64fcf582e570fc519e6f521e2d0cfd43365e1", size = 9804247, upload-time = "2025-10-09T00:27:28.514Z" }, + { url = "https://files.pythonhosted.org/packages/47/5a/993a59facb8444efb0e197bf55f545ee449902dcee86a4dfc580c3b61314/matplotlib-3.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90ad854c0a435da3104c01e2c6f0028d7e719b690998a2333d7218db80950722", size = 9595497, upload-time = "2025-10-09T00:27:30.418Z" }, + { url = "https://files.pythonhosted.org/packages/0d/a5/77c95aaa9bb32c345cbb49626ad8eb15550cba2e6d4c88081a6c2ac7b08d/matplotlib-3.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:4645fc5d9d20ffa3a39361fcdbcec731382763b623b72627806bf251b6388866", size = 8252732, upload-time = "2025-10-09T00:27:32.332Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/45d269b4268d222390d7817dae77b159651909669a34ee9fdee336db5883/matplotlib-3.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:9257be2f2a03415f9105c486d304a321168e61ad450f6153d77c69504ad764bb", size = 8124240, upload-time = "2025-10-09T00:27:33.94Z" }, + { url = "https://files.pythonhosted.org/packages/4b/c7/ca01c607bb827158b439208c153d6f14ddb9fb640768f06f7ca3488ae67b/matplotlib-3.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1e4bbad66c177a8fdfa53972e5ef8be72a5f27e6a607cec0d8579abd0f3102b1", size = 8316938, upload-time = "2025-10-09T00:27:35.534Z" }, + { url = "https://files.pythonhosted.org/packages/84/d2/5539e66e9f56d2fdec94bb8436f5e449683b4e199bcc897c44fbe3c99e28/matplotlib-3.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8eb7194b084b12feb19142262165832fc6ee879b945491d1c3d4660748020c4", size = 8178245, upload-time = "2025-10-09T00:27:37.334Z" }, + { url = "https://files.pythonhosted.org/packages/77/b5/e6ca22901fd3e4fe433a82e583436dd872f6c966fca7e63cf806b40356f8/matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d41379b05528091f00e1728004f9a8d7191260f3862178b88e8fd770206318", size = 9541411, upload-time = "2025-10-09T00:27:39.387Z" }, + { url = "https://files.pythonhosted.org/packages/9e/99/a4524db57cad8fee54b7237239a8f8360bfcfa3170d37c9e71c090c0f409/matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a74f79fafb2e177f240579bc83f0b60f82cc47d2f1d260f422a0627207008ca", size = 9803664, upload-time = "2025-10-09T00:27:41.492Z" }, + { url = "https://files.pythonhosted.org/packages/e6/a5/85e2edf76ea0ad4288d174926d9454ea85f3ce5390cc4e6fab196cbf250b/matplotlib-3.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:702590829c30aada1e8cef0568ddbffa77ca747b4d6e36c6d173f66e301f89cc", size = 9594066, upload-time = "2025-10-09T00:27:43.694Z" }, + { url = "https://files.pythonhosted.org/packages/39/69/9684368a314f6d83fe5c5ad2a4121a3a8e03723d2e5c8ea17b66c1bad0e7/matplotlib-3.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:f79d5de970fc90cd5591f60053aecfce1fcd736e0303d9f0bf86be649fa68fb8", size = 8342832, upload-time = "2025-10-09T00:27:45.543Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/e22e08da14bc1a0894184640d47819d2338b792732e20d292bf86e5ab785/matplotlib-3.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:cb783436e47fcf82064baca52ce748af71725d0352e1d31564cbe9c95df92b9c", size = 8172585, upload-time = "2025-10-09T00:27:47.185Z" }, + { url = "https://files.pythonhosted.org/packages/58/8f/76d5dc21ac64a49e5498d7f0472c0781dae442dd266a67458baec38288ec/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0", size = 8252283, upload-time = "2025-10-09T00:27:54.739Z" }, + { url = "https://files.pythonhosted.org/packages/27/0d/9c5d4c2317feb31d819e38c9f947c942f42ebd4eb935fc6fd3518a11eaa7/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68", size = 8116733, upload-time = "2025-10-09T00:27:56.406Z" }, + { url = "https://files.pythonhosted.org/packages/9a/cc/3fe688ff1355010937713164caacf9ed443675ac48a997bab6ed23b3f7c0/matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91", size = 8693919, upload-time = "2025-10-09T00:27:58.41Z" }, +] + +[[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, upload-time = "2025-10-23T09:00:22.126Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, +] + +[[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, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "msgpack" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload-time = "2025-10-08T09:15:56.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c", size = 82271, upload-time = "2025-10-08T09:14:49.967Z" }, + { url = "https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0", size = 84914, upload-time = "2025-10-08T09:14:50.958Z" }, + { url = "https://files.pythonhosted.org/packages/71/46/b817349db6886d79e57a966346cf0902a426375aadc1e8e7a86a75e22f19/msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296", size = 416962, upload-time = "2025-10-08T09:14:51.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef", size = 426183, upload-time = "2025-10-08T09:14:53.477Z" }, + { url = "https://files.pythonhosted.org/packages/25/98/6a19f030b3d2ea906696cedd1eb251708e50a5891d0978b012cb6107234c/msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c", size = 411454, upload-time = "2025-10-08T09:14:54.648Z" }, + { url = "https://files.pythonhosted.org/packages/b7/cd/9098fcb6adb32187a70b7ecaabf6339da50553351558f37600e53a4a2a23/msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e", size = 422341, upload-time = "2025-10-08T09:14:56.328Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload-time = "2025-10-08T09:14:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload-time = "2025-10-08T09:14:59.177Z" }, + { url = "https://files.pythonhosted.org/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload-time = "2025-10-08T09:15:00.48Z" }, + { url = "https://files.pythonhosted.org/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload-time = "2025-10-08T09:15:01.472Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload-time = "2025-10-08T09:15:03.764Z" }, + { url = "https://files.pythonhosted.org/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload-time = "2025-10-08T09:15:05.136Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload-time = "2025-10-08T09:15:06.837Z" }, + { url = "https://files.pythonhosted.org/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload-time = "2025-10-08T09:15:08.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload-time = "2025-10-08T09:15:09.83Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload-time = "2025-10-08T09:15:11.11Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload-time = "2025-10-08T09:15:12.554Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload-time = "2025-10-08T09:15:13.589Z" }, + { url = "https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf", size = 81212, upload-time = "2025-10-08T09:15:14.552Z" }, + { url = "https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7", size = 84315, upload-time = "2025-10-08T09:15:15.543Z" }, + { url = "https://files.pythonhosted.org/packages/d3/68/93180dce57f684a61a88a45ed13047558ded2be46f03acb8dec6d7c513af/msgpack-1.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999", size = 412721, upload-time = "2025-10-08T09:15:16.567Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e", size = 424657, upload-time = "2025-10-08T09:15:17.825Z" }, + { url = "https://files.pythonhosted.org/packages/38/f8/4398c46863b093252fe67368b44edc6c13b17f4e6b0e4929dbf0bdb13f23/msgpack-1.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162", size = 402668, upload-time = "2025-10-08T09:15:19.003Z" }, + { url = "https://files.pythonhosted.org/packages/28/ce/698c1eff75626e4124b4d78e21cca0b4cc90043afb80a507626ea354ab52/msgpack-1.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794", size = 419040, upload-time = "2025-10-08T09:15:20.183Z" }, + { url = "https://files.pythonhosted.org/packages/67/32/f3cd1667028424fa7001d82e10ee35386eea1408b93d399b09fb0aa7875f/msgpack-1.1.2-cp313-cp313-win32.whl", hash = "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c", size = 65037, upload-time = "2025-10-08T09:15:21.416Z" }, + { url = "https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9", size = 72631, upload-time = "2025-10-08T09:15:22.431Z" }, + { url = "https://files.pythonhosted.org/packages/e5/db/0314e4e2db56ebcf450f277904ffd84a7988b9e5da8d0d61ab2d057df2b6/msgpack-1.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84", size = 64118, upload-time = "2025-10-08T09:15:23.402Z" }, + { url = "https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00", size = 81127, upload-time = "2025-10-08T09:15:24.408Z" }, + { url = "https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939", size = 84981, upload-time = "2025-10-08T09:15:25.812Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a9/3536e385167b88c2cc8f4424c49e28d49a6fc35206d4a8060f136e71f94c/msgpack-1.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e", size = 411885, upload-time = "2025-10-08T09:15:27.22Z" }, + { url = "https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931", size = 419658, upload-time = "2025-10-08T09:15:28.4Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ef/2b92e286366500a09a67e03496ee8b8ba00562797a52f3c117aa2b29514b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014", size = 403290, upload-time = "2025-10-08T09:15:29.764Z" }, + { url = "https://files.pythonhosted.org/packages/78/90/e0ea7990abea5764e4655b8177aa7c63cdfa89945b6e7641055800f6c16b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2", size = 415234, upload-time = "2025-10-08T09:15:31.022Z" }, + { url = "https://files.pythonhosted.org/packages/72/4e/9390aed5db983a2310818cd7d3ec0aecad45e1f7007e0cda79c79507bb0d/msgpack-1.1.2-cp314-cp314-win32.whl", hash = "sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717", size = 66391, upload-time = "2025-10-08T09:15:32.265Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f1/abd09c2ae91228c5f3998dbd7f41353def9eac64253de3c8105efa2082f7/msgpack-1.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b", size = 73787, upload-time = "2025-10-08T09:15:33.219Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b0/9d9f667ab48b16ad4115c1935d94023b82b3198064cb84a123e97f7466c1/msgpack-1.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af", size = 66453, upload-time = "2025-10-08T09:15:34.225Z" }, + { url = "https://files.pythonhosted.org/packages/16/67/93f80545eb1792b61a217fa7f06d5e5cb9e0055bed867f43e2b8e012e137/msgpack-1.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a", size = 85264, upload-time = "2025-10-08T09:15:35.61Z" }, + { url = "https://files.pythonhosted.org/packages/87/1c/33c8a24959cf193966ef11a6f6a2995a65eb066bd681fd085afd519a57ce/msgpack-1.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b", size = 89076, upload-time = "2025-10-08T09:15:36.619Z" }, + { url = "https://files.pythonhosted.org/packages/fc/6b/62e85ff7193663fbea5c0254ef32f0c77134b4059f8da89b958beb7696f3/msgpack-1.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245", size = 435242, upload-time = "2025-10-08T09:15:37.647Z" }, + { url = "https://files.pythonhosted.org/packages/c1/47/5c74ecb4cc277cf09f64e913947871682ffa82b3b93c8dad68083112f412/msgpack-1.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90", size = 432509, upload-time = "2025-10-08T09:15:38.794Z" }, + { url = "https://files.pythonhosted.org/packages/24/a4/e98ccdb56dc4e98c929a3f150de1799831c0a800583cde9fa022fa90602d/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20", size = 415957, upload-time = "2025-10-08T09:15:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/da/28/6951f7fb67bc0a4e184a6b38ab71a92d9ba58080b27a77d3e2fb0be5998f/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27", size = 422910, upload-time = "2025-10-08T09:15:41.505Z" }, + { url = "https://files.pythonhosted.org/packages/f0/03/42106dcded51f0a0b5284d3ce30a671e7bd3f7318d122b2ead66ad289fed/msgpack-1.1.2-cp314-cp314t-win32.whl", hash = "sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b", size = 75197, upload-time = "2025-10-08T09:15:42.954Z" }, + { url = "https://files.pythonhosted.org/packages/15/86/d0071e94987f8db59d4eeb386ddc64d0bb9b10820a8d82bcd3e53eeb2da6/msgpack-1.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff", size = 85772, upload-time = "2025-10-08T09:15:43.954Z" }, + { url = "https://files.pythonhosted.org/packages/81/f2/08ace4142eb281c12701fc3b93a10795e4d4dc7f753911d836675050f886/msgpack-1.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46", size = 70868, upload-time = "2025-10-08T09:15:44.959Z" }, +] + +[[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, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/77/84dd1d2e34d7e2792a236ba180b5e8fcc1e3e414e761ce0253f63d7f572e/numpy-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de5672f4a7b200c15a4127042170a694d4df43c992948f5e1af57f0174beed10", size = 17034641, upload-time = "2025-11-16T22:49:19.336Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ea/25e26fa5837106cde46ae7d0b667e20f69cbbc0efd64cba8221411ab26ae/numpy-2.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:acfd89508504a19ed06ef963ad544ec6664518c863436306153e13e94605c218", size = 12528324, upload-time = "2025-11-16T22:49:22.582Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1a/e85f0eea4cf03d6a0228f5c0256b53f2df4bc794706e7df019fc622e47f1/numpy-2.3.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ffe22d2b05504f786c867c8395de703937f934272eb67586817b46188b4ded6d", size = 5356872, upload-time = "2025-11-16T22:49:25.408Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bb/35ef04afd567f4c989c2060cde39211e4ac5357155c1833bcd1166055c61/numpy-2.3.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:872a5cf366aec6bb1147336480fef14c9164b154aeb6542327de4970282cd2f5", size = 6893148, upload-time = "2025-11-16T22:49:27.549Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2b/05bbeb06e2dff5eab512dfc678b1cc5ee94d8ac5956a0885c64b6b26252b/numpy-2.3.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3095bdb8dd297e5920b010e96134ed91d852d81d490e787beca7e35ae1d89cf7", size = 14557282, upload-time = "2025-11-16T22:49:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/65/fb/2b23769462b34398d9326081fad5655198fcf18966fcb1f1e49db44fbf31/numpy-2.3.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cba086a43d54ca804ce711b2a940b16e452807acebe7852ff327f1ecd49b0d4", size = 16897903, upload-time = "2025-11-16T22:49:34.191Z" }, + { url = "https://files.pythonhosted.org/packages/ac/14/085f4cf05fc3f1e8aa95e85404e984ffca9b2275a5dc2b1aae18a67538b8/numpy-2.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6cf9b429b21df6b99f4dee7a1218b8b7ffbbe7df8764dc0bd60ce8a0708fed1e", size = 16341672, upload-time = "2025-11-16T22:49:37.2Z" }, + { url = "https://files.pythonhosted.org/packages/6f/3b/1f73994904142b2aa290449b3bb99772477b5fd94d787093e4f24f5af763/numpy-2.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:396084a36abdb603546b119d96528c2f6263921c50df3c8fd7cb28873a237748", size = 18838896, upload-time = "2025-11-16T22:49:39.727Z" }, + { url = "https://files.pythonhosted.org/packages/cd/b9/cf6649b2124f288309ffc353070792caf42ad69047dcc60da85ee85fea58/numpy-2.3.5-cp311-cp311-win32.whl", hash = "sha256:b0c7088a73aef3d687c4deef8452a3ac7c1be4e29ed8bf3b366c8111128ac60c", size = 6563608, upload-time = "2025-11-16T22:49:42.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/44/9fe81ae1dcc29c531843852e2874080dc441338574ccc4306b39e2ff6e59/numpy-2.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:a414504bef8945eae5f2d7cb7be2d4af77c5d1cb5e20b296c2c25b61dff2900c", size = 13078442, upload-time = "2025-11-16T22:49:43.99Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a7/f99a41553d2da82a20a2f22e93c94f928e4490bb447c9ff3c4ff230581d3/numpy-2.3.5-cp311-cp311-win_arm64.whl", hash = "sha256:0cd00b7b36e35398fa2d16af7b907b65304ef8bb4817a550e06e5012929830fa", size = 10458555, upload-time = "2025-11-16T22:49:47.092Z" }, + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/c6/65/f9dea8e109371ade9c782b4e4756a82edf9d3366bca495d84d79859a0b79/numpy-2.3.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0963b55cdd70fad460fa4c1341f12f976bb26cb66021a5580329bd498988310", size = 16910689, upload-time = "2025-11-16T22:52:23.247Z" }, + { url = "https://files.pythonhosted.org/packages/00/4f/edb00032a8fb92ec0a679d3830368355da91a69cab6f3e9c21b64d0bb986/numpy-2.3.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f4255143f5160d0de972d28c8f9665d882b5f61309d8362fdd3e103cf7bf010c", size = 12457053, upload-time = "2025-11-16T22:52:26.367Z" }, + { url = "https://files.pythonhosted.org/packages/16/a4/e8a53b5abd500a63836a29ebe145fc1ab1f2eefe1cfe59276020373ae0aa/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:a4b9159734b326535f4dd01d947f919c6eefd2d9827466a696c44ced82dfbc18", size = 5285635, upload-time = "2025-11-16T22:52:29.266Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2f/37eeb9014d9c8b3e9c55bc599c68263ca44fdbc12a93e45a21d1d56df737/numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2feae0d2c91d46e59fcd62784a3a83b3fb677fead592ce51b5a6fbb4f95965ff", size = 6801770, upload-time = "2025-11-16T22:52:31.421Z" }, + { url = "https://files.pythonhosted.org/packages/7d/e4/68d2f474df2cb671b2b6c2986a02e520671295647dad82484cde80ca427b/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffac52f28a7849ad7576293c0cb7b9f08304e8f7d738a8cb8a90ec4c55a998eb", size = 14391768, upload-time = "2025-11-16T22:52:33.593Z" }, + { url = "https://files.pythonhosted.org/packages/b8/50/94ccd8a2b141cb50651fddd4f6a48874acb3c91c8f0842b08a6afc4b0b21/numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63c0e9e7eea69588479ebf4a8a270d5ac22763cc5854e9a7eae952a3908103f7", size = 16729263, upload-time = "2025-11-16T22:52:36.369Z" }, + { url = "https://files.pythonhosted.org/packages/2d/ee/346fa473e666fe14c52fcdd19ec2424157290a032d4c41f98127bfb31ac7/numpy-2.3.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f16417ec91f12f814b10bafe79ef77e70113a2f5f7018640e7425ff979253425", size = 12967213, upload-time = "2025-11-16T22:52:39.38Z" }, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.6.4.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/eb/ff4b8c503fa1f1796679dce648854d58751982426e4e4b37d6fce49d259c/nvidia_cublas_cu12-12.6.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08ed2686e9875d01b58e3cb379c6896df8e76c75e0d4a7f7dace3d7b6d9ef8eb", size = 393138322, upload-time = "2024-11-20T17:40:25.65Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.6.80" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/60/7b6497946d74bcf1de852a21824d63baad12cd417db4195fc1bfe59db953/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6768bad6cab4f19e8292125e5f1ac8aa7d1718704012a0e3272a6f61c4bce132", size = 8917980, upload-time = "2024-11-20T17:36:04.019Z" }, + { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972, upload-time = "2024-10-01T16:58:06.036Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/2e/46030320b5a80661e88039f59060d1790298b4718944a65a7f2aeda3d9e9/nvidia_cuda_nvrtc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:35b0cc6ee3a9636d5409133e79273ce1f3fd087abb0532d2d2e8fff1fe9efc53", size = 23650380, upload-time = "2024-10-01T17:00:14.643Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/23/e717c5ac26d26cf39a27fbc076240fad2e3b817e5889d671b67f4f9f49c5/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba3b56a4f896141e25e19ab287cd71e52a6a0f4b29d0d31609f60e3b4d5219b7", size = 897690, upload-time = "2024-11-20T17:35:30.697Z" }, + { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678, upload-time = "2024-10-01T16:57:33.821Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.5.1.17" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386, upload-time = "2024-10-25T19:54:26.39Z" }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/16/73727675941ab8e6ffd86ca3a4b7b47065edcca7a997920b831f8147c99d/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ccba62eb9cef5559abd5e0d54ceed2d9934030f51163df018532142a8ec533e5", size = 200221632, upload-time = "2024-11-20T17:41:32.357Z" }, + { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622, upload-time = "2024-10-01T17:03:58.79Z" }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.11.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/66/cc9876340ac68ae71b15c743ddb13f8b30d5244af344ec8322b449e35426/nvidia_cufile_cu12-1.11.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc23469d1c7e52ce6c1d55253273d32c565dd22068647f3aa59b3c6b005bf159", size = 1142103, upload-time = "2024-11-20T17:42:11.83Z" }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.7.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/1b/44a01c4e70933637c93e6e1a8063d1e998b50213a6b65ac5a9169c47e98e/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a42cd1344297f70b9e39a1e4f467a4e1c10f1da54ff7a85c12197f6c652c8bdf", size = 56279010, upload-time = "2024-11-20T17:42:50.958Z" }, + { url = "https://files.pythonhosted.org/packages/4a/aa/2c7ff0b5ee02eaef890c0ce7d4f74bc30901871c5e45dee1ae6d0083cd80/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:99f1a32f1ac2bd134897fc7a203f779303261268a65762a623bf30cc9fe79117", size = 56279000, upload-time = "2024-10-01T17:04:45.274Z" }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/6e/c2cf12c9ff8b872e92b4a5740701e51ff17689c4d726fca91875b07f655d/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9e49843a7707e42022babb9bcfa33c29857a93b88020c4e4434656a655b698c", size = 158229790, upload-time = "2024-11-20T17:43:43.211Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780, upload-time = "2024-10-01T17:05:39.875Z" }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/1e/b8b7c2f4099a37b96af5c9bb158632ea9e5d9d27d7391d7eb8fc45236674/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7556d9eca156e18184b94947ade0fba5bb47d69cec46bf8660fd2c71a4b48b73", size = 216561367, upload-time = "2024-11-20T17:44:54.824Z" }, + { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357, upload-time = "2024-10-01T17:06:29.861Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/9a/72ef35b399b0e183bc2e8f6f558036922d453c4d8237dab26c666a04244b/nvidia_cusparselt_cu12-0.6.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5c8a26c36445dd2e6812f1177978a24e2d37cacce7e090f297a688d1ec44f46", size = 156785796, upload-time = "2024-10-15T21:29:17.709Z" }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.26.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/ca/f42388aed0fddd64ade7493dbba36e1f534d4e6fdbdd355c6a90030ae028/nvidia_nccl_cu12-2.26.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:694cf3879a206553cc9d7dbda76b13efaf610fdb70a50cba303de1b0d1530ac6", size = 201319755, upload-time = "2025-03-13T00:29:55.296Z" }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.6.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/d7/c5383e47c7e9bf1c99d5bd2a8c935af2b6d705ad831a7ec5c97db4d82f4f/nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a", size = 19744971, upload-time = "2024-11-20T17:46:53.366Z" }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/9a/fff8376f8e3d084cd1530e1ef7b879bb7d6d265620c95c1b322725c694f4/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b90bed3df379fa79afbd21be8e04a0314336b8ae16768b58f2d34cb1d04cd7d2", size = 89276, upload-time = "2024-11-20T17:38:27.621Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4e/0d0c945463719429b7bd21dece907ad0bde437a2ff12b9b12fee94722ab0/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6574241a3ec5fdc9334353ab8c479fe75841dbe8f4532a8fc97ce63503330ba1", size = 89265, upload-time = "2024-10-01T17:00:38.172Z" }, +] + +[[package]] +name = "openbabel-wheel" +version = "3.1.1.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/55/c916675c49beb64256bd108f4a797111cedca592c9be0c931014b8654806/openbabel-wheel-3.1.1.22.tar.gz", hash = "sha256:d12e07f8e2b2a8a9007b486087fdeb731cedb5b14129bf93ad3d2c5a72e54d08", size = 13246, upload-time = "2025-05-20T14:27:41.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/de/be239b210500c0332007e18dd0a8ca4939d13f05433d453e3a0983defa70/openbabel_wheel-3.1.1.22-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:2499af11947d3454439182a75516bc4008fe0ff22a24f16b3b964317004d5e86", size = 11514597, upload-time = "2025-05-20T14:26:20.174Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cb/167d9bace82f82fa9231e562e723d489f5c07e789290e668b552874c69f8/openbabel_wheel-3.1.1.22-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:4beda0224caa906d1c2ed35652786da244757aaea361cdc0aef13e935c0149a7", size = 12381697, upload-time = "2025-05-20T14:26:22.251Z" }, + { url = "https://files.pythonhosted.org/packages/40/61/3f6f6e78c45d67453628596dff1640e8d56d58e6317ddace5c3be3d550f4/openbabel_wheel-3.1.1.22-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b33c21c987b3a22f7a4c812b8283edbe5ad6c6deae29e9568f1b16a8f5ad20b", size = 15633459, upload-time = "2025-05-20T14:26:24.554Z" }, + { url = "https://files.pythonhosted.org/packages/28/59/f7e7424da6a6ea81f987fac2093e440b8689f4e27929f92167f2a81fc01d/openbabel_wheel-3.1.1.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2ed691f3f5ac2cfebfaa0d9718acd58e41fcbc0e114735f518c92167f7c5e2f", size = 16076298, upload-time = "2025-05-20T14:26:26.823Z" }, + { url = "https://files.pythonhosted.org/packages/d5/27/c219228b4eb582ab11ac0ae2a8acd895e880a4f427e9bdf17d0e41783d91/openbabel_wheel-3.1.1.22-cp311-cp311-win_amd64.whl", hash = "sha256:1303272ecdcfcdfbe7648f2761aa6639c5a4ec3073b472f766d3d2567a44b523", size = 5095182, upload-time = "2025-05-20T14:26:29.03Z" }, + { url = "https://files.pythonhosted.org/packages/0e/91/df492446daefef9ba3c97e1555b1a7abb4ab9a21f00744689fec8e10d53e/openbabel_wheel-3.1.1.22-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:48846ac5c8dff5589fd7834fbc1ee0d3a5d67ed544ef81b716db6932a27c34c2", size = 11517993, upload-time = "2025-05-20T14:26:30.741Z" }, + { url = "https://files.pythonhosted.org/packages/64/35/b5ccaa112d253fb9089db9c5390d066cab08b5401cd2ec59709937f0a746/openbabel_wheel-3.1.1.22-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:9189315a466da529e6422fa588163be230f0fcfb8d79e240fd9d8330fd2af8a6", size = 12390413, upload-time = "2025-05-20T14:26:33.304Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ce/e9a9553a10ec6f0a3f1a3112cd00619bb77651779b59507ce1be4dcef2a1/openbabel_wheel-3.1.1.22-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17588f6823a1a2bc361fbdfec167e8d30d4764176b0b63a3e3127efae71aed8f", size = 15632153, upload-time = "2025-05-20T14:26:36.864Z" }, + { url = "https://files.pythonhosted.org/packages/bc/79/a713470f17697b5ebee488929a88b2daaa3b20eb5be502d6c5cab9dbc4e2/openbabel_wheel-3.1.1.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc3d01459489334e9acf68526db48be91ce88692c59192a0d0fb9f422f2bc9a", size = 16075937, upload-time = "2025-05-20T14:26:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/21/f3/12a0e194e735cb0f3fc6122cfd39d63f05ab2426ee4083b7de1bc4ea1242/openbabel_wheel-3.1.1.22-cp312-cp312-win_amd64.whl", hash = "sha256:e369179c9edfd35b79faa252be0b28b7b8932aee80acfced1922595b67594dbd", size = 5095492, upload-time = "2025-05-20T14:26:46.743Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c3/33947aadfba41478e04776d613c2f677bfe263e69653d406f13147b49373/openbabel_wheel-3.1.1.22-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:1d442a81e2b39c9b1d24a3bea010ef779542056160b8a6d9e7184d72a34152d4", size = 11518042, upload-time = "2025-05-20T14:26:48.543Z" }, + { url = "https://files.pythonhosted.org/packages/ee/3c/287dd7f2233f83244314ed39968de0593140df052a350508318ce7caa13e/openbabel_wheel-3.1.1.22-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:537fa4e3a48e092eea3aeb3f5eb064330d38ac6e2d1db293b22d9832160c0f21", size = 12390390, upload-time = "2025-05-20T14:26:50.756Z" }, + { url = "https://files.pythonhosted.org/packages/44/3f/c72e325490393b463e5ae7446253aab140b5e5e407d97c7de064f341975e/openbabel_wheel-3.1.1.22-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21d1ea864f987f93033720c3847f653f60e502cb07cbb8bcb4965da11a4976f5", size = 15632171, upload-time = "2025-05-20T14:26:52.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/ea/5f81cd018bf60301fcca9e133d3a47b8caca14576266dcdc9b38f96c7879/openbabel_wheel-3.1.1.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9986f9f5c64f69b27c416fd38f551bb00da037fe66f69dc6b0d2ef10dfc9f40", size = 16075915, upload-time = "2025-05-20T14:26:55.216Z" }, + { url = "https://files.pythonhosted.org/packages/80/1d/8e88918fe6047d8eee9a53aa9b153bf9e098fc871cfd5c86a2a5b16e38a1/openbabel_wheel-3.1.1.22-cp313-cp313-win_amd64.whl", hash = "sha256:e98ccbc75c3fcfa225554e6def913e949aff1c6ac9bad178e47bc313ce16d596", size = 5094724, upload-time = "2025-05-20T14:26:57.818Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7b/bdb2b375120e762681f2607b402c16f0d61cb7e96904f6237b9c17cf5000/openbabel_wheel-3.1.1.22-cp313-cp313t-macosx_13_0_arm64.whl", hash = "sha256:d74da8ad712f1313dab74b5cddd40895581324f16d3a9116e8f193c926df3242", size = 11534313, upload-time = "2025-05-20T14:26:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/96/61/e8dbf08e562055ac4c7f9bf7afab4cd812eeae31a56fe17344388009873f/openbabel_wheel-3.1.1.22-cp313-cp313t-macosx_13_0_x86_64.whl", hash = "sha256:f2666af5edf3085b8b2daa64597842efa74e817c94d20f0bb9a065123b13de0d", size = 12414740, upload-time = "2025-05-20T14:27:02.082Z" }, + { url = "https://files.pythonhosted.org/packages/08/68/d8c305508547a25800c07913e13ed99f91d840206b562393210c9d488e96/openbabel_wheel-3.1.1.22-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:336a8aa2f7a7fa6056a63c1d40d5c0e1e0d9bacae2c3d377468e9fab34e247a5", size = 15633699, upload-time = "2025-05-20T14:27:04.768Z" }, + { url = "https://files.pythonhosted.org/packages/4c/8b/8f4c902400ec1897afad8b27d7abf6b06ee0c00cfb73337016091a6d221b/openbabel_wheel-3.1.1.22-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23fada177808451a7d22f39f9e2e198c889d118ad4861b34d8fdbc1e987ad8b4", size = 16058611, upload-time = "2025-05-20T14:27:07.496Z" }, + { url = "https://files.pythonhosted.org/packages/de/35/3c9a03a69211d71e8a1be693a498553a9bc70f0c8eebd7cbbe7d5ae5c0f3/openbabel_wheel-3.1.1.22-cp313-cp313t-win_amd64.whl", hash = "sha256:28863c6b7e169f26d6d2d58c46ec6e51492f7a82712e22a2262b6255c0935417", size = 5183064, upload-time = "2025-05-20T14:27:10.089Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, + { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, + { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "parso" +version = "0.8.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, +] + +[[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, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/5a/a2f6773b64edb921a756eb0729068acad9fc5208a53f4a349396e9436721/pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", size = 5289798, upload-time = "2025-10-15T18:21:47.763Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/069b1f8a2e4b5a37493da6c5868531c3f77b85e716ad7a590ef87d58730d/pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", size = 4650589, upload-time = "2025-10-15T18:21:49.515Z" }, + { url = "https://files.pythonhosted.org/packages/61/e3/2c820d6e9a36432503ead175ae294f96861b07600a7156154a086ba7111a/pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", size = 6230472, upload-time = "2025-10-15T18:21:51.052Z" }, + { url = "https://files.pythonhosted.org/packages/4f/89/63427f51c64209c5e23d4d52071c8d0f21024d3a8a487737caaf614a5795/pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", size = 8033887, upload-time = "2025-10-15T18:21:52.604Z" }, + { url = "https://files.pythonhosted.org/packages/f6/1b/c9711318d4901093c15840f268ad649459cd81984c9ec9887756cca049a5/pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", size = 6343964, upload-time = "2025-10-15T18:21:54.619Z" }, + { url = "https://files.pythonhosted.org/packages/41/1e/db9470f2d030b4995083044cd8738cdd1bf773106819f6d8ba12597d5352/pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", size = 7034756, upload-time = "2025-10-15T18:21:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b0/6177a8bdd5ee4ed87cba2de5a3cc1db55ffbbec6176784ce5bb75aa96798/pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", size = 6458075, upload-time = "2025-10-15T18:21:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/bc/5e/61537aa6fa977922c6a03253a0e727e6e4a72381a80d63ad8eec350684f2/pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", size = 7125955, upload-time = "2025-10-15T18:21:59.372Z" }, + { url = "https://files.pythonhosted.org/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload-time = "2025-10-15T18:22:00.982Z" }, + { url = "https://files.pythonhosted.org/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload-time = "2025-10-15T18:22:02.617Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload-time = "2025-10-15T18:22:04.598Z" }, + { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" }, + { url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload-time = "2025-10-15T18:23:59.594Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload-time = "2025-10-15T18:24:01.669Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload-time = "2025-10-15T18:24:03.403Z" }, + { url = "https://files.pythonhosted.org/packages/94/5a/0d8ab8ffe8a102ff5df60d0de5af309015163bf710c7bb3e8311dd3b3ad0/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", size = 6986839, upload-time = "2025-10-15T18:24:05.344Z" }, + { url = "https://files.pythonhosted.org/packages/20/2e/3434380e8110b76cd9eb00a363c484b050f949b4bbe84ba770bb8508a02c/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", size = 5313505, upload-time = "2025-10-15T18:24:07.137Z" }, + { url = "https://files.pythonhosted.org/packages/57/ca/5a9d38900d9d74785141d6580950fe705de68af735ff6e727cb911b64740/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", size = 5963654, upload-time = "2025-10-15T18:24:09.579Z" }, + { url = "https://files.pythonhosted.org/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload-time = "2025-10-15T18:24:11.495Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, +] + +[[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, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "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, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "psutil" +version = "7.1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/88/bdd0a41e5857d5d703287598cbf08dad90aed56774ea52ae071bae9071b6/psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74", size = 489059, upload-time = "2025-11-02T12:25:54.619Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/93/0c49e776b8734fef56ec9c5c57f923922f2cf0497d62e0f419465f28f3d0/psutil-7.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0005da714eee687b4b8decd3d6cc7c6db36215c9e74e5ad2264b90c3df7d92dc", size = 239751, upload-time = "2025-11-02T12:25:58.161Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8d/b31e39c769e70780f007969815195a55c81a63efebdd4dbe9e7a113adb2f/psutil-7.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19644c85dcb987e35eeeaefdc3915d059dac7bd1167cdcdbf27e0ce2df0c08c0", size = 240368, upload-time = "2025-11-02T12:26:00.491Z" }, + { url = "https://files.pythonhosted.org/packages/62/61/23fd4acc3c9eebbf6b6c78bcd89e5d020cfde4acf0a9233e9d4e3fa698b4/psutil-7.1.3-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95ef04cf2e5ba0ab9eaafc4a11eaae91b44f4ef5541acd2ee91d9108d00d59a7", size = 287134, upload-time = "2025-11-02T12:26:02.613Z" }, + { url = "https://files.pythonhosted.org/packages/30/1c/f921a009ea9ceb51aa355cb0cc118f68d354db36eae18174bab63affb3e6/psutil-7.1.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1068c303be3a72f8e18e412c5b2a8f6d31750fb152f9cb106b54090296c9d251", size = 289904, upload-time = "2025-11-02T12:26:05.207Z" }, + { url = "https://files.pythonhosted.org/packages/a6/82/62d68066e13e46a5116df187d319d1724b3f437ddd0f958756fc052677f4/psutil-7.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:18349c5c24b06ac5612c0428ec2a0331c26443d259e2a0144a9b24b4395b58fa", size = 249642, upload-time = "2025-11-02T12:26:07.447Z" }, + { url = "https://files.pythonhosted.org/packages/df/ad/c1cd5fe965c14a0392112f68362cfceb5230819dbb5b1888950d18a11d9f/psutil-7.1.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c525ffa774fe4496282fb0b1187725793de3e7c6b29e41562733cae9ada151ee", size = 245518, upload-time = "2025-11-02T12:26:09.719Z" }, + { url = "https://files.pythonhosted.org/packages/2e/bb/6670bded3e3236eb4287c7bcdc167e9fae6e1e9286e437f7111caed2f909/psutil-7.1.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b403da1df4d6d43973dc004d19cee3b848e998ae3154cc8097d139b77156c353", size = 239843, upload-time = "2025-11-02T12:26:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/b8/66/853d50e75a38c9a7370ddbeefabdd3d3116b9c31ef94dc92c6729bc36bec/psutil-7.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad81425efc5e75da3f39b3e636293360ad8d0b49bed7df824c79764fb4ba9b8b", size = 240369, upload-time = "2025-11-02T12:26:14.358Z" }, + { url = "https://files.pythonhosted.org/packages/41/bd/313aba97cb5bfb26916dc29cf0646cbe4dd6a89ca69e8c6edce654876d39/psutil-7.1.3-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f33a3702e167783a9213db10ad29650ebf383946e91bc77f28a5eb083496bc9", size = 288210, upload-time = "2025-11-02T12:26:16.699Z" }, + { url = "https://files.pythonhosted.org/packages/c2/fa/76e3c06e760927a0cfb5705eb38164254de34e9bd86db656d4dbaa228b04/psutil-7.1.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fac9cd332c67f4422504297889da5ab7e05fd11e3c4392140f7370f4208ded1f", size = 291182, upload-time = "2025-11-02T12:26:18.848Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1d/5774a91607035ee5078b8fd747686ebec28a962f178712de100d00b78a32/psutil-7.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:3792983e23b69843aea49c8f5b8f115572c5ab64c153bada5270086a2123c7e7", size = 250466, upload-time = "2025-11-02T12:26:21.183Z" }, + { url = "https://files.pythonhosted.org/packages/00/ca/e426584bacb43a5cb1ac91fae1937f478cd8fbe5e4ff96574e698a2c77cd/psutil-7.1.3-cp314-cp314t-win_arm64.whl", hash = "sha256:31d77fcedb7529f27bb3a0472bea9334349f9a04160e8e6e5020f22c59893264", size = 245756, upload-time = "2025-11-02T12:26:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab", size = 238359, upload-time = "2025-11-02T12:26:25.284Z" }, + { url = "https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880", size = 239171, upload-time = "2025-11-02T12:26:27.23Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3", size = 263261, upload-time = "2025-11-02T12:26:29.48Z" }, + { url = "https://files.pythonhosted.org/packages/e0/95/992c8816a74016eb095e73585d747e0a8ea21a061ed3689474fabb29a395/psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b", size = 264635, upload-time = "2025-11-02T12:26:31.74Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd", size = 247633, upload-time = "2025-11-02T12:26:33.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ad/33b2ccec09bf96c2b2ef3f9a6f66baac8253d7565d8839e024a6b905d45d/psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1", size = 244608, upload-time = "2025-11-02T12:26:36.136Z" }, +] + +[[package]] +name = "psycopg2-binary" +version = "2.9.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/8767aaa597ba424643dc87348c6f1754dd9f48e80fdc1b9f7ca5c3a7c213/psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c", size = 379620, upload-time = "2025-10-10T11:14:48.041Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/ae/8d8266f6dd183ab4d48b95b9674034e1b482a3f8619b33a0d86438694577/psycopg2_binary-2.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0e8480afd62362d0a6a27dd09e4ca2def6fa50ed3a4e7c09165266106b2ffa10", size = 3756452, upload-time = "2025-10-10T11:11:11.583Z" }, + { url = "https://files.pythonhosted.org/packages/4b/34/aa03d327739c1be70e09d01182619aca8ebab5970cd0cfa50dd8b9cec2ac/psycopg2_binary-2.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:763c93ef1df3da6d1a90f86ea7f3f806dc06b21c198fa87c3c25504abec9404a", size = 3863957, upload-time = "2025-10-10T11:11:16.932Z" }, + { url = "https://files.pythonhosted.org/packages/48/89/3fdb5902bdab8868bbedc1c6e6023a4e08112ceac5db97fc2012060e0c9a/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e164359396576a3cc701ba8af4751ae68a07235d7a380c631184a611220d9a4", size = 4410955, upload-time = "2025-10-10T11:11:21.21Z" }, + { url = "https://files.pythonhosted.org/packages/ce/24/e18339c407a13c72b336e0d9013fbbbde77b6fd13e853979019a1269519c/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d57c9c387660b8893093459738b6abddbb30a7eab058b77b0d0d1c7d521ddfd7", size = 4468007, upload-time = "2025-10-10T11:11:24.831Z" }, + { url = "https://files.pythonhosted.org/packages/91/7e/b8441e831a0f16c159b5381698f9f7f7ed54b77d57bc9c5f99144cc78232/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2c226ef95eb2250974bf6fa7a842082b31f68385c4f3268370e3f3870e7859ee", size = 4165012, upload-time = "2025-10-10T11:11:29.51Z" }, + { url = "https://files.pythonhosted.org/packages/0d/61/4aa89eeb6d751f05178a13da95516c036e27468c5d4d2509bb1e15341c81/psycopg2_binary-2.9.11-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a311f1edc9967723d3511ea7d2708e2c3592e3405677bf53d5c7246753591fbb", size = 3981881, upload-time = "2025-10-30T02:55:07.332Z" }, + { url = "https://files.pythonhosted.org/packages/76/a1/2f5841cae4c635a9459fe7aca8ed771336e9383b6429e05c01267b0774cf/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb415404821b6d1c47353ebe9c8645967a5235e6d88f914147e7fd411419e6f", size = 3650985, upload-time = "2025-10-10T11:11:34.975Z" }, + { url = "https://files.pythonhosted.org/packages/84/74/4defcac9d002bca5709951b975173c8c2fa968e1a95dc713f61b3a8d3b6a/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f07c9c4a5093258a03b28fab9b4f151aa376989e7f35f855088234e656ee6a94", size = 3296039, upload-time = "2025-10-10T11:11:40.432Z" }, + { url = "https://files.pythonhosted.org/packages/6d/c2/782a3c64403d8ce35b5c50e1b684412cf94f171dc18111be8c976abd2de1/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00ce1830d971f43b667abe4a56e42c1e2d594b32da4802e44a73bacacb25535f", size = 3043477, upload-time = "2025-10-30T02:55:11.182Z" }, + { url = "https://files.pythonhosted.org/packages/c8/31/36a1d8e702aa35c38fc117c2b8be3f182613faa25d794b8aeaab948d4c03/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cffe9d7697ae7456649617e8bb8d7a45afb71cd13f7ab22af3e5c61f04840908", size = 3345842, upload-time = "2025-10-10T11:11:45.366Z" }, + { url = "https://files.pythonhosted.org/packages/6e/b4/a5375cda5b54cb95ee9b836930fea30ae5a8f14aa97da7821722323d979b/psycopg2_binary-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:304fd7b7f97eef30e91b8f7e720b3db75fee010b520e434ea35ed1ff22501d03", size = 2713894, upload-time = "2025-10-10T11:11:48.775Z" }, + { url = "https://files.pythonhosted.org/packages/d8/91/f870a02f51be4a65987b45a7de4c2e1897dd0d01051e2b559a38fa634e3e/psycopg2_binary-2.9.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:be9b840ac0525a283a96b556616f5b4820e0526addb8dcf6525a0fa162730be4", size = 3756603, upload-time = "2025-10-10T11:11:52.213Z" }, + { url = "https://files.pythonhosted.org/packages/27/fa/cae40e06849b6c9a95eb5c04d419942f00d9eaac8d81626107461e268821/psycopg2_binary-2.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f090b7ddd13ca842ebfe301cd587a76a4cf0913b1e429eb92c1be5dbeb1a19bc", size = 3864509, upload-time = "2025-10-10T11:11:56.452Z" }, + { url = "https://files.pythonhosted.org/packages/2d/75/364847b879eb630b3ac8293798e380e441a957c53657995053c5ec39a316/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ab8905b5dcb05bf3fb22e0cf90e10f469563486ffb6a96569e51f897c750a76a", size = 4411159, upload-time = "2025-10-10T11:12:00.49Z" }, + { url = "https://files.pythonhosted.org/packages/6f/a0/567f7ea38b6e1c62aafd58375665a547c00c608a471620c0edc364733e13/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf940cd7e7fec19181fdbc29d76911741153d51cab52e5c21165f3262125685e", size = 4468234, upload-time = "2025-10-10T11:12:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/30/da/4e42788fb811bbbfd7b7f045570c062f49e350e1d1f3df056c3fb5763353/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa0f693d3c68ae925966f0b14b8edda71696608039f4ed61b1fe9ffa468d16db", size = 4166236, upload-time = "2025-10-10T11:12:11.674Z" }, + { url = "https://files.pythonhosted.org/packages/3c/94/c1777c355bc560992af848d98216148be5f1be001af06e06fc49cbded578/psycopg2_binary-2.9.11-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a1cf393f1cdaf6a9b57c0a719a1068ba1069f022a59b8b1fe44b006745b59757", size = 3983083, upload-time = "2025-10-30T02:55:15.73Z" }, + { url = "https://files.pythonhosted.org/packages/bd/42/c9a21edf0e3daa7825ed04a4a8588686c6c14904344344a039556d78aa58/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef7a6beb4beaa62f88592ccc65df20328029d721db309cb3250b0aae0fa146c3", size = 3652281, upload-time = "2025-10-10T11:12:17.713Z" }, + { url = "https://files.pythonhosted.org/packages/12/22/dedfbcfa97917982301496b6b5e5e6c5531d1f35dd2b488b08d1ebc52482/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:31b32c457a6025e74d233957cc9736742ac5a6cb196c6b68499f6bb51390bd6a", size = 3298010, upload-time = "2025-10-10T11:12:22.671Z" }, + { url = "https://files.pythonhosted.org/packages/66/ea/d3390e6696276078bd01b2ece417deac954dfdd552d2edc3d03204416c0c/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:edcb3aeb11cb4bf13a2af3c53a15b3d612edeb6409047ea0b5d6a21a9d744b34", size = 3044641, upload-time = "2025-10-30T02:55:19.929Z" }, + { url = "https://files.pythonhosted.org/packages/12/9a/0402ded6cbd321da0c0ba7d34dc12b29b14f5764c2fc10750daa38e825fc/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b6d93d7c0b61a1dd6197d208ab613eb7dcfdcca0a49c42ceb082257991de9d", size = 3347940, upload-time = "2025-10-10T11:12:26.529Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d2/99b55e85832ccde77b211738ff3925a5d73ad183c0b37bcbbe5a8ff04978/psycopg2_binary-2.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:b33fabeb1fde21180479b2d4667e994de7bbf0eec22832ba5d9b5e4cf65b6c6d", size = 2714147, upload-time = "2025-10-10T11:12:29.535Z" }, + { url = "https://files.pythonhosted.org/packages/ff/a8/a2709681b3ac11b0b1786def10006b8995125ba268c9a54bea6f5ae8bd3e/psycopg2_binary-2.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b8fb3db325435d34235b044b199e56cdf9ff41223a4b9752e8576465170bb38c", size = 3756572, upload-time = "2025-10-10T11:12:32.873Z" }, + { url = "https://files.pythonhosted.org/packages/62/e1/c2b38d256d0dafd32713e9f31982a5b028f4a3651f446be70785f484f472/psycopg2_binary-2.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:366df99e710a2acd90efed3764bb1e28df6c675d33a7fb40df9b7281694432ee", size = 3864529, upload-time = "2025-10-10T11:12:36.791Z" }, + { url = "https://files.pythonhosted.org/packages/11/32/b2ffe8f3853c181e88f0a157c5fb4e383102238d73c52ac6d93a5c8bffe6/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c55b385daa2f92cb64b12ec4536c66954ac53654c7f15a203578da4e78105c0", size = 4411242, upload-time = "2025-10-10T11:12:42.388Z" }, + { url = "https://files.pythonhosted.org/packages/10/04/6ca7477e6160ae258dc96f67c371157776564679aefd247b66f4661501a2/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c0377174bf1dd416993d16edc15357f6eb17ac998244cca19bc67cdc0e2e5766", size = 4468258, upload-time = "2025-10-10T11:12:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/3c/7e/6a1a38f86412df101435809f225d57c1a021307dd0689f7a5e7fe83588b1/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c6ff3335ce08c75afaed19e08699e8aacf95d4a260b495a4a8545244fe2ceb3", size = 4166295, upload-time = "2025-10-10T11:12:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7d/c07374c501b45f3579a9eb761cbf2604ddef3d96ad48679112c2c5aa9c25/psycopg2_binary-2.9.11-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84011ba3109e06ac412f95399b704d3d6950e386b7994475b231cf61eec2fc1f", size = 3983133, upload-time = "2025-10-30T02:55:24.329Z" }, + { url = "https://files.pythonhosted.org/packages/82/56/993b7104cb8345ad7d4516538ccf8f0d0ac640b1ebd8c754a7b024e76878/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba34475ceb08cccbdd98f6b46916917ae6eeb92b5ae111df10b544c3a4621dc4", size = 3652383, upload-time = "2025-10-10T11:12:56.387Z" }, + { url = "https://files.pythonhosted.org/packages/2d/ac/eaeb6029362fd8d454a27374d84c6866c82c33bfc24587b4face5a8e43ef/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b31e90fdd0f968c2de3b26ab014314fe814225b6c324f770952f7d38abf17e3c", size = 3298168, upload-time = "2025-10-10T11:13:00.403Z" }, + { url = "https://files.pythonhosted.org/packages/2b/39/50c3facc66bded9ada5cbc0de867499a703dc6bca6be03070b4e3b65da6c/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d526864e0f67f74937a8fce859bd56c979f5e2ec57ca7c627f5f1071ef7fee60", size = 3044712, upload-time = "2025-10-30T02:55:27.975Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8e/b7de019a1f562f72ada81081a12823d3c1590bedc48d7d2559410a2763fe/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04195548662fa544626c8ea0f06561eb6203f1984ba5b4562764fbeb4c3d14b1", size = 3347549, upload-time = "2025-10-10T11:13:03.971Z" }, + { url = "https://files.pythonhosted.org/packages/80/2d/1bb683f64737bbb1f86c82b7359db1eb2be4e2c0c13b947f80efefa7d3e5/psycopg2_binary-2.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:efff12b432179443f54e230fdf60de1f6cc726b6c832db8701227d089310e8aa", size = 2714215, upload-time = "2025-10-10T11:13:07.14Z" }, + { url = "https://files.pythonhosted.org/packages/64/12/93ef0098590cf51d9732b4f139533732565704f45bdc1ffa741b7c95fb54/psycopg2_binary-2.9.11-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:92e3b669236327083a2e33ccfa0d320dd01b9803b3e14dd986a4fc54aa00f4e1", size = 3756567, upload-time = "2025-10-10T11:13:11.885Z" }, + { url = "https://files.pythonhosted.org/packages/7c/a9/9d55c614a891288f15ca4b5209b09f0f01e3124056924e17b81b9fa054cc/psycopg2_binary-2.9.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e0deeb03da539fa3577fcb0b3f2554a97f7e5477c246098dbb18091a4a01c16f", size = 3864755, upload-time = "2025-10-10T11:13:17.727Z" }, + { url = "https://files.pythonhosted.org/packages/13/1e/98874ce72fd29cbde93209977b196a2edae03f8490d1bd8158e7f1daf3a0/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b52a3f9bb540a3e4ec0f6ba6d31339727b2950c9772850d6545b7eae0b9d7c5", size = 4411646, upload-time = "2025-10-10T11:13:24.432Z" }, + { url = "https://files.pythonhosted.org/packages/5a/bd/a335ce6645334fb8d758cc358810defca14a1d19ffbc8a10bd38a2328565/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:db4fd476874ccfdbb630a54426964959e58da4c61c9feba73e6094d51303d7d8", size = 4468701, upload-time = "2025-10-10T11:13:29.266Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/c8b4f53f34e295e45709b7568bf9b9407a612ea30387d35eb9fa84f269b4/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47f212c1d3be608a12937cc131bd85502954398aaa1320cb4c14421a0ffccf4c", size = 4166293, upload-time = "2025-10-10T11:13:33.336Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e0/f8cc36eadd1b716ab36bb290618a3292e009867e5c97ce4aba908cb99644/psycopg2_binary-2.9.11-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e35b7abae2b0adab776add56111df1735ccc71406e56203515e228a8dc07089f", size = 3983184, upload-time = "2025-10-30T02:55:32.483Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/2a8fe18a4e61cfb3417da67b6318e12691772c0696d79434184a511906dc/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fcf21be3ce5f5659daefd2b3b3b6e4727b028221ddc94e6c1523425579664747", size = 3652650, upload-time = "2025-10-10T11:13:38.181Z" }, + { url = "https://files.pythonhosted.org/packages/76/36/03801461b31b29fe58d228c24388f999fe814dfc302856e0d17f97d7c54d/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:9bd81e64e8de111237737b29d68039b9c813bdf520156af36d26819c9a979e5f", size = 3298663, upload-time = "2025-10-10T11:13:44.878Z" }, + { url = "https://files.pythonhosted.org/packages/97/77/21b0ea2e1a73aa5fa9222b2a6b8ba325c43c3a8d54272839c991f2345656/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:32770a4d666fbdafab017086655bcddab791d7cb260a16679cc5a7338b64343b", size = 3044737, upload-time = "2025-10-30T02:55:35.69Z" }, + { url = "https://files.pythonhosted.org/packages/67/69/f36abe5f118c1dca6d3726ceae164b9356985805480731ac6712a63f24f0/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3cb3a676873d7506825221045bd70e0427c905b9c8ee8d6acd70cfcbd6e576d", size = 3347643, upload-time = "2025-10-10T11:13:53.499Z" }, + { url = "https://files.pythonhosted.org/packages/e1/36/9c0c326fe3a4227953dfb29f5d0c8ae3b8eb8c1cd2967aa569f50cb3c61f/psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316", size = 2803913, upload-time = "2025-10-10T11:13:57.058Z" }, +] + +[[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, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[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, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" }, +] + +[[package]] +name = "py3dmol" +version = "2.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/62/11/a123e22c6797d9cfe64eef3113dd7219bb9bc675c4d28246a56a90fd5c60/py3dmol-2.5.3.tar.gz", hash = "sha256:d837168aae65d27abd607b21100803e7b60d6f7c0ec9aa48cea5b3c1e85c437f", size = 7853, upload-time = "2025-09-28T14:20:28.141Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a6/e2e8535d8146bce05de6e0ecf1099a7e2887d840ae2a7b3a09385543fd02/py3dmol-2.5.3-py2.py3-none-any.whl", hash = "sha256:5c1c9ee40bda82b91978e75f3c144be5b90cdf472e765bcef4890db76cc8f843", size = 7156, upload-time = "2025-09-28T14:20:26.941Z" }, +] + +[[package]] +name = "pyarrow" +version = "17.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/4e/ea6d43f324169f8aec0e57569443a38bab4b398d09769ca64f7b4d467de3/pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28", size = 1112479, upload-time = "2024-07-17T10:41:25.092Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/46/ce89f87c2936f5bb9d879473b9663ce7a4b1f4359acc2f0eb39865eaa1af/pyarrow-17.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977", size = 29028748, upload-time = "2024-07-16T10:30:02.609Z" }, + { url = "https://files.pythonhosted.org/packages/8d/8e/ce2e9b2146de422f6638333c01903140e9ada244a2a477918a368306c64c/pyarrow-17.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3", size = 27190965, upload-time = "2024-07-16T10:30:10.718Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c8/5675719570eb1acd809481c6d64e2136ffb340bc387f4ca62dce79516cea/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15", size = 39269081, upload-time = "2024-07-16T10:30:18.878Z" }, + { url = "https://files.pythonhosted.org/packages/5e/78/3931194f16ab681ebb87ad252e7b8d2c8b23dad49706cadc865dff4a1dd3/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597", size = 39864921, upload-time = "2024-07-16T10:30:27.008Z" }, + { url = "https://files.pythonhosted.org/packages/d8/81/69b6606093363f55a2a574c018901c40952d4e902e670656d18213c71ad7/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420", size = 38740798, upload-time = "2024-07-16T10:30:34.814Z" }, + { url = "https://files.pythonhosted.org/packages/4c/21/9ca93b84b92ef927814cb7ba37f0774a484c849d58f0b692b16af8eebcfb/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4", size = 39871877, upload-time = "2024-07-16T10:30:42.672Z" }, + { url = "https://files.pythonhosted.org/packages/30/d1/63a7c248432c71c7d3ee803e706590a0b81ce1a8d2b2ae49677774b813bb/pyarrow-17.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03", size = 25151089, upload-time = "2024-07-16T10:30:49.279Z" }, + { url = "https://files.pythonhosted.org/packages/d4/62/ce6ac1275a432b4a27c55fe96c58147f111d8ba1ad800a112d31859fae2f/pyarrow-17.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22", size = 29019418, upload-time = "2024-07-16T10:30:55.573Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0a/dbd0c134e7a0c30bea439675cc120012337202e5fac7163ba839aa3691d2/pyarrow-17.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053", size = 27152197, upload-time = "2024-07-16T10:31:02.036Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/3f4a16498349db79090767620d6dc23c1ec0c658a668d61d76b87706c65d/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a", size = 39263026, upload-time = "2024-07-16T10:31:10.351Z" }, + { url = "https://files.pythonhosted.org/packages/c2/0c/ea2107236740be8fa0e0d4a293a095c9f43546a2465bb7df34eee9126b09/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc", size = 39880798, upload-time = "2024-07-16T10:31:17.66Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b0/b9164a8bc495083c10c281cc65064553ec87b7537d6f742a89d5953a2a3e/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a", size = 38715172, upload-time = "2024-07-16T10:31:25.965Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c4/9625418a1413005e486c006e56675334929fad864347c5ae7c1b2e7fe639/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b", size = 39874508, upload-time = "2024-07-16T10:31:33.721Z" }, + { url = "https://files.pythonhosted.org/packages/ae/49/baafe2a964f663413be3bd1cf5c45ed98c5e42e804e2328e18f4570027c1/pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7", size = 25099235, upload-time = "2024-07-16T10:31:40.893Z" }, +] + +[[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, upload-time = "2025-09-09T13:23:47.91Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, +] + +[[package]] +name = "pydata-sphinx-theme" +version = "0.16.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/20/bb50f9de3a6de69e6abd6b087b52fa2418a0418b19597601605f855ad044/pydata_sphinx_theme-0.16.1.tar.gz", hash = "sha256:a08b7f0b7f70387219dc659bff0893a7554d5eb39b59d3b8ef37b8401b7642d7", size = 2412693, upload-time = "2024-12-17T10:53:39.537Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl", hash = "sha256:225331e8ac4b32682c18fcac5a57a6f717c4e632cea5dd0e247b55155faeccde", size = 6723264, upload-time = "2024-12-17T10:53:35.645Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pymol-remote" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/0e/266eb8409baea23f66f7d6b9ed4d139697009049eaec0c3720c60ad77326/pymol_remote-1.1.0.tar.gz", hash = "sha256:c5177133adf7bcc665077eb21ba0db0e2aa4333772fc1e4e203559365f8f8713", size = 766417, upload-time = "2025-02-16T11:43:24.699Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/16/9a5bb7ef3bcc5b5a0e708cec0bd08069b87223e77c429b6c0b294b3bae49/pymol_remote-1.1.0-py3-none-any.whl", hash = "sha256:32170b896bcf21e6c7d4716ff1f98d358bc80376c9e175aa5e8b86ba245813fc", size = 19416, upload-time = "2025-02-16T11:43:22.792Z" }, +] + +[[package]] +name = "pymysql" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/1fe3fcd9f959efa0ebe200b8de88b5a5ce3e767e38c7ac32fb179f16a388/pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03", size = 48258, upload-time = "2025-08-24T12:55:55.146Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.2.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +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/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "pytest-benchmark" +version = "5.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "py-cpuinfo" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/34/9f732b76456d64faffbef6232f1f9dbec7a7c4999ff46282fa418bd1af66/pytest_benchmark-5.2.3.tar.gz", hash = "sha256:deb7317998a23c650fd4ff76e1230066a76cb45dcece0aca5607143c619e7779", size = 341340, upload-time = "2025-11-09T18:48:43.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/29/e756e715a48959f1c0045342088d7ca9762a2f509b945f362a316e9412b7/pytest_benchmark-5.2.3-py3-none-any.whl", hash = "sha256:bc839726ad20e99aaa0d11a127445457b4219bdb9e80a1afc4b51da7f96b0803", size = 45255, upload-time = "2025-11-09T18:48:39.765Z" }, +] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/15/da3df99fd551507694a9b01f512a2f6cf1254f33601605843c3775f39460/pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", size = 63245, upload-time = "2023-05-24T18:44:56.845Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/4b/8b78d126e275efa2379b1c2e09dc52cf70df16fc3b90613ef82531499d73/pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a", size = 21949, upload-time = "2023-05-24T18:44:54.079Z" }, +] + +[[package]] +name = "pytest-dotenv" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, + { name = "python-dotenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/b0/cafee9c627c1bae228eb07c9977f679b3a7cb111b488307ab9594ba9e4da/pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732", size = 3782, upload-time = "2020-06-16T12:38:03.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/da/9da67c67b3d0963160e3d2cbc7c38b6fae342670cc8e6d5936644b2cf944/pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f", size = 3993, upload-time = "2020-06-16T12:38:01.139Z" }, +] + +[[package]] +name = "pytest-testmon" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/1d/3e4230cc67cd6205bbe03c3527500c0ccaf7f0c78b436537eac71590ee4a/pytest_testmon-2.2.0.tar.gz", hash = "sha256:01f488e955ed0e0049777bee598bf1f647dd524e06f544c31a24e68f8d775a51", size = 23108, upload-time = "2025-12-01T07:30:24.76Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/55/ebb3c2f59fb089f08d00f764830d35780fc4e4c41dffcadafa3264682b65/pytest_testmon-2.2.0-py3-none-any.whl", hash = "sha256:2604ca44a54d61a2e830d9ce828b41a837075e4ebc1f81b148add8e90d34815b", size = 25199, upload-time = "2025-12-01T07:30:23.623Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[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, upload-time = "2024-03-01T18:36:20.211Z" } +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, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, +] + +[[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, upload-time = "2025-09-08T23:10:18.157Z" } +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, upload-time = "2025-09-08T23:07:45.946Z" }, + { 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, upload-time = "2025-09-08T23:07:47.551Z" }, + { 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, upload-time = "2025-09-08T23:07:49.436Z" }, + { 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, upload-time = "2025-09-08T23:07:51.234Z" }, + { 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, upload-time = "2025-09-08T23:07:52.795Z" }, + { 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, upload-time = "2025-09-08T23:07:55.047Z" }, + { 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, upload-time = "2025-09-08T23:07:57.172Z" }, + { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, + { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, + { 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, upload-time = "2025-09-08T23:08:03.807Z" }, + { 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, upload-time = "2025-09-08T23:08:05.301Z" }, + { 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, upload-time = "2025-09-08T23:08:06.828Z" }, + { 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, upload-time = "2025-09-08T23:08:08.396Z" }, + { 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, upload-time = "2025-09-08T23:08:09.989Z" }, + { 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, upload-time = "2025-09-08T23:08:11.907Z" }, + { 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, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { 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, upload-time = "2025-09-08T23:08:20.801Z" }, + { 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, upload-time = "2025-09-08T23:08:22.47Z" }, + { 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, upload-time = "2025-09-08T23:08:24.286Z" }, + { 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, upload-time = "2025-09-08T23:08:26.063Z" }, + { 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, upload-time = "2025-09-08T23:08:27.623Z" }, + { 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, upload-time = "2025-09-08T23:08:29.672Z" }, + { 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, upload-time = "2025-09-08T23:08:31.349Z" }, + { 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, upload-time = "2025-09-08T23:08:33.543Z" }, + { 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, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { 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, upload-time = "2025-09-08T23:08:44.973Z" }, + { 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, upload-time = "2025-09-08T23:08:46.601Z" }, + { 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, upload-time = "2025-09-08T23:08:48.187Z" }, + { 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, upload-time = "2025-09-08T23:08:49.76Z" }, + { 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, upload-time = "2025-09-08T23:08:51.7Z" }, + { 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, upload-time = "2025-09-08T23:08:53.393Z" }, + { 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, upload-time = "2025-09-08T23:08:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, + { 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, upload-time = "2025-09-08T23:09:49.376Z" }, + { 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, upload-time = "2025-09-08T23:09:51.073Z" }, + { 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, upload-time = "2025-09-08T23:09:52.698Z" }, + { 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, upload-time = "2025-09-08T23:09:54.563Z" }, + { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, +] + +[[package]] +name = "rdkit" +version = "2025.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pillow" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/de/4a9ecf9acdee20deed93ef3bdadc9b0cbacd09d5cb23a8620d0f8411bd31/rdkit-2025.3.6-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:3ac57fcddd17d6707139fb85782d11c2ac674b7f18d06750f5014dc43ece34e4", size = 31642866, upload-time = "2025-09-05T12:46:19.242Z" }, + { url = "https://files.pythonhosted.org/packages/db/88/b6f915ebdffbfdfa140cb4d515bbfe0cb08008e2ce94aa5c44414b68234a/rdkit-2025.3.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:682f74525260b177b7dd84ea235b3abc4e5db72e5c62c664c896c7c150299e2a", size = 29089754, upload-time = "2025-09-05T12:46:22.834Z" }, + { url = "https://files.pythonhosted.org/packages/f5/70/96953e5d85b981e5dfc14075a8baa41df91ade2b9b005b133a959f178925/rdkit-2025.3.6-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:d3ad26d64d10dd3cf001c3dcf0b7e1e2eb7221334b1d0f6f3fbd5d5408c22d74", size = 34707581, upload-time = "2025-09-05T12:46:27.075Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/2622e01e38736a68d84b34c7b955e7ce32f0d19901e79620b80b1217300e/rdkit-2025.3.6-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:afc931d1be1a4ad2fc4f2f2732c10983b1a57fbde9c22870721beafe42be3ab0", size = 36180899, upload-time = "2025-09-05T12:46:31.335Z" }, + { url = "https://files.pythonhosted.org/packages/a2/45/8d07d92475bf4598f5e948c858d3e9f15a67df2ae04e4627013b9d86edc3/rdkit-2025.3.6-cp311-cp311-win_amd64.whl", hash = "sha256:4339531a3c149087f6e39de75b7c71ac75c87e5eabb1b34c27cd0bef98a72814", size = 23506723, upload-time = "2025-09-05T12:46:35.119Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2f/23ec58616edd1bf467c6b7cc96dca017e9f4f9c9bb32dfa3b35637e6a745/rdkit-2025.3.6-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9c433eeba711144304b8febd8de4ec653f9fb2520923e9f55b3a617e953870af", size = 31719603, upload-time = "2025-09-05T12:46:39.746Z" }, + { url = "https://files.pythonhosted.org/packages/49/44/bb352e512f20052d55fd0ec29483f122ef17228dacc103148d2eb8fb0938/rdkit-2025.3.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9df1b9b336f1e36f439e25dd816ec66bf78f979d473998514d92980ce2ed58a6", size = 29132323, upload-time = "2025-09-05T12:46:43.856Z" }, + { url = "https://files.pythonhosted.org/packages/6d/7e/0868837a10a4bb2c0ecbab30b29b79aedce93d61c3c14949123f8e527bad/rdkit-2025.3.6-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:24c5a3b5c367c174d169e0271576450aa2b83c2df95a1ccaed4662efe13b11bf", size = 34595105, upload-time = "2025-09-05T12:46:48.194Z" }, + { url = "https://files.pythonhosted.org/packages/47/06/84f140ed025dd96c7ec36aa38555b466f8006bd36085abd3702d75c98160/rdkit-2025.3.6-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ed5565d4d6423def7c52eb20a6263afcd979383757086dec92f57e77d7c7f856", size = 36119142, upload-time = "2025-09-05T12:46:52.003Z" }, + { url = "https://files.pythonhosted.org/packages/cb/98/2d34338adca7f7932fcc83f6e9139c8ddc313b166ae18033ab7c996be836/rdkit-2025.3.6-cp312-cp312-win_amd64.whl", hash = "sha256:632f89345c8e84306a21473fdaad3a58dbd5e6c0b128bef33dfb6090af326061", size = 23526290, upload-time = "2025-09-05T12:46:55.72Z" }, + { url = "https://files.pythonhosted.org/packages/66/c3/53ddc0f88dce2a0b5ac938d97326da25b4e9f6b6858ffc6797a95d824ddd/rdkit-2025.3.6-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:6439943172350151cd45e19b41acdf206397736e686a7717df91b07ee91fc174", size = 31718554, upload-time = "2025-09-05T12:46:59.379Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/1fb7644ff06817a9e3b67d70da53dea59b64c38badc49426e8338e36fbdd/rdkit-2025.3.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:760dc4d90cc30a96145062811136cd5d309a91a7eeacec0afcf0b079877f8be2", size = 29131323, upload-time = "2025-09-05T12:47:03.078Z" }, + { url = "https://files.pythonhosted.org/packages/e7/7d/2e65c55eb6da56c000f9a7b0b2cec6b4aa2a17ec70ef58879f59c036ca43/rdkit-2025.3.6-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:33de7c4c2c49d3ca9b44331b0d6591f4f3957605bd9271b845d358ffc9e1bc4b", size = 34593714, upload-time = "2025-09-05T12:47:06.832Z" }, + { url = "https://files.pythonhosted.org/packages/c1/82/b2330569fbff20c5f5495f69ae28d3e61dfbc055f00b7fe977905a574089/rdkit-2025.3.6-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8bb52f5fc9f1a93817264dffc0ac8b20cea71091f9b8a253ebd288aeae26032f", size = 36117945, upload-time = "2025-09-05T12:47:11.31Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ed/57104398c6efe7304668846cf92e38102cd9d3a9d249087893d68f595907/rdkit-2025.3.6-cp313-cp313-win_amd64.whl", hash = "sha256:be1064d31630cbfbf2fc4b35cf9175a725378601bbd1b945047e9ba9c231fcc2", size = 23525366, upload-time = "2025-09-05T12:47:14.636Z" }, + { url = "https://files.pythonhosted.org/packages/ad/d1/447534eca35ee67db94e3ec4a4e0504d6b0088d963ac5edd19d451f6f80c/rdkit-2025.3.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26c4a1cd658b9b7264f9b021366e6d26474646d9021033e1ec4b93e80d5215b6", size = 31720872, upload-time = "2025-09-05T12:47:18.259Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f7/b3e808851bd2961452ed672c694b38ec8c1fd3b30cb0f56b8ef722234f9e/rdkit-2025.3.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6b2bbafc9034c058a539ba7f29647d2c45803019ca48ac0888024971082570b9", size = 29150282, upload-time = "2025-09-05T12:47:21.961Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bd/23aba3a54a3e79fafbf74d3b9dde7acda9ac82577b293949d825816ac9dc/rdkit-2025.3.6-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:cda846618360858a084bc096a9e1af2d6693f1577c0309f5760ae87c01d089bb", size = 34625860, upload-time = "2025-09-05T12:47:26.294Z" }, + { url = "https://files.pythonhosted.org/packages/88/76/8b2108aa2e4a202bd5e9e8f8c4719eb476be43123288ee0ffdc74f35261e/rdkit-2025.3.6-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:7d10009d98a4c390cc14c5059a0c15f30f614f19b81ca665ff52a4fd8202bad9", size = 36125228, upload-time = "2025-09-05T12:47:30.33Z" }, + { url = "https://files.pythonhosted.org/packages/37/1d/415fcfdc96c0453d02d8265684083bfac45425c52aeee64aadc330aa6f66/rdkit-2025.3.6-cp314-cp314-win_amd64.whl", hash = "sha256:600d7fc3a2665baa9de7ec6870f33a53027f532f9a47e5df765ac91539c7e746", size = 24004467, upload-time = "2025-09-05T12:47:33.743Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "roman-numerals-py" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017, upload-time = "2025-02-22T07:34:54.333Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, +] + +[[package]] +name = "ruff" +version = "0.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/5e/683c7ef7a696923223e7d95ca06755d6e2acbc5fd8382b2912a28008137c/ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3", size = 3378522, upload-time = "2024-12-12T15:17:56.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/c4/bfdbb8b9c419ff3b52479af8581026eeaac3764946fdb463dec043441b7d/ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6", size = 10535860, upload-time = "2024-12-12T15:16:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c5/0aabdc9314b4b6f051168ac45227e2aa8e1c6d82718a547455e40c9c9faa/ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939", size = 10346327, upload-time = "2024-12-12T15:17:02.88Z" }, + { url = "https://files.pythonhosted.org/packages/1a/78/4843a59e7e7b398d6019cf91ab06502fd95397b99b2b858798fbab9151f5/ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d", size = 9942585, upload-time = "2024-12-12T15:17:05.629Z" }, + { url = "https://files.pythonhosted.org/packages/91/5a/642ed8f1ba23ffc2dd347697e01eef3c42fad6ac76603be4a8c3a9d6311e/ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13", size = 10797597, upload-time = "2024-12-12T15:17:08.657Z" }, + { url = "https://files.pythonhosted.org/packages/30/25/2e654bc7226da09a49730a1a2ea6e89f843b362db80b4b2a7a4f948ac986/ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18", size = 10307244, upload-time = "2024-12-12T15:17:11.603Z" }, + { url = "https://files.pythonhosted.org/packages/c0/2d/a224d56bcd4383583db53c2b8f410ebf1200866984aa6eb9b5a70f04e71f/ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502", size = 11362439, upload-time = "2024-12-12T15:17:14.605Z" }, + { url = "https://files.pythonhosted.org/packages/82/01/03e2857f9c371b8767d3e909f06a33bbdac880df17f17f93d6f6951c3381/ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d", size = 12078538, upload-time = "2024-12-12T15:17:18.155Z" }, + { url = "https://files.pythonhosted.org/packages/af/ae/ff7f97b355da16d748ceec50e1604a8215d3659b36b38025a922e0612e9b/ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82", size = 11616172, upload-time = "2024-12-12T15:17:22.919Z" }, + { url = "https://files.pythonhosted.org/packages/6a/d0/6156d4d1e53ebd17747049afe801c5d7e3014d9b2f398b9236fe36ba4320/ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452", size = 12919886, upload-time = "2024-12-12T15:17:26.693Z" }, + { url = "https://files.pythonhosted.org/packages/4e/84/affcb30bacb94f6036a128ad5de0e29f543d3f67ee42b490b17d68e44b8a/ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd", size = 11212599, upload-time = "2024-12-12T15:17:31.053Z" }, + { url = "https://files.pythonhosted.org/packages/60/b9/5694716bdefd8f73df7c0104334156c38fb0f77673d2966a5a1345bab94d/ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20", size = 10784637, upload-time = "2024-12-12T15:17:34.31Z" }, + { url = "https://files.pythonhosted.org/packages/24/7e/0e8f835103ac7da81c3663eedf79dec8359e9ae9a3b0d704bae50be59176/ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc", size = 10390591, upload-time = "2024-12-12T15:17:37.518Z" }, + { url = "https://files.pythonhosted.org/packages/27/da/180ec771fc01c004045962ce017ca419a0281f4bfaf867ed0020f555b56e/ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060", size = 10894298, upload-time = "2024-12-12T15:17:41.53Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f8/29f241742ed3954eb2222314b02db29f531a15cab3238d1295e8657c5f18/ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea", size = 11275965, upload-time = "2024-12-12T15:17:45.971Z" }, + { url = "https://files.pythonhosted.org/packages/79/e9/5b81dc9afc8a80884405b230b9429efeef76d04caead904bd213f453b973/ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964", size = 8807651, upload-time = "2024-12-12T15:17:48.588Z" }, + { url = "https://files.pythonhosted.org/packages/ea/67/7291461066007617b59a707887b90e319b6a043c79b4d19979f86b7a20e7/ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9", size = 9625289, upload-time = "2024-12-12T15:17:51.265Z" }, + { url = "https://files.pythonhosted.org/packages/03/8f/e4fa95288b81233356d9a9dcaed057e5b0adc6399aa8fd0f6d784041c9c3/ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936", size = 9078754, upload-time = "2024-12-12T15:17:53.954Z" }, +] + +[[package]] +name = "scipy" +version = "1.16.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/ca/d8ace4f98322d01abcd52d381134344bf7b431eba7ed8b42bdea5a3c2ac9/scipy-1.16.3.tar.gz", hash = "sha256:01e87659402762f43bd2fee13370553a17ada367d42e7487800bf2916535aecb", size = 30597883, upload-time = "2025-10-28T17:38:54.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/5f/6f37d7439de1455ce9c5a556b8d1db0979f03a796c030bafdf08d35b7bf9/scipy-1.16.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:40be6cf99e68b6c4321e9f8782e7d5ff8265af28ef2cd56e9c9b2638fa08ad97", size = 36630881, upload-time = "2025-10-28T17:31:47.104Z" }, + { url = "https://files.pythonhosted.org/packages/7c/89/d70e9f628749b7e4db2aa4cd89735502ff3f08f7b9b27d2e799485987cd9/scipy-1.16.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:8be1ca9170fcb6223cc7c27f4305d680ded114a1567c0bd2bfcbf947d1b17511", size = 28941012, upload-time = "2025-10-28T17:31:53.411Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a8/0e7a9a6872a923505dbdf6bb93451edcac120363131c19013044a1e7cb0c/scipy-1.16.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bea0a62734d20d67608660f69dcda23e7f90fb4ca20974ab80b6ed40df87a005", size = 20931935, upload-time = "2025-10-28T17:31:57.361Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c7/020fb72bd79ad798e4dbe53938543ecb96b3a9ac3fe274b7189e23e27353/scipy-1.16.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:2a207a6ce9c24f1951241f4693ede2d393f59c07abc159b2cb2be980820e01fb", size = 23534466, upload-time = "2025-10-28T17:32:01.875Z" }, + { url = "https://files.pythonhosted.org/packages/be/a0/668c4609ce6dbf2f948e167836ccaf897f95fb63fa231c87da7558a374cd/scipy-1.16.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:532fb5ad6a87e9e9cd9c959b106b73145a03f04c7d57ea3e6f6bb60b86ab0876", size = 33593618, upload-time = "2025-10-28T17:32:06.902Z" }, + { url = "https://files.pythonhosted.org/packages/ca/6e/8942461cf2636cdae083e3eb72622a7fbbfa5cf559c7d13ab250a5dbdc01/scipy-1.16.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0151a0749efeaaab78711c78422d413c583b8cdd2011a3c1d6c794938ee9fdb2", size = 35899798, upload-time = "2025-10-28T17:32:12.665Z" }, + { url = "https://files.pythonhosted.org/packages/79/e8/d0f33590364cdbd67f28ce79368b373889faa4ee959588beddf6daef9abe/scipy-1.16.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7180967113560cca57418a7bc719e30366b47959dd845a93206fbed693c867e", size = 36226154, upload-time = "2025-10-28T17:32:17.961Z" }, + { url = "https://files.pythonhosted.org/packages/39/c1/1903de608c0c924a1749c590064e65810f8046e437aba6be365abc4f7557/scipy-1.16.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:deb3841c925eeddb6afc1e4e4a45e418d19ec7b87c5df177695224078e8ec733", size = 38878540, upload-time = "2025-10-28T17:32:23.907Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d0/22ec7036ba0b0a35bccb7f25ab407382ed34af0b111475eb301c16f8a2e5/scipy-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:53c3844d527213631e886621df5695d35e4f6a75f620dca412bcd292f6b87d78", size = 38722107, upload-time = "2025-10-28T17:32:29.921Z" }, + { url = "https://files.pythonhosted.org/packages/7b/60/8a00e5a524bb3bf8898db1650d350f50e6cffb9d7a491c561dc9826c7515/scipy-1.16.3-cp311-cp311-win_arm64.whl", hash = "sha256:9452781bd879b14b6f055b26643703551320aa8d79ae064a71df55c00286a184", size = 25506272, upload-time = "2025-10-28T17:32:34.577Z" }, + { url = "https://files.pythonhosted.org/packages/40/41/5bf55c3f386b1643812f3a5674edf74b26184378ef0f3e7c7a09a7e2ca7f/scipy-1.16.3-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81fc5827606858cf71446a5e98715ba0e11f0dbc83d71c7409d05486592a45d6", size = 36659043, upload-time = "2025-10-28T17:32:40.285Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0f/65582071948cfc45d43e9870bf7ca5f0e0684e165d7c9ef4e50d783073eb/scipy-1.16.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c97176013d404c7346bf57874eaac5187d969293bf40497140b0a2b2b7482e07", size = 28898986, upload-time = "2025-10-28T17:32:45.325Z" }, + { url = "https://files.pythonhosted.org/packages/96/5e/36bf3f0ac298187d1ceadde9051177d6a4fe4d507e8f59067dc9dd39e650/scipy-1.16.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2b71d93c8a9936046866acebc915e2af2e292b883ed6e2cbe5c34beb094b82d9", size = 20889814, upload-time = "2025-10-28T17:32:49.277Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/178d9d0c35394d5d5211bbff7ac4f2986c5488b59506fef9e1de13ea28d3/scipy-1.16.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3d4a07a8e785d80289dfe66b7c27d8634a773020742ec7187b85ccc4b0e7b686", size = 23565795, upload-time = "2025-10-28T17:32:53.337Z" }, + { url = "https://files.pythonhosted.org/packages/fa/46/d1146ff536d034d02f83c8afc3c4bab2eddb634624d6529a8512f3afc9da/scipy-1.16.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0553371015692a898e1aa858fed67a3576c34edefa6b7ebdb4e9dde49ce5c203", size = 33349476, upload-time = "2025-10-28T17:32:58.353Z" }, + { url = "https://files.pythonhosted.org/packages/79/2e/415119c9ab3e62249e18c2b082c07aff907a273741b3f8160414b0e9193c/scipy-1.16.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:72d1717fd3b5e6ec747327ce9bda32d5463f472c9dce9f54499e81fbd50245a1", size = 35676692, upload-time = "2025-10-28T17:33:03.88Z" }, + { url = "https://files.pythonhosted.org/packages/27/82/df26e44da78bf8d2aeaf7566082260cfa15955a5a6e96e6a29935b64132f/scipy-1.16.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fb2472e72e24d1530debe6ae078db70fb1605350c88a3d14bc401d6306dbffe", size = 36019345, upload-time = "2025-10-28T17:33:09.773Z" }, + { url = "https://files.pythonhosted.org/packages/82/31/006cbb4b648ba379a95c87262c2855cd0d09453e500937f78b30f02fa1cd/scipy-1.16.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c5192722cffe15f9329a3948c4b1db789fbb1f05c97899187dcf009b283aea70", size = 38678975, upload-time = "2025-10-28T17:33:15.809Z" }, + { url = "https://files.pythonhosted.org/packages/c2/7f/acbd28c97e990b421af7d6d6cd416358c9c293fc958b8529e0bd5d2a2a19/scipy-1.16.3-cp312-cp312-win_amd64.whl", hash = "sha256:56edc65510d1331dae01ef9b658d428e33ed48b4f77b1d51caf479a0253f96dc", size = 38555926, upload-time = "2025-10-28T17:33:21.388Z" }, + { url = "https://files.pythonhosted.org/packages/ce/69/c5c7807fd007dad4f48e0a5f2153038dc96e8725d3345b9ee31b2b7bed46/scipy-1.16.3-cp312-cp312-win_arm64.whl", hash = "sha256:a8a26c78ef223d3e30920ef759e25625a0ecdd0d60e5a8818b7513c3e5384cf2", size = 25463014, upload-time = "2025-10-28T17:33:25.975Z" }, + { url = "https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c", size = 36617856, upload-time = "2025-10-28T17:33:31.375Z" }, + { url = "https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d", size = 28874306, upload-time = "2025-10-28T17:33:36.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/65/3a9400efd0228a176e6ec3454b1fa998fbbb5a8defa1672c3f65706987db/scipy-1.16.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:5803c5fadd29de0cf27fa08ccbfe7a9e5d741bf63e4ab1085437266f12460ff9", size = 20865371, upload-time = "2025-10-28T17:33:42.094Z" }, + { url = "https://files.pythonhosted.org/packages/33/d7/eda09adf009a9fb81827194d4dd02d2e4bc752cef16737cc4ef065234031/scipy-1.16.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:b81c27fc41954319a943d43b20e07c40bdcd3ff7cf013f4fb86286faefe546c4", size = 23524877, upload-time = "2025-10-28T17:33:48.483Z" }, + { url = "https://files.pythonhosted.org/packages/7d/6b/3f911e1ebc364cb81320223a3422aab7d26c9c7973109a9cd0f27c64c6c0/scipy-1.16.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0c3b4dd3d9b08dbce0f3440032c52e9e2ab9f96ade2d3943313dfe51a7056959", size = 33342103, upload-time = "2025-10-28T17:33:56.495Z" }, + { url = "https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88", size = 35697297, upload-time = "2025-10-28T17:34:04.722Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6496dadbc80d8d896ff72511ecfe2316b50313bfc3ebf07a3f580f08bd8c/scipy-1.16.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:663b8d66a8748051c3ee9c96465fb417509315b99c71550fda2591d7dd634234", size = 36021756, upload-time = "2025-10-28T17:34:13.482Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bd/a8c7799e0136b987bda3e1b23d155bcb31aec68a4a472554df5f0937eef7/scipy-1.16.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eab43fae33a0c39006a88096cd7b4f4ef545ea0447d250d5ac18202d40b6611d", size = 38696566, upload-time = "2025-10-28T17:34:22.384Z" }, + { url = "https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl", hash = "sha256:062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304", size = 38529877, upload-time = "2025-10-28T17:35:51.076Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/9d9fbcaa1260a94f4bb5b64ba9213ceb5d03cd88841fe9fd1ffd47a45b73/scipy-1.16.3-cp313-cp313-win_arm64.whl", hash = "sha256:50a3dbf286dbc7d84f176f9a1574c705f277cb6565069f88f60db9eafdbe3ee2", size = 25455366, upload-time = "2025-10-28T17:35:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a3/9ec205bd49f42d45d77f1730dbad9ccf146244c1647605cf834b3a8c4f36/scipy-1.16.3-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:fb4b29f4cf8cc5a8d628bc8d8e26d12d7278cd1f219f22698a378c3d67db5e4b", size = 37027931, upload-time = "2025-10-28T17:34:31.451Z" }, + { url = "https://files.pythonhosted.org/packages/25/06/ca9fd1f3a4589cbd825b1447e5db3a8ebb969c1eaf22c8579bd286f51b6d/scipy-1.16.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:8d09d72dc92742988b0e7750bddb8060b0c7079606c0d24a8cc8e9c9c11f9079", size = 29400081, upload-time = "2025-10-28T17:34:39.087Z" }, + { url = "https://files.pythonhosted.org/packages/6a/56/933e68210d92657d93fb0e381683bc0e53a965048d7358ff5fbf9e6a1b17/scipy-1.16.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:03192a35e661470197556de24e7cb1330d84b35b94ead65c46ad6f16f6b28f2a", size = 21391244, upload-time = "2025-10-28T17:34:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7e/779845db03dc1418e215726329674b40576879b91814568757ff0014ad65/scipy-1.16.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:57d01cb6f85e34f0946b33caa66e892aae072b64b034183f3d87c4025802a119", size = 23929753, upload-time = "2025-10-28T17:34:51.793Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/f756cf8161d5365dcdef9e5f460ab226c068211030a175d2fc7f3f41ca64/scipy-1.16.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:96491a6a54e995f00a28a3c3badfff58fd093bf26cd5fb34a2188c8c756a3a2c", size = 33496912, upload-time = "2025-10-28T17:34:59.8Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/222b1e49a58668f23839ca1542a6322bb095ab8d6590d4f71723869a6c2c/scipy-1.16.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cd13e354df9938598af2be05822c323e97132d5e6306b83a3b4ee6724c6e522e", size = 35802371, upload-time = "2025-10-28T17:35:08.173Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8d/5964ef68bb31829bde27611f8c9deeac13764589fe74a75390242b64ca44/scipy-1.16.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63d3cdacb8a824a295191a723ee5e4ea7768ca5ca5f2838532d9f2e2b3ce2135", size = 36190477, upload-time = "2025-10-28T17:35:16.7Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f2/b31d75cb9b5fa4dd39a0a931ee9b33e7f6f36f23be5ef560bf72e0f92f32/scipy-1.16.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e7efa2681ea410b10dde31a52b18b0154d66f2485328830e45fdf183af5aefc6", size = 38796678, upload-time = "2025-10-28T17:35:26.354Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1e/b3723d8ff64ab548c38d87055483714fefe6ee20e0189b62352b5e015bb1/scipy-1.16.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2d1ae2cf0c350e7705168ff2429962a89ad90c2d49d1dd300686d8b2a5af22fc", size = 38640178, upload-time = "2025-10-28T17:35:35.304Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f3/d854ff38789aca9b0cc23008d607ced9de4f7ab14fa1ca4329f86b3758ca/scipy-1.16.3-cp313-cp313t-win_arm64.whl", hash = "sha256:0c623a54f7b79dd88ef56da19bc2873afec9673a48f3b85b18e4d402bdd29a5a", size = 25803246, upload-time = "2025-10-28T17:35:42.155Z" }, + { url = "https://files.pythonhosted.org/packages/99/f6/99b10fd70f2d864c1e29a28bbcaa0c6340f9d8518396542d9ea3b4aaae15/scipy-1.16.3-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:875555ce62743e1d54f06cdf22c1e0bc47b91130ac40fe5d783b6dfa114beeb6", size = 36606469, upload-time = "2025-10-28T17:36:08.741Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/043b54f2319f48ea940dd025779fa28ee360e6b95acb7cd188fad4391c6b/scipy-1.16.3-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bb61878c18a470021fb515a843dc7a76961a8daceaaaa8bad1332f1bf4b54657", size = 28872043, upload-time = "2025-10-28T17:36:16.599Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/24b7e50cc1c4ee6ffbcb1f27fe9f4c8b40e7911675f6d2d20955f41c6348/scipy-1.16.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2622206f5559784fa5c4b53a950c3c7c1cf3e84ca1b9c4b6c03f062f289ca26", size = 20862952, upload-time = "2025-10-28T17:36:22.966Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3a/3e8c01a4d742b730df368e063787c6808597ccb38636ed821d10b39ca51b/scipy-1.16.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7f68154688c515cdb541a31ef8eb66d8cd1050605be9dcd74199cbd22ac739bc", size = 23508512, upload-time = "2025-10-28T17:36:29.731Z" }, + { url = "https://files.pythonhosted.org/packages/1f/60/c45a12b98ad591536bfe5330cb3cfe1850d7570259303563b1721564d458/scipy-1.16.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3c820ddb80029fe9f43d61b81d8b488d3ef8ca010d15122b152db77dc94c22", size = 33413639, upload-time = "2025-10-28T17:36:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/71/bc/35957d88645476307e4839712642896689df442f3e53b0fa016ecf8a3357/scipy-1.16.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d3837938ae715fc0fe3c39c0202de3a8853aff22ca66781ddc2ade7554b7e2cc", size = 35704729, upload-time = "2025-10-28T17:36:46.547Z" }, + { url = "https://files.pythonhosted.org/packages/3b/15/89105e659041b1ca11c386e9995aefacd513a78493656e57789f9d9eab61/scipy-1.16.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aadd23f98f9cb069b3bd64ddc900c4d277778242e961751f77a8cb5c4b946fb0", size = 36086251, upload-time = "2025-10-28T17:36:55.161Z" }, + { url = "https://files.pythonhosted.org/packages/1a/87/c0ea673ac9c6cc50b3da2196d860273bc7389aa69b64efa8493bdd25b093/scipy-1.16.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b7c5f1bda1354d6a19bc6af73a649f8285ca63ac6b52e64e658a5a11d4d69800", size = 38716681, upload-time = "2025-10-28T17:37:04.1Z" }, + { url = "https://files.pythonhosted.org/packages/91/06/837893227b043fb9b0d13e4bd7586982d8136cb249ffb3492930dab905b8/scipy-1.16.3-cp314-cp314-win_amd64.whl", hash = "sha256:e5d42a9472e7579e473879a1990327830493a7047506d58d73fc429b84c1d49d", size = 39358423, upload-time = "2025-10-28T17:38:20.005Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/28bce0355e4d34a7c034727505a02d19548549e190bedd13a721e35380b7/scipy-1.16.3-cp314-cp314-win_arm64.whl", hash = "sha256:6020470b9d00245926f2d5bb93b119ca0340f0d564eb6fbaad843eaebf9d690f", size = 26135027, upload-time = "2025-10-28T17:38:24.966Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6f/69f1e2b682efe9de8fe9f91040f0cd32f13cfccba690512ba4c582b0bc29/scipy-1.16.3-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:e1d27cbcb4602680a49d787d90664fa4974063ac9d4134813332a8c53dbe667c", size = 37028379, upload-time = "2025-10-28T17:37:14.061Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2d/e826f31624a5ebbab1cd93d30fd74349914753076ed0593e1d56a98c4fb4/scipy-1.16.3-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:9b9c9c07b6d56a35777a1b4cc8966118fb16cfd8daf6743867d17d36cfad2d40", size = 29400052, upload-time = "2025-10-28T17:37:21.709Z" }, + { url = "https://files.pythonhosted.org/packages/69/27/d24feb80155f41fd1f156bf144e7e049b4e2b9dd06261a242905e3bc7a03/scipy-1.16.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:3a4c460301fb2cffb7f88528f30b3127742cff583603aa7dc964a52c463b385d", size = 21391183, upload-time = "2025-10-28T17:37:29.559Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d3/1b229e433074c5738a24277eca520a2319aac7465eea7310ea6ae0e98ae2/scipy-1.16.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:f667a4542cc8917af1db06366d3f78a5c8e83badd56409f94d1eac8d8d9133fa", size = 23930174, upload-time = "2025-10-28T17:37:36.306Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/d9e148b0ec680c0f042581a2be79a28a7ab66c0c4946697f9e7553ead337/scipy-1.16.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f379b54b77a597aa7ee5e697df0d66903e41b9c85a6dd7946159e356319158e8", size = 33497852, upload-time = "2025-10-28T17:37:42.228Z" }, + { url = "https://files.pythonhosted.org/packages/2f/22/4e5f7561e4f98b7bea63cf3fd7934bff1e3182e9f1626b089a679914d5c8/scipy-1.16.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4aff59800a3b7f786b70bfd6ab551001cb553244988d7d6b8299cb1ea653b353", size = 35798595, upload-time = "2025-10-28T17:37:48.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/42/6644d714c179429fc7196857866f219fef25238319b650bb32dde7bf7a48/scipy-1.16.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:da7763f55885045036fabcebd80144b757d3db06ab0861415d1c3b7c69042146", size = 36186269, upload-time = "2025-10-28T17:37:53.72Z" }, + { url = "https://files.pythonhosted.org/packages/ac/70/64b4d7ca92f9cf2e6fc6aaa2eecf80bb9b6b985043a9583f32f8177ea122/scipy-1.16.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa6eea95283b2b8079b821dc11f50a17d0571c92b43e2b5b12764dc5f9b285d", size = 38802779, upload-time = "2025-10-28T17:37:59.393Z" }, + { url = "https://files.pythonhosted.org/packages/61/82/8d0e39f62764cce5ffd5284131e109f07cf8955aef9ab8ed4e3aa5e30539/scipy-1.16.3-cp314-cp314t-win_amd64.whl", hash = "sha256:d9f48cafc7ce94cf9b15c6bffdc443a81a27bf7075cf2dcd5c8b40f85d10c4e7", size = 39471128, upload-time = "2025-10-28T17:38:05.259Z" }, + { url = "https://files.pythonhosted.org/packages/64/47/a494741db7280eae6dc033510c319e34d42dd41b7ac0c7ead39354d1a2b5/scipy-1.16.3-cp314-cp314t-win_arm64.whl", hash = "sha256:21d9d6b197227a12dcbf9633320a4e34c6b0e51c57268df255a0942983bac562", size = 26464127, upload-time = "2025-10-28T17:38:11.34Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[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, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[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, upload-time = "2025-05-09T16:34:51.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, +] + +[[package]] +name = "sphinx" +version = "8.2.3" +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 = "roman-numerals-py" }, + { 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/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, +] + +[[package]] +name = "sphinx-gallery" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pillow" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/14/9238ac61932299b38c20c7c37dbfe60348c0348ea4d400f9ef25875b3bf7/sphinx_gallery-0.20.0.tar.gz", hash = "sha256:70281510c6183d812d3595957005ccf555c5a793f207410f6cd16a25bf08d735", size = 473502, upload-time = "2025-12-02T15:51:37.277Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/fd/818a53d4da56ef2da7b08f77bb3a825635941d1fcc6b6a490995dec1a81c/sphinx_gallery-0.20.0-py3-none-any.whl", hash = "sha256:188b7456e269649945825661b76cdbfbf0b70c2cfd5b75c9a11fe52519879e4d", size = 458655, upload-time = "2025-12-02T15:51:35.311Z" }, +] + +[[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, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[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, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[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, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[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, upload-time = "2019-01-21T16:10:16.347Z" } +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, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[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, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[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, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + +[[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, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tomli" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +] + +[[package]] +name = "toolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/d6/114b492226588d6ff54579d95847662fc69196bdeec318eb45393b24c192/toolz-1.1.0.tar.gz", hash = "sha256:27a5c770d068c110d9ed9323f24f1543e83b2f300a687b7891c1a6d56b697b5b", size = 52613, upload-time = "2025-10-17T04:03:21.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl", hash = "sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8", size = 58093, upload-time = "2025-10-17T04:03:20.435Z" }, +] + +[[package]] +name = "torch" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/56/2eae3494e3d375533034a8e8cf0ba163363e996d85f0629441fa9d9843fe/torch-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:236f501f2e383f1cb861337bdf057712182f910f10aeaf509065d54d339e49b2", size = 99093039, upload-time = "2025-06-04T17:39:06.963Z" }, + { url = "https://files.pythonhosted.org/packages/e5/94/34b80bd172d0072c9979708ccd279c2da2f55c3ef318eceec276ab9544a4/torch-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:06eea61f859436622e78dd0cdd51dbc8f8c6d76917a9cf0555a333f9eac31ec1", size = 821174704, upload-time = "2025-06-04T17:37:03.799Z" }, + { url = "https://files.pythonhosted.org/packages/50/9e/acf04ff375b0b49a45511c55d188bcea5c942da2aaf293096676110086d1/torch-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:8273145a2e0a3c6f9fd2ac36762d6ee89c26d430e612b95a99885df083b04e52", size = 216095937, upload-time = "2025-06-04T17:39:24.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2b/d36d57c66ff031f93b4fa432e86802f84991477e522adcdffd314454326b/torch-2.7.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730", size = 68640034, upload-time = "2025-06-04T17:39:17.989Z" }, + { url = "https://files.pythonhosted.org/packages/87/93/fb505a5022a2e908d81fe9a5e0aa84c86c0d5f408173be71c6018836f34e/torch-2.7.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:27ea1e518df4c9de73af7e8a720770f3628e7f667280bce2be7a16292697e3fa", size = 98948276, upload-time = "2025-06-04T17:39:12.852Z" }, + { url = "https://files.pythonhosted.org/packages/56/7e/67c3fe2b8c33f40af06326a3d6ae7776b3e3a01daa8f71d125d78594d874/torch-2.7.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c33360cfc2edd976c2633b3b66c769bdcbbf0e0b6550606d188431c81e7dd1fc", size = 821025792, upload-time = "2025-06-04T17:34:58.747Z" }, + { url = "https://files.pythonhosted.org/packages/a1/37/a37495502bc7a23bf34f89584fa5a78e25bae7b8da513bc1b8f97afb7009/torch-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:d8bf6e1856ddd1807e79dc57e54d3335f2b62e6f316ed13ed3ecfe1fc1df3d8b", size = 216050349, upload-time = "2025-06-04T17:38:59.709Z" }, + { url = "https://files.pythonhosted.org/packages/3a/60/04b77281c730bb13460628e518c52721257814ac6c298acd25757f6a175c/torch-2.7.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:787687087412c4bd68d315e39bc1223f08aae1d16a9e9771d95eabbb04ae98fb", size = 68645146, upload-time = "2025-06-04T17:38:52.97Z" }, + { url = "https://files.pythonhosted.org/packages/66/81/e48c9edb655ee8eb8c2a6026abdb6f8d2146abd1f150979ede807bb75dcb/torch-2.7.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:03563603d931e70722dce0e11999d53aa80a375a3d78e6b39b9f6805ea0a8d28", size = 98946649, upload-time = "2025-06-04T17:38:43.031Z" }, + { url = "https://files.pythonhosted.org/packages/3a/24/efe2f520d75274fc06b695c616415a1e8a1021d87a13c68ff9dce733d088/torch-2.7.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:d632f5417b6980f61404a125b999ca6ebd0b8b4bbdbb5fbbba44374ab619a412", size = 821033192, upload-time = "2025-06-04T17:38:09.146Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d9/9c24d230333ff4e9b6807274f6f8d52a864210b52ec794c5def7925f4495/torch-2.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:23660443e13995ee93e3d844786701ea4ca69f337027b05182f5ba053ce43b38", size = 216055668, upload-time = "2025-06-04T17:38:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/95/bf/e086ee36ddcef9299f6e708d3b6c8487c1651787bb9ee2939eb2a7f74911/torch-2.7.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0da4f4dba9f65d0d203794e619fe7ca3247a55ffdcbd17ae8fb83c8b2dc9b585", size = 68925988, upload-time = "2025-06-04T17:38:29.273Z" }, + { url = "https://files.pythonhosted.org/packages/69/6a/67090dcfe1cf9048448b31555af6efb149f7afa0a310a366adbdada32105/torch-2.7.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:e08d7e6f21a617fe38eeb46dd2213ded43f27c072e9165dc27300c9ef9570934", size = 99028857, upload-time = "2025-06-04T17:37:50.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/1c/48b988870823d1cc381f15ec4e70ed3d65e043f43f919329b0045ae83529/torch-2.7.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:30207f672328a42df4f2174b8f426f354b2baa0b7cca3a0adb3d6ab5daf00dc8", size = 821098066, upload-time = "2025-06-04T17:37:33.939Z" }, + { url = "https://files.pythonhosted.org/packages/7b/eb/10050d61c9d5140c5dc04a89ed3257ef1a6b93e49dd91b95363d757071e0/torch-2.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:79042feca1c634aaf6603fe6feea8c6b30dfa140a6bbc0b973e2260c7e79a22e", size = 216336310, upload-time = "2025-06-04T17:36:09.862Z" }, + { url = "https://files.pythonhosted.org/packages/b1/29/beb45cdf5c4fc3ebe282bf5eafc8dfd925ead7299b3c97491900fe5ed844/torch-2.7.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:988b0cbc4333618a1056d2ebad9eb10089637b659eb645434d0809d8d937b946", size = 68645708, upload-time = "2025-06-04T17:34:39.852Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + +[[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, upload-time = "2024-04-19T11:11:49.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, +] + +[[package]] +name = "triton" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/2f/3e56ea7b58f80ff68899b1dbe810ff257c9d177d288c6b0f55bf2fe4eb50/triton-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b31e3aa26f8cb3cc5bf4e187bf737cbacf17311e1112b781d4a059353dfd731b", size = 155689937, upload-time = "2025-05-29T23:39:44.182Z" }, + { url = "https://files.pythonhosted.org/packages/24/5f/950fb373bf9c01ad4eb5a8cd5eaf32cdf9e238c02f9293557a2129b9c4ac/triton-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9999e83aba21e1a78c1f36f21bce621b77bcaa530277a50484a7cb4a822f6e43", size = 155669138, upload-time = "2025-05-29T23:39:51.771Z" }, + { url = "https://files.pythonhosted.org/packages/74/1f/dfb531f90a2d367d914adfee771babbd3f1a5b26c3f5fbc458dee21daa78/triton-3.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b89d846b5a4198317fec27a5d3a609ea96b6d557ff44b56c23176546023c4240", size = 155673035, upload-time = "2025-05-29T23:40:02.468Z" }, + { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832, upload-time = "2025-05-29T23:40:10.522Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[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, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[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, upload-time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/1d/0f3a93cca1ac5e8287842ed4eebbd0f7a991315089b1a0b01c7788aa7b63/urllib3-2.6.1.tar.gz", hash = "sha256:5379eb6e1aba4088bae84f8242960017ec8d8e3decf30480b3a1abdaa9671a3f", size = 432678, upload-time = "2025-12-08T15:25:26.773Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/56/190ceb8cb10511b730b564fb1e0293fa468363dbad26145c34928a60cb0c/urllib3-2.6.1-py3-none-any.whl", hash = "sha256:e67d06fe947c36a7ca39f4994b08d73922d40e6cca949907be05efa6fd75110b", size = 131138, upload-time = "2025-12-08T15:25:25.51Z" }, +] + +[[package]] +name = "wadler-lindig" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/67/cbae4bf7683a64755c2c1778c418fea96d00e34395bb91743f08bd951571/wadler_lindig-0.1.7.tar.gz", hash = "sha256:81d14d3fe77d441acf3ebd7f4aefac20c74128bf460e84b512806dccf7b2cd55", size = 15842, upload-time = "2025-06-18T07:00:42.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/96/04e7b441807b26b794da5b11e59ed7f83b2cf8af202bd7eba8ad2fa6046e/wadler_lindig-0.1.7-py3-none-any.whl", hash = "sha256:e3ec83835570fd0a9509f969162aeb9c65618f998b1f42918cfc8d45122fe953", size = 20516, upload-time = "2025-06-18T07:00:41.684Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, +] + +[[package]] +name = "zstandard" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254, upload-time = "2025-09-14T22:16:26.137Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559, upload-time = "2025-09-14T22:16:27.973Z" }, + { url = "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020, upload-time = "2025-09-14T22:16:29.523Z" }, + { url = "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126, upload-time = "2025-09-14T22:16:31.811Z" }, + { url = "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390, upload-time = "2025-09-14T22:16:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914, upload-time = "2025-09-14T22:16:35.277Z" }, + { url = "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635, upload-time = "2025-09-14T22:16:37.141Z" }, + { url = "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277, upload-time = "2025-09-14T22:16:38.807Z" }, + { url = "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377, upload-time = "2025-09-14T22:16:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493, upload-time = "2025-09-14T22:16:43.3Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018, upload-time = "2025-09-14T22:16:45.292Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672, upload-time = "2025-09-14T22:16:47.076Z" }, + { url = "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753, upload-time = "2025-09-14T22:16:49.316Z" }, + { url = "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047, upload-time = "2025-09-14T22:16:51.328Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484, upload-time = "2025-09-14T22:16:55.005Z" }, + { url = "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183, upload-time = "2025-09-14T22:16:52.753Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533, upload-time = "2025-09-14T22:16:53.878Z" }, + { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, + { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, + { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" }, + { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" }, + { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" }, + { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" }, + { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" }, + { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, + { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" }, + { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" }, + { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" }, + { url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload-time = "2025-09-14T22:17:31.044Z" }, + { url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload-time = "2025-09-14T22:17:32.711Z" }, + { url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload-time = "2025-09-14T22:17:34.41Z" }, + { url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload-time = "2025-09-14T22:17:36.084Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload-time = "2025-09-14T22:17:37.891Z" }, + { url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload-time = "2025-09-14T22:17:40.206Z" }, + { url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload-time = "2025-09-14T22:17:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload-time = "2025-09-14T22:17:43.577Z" }, + { url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload-time = "2025-09-14T22:17:45.271Z" }, + { url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload-time = "2025-09-14T22:17:47.08Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload-time = "2025-09-14T22:17:48.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" }, + { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" }, + { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" }, + { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" }, + { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" }, + { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" }, +] From 88a728212820dc79cf02d5524eddf20d6283aa7d Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Wed, 10 Dec 2025 10:43:18 +0900 Subject: [PATCH 2/6] feat: Add mmjson file type support, update file type inference, and introduce a parsing verification script with example data. --- .../2hhb.cif.gz | Bin .../2hhb.json.gz | Bin mmjson_verification/verify_mmjson.py | 101 ++++++++++++++++++ src/atomworks/io/utils/io_utils.py | 15 ++- 4 files changed, 114 insertions(+), 2 deletions(-) rename {example_mmjson => mmjson_verification}/2hhb.cif.gz (100%) rename {example_mmjson => mmjson_verification}/2hhb.json.gz (100%) create mode 100644 mmjson_verification/verify_mmjson.py diff --git a/example_mmjson/2hhb.cif.gz b/mmjson_verification/2hhb.cif.gz similarity index 100% rename from example_mmjson/2hhb.cif.gz rename to mmjson_verification/2hhb.cif.gz diff --git a/example_mmjson/2hhb.json.gz b/mmjson_verification/2hhb.json.gz similarity index 100% rename from example_mmjson/2hhb.json.gz rename to mmjson_verification/2hhb.json.gz diff --git a/mmjson_verification/verify_mmjson.py b/mmjson_verification/verify_mmjson.py new file mode 100644 index 00000000..9e5f6244 --- /dev/null +++ b/mmjson_verification/verify_mmjson.py @@ -0,0 +1,101 @@ + +import sys +from pathlib import Path +import numpy as np +import logging + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger("verify_mmjson") + +try: + from atomworks.io.parser import parse + from atomworks.io.utils.io_utils import infer_pdb_file_type +except ImportError: + # Add src to path if running from root without package installed in editable mode + sys.path.append(str(Path(__file__).parent.parent / "src")) + from atomworks.io.parser import parse + from atomworks.io.utils.io_utils import infer_pdb_file_type + +PROJECT_ROOT = Path(__file__).parent.parent +EXAMPLE_DIR = Path(__file__).parent + +def verify_mmjson_parsing(): + print("Starting mmJSON verification...") + + json_path = EXAMPLE_DIR / "2hhb.json.gz" + cif_path = EXAMPLE_DIR / "2hhb.cif.gz" + + if not json_path.exists(): + print(f"Error: mmJSON file not found at {json_path}") + return + if not cif_path.exists(): + print(f"Error: CIF file not found at {cif_path}") + return + + # 1. Test File Type Inference + print("\n1. Testing File Type Inference...") + inferred_type = infer_pdb_file_type(json_path) + if inferred_type == "mmjson": + print(f"✅ Correctly inferred 'mmjson' from {json_path.name}") + else: + print(f"❌ Failed to infer 'mmjson'. Got: {inferred_type}") + + # 2. Parse mmJSON + print("\n2. Parsing mmJSON file...") + try: + result_json = parse(json_path, file_type="mmjson") + atoms_json = result_json["asym_unit"] + print(f"✅ Successfully parsed mmJSON. Loaded {atoms_json.array_length()} atoms.") + except Exception as e: + print(f"❌ Failed to parse mmJSON: {e}") + return + + # 3. Parse CIF for Comparison + print("\n3. Parsing CIF file for comparison...") + try: + result_cif = parse(cif_path, file_type="cif") + atoms_cif = result_cif["asym_unit"] + print(f"✅ Successfully parsed CIF. Loaded {atoms_cif.array_length()} atoms.") + except Exception as e: + print(f"❌ Failed to parse CIF: {e}") + return + + # 4. Compare Results + print("\n4. Comparing mmJSON vs CIF results...") + + # Compare Atom Count + if atoms_json.array_length() == atoms_cif.array_length(): + print("✅ Atom count matches.") + else: + print(f"❌ Atom count mismatch: JSON {atoms_json.array_length()} != CIF {atoms_cif.array_length()}") + + # Compare Coordinates + try: + np.testing.assert_allclose(atoms_json.coord, atoms_cif.coord, rtol=1e-3, atol=1e-3) + print("✅ Coordinates match (within tolerance).") + except AssertionError as e: + print(f"❌ Coordinates mismatch: {e}") + + # Compare Elements + if np.array_equal(atoms_json.element, atoms_cif.element): + print("✅ Elements match.") + else: + print("❌ Elements mismatch.") + + # Compare Residue Names + if np.array_equal(atoms_json.res_name, atoms_cif.res_name): + print("✅ Residue names match.") + else: + print("❌ Residue names mismatch.") + + # Compare Chain IDs + if np.array_equal(atoms_json.chain_id, atoms_cif.chain_id): + print("✅ Chain IDs match.") + else: + print("❌ Chain IDs mismatch.") + + print("\nVerification finished.") + +if __name__ == "__main__": + verify_mmjson_parsing() diff --git a/src/atomworks/io/utils/io_utils.py b/src/atomworks/io/utils/io_utils.py index 5d160f17..b2eee443 100644 --- a/src/atomworks/io/utils/io_utils.py +++ b/src/atomworks/io/utils/io_utils.py @@ -45,7 +45,18 @@ logger = logging.getLogger("atomworks.io") -CIF_LIKE_EXTENSIONS = {".cif", ".pdb", ".bcif", ".cif.gz", ".pdb.gz", ".bcif.gz", ".json", ".json.gz"} +CIF_LIKE_EXTENSIONS = { + ".cif", + ".pdb", + ".bcif", + ".cif.gz", + ".pdb.gz", + ".bcif.gz", + ".json", + ".json.gz", + ".mmjson", + ".mmjson.gz", +} @contextmanager @@ -365,7 +376,7 @@ def infer_pdb_file_type( return "bcif" elif inferred_file_type == "sdf": return "sdf" - elif inferred_file_type == "json": + elif inferred_file_type in ("json", "mmjson"): return "mmjson" else: raise ValueError(f"Unsupported file type: {inferred_file_type}") From 2f0ea72eff2749ae0affea467c9a361ed26ad72d Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Thu, 11 Dec 2025 09:31:21 +0900 Subject: [PATCH 3/6] feat: add automated mmJSON parsing test and refactor buffer file type inference in `io_utils.py`. --- mmjson_verification/2hhb.cif.gz | Bin 131968 -> 0 bytes mmjson_verification/2hhb.json.gz | Bin 85741 -> 0 bytes mmjson_verification/verify_mmjson.py | 101 --------------------------- src/atomworks/io/utils/io_utils.py | 43 ++++++------ tests/io/tools/test_mmjson.py | 33 +++++++++ 5 files changed, 56 insertions(+), 121 deletions(-) delete mode 100644 mmjson_verification/2hhb.cif.gz delete mode 100644 mmjson_verification/2hhb.json.gz delete mode 100644 mmjson_verification/verify_mmjson.py create mode 100644 tests/io/tools/test_mmjson.py diff --git a/mmjson_verification/2hhb.cif.gz b/mmjson_verification/2hhb.cif.gz deleted file mode 100644 index 19767c42f907f39b856ba9342aca7c6ee679d666..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131968 zcma%ibzGED)3%C&f`Cd%cXv0dbR*p$-Q5VRNQ;1Uv(nw&ARyh{BHg+4?tV8u&-Z@M z+uuL;nVB z%l1bm!0hks@ngq}?Vs;&m!Li0^lpc(=n6|JKedXM)${qJcest23f&&QY`kjlo*SJF z-!{uZ2!lW+BBO>RAlTy^w!7oOL;G57q)#hyHm|q57lfEDQx5n25NBZc86I^rt=SdN zA}jbYjf{b<=HRj+Zga@=9;@G4Rg+Tc@Zh~EoNf_nRjE57F$$+&#Gw(gB}q(sO0j(0 z)79miuQO&!U|=Xt%iG1Nh7XVJ_F_VWl^cR2WR|cf!VnZ#YrIR@v4(#Bwq0HnjWJcS zdwkw_(cpuS8!4Rv*;(r)7O>%a=$4^oGfeXGxA|Rz4r@l1J&Pr(Yo~$xoeu(L=Jgrj zb&BB8P4x-&sujtYr|Dzp*P$BUwQYx8Rv_y1B}c1VG8D6^zGml?RnPa|Qbw;LS>^V^{Lz0gDo`g=WPhi_Y z!nfd@B=N3i&&uP+`S(E@qFz5+LrTP;`}y6TQ=@Q)dtgrQ=8;je_k6vs|GJvT4&wVW z+eFsXWz+*|fmW^ZOUC(~!!s*-l=VU)rsEEpsw1EJ!R^g;R119JK1D?o!qP67GamCy z)VOi|qL6girb&(8oJ4BkriR(P1X#y6(x7fIUF{Df8|GfQ(s@CBqp=U8SvWL1>bYe1 zp7TotgCrpJ&KW|&Q^$sNsSd0t-umZ6^V=ymb0o7%d+k4N=(s8rkB47k4C^0chYX(& zPFh#`eVz%ULq)HFXEQyDBT4x+;g~VvTtzq6nh%3*X)D6FXjy3;`Z?nUq9-632?P0K zw$4=b+y2Rh1XJ6a?(~ecT|TsCx*419(B_(`ke)x(q*c|8Cv#IVVy5p?(6+WkZs~<_@M)h7%q_&reWf!OA>tRqk2i;{X68+VUylm z+n?wD?1fs9L{VR_<|+%4)JAliN3-W3#Q>}XJ|4u?Bu|K|9vtyvdlX}9 z6}sX4jv&H-Cu#f+(hu%OK?=qevScFf^iy0j9qDco>*}!m<8`UAhnhnf@L?tn_$g{rt zVTGH*0Yl<}W4*kzBMrlYG0x3dP>kW+Jq0}azHkuIBGCQ=iuXtAEcP}Z6a$$8eR6}x zO@k28_c`#Ms0~^ut6?f6q614AX6cuCJ_|}QtX-qBt8O1dedT_|<~h|cv(Br~bjFJt zDBMVLS0_XbS9RUI(sXD|EH73)0#D9vuHM`%9z>}v%aau^`yHtpZjDCuw;MWOHHOZE zrx{D9vzH&`_3WP=Cmmk1f}zyqr2)@#~6+BVa#)Ze#3SSkYggdPgbVxjDgDj*BKL4U!`*gff zi25+&b9JLWkfjZ&FE2Qd52!m;|JXhg0-k$ zWOInHUK#R630k4FvqE@SUlrD8T3U3_DCT#WvW@XBW(e3^O{l%*dFA2Vwj@%%BEFuH z^6E{pbM=znB4RXkr^;g`z(tzk-l$e{`<1X8kv;fO^V9Q%ra(mfO45p~ zDk63~?Zbv`zTP^AZ7kYrErX^bsSXg9#He(pz26A4W^aQI|BdC@T;a>bd2OF_{@dF_ zugXZ0#8gllSf2^PYnZ_U(b%`FjEXTxmVj9{FUbh+O~$ofvhXUkR>$8f#l?BWN!Q0o zvm`NQwHp{fpsP}(D^gBO-MY&C!o4y?iB7NR9WUCmuqCKzGbgEzsGU^qdt?!+@vz3o zYL%8!MfE@pSgfLTqrN@a3X_LQ)nQdM-r}%8Oeul)uuw!9uIy{X21t3kLVQ47E|){x zb-Mj-41#Z_=3w#x`96HT;d=YxbOe19JJqN8-dOSYN9`=w2T`Rb1sjDJxoe^(&Cy(C zg+nbG8}&d1M-XM*IXO!FeRyKb@5G^cwFSY5+kI&L%Hf&Ej^77+))*V>IjzLJX)|J| z!)V!EyEv(NRl39}kK9I;Qmug81Y~CKrLOOlTeDspaoL9Hvs8Pl`E6(0(v7iXU&FzL zV-3M+ceAyo{bc`e0~TGV1VR6n7v8dtAQ(&k0uH})Kh;;kQ(Db^Ykxy4LnKvL7-#G8 zn#*^25m5q-b>D7CxQz~GjkM+GFW^QtiY#Y^emM?g_|uD+&L!e1tWCTBjvPkt6`Xa~ zh&zGHJg5CWlwlzDi4FdGfyhlF#{LMH_UBo;qNNM)`L^jH`0MV|?&uF_Rds@6Rl6Id zFA68Q>+h{WkCWCWc}^EhS32nj7_>SMt%sy070(F6*V3LmCfARxNxSF zI8p?g6Uxm>E`CovG;fc?fiNRx!gmK!oeNsD6tOPq zOc9DBs?Hc7{#F&$LN2;O>PH(weV|;gKAg@jO|~lNx@c6w{NAod1@Er;tl^5D$faVG zy$O`n(j*#oY;EGA9D*i(m&$zBLY)gaP;~bl*i%;2Djsz{7%g`|!4s=GS+h}Uybk2= zR=E+tMn=jVX=B0N51Q&s9!Pg)7~&a~<2SP&m%Xyb`6DyJ?^ZQeipMx+??BW4EFYsC zMzgtc0WYFXOcRLhI<#u^rSzRp<4|kcD7PVta9t6Y=-?EC*1qN}(%hyp3V#Vd;{}wboX3)%G#R-WWmcz`PLn#;z9Dq$kuCMpLx(MY(t41)Y9U z3-xM|mRvMVn**HU~VWQk*u~)D>7xtXez>N<)YIARJwl&cNc6bv@gp@jZZXtX;*q`CTMA{O#?a)+e zaJGH;CtT;*oaq-opLro)Fb`i`t!qwx?D!_s)7#hGiJG=>9J&gE^WUn1y*YQK0%Q<> zWJlCxGB%u8hgH`dSI8;O=(H`e1!-jmimV&)3K&@!BXS~ICA^xCZLF&5XFX7H$BT_0F(b%me4A5)0s;bW={ZRS39eZqjJ;P_q`svU;6?Acp za-rLhC25n6#|zTn`g^$|gS3Lj6ykqOZ_K$v7%qoaySrTlsyWkZRt`zGm5QMb&ZC4B z!VWX37PU7yRK9(6_s5My-RJq61{$RAcY7;_Npbhd7}KUfJo}}gcRiPb&L9uf=AZgV zFf;nz?)5VzRjZf#==Z?e;wZm56@CI+o`&7|ArepT?wr6Aq){S~ciC`P*H2y|>FKLW z%dPEqo_?JCq>2`?rzME`yQ}s7YuMc#yaLqPytjHqd)2kJIjj!$=Ga%V=-SNzd4XD6 zNmrH()7v2fdI7r^aQlU0r958P_|38c!fyhi5OO@451WS_9Qk?kenOmHZh+u;GX)6q zA0c|pZ)hi*Q^$8;C1CI@L^QqpC?xytRBOi5hjFkG;dwr|ylOu>Dph@6S#q{KTmc62 zw>5dO5*F?W6JL#5be*bcSa`Z|_=4I5k5?5evUg3{d_eILjrjWMa?0z)ce}9P24@N* zy~mj=yjS4;D-iq;2J;2`tR|u-pu_l-Q|=A5ORIUsL@1#5MZ;PnBoWd0S%e{26v?kz zyk&p?7NVh5fEILg%Is|koLl6awD&`E%$odPukdWrrCf;mPg%G&iLC9b%$Q{>LzP`u zA(A%Nk6m_LFWw_QOZ3^g7K1zFnYpvT9Ypkk5{S?0@4@cb;Eo&-7~dr5W1}xG`xEOP z_gruv_jg7$7B4-L#-C1En_q(OzpFPib8mKV31|3mflwKKI_sOy z`0%u!QsvqRo8kvDslunHrT%mUpJTQP>2mY-B3|gCayJmCl2#!nW(%H+&HOg!-~e$j zkkP`BJ{k9F#Ei%?PM}#S_?fbg>n42oO2#~FiC*;0p@A8JVwqBx z1vD>Ft`xKZ$-_rKb=M2obA)JH(^UogtgE#d?P5@WdI?P#Y*IGX>E@I}#&~DV1IYpVnA35A~R_H}ZQ%$m=e;5S_ zisP!x9`>^YKC5TgiAwZ}s$#bT_wAY;0EQ!A6d>-*c6MG;EoS zA#TCwSc-nthI#7f*epBum@$Grnei8|YLJ~(Tx)S37Ajl(@yH(n-(#~5A>xW(O(V;t z-JVXrm$f0Im7vv8{8}ae_{4pyky88`7;*U}4f}2@{_$0TU-K5jch?&w+%bCfd z@#;`sFp$Rji5xir`vKtX`fbdlzBr_-l1QOUhik#3Y2k>ChGV4{} zTq*fvdnG^l^U1y^&i(N~VYh^VTmc~TY-0+;xd_QI?iVXS-wypO=7NV$mbQroSLK5s z*b4L6B}&i_VHQ?n?nGQLehQ%tOMjENBd+RJANt z=yBQNR=?>=ix{lKe$&}~DvHBKjhwjDlQ{g5#a$pfAZhbKS+Kyw*qFQYJ+m}chcd=N zU`#a4R1MzV7t|jD1-m{UREa-l*Wf;hoX|ia%ALmGlU-DCjI$?ki&XjWP^If+tZSUO zjzV5O6^&O+ph}<(z*@B5G9yi~DCj{x%cf8O&bBx;4SRWtz5rt*XXgwU0fli2O7GZM ziW}uIt5(-@09R9)pT3FI>L8EHF^(lF4O@R%r3i_iK892c#p*plVgfL)?|^BLt4eB0 z3oOtCrXl7{#DL8Bv;ts#k$f2R3yx=8yWb;H1Cxk}wCyJ??e3ZMYg_bL6k*ziKyVFp z8bp}e3$zFp6*wa|Z!6Q+jm}>R+GBluZnkRM&NNfJeC~5qF~MFJf;$53%AfXWzeX|+ zSd#>6m$e@Pf3YX##t~B-)Q3+uCAS$Ky00eK?Yck%G0`%5^*^%}ffPIVUl{=g12>XNJ~i9B?m!_vxzB z{`8)L@yTl|bW(wI+YDZg8wrAmBejuDX9jhdV~l&HQZsNCpYut;Xet3wGR*4BAC~v% zSfReDojY`%M5b6Z@xF!*Gpi7fZ^n^kqE?p$$TV4#ySi9j5oD|BH~d6x10=;*2W z0`3~{31$agB42qvnk9pyAGRaFt)4iNiDG~FbjeHWx-iDigFW;%Abia#-!V7grB_b% zuKyzFF&+^v3%y6S$&|4h$?y<6$R>;3_f>m#g_ihT6(=%Sn6PUSp0k2QWy2`eUcCWsQ*TZO366T{<% zcbCsySw5+;kc=b_5ShVF(~h1Bxo9!RID4=QiEanYc6e2zjA`7$o!G{vu)t8 zj#fjCJWE+Q1}3=TJTNkgs`!&AO?t;0ZYDjIG7-h*ElJ9jx}VC-5-V~W=9^C=1sCK` z$CSfxS)MJ4J4{Y)u^+!ENzt|T`y?z}B<2*j@Sf@lNm%Oxq=SbMK#1J`kk(+kx#=$D z6^=FcA}~m9pr9JmAE)cGCbJxn-v8n$yH4P$UrTfsc%of^Oz(0_{0I`q%y2_7;w@^g zruZ>_h2nnw5PFbwv!oLa6<5zHeO5HgXb-Kk}2hDQ!oA@W72zmvb<&%Sy|rjA~b)D8jjK#!9e<_ zUMCxsq>a_R;sMSA~k>5dvc(8v^+uW{J;fRE0ZVn8rGk+uVvZNc)kSSc=h6j1F-|5t^v16Nt8~hH`VQjq&rk}#$AA_4OCK_T^x?TN$wLSqCBc&;&mdIpUJwBITjb>9 zbHIt|Y1B7hw?p)m+hd?r3h#uF0o-ri;?@Aths5B5tMg-h_252M`y(R}h zK01Wr_zN0jCJiF7)F{9NK0K-9bClLB-g;oM7|XMfr7;R0-QrjsZsft5|J zyA5yxS~K(%$U776i4R!cLPK)^K>r?0V_SgL5BtzIKz-aw&Vm9UnKafbitS-)bvm04v)xnKhsSz3`*~ zVi=}~Ho6|F{R;?$L;@k1qQgc^Kv8esP!s`F3UZNco&iKBUIjfYs^}zwK*&3+SB(#< z9DTPdPhkW>Mk(W*l_j<0Erw) zLmPof%@jo^zyu)cDv|SnIsIZw0D2hLJ?=RXz^NoP_zlpn&(V}a4`Z>P7ySk3K?SGi zOY(oPLVLIZcrTA$0T3x4Uxfj?Q%?ib0|gDp(b(xE0f@b40SyUp0g!Qd z;}F1V>VS-g3Q!J8!IxP%MP$&2dBp-gzX8X~Cq`nfEa{@i7}gZ4*Hpz1Li;F z9!yN)7?Wd+l9u$ToiTv#kvo0rd%{V;sWntAFLU<0=u6S$AcNtb-*n37hsMWj`ufm| z9t=xz^DkGDLktLm1EnnqywP#2zZU{{W4f9<@m2VG+~}>rd*-iZ0TVFL#sDC2=D7-D z<^E0NeyKoNl3BLqgzo`e^z}JlCg;g^15hrW{OPvZ;qEqnwEGYy zke@l*(YJ@%s=^bXmY=ElEor=Q)-pZV0IBu!jyr*OPdt(tXM+cTQJHLl0xU_?#+v{X zTOq~Qj9>#X-~>VeXY+X+?_67Ap#GWH-nnJNzpnwGjmPLeA;4yE;2ao;dZ<46IBzVI=1-%^dG!F z6Ax-O3FL7mQ1+wle6fe5rYDWB0dMY3A!SkExPyLI(*PLOg)h#4gXs`Gxxof@ajY{I zK4#9E%bh0U0_w|mJ_|trR?r_8Ho&=p*GDuMQ1^N)EFK_r|EO|5m|yvE1R5e8-+F9A29Lm#*a!g>D?{>}2Q z!p!2oYX9OmZt^b}|MU^ycYWkRuZ!ZCSmpLV2;xzHeMVaU=KpW-|Bc#1B7kFADN=*n zyujz?xPJ&)z5f*c&GIjT>*m;B*#C;;f2Q5Uw*Tlzr4Hjai`oB&pnv85Kh*Xgx9l1J zQl|8l|Nr1V=x%q|q5o?JW68|+-wPzd=C+69CjWjb^^f~+784tkBaXU%FGP`W{s#-n zQB{(dpkrcXEs_Vm?*A@mOXm|e49+e1H-9Vr-vuV)|4X@xN9fTKu|OTmZx*BdCr5Ao z7vW#}{k-*mI)VMe|N4X?#~A+wv;If! zX3hU;dj2_Kz>B%=^5G5rFEdxA;Pl_jQ;5NT9yRTu%>R9!{%z)%awh-tUHES;xa|MR z>pxx!lp_M3W3#@k)O_Y+(aVAeP4Z8!@UxFmZ#}0gdrzIeQ(k1PfBrt={nWsPs3-)H zu>L6OQ~xQQ>~zRSa^$q#9ijU`w3Rw1XA-l$yYjCFMQjg-lPOx0ly>7A9N!5RQjBMc zEDiU8eIfRs8=Gby2{7sAUUl`?jG_;KYq8SqtCj?0o%(TdYxJ4qnlbf;rVo!#$b@;J ztU5bEh2VKn*6GDV^{0H&A>Um|iW{uHV^r?w1*inLYK?3NP!Z%IZSbpCj(A-1#J3zBIW8kbn=N!tj0KrFD5sM z^enk_=lpWus916@CLW_@6tPJqVW8k9e{~4lrT6*#&W@|gwGc$#Vja&4r47=wgCPxu zXQ}8Guo2tVYv=|63$I2vf=z#mnfno?P@CzB3hR%bu8;cjt;gTwb;&5^X)qdjqZ(!? zqlG^>q19$RpEO&kQX2uuCwdLadchv7wWOGUkzvN3S-N~J_K9`m^HC6oLvHWKBn&0Y z9rm|*U9UCsen}^>oNF`^P#QH2>Ea9^cey6lGsL3@?{YY(7m8p207V+UZ}SFQ+)5T6 z7H*-TG0{X93ze=g-Eg?GX9-38MZ%d2-`yZpYc9z&DrZjdwwT`4D<2q*lO3@)kcA?GPMO6O>_%K(eTP zFK|7oNBRwUcQ1`sy*C68eRL`{v-&8TcdCY$g$Jm0dA^m;?o2$*D{V6^ijFAk#|<-zo5Jf()A5Rqvg~}ebBhFh^qJ(#)s`jx>>kG)gE;?y zP~z+_Azp;UR}d#O;GzBSP=9#1Jv_34BJW099v*dPPKbFL(kqA+p?oK18PMK>7J*;ENuK*5ljoWy$7K1nR|1@{0zt(p4$uNszpH@W4!tLwn+!61l1jqBJZ72 zRogb8VB4Jy!&Phg0fTbQ7$C+m16KLPjdeJueKHteB-snIm=FaXa(7OMH=MWq;_5HC~y`D@E({2wayl4HKOF~0Y!ruXq0yC4hk>};eL*QSOYZ8P3~?O zjy3Rnau_~YuXH?ix#)dv#k*>|ji_F--%1S$xiN0{T7fQEnGyC5pV-1%y!1rIv8H&; z&v&XM?qcKq2P{fyC?}uKwWW^BG&Ae@f7Lzivj#@nTY3A%UXZK1o0k0l%z6uoD=h zK~^tOJn&{U^Aqlj?tJSFg`&T#MptbGFQM)8TAc{9%nH6c6=KB`T$y8A-861TG~I`+ z;RrVdTbuZ5+mo73ZZ{8OSyCPM!wh0Qt}66f4>VJ`XSr*3oS--7?#mO{)3{wmIX99L ze7K_!jSq>ivzwm%sYku{${3N;Se3w6NY1TWg>0J*P*QE{>dDq*n(+Cdbp+bF89kGe znL+~_X1|vA2G5QC#tm9$gtmLPz4Q+7&O;pThPOx0%Zpi^74K>U!4ety!yr*@jKpf+ zl^guV6_U+W!SAc{5}86|?TktjjGPJRb}h|@Udr|7qv0W~7cF)gWAXXJs7+@}BZ$g* z_)HA#QNJ+Lz0KgA7w{#OI-x#JL;L#F!>A4NF4nl-NiR9{=3o`w>@QvhxVpQXmxG7J z!AxYxn)|R$A^Y6>79CQnGOE!(QIzL>n}_yD)%Uj@LlS39GvBulK(UAz1lWw^)bI>Z zJ`@X2yhrTs)A*4o-69?G3q-kkwg>p{mBu>^^=>Hh@FEmGjc9J(xRPNiUSTc{+w&rP zPiwr>c=5=Dl%&wE+hY+80Uj}WhN~E?Ww##L+FWf7r1}!E{&(V ze&fSjd%AKr#hbCAzZX<*>ufLn1NXf?&MVm=y2!Hh6%(wkSsXtw zr%DXI%HHi==?9;{s=er6IZgAxJklvy6Eh|hG~>Ic)QtkZ&ay^e7-a?+L?Kf zpfrf0Wf1%;6Jl|G=gdfa;KOyt)-LRf-+flV(Y$Tn#nQ-{-#c=}GCE)BQeTt`Z~oLu zuwqm3EJ=sVLr$he$YTY5J9BANz03l^ErO8n$Tdy~u70M^0NqQI zj5hO@^vkEVgWx9cs%0OYk^1o7>7qqz1roZ0S}%9QdfKx!fK4Pd_5XoA9B4X)onJ;U* z@2nH~kl51qRSf^Y?K2dseSqxLPtMKPKso*BJ#dx0i^j@hvU&N%T)Tv+{=f$5cLVw1BnD zi*)sGg%qb+I?q7%-^YpbPD~@wPz&5d-R&OafqcLoZiu#3gxNjZZwYeIn;o?dF8~oQ z8)PV1Z1Z|}93P8htjdpsOwOAM?IRB1Fi#FY1iTG&pmbbzdj;!1XWj^04KF-%NXA?9-|1JwLuC(kL_E-ukMzyC~lFCD`HR zy$_cl=^*Or^2@uc#P#CTtE#Y~nMo&v4-b)&nOU$V?c~*Z^Lg7+Z$w^f=Lt-WXVcu( zjYT4&{3!n_;8Q;@KWTf2&gv4PbQN)3e|2>QJM}f>(d0Q_7oQa{eK)2nybQ^prbAs4 z+bu$ymVud62N0w9YAt35#A^v!4=Q@m(fv@LafW$*n0aG8#ZbHm$3gpmIh9uBiful> zu&qBo_PhvO1 z<4^OYcXLH==++LOr;3zkbg*=(xJmwQlVn8D^v~;g5}wr|MJ}6;m=@cLc)wj=9lMO@ z&#C*6&_WfFaTpIaDk8bV6z?olkidHg!_#e5Pc^2n&Qj{}&04+pYwh(X-|7@W>HL?{ zId1stZ)miZ5;vPHz*;(9PkMjra!z4Z5WX9`m$9#}y@01y^9JyC@n-XGJN$B> zabQ`whYsKIPVy!?l%;U1=e}QAADXNzwzn)1*Nj>SlIke<;*ekZW-8@}@^7Kh^BJbl ziX`1rjzLm~w)Pvy4AaUM2_;S?%tKt!IS{*@#o~4#&4BJV)C_fIL~{!plt+Hrb%+gG z8o3BrOolsx&ye~ya1P}K7i8){Y_MIYq^BB^4?le&xtBW5+<77yP4L3~{e|02&24t_ zqjZp}DkfK5|a)c^A?-YH>4k`Y1d+E8p|E|@mtlU8DM6va0aXATt zm(+y*UMI&uA0v`MG(Q(~*d(9P(`iI7=166e! zm5;!Laa#$C=rzd+FGVhq1~|F8o3}BdW4<=QFPun~^C&DQC6#%Tjy{B!4sDo(XpX)i zViW+%_4Dad6e1)@Z#Z?zGblNIU`R?w88IR$Nqh2cR`A^FpvtjnU>N0<>)w8^RE&hh zwj@^k#PmB~HbRo`-VZePdqcRsa0-izOa-VO4_VZ#k>_|&{Y93hV}qzT z!%g1Z_jcSybzC&?P0Y{vDJ!7auP~>EFd!B?MI7 zd`LJaMfw9mo&mq~8v};)Gp`=};!2e=GgDtk8c|d|N z#9JK%`#r#Qz><%R71s@JB7NUGb{n+@5L1@u${Y_PBo+Gu3U>E-2?p>52qM2J0tLN6 zu-Cv%t^?qd5!q{vGDg$f z=SguoybOn~8{f@oJH6a|7W(IhdH4I_P_dNPy;hP$x%lIS_|q#hz9J?&6I!}-j}~2i zJasB~>QoU}CnCn3)4R)cct8j#&ixs|(S`0%;dW`VFdda?IY7W(AsC>Hp^RhHHZQ_b zPk!cpPE{?_!;(P~BfYxGM4fMQ&vY>@T@dI&BP622YH}p8O*t|kXcQIk?tUT z0Ik}m3yC>gmAThNdp~cGqxQLDZF33qaiRp$@K=4|?~68RDX(?ru!y>bGUP!WgAn;+ z^UDn2v89w(e;S<8e7q%G_A^rx)%A=-b9s#M*@9<(%VH<3!DQDT9AT!1g&SDL|DpY3 zi99ws{Yru>b?JDULZWCm-nDDv&F8CtnP0xMc7Y?D)|M4Asd?e(?eh;yC<(?IuFsiI zqiV(5^}&*DTCmPl-Vy-|&PsI8V-7tiCfk&oQV*qKw-Uq2!6UIZy~06^ajAydf-2G@}J1=s1P#DLRudUF0g-AhrT05+&(F8$>(xcfm6j}U>0%B zN~*%B;z<}P66D@Z|GcFwy!eQ=hR%Wt#twiZpwBdt@vmi!Z^u~f`XMbHmGRr|$hLXA z#s%jY@3q1ps=wzmpEy~|shDt?XH*^T_a4M+4iGbvU3T0>|evz`6I9k)KYIs_R2jittNrdEY`SWsnBO~Otj%4%S zEj?rh%rqJ+WGxSgCk-;uutE79)m_i5vtRQ~%BRVqto7eP7(NJmthOHXQ$#~Sc^lKf zCK-!J!zE#2D_8L6o4gN4iz6{)#ge#jQ4X;#4_x-Yv{{*-I1usvk1kc|EMkAiJDYjXk2=|b1H87+vyCz~mf ztbvmU+cl1kpUJ~)gqbGpw`)#5`g={QV)i_EhNHP^==?3Yh>M+}^l!;@vs~VJGW(G1 ziM7|hTE)OSk_)kit6@&WGm`9442wzUEPfiH0w>N$_tf&HRf;6{Y1tkp3^5~F205Si z4ac(fR=_W9SLUmhyj-t-?2(0;Z*@{#imLIy&dAW$LuW1fHGc5NK4-WCFt8w zq7?Nyz4R-^pYt|UY1%IeV>{~VBto9Tpz8evRHii;IiGqSzxWU$E7O<$bnELG(i`MD zjAzq1#bU(7-`Tj_o)bX4P5XEs#TUSzt5_bR^fBkxkO*5g1d?#bYkG$`?S=f%v0IH^ zv>6lNu!O-V?I1_#jDoE^BSXw#LczG5eKJfd;S@io}qXp$9FML=4KO-BbFwCn-4Xb&1fBd`*FGE@JsJH292WeBuP%m z+2A#i?D$v|$KbE#Xks{~rviyU8){LDapcAuCkJoa5&K&LuKe;L=#QEjIb$~@Xb;s$ng<)+igf=El<>YMj>}Y> zwu&6uVMD4x&)s8(D){?NaX9wP0#Z$bhh=DrOHB*?$#*-As!`69X6J{cySBc?(PnIX zk-pqdLo?<1=qgBwp313`;oN^R5AoP=7)kRQa+f6Fv7o}#$u;n9{w~L*)!6y?-tV-6 z_N0hS__{QXjqw@(P^^jPFeSYABt_yxxy8HxQ)v7bB8=0C+7ohv+Lv{h7qsPL$(}(Y z-Hfg@k+c6-GRUq*8hRu$jdHB}I)a6bB_6LWRZc<@NhXbJ$w~*~mHJNTOB$_Zysbkz`SozSo}L zN=-s|b4`Bp{X)vl%N_qSCmC)+$Q)@~!&mp9c(DHjZ@na({w2PO;~RSAbaN-${%+$@ zwr|o}64AqNSuP2+*v^no_9#3*$b*C~S(-?s3}h$d*5v$J*BdFaI)@ynpZC&@-jc@xK-;h3th$S?x&9JN3{@sO__*z^=-Y0qyAX|r6U?{?N- zK||k{;z!|6$5nsQ!WuzZPjPg|w4KcmqttaF;jBSYz?0(DCt7xOvYqT1|EF?sv6GiC z#Vagax4S#8pcG~A?Xk9JqC?DyYbGevu6%@aj$DuU;5mtV@BcdEO$druhUb@&U-*lsx)@tFWt6YI+4G#N@- z9$}r5lO7svOpzT+>(r}{m=VU)+0_9ep+UW*v1*{3EE;eE8?J#Y#Q=#=PFg65PZ`I4 z=j=}-7UaskFeqa!GEzviSzetlXl=-%aG%7dPDDlxeGS@p!mg;Q3q2_sL6ZB)!L9Pk z;3t&rROMZL*zF&By7zlzv&Wt4#&Wc{JUV6)-BnMi6Y{7ic3(irHLkycr!^b_TXOZ%xc9>B` z_xavOyS3EL6D|-_eW7qf%Tp^S15_fru2~U@1;!tBXBt{^(r--a(dh$%m%WX1&D2Ni z2Mr_-cwYbNsQGizbu`e?637Y3WqF@0TTg~NgojJE@Fr&JWk@hKYo|MY9+fESz@g*k zpin}L6JgVA-REDZtV(mgwFDL$`r;NaKbKYG^|#+tstKgBXqwJ^lBFx}*whn8)&J=v z+A&*~-;*(G@#ovQ51P3($XnDeeQ~YoUj_OvFv#_Nl3=#cwXDp=L8DZq5@%BQ+&QS) zQ8l&wZTNRk<4+8O>zV4puPNCkHuXY}4-)dJlG7X*Yjg|0R#E6{5H9oNcy7wSF|)qLacO`jS|2_ExeKIU>t16FM;k zX`d6BH8E)0<~y-I9Ah|1%a6yB+L;z?*XB;;6UM^>D~TKzZ_+YK=HBEzRbP~4%w+kE zFU!nh(lqR|Y>vKc{FML$pBTfm$Un+16*n@URK8((C*h&G4kZR^Q{nkzhujN_=vwY3 z<{>psH77Aa+O(S&CXn1R@1T@Ul?wGSyBFjyUwa&SUZyg)#B$awzgM|3Kxq`kqzX!I zp-uZKfA5t0G5vl!jzB&$zlT7c)ll=WW?9z38*0-cOUxdV!aOA_f3bnAdT0qvR>dLo zj_%0HqVvw0T2zM-;H82zk?4y%ET{24yB#z#DYvD$#LzKL^IE!4f_FByPnew5;##vP zg`j6OTC5(Kk=$`de%$iu%d%bz-tlKOt_+1rHV}f05f*NtiVBD9UCl$$MCsJ~K!0s$HtC@4vHBz24}UpQF*rNb=JV#u z?D?L}kX?O*wJXdBnbc@9en+A{`#hXc26R^-a^TM2l&XiB`MLcP<#^g-DKGmjyt&zc zY8S5>t7LR%@95IR)kQF+zx~2vXGF5PS=sAX5y;b}{>*laxBD#YAOKHk#rzieqGj_`LpEw;lggzmWCk8|Cs z%%pK8)vDHyZdD)VShuHM98ZNjx$7EV6}dpa-aYen-#+tgh$m)CX$>tZF3zz`-fex%tFX%VCB!HUD^24k1{~eD9oao97swSzd*F z-Oh3nu5mtW!5`3Be>as{JTH@Wn*>RbCTE#)Q7w{ktYC`zVX#O^JFk?QPor!yP?x$5 z{MP)l!_kY=9agj=yceYlo;-`a)86EAkFimi&VPe$2Z^E;1EFDQZ_Q#b=J&dvW0g;( zo~Tg}HFSV4Ecm~l4>@fmoF986RCjcTc`L*yGTCK0hQ%u!GZ-r7GP*>=I;36U`vrG9n5^&y5ob5;sot%7TcQl&&} z<+?mpsx%)Uk*~?yQLJ_2DoB>e7TS%Ar#zy;Wl^3JU(5<~OpBLuO{$a_$qN;L=Bd29gW$G0-=F#?_-$WiYXRVYKn?2SJO3PWTUZ9%r8?BV6 zS#<%DUlHkw-w7+(W$kAZ=~8`~WZ)mw&r)}eWX_TuaSOLkia8&kQlZ}Frg=k+S1FSt z%kpM}N|xp6gGz5sE6c)>N~dQW8RlBXC{Lm83{)b^QX!$%|Ew;Qq4Aqtma20YbCy_M zH?Fd;sO!a3g9Rz5wmHrC?m2E97ftjImU}-#^d43gaZ2nC76l`N6Y_0ZayLOW7IUW! zk2=M)O8iF(=<_F7VF?VjuK{gdJUnbP8`TO^dI@f2f>dRQh-&m_Dc#>V!w zx^o1;TJd9Z(VN1M2rPLj5?n_d1}AxbRr#E>WErByWb!bVhboQU6wXGVw(3aQBv!gMjz%EbiXMk1+L~TL;s5aT-hpg?-{UY%*kjb?aRR(iq7K-GqEbjN&6C=W-iKz3M-^0U#J zP_9|pQKdPy((}&b*BH%H0If86?uAl(0*Cf+hp3- z%Gj^eJeuK4Uaz`88@q}9NzGG6{Y{r=Ndg2H`eUZTs54RGao9~RO4aPoqt{=BXlmG7 zA~>y|?+QF{IZkUG>(2l`21k5Ao#h zu=j-tP=nh5z~N(A8tK%QO#ISeV*jS0Xu)ghPZFe4w@)QW|M`W8k#OjCb59UPg^qt1 z7tkduW*de0z75Oe1t(6oa=stTl(3L~FKHJ?9!{h2R_NmUwl#4fpa;Xu7m2hLFZ_iC zEd8%p7eL%{sU3z8BUC(f+kg^d?vm|9@}ZgjI=O zP5$}z-KpDr&Pp_{dc)?bvKE8FxSGjqVS$wxSzzkUU|{N%v8qsa=cM;+n^&z}E~O+( zwzX#hmN|6;A~7z>v=ura%kWpfXiN_Ildh|M87=4V2^Khw|5*N4dE(*wK_|%uWEYX$ z4V8~qFkU5sc6D^}Q%@dMi(rVrsNEV+NJzmaWxx_W)1JsBgX z2CR~$nmzv^fLEG*&09i$A4R|RM3c?A5oo_%5oQe&vWa z+0M_F#!8J3zn%OqaQxqU2~9o?j%00(@B$$%<)2|3jlu%irm465!+wodeLCPTjBTME z75pwn(jOn5_w_4SK(}|=g*b#sC>MF@hXiHq5_ttsho)_!*4Xgr|UI-|4$?5 z>1&B9S24^H@CPTDMlUcWf-76?yIA1G`+GX%CG?MDc4USvAn&BIKJOUcwiN68s=F!XJ1U$@9Qs;_azooD$rYl`m z0jzdRKnN zP;U0kbHyT?+JNnSv?}z9JCEA4H@v}DlHhE=k_rF;3B>|>lqlrAQj;!%_(}?3vJ!eX zwtaG7k-)ApXnG6aLKXb_orR?ub%ipFdWZqA$mJ5v@EbIJpN%_Co1Y6FFg~ST(PWrDYPPR0O$zCb&7E1aR7Xj5mg$#XIld{e;)3dP^ROT;c^ERNx-6; zYyFvz0VZGr{;AV|l&NR@g#eS{mfZ^m1ju0>ccn<`%3dI}(2%NXXs(310ILLavJuO! zt`T0w{U<%_^F3)LEx>q0J_1d#?;44;Iv;w1{%ewJaDX}f>tbtHN?xc6H45bszH%~6 zt|~PkbHM-tt)=-32@wnQ7Q4RVVJNzRR~`w3WYHMG0AV?gUG=Cja&w4uD=AP@u*ZD` zg!DMZ9e{7yb|NPLPkwD}tb|&9A}SE;>as!|ta)Ehq#6h!1HwQMsRx1x#eYHMlSfN3 zYY1wm!A%3a(yKe_jZcDN^8Vw?_P-3{q7i<$07$L?u~@WF&SQBmS)bDq0x#Z9I|w z#Y+`X2rcu}L>6h7zi>6)>CeyTiLRCymsgh8C;~p}wTQjuyQw+|k9;daO=C!NKh;HN z=r8XJ2Vf#z4XvydMpfb1$I04y0XcdjA_@FR4h0oS;#uB@N$d|&m0aVmhjo{Vmy#F! zG;uVhp{_N%p^TjBC;Gg2`!P?LQ8{V8SSeg#f?*2%&Grtu+NnAZXFOs&?k(U}`nj35 z_M=_~7QEv)Se6c$+NWbUHfGL;Z=2$fMQcx{{Jy|N9 zF~5DZJ~%DL>LvPB!^yb`#(1}E)SQwM4y4pS?2ZzGyTl0n*H)9ytt?!UJFfq}Zr6>v zLy=_nRZWK``Vr>WQ!b80UaOa?C3O9%U-WyFo&P}|Xw%nlmn z8`hat>OI*2I%&Pd_2MKSd?NPL#OViQBI~@1e?bwQMlz+zFZt9*yKlZ(YlX`64-fk>mKHhHp<_dgbA=i5>Iwwf6H$IebvxHpj zjsFf~;W~$cfq6yXJ#Y0A3Fi@M$FK(!uMd73I;*MphCQ&MtU(D>tfWRCQ}YWl_L^9- zN(le$_;xzM6hUM8Wli;al*1TWUH( zDe{#L_IH$_8#otTX{8K!KigN1@&x6VDoqK&PM=-?%`KH%Wv^A}IYsP4=UHzyo4t~- z%uKlV>*1{QTgrp{$KFA2X{cNNf{Z?ItK4FE`IRv&kb-Z7nf2z&YkQ3M5~X4TWMe={ zfed^DjI3)x*GI(J{yK4xCb8A4k?Fk+6^|`u;~)x(0bQRjSknKs}cn6>**^f=%^Z1vuk?ZVS0kqKpv6vT5uTO3HsD_*WkUrO*8q#_1Kpt z)Vk|S<+paWUa2L~jB%zg_O&g4m|T5v{ddp=s-BN56IZMw{ctBJAvjt~F;*aYh+wKjfcM+%*V)7_ENlDu?{3!_%`z+2D+|!q*#AgZq%%-c)XZ5W60w;{^jn-BZ*)IL&v52H(Hys^b-3l!pP3<-|&a} z>pcu2+|aVPdq~k%23hNtYKv(KBPVW2?jW_MY%h7=81zdIaNsvrPJC8r6JoWN*_6)o zyPDnWt6^tQ$If3h#@o}Cia~eCwxa_=WTpSywH&6rr^5JG@fP>d_DH~wl&_&9E8m!m zzg66Sj{F)bjQqyLHZAc!gj_ORZ0D|j_w4gT;>Twa?{&yuQX1ZW8AEd8O#&tNHvJ1z z$yggAcTJTu71>CpuEa;*uJM_S(R1H?y>eseMgJX=_ajygM6@mQ&xme(SiiBQ(2+SeLtq6CJ97| zpK(vgjE}T_C~K)GYVk3K%{AT7dDK#AGo8)G;V_;3m1FqtJ$)wOFBD}C3^l=q;&&eT zPZ780IoS>W<=vPa{~l~6ZvC91#bM|R?e_(@9NM2(AeKou<%#pir*eMLWfe0&D_&OT z@V=*H#YYWK`)`JMSm{f|!sE#oDcy2|ox~f*uGL#f!khT-4KZz~-P$^8h<(|}o&Mt5 z-qA#g4W-^rq4+RUub!jXU1|eIGbx#x{KY0VjOV%G-bE)4lKAWqwm09L$gV zr#c+aKKa;kOF6VoU#R@muJAIA_WR}N`de8KmDZ20K3 zSc9<_U9NkV8dLt%eZ-+0*7q~I?s?yQOw$D)1sMhYwD`%*UOR)e$195i)~%?)<@c-` zgUjDu9DeJsaXQTFugN^L$c|YHQp(&+@6RK0AGTuGFpbmY`s+r1)Ea7#%MxV+!xe$c|Z_JC>5uyQJaUra%FxJnMlKao)*oDB`7f91Hu*sex)h_lnK$c@wq zz2alaUaUN6aG7>t!M~G^jUxQG8HR+ebS#g_&Ko=-ziLm!$jlq0N@_HQ5MI9bCBj=R z?`zH{koJl@o0G>=EkU2WhXPm2JRi1C_eY&PjeoHLPVsng`h8GZ0{kIq>jf^tswj9$ zJfV>GJpzHpb!%w5uca^OT zsqk_>phOMJmXIEa%a#P=0YG{}=1o79y=QD0>>EN=?cNkQ-5itXvE!~3dD!z*L%O4QE(Y4bv{_7Gci&Mdy0v}yMtba(bRFxEyyJ5M&bk~rPI?(j zdjNdBvgrr@?QY@Fsm*xQ=-{gNS5bd)fhfmv`T4_XkG1&go}&&_=2iUMVR2X;H#SrW zjbv16kHAsy6WdjPU7!E%zs07oJ|aCO-QMN)izrve%l9p2E=doA1AKnx#&kks7xH^7 znr8i|#<$gHnG|HbSDMoobjZSYAhMV2(MPh;NAgeXv3q+vRuzz?)PI=^*3g-ugv)b# zoKGcRhWH#R_{)jGvG09$EPTLclU36TQ-;6kzx%iEF=hyZFg536?|2PcYW#bOMTMz> z={Vh~BK_EP@bB}!my^9E_2txN@c4ar-M5`s!o7^&e(Y75Fx3zL4D8x1PoyuSGOuq! zw!X`9q|5lPUecRd4nJH-aKVn(h@VS}A%@~y!sjQ%HNBO)*8ZJZuhZ9{|IRZwmFiM? z-S$@TQGWNZ{(vpJkMI5%ad91`AuY$y$D3r%J5!Gd zmBi+}J>1g3o0LLt|5+()A^O6+73WUJ(tlYE=p|=3)`%{f3faj1da=uHBuD(GWg<#Qn-R(OXMizLm8Qa z&7NCgWo6zxC<@7t9?|r zN*sw>JL0#rg{6aLP%nq$zUfE)Ycepbe;?Qc9e|KV);j-%I$4t0-;fdQ8FUd9Tr~_+ zH#4_}?VV*+l9Brb&fi{}dQ+DAfvAV#v{aYTF?Y%_Pp;f~;V^}_noQeafh3c+XHWxH zf0FfGdr7B$o>}SDj(>mfQ9F`d7}J7%t}FOWu8Nsjb}t37v( zD)X%KM^0Oy`Ju7I*(7cQH6EO={;IKq4)<3%ei|;gNe1V{5CcwNDNNK*TR#us0;uV5 z6eL()p80jEz>$&)LrhT3<(tM24xn27RnK7Q;r%AMQyicSpqMAT}TK;r1e%?8wuB& z!QPc1Ji)o;{`*|$M}g+OK`HRKe>&!ij$&ynGWB~iZJbs4vx*mL%&VM)E0u9SZG_!TXP&Mjf)(J2RaG2PH}>_5aY?_zk#~-W z>C1(}6IMAR5A9M&mXKfcm{VhoG^l9jDFQmA# z@3i*X>XfY+%y!mj5Kfg23Z-Z{enBWj_Lb#41!QJ)4~q-rraPlNW`BSR*#EtB$~q1S z?XkiMP(vYmtG|Widqmz?8#|=dpH4MF=Z9{!!l^U_OXyro%@aNTDRoAbAf9-Fy+DF% zXu$FBAPxIUZJV_Q-%!1`d63Y*j$lKg$+!$6DW*eOeLt^I1v^~`AWwm@p5WkrqLq-n zEeh>#e6ru5?@cY?g@s4hj-lz(ES>=8wdvzQsYzVKvKWmpZAn_L_agDo8&Ew@ptIGl z6yU~pbV|D%yTC$&6fX|a(~H}#z10=}A%{#NMh_S4nRpoQl|GF#qILx&?=D=%IOm+T zqrl;fFq$Z=MzC49)Sv%$2GB^TFdQkN1JN6bcv!CWKB5iXzg??wHTiC1HALMozwcB( z7prJ%#_i$-GP;iJ!(t2#qq)tAxa zya*@d^nI$(iq<%vp?=JK)f=J9cgck|z2|pNw0?f5Po_#s%mvH5)bhe1)wcdY+3=Fj zB7H(X+9YVI@ReYRhtePXu9Smr?$FRdEU>te+ogJ?%x}+bA63|z3ZP9aWcWhL^D0kW zq>Epo-_AMqIZS$+qFDz)pc%Bdoc3?`Pib4LdEVy~d)K1vkX3(ok={$_2|mhFy$FzG zMxi_3gyx33Re&>lXuWIwmo#I}Ecc>#lh!6Gw7k0(hx?EHSefyCGD{fH74~MH{8f@! z!Z)*A+55uUJtwSPC%4y`#1@q#9Ny+;)y2f{<8|8x;*!!msL?`d%`hjIle&U`Z{~aY zN`IZdlqu6k)+wF$J)O7+=vl)JDmt^X*G@Pq@fr}aUgB709S3nO-OBHRR$l3sz1im( zQ7l^*^)O3ByWcDndPH~EokVMA3VgQN69-?fp{? zLao%%`W0^LJuGXUahiZ4RwifQ+`@X_IaPS!=I zN+ozed%H{&%WPraJo6X*x^u%Z9g=bVgi>qdU>t>W&f8uAY9<)nS48Y4){rd$o)96f zT{h#P2)01nL`fdWJRU{A<%XlhpD)VPf7UMW_e;uu*cDXdo`WsVWwu-E&LgM2zN9{c(U&-yC3(Fbv~vL`>FRRoC`C+8oavEx$iC~Uk9mF~6pVgxf~!RB`m6Y8xCe`(0WVdV)>>)J&h zI)xtifJ4?%aK$0E0lMdzAJOlH+%Ygifcn#}qf-jcn|`IBk8R#b!;*Y(X?v%%ALRmT z)p+ac>ARB{x}CJjhwoU(=fkBdjPR;jY5mfe@01nTBp?V?Fn7CWp_p1KGMOhNBjeCW zF}|l6UM|ZZ?O|!oRQxwtgL+)|mTz1SZp$R@WFU?o-W>Kj1%B!))rF(n$g*^iZF)r= zawHI3=vcVIIi^3@L@D$_LAC%a?)3dgU~jCZ1)3|28&umt+{!{0g+>1Tl{ z`UWjhTa8Sz(I(mF>$)hAAfmRV|Kyr;&e#AIX{!1RMEw`|vBR5kk3Oe)^2Kes&_`MG z5A&p3kn!=Y`}ZASMxynLb$3;H96q8Sp&@~Aiw#%Ie0q53kAB=1|4V?(&)Vr}qh!0Y zcVW&CTM|BMlts~~D+2fuLMFtvDVO2(=8AONG_aFCYMr}Ha@CI)!l~749%ye*gljEOxvsG`!rWI(Ob42ruPxsK8&3%*%N(fcD+00qDG{g&Pgm(IL zYt@ImT*IwNfr(i@F1uWKoMH^GpAs5lmZ*>8EC@3}%@be3rC#lFJ5IF9UaL{K#>s5)TXd0esV$0@h8vVX=aN?qaTjvg4A-&uUURv_0E- zP`ak){D@#L)Ja|!!iT`Sr3;wt(_l1qV3!jZL$<`T@COA)!?U+yVec1cVU(&^JQ^-q1g$#o2peCAHXMdgdnZ3_yIiMkZ>w$Q>vI=o&VDzhPlA?X2X<{Nv73M=T z<$B{}_LPC=nbB0O&ip;zud7X4hIJjC-6zq0J?1mGQd{sH!Go&(6MTj)o#Bb?sRz$3 zc$uRf+RlmO%-{2oujBe4{I1!0u-*2KE%<@p+S#TIJ46gq`_Hq}E#zac9oz#%Xj_sy zit&>@T5sJ~{E{E3Hz<_|7Ag1H0PK%)CZ#St?#QQL&*!3T690w*PMBW$I)t|n;CJ#s z7^u7KGJ?+K9Ar2T5OqRkb%zdCKEbsW#|+AzN$}GxLUu3V4nDXQyaF-4AoJkbM=;`> zd(S24%61idJ<^t81LA7@RLo9PvJhzrGj0CM7mmuu^lO9*^kG(&3!MI$!%ODCGmCF< zWjUu~hNTQ9P^FM@Gx|0|0wN(unjeAnN<;Ukegb`PY((FtrRyf!sqMw@mxPe%{sT0d zjcXiw56_B2jMXc`AD@!0EXyalj}WpW8iz8Sz5JGc(x;L|8Kl}mQx@p3Wuk`j&m|UH zy;RY$>zm#53O-@M??r+!o*-Lm5ZDcXhG;w8Nv-- z+aVmT;JDDydqdts%LDi~z`t*$+)b#8@&sQOGIRV#xxxQ)0wu~R*h?nP51J!;*z5^j zUTF$jj-ovVGj25q{VP!gdmLY-4eNU(FEbj?%#h>COebVdi6dM92g{Dt^cDTX2ZD zc=~p+cEkbjzYn%e?`kfoQ6MCP&w}Sa%*8iUqpX9%q}ndK6ofVf2seWf+>K2nPOzBf zh@Ay6@)wQZtQmG;-qU3{_DFoDAN@j>_%lIK9G!_7-0X@o-91qw?D!+y6S>osqLR8M z_gCEjwvafDx(D_;1>EK`DJ5_NgyVPwH^G}~)Cb}+9dgW?+HhHN!(hQt)CV$)L!-_6{D@=^^g^ z*h<0~@&l8n`A;_Y@9((7l~*P<(Y${;g-*shJAG0XD}pg6Pz=(2Sle8iRR9t;r3b_t ze(rfQ3CCYZFDgy!!i4nW|L}>~b0TXC3sT)W7HgkbE|ulmBU0`=xb7kuJNzDHpn3Z| z=1#VF&X`VfJy^Kgg(~W*%Cx5=zdrB7mqI!EZUSNO+(QDt-^DpN%W|iR8p6_zq$<(A zdq$9;hlI6p4lQHL6$>u~@zydZk^>zw__5>dA@GyB2sF_hd*T!i*lt#qb7}fZx7`n| z;34{ra2dSyIjb|y%ciryx%yHN(kn!kP$j8yxe_)1RmN*;W23Uk$^G(dC82;I5wZ}H z_7|ENJSMm38}Q{^0nz!ehG&3`dMA|Kb-IJddoL1-o=E5u-lGP1>0R=o19{}5{_7>x+F0~ zt73w{&I*Rn&$qb$LoEhrP?ai5VTc0lj+~*G+Jt6LC+(3U|CCxYWy^(zezWE%EEv|j z9c(tXT6Mo0Z2?2YTsAx52@EU zQMULHVaoJ|R|v;|FrA@T&Swv<)fr7CoYHMTUl8QhSoE3FTx#n=(#;Rdjlen5=9W$* z(uT?>F*^&Gk}er+pxv1`;v|-CH*?1@dT~X<7EYov{sst57~in2&QskC@_tg*-C`63 ziM2o)Up8Yo%W<7zxG(hJ2G`hhl=CMtRxH`D&0(VuCNe3Y%x{YBrjSk{rz0{ z*$lGi-HK>3?Vp2CAT#lh@VW*#8QI?bi=G~KUHMni=NCPJETGD$2e6K%b?$Eg&Hh*h z8t|#K)?}SE3w&wy=JncdQKv)^?po<`%Ww}-g6F>a+w>Ps8F+>@_s|-Vlg8j`=+d?= zs5#2c<>0yvQ-K_O!nHLh;%@(Te5ce1=}_mNwIKK7Zb z7y52yp3`WUPnYn_$b2M{qE@zI9dqKa8d)t&Hn^a7dnxg`bjR>LY#s@3ZUG^m(^hUV`oo%JOuI(KIvNjzs1O3}BCBdA4 ztjvSX1@EUV_M7cc0ZPvgl+NtN1#YaHo_)dkDZ^IVCNKUTb4m#sT@Wo4a0?n?+I%}< z3)98Jl~YZ19|iO2raLgx2V3f-Il zZRvWn^hu+_(9ct!@&>o(M_Y9t_th`H;!Sdt%)7-}>yS+*KUyc9RjDE&w!15^z}>;7 zl}fL}wH}rw*tw#7_3PL2?nv50QPBm)leh(LMh?db`9nP)mqR_$+Lv?(t!b(UFxOPD zf5SMCbPh&Bwz}@b469bz#X(*-uB2r;4a)6yj%qKUzoDpgj#5e#Wqj{M=A0%#Y~2s_ zs08WNc!_)MewNmSp?P+g7N)dW zz2i=VC{XzQ&C8PC@6||OprOB%WjU5$1{{1=TeB|*X zp@?lCz7P0|{?vlkVoJ}r?s=}MdrzTLLwukS@7!3uCd}w(Pw-hv`ssLZAi&5+9!?9tHtI{{D-Y1Bry-PO`;|#)Q0G>G5$OG!--x8jcl1S49wKEN9-oNz z1qv=uc1+Th0qfj6jBuRSBEH}Iu19Ls8@Q=}z4;99SZc$Zimg?u7i#eVmsK}FP3jgG z_Chu?V3JCxvj_84Tfv#6A}k`d%!jRF-gB&yC`?!9rHo^desCe@SKFK>_ptY}L- zoR{nNYCF8IAy*Xad?GSBHxA9W-7~$pBrM|GBdsNTjraDh2)MQh9AA6kLRV5F(v;>k~0gMQ<{8f_r3e zf*BJ!*_nQ1sGYD#t$bRrl9cn!7ZFS_nVUKm(SuAX^?k#hld}2b9l6YmBlolLaOb~K8Jc#2g$NRRQM6*(; zSLeB{sIErzyL^x6yUXNB63oLKZ}n>Kt~N=k@o_^f3H(RGr>c5uzE*Oz;wyFR7&!JR|{1iEsi zcwNy(=9Xm_4nHDr9-=74gM+y4MP8KDVKB|mhxl?q7I!_iXHD3+0Cn%(0d5}FaLSJQ zsC*+bupEbwyw_CLQ^!Wt45tF_VJo;o232prwu6t&x+|H~q1)7-V&=Pd%4*>K+Uf2a zz85c}!rXWW%Yk#aNtEKzL0oQ$hx%(X`h%>VL9;VaGsFst+Z8}Rq8kq4YO3i0t4Yfj zIuFVXnL%8TW8hc&LR}Y2Wle5u;r}gEwY7ABqUfPb5VYA8W9C{c9(4%d=2wX#7z<;d`?tb!MlHlPD1L2Doy2o z*MsSHg(Bvdn&Wk?!1r#r{SNOY$gzNZAU5yJ9XV0U8>L@B18cF*KTa*lH<0;W=wD$s zH%iGJY|?(TewdYj-sbjuE>>1kd;PUzZpo>2&yxK8)is_WW*eqg26bJ-YHo-6M^Y~` z-j|&p9dDPZlZ62rc5SS>%c1^rLGdu#2=`Nj ze$}QC^Byn---#&K2s7UrCsd0MbGhqTBR)sk40oD*t{(@Gaet9yBR8kDTRSMvUMdz? zj5irH^PQr_h>7@7XCzprn&EuEALz&rReSEw7>5Yf)d^?zyB)@#FcGeh-upBE=-kbI z48I9MkC2!l>>v7#5K5m5$;~0`4}6%Zh^HTEL51jnR1a7nZsGeO)w@)houY>{>giAO0OrkVrte)X1`g7QXiFK zPiXdLsofrc&(+C@$Ir3evw`!cKdS?9D_6JzDp|PlqVv{hez4hkH6?)F8i3Qx2Y5W5 z374XuG}H$dT$f~NkT<6yaWQWicuMO>?b>zOv%%f2k^c|*b^|{uBx`2vu&`|90P2wD zn0w+C@E3Kvj}geof#YJ6M(bb+Li5AtajH>HS#Qe`CKwRG$FByjeirS|ROoI1xvu54 ziCxSEw)fwk@4^1{Sda%{rdi$pEn}a$Mo|jsIgy;+E?68yQQ}4!FV_h6$4vuG$DBVB zdh22cIh()%h|+{AYF+;kXa}YaQ`&!8+nj@Jmc&b~j>|{M{Q`odqY$M~WeG%YDxbY zRP^Mp%2pnpNskh?G&&H=o~Zp&mqo>q6ZyI+zmWF+dGrg^N>s}~PYIT;B*Y+o%K19J17fnARXRqdGkYf0+DH_S&x!my8~1P?*%gRMgg}ajCV!I zI95P5zORp_dTh6@K}kOP-<7V;8Slp?%eyIJH-@BZ%1#{5hCnhYo`a;r^ByKwXdu~& z6cluW*Mk}Be|GxuJcU22C2d0UE z%+*;u#w1C~v8S((rYSJGJMEl$dV>3KS4){rvUP8_wUbg}#oK7cve6>lv~^g9Tgd+aZLbgGv2KkVUv-QxL0 z3;{|FGkGO}{TriQ%HmqDws$xnE_mq0y%AADR*O4M*+xdygE&3C*8}DxS(M!`SsUyd zA)|H7Z{*iq;+Hm)9OoC~CPI>%qO`$0o9@Eczk&HSPpuDU zJ5Zz4Ur9B!mh4m`G||hv^KCeym4Xp4N!ps;YZUeiau)MEekinUP(vnV{`U|r+xzrG zagBjr?ZaO~p{>eoqBllW2NEwEr-)@1D1fc&;niTx4e2a7^`E3U4O%_Pj(*EqlItS8 zY4-xd>y6Sj`A4$mrBdIm#8yK2ATQedx~Xo6yDWTGlc$`lT~8`*CF~rR|6myz#U)qj zqNjS7ad+a*vlbfMj~ym6Ds?U0*Gs<4%N4Kcd6j7=h75~6E1RLKkaX3*o^a5UidRax z2c48SLzDsKnT4dvf6io{&pWUbZQLr|i-k^u(9m`O3AcDk<(+LFiT1EDhI#y7Ek<%b%)QV7v}V(b;oh^`&&qqlbaC-T!HMmQtM>pspJv`*FqdM|sEUsm02giMLi>#+h1^odw z&bwZ#!&}{{{BB>Gj{CY7hom+?(RIkAxLyQMnaQt%;#c?M>48d9!-iGcuJa^CuAu4v zVM!D2CQ=2;8J#*1w2$)&` zZIW<&yXn?SQDFD@Q0fXt(*RJ|QT~c>1ZTvlx}|V$Hxo#HHd~v2#Gg;qYH zKF7^tdoG!Q3hFONFT}$!O=Y56g)ZvcW4Jo%sdfNlb1mn`n2<=FHe;}#U%F4L*Io|U zHMyPEYV=%_@5D4-qffj^CCfAoX_UWVB_(2;hO zHwQeCfJb2>d2p(3#N2;@|bTtrXN8^m+as_tMHp_-i?eawKdJ_{1cfCu(ZnrssdJ z$o?yWh5)}b#lN!!#zuq(G47O#<>R+d%8O9&AviucRidcW*L_1~*rrcrtYK^8Pd&W4 z`BbKOCM;*Rk3Xbs->l_~%$89Si;8Gomzg`Grc1yI1(I6s)u>4?5=RwY5g8P6cA~*| zza&JWWY#9RLDDFe+1CiV8&XXxJguA&?icuOkDTU4&;57D3_Cd(3X(Yl!E#gZB`xtO zPg@}6>k#sN%JZ=WI(JWkC0a?B{@Ph_Pu)qM-6v3^P+qOjFR0Cm7gd8}g)0=(HhEOD zv=bgYmnn2UFTZNDq{L+QXlsECsKe4WgDadA*9pz9q2eCt-z>w6b|wkgoQ~#CKs|d3 z=A{RXoM|Ux3nhVzSEaW8*1=)3HLtA9+Hd8_9?hitL&3%P&Z`sAlJ4y;LiV#|*V2>Q z?+(&|!USEZH-SwMyvF7_8@qb1+?yhUYX5^d52V+7xHg{5@!fh}w*2FB9gN(IW5?4T z4A4Q5fJ)b_7w=CZ(X3<=1H#Z%1x~p@q8F6$Rx3lB`W!(4pO#KL8|osBArfIm8^9M5 z-mXE^Sx%Tb0S5>s^lY3nSW&9Td#{gF)^AS|EV1g@A^iyZZ{=+b(_Gp<%UfqdKymv_ z%f$PS7*#L!!KR<|NrB9rvLA#7arw+rZz4Dy*RlFvdGqs>zxZOovE~zEd$=+Kfn;@{ z2h%m;Dm!Oj`o{-L@?3B+`2Ji^DqJLPirwDaJ!W^13OGWVwV$ZV$k%va2|OXc?w8?2 z9U(1Urr4;_GB&TXcjBZhP2fr8hVG0nR+A=d!v+djKTm1(rlh_fsz=Ei0r>ek#XY`t zN9$Goc)5XAF@(M6nQCkNMG1$u;3^FF10K>fc|;i{U%#WQK;?>iy4U|en+@jbH0be& z+3%o4am6dNq@RJ6=P&97_tjJ8cBFQVEdGhBIqk=QeXZ>jD$(lZ^+iTzKV2u)I5rAx z#ck7b#}4^oZ>B?nr{`Jk2gf+c-psfFyx8=*t+3pQH;F;J(F-|=wYC73h9K>BE#D~9$ z2bYDX-#H&cHq(}xTRMjfz|#wmATOsarlDJKU-44&Y-edtf(#4S56D(h{*8+npqeH? ziK#A?QjGSRd|aagew=`DU9V)4?y$m_NSVJLw}uLDpM zB6-+Hz*S0$-F|JyX2~Z2d)IUm;tW~EBFo9u67cv9wngWx7>PO+d3FIM2;Mjxe+#g zk2wGq<8glN1ku0f_i27*<7buF>yqc`I_aBwc|rw0pQ}T$wNX73$DE8A4KXD@!e#hLLh^RSBh(w@ZX!x; zYNX@;5Td96vvr3V%~zp(D>8QKLygvjP3yYM++od5+`|h4*^V$2nllOO4HUBqPb6;C zW@SVp=w+ycr*cxRLs3@cN1|dZsNjCg^A%~zdhyvIy#J-s@hbgf-6iv#%H4? zHJq_EcgiA%w^kBVeDj<((-uB54@4j14{Mc>He0DBKg|CjLrke!PSkfZdtioQh`ONfo*a)FE&?8*YKGQdW20UOA+xIlUbP}p;u9X%FN8v z%8Z;aEi-evIV29ib-BCU@)D?R$b;88G$?D{LsR1&`4zRVP%hhETdYcf>TlYa|C>Xux- z`LtAJAAl{*QY&Qumq(jdzl@7jqPdknZM7M^n2^_S%3Lq985BtW%uh;5k8HP0?h?`j z&8m60e}h{~=0qp|x8%YXY9%MYoC&Ttv-Z6Imj4i8(nPY~^{D2{NlNQrn}rQCcs9oK zZ3qPF`3i4{!3{t#JUt&x0EbEo?r>loA<8{~G{O2lu3wCK04h>0d%Sw_(xajiH+JDo zDX%4OLBfp44ij;|!Eem199#LL`~dx*)oH3WKj26?@G;f1YYzcbaBgeZ^Tw%lS%tv9 zOd8tW)Ft9d0yrs0km|ce9F4e%P>$tW{ z8F|i6C0$j3T;)m%`_G#Zuc&=qF}=VDX1{BRC{$e1`r4bP&hKR$9#M}|&-!Q|Ca!yj zVtz8XnCGVTn@EEUg&KIXJ5PJdzqsJcc=UX4n~z16t5()p6GI8VL>`vwsFpo91Cx|} zQ({hvS!B?@VY{GpmtVO!Qw$^*r}2f#KDHR)6}BcxzV^@cJw}yFxqMD1I2jqEAim1< zkXzxuPRl}1o@4pL0f%Zv%povM(HY<4cQoM9O@?z?f;ybXf-Ix}@ecE3akJoK5sGw- zjR5znVknDA@xx@6ryE0)4GZ53{9|~zI)y^Uduyc^>oM}iJKdO9RnprTm?z{&KmAhW zk2x`?7|+mohaVHoU6bEAJsaNbEX6Upta=r+!i^-i8Pf{xT z_{UAoypEJKEm26FSbB(>V}d4*{X3> z)6EY7)k}ERrqFd8&Rsdh;U}PB!83T-qkf&p(?1cDuy~edj&uJ~%oFRJ{x%E{|9RG$79*X}jvy(>xT4)3rB8PS=b*`1gf&a-;tQC6tgv{fN$ zW7v>9&*bo17o7oN)|0o1hJ-m}+Qj82g`-sY`3TKht*PO94H<418dAzs1pjkf`jK2Je6AvMb~E z7C||7s)@}5dFA26I*)B9$hzGHLF_#px|2achU+<wNxe!(gm-KqUf%AOVU-HsXoDLGn;D0b zT0JYUvrQoFt1!(0GYFkV{jMZ`x~P*7(~0}QMBAP^m2Wp9o48iJgbwQM#N!5}T5%rwHmUy5!Psf9-_OcPGCbcX_J_zh zj@8RJ^A@uf?N^QYtULg(+;}Z|f?;}nFax3nIxBNn&4(CMBV{W01;I>dTm!6!Go@G=K#;Cm^Yf6sJYYf6gQnMh2j7(7=KiKIr_n%N1QnM z06~oSxesh*-U+rAeYA~J_|0wU_KKo3ML-W!vrryjfP0jW-uPjky(n;kmpNHys~d)y z58*9==8E-}c+}v#itSZY`$a8PWA}fbSK7a+aG^$2&E1cw)hVouzRq7td=+bcRkEwk zGN0p0XIx;|fpm#la@6_OS$ON(w!8!3^nS~bmL?m}UtL)~Lb%f|-ofqYvQ@*$LGFE3 zwlOlbhO<0i_2F{Pf=$Vf{-q)nF=hGig{j{2%Fd&Zjq;rUj|GF(eLK!!@C>_kf*c!o z<-Ksg7?QuW9p-3f)nhI!{dI^ zJh7m*B-cIkzi8(_Y@)bt$`QF%XlbMd%x%2VjNChV!YI;jPTz^{9q5ePjy)q9$}Xyr zj_pD)x`P&lL*73xMna7+;~qLyC^8~qV%|g3iH;pV2}xT-CP_~Zjv2q}h2B66*QmaBBCdjtWS~iX|YStL`)$#4h0|prm zfxB2wZn!!mE#*&J_^a-C5Et-T5V!xCqx>9qdevh@5cp!+3DmNFywq_#K4-R9w8HBf zU{z35QwI1L7|f`hhr16-Z~c^JNh1nftzrGwf}ii@;$FjAVI7t?=wp*wjW`=v{|_C$ z@$^#%T1Y$dw1KP`+%rwg?RnTIYDQ#ghyo8?vrE!TEIlQ-hqK*jz+ z6jl&9hI;Z^h7CzLYF~aH_wc5zm6*JnBj$41h0Wn1S_I!1{%%pK>kP^QZ841ktX9SY zA$|BiLz|;rbu0bT=m*5p$vlz;j6Pfz$_W^O6;h@QiUb$j6gQ`X4@wJMIl~87f1q=E zAvKsAS49*r;jH}2lHm|!Pf?vGuhrQ0ze;^{6GqRzJppx@>#*OX#qO2I1l?MIZo^rD zN4wyQuG1 ztZ<*c&x4pdTiJG;Yk+B@$$McM(Ppb`QZ?K%5)Yu6y90I0Pwa%hU81i|Z7LlT zh>=b|=F$_3HIqdvCegp?dQOy}ql%Bz<^uTGpau!q;+C)zi=;1W7@0*q0!OV=hh!`` zS{C+B{3Q>XvA8@8({7Q=9DiZbvbH+GM{^Bn{5O@2elT*iO^cNGg*m>}^9o0Np&{(^ zfeh?godnr{Hj(f(F~)^i_O`VYb&5<-c-D(GT2xB zLp7;3WkRGIa@;kAC+Gy$@>OMRk`bOA=Uai;97jQ()?Oj{K7Fz8s#!rguNREJ-0n)} zv{y_Gme3FMw(emj@w#mO3x9!~A)AGx=&4V2Eu4=Ff-G>Ns?=NgnE-m89!4Vq!gtuk z5p0_`@i#cZWG%T3l}BO{MiC z2LN!jN;O>4hRUdgX3EYCaCgtTtAMLmcosbs)f=5PeJ{HM{nR^_?NSveuqov`^n{~^ zT6q`Lg9ZZ?4~J#OQgdvzS#-CCgkifaq#dOdBtP9}_+NMl!TLZ(;uW15_%@~fdFa_u zr!U*SJFh^idveM%!Sd70*0~dS$UlzdlciN6M81pY0f+h3uoG)S07){u5?N>gVFc$H7 zttlZI?1~?587z?HxdqMnTbKL%v>ttePL>k1234d-LNP;e9!m4o4eCNQai0+<7A8*~ zB0hjP1Bk1wIN?oE6Zy3z&6aitufL3T62C!n)m2DaT;hCOR>`Fhn;(G&cd>lK9Vdj} zwAzcuW=&AntZ?P@gu;XL@4QdY+~|p(Xl;|mkAFdXuZ8T{pY9?FxxWVJPqhYewGIVr zHZX7h9pfdrZ3z3M*RB-@P$ehK*}z>quV(tcvnDwKEnErsidwxOnEgk30(0Xk201`^ zA9*iLl)Ib6|;yDZe)`w zpnaraf8~Rev~g}>OeD!tZnwU{E}xSx-0!jt8pxBIX-Df&iJKNH^hB;x?Qx+p9n?(| z(BTDl1S`(!!=9A})H@2l7xuPWK)nKZ608|g$B)^jpIR58H}4uO5K7)wfDXmXaFb0~ zSdnhI8^LJVHe|Q)Z=TvSI0o={&|yWWUb9bal;ecQl7lVHZtCFh7x2BA-zZUSysX#c zPg{Kr^bah6?2TJ8F+*BoGU>BT$Fl61hZa1NBc5V3*?=i@btVJ9{c@i1@I=Bl40AQy z7){N;!fg~6x9V_WJ+G3gQU$#tWDB6(cnbCts_Yp4f=lT#H3n~(Lz&Jsm+L%rsO}Qp z=J|izwuNf5c{BK|E9r{Zidm-xwU;LrXZIzdqOYT{s@5|~0-gG%C1_C$ou+=76M0NT z%+{1)`#>~Fb2VD9pR=R8plXp2hAGHc2PjLp^1WDXH6C1gwEqPsmMwzw0s13>9t(Jn zhMOMwE~?j>_9gZK9%5SX1`3h`|mn zbUG}ku!!tonL4UPg^G(_DgTyljC2TdOXECyxN1K3D&-^U@ZX@;Iu96g|FFkTd%c&Q zS)B6QJ!R|(ifJoAIf&dO`cO46A+zBklGlI(8sy{!cAjGLq0byvn~R-%zSvEw8pM?E z2^)HSAUpJMhHRUp5eoix@su-};(@PNd+1y>JxE2=SA_RhtuyH@uOR;?IXIfKsdOw| z!%fQZ;$R0fW;&XOlazD1maHs@)zH$-ncE&M+HDj)lEuiTFBPz3975YF1U2zA*ZEjQctW0X1U zj8q_4A#N^$9dT2xV2|$)GjU6QayK{_EYAXO%)K>A9ZP@y`=76>m=B?#`vqc;fLJqx z70)`OMgDlcMfAii0&M!o84w*{aJIT5-9cG?q)(j!_|hhI;3~=(cRH@JY2{|F2Gy6S zv5mb*!4%${sE2>_unwan5h}DsR(KKrPWY`unLwzUHG7(Ldu8%&rdhkS=EEO}i|9JN zEUgz`uU?wpRcw31dn4b|iN1<+O_J>fnFX(`r|m#NzakK4WmTMZlkX1$S$3o_`Ld^0 zhKzGIHTlj-eKyXAPWOS@p~&_z(wJd&#|h~}`yntgWp2;{%@8ofZ&s|(?pvL}IBeZ$ zbyXZG41T4^_IO}wn|vMaWBP}nN)sLUr^>Uwn zoR5B}_g>`h&q@{ncd3*#i1R?o-TIdKtg3`g40m_CM-LnUunlMy%FJ4_Xpg5s`qH0?Ox*t2FCJk z7GlQVTz=qb>PP3b;n8WVSf!OQ=@USGopLBXWb|_Y!TwErDpf>uNB#e%#=Zp8rxWaX&o%fts%ZMf4{>{t!*JC z(-iLur^feVuPisxl^G_(Vdexq?(`ZhZ^qo>$|`W~)}GF=MtX3|0%LRMk{(A6>U5zz0*`^ds3lXMYX~am>F+5Y1j#xdOjP-$pbie02F| zCj72{5jT2tVI|nN55~#TrjOImgSp5!TgPa#&_Lsd$&OXN2U-DO+{?;CM`D&oo9!h! z&pojyKM_=GBtgB;2p-px{Ezb7)sW4*dlr*YiY&B@|K4A1X8$NOQdj5Ze-no)?;ui` zHjr=L>T>!O*;||V}eyWu!sX+t&o((d}Cu?6_gD%HN<@-oXHYtf~uG zYC@YtXl!7UdY_yM!{tDnO>7e_*dHN@2913=Thd9oZt1=yRf?fgIv%oDEW2l0$}@uF zjfSF?n*F#Hcvf`}ZrB3*8*P$XuII_3fVH*jD6UZX<7mbchF!kVP)*_>C-d99Jh~CAv^6HR7kb)uF+;{iH`Qk% zRUB3UTpVD$rf55|=fAYHE%=EnWRfyowW`X$D+?>nJ|XMPC`9RQ@0ao`6tNnjtN8d( zm)jk}32DK1>^(2xM$t1WgWZ>Hf6vJ)Z2S?<=XJytHMrYsSghaRa3z1$aIS-?3HQO? z%oD_~@Yg?nj$SQQ>22$B9W>Y}RR$l`E)Y=!%noF52&?DvNvzaE z9b4?rIZ1!}$@0O>!jN(6&@N(P_Ku}LpKtSq@G%`O6F-?^4L#@x+gz2lNaKLXQC%5%j!pk;1Adt=onvV1Ww5jppjUYN{cXfY&Xiy6F@sD@f~(I`2 zea7F3^0Vi~$SF-x{ys zd+P@7xA1N={vqfCI?X>JqkNnf#yX%}N}WaF!%d&tQQZ^pXA(VfwwD9i*3@xBmH z*Z$>$2R9*+gzvDr*GoI%KaJM{05*>rZ6Z5YkAc$6D|nv4;_(_*xmnm`J$|w#o9`;!stJB;5c+` z%VfQLsK@lwv1J9oo2Kh#SigzuyR%Hw=pIoLOQ(!eu_|~bovc}7Ncb~@vfeT*5a^_G z^80J%VmG9bQIeT_^B!CBi!ldhs00fGjC zwj8!uRO+1O%WVm7LH7-l;|~@8>i>?c&~(2R^8I3gazW1mjv4)1soyZeT2G5jcp+Fv zWI7V^sxbPufv(0#tNhB;rjNK6b6&ys$G-RgsfNGm(^hJ~|0wEwDSdFzx;s)@t_T>; z8y}f>kowPD>axT~%$%RtQiSV4_C%!V1U$(9^~ZH=ZYbh_?WS`M%3rjQ$En^3>!Cgl;5oRdCEk6Z=T7{ zO8wX059kYW$`~Jf6|!!OuQ4bRQ$Hts`vgx5OdylmTvVr>ip+-*BAMi(vqwDgU z@|`x6U%3B8>mDpx4;cRm-3OI7`m>{J%dp32A@B3+X4RfO#Eo*wkvX7CFc8FWUmQM2 zS%Jv-lXk5r{T_E0_}(kb7SoQ6-MCD%Q=~d(NNakr$0Bn?l}NvqERAdbG9H)<*hh{6 z;QCki7TRCDxlPmyn7}$g{3Pa$EUa}cfzI+~q+GLK`=~ie$jfCR6+6U&_uH&(qF$75 z6QuL^go#%(5pZ5rroJX^deIep;^t!kE$%_7Vyr{Iypbzu1Ty(wF6(JOQ7O5U$PR}T z8%rn3Os8;=Gc{wpDqy|M!?6>A)uuzuktlg6AZ%#c*sQ2&pH93z65kcN9M6Jx2Zz2Q|EqGWxHB%0jIjIp<_= zdvTr?-p;#HLXI!8>`W`=%l^xzd5nb{RK^?Lq?e|6JOZqm)8(N2%P@1^Z(mgKuR%SV zGOgNogz5)PW`>Jl+XU^2BqN+_A9>;bX7Iy|!awZLS+XgmM*k3gheJ}j=C!V|4jS=X zGJWF*7QVnGDqD&msaju1Y?jU%OKAJrpZyi|QroW~t&Rb>|E|M3_s!V!h^ra`gUlm^ zrt*N~X4MRTjNbjW#ijDg`XXXF?05;8Qbq#N#b%lv%994K=uP6e@-O{v{n20gpaY`Q zcf%dVHRE=|PUptk^n^9wBe@8F*nKP%|#og3RTJmuz1-Xz8g z_#!*6Zs?V4Ei091a$NB*YdSAMAkOZ0GXsS=PLJjbckCN&vP$kq$1WLu{~PR=eGzF8 zlYn(s`QW+U!Tim|6F0%h7}DOv1*J2l)mr`8qENv14OV%H9FV`onG>lMzkJBOBhmxZ zU;R6zSwu{*sc%tHz-Tc&w5IyOz2hPjWlLP1boTiE@P2e6-*h2u%?u^m{lz%{z@B)B zj2xew=f=FyjeCOHalpItwz3=l$vYbYl$Lh9+3Ir=&4rFE;+;Tmi?Tf2R~4s3G+TXN zp#N;Y^g^f`cVR3UidW4M?Z)(C#mY2E9+u1`-%?C%Gl%s79Tx08(hXGpozP6n0c+%g zU&54d6tyYFfSndmh&K_G{}Y6$fV~3~RDi9cqiX(wO!Kkk@?KL{LhS6$;gN6QXJ_#H zNi`pyArcmi3J_Ca4ko<|3j}yr<$ISI&p>wC?=>@Y37oX-kO7h*`GU zXHQfwK$m8xudiX3JpVAh>6%%FMDxM1ur<2>4`5Pb-RshQ%{Xvi_bO!?m{na@8I9QHJf9Ca&vdWkFQj;@1JZzM@Pi-32c|ZR=ud0A3u>6Y zk!jAUr9D%93pNS9M<#JYt+=W@im6`^KV-St_d>m?wzJ;oJHLD@0J7OPG0k}xj)wU5 zI9y7I&2ctYwcz^ZRD*V}#dj`A0*c5;i~j$;AIT5-K^l2-o8a6S;!s64M&&{OUx(8x zysE9C#zQaFW%S|)SijGfh%Zz(0yGikQ z+GCah4+HvE@BQAcvoqA09 zw9Z{v|FoOpp~_a{e>?k_ezN+tHAQwQ_F4(7Wnh)4xZ)Zi)T#?!L0V3>2vgQaQIx77 zf0DTcQ{1K;mcbU^V*8&$sXN%;Yrj4vBmhBAO*b z_hcjjpWku=?={T}HHi$SDS*{^Sf{G59t*!k*J-8KauJUC zMtxK0@`+o4z2xb-R+LYdt=-_Z>#VktbKD+ga#M!wtP>^-UARBYUk`8XTd)xFz*@Xl z5g`7=KJpaLyiN?IT-MtWcFc5(O}UC>9X~x;Q9NC?gL7P@$FCneYVS7n6cFwxyU^%D zA4E$U?)Y^>IBH=UqX!@dToSgq1AhlJ=1J*naR&xgqF$imObOz7f}=gk>#VFo z&(Yv6kc_yJtov)*OZ8WqwTRbKZR)MR1MuA6n-GgUMcZ5Gqjoj0pz*rf;*!>NBEComBVIsDaB#>js%Ap{9L7rlNr0DFstgr zc(d+zdN0qRT=ReTq$mDMXwD1vQYY^s0Oi$HY{nS3w@+!jtNfclDZ?vO2gJu}%Zb_x zPh-W?J&cVx&3+Goz8?V6`F0a0{ObkjcKnr8bYt-I+eN}?AV9RCy$W%ig1L9^qg(U# ziUpB*tk`#M5Ys4JC-0 zJ}`_jip7@EbUr{&R)0YX>@V~iWp-`oXb8zK zTzQ1pJUWVO>$-+`Ej;}pODAY)`xA->5*?})@K0#yD~D<=i;$HR=%OG#iI-2bu0EU8 zXQq{ajGd<1a(=uy#hhu`wKC3czCaTUo@3aKdnO!qyItx+83Cp)7_l8HG}KT3@S^Z4 zeONH-`*0wZl&jv1mzAs9kFU+osH8R<1DTtjeE(ezHZRLJ9`$yy zH|tZGw4_lI&`V+%(8h)l!R>}OhOaDS8aKL&)l*h@9tC|Aqv}8)+&Z1HoV)K^8*jC* z{>$$mZA4j97(CDLqI{);rTx_)h4f%>&K&FB>C1P~6sC?zP?O7OBeGaJrh7F`x>zz= z&D@6X@M;!q>1${37(cLAgu$f-v>7mL7OQD1VEHT!HMg$oN^d5|yMERgl-f{<@1Soh zgo*P7qw&#{8d%_xxUScS7lmmb|8K`NE(E(UM7znG1Jgopz+D!(*W2B#_=eDxWr@^P3` zZ&iYY{gV9)+3@rF+*~i-?O0Hurly2ILXw^PDh$@|9P+qb#;H{xAvx^fCaGs>(*N7%5byW%dmW~9EcKP?uqM*eWcH?AONSNsR$Wu-V(P8q(uBGM6lPP&sjzy0V>OQhQMpw$odr!vPntE?6yNGXNkFR0O@WVM|ao<5>4 z%YVXCZ_(}ia)V}LzaJQ^ss2Y_j{f6qn;o@oV|Ar1={Ls;%F*V93%GT^3Jb25!Ann_jH@HU&%N~@PEAKLJ2-36a6L~y&KBnfwA$MnDq!sbK5=%ZF;7+-=_fi(8ar2|`Ef^< z!C$Dt4jWrTn3XUEbEzow^7z~RYIBBc*Y}}|-8n~DKo$lK)wX)%v9a~{ofERXXW zYYuBj+#d3h9X3|IEp(B`kJ9E1J6gN9=JKw4mJS6dwu#+M_E4~aINfkoF7JWo^rR^# ziML)pW^t@*Qx%W_&-b9=z)dZ&ZQsX;!CVT`^ARu`Db#aTOpcr>guixP2g5b>GHN5F z;}qOB8nTyhhaFaLmb>4qBslZeQO121(VFtEg7pu)El=?!&=hZmgx!i4^X~4$tGdv_ zh9_2dwt!XL=WYdjw?IKBPt)ZB_Uu4aH`sY}$Kj)$m0Vl+_&9 z3CyzX$L*&S51p1JN1OoRQazJbnmOPbd-bef(k-z!^F$jG_ z5H7RPP$@CyTm0y{0sGK{BJ@%Fjy~1+H z**G8Db4{x<-};tA8lxhx-G)y)_>FRL^eNnlrTemNL#(cu9}Smm9=sV`4|0aIxJm8B zMpoLIfFulZz;CSQQZO!)ThhUL9Ky^_{I!yG-J7__N&kXK=YeO7eGR?I<9?xh?9kEV zJY+#+jEjAL@XFeD+dBq+`y&WZ^}MewW20M=_u2n%Df_SW@--)R4z7(*IE@zMTQ3u^ zPe=KQhCWnwd<^W;k^I)6uMCa!XKmeCNCxZ1blNhqb_HB&^gRB|lvj-H9W=tgvx;%I zC-}LB*52J(ZwaZJeQy* zX)f<%9ZPJeOcF2#g3?cnX3ZxHb=N)E<;_iT&}es2S;hV1Tuz~>Cov}Y%qslGGoM|`IA-6P?}Pg1a?_7* zrhCIP6M2a#o3rD|^rq7iCNwoXC5zR8%{yI&dAxSW)k0gS`8*~XgvuU+W3$8*-MK5f1d+2#BXKsg#xLC4Td z<`9)-Wc}ITP1qvg8c_EQdXy>RYa1#wXiRu)2cs8y5@8W1MZ^x3DmtP(HkjEEt^Y_7 z)?R09|ImaR@RR5J$@R;~SLXi=2#g_8*?ZT43biA0P53HOfL@R!;#G z{(*K-G<6%dNUtqjn&D$IoyWj0x~Bk-9@Xsoej;t~RMFCcONqBS%h!xDLDH03hZ8h{ zVEf5>rGBbYQ=3v>Q;=VBfjGH(=_~}n#j!?UWg7iU$qOoLpWIm6i%(uGTKPfTa;?C+ zqTc!ymJEzP#xag+f3FIek4-sH*w^}M_q!baVW?-<)hS-)M{G4cstlPv3b~ID=H__#FHjEMD|e9bd0M-4UMO*R!=&dc`epK z^(WLg&u2(?Hi*d6tg5m`&dF)!Z3EVCrrHugj)H&Y({(Tyv)MZJ0K{R@XnpR=es=6T zhBT`PwXu|)aY1tN@S01hAy-vW@!V?BX*hEAY{F(|r>S4UB(taQ0gx}<*()OdCWbaC z_j_K<0di+uB&7y6EtZ^@Jqn|& zV~ePHCKt-q2CD5XR1_sbW14%awwSDWZhJ02A$a@Xq}JD1Jz78cpn$D`mo$h;?pEXR zHci#090Bl?yz9boC87%KMlFunn_UV0tPU>z;q34O{ewl%I)YOer^R0zIIV{%3&lYH z3SL;FBM}A_GMhYR3P_8>qmM|FV7cy04J-d{wkUQ$oi)SE z6v=oAIq2Vp_w?N*U=u9DpShNb8OrRi^*icKv&`4XQ?G>Ymy(Z@B_o5FOOCk5#rSJ>8*^?!AChhryN&{;MqN+9&gE=sJdzc8)uP%Ai8nesFX6F`kEUc}xlC2JwsOnJIR~bts#hjS>S(G7O zwi0A@U>E)-SfQ0N2hPKrqB!SKyk2;LZBPz-vk&BxKi>%XdrgO6Ymq{`FIM^0s^M^2 z<*(X?YH~&rS{9_}aIyC_aFKnr>T;O%3VG?LZ#jPQN6gf@HdC!A0d>rNIA*6bWY{>s zc04p%^891b8%@ZU+2DT}1!utglXS;8-lGFQBc2CIH18BP+7BDAp`7YZ*EW&8m*xKp zyG0BBwF4vOeqwKq0+puIr7?zMF#09+j`#4r<_>o;xSH#9bp3}u@nhLQi9r;_!yj+5 zPjnPFvEg&J=Ld%bIWq4M?N7C+j`XO-4 z4ZwPcnmFs!DQNDuj@gT<=(aa_8nq>%dt?d=jw9a{ysypihYdBGI9? zMifR%ug;n{U<}PI(FRvSA|Eg3*)&kL}Lu-2mRuUDA{*M*mZ)ubmSwAO}jePGP!?#Hp*<{l$x&|7bb z`vpw*{Nn%Q-Gt5F*}S28_RdoW@wsBR&|^XHIoN+YG3Aq=oV15R`iU=mJ$ScY|G@s*^ho zf{}+ZMvZz$SMvUDjG^u?j4=ui>u(0!aTw&FXsh*Wfx*soXGoe~oX)(Oa7%X#+$3?w z$|B;^e-gv7uGb|j)$DI-Di{ip@^HWw&sWh>_Zvpc!((mzzEk-KtUB)^OFxJ7$? zE#n`Se`M-czzz~hvA>AhIGbx%6cIfoXQq4mK{_VImJnY*k+@$=C@HPm_htLw6(Uqg z;+VzhCjTKTxnW?=LZy>0PKorx3zQwP$~@#b9qR?jNf9gMQ@$NDwU z@Kh-3jc#tmd;(>P+md0MvWz&blqO&FebRx8xogrEl_w8bkj?`zaR%3kUWu01O7?|$ z^SJOtysmgmd7XA}$+|A$>B*46UbBF{{)x$Fz@spnxPfzlAYJJ->JYtmcVy~O6W~|M z5N54>CW~JhsF#25FeQMKR(VXg26woM7{pe5Ru~ZS4%N;u);8k6@SVA+XR5XrnUZA&XY|;hk7urpE8@K23m<`x-2hxo@2V($a(p(#mIT| zv0qk2j#sUJlrNy)-zhvp<_|8(=HckcWCq%&W_}UYVV!{wBNf6{6Eb=!i!CM9ycS)& ze1CKG>9M%pL}>DMumh<=vn_WodV1;@&)54-FLNOl3H&+Li$8Q0Q9M^8)7Sm_togMb${%*`{~lZ!0{j5+1bca^Ps6Q6MJ` zoJr-$-=9{7_tyJXjq{ybtctGk;tFy74hR|#IYvSy&!{y=!L`o@FKYH2-} zoM<`o@|?1AbMaRnXk()_>ks;k8|s+YKL63%B@iofn)hMiJ8Vb0!!Ia!A}=9?ad zEnYeYj4mNZce5j5W6ra7%EM>sPYPsJ+r#{MH3zeaPC9ym@AsrROg9aVqE-0lyyIWD`Y zi((Qvc^5x0|#|(di`VEr1!shSO#fJ4SEA<>7v@jGFXcoZ3 z+jw1SkWJ6R=}pPJOX>h#8OJyoc)nDge*doTCd=Q2zV`tr$0ITlpH@vh;)ZUmJz!spmbpHv-Etvh$f6|1c|*{>i)M{v+;Di6A9py}O?#hr3o( z2ew-nOANzJo?MSUAHUu_e-Eud%c(;6wZBGn`2(ocJ(fK$Q0foT>q$fM;m=&cTEM&X zpxog;y?hC$wu(-g@Y?3asEW&WOF7}>|3AZ;3Q(RU;n0=RDFD)z!iqUK;+U zb$Dfhs+EigKzOH){6k;A+t!2&yf{uA`E-29PY$+5iXN>7xx4KCGCcj^)1mFmI1?It zWk@yJUtNc@MRRCFQBmdDB-lGY3@#OOh*5p4CR=P&tvTl#v_1n{ykRZSZZyo8UC4{y zbSPu#(1G)`ey8+&p5wEkrA%}Am;1fVU#-~cU86pjp-QvycPJxVgBFP2LVE#=hnzBc z9eNngGdM|}04ctu{0qpU-TWIcqbYebB7~_*wE%yb{?jQCO8KeEtiTk* z!bh<9rmfxXuqZ#}E zHCQF@Zr}AqRSBuFq={+2UlS|SE%wnU?y$udGgJ6#k%;>!P6gmpN5R}`PEtW6bTBN-5F6s z#(`V+>%^EpNJF=m{S6+6any=c6}WG*eNV#eTP6{V%G$3y)qgma58U_{Xg&W~ehZ=^ z^uxOH%)!1|;3Vt30~t@#qrC?Y?l8c7XffSJ8H*lFTRJi7^qx^84JDu->)DoqANe06 z?7d>mudIg0ZxaKz3J0IhkN%Vm0(9ep*HbDcF^pCVwV29_8A_f+s=D?#!*jWrjI1C&;H^JUq$Q?uAVQiV8=EX?JWxamut5V zLAWrRS7^`dy|Ha4Ej3nj{>p7a`ch5FxdJl!*ei!hr+3kr-`$_;mXj~N4hd0?41DgR zTkF=$(~J(>_I`tRXrkW@EFj6-OMw64lWkr1o2h&01D2%2M$_Q#=xR*$E$LtO=VdQG zW-sBPul~31pzaV)4Se3g>YU+BTfUWbB)~ZB1R-vuxMNvIdJPj1;OlLF z0a*Q)8!)Va?3HR8KOz`S?@iFOk?b}Bsbv`N;SbXKN16Y)SVkLbl`uD+Doiy1oVYM7 z@8L0%MM`3ZS`Z=t7W%G23lBI$g2kzURczjkC!{B0$Fec~l3+@kU`UXYH?K#feij$aN#Z{Tw`?{U zJN)g?CFL!{j=E%rSk&Ukpg`Z9_0EeJ$B63bbClIE)6xL1(56X+7nC|B*G^Vr8uVOi z+rueaun-8XU*cNe@}=+Q4ext*)9;7*_WE@QdxR;xn@0*<{s}aO)mewU4A+QjRys~6){HoY&Eb_!|{wVd%wxsda|S7i{-Hn zqTSStj9NA0X!TotH9gtBot8dp@BvrpKmojcrss5^leh3edhwA@ea2OR8bQb#MGMq1 zfR`uw1qv*3mkdE$ox8NbE%Ci)+D12feS9ZW9`4Nrw1`Qg0bm_sTRUu-^M;cN;9_77 zf6cRc-#x@7oNHV^?ZK#zYMIVXcbu9@I1Tyh?nYm1d7BI46p&I3V)B;^wROhnpQih4 zgwG#Mb-R+t|3LO(V;V1vxY$vW4NjG6&bQe$uk4>2ZvYG`&pw?yUekXwC%VMWcQNfY zP}#-;tCGMS)h~`YkfSfdSVM8P)8Vk_ktM`N++&kt?Z_SEUBjs!kV7q!FIvj>9hQo! zz(Ymx#ONzppDO9rsE=Imi#6gy{o>grZm;`^VA%|C8NitK_vG(h#vqsRvA<>sp^c3ZGQcx-4DF$Ri0^09OVJWRo8>j7K1UYT z;gIooHub{}vwsuHO|EVxTvN0ZF;)AmF4eek|C>gporO%l$79hAYr~Me#gn{bYj0ni ziI^VU)c-r22fFg1tGZro4C{<+3YuE|$=Mt?+0SbS9yIAv?V8~+>;A1k4JD|RCBdn& z@Qn;2wNkrJxdJFTZW1g)8}cJNikR8(x7IXRC_C(V#w7)(?bAu}ZZOIJ$J4h5GW~!5 z*Sm{K(e0gb?IvBVNHdptm$y_xN=YuORFar$4BLt%DU>wVEg`8;sW!}(+;1Ba%4~Dn zWNesiw%Poi`+Pp%-@j*PXRp0p&)4&L&f`4JIic^93F!l@fk27yLN!Rw}E~i@k(*K1X*MG4`1W+P1+x3&T3W~p>tvGuv$70y?0dz0I^)gT`3`9i7w9=|p0x%9x{;mZVSIttKg zD^h-R$i%C(qFf6SjnVK5ywtp=&!0bh7%0mEGq9&oPwK=C!I1&mv;k&nV!$Q(Bkgiz z6Ph_`8woj;VZE&Ou?IIgL3^^_Nhs=U;2s95El{AW0Fx% zmJAIXg`;(PFXxt$(}j3~b}wGDqFN+h3VmsF|Dg8YOV8LCR|z(eC&6yj546=HOakpN zpLFqSa_v;QD6&WnBHXu-RDCX6VyBmYZIA@ZI|QvLib$?e+D2%!)R0o%q6)N1VFv$F zM{r54p&D=Wzfb?dQ%}yb-UfrKo8ywq%myNBd8 z6LM}mTRJv-7QK5PaO@4K^8K2|GupY_$h6~UEJPQ(?Np}>O5z^KcsO4$Yt$LNJ4YVN z5-RfPCO8?td?RCd#SJ`kazbujRqn2^khSP&Df~9t z?!b!4UwG;Et5<<|_h+ZuCPs72s+P&W;SrZ^Wf4PwpQDE!jZ2EUa1X9AdL_g{q&};s z>luwdZ;wC?&s5oQh-bW_ytxIy%fXx3BQk^cTzDq3i&Gz6*H~f|vv8GgiKcAms!|^7Fi)=n~se$sx0wKNDl<7`2@s zW$^w>c4I-%4!TbvdATUR!=n4AuN8yasmz1_`0@N#Kk?_c9|_b? z`)-I?-e|c**`J!yhYsgdWzLF^(-I(zm(=XRL)SA?c3AC-_aM=Z zv5+$r<*4cB{y%w_Ii@50?kb1W(De%25$ZQXy<#ErnwO+3DuVA+?Ga=-zID!d$gszs zwklU@I|$sW+$c$n9hwr1pbb+)sZe!R37$eqi(7TJMIHiJIFMtMCvqf1jtKUi z#Qr0F8}Xw6eCQEmO8=M_-hkOb&B#U!B#Fye%X^C>)Q#70hN3pjD*f~>P$258@|d4h z!l3a1En}g95?e_z{Pm1+A!J{~66li!`se43Cec%_bXV;#u2QROvD%5$tv&@Ne>}Aw zEq=BY&euS@1^j9>f#fpB2R?d@55ziHTX-4?(-qsIf0{j_vH5aRiEJ^|<}r_JnIv~O znDWe0hV#{5&YDyufd(1_erkRoeF?EyEIYkwT4#^V>Y21h{*qu1(ULoi2NX~CS)0?- z9sd2C{aPUWeQOZJ9;#Z_vu^idt59Lg8=cbs8sK#VBjJLh-HwR~hv@Sb<6248Hw=j9 zZ7w$!Ds#W1BZqu{`gx^@EH(nC;p>QzCd2!e_tb+f>u!)27Y#4#C9C&8BOE4e5q7@U zq)o>`g1I}qf+H3t9WXQBCX;*fHdSz|#xvY}%0M3ll_DLAgWDT%Z7+tkdKZ0d`XQTDN`RuUI3*)87uH3qP|_dl#eFu!#OUU_Yyv7~UGpYWi`^_rv{oM1?8j z-Oz6|gLmB^p%_{#*nfDDmKr6ax$zoc){%&|(hr{u;tzk+D1e)UzfL-*Z#!bOIWY)pKawaPKQWyve$WL$%iAhjW-(l*<5|5MAVzf%_~A^?WY-d z7~#=e!L>eXzLeB2hxj9{xi^+VPb^#;weZ}-_S1{HMP?1P0xOd_*_k|@9bEcen%X!) z{Ty*=)XAi3aCl&7?FUPJ6_?3LZ&J85C7~L29F!IVZD1szRcxs#=`!j;DZlP)*ZG?+ zdcRCkR3qXt+CGC~+q%UkmgF3cGadg3^N4PbHcf=njzD*iX7#}ra^5AU9@Tx4V6y!`x~QouhP_2%(P?^Vk}U?b6M!Pbb0z8J-5A)i8nllpdbqp z14jvejP;J4O)HlBNvoF{^|rR^yl(4yeU(n?C{ zEt>-+wItRX==Mp#tJtP6q?Ynpxf-p~wfr3FR%13Az3^533Ne&xB^%vIIOTpc$MPgA zUbl>ki!@pmkr*-4k@gQJ!Th4sD%2ZgK9KCM*f!@tPD_A0J?e5k6Nxyjj|1J-=hq8T zgMMrgT>Hblg%_qJkH?1bA1ljuqbnbQFVs1ZO?wyf9D)s4wlIjrQ9okuob3r*q%S+R zESV{CHOP|(j90kfao(UJ^nOfY#PYxwO2kw}>R10W_ys^1PmDNLQD=z~>wr4S%0+%? zuXA2?OCoIO1=NwyFIpC>4r`qfj2xQ|a#6y|H8}I>%4hVS-fLGxa_+qrm8d&IWOWw+ zp@v##8LGE}ULL4kf=q6KZhm5u5ouHzYP{#~Us~JLCb@gJkR!8`9ixU@Pj?bRPXbUM zPT_8#m2-0sg+JOsH!Orw+BVk0aEF7RLS{@>Ts)EF5dOPkA(c62a_%wLv&%CfL(06b zzv{--^O}I{i;T(in}lqcKj_zHyS>bb6b3oRfb!LYUat*A4{kf;HrvetK^-PNMv~)*46gUus?h#H60IgcCuDgcovyH@roH;ZkY%Z1i6KN6O^L zwo^WM+{F`fitk)^Z7wo|kwWV8r!{|}j(lqmLq5ZArm+_3Hx#o5?s$ee?TVOLyRwuE zi-?+4UCMl-Dd*sP;ZsYEz*iD5C(CYSq*I}8BE}j$g?AHyzi{G*xW&jqiDmpjPT)Frb1Dnof|)%CWIv5Vqv9c|hNZ6`cE ze!35!o}3^QadmW(kLP&SHXDapW}gOlugGMN<;EP*P5M>--J!t(i?Z-qKx+FjI$#ns z&D_P{?4;&L^?CY^Aq6jTAc7b0u!uLvWx|tZA)evslJF0L7oIdqx|Qh7ZrVylS!~pc zA0$n5+-$2q>r{(q!lOAf`EQ<%6#g0>|I(tMX~$mvpyuR+M<$7leHo!US8PHf7Rx;% zz;)QjFYF3@5o&UQ?-5)M-x+layis|ia-^Xq{=`VHAJZh*`m$J3{~h(D-g{WHo`Bwm zn)&yt-b3sOPVOsCeiw!E8flmwBrZ7}-6?S}edjg)+C`8T*b^b}$ZMe&tMk=tw0;W5 zss>|DL?RsrOvnC_<0wO}U3OYA?AJ|-&!r|Q-zJ7N&nCF4{A5H}jp8D!Nn#~76?wrX z%Ni{2fc5zz$$0LY^(1N{1xe#{iJd+5An_z(klNZ1xn&k+R5*;Rb-s`!H z>fgFVePdbr1&SA_e}T5>Zsly+C);$SI=KD|=E4str6~@QHn-M=Ui=*~WJVosx7cj+ zP8x$4Ifx=Fw0H~4;ReSM!F#Q=D%sjL?*O6nwC9*dp4yvW)@76F+D{t0;2Y36ljuXi zhm0PZ?_H(I_}-eehL3UTxifQUw5DqFG$ypI|G0=>yibb+C$PfkXD5ve&gok{7(>|G z9OzAGX~X^ds}Wi0TU?Qr;y3ilIrG+ht~}zC2U82v2&O<{XAU`fLeOzd3mi&!u2rM2 z)KRkkOVEFe_xZsW34D_Czkh}vvN?+RVV&mrP+Tm%>w8m^bs4T(wx z13ilddI#qMMLDdtxQM4*jlCN@&c<+DvHIafD#HcTYuT)go}7Ve0R^=ApQhB|45Bf$ z9l7fdgSg8r|A!tUCRBh8rHX-6GoGvId}mBb zYqSieKKQTZo%gn7XM0=Qiq>wzfV$mokZl1*X(Gq-GI^wa5p*=}xPDBHnWTTip9LX# z65}0Y&2v9%P{_We&j|H)3SKxA{CpM{Q;KN_?R#E^i~QuLd;X4%X_V>CrBNfj!tVUN zpD2l}Y?S!vg$gJ_$Wy$sPgk?KnyS>Bde)`j9A0P@BoXJM?r2%R^+VFUIQy4KYTL-4 zrX-{PCoR*W?5q13AF1`l`=Klt(^}@Myrg;Wj#@{dYOQ;qxly|}XrY(ZA-m0~`u;2tWfOQ}aM77vrJ-lBY05Xv zNylJ4m4o^`4`A79<|n2baLm5Nk>A(qFLcqYK($3vS?{3~Z$qSk!drrvzny|Dz8b+<`J3HO z^JGmtkxzYc^D>?V16ayXe`T$(5iYgGHpy#je%-S~4J7K6+y;|L(4>)-zs<3^ILf|1 zg6zs-JgP-?-Qh;RXoN-n)7uEP~;x>C{5iv965u@=lC_wM! zI^Zv}Lv+n#=|8#{5#81{$Q&qQ=Fe@VTi1V@HYM zV8dIol+2PP1tP?g-IJ|5oE-+1v+ozcZQfE1pU}^woM+V1WySqCd+&<$8s~kArS76P zIW=bDrYk<~GVV|BkjSomMHL>L<;yew?ybHhT?!_Aap*iuIpAEpvdoF|vMnkFD4^PWYjO zw>27*4C1n#2Pl7hjb|v|tWNo54C_|%XmbLCxaiLOz4`j=>Kx6(Wyh`2P9kWh!FlHF zn-J2NOL`5?eRTfGQSP*J7T0B`?`a^=Qe~Kc5WNZiPlu(fX7tBP0v6fyPMRbg1=P zT}YJc4{sx@oUtVO`?w<$lMPITo`VsnGko#Xt&}YaZfkx1$MVQeXgonm6hdDM=MU^C zTaEEM75xC>j`&GvWZVO!-VjWs#HI5_-lkxiV_vTF5rGBo=D*$dl5 z;R-v{*VHnno-MS4ZzLy?cG~u?h%%kkZ`tMi0YD1E%!ORivZ!J!%s-?rdkJf1kNpi& z9>BsywYkjCRIq#AP&mrkw4&Q77e&FC1%v5?8uhUbwYV3 z+Kj*Sj4ccrEOxWDwp$@djS(J0%}camj~^pE!aR9Tb{+Hg06ffhaN0ecZz;8()@Rs) zIRZPp-9Q#(M)md8xzBtNu4DW&3$$)gn6Bgipp?A8MRu`war#S78$60hbQ>rKL zOaYW!wI=Ys_ohEC>#DWq^Zb<1NuC@je)T`#E=#yYmKL96q->8X{Y4_ykS{9gkY91-llU z))_#$f%sIroFvKrq9gS_%;`*g^roBWkhs)O+PyhN>GD6*1yEp1Z zi<_r8tB7<5?Le;cMUf#LIH|7SmG3XKt8zCLq?dmf!m~-AJ9Tl}*1181QDoMPN6dv8 zLwKtx|J`Se-Hjo->0HZA=v7HzSjE24^@Jx;i)J@fk5M~4g&iOB^phyVS;F_-4lzf@ z7q=0=hyBSY*OkXAD<(<1;A#JfKE^84^^BO=aayT2mOZZikEdYc7G0w@l(A_osxDZ0 z*4SL2^dBn!LcKPWjEUxBFKhdQS!F18pFvAM<)R!gFQ3Bp2F87hNXklyWj+Rh`bV)U zxqobUKeSo?>ZTV&N41GgB;5nfPC*J>Z1=~Hi#iKJ#UAA|A3e`Fjl%?LeV!ncW+)x- zE(cOj1RY65b+iXr!8pg#x`Q`?TDe;lz<`cBLCc5P)Sog3U5Ols1x))A96FD*Sjnrd zD-K0G#Qz4e_*vY11^X<)XcpD^)e%);K6EQ;!}9^`BxMXo1`Wl2b~mPk<;<4cjCl}a zpqRl!Z}Fc&-`W=ah2Cd#^MtL;=sfm^08B4FjBVCg6YXLk%yBBraTm0_dtfyg>p!^$ zNACPUG=Gn5epOq5%BU0C0_?^vNo88*lpJntN33*3tG&efe(ar42M&htc=+6s5=eUW zj((l45Tv$e8uXd+nKjbY$i{p~Ee1YYw7lJZ3-$vl{{l^#WFni(REuj=G&9ehCoV-t zjs_^V6QgK|=bcEp)l<)1vHIuF^-3M!o>{UIhqks=`4Q1y2^YIwy)a<9ni+J0kO5{dy zRdS>=E}}If?VD9C(H6ZrrtB!H3q`H|gCE7K!VQ)!-3G1JLuh+n3+JU`Ky1?AIy%tR zh{>-T0Ugmo#-c^d-AkBZ^b=X~7~*Qrx3AFXb0x9z8jmxcvn9`=1LX{eBJJlB(tTR4 z;2U~vm=i66IF{D|5lG81e+U~Hby0nqfjGhI%B8v7=8e7Yk-<3S$(q6?ieE_9IoIws0OV2B5gng#pDxc2WFRe*;Z|)K0bqOlkAa=1C@@HKWwAQzP9GRI zHThkuKzyNQ&3pB>2dS64Ky)S)}sd~VbofWR2`NbgZAwaH6KpMea_m=2md*WrnT32*&CJ}ryL*7 z*A`@ie~|YPLn$AUD_6*Ls2g~g>nZTGVxy0M?m8idA$F7WrvEC5Yb9&^pkL)!OZY+)Cr1iJ#8j&$ctViRZZz8ZF2_x11u)?(1z9 z{)_pCYkOU9VEqp~q6``SU_C_9vH>?--lAwJs69O7nk90yRN;)WbfZ#dGV9i8^f_MR zcN=%s`09-)U4b;qm(j@UcI?UiC zoH{#({gZmS+D^txt64Iur9av-%&H>R8#h# zvMvj9A|BZ>8%HOrGrLBsD}HWi^8UTHqkN*A&Y0x+E1;w0i2NQG!Ewrc?OV3rz${e4 zBIOx`%K)?o@trDr1zc@UT;nDu$G%G?Y*b9UJS5^2v62Plgc_a&gI4jhCHW;qtPz#PHD>#ION3-R}5jXZ*Q7hP4k{eFo50u&_--a}=J~QtT zW{~gn^?e))St>IZ&gWX}^PZQW5?&Tn-XiQ6|0p_uL|j1UEYY%xWa-5aJC;oR_N6JO zUJxO`6H9iGZ*P)1JUN&+ZV@n!HzR`ArGFIk4u&`RrdEfQK1DiWD!zrb|JR6axrV;5 z^P#~*8?#{BCK6YgD*|Tfz4+2y7>+J=$wO*j|AN>q3EduJu^B7<~i)P!XdLSkK}p%`pBMlASzYW_CHJ9WepUAY(z_^Z?2DucK=< zv76CH3a0MeUcCRwlYcmaHd4PQJ}o~2nT-f)J083Fnm{PbdeY+ydTx3KY>7Ay$n zG>H`SIU3k=M87-Yw=p+SSQa$a=P9=x{CtEr_gL%el=9&l9Nsr;XUuWa)qc$Ei->w~ z@qdOdMi)bHG}BqBi|*)QcrDx;@GJi0sOOT7@{{y0YIzDn(&dl-?v)8%r}*@4o0ctK zO*%6fT<1$ly8{{`1j@`U1CJ?AiFH2SJHYFQ@quT(prKrk9Xd|)O|_YA47jQHtikd+ zK($zRXz}9~<}muD6;08}RyF1JL&^bVfPzSvw$-uNnh`3~M-PStKGa_=6%ch4Mjncx4`dp#{-S?_Nh+T4|)t4?!O5B0bH zaolIHg7ZOj!M_n9@0ZLT)@O9UoKua;E^(qJu7U|YFKBaljstqltuEfVv|J0GQ~Pg! z1##3AbB6I96+MNuj^0nNJTVIIS_WX%eZKQs0YgKV3WL{MoYpUCK*|4(kg)D#LIaM9 zJ&I6aGv!T~Bix2g^;4w5Lga_ft>j|%Gumn_FaD$kHXABz24b1>wSiwB9Osj#pf}^g9}@F zVO(ia_(P;r@*ig(?=II{R>NKQfQ^f|>46iy@8eZerR(4uI+!>X3RQk^p#zVzq zYb$g1q-_Yp&^b%J1(`OXI-s7Xpe|-A`s+@~ve|8ZXw%;2vz^fohu_S87r5uzNUfLQ z#$SgR{HU<4WtJ{ky{#5E}x*Gc5Q}LUPnLiG9U; ztD*ozf)DyfvtSP?U37;MU-V-B_RQ=JOaw%%ydES}$)BLoC{>Pm@`kBG@gpV1PUO2K=)@tIo3Yt`qbn{Vm>kmW{?`fQV}mA z#e&m}u0HRvUuUQd-?g5v=IayA6KG1kn!<9!@7_~)I^LK3z>EgYUjbvP=)Mcd>@Mk8 zpZA1MLJYl6Yu-5K2lY)CVrC`Ovkm>UI$1u&c=hhKV!~&l#CL&Kw@mXen%Km()e&qP zSA+7V8e@nK3)l7yQP+h(Xp36ajTlI`S*7ruEWw{w6oR2{)|xA@zJrHin1@ z-%%YTt>e}u-Nra1)F^Z!Ut6vyghxD92?Nn@S_ z?#_C{E2`uR;}>Bs2{R;XvRbg_TZ8%WcjF>G6n>udgq&nTu3AgLVB4ayqYr z#6?cgg=Mj7jeBsN?-wY45Uv213;zN=4sL&33KkHe1e?L$|2m1{7ZIxt|JLX&xQK`v z$D^77^|DO%I?PmG_WH3ymq!!sOkfJV{3~e5O>hX-#FECcouX^1h9lduQJ+7FrzNU1 zS0_|Y+%=^xUGfF+2AW2!Q>`8k=_`YPm^63W+(4IwglT(E)O+(Zwb17pMvv@c*m_4k zypfBGy3a`VpWlX7Kft>@%K2QQDXF$%R3Ncr~gFRq!sm%Xkd4wo(`IAY%syK`vK z-a)mRf31LpVvGcMp}k?xHT92Ogf4x>i$-?+-Z0EeX&MW=_49X42t z+P{8&Y1+ckNKKhXbs;B;DU5YMuUaS1V8h_TP=kC-Ckt310#>Xo-P#Y|@>2ZtCwYHfoVgDHYw7)$c_evO_p+1Qey|~0c(IqbQzshnR6E9;hIleA3BRMc% zI&YYtQk-J3WJvTa>}g+PTEfj7>R=(Y41AzwoI8wgncMqq;bo{Rnf2WPi|~?yE_ zA&)(evvII10FY$2C#)Z%U?+M3cIvbb5Q)3XII8}|?f{qzpJQpG&E^)_h zYI%1j0JOwlw!FIyyEm~l;GfSLfpbWWEY=|D+K|#m>`~%N)fFfjX0{_3^>vcz5c-a? z(^Rs!wex;+C!~=SCz+T=aLxp!&yE#DUaaxh1~wa=Hje0V5lKihuxyUnjg%GQ97DmNrR zG|{`(6M}+=m6;0Wo~1lm4p1B#=1F3bBxV^JIv49|U=rk2K%FN1?4e`U)Q6L}mXTTp zj3JP{AMS=K%YP62D$C=kdtDlA-jlPCBh0>`_jmzpaP)UJ?3{uRYOE(ABEK2?yagh# zaUN_gIV4B^;3D&>I9}Bm*g8St3MDJzKS6d(-dIuF=4-H&UE|CZ__{DVUwFX`} zv&%yG?65(8__kjIXdap*FWlY@rJ>Q9$a1FoYxr7n|^8H3*dJ! zuI0;{ zJi0P_4F6L3l~!q4d^2~OwhAc{%@}WF{4<&Hyy!Hh4js%b<0C;Kc0mY5{axM9$g;yP zDz19w`iw>@0{HJLFet4@)i;Sn(fKDC+_%hZ8ps>D%{jn}s_7L@0e5C;m*F>eoz1m+ zdZlrI6@S<-l%jrJPdm~`hxqr}(w?dfy<24c3@tlPHOOV;kZ;F2&evO*MjH9})m%5( zXu8%1Y2?gbtBgg}$1foo1qV3I%LC;#o_63p&2~0|us;*e865Sg(CEQ=N3vUz{U_Uj zu+H#;r3?dCXI<{L*eQDlG67J8llM0`FPlukqs-MKBd_Usn(;1+vuAO)$#>D+K8b?I zOuH$cO9`b`Md1s9541k4#5Ommn+I1l!kXnUx3TNV5kz;jbD%Z^!OYI*-$$8PM8u?0 z{w|ZM^~sMAe#Tajp}vatk9bY}rtaP&Qr+qtU!>6ez#ISo*sInPhdrD{y@FI}em6 zg05dpsOT)qi$m)fjp_i#sXQk+9aLPp$diWL*>w_PS@r>hR8N%M*4exyjI;K_BM=7{ zCjo47!c3`CTO8d$I(+7reYA5 zOU??!?7Oow9R;6mNS{fGaPgtgr9U8LBK{@_;6^^#jL79ZePa(>&0vGL)_3|W;8xa! z>vn9|IOu;acdIl|=`9HSkF-sZv01>kGWs~C#R$RkF)NPvIffQypU)icaR zZg-J}knn}NO2bxJmbsbAuHN3+Mb;9-E?x0h(UVM+%LRsF-f=o7MZ{jEqwtL+PI>0i zTi)%Gn=`mR9;di5@7bF=-{mWFXo>TW^*cJeL9aBnno5;O_;qEa`N z*qrn1f*HFo?K+X}VA{|aH)i59u8-tme}{oI$eww%lUNp)Xzr+G+Ts+m61iR37 zayK=E(c9bB_;rFVRZjtd+4u&&I+-GeL%B9|f9PhxrGkMPpHUo7F@_u;xswziiOow(ARjJSpdjKhr+p# zF!Y|}?c)kiY#PU=D`GxT4k&1&aYUh8-0u%qY-5);4-o=?tb1Sav93qV!sUU;}!g5K^&^Q`kS{h_0nDPRGDS2a5}irOad|| zF{R=z#@?Txfu6jA5Y3Qd-53MjgAl1OycSI9#4{FJD24W3kB4`#_K<^{lTV2mD;V3Q>!tV1YD@^ zZxGwKi>e|Rhbh^iOCrWn8%+4bM1S%07^H%I9G_6IDZPPrP)h$a>jnWiF2H-CFO#6u z%yZIi4qu@q91PB#F0bZyzx{!}5@d+*I`d!|f28K-cS&X6e=|p7BfgNye;C1TU_-Sf z%S0b0l>e;I0R`Hu!3Ws~S+r5zsoKZFdr=qLEasW?gs4A+0~5>gob}|g-T;noufswCI|QR0jKD?o zJdXHHV$C?@zW0_H85s|q8yhoOh!e2-m>XGQKwtnB@L7dh?z%++yH#fC+ zh}9;4!Xd|T(tm(+!x7ksb6zbv1~XD$+HpgltRhf&P^4w=mn_AeltDtR+?P`yNQN={ zAj__?N6 zhLjkU-DjU-zBy5y8VTY^HPQfZfUR@L>tp2%U&@#)mg>w}9MA{=z%uEx2407b*ds1* zI>A<4};nZlg9XPznTMVbbgEhchrRA)u#B5b{EiQaIbF2o!bp4Y4*Cp)sN)F`gUKh zsM00$JoCW&PIkQ2vzyF#Q@EM~Dyi)YlBV=}R_-VAdUZZz*jM!4!5Mp(_V-P5;MhSb zwP}6w);ag8I+wA@H6bom5-Zs}UU1=cwKAdmHN!f2yc99CyWxP%&8S5vSVh8N`e=rl zZ7`TD6_J>~nRpEOke>wJu@7Tfv1L~QS{H={V#!MW`q`|3NTiHBduS9q-AqlK`K|YH z`RZ^}1%wJ=c&beu-Y?d+0f}sc8)G^1WS~#1%}#1>iWVq6hI$RX0bFlQnVm^e?yxJh z&LyUFUn$H808=UX52{^_6sz);7Y<6`BG%iQ0Yxva6}EECzOm0owXBY#3=;AT)W^fv zGF)g^Zz~KIbjZyuLnD(Wg3B^2(#wx9YO(#JIoB8svWWE7rzF;m0oD@*2SGc@f^c^Z z-ndzB#z`Z(Q&VV#u4D))kf=OR<_D{o!99j;OsTqSP8!4Cd_`BsuK4X+ ztJL8OZP6;M{7JaF<&PC>`6JV>tD2FZn&g7=nI6=FQ^R9i_-EREzlB=U$D|<;H^Xdp zlJKGtiywczQj00AZE|x4{GxG~&Eej~GN+wJN9A!n#G5v5E2^q{=)ZxOsw1ggOE{K_ z9-PI~bxJc0#`9RT+$J7Rcc$g%Nix3G%HUDk+B#gQQDuL{20MdX`RI1KbzuPi1y8vF z1Y5JjQ2U_H4=$O;>ti~6G_JQHR8c{YWyD<_)IX$8`~Mz%0Z5{EK+~DJNXv+8=smpC zs37kI@)T}oG4Txu%dS@DTDpV{?U2oF7*Cz$(<}(-waNap+zcc)xi7oISWgy7hs3z$ z^j-{-gc`l@hYgxb;#$zZPhW+6Xvx#>AzJcLgQJNrauM=Ei#~RH z7>uW7)9^SXDv|z-TJM{vSUepy^4UP34wYk*R3y<=#JT;`)|vy)zJ21e-{Vy@gyz}x zgu=)q`Zc|=`R`VOCc*wFVxBf*0L1vuYK%C+U!M`C8Ct#24b=ji%nD14;rjDbX^ldQ zJwv(4@UEsch35=Hz}}_Gfp}W@R5&k|bv+#)v#{AX4>qF`BSbcP7vHqZbJI3Yt+e87 zC)Fx#?mf~AHJS~GbHasaeDTwF;j8TCpKUn=Sah~dytUJK9O*u@Sw>-FV!60p*mL{< zEMYt8l|z5#F5T&0LsUlDq2S4gR%MRuI?q)**AeRPdA!C~wb3D}XGqHfvyGw4*)OIw zRyYnLrprSJwtryw(A}}wk>9dqPg0GxV)mBMd-XttbPf&nyn?d%pVzvd*tBT)L%uB5 zpQhK@_=|I9m$BV}hvCJ1M``!7JIwxigSLvaR#<`wSb1K{@X@bGNDB1Fl`>caAkq&b zNgXwtDwdGB_Il4~F>&%k;;*3^*JZYAJ+r>P5(Rkigm(}zkE?qX7f|S89fEA{cvF!@ zN%o_K9-QJrsk~&y;$_hMep8y>C!(GpPxgt`5)PWECTu)t^!SbrdC4XPw6t+==@&^Q z>u&!IM5>N}?@rzQKH?qe4mF*JNeiFS#l4(}wWy6WNIQP6ANZ0bo)U29X9c0r%VzNT zpiSFbz`9ZWl;iy3dF`Dp*0Kx7tzSe56nxDa|1lwWpth~^>5*o8sa-<%9O!O1TFDy! zl(MgDJO`>RSTr;G;lJMx=xfFFykfu3+i~1FMK1fTxF9PuSZ8Wg=dOYIV}yTBDkwB8 zs}X;Vwz*oy?@DPRrAvo4w0`TfX5l0s>!_2=loOfhz9#|r!^d<5-|q79-P`9SW!~ zV2mlcQp_njVS#$B-(ONP&l3x>!~5i=4}(ST^YdRj%h${+Z7gJ^`q*S|ZsCspenI#w zbG|Sc9@H6OXVRW1i5Ir`(!!aEpt4FGXJIkCUd?=57%%ZyzPNRwd|E}e_8uR5Y&rKK z-t9mLi$8)or7EpDkZZL=pJj1jjM-W3UV}^9nr|ljY~?@7x7txXn&x|L=vCSFd-`1U z=qux9N&4@GR1{YH(?s4I2czu)%Nbv1b*53TRhY-j;}wB}Yv%7evun2U``*Y>Js~-y zM%mXi-+zPR$M&q$)Esqw#`nQQysPHq+*XWiS;t6*Z5c6JUlylBDmcf800+UHh?&O+ zjR(?ZOCP3c%@0|fC0JZVBh-Efeied(lA3gB%R%MO0}r)fB=e zR(l)F+OVq`M)WXdZ!h=&(6?yPZwX^wO)&wfNsW}<>M5HfA1H0bA^^*=H}#-IIh=cU zGK7}SmH%UKd1|j-LrN$Q3d2TO ztPwXDIwk8+w!ZavCKi2>UsdH3tEL`2!!PF-2IE~cBNzZ58pFZN8Un1a)9v#IW*5#i z=x)71xWfoQEaft;I|cOhZx`0*Cm)^u-4xx0=~rAKoKtsgfpfbz6NT)0s4#UsKZo~n z^E++Ehv5efo=>zLPoLg@wBK$1{SlEV3|nhfsu8F<2%j3XQ!B9l4N3>Pi{0ocU>384%nGq`bSRj;4@(BtfjW zHbeA(7DQu$r3Uzg-wK?k+`mzAJ*Z!0AkPQAO@0^sX}0A4=V9exWj`c1JXN+!a=!L- zpN^Wd#kHx`d_EOqx$mhfw4**fsd9EqRWc~aTyXZ#)Rvr4VQaQ`BcR{%GDvH8 zt}tP(Ps}gbx8O7Y;w-UNwMI?&nE(7$)IN5De!Eo}_`i@Sy~jG&*mu9@H1XD!b7}@C z8g~rjN!|&ips!eR>tB6XCrP}d3WOLcA^Tb0Vy;D)Ninmc8(LCLeZ1g3Yq1o1NKoSQ zYkghn`S3OvqC~9xt$>o$%l=KZ*rGkR=k&hEI=M4zX5^F7(I;*owE`ip|7Lig4FLU+ zgQff21$lrx?Y=_Gdu0PU#z455p`Q}|u*F$N29B>MD(QhG#E_Uxhp`+x=VQP-j1L=3 z-^@!j8Bc8!Y`<^vfVnE^OiynnsVSN9$h;?`aBM9%8>ozCf2)auGVDvrm zW!mi^859>6-!3$k5%1^IL_((gQiY>JBfeUf^fHSxYBNOn{<}C^=I|3U&z(xX?}>UT)X5tH+|CE=@66mEIqr6Y6>( zsnoMUnp$gu=sUs~uKL*@vB7gAhibh+@go|3;Rm7woGEwYfw{fCiPiUJyt*~leF@w< zeGMxQREP(zF;|9~79^cWyxvmu`kKt>Czu(~@|LAo81Vw5b=tKoAd-)9)mdC^!FMh| zXT(+M=c)Ze&mOI%`s^5QtkiIsIlcinXrIO-1f-{;EWH%JJg2kynf@14$PBA`csXrD zn~YPgf1VpC^)d(E;J$YlNpdzyd}L4(CsOzpihdAnAEOyg9mE@pT55Lwd@xjWqfp+ci3U zJOwa+XVB@q#Z(BXo3QR8?#23VpEc4n=?>(4rM#d0z#-?+r8}uHU${P-xxYf-Q}XRH zocWgqhnyA?p8M<}1vO&r2Dc&({ubuFRtXQAE?0a{#+3FQO0Yzwt^wWxV#u}hPsD6? z9%4r`+<0I_zN^&Q;8sOlv5#JduTy|_rm*F=+JHOZ%16+d=8N}`Ys25nICI&?6SzIj zHp8lYfNL9oGY@A!XhF}rOibEI+oWD^KpW%|#rh&Anx=+^F+G^?xNFrf6!IqWx{u`6&$QnI))5*OjYD~(^ouN@F}8{zgFgH~us z|NR}=s>@6E2aRSCS0_uF{8N<)b-s37b(pssr~ptI0K=88?1b;ZKbGOSF<*wV(4FIj zWmnnjv9KZ2|Hsm`2QvA-?@E!6P^l!OlT>1rYK~J$Dj!rT$ynzlWroGDt&)&XlqH9C z(7`#WHq7QMr!8{GX>%TiVYb<3^LzIB{{DU5`+fFq@4NT8pXn?`w@-mQ^oDDpp zU}`J0uGKefu5LP>x!|jVv9Szq43ci_!H;FX<{l9-gDR-n<91$BubYU+J_!4_ak*v$ zWzuKVprV`HQS?jZr}XuMj`AF-qx=~{2D&^GWIUS1)Xl)9ZW;(ovkTWVpr}odp<#d z7T6FD`;B=S!B;A;S?v4@Wl(m|hL}KH$|R}7&pGT|{J4ABoT^EP*@AEMj3J?&+r&(m z53jVkI8u@skKoMe^2l=|$jK3;cPf{{S>t?-@og-OoQfQ4VoI8r%Iqu4Ou49Qcvm+6 z8@r{KNezJ7YT=Ks8!2sNpIdg6o5OEc2fSl03cr&ZbM(o+k;rY!gN33`T~cDXI@H#& z!eIEJ?pu{8iBAokOu>b1NV%I9^~Os8REcP${3`RN5K zrzUK-PaVf2dVu&Lh%6@W3cI(i$yGl=>|IoTjRv_79L!j~BkYZ2zwp=B-48XU+(!+j zNf$h}C_ggGFQ+6&{LI|DL!NDI`hj4>`u{nuqE3wxjja*CEXM*^b$@+i6E(~gP6)`t zrk5RMsV8=c9_wl4Riazkd+u?UhiG`tHv_ctYmh5E)GZxCC}p}{J68gFFSt~rY9H-iG^ zJK(!%z{fReXtx`Ebe_&04&wJVigkSjOIVJ_k30^g*)h}R5By139F|Ug+}u~0ySa># zEZaN%cjZXJ2H7QsaV;_AfhIX*$>2^rs>S^N^`6w!{_-e@V2J^k!@@N^X5$QKvGhW2 z-@Xvi*-o{if;^xAq?{k95y3g5HQ)BA|S%U_<>fQPIK`E2qXv4oyb(TPA~yuRDV7 za;y82U!-3q;|Mhe-+c8S1>Z*!K}Y>f$@=TagEpE->O49`f*)*?Vl@IAuEHRR_YD-D zg*Lg*Pp<>E+X8Jltw3Wm|3%;`CV#wVsVJFiIf1G#b_U(aUc=&sk6ZI$~z^_esQNK#P})|Pu_f-R5-;338C%psiy& zuIk?bO~xjF$U_G!9qs5J{nOrEn+oiIk;Y2`KNRg%-(ajJs&B&>83{AbQrkP@&IT<+ z9icGl4$H$Wwabfb8kHfOWIwvpn0y^LIE~(6b&qkbz+4_r%9| zbrtN<_Sk0g=6w2|+Dr zmgfUTsp;6)b77}ti7%LfgWQMsO+rKZNdzSw_?dqTU7FkM(y8k z8a!$?Z2JmT!V_+0n;_;5Zs7ET_t0*#RH%c#BlODY~BZ}slV!56*-|0o*S9{JIEQdbSPHle|KsA%DIb}qf;(qO5M_uFR z(68SAdhCR|`|n-5>U3Jxjo~kM=ATD zj~But@e{4N>AXwTKZLAtRM|(4$6EMk%eki9OpQ6;{9Y7r_tNEZ^?A_g6))1K-(Ro9 z-Ma$-62&kjN|)xHSMn`x3g{5Rp{EqQXR;(E2UQ+s)mHd6+~N5CO6Cbd^Z;Oug7Lm% z8q?g8eFj?naY1*{2}WlWtWnUoLw{Z-@%;NDpxmNdYErjAmGHa>9};;JoMZWFu`1KJ zXZ~tp)V(g1rm%ZVNWKhCV@ZmZ69t=>5nbwP>hk|Rv>D_vxU(o3yv%8@(lJ?mj`aC= zgPrLhh4ir1_S=3t@(j45i(Y&>zc+#Rzw>J($MPT7m@bEID24XYX!jAViqPz7?Q00I~-HP=b+pVwRa_stpw2O#V^KnKXb{O9gS`FGm)@` zharcth?gLptM*8JihW_Qe+G67R{L*N21a<{SCBCTeaDe(zTV=2fj;lm!N5kdRR%or zT|lB0Z}|MJ^cB|2ee(+j+d^gI3HJRxAlR5}{%W%NlD-W2h=9T6d-+g_roJ~k8s=Kjit1kp(kNepX8q?(cUTL*+*2Yylvx)EC;4$0TR~H z%3cSJvmn%`92{Y*7Sr$um6G_9O!{uqSH?FqN<)&_6PsN8ZF3dHSEztIS#q@2<}~cZ zNU4MTDviAkoL>B2u*yxEjlD3^a^7gS@OXhi87?H+}W2Mb*@9f zc}6oo`wA_SMW>_D+%Kqe@gx7Sa=vq1-9pc{R|X|wf7KO6CO7o5fKr^r&ouVUJ-`kJ zow4i~z_N^uP$o}^Ti0vPcKy|UiTI3tQ9%2B{x2Fd8>bY5Dd49s&cMmjlByZT`^`=$ zK&v+uJOD-jOMRE;g-@uE;$K3x(w?H_$HF7R7Q}3EzQ&^G_)_57X#V=ohvOz`!)N)L ze`^(rgSOgEbf)jw>_)c`7$mVPCcqyQw17lIxg+3On*YsLO!mHU)WOh=hryZ#q!?H8 zi2+Mj+<3!F6RV6FdjTp47fY8Fcd4ZrchUc%oH43V$SQ@l{BxSa1HV6I5vJOckrnLR zIIPV;!Zy&w6|@ymAq8!IxB_}4XdTt6?6Wd-GGCeW0nk#;+y}!Vu}B4V{%C15&t)>a z#^yT!^0*rK&(&tY&4Ht(j5ca8Bs8#g?`kNI)oo zY$}`XtK5=XXbv1CsDKW)(wDR5l3#6D=z7@x&kJV*FH-as_Clfhk$(Jn-;cA_yP`~@ z9lZNJm$TQ)5*F(L=o6}sEMM>GH=Xuvah#gjc*q!R{a1@D8BaW-36Ue=SA%|sCQ43r zD@x0X(59YR7m*=Nx2@-8?FxYt@WI$H>s8z7cQ(?{%akea`zCy0S*TINthh{&atIGS zM(~wkmygre*Ag%sAdH$t=(F$Tf<{8CG|qJQ5&@R-ht_V7FIPC zalZ2ZQ~Ugo{~X+zj@%MDL&`Y&S<>=LYgeAk7oAI=q^#q8BRo_wulbn&em{zTEnn>0 zoR2eB*0xUVQ_a%LhXkDeWxJO$61EzrH|Ejlr=*o{D_?$>45nDT;*>YB8J}I`wiU3|3Yi5VQpz;;oLw*DT)%gxQW)W z0_s-*R=_H>z}m<`9#jAf3;IJn{cM8kR*RHbC|45nv^5|#E;>EoVag2|nsJUt9_tmo z-OmXd07ww|#=O^hVwcbRM&oVrhCZ?m#hkeTtW1Z(@}F|IZm$jalst*CgYI#p(iHN4 zpZV#PWOc%>Zw8n9rG@j~I_gFh1Q5iI%1CnGxp)WxI=bwU=5gts=R8+<2_&JvvfJ;S z(a~bFN4&I=^0T%I0n8IkRQbK0$dkY(*4@U3w2XnN{vq9_1EV&v*1jgbo!=6ce3M-Z z49@wBpzMrX%$}E6**ijeJz2`QCOh!A-*uK3nfg zE!;%!F1zj&B&9^&-nn-|xM>j>P}zXlT{$@Tjj4;=0x!vdUPmvBRk&2YO3bemi#hBy zMyWU37R*RU9hc4fR)lku_?3aYRR-S)F|LjlgRRlshR!!-zMtieVHpY-Rq)Jp z1=*3BPAR`OtfcCyGGyXxG6}{ytafCS8Ean>-5oKil}O0uKjzGw)3{|~_W{rRuTUo# zH4_OI<%>ZznU6dk6My=#_~lJb+>o1KiA)4y3;xpv%#s13Gc_Iw%TkMv0U!TgA;c-z zW%}RcQae4|zut|iQZR1~n3u8?YuZIWI=7@ZM{@=yM4|6EAz8mvW(t!mG?gm;X}ORt zHP`g|L8hKQcM9gM8$(y{#(B&-*sut-!5b(3n&9X4RPp-ckEEv+s4Hl!=?fqzf4f zI@N@OJX`*W3xR9aD;V5lE#gq=Zs(874tcvaS{yOLEJlZhk#Ev)u_Q$4BC#tE$oRnRfS3tT-8!QUlN!l*3n4&DoH--+jK*)m|c8pkvVIrVQpfsuAIv&) zc&O{BZmi~m6b^2UA5+VC!w9sr9qO(Mxj+*M` zSunpWqs(m1p{!}#bY6Sbol$sLy5}{@15IC*2hO+;-}ZAysY)2x=>DdeAwIKF`yhJp zCtxf4?p7kMW4`^^@ml42Yvjqw$3=QxEE9BFZ2?8~nBjS5qCoJ0u_Uib9l#!eSn|I; z6|e}bA=DkUT8B<2z#2 zx}`5yP?dexz)x@19&)_R(ziCfDpdDhbjM=J$2&}U8_IK6-`Os=?^jCZJKr2ld_@d$ zdg4TyWvm4AJ9An?rlK$q{dOX63j>jd9++NgKQ^!s(WW@nxi0rhwPpdsoY+BL%V%9Yru znC3+_^$G>|+7$c2QmFe%t6Uv%gJ$Kjcr)#-Bmw#qhL}BpN#%;M_PGACou=sm)a%)x_oYrP2a7Y3!5DKDatv`+kM{f);V*z1vC8H#L`OYR#oiCswz<(J^jV1pmcH=A0xj{cj~!>&f88PS&oD_AOOrKyibqlmK{cWuZkKN z{}q67)!wg>Hu=BN_8Q#3b7kummD8btb~FBg8-Lzy;^-`@Vh^&A8_A{ zQwMM$uL}h#EG_6Wue#;%Nn(s1Pmu(H6t##Z5T9u^J1u~|aWJ5sIu-mJ_`(EvfStPU z(!$w7jVL2;y4arC()WgPeBN;cUK{85E$eEdw({_gFu#B<*;PXAiGE0OfWERwObQ?M z1N2{b>h(3;Cm)oF;A7>`(k#LZpfCuPs;{>@Sd9!gI0ac9#P2{1+mVyaet}f8(-|M(= zSO_awZy~AYQ%!gQ55V+fUU9u~US)=1+r=;WhZEbw$8$1p`V$hMNZLR&;(i$!?KJpQ z+N$*YJ^=H7;X5v{(5JpUnvYN-kli7AVZYV#iXs7O&ryeliyxS8E&ub}&v_cO&3g*u z$gm`NLS{B~V8g#J*APnwaTAFQ<_G!>cf@}RqSgznNyD3SWmL`S!WYo`ig4<{l&Cr@ z-Y&7ItPKEvZM$oAES%G*Nk>_|bB=Q35(to_YY|%x4$+f&Tdx(o!35F)R8cTKxDo!w z`#m4}z+ou|^#``PJx@_E?B>jZ<>ThNpDoFd+vB@-Ol6$RTX+0pb$>L5DOZr^-oA( zo~xc92c>#ha~jkm@mj#63E>96^Y6zV!oUKcsOvSKz2xVVp8ZmBElsOWe&+35z-5)B z52d>;%I^7b4NdDlEIu1IpX+@}Eu@YQUcv984o_b9CQ^1drY(Jh43xJ6KtIc&nmhf5 z43VuRu7Z!|JdcaHE-&2pofISMKZHW`f=RA>Jyz~LWv78Q(E9h^^e6fNK@c2>*LvET zwssgd2CFGb^g}h${_RU52bX${pf~g^3Ee&=rvBA+H#mo$l(aWkGpg*F`yr%0r5%k0xbwjxNyIlv%-c`@vp`i!+|W(|?3nFuO(Smkc=u>XJu=b=oD2_XQX7}8F`YFy9hAE@+ zagMd$g6RY#?4JVm{JP>s;65CN-H5cJb~Hx^ARwd9Z{4qpJ-9 z0PeVgp2g1rp*v0647^Vipf`Uy_#qPfYC%U7mxbB9w%AOMbST@XU|@>FU?D0f&9S(n zi$BlTJeN{#OzIx*eTm1?<3;iWb>h^%#p<4}XWilB&X3%V0ZqZDQhL?jZnX1L-`hK# zFAs4-r<>@SiopBQfXN@lJ z=)VbDLQQh!%y!dgQd}zBf;Sl5{gs`*@4Y|Oi)hhs2VEIg(yk=u$Dol2>uUAi+q7Vw z`5c{qwdZJ?2m%yW)5oT4AYpvXRO&X-%&*XM-0_Ylp%XDbHh&%T_e#1RkQYPwv>*f? zoRk_bdb`qI)4;F$|1d-&t?0RM@^w(~@9zkC;2F7>tGkS&8o1d(;;QgXn|72n^}(c% z79I#wrWcEwT^vpH0F9UST%JI3gFj`yFb?P;c53T8(52zM+W)!0!KCk#Ao%M>QzG~r zx_G8AzT9)xP?ZK4$l2bscnQpyY| zKc9eS`IV^n9`(d$8-(^(y7mwnVH*_5ruN`u8OC!?BT4+=J0MNW)FWo;z)D@Wnt5ck zbCC@e2@!%uzTnhLX|h%rbgreS-AoNF%>6NdcCG55&JTy$+xURS_dty6|JP&G^XTNY zWGr>Cwe5M32-qUJNgStX`zRWdaC5EQsHY1zQqUNHa?&AR&K+WF*IHiD(ABG0Bc^p4 z9OAuO5oAkH>`l8IyARL6Mglm|(k$Bb7l5Jc)B}|`R@}p#a?sH`l{V?*iK#k+yo8P| zwdXZm#}ycSX^aj?8z`gka{;Wxf=eB1q$ZzcV4pe;#oC-Q_%r07$GapMKIHOTVU*^` z=FWr*;VIFAGd&5BM`gzV%IhU{1a7G;AKS1L$+j4;b3I^gMG@6;qQ9y^ljb$PVjN2V z4A&E@Ub2UYOFdF-Klv@Ulgt{c7DDT;a zeIX>>*Ftp+_$Ly zpd-y;he$|qM9_-^!A9V~g4GIc%pAnrl_**CSkDLD1|;5F@LaRwQ=dHn zE;LzD@_IOI^dR!wi=F)z2K3QYQ$irNgHU4tM^*lU_2B57+I2U)X{%rZ5Xj#O>i28} z!cX1zW=2F%(?@NQ~qD&;lDh@vcn^4NLmK9+EC$yW9&cpxWV!_ z@L+vZWi@PK3JOs7;hN-Q3%}D+t=!orqtMIXO2*a_SNcZcmsDH5k_KY*Gg$9IkJXDf zy%CFb|_x741Nd#G{k7-DGs_MPD+B%}fthOF#8i%-D*d2c=U8UptN z+b5YJ$~@xYKRz3>keOMPXp89^=v4MJ5E%;oW`tCL3EcVp~fu(;{Dmr2l6Uk8g_P5Qxm=WMay~Rk9=6QA4y^NUIZ** zUYrCb&61@r^DlTgPDcZC*06h-#fkZ`XcBV$+-hB7^cjLjuzR!HJ0NGsvK4pjG@Vkj z>=^E~!IYov?gZ4g{vn_1Jr&={<{hptLt;jXe#d_Sp?9nmp>xsQg-yqienMmEn$JJA zX+L+!40RFRmm*C$kQV>fnj6uFLhSB`im=}f&Y>$-5HVHhA7TVo^=|K{#2>UdTJ6h& zxg@pA6QaA_iCYGGW~^-^f-bgE9;2l|Z4^UN^}RxPD_Je778x2;&o~nVh4*I)O{L2$ zcRh}=gtS4WRl@<_=n{AOeCJnfj_I|O3hblTL7pxE%l;`OUJAA0zB@km@fy8p{_fB# zX$lE=NKGNrn1xR$9V+;hH%7c)QIVD1x4;t&eEKHvJB7E})1KvAj|)Sb?-c+-*+Ncr zfG^y?#M~Ec5KfPmO#Vs8|AYe?c}DE#Bu3H9L+-oK6O_@yt(zYgb3*`(T$scxLf3pe za72f)UShJ}M7CT(1WF3<4eL9dI&S}Y(&E8LiPbDMabPq4q9RoNef}f!r&8v3R)RPk zp=kBP0HcEUu3LvsR;1yI&xem$$H0~uVKiv%@TRJ%Ru?5v@}ZqbD!ZlJWnlEHHGs5@nxzE!SxT>$4+ z9rAwM-dW+Ohxc#y&D@yze-)(TVc_VR$D~5eT}>;uU@l2+RMea8)E4i{H30DG&VCY{G3dS(JN%RX!W1+gBa48Va)mJR(fraM+P}it90{b3MUpU2>bn-oy&i&7(H9mskuEYU$F@Uf>0&m zug3vJrhOvvyyX~ z(^iT^2&heKZc5Jf2^sS4TXf`r`JM7!z9x2b@NrD3PKf_OQ?OtAe0co1F=%VSRm|WO zyl2!|v!~-zSaLEp3ZVD}3O(qv?s>}5Qu}dKwYM$BGZGAv_}bTThA_u(v^4>yNre)0qG>M&NfejYu?`>#XcWAb84mCDH)I9*EIgq4hh(SRBGkE@b|Q^I*TlT2T%XnO6URDO+U8V9A2QM*-VRKp zDvgHiI%t-`yEK=ZK`!hC`QOz3eH(x@tI}+cmE$GVJ4pWzX?%ORRT?T2yq&~-Al5ry3mz#! zyN}D$q#cTRBOUSnT@C1U)ngHYt=Y3r2J}-{NPp%MTpV{kq!8ZFY<-UPp^1c(T zCc8MtRKL$IXgkt0Wrm7vRs!ip&#ytdU#e%kGOST=>#WjmA~J{zH#CR~I|euSY7SCy zm6ng~p-*`+a|xuzentF0mjm%Zp>p2<*b+F!Di0VWCXiBv{(9@trhV2vmXV(7Q!e4% zF0@xKhf7vibfkedaAFNN3^t@qd!^S~N3Ni}7@KddJ+5-*9lA0H+ohmk&l$1*8C3Qi ztQ9+|%!GR+jB9^e98ttqD&o`g4SH^VM>OzhuO-h1ZC)bgFZw?-V%J|nNQnKx3IFWS z%+r-EuWEh?Y{^K~fwQ^5a(>%6lPK7gQ=9Vb>;h{K0q-5fMBhJVxa9Pu$G?u(W5=?! z#StjOTL0PHRiQRg)S&t?VVvmJstp}1?Sk|$V6$gM zHdEA`v0Qv=BE1UvL9Q%^4%L7A%RPwSr;sg0GjH{NM-ve5Dpn5DDl3$L$h#M{+iRfk zp_+UHb*U1Gu7+AWo31$DwYUoTjkb$_jlN!3m_UTpf}+1H2{`cn5n%KjZo)bm5+awP z@FCd-ob$lg_lv=H0|#kE!D3CO){r4AR51*h>CCBZ!OG{?%_P1kEhHoi0Bc_`NtYo^ zD^#gAGmV4YZK|48!r%;f$jm?E!PR+M?)Oz)>tL8BQsKEN=Jqs*#G+jFalsMN>~}_I zUkd|g4`0V|V`yG10s3%H*|C|qTZVX2!afHWmf8!jubI5~!u}KOE=OdK2Gh)E>#tT> z3BW#<2MW=^nf?6r_f%z?$Dg2!-9Rqz-xO86^^KQz#2K9MN)86hP2j>=0%JT$DY7Mw zwq^D0Y?D^>0RLMdnD;u`OmyMQPd!nJYp=>2aW8O&K<9m?v8pB`WJ`;qKK3os2@8Ks z^g@di$j&o-QR`4iL?Z_x*>n2R_-Hiu2Iwwu^ zfEtwBa6Z%!e|wb7Tiv6}Ekk2M#~L!8O*IpfC4C*gj?N0hG}~qvn?nBnch#nXiH3FX zW^aBRrf(GH6ED7TDSNWv+HS(!zECrc?5`CKUBu(I-AYnj@l` zmH0eBR{ufYBs(jPg&yn(qg_`q-Tm9qx2ukJJFBFyJ9OU8f?e=5<`_K@`#BG1JjV(I zicf=aaa>a(r}b>Oa%UZ8&LUrXndlw|%K8oORvh5HsyUJAu);c3of^!yA>AkJ*!dzBB|WssB*jW5>e%GW!$93o!lH4{&`3#z&YzIeFn9l)KEO20-gP zQ<|*!9wpN*x9DQjF=`~}Pr#0pn*k#e&Tg{W;*IpMjN{V5qWs4T9Z)(~(JlxzSz((g zJXc~Ka%wH3Fw^mf3=TGOz|+=fy|${#ROnxJN(6rs$Pqk1{{`&yW#!aFu}bFiucf{N z1FQ@Li$}g+#9mHD4_c0=q_Uf>g9k#$K*SYV#NL^wMcZ<%d)d@1u?5dG)n6W;5ZSDMQS8*6{f;5qUiH6>i{Q=>U}s@Q&xdA zrBrp)P;6#HX&qF0JU_+MZAu%)k4`BETt(!Es^Q*k62AC<=NIMW=h!(|CzmIh2N#qZ zr?LZ!qOKw>jNI7=@NXY$IK6oqBC87 z@w}fi{W|b;-c-*ouU*h=@t4#f;PZN9oE@Tv4*m?up_OHcHo+UGr|E1dRV8^&%4L=8h9V_sT{lC zlAYsxHLyyhTufgRuDd_-9OcL{%#$xX@pox*zs|d;uo_Keq9jucSJ9je&kotO9e-xA zcQA6GKC>{PHtb@pto@dakI<)a9!ek0S?A`G_6oRM->q<3(3l29wqLrt0oq&r!xd?$ z39D^+l#X;+u)=hmOsJg%?|b}s&c8iNXp=^%n=p&N@3VFQdO<~rEAr;Rdtl_)h{nO< zDe)nno&kaZu*LdRcmSQ*y@WDqdmWaZOomcI>F}BUR`+DKx_H&!8gXROkHwCh@G;_t zwF}MpsSOm44c{VU_Rqk+=>y~2sPXK;ye|jPbHo~J<@E+NLz-LmpIW1?Ru zy=^}`mUkjFiHShW<{^{04bt4l-O_tQ*_km*_j}K_FfU-H+ED-w1*4OTe+0gDKYJ__ z`pz?!?@*)FG0%CYwBG9d_^nvnoGI4KSf=rO$c*G+LfZ3)NND~ z7Cre(0}MT0xhd%MMEqjOkk)hSMQ?33VYs`PP)_EgxKRzUkFi2knD8 z)2SmLvW6jO$_q?bl|>Ox9WexZ{?5Jld;LljS4M&E&7QB)~6m+CnCDE(;VXqIqIU+3*`WvZ;PD7^4KIf&_S zp#iv|DJSKZlOa9OOC@=Be+Vp*N&c<=gA1Df*KFoRcVSFh1?mEtD)8G_c2B{6@BDy7e zBh9i%MW4SwYg8`PIas!K>WdV#8ZXL!GpOUBYTAZyH&DT>dc#+(M~2HIB_RFMzv7_x z!>`=+gk|{I`SR>$TUJLuAm7)V_0hK!n~ZI;XM`jF0DsZaDeHz|#Ygr(W?6dg--239 zM;0P1F!-PjFukSJF^}^5!cP5K&@nrW6Y@%20VcnIB-E`S+bJ)%sH_lqr1NqvYleF2 zy^`uUn1ohVT6SlAil)tD^IT1~^W@xtFV?2gZH=M$ucU|?>HAH1zea8|geQG(O~kDk zVl_rNZkn?_gIxKEzT++hk9g_VshyBNA~$S#m?UmW7c5j;c>9%>&U}OHGP%&j=RZ>L+;qPAlEa$w@iAQ158F z1s(PYd=U^1u*^pe@jf@w%Fn(c>j;*Fb0>bt3?obJ0y`XT$qPTnrNy5@%V=L^hAO@v zMC<43E)fc!{N%Umg!a;2E67H)bq+1vMlq~w*!!^6;oMm(fJO}mEho-;%;Hmu4KIkL z-=w~#bXU*?>P{VG)uG+L?m) z24DT6)tA`B#&(dciy^3!eTit4prQ1g}nA!0A{OoU7tOKm}z#dr^E=O zKdSE{JUlXJl=iDLznpVJK1#}&Y_WCc*Sl%ZeFHSGVh;At+uY*R(mgtY} z2}{Q2CnjV3c!T%HNO0jco}=)XQQ5=#Y#sXYb8XIJBmYF2tM^n9rr`y zc^8?qjtI4D+uz)bZcOw_NJsv*KMzO%KMHx6{%g-Zpoo& zrgAU8O3fTA-z^aN)M7Y{A&4q8bbow&`lj-x6Xg6!%2bcS!kqWRG`*C;yFO>4m4DN$ zcsawMr^u|L&g>kLZZo^D^~18wl{2B(gQzO>DQTZh=Js^!?U<2rHO8rAXwyMxo@oF4 z#dRH0-bo|ouW#B)-=d|bR|btm982-86$nRwSia*StM}CS=egbyvE$_|?@EE(svgYl zCVRA&6dhdd&hr^_w7Yzt+#%+DF=C!f6KuG4uNtq`$o2Zh(q_^$;*c3nVT>BHZ+>Go z|8l$EkDh1>wplTyv|m_E=^7tgh+p*UrTbz-CB7#AEG8$rDw&R*kZ}mT3ymz4m2aQu z%AT+?t*H-qY+ zt{K?H|9CL(U2S+1{K|2lI}G}i*K)kFXIIWbUxrh0ez*wHjTq>7n4o3Oe6DF^^YQ{J znfGpH4e3w=;sAg7WU@E`i#UT=of|%;`*`zV+3XwW9mV?DB7KTJ3QsK@C;u+lcaI`3 zahE4(5gE1TEfDIg?mXNKPH|VwP~ZJ#82>i9E*SqQWnXZ!xC@B6#z@weCP_6Fvf2&# zM%Qh#`&_h6s4OV^zu_})1NQDGX?9vYV`+~UC#DJSI-viq*lat#mMzz zN=Tahvv{AYV}0sgz^v-tx=Dn?qLOSD4}07obwbZf;Rk_#bBo8R2Eti_E1ZX%QA7_* zZ|f`PtIQl$$z^V*U-wHZ1;b{P?*z6IZQ8Qx6+6?q;~j;?92l1UY+rgjm1h~4s_DdD z`V#uIq?EzDW+~m%Rlj{L`p$Txk^^_&VB{t9^bGJS+jF@QiLg(xJp7vE5-!+)=s74O z`rpA-f*t}E(mflY)c%8vItK1XvcxTrp(4PBb0>3=h!uk;et)bWfCgt2GrDs?(mh4I zm2}Ui(zm#>pzyejV=?Q}n0rb}DQQfwD3~{Zm;EG9qYx+85>bL zcfT=j)wmt-?8l|f4#PI|ER`o5uL^(MApTIzbp@Fm`&>~^ZAI<6GPV*T$uImfK=fuUi!a@ z_xWBa-l6E>ylKn(WL$oj0ijLlfoj4E z?f%^iPb~Q{HvR0qw^KsPMU$}sx_xllTYiMh>I!cle5bl?BzJ*46tlQtVd7G6!Kf;nfZ?# ztP!5vs#*H`VppcNC3<&SoOBX9kDF;MiZf?MO5SOAowgMm(;+{dvfs0JBHa2R!)k{1 z#USKe?lV_N;6Tz|kw;STuRkw&|6op53*;UoFq&6cDNYc{_V6BD!o;<8gR6Yv3VDfU z557HIQ~iXIbKQLKR4aQ`9-rNjVFxC8Uz#eMc%b2W&SssZLDv)R+%aHbx{yjq9t%3d z+pNcXHafp1w$xSwN(xKPoxxX{>vTTB`%&57^kUqwTiAW_u-<5eyQp&Hi!>((}f^{Ww=d_mJl$q*t== zewSY<=|^C@{YG*@kM=c(9Ns>eVZK(9en)o-v-nq){p+{|yJ1Ub4^Af)0^@GWO~t$@ z(g+_+C_fhWtDCELcS}*Sot0J)oWOLECj`4ks_^z=Ro*!t<`$fq^Hod{3s8bzvZPzAmAr~PT*iKX&kS6< zy(FM6R3qExxOACVuvGtHt_v9qhERrVYFpcO`8&gMJUl@WaSx+Yd-}f<`7}-KHux&2q6&a`Z6uMY%xuvk(=5 zwraR|{pa@sdF{>ipD&@~dF^24B8?oE6En^u0S7eOBFb%069V?VRGhJA;G;__`&9D> zOW2ax!oZwxtDswiQle&B-oD4`zcuy-I2gh0SFlL6IeX;iK9hpI|_r-x9(zUH3dbgcS!R= zOB28Cy~LNHS?@W%b4q7OP>=}w&vvf#y^=PwgP+vua2eyQE~|gam37P#^@MA6p$xM| zJLRelAN*|uf=72X;M{=-mHOW!!X=%8bO(IPU#?7aj=+7Ny%qG9oL6OG4hyi;c(A_` z{id|CclzRntbIls_C7KC9N_7KPP3ikoFk-A_Ma-XdYXqz6=N=|M1my9YaFGeJ-2+c z;olrBIzuo&ZFK~_I71;yJmSrqaW`qBjQ7z5&6~xXNMZRYg&0t*iq$< z?oeQ;+4Im}m$`H#Q!P;_z63h@bbllyprcRZ@GZCCw}eK{8gGXn!3_h+f9Ic8L8|Qg zL%PS)an166`LG{oEruH>A5nRHC*zg$ZNqJ;-YZ~5@oqENoBUxtGk-OrG?LmCMmNk% zbnl@IK54LdDK2@4kJ^_ox1MunKBx~V9^5?slYXPt(1ujTUv*)M48xwiO|!a3VG-^T zqANf4>>o_}Y@YU(!GnSYzKIwbh29=`KiKpo=gfK3Emq3^&IdrkvKQZJv1~hxpdZ5s z&;gl0Z~;Vg2uxz7Z?6y28uxLoXa1B=fY-J9WMj8z8+Y{?a&WNCKg?6ALff8gKvCKUx$gB~^dH7;|_n$c1Sz$3PdXSccr5U<4**>oApW?Xh zB}ysv_;6OIPj})_iDBFIYHRn!H^|Wfuc^Uk>G^aH?gry?P@2+l`8z_B+1y`K(M(lr zRlY;fuN~;<=H}s`_6}>M-sK9;SEf%?*gwlWGg7*~8?2Go$$Zk^)uM~yvwO6oKHNs^ z7+Dk5HoY^V*Na03qLB`DBBp3SdLLoE-O`~=FORSAUF2OazxRvyAUhuWy=y#v+@FqX zGJF1#i#2d-Ryyvv<8U&8+YRUYfuGxnh|gmsX?Q)hJ@O!Z?r{mj@F6`OkDcU_dV(#@^Ma=|r}>m4YkvVH4x*rJ}_rT#<(=(*Uaa0{ z9>bg8!6@R%x#kNJhZ#lGHRueX| zqIhjeo(;&+ox9{~BR$;zZWetS)rMt3!(scY1?(n3I1|2KeX3Mo^N-6=A@{5f9GMTS z#U>1YT%3scWqsLZBYs-Hg8=PD`1f7IKMh{KjqkZ4kuxBwp0_ko`~&Yrq5M!9b-d+m zhXz9NVQGnmz^1ciGDpQOZ2j8&$Ow-iYh48A#%^MOe_rKk{D)@u&*rvFSmeD43})Hyxo>Omh>9q#~Jz*zn!{k@CASG zL*`D1=c6+%Fx!K)`8 z!*|c2t$ml;P7bZvc!IaZA8zx%lLyh|Y;|>)k+InLx<9}dn9M$mOVtHz41Y~-)?rD@S5q%xrAHrWg0d5B9}-HXD?Djw-VbI@I&RilGi)kJ5=sYz$tg-GlsRn6agJLFOJ;K(#%7zD zZEU}L@6Y$~`2BnDcE9$r`}Mk?&+Bn032lA{-e ztB%5=TJie};Oo4xx>Yv@ zJh52C)#-4ayuc0vAO1zHVr+5l)6FJ(ebb2o)DW`jK(pT9geGIrzHK&2Hz$+_>;Q@F zs~(FvyM2pJ=SIO>7n#uu74TmU+Xep_n>++@4gaT-;;?~GR-%qRlS89wb|qR|U3Rz; z-CDVq?5~LBsd<9R%HDWlZLc_eiTjn`xD`|3`rg=rXegbbS-OX_^u`~PSQBwe^O|2i zR)k?X1~@WEA2p-)6@t3+E%SZ4ov;JbnAB_SRsntMsx$Y{Cs zcL$48DsM@bmGlL}^oKs{?h2_2JHpi+(*7Ct0dp_*3>927HvoVAXitf|gI~M;ZqrOf z#`v@$U?$0bUec?KI@2jH=Zz8;tto%(FWdv6sM@XBK9-@KKiPqwpqlE9HQL} z?M6Y(Bxy3Fn82cC9mTR~dtnPU0C|`{jQ$2XV~mEkuZ|Fa3P_Fj_KqCX$FwDl;=J-iR;leqI&%%eWkUQ-2QcwacQE#5P}spO~uXn$nVY)5U`3J9M-jJQjO zKle1c8AJ8Dxi`#Dv>+5(5+{pZF$Sno*C090RWU4gyYtkX$$i^F1L;Hx^QP2|KVT1MHo?=mcUimQX6AP^4#ULvjV6Co=;pbIs`efe@t51Q&Pv#N)d5m(#_ z2fI8YRr~9}Aj}lS{05#)zJD{IAFGspEOY$u;CI&xvBTPVY@~q;8PrroN>E6;?|s}= zCpOG4=$b=B2Quvd$dKQHa4>tC-atAwjEj~bI{Jb`-0aH+wlyp{UP+f;J5c#&JV5)u zI9|w$4p_?;hci-3M0fXc5#tizw0tbCdG6yB-#iq0eQwuLiaU5sy;B~G)0UqNY}Xua z_LgdnP7gttGLQ#!p`zA)5ZeB0o)#D_8jt7;#Hzl{8nfBcM-5lth4-MJW$D`_+I0ZR z5zS2lD)K$zxz5t&S?6=?VGU;2Es-$+Vk_OTyioK4`*y6?S=uulx)^ghRkA5byxx=j z6*o!tG)Y@0(_rfjWJ33yE^Ch*o;~%(dVd4!vZ1Zf0~^;miNdkm48@i8M9M4J~(PFHy&53sR8=o%6 zr_^UdxALN=cej%@#B?+K=*n0LMqv$0kiYm7E!ra;+ehq9p6=X=OB8|^2;h!AQG6i_ z=FTTFuH_@wDk0&DfxrQ<1Sy;&Zdb&w!}6`h8oMVj;DQ$7`STsRjtv*TxR7s`c4)b` zeCQi^*<6J_Kt(ZK`2HijUk+2?%)uFed)W*h)>tR?lWnNPznk1~r2}=?UR^axkj<;t zEYzh&I<7k=s6MB+!dHFc>dC{lXIu84`MeQ@@s(fEmF57DiqeoEdm!tv4RUH^Tz-qa z?McdY+5oDV=HmI!P4|VfO3gx(jwuvRyx>^so956TC01g)2UC(nW>JzdejMmgWIRq* zE$nnK^{?lR>qhIn5S7fdDw-=)Z-c~~AE0UlFsom`?fz}WJIoRQh)Ff>nYH?omagMi z_M~ZcL9_}x?X%t+iKNJo%ZXDBGBq4&=81dp8&N3boJJ^{dAoNrPmn%ZL(zTGeQNke zGE6PfiEHN^x~8<;@aK~KC<3p}KBB~M&&Z?t;r*Pc2E}GRe$7G<#8PDzg-$o31|XB2 zzgR(?xZkHhK+QqXOBYmrjH>q#^*YlVZ?nJNRn{v)n{yd9oNCg~#r=|2UGcJEYYFA) zwg8a8d)3%*Hj^GoJ~jGQYVXK7!&SJE-mhkM>jMYss+iA_)|jvzvCpm%{oq;x>i$&m zE;L^8Jg=hG4p;Z8su0}9J20_+*$HIRoNo2NWjV8s(T}HGy@*fgGFtN@Wa}J%8-^Xp z+~lT&WL)M-+@zE$KMBeJ(R)O5BvE&`;+@#~%@tQ5;%@Y}%W6AmG2Zd1iLr7QMmWnI z1V8uOxc+MIcUaTg$jgQ`IV0FS91sfkOTmZVf&`kMvOlJ4^X!b9$|C4%44H297d^df z31Vg)^a##^f+ zS70EQz!v4IJ-8ny!&X0YuW2{##Yy)k!0&rY*|%lm`rf48uuQv^(rv=8yb9wFcnB-x zH{eGyR74U^v;<9FZhN7&kTphRzK1Iryo#UG3D&F@>4v+bDHbBq z_bnIt%wg&@_pFh`ADx>x=EwZ%!BUatItztYUZQgX@z6IeGn4i9CVB0ZO)mCbV0Z=P zPFY-Zd+}O$sLA>ffLAzC>t8*Jj@%^KV@$vGdcX8dfVU5{zmX7Q5I zX637Gh`C9QkTqNStiZc>#_WwbZe3<{q7`_Uwt&HtWG{a6p#3i45}txIJ{_!r00)e7 z_iotHK9T_d&`K`r=FMTVl7Xzrqp+veB2zAw_#SsjSS;_OZsCAM34VRz`MT!)zu(Q; zeWi;_2{WLv&{~xWJj*oYE5w=hPmWE2m_Q8gvp^}mxDN0c{CvXe`P9VeBc(d@Fc&*s z+kAtOd;G1GNJnp>T;uDirwmfs5oJ&}2?g_1gGW>C>y)s-~CpM#^t5Nw_+l{EU`V$)0_2 z>qu!o`s*Q9Y31JY%f51KSG~(LDScY-WICrQgaXHuwTWM!NpKB>o4irNr!c?f);>4< z_irE;=E^wZ?qgo%oatX(rreFVIJbZiN}J9zXGV9Q^eKpPeN6n}w$lB`?;KOqS?bu` zZ0=}|IrCEFMp^DodzE_|;jpln&@ps8Ze-wgxi_z(&mdFqB-ChhrG2x}phJ6Mx%Vij zNV+8e=dj1l*YPMLsnns+Hb~Mnfg!9d5Dq4i1l6Yv*2wTLhaGe;8TH2U@U#8C1C4%j zoAy404Ea47z!(!Pg{MZ^KSOV1EKf15U1PMfO7`ChbW2<89+N7rVBIBY*jTJ0p@t0BrE}`b zo369o&&DP(Zz*iYrKsR)u;(%JUam!bdE!FXs>#t;zfuAD&2d-6?54^b$JKLgld4aI zO*E>&0x71AM(F_;(B^+qMob#2R~3lGWk>)v4MYHM`)yl;M&{OfCcHo4lJk|5gP<@Ez0)>a|r_1s3~RXX5_7%KB46wHW8|=B$RhvD!sC!ujUB z-Of`z7LaY@1JVQ|PCkp`^#b$0{$|sv1vvPX)^0TMKIrPqXH)bCRvug2X|=iw>Be*V z$OkASP^f+Gx=QsXpf>w;&_`RFiiIJn%ZD7G&84A@)!DUHH#ArCEk2?RQ}1G~ z)<_h)I3nXmUYiy;2~YNhSUPv4C5X-NwE?oX7M{~>PERjKmPm)wgT{f$#a>%=n)NX$A)ZIY9x#Wk+vq z5s(nnAur06eB?%0UJK)m=NG>*=oM)X3&1uhdW*jdSuI8W2=g=&9h?gjF0n*V=+Tv= zxfDGQ?|9dAtm9=!P0l(>UQwT+(vFT>5w0L$uFoFn+>wlFFq20tWOjKG(Y}XKQIiiv z-Z3&Hb2c>gH$#N+9jsf%t!$`;SU2pj&~k`Kmql(B)9L|IXG|1te&!`(hwkLr6qLhS z57eq-TyQwzYOY@1YkMoZa2LJOAhixWGx$5BJD5R5ix8pnS2$^ntg=5t-F=mRD-+Hh zXuKO^qG#TN^qhK=N3l2$oP8yP^98~yNx~X^>*drHL$G7wUE2lLTrAi;A>ar~p|(%2 z{a9aXOD-Ez{z7*n-^z&4LFQs znt0EI=87&TE4q{`G(u-iW=Q@h0|5 zyQ5qW?e5*v@?%-olqN7OQe#*BD9a7aQB0HK*zq=}W5v4e6BthZJH>=IJl1ODwKiyMzN0bL{a$=qbZd1IV=svxn#+Pkkp#8bC&k;v5kI%2 zP9H!DVCMW)c!OHJq153z@d(fHx8i3)G8*%AKFG?Dodi1O@y}YLrw3k$cAvQrlzVcU z^c$I4*^0@^iA5Lq_wTK`@fxZr;(VCh&>t{i%X~?kP60X&RvLP9;aR3D-l)Ha76N5lEpC6qqA#rj& zevexP6y^lV=Q3J(oOnO9ve*njnUK#RCjyqvTJ_>d@_rgH zI`^cKi?ayxeJ{0Jti!fCt<=5CMv=(_)AV?`W-GdeF=@W^XWZX=F@Ru`1gb`z^JSj4 zj2{;ECk(e4@Oo!&Kkl}>)mglm$=Nv*0cWj|M#$(Jj09$CzqeS|sD};Ay)z@x!ww-F zl#juFfF;a_x?@I9M`$JC_?VNIzxY}LCs6tZ00Tt0cI_N&+T7iJf(=aoF<%#HlDq^l zFyHA}-VOXQ%kMW;wj4cS9(ylXCU-2D`dLXDamVjj(qVD>AB*4bGONqPN>OL2sNWa#5+hb9F~Rry36_eO zf%XU<#S6e4OCFhqT6#=vdNpCPd~TkanFD4nD1DTcIG%l1hZi!P8tJR9N$Ei~tFooK z;+)eqE2r0{YA>U+VFvsNcfY>9f;$7sjZLdcX3BIF4y%dUX^(mru6+FQC(lv&P;Syn zh}N;a_GRf(tgx*l}%|L zMt1npg3vYg=(S+wO)QXa%I{CA;)!;J0{j1~4uM2ngIayI*{J1;x2XM`jdN{ll5leKA;k=)T)n$P@(0^s?Q{x&| z>_J2WBW1I3$yvaqtO$Fj>G}}dK z=KYJFF^k7qO8}BO-5tV8MPodMx8^>3LV7&DE&nE(y2dv$G&RrlAizOsno$Xq<9)CNsW*N{GO-}IjinhlXT<`v2_x(niTNhJmggsdw{84;l zbRbTbW;{a8z$D5b{neL41Zc>P+WY@~;$pO;B+HH)^PI9u>Rzw#c3JWjK34hM6|HO$ z!);ZP`&t~?-JajKTRdKT~T-&8x?uJzKs`zHn!o0;p|GPzEFfulre zTIJhYkh^bfjM`DT1?LP@;eSCUl%gJ7p5_5b<=cF+v~RMY%{_ev3Q#bU!l7!nZ@kd8 zqjfm}Ls*i<8D^CXsRM?+ISZ8A$BcJ`o_x|lg=P_M1LUezILKK%(>bV1ihMTXp^SHl)tH7cx=#19qB4iIyIO#vDlUp%Rn*;%V5 zThI`jaS;C_VKOYBTMcNHn$9NhkJrWUE9OQ6X^m9NiR`bpYK5{PG->eHQTZj(#|Keuh0RwY~CX z*4QxN%4<)-c{z59z!U%fL0M+T2V5g)0vaAzIJVX8uYrKk>TE_8W5od~mn-5ccW5hey^DO;T%OF*J;#T9jbzJ*Mdo zY5P?cmUA{!Z7hT>@KW;tPp|iPJHbak_fXWbq1W89JD|-O<5PJ>yV+9n8onmT8uq6 zfenXluL%QNe>f_1^T3fL?!*vkPFJX2BRB*;X}gJ{8km3 zFf1Q?y5#(!b%Aw4%y9*^_E)d-{Cl88r;pp*e_&otd0?09@)mhV$!h=M=)HDDvI-6E z8K!b`+gy5flms=R=OT!`V!K7#9~8!PGFy&4Uj_&e6Y<=YtObVFZA))e#yPdgPjycKY9Mv6?1AeU=)-~HoIS9r zv0Isy-s--d1K^ebJ8iG|qAixf9;=Sx@d`4(Lc&$A@op<|P-=g}?d|>qhB~96L%@z2 zJDHf@F!EtY@HWw+_yRsah!-kh1(=3^Wv=#!cjcf9#s1{+U&0@|yal>yfZMp-GAc}a z*y}n_6o5K$K-eKW9k~Eew+_N}xN2C0Im2nuFOX{ew^v=xZ?HUh)v(4d=tXlZ=sF{} zZ_>0{DnqoyHK1yn&~G5jj!oIrD}_$~SQU9M7JYmVB(&cJWn)?Sv3g-ZL>2*B?YU|90?+VMpOumr6`;K&iv7@DE6F(#AW|9pJ zk9axu)xQ)_cLwTn9uU9ji2oQ}F?4YFCCQ-x6Z*ag)WDg4ciAF%PHd<)(xsDffWFEM z0E!3@fkfZ`rycb;0J(ZXwXA|131iKy&cf=-94g~X#e0Tw$_befAu}~V!>2%l*0Icg zU67G(Cg1=A(@TbwIA>?uXhL=SKr01E^`3|r<M`ES%) zV0GPI1$~x69f4)y*y-H$|Ap>sq_B*Qj9?~+pYGFcwokc**!Gn2vELRJ&5#iMS<^>n zCzp15emqj@-kHu4l+JhyN;j7S4~Y#jKV|XHiab4YR+v3sLKu*^-Sg?kvp^YF{&nA7 zE70l{NMb5tP}-uqwVFV!(Ku0gtdzoL6iD?49-Uu?f9k%*klqI}Fe)dbgXSqP>)g&Q z(c#M?B^s|Ip-bZY%Ei~oqyZ684{&1QFC}qdT0{D;6*KhAH(-7js%DGe;>tfq?Xmjb z7*BYfqx4Kk|C8nrLjPsxBhiMZM)jS*4?sQqzv=qFPxpBXZX@%aaAANJ1JfQA5w#F& zU;w-NV%X$A^=^nzA-y1PBLnbNfu1EXM?ZyCKb@86p%^|+yZ%A2N;+BxZ z_rqRixtsOiN_<(t6>&+cMx`gUAC^BI;jeRuqLU^FMzo&@DJt1E=ybw|(EY8Mg|mV| zXHTFs0|Fe@VNS`tC=*$V!7!z_%&QLYsnvse_NbnZI>X(*@(=f@5)cw2L%|ZO9Q>AK z?Kavd-xW8VA4o0w3#!FaC>BsX(wxO7NtmOC!BbEIvBwvLAVC#zIk4W)jppk*jh1}G z_sP+1V*}UiyPQko3{w*EX4MtBn4_}qb4s13=Z$E6*ZR^z8Ht;N;jhx7FEc6NaR5Yf zorHTNTc-05-kCi#8*!5%v)cK5n|(Av5boEYeq3+@^J2NSw*9t+y^L zbXr=j6K^#p#X3Hpo7P$Gy$E(ng&xHINW_(;aPhwcf(O@SuIE#qGdim)JHAGzVa^0B zvShE9+9FFpD4bBjpQ+g6u2FXeH(?c(M{9S*8N3Lex^;&AR33Dcdy{ODF=g`!!0g~4eAs=}{NED}X>~^X zxf-jPGN+yD1tMN-sl&gKAkMVoR9_U~c_3^9$zbnk^NsIeOP6UElKuJG{kF&L_;EFN z)boeR{M)KbKQk(Z-NFZ%9bqaAX&Z62Q1y1M-k|c0;?@Wd_sUuO9I-RaPM~_I8vCQS zjd+h_kkE$T^KPavi8%mp8&La64r=SW-wpwcHeI4;MHe|+rTPnock6$aX!FBPsf$GFRquUoAa}_s&Sh#;qh9xy<6pYjj|N&Q z^jg0Hy!Y;X)VKcfpuNdKq8|~l<`Ngp*f71Y#Y2imH9Z2^?O`_vqMvYJ%G$(lQb>eqE&vDV((m(R#kpivQW!t&!Cmg;Hgr+GT@x%fPXKc?z^kp7W9}#-x zWX7!FqmiA3ii~5axBKMc^gr_MSbb~V2;AOSlUs8o%rxD)PEIA+-lFYPfFEThpvQ^j z{v~iucIx(A>wwNwoylGB(zN9QiHo$hV3gQ2C@_9!NbC{bMJodbU< zRlT!S6ILLBwPSUrTXl*@GqAUKo9*K=re4u{0IK|y(mWUGtspQ6C zLkz9|SV!z=xonjbmi5u=(EfG`_?J|v3o&|;bTOx?|7xq7%r&D1M5Ydc8-d2|j`+@> z*yEQXTZ)ZB|2Nfu_n`iAn?{s(z|&$?`UyhFH)g7CF?DMSDTC`Iwv58~J*5T-6JA4@ zWG*-*ha5^V^90tdiyv5sC2=1GhdF`P-dt*ISbX5XETXo)Rk=}dr*nPLu+G?9-|QlcX4#Y0Ow8E_9!v_8pJ#0uYqc7-?n!zSqAq3hqR_|xTcoeHAGN@kIal@~{gbkzVjp_0?Fj=_?8sNSvBw`qwBH`vn06s^mL! z{UR#{W~1cjjOVN1=D|DL3e1ZV2#sNw86=0dbYZE`VB_d@V}jn3^=ZGJEB^%Qsvse$ zRlPchqgivE*2uHN6))~a`_VAdu>pmaw@DETjgJbBPuG2-dQ=+zSGgL;Ji$Yr%oJ8y zF=xGEXJhw++U^>B%DI5uq*ToMK#nE9I4EM3)JEO#vA4}P;Lq%)0q6&`_54z|p2)4` z)Ahc334fF;FQ44R+6OfO;rm!8p%R zZ$av<_yjNI&%=@JfO~vl25cHaaQUtD)TIwGd8rk`~xC*&_H@s zm~l8Z6Py?7Q4{lT?sID&UkGwMb)Rq5?yM%}2tt$W%#HsXb2%Wyb#hYzy-m3@IcdO}%P>9p^4pz&n8zoc}HbW@?9nsJ|M@w*>dsq+$3 zcDyYlSBF0USlJ9YnBDC~oKO5`rb|(<-#+CAT#J^F1gyq{S2wV#@OKNzsr~WQv$EUB zUfbBZ9yA7F|)S}CVN}U&RDW|-Hzx=Y#o9g;(>PUAM=R;dmk0R%BXDp zgPcIaAK&LkM?_cE{qWbaW?VDe7VV2xuz+-7(L{8F>zVV37n<9UtM^+(24fX$y#lry zsb|Ks+HM}#!fIo_;0VuEO`1_`E)OoP%Wkgx*JumTY$Pug7cy073hw1sN5wA0g1#o? z3fuI@6~n(WCx7aL=QI!N#d>_?z$L9;VfwFfo(ErPQ{T)z2_Fy1oiDH&b{L?Xh&i(- z;mSBhy|gseHO8BIb>z^YLIfQ?I8Y(Oukay<(6Va{WWp^t#`-i5O4bAk0Y7{}z^3Zk z?5+!V1Dy5Jw&0xt1aUPO2_KTM!I7}VA#I~=5~?Q|U&`#L_!v)>Xs+O2RGxw(Gq68u z@CSH4N53tTBfyI%&mT^b&5QQh7&@Ok^D!?4i@%{Jhm^@4K&(V%Y>zaHcco#R9zX#W zL=O&Ym?7#m_C|XhHaRN!QbGIQ#2(+xh8dxl-bxR+0MU15H(o@|WEY-a@b4E0Uz4TgQ9#5udqB+R~%Mh;GC-1lBT_ay8`|F(Ts zju@h84kc4w@^(!)NJrKsl%Gi??QM7{bG9{cGccazfn@fI1Z8io={Gpfp7|p4*Z$xv z!V2iv$wnYHK7G1c+4ohaGAf$Rh(6g3GF(ppohN6f7yj$JOP_MVmQnqLM@{aa2}$!G zr|UMEg%()&ero)^9Q^%_v4O{?=Gl4M%gt{K#%_gg`xRTk#hx|?-{7Lq*1Tz{?+bfa zW_!h}nx27NZ-)Klr?>EMffihcx3l!KWS{}vYJ{tO-JRr;LehLJt7UEsUE?oYlF*np z{nF(`SsJc3%In~DcVTb>kc*KYT{`so%ED(}x@74K z8@7zuzNVwnJ|p*6mR2hyU=iaK+~GMy5N+G9xMfW$SM+B;&~oY-6=3MWOjsxi^Y=YG zd8Zx4LO_^jmoD~fju4L(4OVjfI0CZCaM&01j zQ#%quuJ^V5ux^CZ!mBOY3}Bb#<&nq9ET>0yj@#Ep2%_l4A8>(6#3;{j=fqt=h_u^~ zaQ%&qa^hWFeA#SaNbXee$+eqYd*=G_*wS(m7BLMlV%Yg z9j|a>q}muI!@zfV3%&!TTd{PD?1*P1W$dfd@FuZKs@b^^>Rg(tm2|a0V@1)Cw^2EQ z1E=rK;svU3aLypVNxL7qjy5+8;YKh^C(;i097E}O4Ypmz!rvAb)F)vp8>v&;;Hdp;a}m916%}OmNXyw*hE~xJjO!0o1+bSf zo_c9R_|+R*ot6eo?47dAHowLV6V?}o!UXOX>_pcdBimgQz4KE8;tfh<$={X}Dg{@|sj zlwuO#1ATx1^8u<=$d(1QE1N4HmCAmhd-63l-6plck_t%eY+{+u`dOYS-?T048fZTa zrOx3?6O?`Hue$x|HW3^&XtT;Cg`{n9{{F#mlJnf_g7>2k%5oq5G`mm5tx7KtLCeIS zk&*|HgeQnaizYg(L4fu3E_}FJ!u8~g&DS^giGBQV`y<(#3xvIkb&L9gLrQ~x#JVQk z1P6Q&#LD5vP9=!Xah>9%3m^6^>~{6j{?-$%Do{ekBIe~OeOweLU# z_lT#Tg?vUjh@0x!(kXLm{1=@j<^fK`glQqGJL$rC)-++yU5ze1Tdl;a#LxJlHz6=_ z(=`bDcSMs_)EriL!DX}O8}) z96ai{{+|0G+`+uIs2~g5)sI`wF%%R1g6RfiTw3GE*&Ww|GFm%$U3nub-UA;H7 zTNRC>iHfE6nI*x)5_}83YPLxLV)c}?m!ibJ?rBo{6JOk{cDaX}*u&t0g*P`q_El`H zBX#((Az!1Z=<}^CbhUwMCwP_92MkE^nS&~iMg7-zqk~QgeF4FjorIpP{F`nMgJP9MWoj*&UY2C_2o!+d<}}e0KG}~ z0}hWuTjPzt;1G*xiq?Q)Y36U28DyFb=TTQf4?}rR+08)jg_;(=3^cOjupQrjANKlL zI2#I-mezA^Y*3~Kd5+UDvMaBqT_U~!@O>Erce4JR-lj*Yrh9dXZeEy_ALSl^A)sH4 zJ9#8umz>k7AnHEqz5@Z)_5$iAA~)-6DRwaCaa^ue>MKV)Tiwh8xV>jXc)%1Qn>dLp z9SX>>xC0Wmy^*2BS2vN>A&dNrKD(uK$}=n)`uT+KqXV;`Yhcfbu=iTCiZq{2=^lJg zqEQBLg~Gu=mxT`N@ysUOzB~GHW0_*PIje^8x4`wwKzvQxh+Fb3rnvCp)GtuG0kZlF z)|PHGU;qA$zfaWqoNYE?>SEa@AC*!de+v+ zR^bU4anh)(Ni>iDwTrYF|6wLiJmp^{ z_z1W^0A8W(V&!g@m`x^<%AEh#NS@rka+Sf~6LMfgdYfAeeg?n{HoUL^bu=f#oFK*V z-y7ZnbmMLYmXV)l`N`@OxF^fqG%FzVe@5J-u z7aMLFZhLJ^w5j2RW9Q9@3}IQ#m7}$-|Be|Gel*Nlc1`~4$UFlSOw{wElK+H({=J}C z!w&7bkl($*Ar|5ftE?Vv*D7iSu=-A_iNZ<#%&6@u`z-U}f(otQ>_@P$b;KJ1;5i)K zi~PiMyi=*+v75IuU}(b8@KYzCz0Ewi32rtS(u z>+n(hkMIMpUDirA0bS*|M9?)vTb5h0^zEL20*#Jy_dy(gJFGD(I{fAATU_{|u=|kH z;9ndQV2J8(dwIo9QC>T`eO5SvR$8t`5dQMqGo!oIT3v0uWv|xTT8{KRyOeMQ{sJhO*_jKS zQhD>L_+~r>;zfq-o!kJ>Glj&dhsD;l{!WagHYPPGig&hI&v?wz$F8%dm@-GHzVLi8 zxo5I3-2yys^u{juU7E4x=5l>on(kFHXL#;BwOp#OFG?DX`L)>HY{emUMl-W9Ngl%k3x`%Fjtx^*Nh z4b=Byiy21(O=+q?t60|(qpyLm=jxeh#efK|@i;LT|0Vil=oufI$*y%ET+ZzqFOKpF z{N-+Nh46~sn%&JT6FdX0d&Q0WiTDGLT+6X5NF#+GQjllD965RYa>4oE>Pw#MeE1gw zdI_6o0Ga{{6teN+6|CyYl6&{hQ6kSK+>$$~Mv5E1rQi?Tg8Ya+M6;WkuzC4?){h3t zF%F8`owggRjF}6Ax*ttP`NekhmWw}sSAT0y&f3ZgFL7C--%^}OIFBvgBjga&yAHQm)nuJ>X#zl{_4Vn8N(p_t6JkvtKcNVJYW;?JvHaHmsaq#x%lsgQ+SP&mvaDw z4K1OFU$6J>f7J5DstNx!h&oaMxHGA`cgDdIR`zE0f34@IkWM%-v{GIzWYz&yA`zOF zz54X3?UiRCFD_w20B(!o?kFY+oRZB; zs_YLx)<2uD(KZB2EMonppZQ*>@$JHC`6Aoy#j_iE4yz6Lgp-Il<5#*{8z>LHnCx3* zDAj2wqV(~I9J%X#RxQe+>2L~6`yeK9GWMJ|HLg_Md0qd@G|kR^RcZ=_s;$0rpP+#1 z!MP0SfeEXTSZu1*vUsfv|IJ-V)p?zNIbT+di^=6I;}(8pP7LG&aj=9X^GWEUO6>|! zimi8PTmWbd@5|VI7Nvn_M|(t-*#rpHZ9B3<8?5d;ymE~FG)EmR=*L?dB8 z6$Ow_o5s+o_UIivN0&WwPY5_E=cTz)KPT;%-J(06&P`SMqZwwvAGypMG8vxlTlx0&<$C}q zf=sBd*69qz?i5qZ4Xtn9h*GN(5rmvFo%YlxrS4atgX=_Wt;>Kt8XK)TQpUBMP2a7n z`)xmXyf3>(R>+WF=Zr1W-o<~`5Uv`akIouyxaPY+>@;dh^}P+?|JD|Uqvg?;ypzGi zHGJ-IxJ+^xcx{J-k0b`n=yyb(4bT)kn0f=ZP^)0o*X4K(dNYO{;;^prrb0cyj|+7E z5VP@ntqJ_v zW#3M7%-(0JPRez=f?_LsJysd# ze~d&4X+Zaq4-nF*R7jcc;Lu9CEIWCu69flG^b|2OmX@R{^c*~RD)gK!);faLqIRvEZ+G0D=M-d`Z;ViaA1wR_5`IINm7PB zof{PRd)uznO4ChI?OM0oC-|)nv)k^Zl5#_k$n|tKe2LNhKn`Uvb(NHO;wx$#%BbPO zUU+4t*IR;BYb#*PVxd`qBB@)*$Ls&F4oHT|$7KJ~+rUfv;0);Elxy%lP`*3dRc^qq zfHHYnVMcq-7@^-T#;nNjXs)Da%AYzb_J&Vs0zoeHTjL=#JsxFQWM^$ONsNFkh{@wU z;mw)7LDPZCv^Z~y-ZYE2@ucw4Tq(ZA^X*xNP4f+l!LIi`u^|m~yhC+PH+0y{^(HsP zcp%;@rc8(BKDo{Tt3*ur(~GhQbkCFC$3Fx@&rKPL#*5QCC*k1vEJo2i%|oJw*Wmss zi_ZX)Kv()J9Gmz72zt>| zki>TQ`bJXZLw_^HG*B$+aZ+Ry zKGCY_QWO@Kf;Df!134D0GPJ?Bdy`KO?X?5Jh6C5k1ObXxJ$m6F3?B=Dmg8qji>1|t zDYhJ^k~>{SpV~PY1gn}ox}=Tifekj2>!y(Eo1|MV-9%xQ{%}JPYgo`6Uz2DsAeW)NGKBMK$ zmxemhiutWQ>>9?q{A51K<{5d@7yb#K(Ad33d8EiROgF8hP=h%C%Q9KY40;ab6S@sZ z!O;c-f4w;7Ftqyp1JjQ?1ucj|p8w8_xGne-`UQiS&A%lXITqWg9z7En`O>U=*!Bu> zjc`5d!L19o1@B-ViWh|r!zKLF77|3g@ukU~+$-@w>0=Y{^(zde#<1YK`F*23swAY#`xZMZQ6EkBuYCJ{FKcl_bM=tmnDwRA!ORJ@!VJo}{7BfeD;+rkL~j}o9%$IlmGZAHEy)s*U>mm_f0Ul4!&5C9{R=EX~I?pWlR~x z)e&7FSCqJtlTnS%rrp}gnQuaOfZn!!Cj8(4yO^!9$BT4&wQ_>x;&J?%{|ZEL z$sM|Zr1ry4FdOgV2~5*8^I_m!Ef}~a(Kx`8T7FG)rkh4mg!ztEO(5;aC;WJ#_;;rf z{=&}{H6e~-yOAyG$UwaYZ=P&Zb%Z(K#`zDONhKqUtn!S$^nKv0nxX6tt5RgF#bc#& z0C;A(5kxz2+VBU)UM=r|DY( zExysAqPWaj5B~<-k%z|Dub+Tx(o<)?#f6Z^2du>#T=$nFy<6}KB3gON65JQ{|z_Lkk%}`%b3^QGquczNQ z)m;jx+;KE?7j0FkA0(sF!m#5^rd@k}VK)s_Em?sF7aYQOKji&JC0g$XK)X>~P!}yP zZ65yTiB&p?oDXx}Bj^&49I9=QD#%HS_Zp&)9^ANNMt4;Rg4$;WplY_;Z&Yfa#xf=R zi=&xpWMT>`4Hv8o|?%!H2c>*OM7 zvRK@xR+1S|kKSNAos$nwh1>A+W4sqWERPlRX%Ip%(UM5ugZuV@2JKXSezA4n1& z0P_VfeY6rdi$5~2P8G~+dq*%puu#p7$!P&;hg`_JEvxp{1~n5Fh7*g&&p2{yhk8f) z)?akLFFZF+qEXhFAeEOQSI!t_l+E*v{KEDOg%9eoXLrsShxr6{5Bgsj}AYDjjpU9&&J6*p@unlBsUrJ5&xv zr+tp8kfDz%U)9hrM@^m+) zADmNTG-k|BBK>qeTzDm(Ol z*JhgW#>Yq4e@8HfBY|sY?giNZ|>Z+B0s!En_bB&-Q%dkCq(tex zs(w7sj(m*X{BZd0=#?jc?LUynD9egyMjzXk2oGz;^<@{9svjaVu6G+Cvwu15dp9sF zG`ZaFm^?-VRsoW&uZ*^VL*JTIxN9vXZY|O!o^l!du#vfcmGK(Vm!aN`1_@c$gN{@` z0q`me_jL6I5z1coq7|O}r90%az#8{dl;V#sAFNuX@Vfbl8l}`yYZ-$mn)QHEwWxeA zF?u|jy0r{Qkz`F+l>KRz1-C#pLiM9Li^RZuKK0cOqWxhUohDN3M8o&=ot(p6x8U=7 z>BoN2x`LiANVplZ3|Ix9-_5ZbXa{t-)K{Z><6bdSt_~>MZ58}t(ZNhz+pyN2&U;BT zPtv!eg!6RHiYfg3)Rx)(Sg+q#4Fme>Bj?inAPblDnyQlTgXik1p-bTCY(MtetMa4C z@-_?pA7db=9>Mq)kg6NSJtbnY?zko3QoiZvu5fQFKMpB43Cm|l&Vc*Rv70rS6pqtYJh^gm&0C|CD%)&e+IPOD3J67Y;%#-v9OE7!9V)l zTiXH<>Xb=@@SMIz)HRRb_4svikDa-#1|`dYA+L5R+NghBDD-)RU7|~;8k8&rD?f$R z?!)=5D{T$7y74X&U_jKlajzX{{`Y42A@{^#-L>Yep=V-eWFuZ5aXT#MD+Gn5 zu+M;CO7gPR426T_oyrQ zr&142{<9O%$p$jCq0IEdeBJ2kEtB@Pkv-EA(1?{5Z9XGM>@AIw+Dm-$?eklV{vSYzKv7NTXDa zLY+<@CP(>JLcqV}(OXkxP4FfRRb|4u%X%}Hyx8wyYZq@G1VOU{sCpf_cJHr2lun~r zMm|n)?xcDE$l!CacRVg&Lj0G?w2SijR->lnRXkibjbB%5^Zw_@fa^<+_NEEdpZ@{O z-AF(eL4pim9(Sm|*-d~kEOA)p!0wdz=yPzu1&CGolR90FcvZcZaEqY-m4Hc z`rTl>UC!G)%e)&v@uvM7uB#nCw0ZG5H*gh&Rg>h{s>C0D3mG(Qexe)5;JNiI30q4zJ!Guz~fMq6bY}7}XrP;SOl745wR8IvzrB6HB_# zIP~z}$KKK{uR-(mD3ZB=FM(~S?ry5Urb_c#L%Ith3Ufg)96rwahne{k;*_Rg%6tIH?Usf(|7_jU?uyFA3+NM`^RH8G&=G9 zvDeF1L`ot217Q^N6ZH0Vw~3$jSqEu+WNpV4)a~11Lb*4?!#!Y^qOn^EzXG8&9iDxU zwSoLYk3sR0{t%vCI+%*VKO34jh5yU{VMdekCq+J7KPv9OV5C!D`8{&2`R7-vX0t5T z;)CH5cQy%dt8QMG}msYMtEvAV8@y*rk<6-;%%Breti-|Sxmv;ls%1qz? z#%uL#4{i$QOXB8aWgG+52DmUFKx%!)_B+{2>Fr0J4Nes|(Q^*QyK*s+;kL!IB>?s2 zF!xWE?P|`urL>T1=S+B4R0zwFq40|fPKV4Z^z#9z>u77CQa5|U_%r=76_Z~nZvCtV zcDEVORE;z`@uiOM^rU<Ag0T3!UR-Ya6%_FFl3wxo> zw1_stHw@C`@BV@@X`#l#VOBZ z=?`7R!W!%>)O4qEgW1=f&i2tL*6dM&d6h%R8C8duQO892k7Pp!K|dA`v<9(G1@?d6 zoUl@Gwv+5etyzpVKONAg18N7e<5MRm_wjr4B%MiRbT@*F(kF#YXj*Hh^^$iAH zIQHv5yECdII|}1E^7iFM?eo14P(El%Io5T-^~LAN$)!)x-(h{K(izr}_!4MBB93&| zVmI0>X9aWyP6KK$)c(nZUePz65iA%{sDvifNppS3c|CBb=~qkN6C{Cfh1H2lkt$ z#%*yOPIC&hyXx!DB52)IP_@V@_dU9gZ#D zEv!W`=#6C4g^A7+_*djhbrzz$WM*MiX2?N^{lVzK)Vq1$p+N84g7-;RDSY%)yp6x z&XmsiNI3OJO11taJC0h%sq}rTYf+I)^o+b0p`U%;v^mX7N)CNFgJf) zDA}qN--JKQT@6Z&u%%B%E`+S4D0sujtp1nUnYK8SX6I;tz9SPj(8>x;eNVJ^o}6$0 z$F&&@MN_wW?STqMFy536^U(hAcq$!kYp$4!*Y!;90pQ4B*&}ITO(w>3e}L!UKK(;E zA(5g489(&XWIo*E^zJSq>E+6)8$G`T35opA8;4@gROoLsj z2PnaU!;QVZn#*}5M^od6EpAX2zc`dl%6Dd}Tm7|>gI*9j1|)YYrcJnE5pQfs-kJXjO&+b93FA;nD4^<5kXnNOJLVMzO4e@|HK ze=i9s9|nh}J`m6 zaaYerm#DNi1>PFGF%c30Mq22Jx23+#RPKDFc`b=}d?paEP$eT>okofcM!zt{Oci(e zsp^9T9=B0ORaEba=t&{L*eu_td#9Zpi#Pp3Q*f$QfEeZP#GO1tG-47Ak} zqOtRhBQSS_U&aoIUxo>0)nDx8M(AcPH_9<5sN`0CrU^H2~f-=9qh1N@z?H^Ek z8je;Y&V9JtJ130-6&I0!zl5gVCQ!&p7a#r-<-vH{9*rFkmRDW{A|9Sm@+)`2-J6dx33m3`6LzL3p(EJ^19_OLBZlg2wfpx89Xa2kqL zF)mB*T7VIbudNm5opkOxkM}~21?yNnA}iK>66MOkygNGG_+dJ??@ejK=$Ar4IADmz z4|+}&cQa}xDQ8MQ5q%ecX&E?+ziNjKby>CjaO_anrAIS9pM^&Fc2E$r8p58_04jSBY8O1(4_r13T@ZQ>yAs`%dK!LkU_0jbndnwU+zNg<^?gxEU zC`zRx=*m!2*2;1|6Xk!9_6P$uiKk!b5hqiRFv@1nGrx^r`xi|EP#Oa`b`!fHF6L?4 zNUi%BE2sEd#0x2Kb%LbnB$pLC?LM>tNs1y;o0`REL6%si-rrhisU7dDcbN48njtp} zjw7HPtN>I0kbz29(0WTz3-kqbL7Ytdw|v1f>e61CrNvq6!U9i86-X$Dcn&N4TZ|W{ z1#q3|x0VA#tHvV#;iz)#)K$qJPppTe%_LX*EviL4%ehfH7x6!9C_P~o@_`73-j z3G$>5C3WDbb2r^xr(2&)y9yc@*|u<|LSnYz{>hT7A1{`Na>Zx+ZpgA4RKef(IO?-O zsIe;Y7iYn#<)jF0Zm@+pGw@D$pKW-6VHo+mZF6BPpl;F*@t~^yFw&i`L@@7|qKByF zt?HbQg);h8Ph#un_pS!p@Be(VykRe2-WsTlwH!cA-P8IU(qbMplEpuv)CnnP!F-TKui&pB^wT=b^ z!de%#xyC0>`?rpMfnWLOESGIRu@|XnfnlEmprOewFb~Uy3870Pm$4gJ?1=2q^L?;C zD1^@|E%1pORr42Vvl!MsxXa3?))z~e-eln-d`loH@$jcqzs_59zR~?ABXo)c)3#h8 z-mme>V)l(zbK#Icuyhl-```Xi3r6!yKpie1T6-ouLQ>VG`qJm1HplO7jtQNsKqxoa zSz1NE8FDF>byT+3gKg9DaRGP7KKt+5y3`TjatnVD+^B?razKTkzr^^2*EPy-I51^< zbKo8p61efTwRDcLm+ALV^95DM2U%#QJrZnt+Vhd6=s@+26X>K8N;D^JVLpX3RsDH4 zDB8as2GR8Uo`Vj5tWAjK2imH_g0r})U>wMvlKg)(vvAgNqQbgCT8IjS(*_RU)o&Qa zxV;0&ZeHBtV~|{`yx3OGBkXnT!DQ6S?99n($(de#}I-`&mAB)G z-7{n|w$A-kuU%}g?qFU}0LlTIMoR!Z+={!5RBl`zI&X1R zdULut^`gTWEJ%;EO^+H6U=UX<4+xIan`&BR1z3O)w*<7~LAe8)#uW@kmwIhav5uVt z%_(^>Y7w~zP?gUoyqb2}in<2og{|b*wpdU+iXgY82_F3;x}oMF9pr^2=S9z@02~gQ zld~5l=MLri-yDep1m6&W7meR5uW6D}J8&208}XnX+cnIVaZ`4$++E;&qB7-r0z%l~ z#+=f5UKFST+f3M)xSg1U-#HnQf@UYBY9KhbTR@8aH|IHhdt(S!xVc7Qz2qRMahfGy zX5O1lbQT7ia6)?S94xe@0~P>`6TJu!56sjuFYkXF#u$yjPdV?D%_?$`#En)AYu2K_ z)%q8T;%`phUk50BK!p(J&v8~!g!-wSZ-N#?6#m-j%MUb@q}{%L4f=5Pz=9xM-E#vi zTqj5sSa-$LXk(=d{#{DN@~-3>ZwXbnwk{jYtE;32FWG1#8+7oKU!hm9AC}mGl<}XO zzX6FhctnGEWVJR)=ApB~eN|G+bp>4ru)w9yQ+yYYPq*RtgI~;T!UT z{-X|`_`8di{>M5f@1+^D_#!gp{3wzNxZa!0dny+Diy1G#AgLL9!F2WfW?88lnBOI* ziq0B3Z7rf6Hf6j3&=V-d6YFfY^B$rpD?Cm>L`ME>D-`ua8v<8a3O6zwU#HKnn`Q8`=?5sbzNgjMw!vU=2JRC-pvzmmY_~nWKj%%V z7H4`yf;CtV>oCm53Sne=l0tkr9Z{$LB%j1(*-SjU-&&Dbo;OMisJA@r-Qid{-s6a8 z_Q<=hLd7loOkf%NBvx!rjt$P8O|QVCq`{*?bQn$P<)O^SgV86 z6~X%CJCc&Hh9}Gxe|9}>uW@7)xA|?eS~!-#9Ly^Bj{nL3g!mv#$!{nnBh}F=2P^7D zubV4hXLIb!;E#vNOHdNeLRWtQqJqgNj9P3U6s%c1eA0hW=?JgM zfQ{}CQWQy+wfJcF-_XM&wprn1Bum`Jc;we=JzYsDSn%`6pq|2x`Z7^mNI4oMi5fDU zNVp!jbJ={^&HeCl%IryLx|wu>bFAQ=pEs3z1E%DeSZH?{tZ+^yY%xXcCH#PfVsX%q`EfkLgm6yDr*?xXZ)PKUU zpX2^oe+V)ChT%Mw;OHHpP$l2s!G*hjhBTE#Xp$gbQV_~ z;h;&)QP`7o!C`b&y!MLv8JgKqmjhILQYCj#bu?LmDlU1E2_FNQ$98DswZrI2#ltTq1R*V+UaPp&mTOMCH<~D)R=x*Wm@B`l< zlV3f}9bLQ10p)RWZHo#=V`t4~&|J$shAKmK97Msnbdw-cfsVj5` zW=;%`88N<_xuAl`>yt;RfK)fXtn1hF48#YnO~8qXL<4=^R3>CtaUq~+@rNes(2;>2 zzhe`Lo1H%S{E70DSg8@uC`RcPxD*}-N1j4?eQ&CYbN8)Vcm;Y|a4yZ#U?MS!_h6B9 zr$CK{4Na7W;%O z4G1**Jn)B|fO75ZTd{l!X1r%0q>~7L+K>s>58j;79lk21n!s;S`RN zH73vTils!x^ihivKG@0%GqW4I{vIaJ&)DG=gu8??BX~du*YbPUCwRDzWaSI%bRyTO z@LTu{ont=guZ53*g*BH?V5iehPz(8vq)em~$CP)sWK2LCg8V_@dZ*lu%T7Eha}LMc zMd&zV)g5jeeqTz^Ql4Nh0(Fj1C#a!Q2Zd-aJ>)f?XGVWV-_CCG80PbwDPy%Z2hF^s zf!oC)SNYn)V+wYu44Jg;lA~bbCFWo5_7cdnv3h|E%8$FUv-DJbh%hjwU}9%uA%?6; z6pGkF9e=zs-^Va{gXbN4PmGx-f>}xuV4bHelUK^;^NL`X>~SS#6fhcK2}(f?m9NoU zyIH{=jB_k{(lA`jVO2v+ma%fsQ#9R$Kk`Gb#?M)mC{2r+1CtOO9&G8S;CWimY3`|R zaSPv`IJZ(hNf2$^p})LDGc;d}9B@M2hyU9z&vTg(#c5yDp1w+lE}MO)rJE_A#f3aj zy{DamkbIp^#4-s<#5V`Leku+ywFuM{)f7Q>*U}FzKql2tbu8ZTuoN3dzrPASc>aJS zmiS$;I2gDETkwmJ@|RF||T%0;lgusX4>F@{Y7eYE3yI@FJB%5$;1Lqe4Da^`in! zgtYOWUCcD0Ot^R8j8?TG>Fry1_(r=zXr;hQjsQC>3eor1D>-WMkgWSV7}E1NkUPFk zzuw);C4s+(wruRF>E&2xs$@hGct!LJcAeEaJ3+lqSq}YzK@q3TJ4F*M#|sEJtJ;S2 z-~HW{a-Ww@4^m2i>3gK-+^Z+>Vd9X1ZvS{YA`^Ryl~~wr$Ux?C&bZ$oaF0!QxJ2&_+TVXljDAKTKHr$inv^T4$n)gRzl zpV04buU8>Fg_Ne0*EaFaNOa%UJHjmNdSN8A) z#=oWcPf!|47S?)}1fOZ#g_Iu*AsILxX04{M;f;X`h4!|K7H;Az?&fy^b$`-+%q#S* zzF+bP+=hmtQgR`g*3i!Kxs4o0YQYK-97kjRun#VAtLjGm22^l^=I#`Jcxv<0K-S9i zN??+5DZ1il@9~k#o#}RzL&6YYCP&YN8A1H|8u7x^`tRF&xL^Xr&Q8z&$s>tZx>@t& zcEha#Y>Q{xIn;E8CKGDX4iUH(K&>VtRL0;_?s6)$wRSzJjrb3EY0`4r{UR{GDa& z;~)A%L5|=7xzasRN0SQb%?Ib*JJvr#li-W~EJsz3kr7zS`CP83H0?9Xsv%%llHu9! zs2bzh)D?Xjbs=4ECdA#a%WAre&e>Q>@makK>ZQJ9_m+Fgha_-+PzFj972YRJ5;SBl zsKOsihliPzPmKj}h)feMJrrujh~L29-+nCwHZrNp?a&>7i0zvM|I{WrvoBN<_S#yV zJjsfQDL3)pnQ+@fp%t~Np^gXLQg0(^ks`SZ%S#}-hwhrs>TC*4I?IZ@ytqz$tKkCE zA87Z6LS41DEtn?v`=#N#y9H|*WQ4Fdj$0?Qf@)OuZai$rc=&sMLd400v#RpXR`&8& zT8mT6hTqvkee$fkWGhh=$Ne*O)&%JU-7iUS^fQ?&5CUbv9X!o~o40475`KB+HrcVo z8lz!;PMB%LKTW*AEPT&w*kM4 z@|6i+da4rfiIe&hyAb=?(azw&f3=(vaB^w2f!+;{;%V=_tQ>7iBnq5DlszP7%5nBR zmqs)%W)3ND6IfBo1vn;#f%ha*3wPef=HY;hDtUlBKy}bM5Z*+69CY%}s zWeqA7T;*sHKVBc&{8=$7&(?@#DF6rR5jCKjA7{rmPyK7<$~#RYrob+__+e*7gJj#T zFy>Vq_R7DW^Rvl)2p?*?%s?b-Z_0+~U-{hY@RCmD|I>wir5n%62`he|lpos=N98O< zFI>+6+AQ8Lo4P<<_I31~x?s}b0j?xcFsRLn4L_jfID&p9(&demZddiMSA2kf;#E|+ za&H&kbGCBEa(!M+@4yIQIdJITicsF5b_?-_u1Y}eH+mD|bAp4owu|M)k=(BLIjE|v z&ziW7IOpPXelp_70Ks_?gP-{$&l$IPdUXmXs5Y;3BQ@*C1@Id-4{T0$``++P|8ba} z(q=8`tK6Br0-*e}?mZ-h(iAwZc59$xuuQ2Le|}i@LVMqhE-x=PrEYp$aMqkwLwPHW z8L5y~XB@bg7FI)Ihme^`3YObU1GUn7@v%-9ITD3>o>w7v=Ph;*E4RR|`gtx5)hv@{ zb{36k=S;rpw$UXCz%DPXT!HLV^|`L(M8#OFo4kcJ?2-d<#0`cRxL{xX8m^WtW&aop zHp%U$i&aM});9Rp88bmb^9OrZ3|`u9yof#@<; zf6V_`;+X9tGwO;68r&bF`{+pOOTKY|-#cDy*V81v0JTwd+HG05h^p`u z_6*}v3adlC;M-^w#BVgN_3pSxj=^%By8Am&qr_!AwF!hksDT%(XCp_{zVYh(w?Cq) zHVMp;6czW|PeGsE`yW4vzJv=(_vc2eN6lw{xVWlTLj?U4k4(jd+$io!9<+d$^|XM` z;o=THLE+^UdeA99?xx;z#v$}a2c3va@s&-IPs~3N;~~cgJ>l-jj-Hr16^##)kCfe= z)7{l`Cs1caCmnz50fR8PsPE(ksEKV2^o2*vy2GompRT{NGuLK;zyI-^?%E!-)ToUa zT%a>`_+|V#;88VIgWx7h(4W*}QsZLS>DxR7zvyCnUF!lh(S`a<(*)$eHWU3kH=eb1 zWkQ>&y;m17?f!crEs16I1jpF)P>g8p`Tovk}jCUtADprInW z1xH1LAJJB2*V_v(I}YApGrUYFM)u6o^N52w7awYzAK^^!MV8=X7UcJuQmlkmLeH@> z(>5~gW?no%;*yE}q&gs;*qcs=h&tt=N-oEPy<|8~i38Ja>G@(WsFZxAB~5CWwvYC9 zEQC?oOex=77WeUVHB|85p7^{PxD3wC3Lo5BRqTbG$Qo?5d!n|U-wUvcHhU%}kHGZz za@k%kpUcS3;pK4qMUHmW`&4b15yB|57MIg_WD93a6eA~FFV;x`<-DOPvXy}{@79t8 zIbze|pgCCuwL$8P@@>k5`x#p>EoRy^<#?UKt2WMIXEL%}%D26+Hu6<+O2MBF^6E2J zGSUFY@<~HP#~Eo=F{y}s_qhw_=UaZd^MX!WE8#>h!c^%*x9-==WBwrvbNGH8L`Q4j z1?54jW>ou=D~vO$nUjHtiZSaC36Mv5pNF!yOl98LX?iAH`fK3%N*_XIm-AXfx%C_$ z(Mn<=Q~Q3n_`tn^_!Zl3ShR~?x=u6mDo1~#-JsH7D`CBRHSCwhlkSpB*fw=lcnMep zke-N=`)Qr&aOE8@%cw8|bS`JFq%~li`|i~nPML3Q4-JgDaYl;i;*AZ?5X!x6IpyDn zF5XLK!dz_xrpfw5}DP3#)s)dIvik!G{E{6@H%v0eDN1#z8iK5A9pNtr*^`hPcuZI8-&}U39ju?d^hw8QGGa^G zqq?KZZPns)qX%lD)mBb%&pd=w6=w-nbCawl`cW)#fk*N1xk&6!QQo?nlHXBH>$)V8 zTg1A#jCxqi2lM$)F-qsmzk8cigJV5<0bp6etM^DdiI%+E_9*?wQHqoX^#W5$8&NlQ z-~Qy2%d8aTH;Y<5b-Jri!MI2Cc)HJMiU!fRbd2>krZV5J6gOsl0Bn1}RJVV$L;cpg zOUx5<7QH}d&IBuWDCE~$G=Z#(^`yn-yh3wUjLXEoN5IC%9%EmqKRSe}TDOssSgaHr zI2#CDEQsBc_+x(%D!$n+=g$<4wGWwz8Qvo){7O{ zaCgj5s>@iiWU2wLfXiqb%jNiIjS zrz-RB9b2yzPyT{)CTAEb65*@d9^h3h6$q0*e#LlHx=^|l#Lrhuk>Wx4e&Y7PZ65M! zENND+Hmgi20K_Rs+C>+!7Ovy zsh^72zl51s&dYxW&8|*dICbps9o)VN!&cM6QCOG^g9rust_54yoKH2>DG&E+rA*eq z9l_DkRE|k+9pAfFd0J2-%5!7O)eTBOT(ajri@s}R)$`fLHTODNl1y#GeAfKnO>?j0 z1t8f$tfc;MU&i!FNM|a;hGCZGz^583)rO{_Af}%Wy+RkXM+MN$((EPnYTPfAmhDMa zQN@4X#;NpprXczx_LJ}M@9NEs${Q^h@K1!^?!ZU$+8uT9aOwhWoxV}T?~}@_pDp&3 zuACmt;hjYZkP(T*)AwubvEd+N;}UO`QaiSY_3pp1$l`@wT5KbKO5tYWUTroKdQCCLbb{q|0m16+Yre}Q}Kn_9}ZWot*k0>aYglhFD+7fcuC>X&>lRgum}C`w||d#4LD_)MH9+){f;MR-G<`sRuaxq-=7?) zHKl`yr}S=L|4$uzwS{@mL%XQ^=+zrD{^?%F`E}au(4z2}W%Cad|c^5F1T#Kw?Ji4ZfWwTEEsz-KO z4F5U3O{H7(_cR~wSwedIWNs@{a_w$Iz{JfMilHDSnfKxc?{I)#-O#?vPIo2g^fu2^ z4Bw3skvlMKv>f`vacJ^N-=}Ys(X-_Jp;S7Et@BR=MH}-~J@euPMahFX$3wm!a`M4d zRGmv&Ipx0RDy5&$YIeJFWT&l@D+)wnu7ywwRZFJlwmDk!hn}rnnCnXiL~+t@G?f29 z+PX5UN=vs+tAna(3L1*4rl-pfC}-ors2s_i*3KG57^gbOKmKF2pw^H~hDmh*3d zem0eRv}EI)YA}-K-qVh?Ije~sx%MJ%K&zRb`LZl()ci(pZck#QY5CB?s>_QLu0!wA zD5IISzQg~T6^!Q_j%;NO!B~GnP6?*Z2vfodO_E-2i_~?(;xU#Lal~o8;1_0})5vfM zI)zq^okaz(BAyV-xE1!#`fEDcm|#W@&ws@cd4K5Ef$sA-i}slhB}(smiadCdll<;o zyNJm>iDjP0ue$FBS)R-Jc7yS46rZzepdR~v5Z37|?8-{H7aM>b&I$MyTuN>H$=msl z<pG_!NEy zTdw1VAAhG(9O0mq*z&{@+;JwBVR)KjL>{4-WJI!8~zi7 z0qBKaKjV`}O_=&7ivLJlgg=1eM*O}RGCq6Yvw3H03O8rCJ6yX*zc_6CIJdz|f~mR5 zvU!ED@NCM^5;q*$tqogQ*v`gha~`y^=JrIP>j7o**|2F|IP@SNb%N<*POPttdfu|J z<$gow`P3!__;Lvp$2((seFWo+8~@+OHr z!}qTECy1xixTf8bbeBorlzY>TNk$`r68i6`M+^MNE)CT@(dIOKs3@5zn)YRLObYj{ zMYXba5)*haj`htkJ9@&pHiS)vN zkWqG6E-eA_s-X5Z%BD3S_>^5%-=7gXWQme6>87RKT{gt%yl=wwSn>4A2lJTVT)F~d zlXKXy>8$;?I*!k!Muoq?!;SfP76B&qKfM8hvq zwz6!*wzHaX1EVkgHBAlqK5@1Sjpvyd@~jW&cNL$9ht2H0j<8SmE6Z83OE$a?Dl}mg z=NEIStTuP9wJwXze5tVA-Wq-*A1C&ayas(`htezW#?{103oPX?ylEymY&DHYvo_+cXEJFuU588 zEq11yDI_%JyG=9V5Ed)$t}r3Eeo$ZG!l0g04u{kCB|e4CHvZOk;<<06jE$`gzRLI% zo-`nBl*n~d-NRV}Y`bFDXbL`t9CSsV!a4qO9eRjp29ZSlaeNEUq}g8zkPQEHYkV9l zT}AS3=G$lrjoD4$8?>hogzfr{7L}&M6zIFrMey-BL+E-|Dn0KDZj^zh=P5_!cLmB&Arlcr7+DWMO z#L$I)WeC)8&dQN83+c!1#6z|=kN1VdQSA}tTMDcT#W&|;=B)QiJ%%21p8ok5y^V%q z?n!3d^dZH(sDl2jNLU_HX@FbbOYZZcQigaZ6HzMHPAs2|aC~2QNqFP*j4$i@JuNzb zEn?%UpdSF*)S7-hak7dbwBdq?Dp8SqHHHjX^L3Xil-vVN{`O`wI5)C)24)nwv_c?9 z`XfXr`~M)kUaOpLOgv1x^@4wabF1#DDE~n)U?KqLCva~Qy1z)g%EVQMdUD>pg~a-j z8Dz&&vZJ=hXT-uhEnqyL0mbzsral?Y;XOcNOMA~*nO>4ki(G0Wr7@t*hQN78;tiG$ zu&#QqrrIj=e%yTOF$rDs#01V@In;9|dJ3P%}b1Q6}rl%k;!=G9-x9MYR z5Au6!vDi{9jvvceMyX^5`;qQ|cEE zbxMI>2&8>q&K?LMdE6v}iE}%)>#O-GOhukT1d$URg;ya1T+$YC9D-htb!m7xeTb`Z z4)%6B=3ji*%E^h*+bo?uGfQ<|hPP3dSSe$|{#Uu(6;p)UM7DK3=C=vjZwgnW^}G6} zfLzUcMmahVy5ZzjgVWU^_GoQmx)YO+3QpVv-`;1+FyO9L$RRl)=UAE}fj*1idVRkJ zBynq1Ew>K3HS3`&Pxd14^VhA9i*D3MPO{RtEqs4pcCnGR^Gq8;)Ok%2BzCP<9YqHy z%n%_UJJXZP3F+7b_sN4^<*&PH_zCu1*tt&WK5*Yknd-Rd0mjC`ppLbrZ|fB9!v6&u zHO;ifR+AO{?7}&}O)HKS)W=7h#y{UeEoa{&ofi45=l#`_Z9dzFaBVQ!iJM+_KNh-K zVB-g=oK8hB?Rw|a5C+p7jpKK;4HnB@S8|)&1U@)uP+RW$5L{E3ddkX=;bi{8-~n60 zf|(f9jCf8GCV6pctEQ^Pi!$4KO1>(Zw#^&%J1hRO|4Ak$pw|j2dp_0|+u`m%hPfMK-dcV0 z=^jxW;-tQ}*L||`{NZ|wgp9dcJJ^t5mZD3YImKJrVZ1NfkT?t<+l|#^iE=Ps*6zc< zs(3xK6CIsEwq))p8RvL7LtKQ@e}|uyJQ>>Y+ECl>x%ftiH|@ACZusAdhfR&C$MqjM z&-o`Vo1qKV)g2uNSZ|w5Hyu&WHP&7o_-b}p9mQEwCEpd&MawfC3nGktG6 z(S`KTm$ID2ZRRBp3t^OJaxwdo3+H%`7$9Rv3kT+CYjStT&Zs7K&us(-VE+3(mQFH<3Z!bo@Nc4kc&6R~p&3NM@ zU&F1X>VvmAmFxH);MOB$@vG4r?)K04PI}Z^OC7y$NfYx*J?Ie)hl7;g-a^Q;B5Hwt z*Ln36VO|gs=GK_uu#hK_Yt^CqMb%^Ce6s>P|lvgkNf%ed#8g(Yj-mw8}EnrWO#KKt7H+36k(p8u&-9iA}5r$B|nj8vnpI!l5t@jrO_;_EWVQdZK3M~ zI+)^E!eJ1()-J>_M)!UK63SpX-U_im#OQ7TbPtQ4MZ?ew~hDrMwA5lmfmC&MRE%kXN7;dc=%%^G&S0E{rHk zAO{&Pt~^UThTDiXI6f5Sy|?CrQyp?KJ z@5he+Sk@6yZ2<~qX~fp73Vw2UB%-;zI$Y|Q34aQF&dE{wYW8eDgd}RsI`(3@ms#PzHfmOWAXjBv5XxB0IJFi zksm;v_yrrWctzn3T_(L{k{X$QS9p0lk6M`9qr67!uG1r!ZBMX1vg76QlWtNC`o--Y z$p%DRYsN<0eB__hK-?pSS&<|E@{oz!P_aow;c%Igp>525Tp|E&4v<3p z2nLy>tuRdMn`;4(gHRGewbGuJ?kjl!{&Nk9(XDGv zB;UNv-hZy>&ZRgSE^6P$Yfc|w7&Ma>Hw&&Rz2`Q`zOZXh@BvBjsVH*g)mQrbW*uGO zS(f>i0Ay-(Mo$ac=7Q>n1++?O1or%C;gKFtiC7GB^2D|1j8N54dt2xx%}pZ?Ol3a7 z0d;Iqdo1aWNRzef7giy5Lcu+6ijO|XmAv!ae7a zJ)b$M@=j?R&c}p*`akt=lrWm*UCm7noJMqe?;O+rEy*=ka)78Mh(oRQ+3^tY$3F8L zFl#EH)II59Y@;P+zlUFBmd+0p`=yQ>u#@liFzyyjqrSN`u-rudtm$^W>jW|92CrBT zJMc=2T$Wus8LM4X=T9^^z0aa0Sl zbMt<$M1IeIkreXP`&jdHa8s9&GyQxECJ@XZO2>rs}UG2oxe0Z6fbt@ipuY5J-6 zdKjsFbE`NG!~j6Ophzi}>vX7Ppfi(s`(*>AJ9kEAMBtvnTrJW2bez)yHR3!TK3s8d zN2;~QK9Nrj>aN6U^=b6NEI=6PX<&WN98DtE<1Oa>6A|VI3U)mqGD$8+VX7Xf@McN& zvTkQT+b;F1-O5LL+P^Yo<5GO_-p*W8baK6%%M zt`YQVXmO>*xY#(gQ7#r~?%h{3g0A~;1pc;cipDUi(*Kee*=@!&j$?1?ud`A;*8N0~ z{UoDtpR)Tp+NV4dy*D9Y@&#n=e~Uyns@%>TN%Kt^S>^xxfphHzEpun@)rV?8^!38} zN#JX= z)wblHqL%{QC)9=OuB6?tE!u0)=l2Oa&S}MRkyGgkI}=MqH%yRWp;zB9JS*whgk8ua zpZ2v8M{nbDX5>PVjJ@}R4xUS{4>(Oq64c)0TZX?&JTXoP1zfdY-!KGXD`}-OAt?WWLf7;_<`jn6keL{Uz?OLeYNy3W~_Eb;2px zXg2~ylg=OcU4B)n+i+!EPfVk2_kSQT-U&JHW7Gl9@QtSc16GhQ;YOgWuQCDL? zcN(8JDNa*(e-_?bEzb84V7W^s3YCRh&AGDZWX*-j^TD>F)F0km`HNN5J zg;{F|_j@>gQLsH=#l3*A(WAEaGv_Sw>4No#dYzYw&<&LRfB3uRG*~r1A@*3r=~>hj z;$75)e|zIG_J-GtAHuBq$c=V0vlV`vMv}|CSW9~33Hns0I7X%5Pd}!Gt|7R39~mW% za~Uv`n$6e@zb5srobtO6r<7T{p=;NR6oum6#Omz_92W>56%n;zYKoA7h%@UE1^0+bu-s7E2#d>6>0Eg(j-Ub>#l}@BQHu{+91d^laF}?9Y^aygxov75#ok z15dLFwXL6H#i2g95c<$lnXo@KwcBr~j1s268?$x8!dw{0jdsgAORzI!?ekhO0S>ps z)wyD^_3%Z~%I9%uI{e*(OV@syj2Y^XC#P}CxRKYmCX_OvQX$29Hv=^p@hi`}ghJV_ z-^0k`_LnIop4j|XYH2UzZ?&5j1WFqTg666L#z9{Z)pd?@P9rgQL0biseI?<4u`)55 zEPV~t2aKDHo?0;!WcT!$*5pLuc1CUnMH6?y8SPzM4RVhOh=tLXKKU)n!*CrcycP3s z&fx#m^yPt2ci;a{^;A!xX;%rAqz#p7tV5|Jp;Ae&PyO4z{QvG6MHk4Q+*d_IXK(2vG8KTp7^ zV-L@SyW13e`@|^WC+a%j^Ii9eU+z@TW@(0BzmVRfj3_=}`*_LI8_zV_FaJRXTl{;S zBvMJ7JbV)tBVgIkvX%~T5MtLp*fBOJS%Uajm^O@0rEKXhlvsPB(W8FD2hbnJj)i&> z%wK~46`Y|l^k6XGg$*W+IjddZO|hvve@QPyI(7&I->sDhW9wmxv+Pe521pF;K%`@* zK)|QTx`{S~^_M<*PD5^0g)V1EuHt8(CnWH0?ps8q6pIe4g*4GIv5#=FYj_EebFBQt zb&e}=pN^4dXK;>qPjtq=u8Tu;)@^#oQSVp(+?yIzx-@(Ofji=aYiP_T{zT2-3BnuS zDzl~nJFcTICz;0sT_SUg7S=@P2#YEp=qWfbU*WzjpK54`RMP>8oX|c zauD3Jp6H^vwQF6BsYb7un}+o{POTIhCt7L{NA;}C@rOV&qb#p6+rs2YW*J9yGuHAL z!qPo9NM-bM53)>Yue1b<>oM2yqTA24Ztpl=7b`rh8!d* zUNYNDDgdDfY*@6U%&HFxF!Y3N%|n)F>P4mlv)t01`h;BwIz3~aj<~szI5wMcXxOiz zk%{y#LjL+ld09}=eMHhMmxchTbj{=??(~F77LP8iQooJ{4+QRrjM8{p=R1@coKE}| zBIht^Bi2&Cy844$_nX%Q+K% z-*Qzca_N+*G_9YXR-*(QE^F<|qiE|cBkG&11QJkI1t`lE-S#wj(ZLpv^%zb;Z|25+@&F zB-&&)`Kt$@kAm21l$s#6wEnXv)rQ|0G4#6|WwOXJbwL!hHKrkEYTS1sJ8(TFi5h=@ z2ls?G@%gen%bI%e&iGA>@0yHWn64zhFOdr0sfp;@8rPHWH+)urnyc;(hHABbXj9>Tni(i)PEE%j-T)rF-J$upZWfqrqG~_Q^UUgnebhG- zXfEiosuAku?rIlxEO2IaRBQPZmfL-p(zzPKy$~k-jcd?24o4Wf1xi>s4SAbBhXwn+ z($44Es1E8gI66*pUB-32aH^E@E5Riq|Lk9bIOBl($|W&wASgz@LUqxn=hx`*M5V^w z*YJnqw@F@7x0f(U=q%G1Bz7?-w(Yp9T#Svb@I5}Ki1Q@0qIPdQ2lpMD*1yTM3a^A* zUG_aZq283RE4cGyfVMKI+yI;GBlh^RVM{5W$SdkbXxXRSmF06-e)2tD^0#=Gz^)pX z;_}~SqPP33R?qM=82^-%6@1IkcJD!y9e^1(J||sZd=Av&v9xP-%=GM+o{WK=bRugh zySTa^rOyb7t8hL8pGmkIyN`%plG`w&sLaMo8~YEx%Hx!>E&uGhx}0)t920Tp_*7bg zu{LkOz#YCGnuVCbVjZaJf#aadJEmHTN5qoMYjoFb_jxL_723woPb}D{`1l_I33V9V z@Y%>GO7&eufuGZ4m9wsRL4Ir?Ugj_UfV5`V+q9atF1y&{dC%RDPJNKSOb?G{vSG@o$6p$HuCK^O%#bK6NhZ_UYRtRYj?S-Cvk{NCgX0x% zj?&*EE^Nb2e?U(3B8}*wz$fp}YDQLN7i=Jx9?Hy@2fJ^>=f;ph+#cxMlbQmw(_r4^?PJkw4uJHU5I9Q<9nK{^NVH{hoJBI@m} z9aU#G1TNbtql|!38HkxFTSFM+qpfm`Gt^}D1RMSTHdU!*SyAeT#S9y9Qyzgx{iYXh zG8Z@p`DfH?i%%wJZy~8u`jaW&6~gxEVZN@j8Dy^4Sy3{cD(*rY4Qx>b+l5qu&lF?^ zwD7(CPxYd5$8Oyds3B&;SQ8k9PZgo){uwV=f8p4`(Pd3jQV}Y@DfnQ3njfgFj7;o* zjW^xuV@w~YrRZZ7b_X#r@!_Vy>rDf8TWv9q*I&Z-=c=3+!zMp|sP}&_m^Jo19Ix3> zcajzWA#CcqF5F4E?%jrkSy(SIF zt?2uA1#r@by|ket)Gxlas4duN86Y5w<_9VN^OL-J*Q%qsfsI zJ{eW*N#G4v#2-u@t)X(d6Ri1fT(OUqw0y4P7eJoHg#K9F^!W=F#(5Svzx99*c#-@( z0XnQ``gh3bxc;G$7JIEok;R`xxD+Pbg_i8IwYSd*9Pb3rt@XisU8KMIO4ic@<9SUo zg(304lQFE^rU?+I`QnSN5z~rYIumT*X0HsY@I4qQ{dac<^<~X6>Q3(pOJ>20;q6Y9-(Aah1 zwYr&!4WeGzW)N`&Pm}NE0r3kqn=XE;P$=71$Whq_j7ndXS~YMnp(!rt359&PRBYGS z=pfLr@Xp@IN(|3x z2|4mmc-01EZ+Xffn0Fn~061QgJ*b>d#A;gL(DJix%dRG~EV-Hh=0-K}qQN0NyJf?EPj3fJnRZAO6o zo4QrrjJO)s$n}NDd8_bf1()l0g&yNjkL*0uY($Lizpk5cZ=PJuwH(IZf;hHRPTL9>&IxEf?63KJ;k;u}c z^a7A=1ce;Zo+_=MOgp^dTGDiv|9&ORpCk{6xe7GGHuSjdXpoJnGBn^>iY&*sR(`Hm zHo;bKl{qav-H*5OItn@IbU9~@Yvb4PBfj-aLyKETD0htb`5BL_`ezpQ^fGMVH|6$@h${0->z9!e1DVmL)@P7g|L56W7rs?L;i7vXu# zWyXc8Sz3fKVRYdb-E%F-(BD^=>eF`I!J%CIU6Ngk>2$)>5t*cu>MHBBR}-%7V4Ls_ z8_jLegqZ;d@y9b$UjL*;Hoktu_a}dQnkUtQ8k8k92mb|AcEZ)x3+C$l*Qkm#AF`5s z&DYYyRZ3WSgVXK{B~8%4blBJo`x}D34JwKK^44ipqHv!bd4Gwxb~V%)Q9TJU!RFD0 zobscX&id3c1czsQg%T;cZ6{t5lLJ5n3h zz($h>9f`kHh<9Jf<{rR3RR=#q5WPSD8+mUOc8a^szC>k%iSdJ$m3$94&j+5Rz3@N0_>xrk(oIg3D7DHjI^!TT5R|^zKa5`UlfNx<*a%!dDMq|nsVnFW(8%Y z_!k7bZh7ZLWabjRvj6uaB$RQ|7rxZ@J4&Ry(*M2nBK4xO>&lrd00 z_uD!GeM*-OxNoYne_L^a`OJj*oT=KIPUJ1_C7I=F&SN4%?%yJuE@}J*WYxrNz4os= zPl>17aoT$;UnBjh2KA>}#C7`pG8#hFxw@tNuYN5ouh zaOiin_7AlvHdI#BD(dS7UE@Nc_AT#K;EL|uuChe56+93=Re=pe`WwSDK6Hb3TRoHk z+=GdyDyDVjO%bMhy|$9xWd~;DqK2lGpd<9ZzDB<72oJtD{10>~EYRq7HH{)^u2Fh4 zK9mEqCL||A?@^wxpu-|j-~IS^p8M)JNLxGIrfAc_5v2-j6|UJf-#~RddlT|&2?abpUm?B9TejC3&-PuPNP2kniJ;P5x+ zp)uUQzcV{I7`mtk2=gHe=!p1RW2A>IXDTNwnx&MPcBU=g#$9!_Vcge-fmD~(jU0&w zTxut7;HVk1DzCWsaLGSs&bLu~!9pz*Y5yE(S{NBd$6sDmQ`Q&D6%aLqDULk;-ni0zG0P6yKHQvLRXwhxm z{#77kfzXiZNxf)aS!?SYQl;T@2#ShDqBQP#oKss9BJL&cOu;pXNdPb=P0>)p3!gl1 z>+i}%Ol}~FyM zL$C~LXw_<^-As}rG-!cKo|StU?v`$H*;Iymufj-K!zs^5p8D^0$`{f6$eub|!nwu# zV+oHYv<9;uLs6{&&a%SYT_iiBmz?M~PhGppWHa85rg6`d{jQXz=NX22nUQ$jG zjB#9ZsgvPkyXe6BW2Ah%<|mkUo+xTj%ZGQ@A4>#nQpO>|wOfP8S9_>#I}D1YHTu(& z01+mnBok)LQW!&Xuc_tn59$03)FdFz!v;ke5;->nqg|N}!Ke}z52&>C19vf*wc>$q zb8iIYgL3C8zQ zj1`05C=YXg;F^Z}X?MS0NAAME(i_F#2h$m;;xzmXM$%R1(}>}h^s#y?)BS9A0@SCH zb~e4EQ}}q&#L}uFxMNfGXrGD>gS5Kt48?-R7v^o5I*rW^8!EvkMwWaeH?GUhDJJQX zIU>bj>_}9LQfS>F-C;KM!pO$yf4;)V<~wF`K_xE}UBYLp)AAC;{(O9_}Gy7CQB@fTDQ;igxYRT`7#` zeGN@Rx`;d2DEbpVE$f{4lJW77)SfcgW_PCDu6rFp~JdqoLspy{!zDyg1ud z;}-z$u;tK~-YFzR?^G;x>2BNX5x^TJY9&^On*~OwzUmega_O8Hwu%p&4{?AYxI)&R z;yzJ4kSXl_DnGPBq6zccweXanq^>ltX9*tCB5$GVDn4LxP+N)Mee$I+g{kq&u>P(H z9c5JE+#`5&W7J;CWpq6Krso~hk=ds#_7g=zMFDyAxWVLPC;HLW4D`^xNg$USc+e5-s4eF6SDw6GH{dc>gAZbeJNnVJ zL{Sp=M;1S2thkBuGotW+F1J8qavyj%a-(FtqB5BMT=*GKEeht78`s}>$Lqqx!*j@T zN;)xEMsw+W=BC1NIh0>kpFWcc7?n^YVjPF4mU~YRy+dgg`KK(W$WHm165unbW_l^C zeJ0+)uT5lLqb{>?To;W_NUbrAu<-6mwcN};q-^RMB4dxF=A=rGw^)@dKj~`I!TTFr z?l`ND`Tt5TT{0qfelJ#^b1kt@9>1E)cGzAr!)~Xbs~eSHwC8io#7-?5Pvc74#AQ#) zpj6W$=*8@l{SwP+_XWF37}aNKJ813X-{t@KvRzIPC4m&rw0DLoYjGxVm2xbiNl8D4 zx6gO3XVokBYI+h;a(l=rtnuNmS0H-a-O-+#Jt$?fz(p$1c&*$Xvr`8;t77#!lb>$5 z000)>2!~{FE$wcP7k;g`xJ-9pLs1IqROs{$Eras!A{H}br0EECMw<(m)${;$U7GN! zUg_?r4m)ryfecSDpFOyDaN(%AMPDf>j*=tcc^n^U{A}WVxw#a+;n>V)$c!z3?E3j1 z31?}q?;!<{4V?Rp!QY3Y5`lG+i4qh}cU1NyrIHzJIb{4l6EcSrm+pgquVJ>Z=a+T# zoil_9>rUetNjk6*ZToY$XO_~0RhRv@WeEh}lw%1iu&w9giR`e)6~%;2tS~v}DOLxy zRcA7D6Dl#W@as$RELwt(CeS$`i>AC>R z{4&;dYk8RBjp8eAs$Zgtpi1CQH1I_xv+ChJlMn97Hj7De{#6?#$(z!cgw7WATp4T0 z_sg^gWWXN1;AxHIFpFJ-1bKCH^vD4XMf?cRTY`}5+G_ndgd2%tMq~6Od^9#U^-Z^|+ z;EDqBkY$!uiL@Or&vIDm+MCb$bv*~)+7krF5Ns-%&Zs7Ca#bC%;>0t9Lu`;?QQN*rYyPYa29AXPowWOYP9=7iGBt^w8&Xywp2EEI zda+3Rn0~F~V6nmFBC-p7DTU2e5n?*q&6&mXC}ZZayyG|$AVL))12;)-qid9F_|DCs zh@3CAmh;oMTWm#P`WiZz`DVRRDC&qk%3Qi)IqAigJ0^q47URa=fR!y|v)5WkT)Td? z*I796OSvN;KMv0-nXjMv%U4aw#Nm8B9AL-9BlrrpalFfGJmix>KKNV?$kh<(e(1@d zO_Te`x}{a7*-?Q0yfhtHy{3Jm>t2NPD2V^5e!yK0@iEW3X7?Dps$n9h*?>t1TUr8QvjKti{j5NbgEMJ3XdP zTZ7wm_R`XD!ZwL{7*(NrLQzlcC8<80cth5#yDlMhj~o0D+acfQ!7K57usCsO$gSZa zw;-^ttgMt?sZ|N<1w4U160h-k>E9@9Hl7iBWv5QCl6U= z6#_=%GF!aJvoh?P&(GQRrq5~OkGUYy`(_^TXU%>l@&;Mbnsnl?ptq>2Qw)OKR$C1ezM}O=T}O!obzxa2ZTJvr394r8-?+#4~Az9PLcH+HVgn z`*9i?K%WCknZ*}xfu!b zzHZOVGk-LBv;haCaELCa<6)0`pXN@tuL7n@Grrir@SaU4aJPJsgbw(jJ3&b3=bsL; zzaqs1Pp>Dpu1)#*yGOQh{@}?HaYQX(y5kNbA&^!_5TScPE=Uq|vb8DB>F(kojL@}7 z7b1M5n)u>6h}r?Puyl0=fIXNMAa9~+ceB<;`qWFmeh%mS&q>tEczFr0<&i8xKqt`P#Zb+q8H!6HY}yj4|QqLaG43AT}d=$^hfb~}T#K4$I==|`iA>_uBVJcRcn zOHzr<`IFQ}hMJd**Be*iYvxXad~jP2;WF8A8asHr`Tpc5?vZyNTpT&cTc)3a50-Vn zjRBmewjO71sv#fG%>~{wL>R|r-d1~G4ax`JAKmjhylhD-X8PtMKzonrKGPC=0@Dm? zSn5;~cl+giTa9O6>Qj|hqQ!|R2_)cDlKX7ttAth(9?WgMhmrnptoIh7vyHpghZF1& zS^Wt}q|P$I7UL4aCaC1rj>16>KO)s#kb2QFWt774{tFWJvTM1*hP1-HIO*%+;^$7> zbr2=cbo;aomWwFj6?~z&l&Y*B_OSYmJHk{PJLYZ-Rt#ngHWgNpUe#)hPnOTRPqfdt zPo>YvtF~86MB(oXyP2W{qMk+ZM6pJR1h>(S#fA94EzMht^k=%4$rD^b+vhKUr+;6c zK>wb;!aJ%C8KPYA6ihqnXL?cld7&<%n!4Az7c+6vee|1OIc7F8+EDQCwWjL@(#T%R z2?yv*S1aK>0cyCf)l5aWYp&({9q4?A?rs2Td6)*at8{kM?V%HoXkv%C0cTGdDz=?A zGaxO~OIxnTKc$*;uS$1BSMB?U6rGMpz?+A0tv;EhM%#HpX?VJ%8@8pSpqWsSl>nL+ zB7i3y=v?CXFkoX9x7VLklWhmPS=6?5vTbR~s(3HCk!8%yyS%oUSZgw3r*ZQFZfypK zCa;Pz<~mmp<*QBF3PISO>IjNbD!jc)tK{E_Ca^g;;(BuJksCCR>Tk6w1t4t^QKX2f z1=!|N%+LOVABX-f?SzZ?08jqw!^OjPm-fa3V^o|nuoUi+zKuQ9@3np5d;Uk;^gX|6 zMrzkAghvt4^9DL@pKwdll<63RT{=eyt14PpF6K6D`>H-(srdxUap&iUnMUQ zNrp62;t5z2)Q04c$#4?p9eN5`VmN5vnM1g_K)HI6pBw+#HzfVSm!JaFjDH*BsPOy+#jnp4qNZ&;<4!7Mh>(qX1!`R-~f*<_V z+PY3?Y!F|Ov7x>^`XfJakEKBS6PIN?lJ>%JDP5=Qg5#}4p!dgm@-X!IVGf{<65R3x zOclY5)Cedr`>C!4e3ZPbjQ0KED9w_76xULP@ zr^9=*=QZvEAEn3bms|p}0OnbvjeDCb&BE)3tBNJ=ix0{)>G0q`zMx*R9%zY`QjZw<+$5DPOpGWH-VDz)o2R~1U9cGD86 zhUS8*b4y-XESgkD^pEzpJ3|@OR!%-pg805Uh=R5)_WezU=u?K)rWa=Ol@vzJavcty z;z({WrhMsVLZ*t|+XhE($h@}uye=&{DFR~x67ZHIgt=yfkkc~; ze732Pr(t+6*a=Ef`d_-1AJ?XKo!g6`nh|G<{qw7*gP)e#pzQPhXEbwtiyza%1G}24 zt(!*}jY7KdRRYAgBaVR(C9gvj%xN2KI9J1N*4Zwe&2nSX>-o4*$jW}srI|1PyBg!6 z&c=9?JJUW4FBmlv#3X7c?byEZ2gF<(D93sCXM(r&VveIN(cPINJtUg@of+^q2$XJ> zkpXxxc~9RVwXVs%%;h^9EE(iIF+CvW=v|+Lw*DU8MUp;d8h zBTi1EVV5trCl_{uM%$dENh0U_M11^>*NeQy%xTinERttT(bw0oSn#AK>7eFjo`$ff zi`5<wn<9v&$t`1MSZb9jII*T;)q$Ev56p&BFpAu=@nDy0}GIspT?FdU7 zpwoD}8I2cMx?GnNsUOl_&`}U6&|m$ur;;|~2ZfPYl=P&C%7x+N$oG=Pk)6dwxyOU& zDlh_MNb7|0owEB%z?}N-R=8+Vl1GCFKP(Qg1E2hXo`XXU5Dk2d`a#b!;?h|30D65$ zjgLb~no9&#I5t?`7RbfW9NV9}&O(j5iv-eOi`=#tE*xbzyn-7b$ITV_W+6 zB$peX3{-`Yl!mGm4@niHsysmOD%GpqjonF^Vhv$45kNk#d2!d~tX-jl=O|PRDh6mV zrJmMG-IB>YD=o}r9E{FYDm8~|7JBG37Vwtt!7D>gG$FOhxl?-+T7#M=W{~3okew6g zx+=RhLbJHgx=_`khTS}T{Xhy@paH4cQ;O889#YBmnA~$t69Z51=<;eUhQ3)h%XOYC zuGaoGRJs>l7)`7&(wp6755Hc^Jpi*uMpCA(6DueqGIbh-gayH_1&B|*=BX1A!tm%g zogxrwJ`aBS!$TWVBNVQBl836w{?crkLSv!LxUE)Pn8gC05fO9S`{rZ^FV%!zfYWq< zlZqwg?vm~_!^w!v%oe4Hz7$VS#RlawN;K<)AH4!h@11T+8l15dyK<@GLOpSjhlb#Y zFlH)Ki>5qQ)=g*ITcVhchC>1q;#mVc9dthV1T}M!n7!_LIWObSgF7bD(?**`yG|QT z8|ueOQ1NWU+BgnVgL*?R>O+)6RH(CvzX-wcvz}_=g2YvO$x8Z(YaCuliNUY$DxXb= z+~fUl%8(#2821jTQIijdw`1Sdo~mzhNZhs`HcH>3F~fS;c&*}{6!atUZBpou*|$lN zKgea0qJL<}B*i}~p`A!KW;6qRGiEZ2_-6dVEbW^yvsA)+VB9+4yNIOXNA(Xscqdgp zs((@763RbSs3}LYqPm{gkQxY?FhfWIp$dYv4y!|AE|Rv3TiH+So{-S=MR=rdIdi0< zqo+F^aGnMfPI-tRNXc|Mri6qlo3UvPWe`RQ{y($wxn-gF027p zG^NttK8`qVWbgP=`Ia(b;6q&+<>80Z$o0+zrY)6bt!c4IE}cvgO}L%iTiq? zyUX@JY$H1#w%Vj`b#d2*PIp#sNe{(mzr(3c^pK`BdEn2H+Er1c_Flg`H0d*zt<-0> zG^vzMVF?P)YfMqn*bk>)$POuwNYfus9ob1J=Va@%KmMR2PxqdHR4+99!$A0Bm3`No z5T&OFxLl;^b!#WpmsFy@!vqfD$eL4$xXRnPmLGky<47zDhhhT`2+T*r{j-ZATl z_2gCNLinotVzmZ6ow3Vn%5wfYUKZ5z?_#J~Yj5(={>q`YEiXlqnIK`GDzH26$7RL( z9B(=eWO>Ma{HU=P{vEMbgPy}oI)g3E6+A;59KbhMs_`GJ8+qJe!+XOotf(6a)6Vr4 zdt)~4$>Y8sA04iPkZ#`v+PI5$l$o5Pq2^&r9h!AoxeF;4J_ z2v?q!aP5vQr#*2WQF>&z`oz4ij&(!aCw@<1ZC!gIO2u3lmKNcer8#_ySp`r45+&ak zst@lT7;c6s1tOujCD^sK1hGYo*iu4`ElZDk20y)E7g|0v>?}L^+*Jnu#=d9Oy}Wdm z>(ZX=HVP8~V+vSxzYCPu4xNbmK32On#c^a+5C0V5skC_-nL}T96*83Dvk6KJK%|Jt>P+5ad+-l{r-}9{AAo=IY2BGy{|pNZowD;Xvme0O-fe$bo+qM zRu(>AoLYRXyMFH0k@LtkS-$9{I>?vF&O+hoZP#siO%^I`$7)Z(sCUa5HH6D%Km`oIAb1 zU)n9{r6w=^-Yh5fM0P%$gN7mYd1vg&TXa#~*(p;2Pi3E=+T0qN8(fm4j#V_1tXd@A zo~?#_sq4Ba`%*_+l80oq@91X<@gPT`o)Ks^r;8iF4*9Y!wYI>JANASus1`LD!Au&< z$YQptU$M;}!+{zpQ_$D`#2}>6JTqnXKtl)L;T}_X;eH@}Kq21-)B9>Yxg6%sL`sq( z{b0`G2E8|M>IUVH0AD|S(bTeZ@l`C^!kGJ>+t%;6N-HQgQ0`+9aS}6(M-5_?SZ&%V60l`gFcwotB;*GnThBt zUZAd@>@QvrbMtr*^Rl@QI$l!>kjq;DeTG^<>K0nSPz#Hio8F)v9hp26V-kv!_))+8 zHCLaVL#CNV4M27_Zu8tA#z2s~DFshQ5sQP-KR&v(zjp;NVtDx7vc4~_@ZSW|XkNe2 zF_9b}Ab7P|ct&_!aIBu&gEx*YEPj=AaMIbrdkhxs|_!Al`jvW!t~izh9Lg0Mq8|M2}PpsKB3(JLPf zu0RpW2E^Y-XFLXZ=Puz-#5+XwCu(oXm)Jj76O1lQ>4kd@Z7^@s#!)V)G1X zrMoN(s`o-C!|vfrk1xT`jSquiQL&1)hc(?T1BF{`@$&XX-N4(!~2K^ty3z3T!8$OT>ZQ z+6Sv!xVbq{9afw4dV_(5#_V$kb{#M_>AAr%w#8q~>*wP6-5!6MF?Kf0VvYOEFLMSG zxD7(cD>tvOmvEx9XY8%!zdm_$u6nJ$q;4H;#IFI0HWKLUp~bauQ;ggFtj!;-W60Os z6XyO^1OD_SM9O$N^x;NH0PnbtVa?63$5#!+)0Z$QtZC^9^ZKfBm5H}$t~a-B01I+?nN6scTGWXZFBO5Bq^L?x0~twLuv>j)y;{od43L?&y^6 zXp8P>4o%U;s$CynNR#@{fTyPck2ttf@0Ex)O!-t8-PVHinu?8rF0m%4T`eT^R7Tic zIBg7zjkK-kN4e)XAcU+Qx27tRkGit6rAcc(_1ozc+gWFpo4S^pT0Y2m_*H>3ELd|J zBpKuy`2BLt0Rt*oS(USlgaG)Wzgj-0pM5{{xgJ_ zPj^hzyW3dpHI@2Ut&;8yrSkC)F61OmX_HN`s`r16m7B@?%qu6CP^)&2GWMNWD?3Ax zLR-N`Tp!MyWVVm_ZSc`2QkL5yKO+n84+idtmrI*uM^GogS&L810^i1C$pOPS0p?(m zIO*aV-@$h-`ki7-mVPArKJJC-n2l*tp=nDJj1&SNn*#Qx)hatf9!)-BZueq&mE$- z`!#Of*z!|=Q_i}gm(Y06*O$&O8>Z94VL8@wb#QW~l~;aD!T!(Q`pZL#LoYL0Y8LUV zMRC4=+DtE;?W(0Yz=~cfoJUzqLtSm37U`TV&ZBlN+eLbeQ_gDC6M9;fHmp9DlB~FU zBBro^dTg{@c=Ph!6U57(9OS&% zx>Mb+D;oDUc5O2w-kmAhJcWZ02+2?{P&`A9Lgsyq59ayVO{v)lnyCi%-|EDg+8sKf z53E;V@oDDb=wKaI>V{SDvYDYbUT#Z@b^-4d3@d2`_#(Xps%tS2ebiX{>kweXLQJr- zsPtVxz6AEkj;`6~<|i#)UmB^#2GR!uv!?sAa#yn8;yAXf4wF*Q|3DbU8G{V2~CnY>!4 z7Ckx_;AQU~Ac<^@mn7Y`v_&{4#;uJmg@=4{)nXm&U757ynaOW+b3UC|E}nX*iOZ3- zBrxydo|azCt;#XJ3TXtv9H+mmR}=FiHNY-NYd#RX0AYNtN#h$oes#SNfj)^M4K=ps z2cG20)Q!d{0Uv2aG`u_bQkwICV7T8>T2=c@2VQD2_Zliv{!O%#IKCMj#t4Sgm&x{a z)vHCfeo_-~DdA6$?}`rcDvC$dB+uDbPd;6Ou3C9#4#O-tXETTpApoku`zGq$fjqU4@{{uw?=p_fT0Y<&yyp&k-v=W@+e|5%RQY%F2LG7oO5e-)+nW_ z<=|b>xcV_ECL#*^$hL7J3*8=9ltM#v!Qm+9C9zT}pm~pG;iOo75s*hI5~U+(QA;5` ztXVBrY-8cn{ATesx{2aEbKF(croCT@qC}(KvWj(b$f4M2v`CZ=*K=m4AzgYfNv_9+ z-lfGuLl|aCF>GGKjo{yd!N5Ze@wotWe3#1)jnUD=;xi?1I7rBGnJe_tU(+BG$GhSH4IRI7ted($#(hvvq({fBu@uT6r>c0wUBaV<&kL4M z`|`P>DeTE`6%O~-!sXIjxaTf49i?K~VdG`rdha2e+XJ{@_mH8JIP`9(2DNnO%g}*v z;@*mjL>;cs^p44oFwRKQ)i@3L^4Bj&l?EIHqD8_&7)jLnWcb)W-+ib;uWa@s)V8AT zeZq!Y+9RcNmH=`oI#Q)zB?;>CB3+#P;8O|rCz;uGE=C8I0*y~t-FbJ6Owk+1v&x7> zXXCl<*saRSIk)Vko7aL(8d|3+%+=PNqROE|;k*;jsmfSqed*l6p(m3<5d7D41N-gs zt#P%?=pQJt^Y2ftl6OlQD}v+FK%yfZ7P)tyB;i7nW{U|?308pGrYK5cjTYJ=^05@r z1rr6mmiyj`L|W0MV(l ztAg=nb0=XXXegfApeiDB)O9W&xZ4i<<_J=;(N0Y<^;2Z$jVs(H1vsId+&mX{sM1YC z8c5-Dle4`SogbR9n(< zO*Lt?y>d6t;|T`H+MaIp+=;hnb3;L@_T*{csaP6+s8mMksoHukQ2AqFo2`bGvtp5e zDg$19OBrZb)oGZ+u)Uf;RKFtW*-VYr*=cPQJnQ1Hk_8!XbMlW<6KuE&^<7_4VRdni{+4YrVH>QHHY5TF@^u{H1R0{jSD(NvZ#JR@=O0fV)lZK2Tb zD@LOxi=H&!NhvvQ2Lw-*G9*9fH4fQYe5VOn3kpb@l`&%=jL$9UrneYcqy{!$JR6xB z7M+fW2h?1TG_e~Kvke`t#j}E>LUoVU)GE$n*+E93x)*ElqP3{)W9F(RJhoEFe%#Sx z*{Y^TY^75Dp`*vg3aY}lZLn(F0b2@{M1FF8vI*B1QZ{WiqoBzi&N9olAx6}dpj>xD|HWKlgT4B{12)H z?)41DZ~C;;5;74c+zzqh1Pa!b4p-N1QwP$cTsFgrPNoAZTMcJ)-^boOSAOCq19Gff z$jS#?*tlqF)=rlk9)^;F4UhV}-UG|lEQA%=t}QRPh70G#(ap)#dgDU4hudjIi@foZ z7m4A|tD0G=xyiIn)$-nk#xBWXs+@w02tM`vEO0W35Tmu7Yk)oDI zRs}|K%aI>OMUsuOsA!l-XFt$GP&A&8_}*9b40+wz&u5)g(m*_%#Ka?4L^@X8;isEh zeYl-7mS%-6I6Olf8s1%P$sK2o{Y?pWSN3PF&HR-^~B zuO_BI)Yey5rp@9PSdzudF#7mRPsk7wNKngr{|dew?!O7?lhFgCt~Neh%#E?`PkYbP zmM^0;W=heh?G_;I1hR9vG2&6Ax3r#%6SRV71g$!7g509n+So@8dzVn@o?KwAX+umG zrd2_aL(Ry%;rb@@2|LGfsV)L2LX*BZJ2#~p&{`d==6xW5!LKW@W3km~y*+iu7QFyr zJGi`}Z~>jt*L&BtEC3ERFIxDgVWS#gFijz)S71Ra;q`;ir@zIKvFV-n4LaZ!Gk#XL0Gl*gpnAqZ z(8AUYjZ^drJ;4uD|K+~FPUcZdB>Vbvp$n{}Z>1xaQ2&%0&vqUF$9UzIVfL&TV3!2n zb!TJP747;>NDDf%M%Q7$t_x2eky7JZ0eZXy6;-mA9}3J~*}V_@gn#dO6BaK6zi(P0|mF&37itLLo8C2owO5J_Ctvf)I2oy*@W3fZ+)O~6nVwvQ$- zm$ocPpiHDpZqz;yc7;tn*C8YcO%Mjzi9~SjBiI+UwB{ntGi1NH$?XUup4`IMCyhmd z_1t1fwTkc?w>nDBzRrIDL$7M4j_12Q?NWSXM8By++22 z5pyPYq4RE#bW2C4r3#>=mCRonzy0Nhe8!Rwv1Fx$qO>Cglf_okQy|WvxUz!VH%A=!_-T|ABmrw6aJh-yaME~ zCwUjWjN~JRpU>_5^!6v2_O|q@>el=WE;(5<0KYt(w$*tAJ@-z|Qt##e7GYz99&t|w zmsG0f8%&K}T?*}gJRsR0xSXzBo7UH{L`n>VP7WuX_J~qJ8w%a$A^2R1N%*P$)e(e> ztrI@z9$kxdWW<4_;p)XYyks z&mP0Nht|foON@YEx)xaAlv2qOk^TXLvC}KWx#1xGK(;ckeyw>JznqsnfAelLm9T?r zC*fTyj?*Wd1oP62wl#5HR#}jW_b928$DsU;!24x^)a#$^!H=k?+84UxZr9FpJ`r}Y z=!LaVF0EUiuQsk?!;A|F)xttm{69YCCwL#uOKcc-p zQP?CzFy^NQFQ3b*JgM!pdK}8COT#&5<==Bq%-{qg&&Pi?FY!nN9=vK($0s4`4HG;x zSS4H65juPLs6=Q@5}=*omD&Qk^$^1u>H%-DL~%+Y7$7;Fzij7QC60+p3b~BkXZXgvUVmUaC~br*sch1z*t*SuQD- zhy@pFJlZhh9arRY;0=Ki;=i`zH6~?pNwv+-*%KaKyJuOt2X9BeU>@Jy%_?5;M2(+5vk<+G0$0{cxr?zo;1~C57fQ z+huxsb<~%OeiG@df)>-LkMT5jfo`G?T_nG@!0#%pnQvLnt9>9?KM6B#NgEWQap^hFoxT+0F z+W?0x^ClWn!es=-IYaHB+Q6*q?Wq9d85yvx(@1aU79J}j^n{cdox`#Z>7n-4@eNl9wOKU$=-o02AK;bgHL zepaanaf8=>ZB(tcpA`@jogNPwhRQ{mgj-hvT}aPOpgZ|qi1NugA*gfVV^Qz93#$o% zn`6*YZEZfGOWfrm5lhF0$BT-?3)s(ji@dfgq9mG=W+sJ(hfnWQv^Y=J6{YStSp-2% zfT5jUA5VI_q7%E*lOoeGfO^Z6I^tX~tM$+9QaiWfh2`nQoN`+wmfH8_ z!WULmb+P(!&dJp!UP4u>HrEi1!QlyE3zr6pmDy}#^DN?zLc9HVvJ)SAB9KsxFd5aciTS_sF|{a#nMxAX9i$@l|g)vgE+A=E)N$a!T% zEYYZ?rW@m7^+pfGe{;U{UGV&yrDVpl`L3;GC(oRIK?P5~qAyB;yhj?P&&77(?=m^v zy>*sZ9y`4Tddp8hy|O^GeM7xE7ga9eRg})_;nF7F?cRJ=V0k9(LL}GpoL6{w@Ctjj ztDzmuZ0*O$BrMsaK;52*%6ffk!-K?n-cM?W8rwC4-jt|beFKNig`S0%uYmGVobmf1 zzn_vkj7z*0p*<~&&adN``P2r&2Si^^i`{Z@#IZH3H$%-g8DAUfK{v< z&1!Q?mS^3rmD>+S8V_x8rqQ>Sx2WAoO(Iq<0V{(MPj1*KzXtT3r9E4_Ng?ek|JAvS zE&YZ*XWvv0R})7lS5nE9$*kiW3v-9*vdeo5hhknF9N^_~4QVTto0iMQE0>BWeP?Cu z!_^yE`uZ#O*%hf=H;3~^eDnKJjUQ`vk$lCvm#gzYj@_)T+v6ZdJ9I@|6@;LwIJ2V7 zF{3CN@d;Yfbh@Mgx_LGR$VtI+9aHzGvO6W-{#d3fzY4L@pxEvlD{B+E#AGl4BP`aG zU$vMT0s{s`wUV!%ja@%V<)LXpfyg6@y4t-Z>~&FB%5MCTXW3VE#jy0prTYj(qV61t zaZ4)c*|tXqe53}V36<{f)}?}quFa6NoP4=BO*n;7E{h>5SW1Aa)Qw3N)YG{|IP;7s zr@b%ieQHb2k4G-%VBL@0JtEITyTwcz0DOay^>4Q6$5HQ+01Ue91gbQ7XLqKrW`Yhf zf?yf8>F!Xg$B6Bb34{JEhdAW=nr6{bS{UrIauuE~@*!&h6a&4OJL6p!Kz}~eWdXOq zPeH@;HBIa%S4S6chU0^I)?~Lz0ViUmuCvyu)l7|j&(|?D#9Icn!*<0=;p@jNIY^65 zk9seU&6Dgk^h-y0GXPh&lA1a2N_8)@)U9}!7~P~nrDPqLg@T%B<~^~cuqCmjeoKaf znW-#Gt4wQ0D?@8Wt3m5V6d?XuyhHqlT9_XbL1u@7ROJ6#RrCNPK4Yk~hDRR0J?u-wU}Z zJW19{`qqHS+OTQu8=_UUuDV^f$!e_}spW7ZnOP%gu7f|_Q>y&7AVF(~nStUFmN|*$ zk(6vtu5$e<5%|nTDeq+(nlD1ynI=d%%W-Hs*LO$ zQncN!^u8xkr@q{!)*B~|tQa#PNKxg$?h2pF^*V`Ut47?Wolbh5_{;aTo2)*DM< ztUZuAN#i+@aY*O6>SfEe!wp%uq^RBN(x94>pk>1x)2FTF>rE7&`bJxuBGd0z#ramw z-<}bW3wZoJ4%@=5EDk%!IySuEUB7>|i25&*kn(Oa{ZG+vd7};Y&G&dEan%b=q@aSZ zvapJcA@3-`Z2<#RD*a)YNKm7+WX{EOx4!#^e{)CV*MTndJQ@k=GD!-@nZ`j}1 z|02YQiTwZSl8sPtaXlYZ^+%}xQvWk@0f*u8Uugft`Q2Sv5IsEjGA*ssFIgq>`u~s~ z75tk}ev8`4n~2y5N00wS^wfg#ZbJEM;D%EhuPf-9t;JKT0n$(&9Nmd6eeyjX9@^)=c@PC-mL4LO1MN%#@+R#>Bj(_ z=A$IvrUexuu+oww7!-IhmiC|;stX6Di#De38;O$I&=__7au zMumN?r6INQFyaG^iZ0kj@-198gw9@d3SM_6UMHVigj!p*-;68WXE(kg-M%I@LD>wU zIU1_NAK&V9y45*(tCRP3G7Dyib@2){iFOe!Qwcp&$@3ZQ5APf;C=XTxJ>IK({Zz*< zS2ru$@|<&!!F4g);!&611g0;7t=w0o&6D}GbsWI*o!H|bT zio$oACxWXMC#M`!HNzT$UK?K3fNW~^p&E_`UH0f*F;5ypx>n zXf9r!R}VD(OY8YTk*)` zAT@4~p`|vm#JnmyXbDoaJzdX;S`+H@!&s$k zPBN`O97Gu6gkIc7;zIzR+|preL=qWrmy99YCz*5ZwLOZ~S`UMDM*7-bIR>i6VV4wr zsS+D?%aC(aeQRoEXFva~EenW?JNiP1dGV;C=B$+@HrLEOnXNA8$#_f0# zUE$^MU>)Q#huUapndzLfIa)Je@;?dZPC!(|4Xc&MW8V87kGVPMUCN<Qb+EOS{|xgz~`tTuT_$@0fp-c-v$DzW=!@#dG)S(aOL z5*HfZHU27P`qiM_bA16bn-cr>bk6lejoQIL_70ReZuz2wMKZb2lOZf&u;RJ-7&r}X z9E~!)EO41lR|xdJmgP7Fw4~<2V>=p~%iZR^bUb-7#B@g+Y7zdBS=Tj=YI*|D(TZCd zqY8v`7OGJ5W_{ci=GAk@EDHNrJnrKAWZ4hlu@&OF_vX!N>qnM6Y4{}R`y#ZJ-$c*b zy{w0e6NQVO)TF7gCqaj##=YhbH!6_(neJu5*y;7x%l_F4R{U_Ia{E@*r6&ToJS=L? zbUI31u%$Ehy`UOq@VqmwYCo`^#bvW(A-2(8?V#`fe;x2d$?VQl!)D~M^hMUSGK$GN z2GB?I@9sIuy9tLNkRKb3gxuQYno@8KbqsZqbCh%HckFk{8W9{~6fE7i{&pfi#4iZj zxQ@ns#eTPu$kMKnXkVfXxAj-&59af)n#f>=?mtQ-?dUpwGdG2h!P>vbKEdy=zX&k+ zrWo=!f#&?h1A{vP-fI7wu%`dT|4|kByEO6_VYB#i;HCibcNOGcGG8%4?Z%TpSz(SE>A6k+l+ zXDfQ~S^lXZ1s(CdMA;rgi5z0?jHnj@`fr!olGJ-9B%YIUH%HwIl;<-1MmLU^Xv)-j zqOYgGZ`elnfgsVbr%LiUH8(t}H%J~3v!+*B_MDCz|Ld1vc_~Bgr{fP2qk3XqKWFGW z{BcutNt~F{bNc!@6Sve?nGpF8hM7-4Jl=F2I7*rKw{FlMf1F%0{n3|5W(!v6p1(pP~M#K)&aIYw_RavPKntOY@EefxMc2 z!^82|gpv+Nh8z|y;Fn!lc{K@BS=ORo%>R**L8AhA|4{laKB?f+owH+;KmRr((we+DNL5;)(M^p8;g^!H4% z(B|e!|K3(&U!DW!WrhSS&)jej6M%8EAnr_o=5DEm<--OTzw zK!`*!h8){%-VVe18P?Lg)5PHvX6JZ^T1~SihFanmzfL5 zkW<*oU47%>A11&3 z$b5ETzsc%90RB^~-&CgYFTi_CCx@9q{Gv^Jt3W~y50uq#+nN_4hv)yrlsPIe{hx4w z2>JgBXW#T=jcrorgMwQAE;BDMJEw5MF*d2>{kV#GgRFwui`B=|H#gJ2y8qPax+=d} zkN-6JL&q=P;uq$BbxYrrsC6^N-vIygIIcpmUVXEL|98N#y9T#!GW=I~Vb4A>-7>gG zCjZm)b|5il+6wj~R@T5r^8alXFT>vaTEhPdmt??n$AFwKL9d}tUM+E#`6bXOr*ObA zHnD_zT*bJd59bcuFT{U!|DnV6M)_CD{in%q9b&xJUzj%@{$cXl4~gD&*Uc3F0Qe7a z1(`qKe*!X)30B^8+_?3Ktw>lS}N!RTRnCZ+?OP-TjA73fGkJP0IbJ$sanO zz7O4C-gx+j$#1vEI9Z;*ruZA+KgHc-PpkeHph)X^=FJrU7T({iUtlrb{O~1Irfw!EIyEo6Q4_; zLcfQnBf%_Ke4HpNhb~Y-GAuc84cp@ZZlI!MSZW}d2tJoPh5k8D$GKVXtqCIfJi5Sl z?LCp?^dw=Kfn;y+xgsd^X?Z)|ng?f05EA_qiE zRsJb~w?n`p*msJEzL+jhQ!=bNkjxUFYmP#{j(6bNRY<=z*dmy2n#iDp4htw5)(}YM zjL&sIp})f0(PNQtrRN4cC`uuEWxm^k-=b^V}t<;G_o9dd8OwK zIDlcJkUe0UON0R$bhsRex?1%HpkTLr7%`}Cxnix*`Q&0y-*F{a5%*!dMUCl7vZCjc zdy5*|m3qb3hw(P`J=f?QsL5T8S2BEav8XA1D2aaF@}(jg zx#jzW=*9sx(cvv$8X}C_zO+O{x64hUN7$Ke-=ZfHxP9vx(c9a%7>GRHY|>4pyr&}> z&KJo${?V7kJX|1BV)IZlc%1_jO!UmpsbB3}$joGM=*N}MKN3@V%sUmq%*0bh(KI1|1;PjD7|F{p7i ze0`{K_I)vEa87-FXmGB5F=%n_`uWh};Q3+D;XLy5p~Io_!+47G%+Kd34yzvqJr0kb z4?T{EAI3AB*M2_FaOC|k7;rxN`7q#U`(ZrCG4%6!j$`SE!HDDN=fjBO>4(9D^V!db z2`9`C;{{HPpU(@N6u*vWCsWcqzn{!FWqz+%aO(Vivf%vmd&P>=N@wey{{})xWVGz$?k@UuaMo15~n4<8zcUS{BDBy zck;U_;w$8Lzl+mS-2EZ`iQ?}6!`)X##T8}gQbi>x65JgMO(3|tTY%tNK;iBL*MvYI zxFrFCC%6W8g1fsEQnOwarCt#i*l`{>@^+4slYH&-m37*r^> zL<}kwqa*=Uh#8WAYQ)k>Kn-F`B%l^CN>Wg}m?0^sTP&Rv)GxL~3K|xpBm<3$8Ipmf z#nQ<@^I}V6pd~R%a?q-nAvtJMES(&*E4D-qIuxU%0G)~%Qh+YS(kVcq$6~UgNclAdq_HkppkBU0 zKH)fU+z>|`ATJ~u2gna8#Q_RJhH-$xkV71x zCkhM_iyRBpMg^22zR(RDcZQ0^dRoae>MZOgx|}gcT2{4pGJf zYC;_GfZC8~JfJS56c4Be8O8$|Ko0SMh7e4ApfQ9MA7~0u#s`{19PxpckZ63MHKY_D zXbTy}2iijp@qvyIOoGpMg>;q#!$G3@;OU?ieehC{r~!C0sKo$$7$gb>C%b0}dfECP_=l}#JFFIfqQx+YthN+DXSjV(P2W((^paV8BL(lACDH{!{Sr%ppkWD0A<(#l zp%7?VB3%eHFR>&9T9Tj?2CYgM3WGK!(uG005=+9MLkUU|(5Zx>2euKUu4bTq*I&|_*XSJwEF2;DBA@z{Rvy_T5G)vi^bsr>67UhM5P}p0 zRu2gX0_%k!1%pjP0)oM|AxNLV??M7Tfqg=dLckwG0z$yyAxNR%_>h25@b?g;&)^>+ z0iVHzAxL51ijaUXa6<@EIJi9|AROEuf)oKB4+)3>&xasIf>%QVBEh>Msv=pqvrmMn z4yl2nRG2hCaVl0Cpd^(t4N#iOkp?JB6-@(tLsd!xRG=EB0luX=qyZ{ZVbTIssaR=& z>Qu_KKusz~TA(&nG%ZkR|fG@v@91sYOe(gBUBSm}VKRLXQfb1FwVpe0o_ z9nhMpln!W1HB1Mzr#hqqI%bX!iJq!q-jPa*po|QOpN?VP3ASHJO17`$P>I(ED1oje zTa-Zel1R!Rpp>XG=&4kIGU&Nfi!umZ3P}ZoEhVY~!j}qA0TD~JsDQ|&kW@ibQlhFL zI;j9v5Q9{UDu`JMNe#p023@;e1IvIEIz;tOB)|xj%A4tu)y-b2Uuc--~+6% zzTpF`v2yVNHdru{ttFlTr`8(1(LsU0jC z9?%X}2uJDwtA_`4fc3(WI>Dyl0i9smaHKBqyYPT6uunKrH~3?CKsPu%9H|E!A0E&H z{vM9h3;q!v&mM`brRzI# zJ=HS#Ukv9vPPZROo2j~3dX8+IZ!<}o8M;{dj&_`HTS=SQyI2N}Y+PQ3*KRd!Ez7;+m{LaetD6w0tCU1XuV%;B&-BMuzQIo;MWrg zD@PFQU1|vU%|ybg5d`~}2?Bmwk+6CM!NKK(fZtUltQkRYc!?+IhY|&ALl7KYY6$uf zMZvld1jm;Nf_|@}V0{RJlgkM~KfWl~5Q5LoaE($h=AUM0!5c1QBf=wX^&My;$ z{H&s2a|nWq%LySr&nVa;g5dHJPuMRs3Wh)sTwQ7i`z1!fHV_2YmkGjtc~P((1i{Va zgs@+26zl*&aC?a-;@5*wLmXJZ_V+*-tmFCKhdm}E0I9l@URGx0bh7KzX#q2k!Oazsq#{lN)G67(h2`+p)LscxCR+dhm_cf*zd!k>vc^AIsMCJYvWE*V zoIH{z1i`f85yuOsi{$x?C|cU3&wC3PV0n(I1x>TC#k zrl;640s60lxWfgSxy#?A^3U108|t2v>@NNq-V#@RxT+}VNumVrj;lUi9S{_Iv?E|K z-Cu*%B7E`xT>95E{x{XN!le^=RJp5FgS8t{*d22Fp$sS4y$wa|4uz@nklgYCNPay}`5Xtlj{&_>Fkb}t($;^r7c|)R*gT)ZZY%+BAB>TLfsIj(8sC{K% z&(qr*zLZ*Bv!S>zRuA7yt*+Y`*!QgWh99O@H*6>#c+PplFH@_VHUfsH=Q%@3KxNKVW=*GaQr+_b9 zIjwqpL-EWL>I>IStDf8#ID21!Qj-+$4+cp%obB;4{8vxG_VkW{8~&&!+)|Vtw3DX7 zciC_x9l5Iy$l9 z@1rGzl|eKXp9o`?n_*KYR;C*6TIQWh1tcHkf}rZs9yQ5x8fT=9gbhi*3yA(3Kxat% zBwXKvD^QE$Z-(;JGH(tK2kC=>!$zWJ9^}hZ>PzQ@@a1GNAENq0>!&5=|Lovx{>E^( z^&h#>GpSg)93a=u^g+sTq9Fb@Wed`67fS2m*o@qNwmsoyA9`j&U@)*Wf%^XzY)whe zP=BPxjB~_$b*c^-ZWAdAwdJKD@?7vbng1JX{IB`ZO#f@Hzt`^nc2D_BjpRf$$}xbc z@MB`WXd(bRt>`+a`v+1Y-qLq`%HkC$-P7)Vq(ov$7i3fCfPVDoEdaZSC>@wm0;wUX zt$^HcSx<*bkh(du2GHYvAQi!kQxm9 zO(1U$HhFaXf5b-qV~*qR>BVz^lqvDY+V`J91*WNA6vkr{b=fuK*R6X@nf_qfpR`>5 zI+P?XMwY$!Uvln$qjB0NTD??5Gb_$;`2{JC-3n%3RHh^C4VOrC4*8cQ+b5>P{1Yuc z@fjnIkr`c~LQq0&DLav-d0X#0?L-Vl9Ah)-LWR%-zB2Y#n&ut7721gej5sD{=7kCo z3AJVHe46H6y{FoV6pT2gX2FFDF$sLX*yS|MdwMx_66qOn%*?V26%rC^f3fRmn)mg- z)7kLRNn~Z@FgNQhbQyeI9II2#Zl}3E(A%yPzMznjP+QLKscAmcd#aNt!iZyO_OwVL zBZ04iJyg?tq?c1SQHBx6%8af^;b%f^1$&~V`B?8e-9#lu9BVV_B89vJzDo8yP4kJ~ z3f)94MjRV6^CE?!gxX5>T21q*-c#K~7$c6YS#Xg;Spr`bdyl61OfM%i(Si}j&Mdn~ zq4LRpw=FVpAlUzvH5$w&s}*j(crLOZLCyUHa{LesiMLGU&1Tm;f4H6g9>@IWrj?8S zo&M>d|BM{|$QlQU^{jCO=I5;nuy0o{INmSw1wyoXNP`pGqyLF~=WnEjKi+gr7Mjj~ z-?1JfzUNSLG)Es)Xie1Nr3KqK+M|DnLR20YT;I>}_+8W<81O&Ly(o6Szms?M+_`4CJ5S=SIZZ6K8k*X6 zv`Hzhh08ZTtbe%CQ(Kh3xx8tv-5`S39WWv8lQyo_<1VJIx7`UQH)fBn?+!}r9&9%H zZ1%hqlNV2Jsym0M(=Kk(nz<-g8W*{CmbrXyHT6qs;ZPTZ(Bzzq@D#1dev%7$<>JEZ zV=|qCq`RFjj~@$>&-3puUf;*Mo{rd^>ZUbZR5Dw|Rj1y3@xA{d+`Rt1`g*_U?lhI{ zoE)+76VW)g^X2HBT-yD9%J!LNibLbRchr_mDq@8FxXA7-q;YBVyiNn(w>{|s&VI%; zh`YK`)TLgv|nU%O1*y2Xy?~++2D@4NCnfoDU8xXz-|`2yWwdDH;tc~8AvnZL}sjrX! z6XCj^^gJ7NXW2?QC}Z}$zVp7lpY%P$I&P&--74Z260d4<(-V4A-0*{fx%M3DvNX!( zwZmKQD!e#rf6>hm6_2pr8=5-Z^Iq$gnK*(UoohY_S~nPYHD7!Qg?l^HtXDfM^NDm` zyYBJ3%R^yack&z4P&?nl88L-i*EVJt_%1Li)XO6zrPI>?v(~TzmhqdyEyP2 zs=J%j^Ds@D=NLNJI)V-v|`7xgA$e0VuIr+I&p9SdDrcD2$_uOslk>>$nlT=g9xei5bXY+ae zMRcP`Xa&}#dor-tpxPEjo&fbb*=Ay~Eq}q_ z>Kf*gL+_XI@Q|4wj${FQh`4{?xqc`ShW_@px!oRv-SIB^9P`3=X*J*QzO}aq6odSZ_m2oGZ={;SD4LoLpy!*Vl_Jj0qJ4$Y*pB!LiPNm4-yRa-W zq0cjP3pzVC^HWk}yZMyx6~n72=9XZ#S`$is?m@%u8&()NXYjg-uZdP#{b@EkC#+;U zeu>v*-kWXs-8SzMSUv_el)Je}2s8*S?-NsDNYw1-Zcx{6*iGygd_8Y3V$TmnMXagw@W;FrF6<`|-KUw^Mgyy#^A=5zO@ z&+xdj*nd3G-!*W$29@q0PVLL@Rf+sxsC2IT5}gY-LU&QfG;l84eNqJsY!3MH$fIsx z-DMc;qU;5nTC#*fjM}S^@}wiW^-~_%qD`b3>lOKg!PB^}QycVAcMDv!kL?jp&mPCp zyLcVg^GS^2aYTCbKW#AdX&eTb0gwCK*Osp}6qo~hURXQrTtulGlQX704wU@$ zOWLsHy&R!}-yP%Kwif@L7OX(M@w0FVgW}JE+lbz@yxZDdnDkZA;KP@buwqS(q&Heu zBncvFS1t)s?uCEeDpOY@A$wHgUV3dv{a$a4h3ne&zMB6bId`0AyQO4;66Q;sa4}R1 zxG$u*A8NX2*6-q2ij8~xD!Jt|8S>u1As8r<7V-hA1|)3uCgT?=9r}^I2b8bu@?!~fjafW|6;eWF* zu(qS+mnYnOd*~$RN_ot*wO_I^adRvXzU{5M^fTcw_NJ*)*Uv@b3hvx0 zKXgNG=K)1qgo=9L4q@ayc8>A<`0 zs65$0A73k;K=gVEKM$%`ylL|Pq7M&@@*3@vnY!6y`P#oyAhS#GTcug>+R0zu0FL;o zw|9(n<9B(x=2~O=j6y^7sA@h)_zE}E!LsE&xZIg7c729OtyJkYOb z!lO>=+_dWK;^9M7LSF_vIXRAjIW8ATS7R}&CEpIB#E)4v1mH&5uqNw;VD3c`Zt|9Q z^ZIb^ndOC@vr=TqFj9b+4aWH?_omNSH$!z*2yoc*vm{2PD1~{ z9y0&cXFCmO@h(gHyyGe>t;y~DrQFut`AT1jPmhmJvscsNy@%43AOB!cJ)DW-BBzI~ z@mZH|R<{2$wJY8N1l0N-9{Ye-KS46Txnc1;tM~yii+(r$+K8Ns?f@pT=+LZv&(+tw zp3@0ndPrJ>mEYQY@gJ}&xIQkaC8oGUIg~v34SfBO^iZhKYqHk=42pPsa2GZE>Ob&k zG>=ES20O8T-E&-`^M`KCucjWwYp^(Kw?CCm22ZZ^8A>Js`}fB` zlW2Dl2s9b|Rna91x&L2w^)I?CZnrB+o0lbBM|~n02rYl{E`Nc@hn>f&<_CpH*h3;| z^A!hQ(^Z^MYL?dBSo8f++QTIUQFA`&V$pw`+MnifJ04m07t{W?v8J_$|7|V*Ve%W1 z6eJuve|`Ec{JTnA$*bJZF2tL1w=7+HdnZx|!YJvl=}@A!Gd6GUG38nKYx_l_9w zU6XX(_p%xAuFrKrHuc@(cOtbCN)H%~OJ13zsdd9OdzwnV=>G_RTsX6O=WIs_4_6t* zwh7Bia|cVywID6utF!F<^UrV2KYMW-cLxgW4kGQGijjN23PM{4=eH3VD~;d`z-7hYVY>R>pWQV zylpC|E^*;Utgj|cy((?J6wggz@Of<2xdhrC9_=2j-5&PBt{Ls#(dU^Ih8f1sGmLdJ zjKs5w3^UN}X&Z)_%KRCd?U}F2GX`p7aODZ%g6zhhzZ!qmE#zk}WaaB;6*p$*H)hoN zYUniyWuf1C=?jeJ zB}*;xyJHh4udp%bclgRFeoi%SW5*WLTZjKxrIk?jS8D&fDr#Ws?vJs?zsDG9;(vVe zcyw8ehmDKoyRfu}`?QC%MgND#NPyyDtKi|dTEwgI-xdBR;**t$l>=d)v$MsA5|R6z zgNGrlhc$;jpM2wo>=K; z%6C_Xkk?YU+FvvNQmD#V5E?wqtghWk8l1DtPa7(pkH1li>QCxYlPs&uVn2K3eDh7H zl5NGV6Yb6_jRW2r;vBYNqqN}tT_ti-5WZV8dgNAdp|bA;abSY44@Xfos_HFRsGD{w zM#|XXQ=AW6?I~wf$OR_O{!;g?-m5!1Lh35A6M<)TatVibMtycX$ebM0mv-0SbcT}O zEgf;M@YL5KJPJl8Ws;>dqN*)_y1jclH4&xBU%YRZ^W=10?d$wPZUAwfbnw8Nhlw1O z+AGVU0Z+lLbP6h)4L5c1h3QY^(^*^BPFZ3DkzpO8p}UDnT(hQv9Vg^>_z0TL4;?V? z`LoN?C=5TnRS#^D)Oz2;tmo9fOoS_CpLxCewG&fav{O>k-sy6qe30+(>BKecz$Sd* z&dS!S-ylztW}novQ?tgc#Ob1F?aGU>eq`VJ*UXvGcebbu0|ZlXZra}Ju^_*=NxuDd zFP6TipmfF6k%B(;D3L?uwg8FsuE(|IRGylbihpiNBwJfzF*%3p-mdj?*S3-I^3E(= zFQ+hu_Miy~g`Uyza_lWXDe5i8ajrG1m!x2|j2GOx4}n~lVB zD@38T-+OJ?r7*4iQh_n0jIfizqoT}Jc-)=4g7aK^J~GsYbM~m*UKgi+hiaX_{6Noh z8;g2xQsr3`YF*ifqpALU?S>BJNnim_j`7*Iovxva+{GhglP8P*<;MHE-BCw` zjDBOSFykUPr=T&<<}5MQ(BcvGVkLd}W#^}+8N?SE5gGI9JQNont+3)6sqJDpfe8~m zN#IIOu44vPB+R9V=!|#pn;zfnO3kYJ8ZncaJF)lF`Doqt?6GkD_C%z)Fn3;$a8*}e zr=>a>72nbbRScAQeWEN`igBln+wGitOv*TC?&^%qKB_C~@n1f})V?car&3?aO;SQl zKknuAcTf1BzV+3j4xBr}uitR`gzq^PnI^-)UD#Wo1xBGD1*!N@>bJo8EYpf#vNbETkS;-enz$FGN~bNi>Ke$#yIx~i#WP;d>Ojz zWF@2+h0b?Bo9tKoY@YsWK85kiZ%NEgrKhOeZYweFDz)sb^TYU=$QRrd9BCH>&V_xy+7XUQ&8K%%R>>AjRS-(o+w+gSXcT@H zvG?v%@Vp!94WWRBi&0p%;JQs5i0hNIs@eRB#%tX*!Tj}cbwbTV{%oS<*b3snX+{%1 z^DqcmVzBsY>9|@K+ug3@jUQIBmNHQt5lPwkY%=mDUVFNk#=j%ZEaJf9nbP3vx8Li^4+D1Ve)Z5Cf)2NYInk?tMbn`wcR6Ca0Je?X_>bDZaavJ zIWn1`4QtjGvFIcp5Z}fPt*wNMNwCw8gDK92w_?#vt~<73&`LXBXQsqg=*3-l6yV66 zfBV=4b+CSC5)tYv{3Xe<*95(sCQ3Uq(us=A!Nhe@BSkieSRjV`i-)D1yca8mCqg@o zd(UsOq81;Np80%AQ3*>zjVEuHyFvi_%vOg{C}MVDdLna0SC_iPCLCZ9e#H56G;6!Q zxX3Ws8hSp0SuP&3pzh=_OVLI5+q&;_J=|*|vWc4FIvc-4Utg{3zQ=9+*@ve45Ie45 zMr6B!UBAJqsm)}By%{F5#wbm(ewu2QL=UDvcC| zJ;viP@~^4!*|$)#o8PI~okm0yvsFiKD{9b!MiID+w9^=~?3`JaeVM6YPek$uJ6=oo z9DyY?5|hto`8er*(0Aa6@{f(ERG6hk_CvOdsxKw5}gf|Y;#Qx$U&1ttmk-r}NJQ(goLXoM-JJd-zO?NkyT7Ng~ zoc|OqDZz*%6=DCqUYdyB){C*5LpLB2{{Va0dQ9;Rv&<_t&&Vi3f=26Zn^ByM7rvQ1>l!#@lglQZ7ghK%TDX?ktO^HlZD5JObQP*qm{L7O&&f=c^zxL zE@pEzv5A#cnRcjL&f@K;+PSvh9cq1Z8(wc)nfXrM9EB_Y<5QfUBn0HMug#Te>&k_bvg}!7{MTGLt(GKm0=)T8lmm<;~kvKd0N0${c31GU_L1nq>}@z^!tb%>?Mta&42Xd9a*PW*j@15(tF(e-0`CD6;q2lb=uL@|K%wEWux zt#Ih~bKSYfI?_gT@Yv7Hy`(2yAR%%;>p3%BrLB30c_K|oR+Ncp=TG-2k}hjq@z#C8 zh_~oJvPw@s4dYAvj$Vl5Rxvh}%uv)l7|(Z}zp;#gAQ?|RCLtI;`UHWwaf4~R zUA9eLA89|C`NSk}L`WhkoF_CLjm^czdLCP6;it5;{FYVHb&EHr(jwwZnS=C+58>#& zMo0FJ){j9t9dFrOw3n3U=nt%f6G5T6AXqySPXxEzdr1DaV%#O~*bDa3U@(I1-Nm;j zOwaOms4BkEsf+|;mRrb#Sj2=735^G_*{goRD5BKG$Rkb=&*HH53Lnu=lluj)bm**b zRs5mL*Gx)I&OzHF zcB+xb?n%++_mv@B82PaEuE$^&fy|EzC;*CXwukOkQk%06quCwqk^CJ@94QB7I!1^(PiCohK-BJX_sj#rbl^$ddcG@a{-kS1jk+NRTo0r2rF zsdNK88tq_V95);r?H85|$6e22ky{D6C6T1->IM&HE09&N3)jTkKB}VU5w|9sY8E&) z=Di4NAfk6$XnVh}P-*~<#4lJzRVeHjjl&!&!yzB=^Qn2(?}l1uqQiUt9KZ!fPheDT zVz2qufkuyX5F)GcFlWx;$ z>=y&EHRNM z;g0SplLf44c=OU;p8%zjLH&z~VywgZSHY6DnVz46W6-~FBzC&7u@0iIz(@;= zB^8#@2pw}Y8&JH%`QJpMKYn=KkTFqI_U=h5RA>IlvK8CsE1KyyVIzjFabDT-L8_79 z&%f}Y*6DV7CZ)I?3SkqaO3KWqz8lwg%lN*Wa`A(`G`R2RxTQ?L>Ht8r9V5TCf{bzj=aYwi1_w~7HuNEX!QHSU4y9uxz&yDy6 z{BVf3AWukLoqJg8%^yZ!v>&^t;W?7OUWG%k-%8-C>1Vlo7d4>Kl1SdE^cdIt}1)9fMXAgj)e>qvL)h8AXUJ`p8Ff|e}V zV!xSHkD{@E=~;^WqZ8wF3Vr-ZEUB7**n~Nblw0sO6BpSTAgAZECk)q)_>w^xJ&gnd z-P(LyLBCUS-oAfIW_U2lFEJx=_jXfa!w$`_)UD+%^l3!)PROe^(RoZCx6&sY4EwK@ zD47aTya)X?qcX2VuwvYh#3+x^8%C^SpOHzj%xK~xSJ-~~`ch7blSz#7b%5I-vvS1% z$PZ6Ghs%wGsYO?@Nb_4-3{=Jp5w4H)#JBoLLCO{w%cx+?*_S<8Q4E#ddGR)|Q`|m} zRenhT*~vPYHQSg~CNA7Kp@_YzB?}KwRsltR(~(#YBE_<^*w^qbk?07bp#eLzn4IPB zsrP4y1>Pez3ppk58e_@ByM$GPa=v)7h7LX$lQF#(b z$i;O3oRhL!I?fU|Jl2#tCb<|!KSuhURDzQRoV$bs3|FKk&y&jx%cERYY+a%YwkI)W zKwcp@d6mS086RD1SV3z@%szWmHKAl0!c8NATULwKS&N&cbb6{-G?Q#iu4aF#XBab1c4i_LRg^ zepMa>G2zf<j7+qV|=6v#C>Etb{P zPzY+j&Oc+wmXb;TApsP{(tH)|^F;}lMM+jWEU(Q&w&B&R>fn4nHG770JB+pH2{)d7 z+iy}vU2=9T&fkMG=t)Uoin+*{At`5t$mvuuI=vRwKat+7q?!j5y!xC`MAc-A?RFkt zC|PXz@M1tATJMdz-Jr#6y61gt&1L5ElOp{M0iasG?EA;%crq9!T0!Amp*tXwm#I}c4 z8Aw!+p`x>zwSCK%Q<+vHEqlW>fzGy{C4m(4^egUHm6#$$4Cji)L0`9a@3#4TOaFcS zz{+}VCE0I-TEJ?O{#22J{Y_rzTNX#m_go{?c*_B`82wnPyGA&-Jk?b zmvL{>YQ5CAcFyR{xu(4&4zvwIL}|HCZ)8>e7WVDp7Q7 zkZVr2BpTf$I5(>B2jIQsApjSrH)3*s9(~%Kn6-D1zcIo>`DbY9gyt)f{FG)oD#`o> zHhBqZ8RJ)EaZKKm7lDd^);z+@7F;e{ji>U?$n>m*?bF}HGjD6mp0?pHLMS4>*piJZ z5rg(dZv#gnn9K9vMtJ3-bRGIrD zeuwq~+#ac5NH1v=aRz|*9`zB)g-1leEKI3h?!n4YG+EcoSBU|VVQ8Y`=mKj3%d6=rT*VQCd>#^AnMMU>U@4oN*c zz}7zErzD5Tu7$*psCYNqJL4#^e8aDQ*t|S&>jO&WA=G18Bv5TKX zOrd1`H^Z@Kbn%%cC`U%IJ7zCXzxWxSq5-~I49gPn76x`@$OdWE>q8NwkyOE^TQ39*G> zpM8)u`u66xs<`MU<2<3XP##jKie~=X6T?2d6S;Y}picX43LKhRK@LQ)5EJg?6;^(L zyijQ8n~kK$l$tIg$uap|s5ld!%br<`I%O4L4>H?qeh;lANe)_#-#19GV05;70UO9u&h=O5ET0I8z>TQ`% zV^OVmu+jUyk~DZQeQ5`td|xXgqaOGY?cOmgzw#xpmM~V{JES>a`u(fAC2p*ECdyjN zBhk!`U~*r4Z)qgQjPad1>kNJoZuQ@kEd8;Fh8mC4DZgy{jc=IA(}!zgc7p-qHKbN# zyh{gU2JiB(I&O`NAHN1=GD{>dul%<7R#5>JBY1i(fW*S&oRHe?*@AlDvv!zrk@4oC zfWOx)tQUo2J?26R7Xj^WU%ELn(jrj0uB{O4++) zGiUR)i%%xWUcJP*@nMZsBSE6-c+rY6n;BefO^l>9m(F&i<8!|f9yBDva(nthIa}NT zHE39jZe&|1&zN$CS^qI;jyJ@w7w8Q$p{9|3CciLk$HQ%-l$tF#_q6rZ8*Ha|zpBwp zG*3$Bgy4l3mxK=qiwX#dMA-y174%y4mjv8aG+_d4sjWWpv5TV0(_C&6>Iyg~GfR53 z7zBo5YzZ3t$}eAk*TK?~P)cYt?Ep~_aVG>-bcxqVrF=`b`L_M(DMdOhkDd1Qr%`j+ zHy?oXVB-%KNP+w&bQ%TKC??SN^QKsnl@%Zz=-M4-;I+bo8x94 zH|k4O80I?`yep*|(B+){f+XA(ESt{9;sM;n9)gK8nuuG-DUJA1q)Q_(yYyo6Y)oFcuGKCLMUrLZ8%Nh3ADK&{_ z?#otb#rn&=XyMeWK=1CNDbbaBx?XI7_FPQu+h%!}&ikZ=QMkY5@-T2oJD=Ah2;iex znZYWtJ*8~a!pox|SQ?jN)oDejkX;)_ef-N!Ly&6wUcr7nUwcT;o}WwIu(bsp2$lcz zL6{W)v|{`)-5Nyy1Cht^BGw=XhSuNo%Yv?f(EU?Hrx)9v!)l|ZvO3S^0E#&`sHtz3 zh`jD{W?!!%nclSX&z2=?<>JX`}mi|CFH?K_9~)dYIvKqW{aJ_DS=o}0Vks>k!B8%yF~Q>EsmzHi zqN)YBJ7ZlM0AW`)$ypCAEqt!Z@R2C4hL~g?_cPldIku4y2Nx=E{kDZ+&dh+@tX`m< zckdXvoxAEq-!}WSnAVopD)VqXN-26^(aYD&_}c1Uhk>h$W^M$9k-m<0%YfDjjBe60 z-Jtmfx#3R75~|m^ua1&lsPa!T5Rqx<>^%W^p`z|0Rob_QL_U!Bea+2g$Q_exuxFPC zM|1?fD^|hVv+rWavmp9S_l%|zxi4U)yL*Z7-bsy%+1G!b*`DE}_T+Bz;jCi$bp^^8 zFB$UXq|LPlrLYMPTX;5LV$g6b__zSpd&m=k;6Yx<9+2&Q|>q|h9? zS_t!KCMwaYscP!mn$zz{CvPFpt>f(Lc4?dq8DE7KNj--9=cg?z{g}@YfFwUm9~iF~ z=>jAw8;99HXPR5Sp<~^f*twEFD4NKuw446$Qf>OJWY0re3-2KObk3yzdvHVC%5K(( zl5V+@zU?#$eP#{bS4}AB@SXF>D|&)EQhL$_{EHBNC31GqS=I3Lm>NMHp_bLP z=SzzmZK0@>_dBELqu+(Z3f7oVqlTgUuE?|F zj{|3+Pqx|x`IbA}x5d#BCHj?i8bw(A(|H>%cr%PC?cDA4Ju4S9^XZ#H-(M(YaBX7g z4UMhJk{)E|?6KbnqM(Kj<$TQZz+ii$HF3yhmq4FatgrQ=mfjkRv(UPH46|%@`?mE8 z;FI=aQelF-(BSOGssRIDEvS@W?@SRA)pwPVY4eljXjo(M=@2G{%CS+alH37)f(Slu z!bGlaAw`b*ijtVEj74r1kTMG3xT}=&DsUR-^PJWCyqS=e5)XNeb|g4wr3{{%y?vTp z$+rD#>x2$fH;}S3f3gby0^`m4$L}t&UKKmrCe^mZ85g!1x?`1qG*h^M>k;O*F*=*q zIVsE0cR)#}^7ATHhomF{{|--y=f?e=dD38;_HUBk%ha?Osxiog)V(wY^GtL7*erM! zgb1>W^Cl{?IkT+{KhO)5m}Io1MJF4N%vOxsU1bYck60hG3b?A^=FnXWe96l@qoJJf zI3#RTOKlx-DV8J5bnCy|JZBC)TkYrn%3AnDI;GUgAec=5)+;A)oZQPJSnnl3WyC|6 zW?ij^uE#z$?3nIgN3pcEY=bj}Y;IGosqkn_U*3kYnOMj=(Tq*+3DbCrOp|!UX zXp@0aU!r}OkMDC}U4KZ)4-vCj+5Vw`TU!;I*Yki_S-Us%)QyE1A)ic2Wal`*;(WKTadeV(-A zwC%3S%;wg_|G@D*|3@WZg`%1ddvxN!``AwC*k`=_;~vw($MBw`9VcQV9rNwW)ST$% zTx@^G7|O1}QJI=nD|Xw2#xE)E65}sBQ}uP=*QO;b-2i~E72GDHT5mXPlY37)!Pk9m z&fU-6n|ZBP**Ksh6RS$L zOg6Zcdf7FO0atO@^>?Xwh|J8HA;}Oyd~04B&yS@5rIz?3!|cjYOz1O`3`iQD=6nE> zg!5!%pYUsa$fU|%=Lh);^lil=FLh^^*))!dLxDG9-)`E?19BHt2!Ssm7k=L8bUxz= zPnel$2^Jm?(*NRBmg%s)h?H8%^sY|T*reY`kwLLl*;R>9N5)Kr6&SfF`CdlREx-S1 z&IqA7d!6uXKt&RRD0{J!CJ*Oxl5K^;w@1tBbMksSvRwL;Tom=(mpM2{TH^(|4iW{? zDV^D3svof}Z^DL<A0DRE7Pmg;nPqxoc!=D!yhK&1M!^MaO)h7>2&?d zoV->yOJvoSL(o@2m31j}eyO@Kd^pB*wgdLQ%6zLbwdNkxoJmzz>AMl-kvd{a?9HF3 zUg;sp6{!qywZIRgGBdst6s9D z9F92vxUBopoeBN9G@BHiqDQ$R10Qo!h zCv*j)bj|O+qHvm$2_x5kON8`*Ln+sHo@r?%f0x9Go?U8<>|K_luSlmw;NUKhvO~UF zq&~61Wz5D>8?zGc)Tu#*qWNJe^PfGjeHaOl2I9=ue z@^q~|$Z9B|HU#3$Hf;w~(e>jI({<+jOF|^o?)zb~n1Zfc#_v$S9YhxBcQ&`kl!76J z+6^+VLy@*n5kfc*q>sOiJp1Uy#T67n7N^Z}h-&T;*hoDo`Ed* z^+_+96}1E;@q-lJn`e~OZK=ImQ)QbDnK!8mq&KpY(3Ta#8issvG<;rEZYkG%ha`}Y ztcKQ%Q|4*P^$H)q@jM#uZg~dfvgYV=wbKeZZ_V#GJ1RaNewV-yP7hH)d~$e03lxQ_ zMVR{tf_C+Dm7-pAmwE2#YdigKvm@@bPo?{-m`3%`MGDM>^$mKmDLhwkCGyJmn44M6I&bs7b-(t4NyL! z7jh^AqR(vVK6Jpzr%wnJ(!{o)JT2o&-yE+opu|mnom|0m^5iDaDl4?I7HlPCL|EiY zj`dCgY8uG7$7Cc=R8N?cvQ(MAK65VqZkStt8ZRrc;-suL%Mnk`=;B!v^{eaqi-hPeRs)||D zN8|-WfFU|BsE(^7H?`HDE31e;04gXmXm51{ol3trYknmVqts^`c>8$^8M_Lg9yF11 zn1tR=<*5F)_dB^jfg`C#LDaU*gA9?Brc@IX3L zy$6z_Jw35{!2j!5pz=Gq-o}&F7vTkR3;+;m-uK~jrN|hoTr`LTl)y$6H07ioW)`Sg`!;PpK;iGj@wJQ1(At3WJ^yfG zu?p#VC%q=mMAjj*?C0sw41xFT4&pvnvQ(FbAFw-DQR&~FIBE571uxepJ zn*i-iju`lgYvym-Nn#0S{gp}(<3R99u;fydnBD|Cb4Av4g=uTr(3*53>;YU6Wui-k zDhd3MoGN)#M#(a;Gh9(+1i%)Fom4DiABd34?$2)j+;^a>UkvR9KS(ZuL! zOXd}Gq>X?q4RfF~r;DBChG}02yb3OnQlo@wVnuYMGR5YYL~F%KROX)?p_0bf3 z)U`6PXKXUO)fzg1^J`K*r2&AkgXLO3g>gbnu%qWbC-_(l1&jP-jTcN_w*0u9!F8$g z@v+rhWcl;V9`(eOwB*M)jVEW7HjpHdeEJDD^4zhsiiXgCeyZGT+CK8q>|iCCq%(Zi zbALzbXtHtAj+$b^nCzHZi)C;+^xk+=9VJb`leMgdB~dk!*P6PVvk^qKl4Yz=gY*gR z60k??^U!j;yfq|ks%&f}c~xW}B(6PM za^#bWMT!=w^a!(mrkppEirXPtLeAS&hm8tb(yHQZDh!d@-)K**7ok}j)$Ayb2YF;0=`|z8;*Ga%bRQ zu_o;)<|alzQU?%HU6L6qi8RZ0x1-s}P#_HBVtoO34_W1GhpNo1a^^$^6}6mwjbH2;&Ts5qUA`=F ziu>~^L~lER1IBG#cfjODYZWG9n+$J?=6zB77PaIiX_^psCv5oOmO^CoA!!h}y$O>g zwnMlW%5nhP(@hp3g}7U|r%4-gq7wAv} z)>biDB*+8)0wSyM$R)}^QRqV`A{?cP%$4!3u%?%?a#4#A;CrG@{7-f7Yzp*@=T zW@2#dQX+=vo*~U;$YyL3N)_Koxla*uZc|ihi6oYYXP^>na;`{vO~Mb(nV3*T({BLe z&<2{BsbN0BZ3~B}a;6dt!(UR&pQ6{$Au0rNLnBc{VVsbpKxSY~nTI+$TCytzZr(6f zahcOc6BTGAV=7=XRW)TAqSUT&H}oS3OJNU#hQ)aH2^9`;0+b3#aHbw%6_A|qKj&J0=ogvIFz23O`3 zk~IhVCeIrHddx^{KPmuFgXL;oG1W?$QJQdc^@&*GAv5*_bLv1_#&)Dg^ptQ`(DNk8 zIP1BkmM@N@U|g#A$r=qbaXxPoVZlwbl#5=DKM_?$n-0jOfgv2xy``w@c>=J`=I(NK z(b}0dDv(SyH&RnD1l8slz@QfOET5)WJJN26Z9l^3@y-%m!0FDCs&Huj-m_}GJR1$k z3_cpQQWbYLDH(6XrFM2a+t{qw7%fe!&JuQ--Au^0iF`U_p%D_jseK|&c<{-zh|D|& zy*Qa=;|!)uu#N~W63xqg80htRpDHCqn)=*kXIa)0B*FyBWW){vhd9wwxP()yGA9Ml zODcS%@!Zb-Hn6+X?lTY@2F6Q+rQ>}aw-A<}>(QhM#m9&x*Nf`3H_TZM*b|Hu(cT{!kpw-bYHW z4N23$nZR={RGw3Q!@d*+bVJM~s(_YN&BTV$nKTsw)Jlb??HK4%2?hg?J3} zY2t7~`jD;Y2CcD)v^(J$BYWi?+dAwO#?IC_v0}j-M6w7(e9YNR+E_vJ-$1Lw+(%M` zPYehoOvvij0GZi^K{G2+%Lz$|Z@EOIf{$Lnf2=%J3i>8!WfM>pBI^f4{V;VvW{hh| z=$Bx2%8_k~S|gjof{8oXB|N3ou)FlcB||$UB2>662@Zzvkemn^VqGGW1FfNGI-UK)l;qVCJIej*{>zt(GbhTG3 zEFqo(Y07UDKr@;YC+;B)ZRoj&e3~N2K+xe}mZtc0VJ6nK^>suo-19pw9Hug%sN*VfE$K*OYnO@5I)1fPU<-$vfK`ZtB_#L6>)ZCy=wBw@%JW@IjPx2p!wRr-|2yE-u6i(RnE{OBxVxP;VeWLf?3oF_}VHBLqri68eguJ3-NE0V z=NA?WQV7B(p5sZl>ptz-5UU=KplmgG-0NiJW6g*dAMwYmO$~Dpoa6CSUD(R zKmoxOPqJa}AMq^{T`zPTYS)YO==nL=hy$r$$GOyZ|^L53fY zutqH=XqkZY=@FHJ=-j!;!T9Y4iYKLnSmI*KilqhNyD@P?3@ zGz$W(179>WN*OPZ`th4XSv~(busknd;i?V5` zDGIqL(Ff=VR}rBn8=z%Rxj5}qF-GkOtkRH@UZ^tiKVf^P?~q~}Ml}`ig(Vvix?}k} zfIQQhwxFPerQeC%f+FE{3M|T##Nr4A5|HXHz(<>aJ;82=o6;t0wN0S`id1wM%M&re zV$%futJ-j}K1nR)SiupcT;Lfdu88eg!H5~NVO=J>ne@;m04BlsVIg zBrnX_yi`H0h|)^fd+m!c7y~(!EE+_rI@`69IEH_kYSf$Cw7e-nq_4;i5Y=S^v7&?ad#y?mDe}fz7)7o zvHv!8lEN%y*hgY2?F7Tl>lU)$RfSHp%q~L^#MpHdU#3!#ok)%CIgVo^$O?Aq`p`I& z06`>W30pE*A=z_)YdA|~u#;1{5>V_CBbCn&zw?b4ik6x0NO?D8mauV3*K^BTdlJiJ z;PtYdebGA)t1zMp1fbkGqzLTwIkVoxXFFs5Obih>q1P3&m5L>L0f|r)s!4!xA~zE{ zinp4P6n7#|;WwY1x^c$FR|KyL)4f8lIPIQfjG4Y_XbU*aul7HSLKen=8v1-=(om=|GC#AhO(LWaEk=gyI*Y`vc)8#W02!Q>cKR zURlH>MX_}`g}Gdw@|mQAE)!!+?T- zql#D3%}F((SqS~ddgR#{3l;xjcFvPXp*tXh-1rxJ8xK27c@ z%kU7HQ<=Ercn6@xU7&6Z4*$Dp8iLba5^C73JLRU>$wntjq zt&&l9N{=SeOC|g?=^_-q&k550Y<*q`q!a2(#KH7VYGO5A82ZGOSxjONEf~$YGJYs` zTVcf*gxRm8MNzul!4jrCK^u`g+Y^~DW9jk?5Sb1dPUy}ir^Q?poBRMd$%G3f zHgN`>b~ZKT*BB(2AuQg&@qiGMgo%;eS=XSb@a+-Wb8iGWVm!d%DPFB0PwiFYIU#Is zP^S@D8-kKZ(v^rjfe40f)3g#zLgl+-FXp5_&@c|UB=(<4P|{7&nmto&6vEF=<2J zu3!k*2#HrT75B84lU<^srwz#)J7JczVeXnWm{TeJ)69Hea?p`}QrNK+BFwcEW=xFo z3@z>-)dL0ZYQUdLhXuAXs-R4kLcEf(8SB_F3ab~6z6t0Hq+QZ?S97N-UOdg85+e<5k$7??&9~&8R!C`wNpU8o4NHkw zqy);F)>)~;tk0McoK3+&?*$iRDiy&AU1MiE+i9zx6SwH{Y%Zn#-G{Hf{`>#+$AA6( ze|+^{{x+gHS%&u_MFMG^6lcE>L%2$+GrSceiqb}=W@5^Rr-@kooLTKGJzFA zpGkUZon@F%uS9%m#PB6emXjD$A&qn26T_$IY1-%}L9gUpjzyut_?}Y;5SuabC-F4o zz!F6;h*KLeBFR5XhKOmzE+zpG;o?Z{6YU;51tFj^_vgsS`2?!!T1PW%l_JS@S@dY- z+@AwhH7zBIY^B>MXz#8(oqJ}&RBr4kl}pb_=xLh0^I#=|ZV{cAX#I^y_#5fK6j$8@ zx`pX%Cz@>in4B_`TG}}hs>eSn%uE}U_H$*e|#%+z}tkzy6n zZX;rpvvWIHne3ckyAe57QNfDRlB8YH)aX`jaFh*6^Ge!6p4@_o*7F$yT_7+AN#_KL zBK43HYCiMHH6j!i(y+wBty`8M>d zyi*FMK#IjkLQbhy1a{rg!%|r+1mN%Kvq$ow%6eRgHEE;`nuMq#x8&IyjilL11zJT} zrpacQ;np2}*YNlwENdnlB!cWjLEZ`X*)dI5AlXK~LL(BSW2uyRE}cZAE|9Lk8|a!J z(*Caia0CjtN&m;IG6E~$E5YbX*WeQ0VAZIEXw%`*X0A+|P#{J$<=d2&Fup72zV17aq(zPEwSnGzhJYQTU z%1vNKR~vK_s=W_QwU z;MtJAIOrde<(-)u?@pl~+sAZPVPMBq@xYSCInnc`n zV)I&tqpelImjJbb%cls`-ab087;eu9IZog^MVN&_7bqqVWDRc>()M>ng=_NI4XJR5 z(9QGsX`02RATg4U$QL8YL&L<+ z;erU6BLe^-C%PV>N)>pkv8l|4l12;aCZXeH9OlZg5x!00^lP&GP4~epXIH?8p?Dfy zyUU(gcLO0M*;65kYayw6q{^Da)!xAE3JHWIk588NP5LRR5lFu@H6=wG(&|J4W*e!Z z^R?{6#xgRVG~J0xQ~*y&I;RYHD6V9lCfNt1Q*2VE{Xy=}O);?ocr+rillWOq>d(1r zcYa{|vwIS$MWpZ$Lb(!)IwM8n*0g2(<)KZP%{ZD|iCl;viH20zwo@?Jz&EwxO+qtH zP8pi$A#xNH-a&#IfJeDVO~PVNlKV{(;tnR+)KDwZSE%!x*NUv1J;T#Z zvb}YQ`O?Hl2(GxaB<$FY^z#a|>ZDqzWCjTytr8^6*ttTTAX%Lfadh_VP3w86QJZug zVjrhwMQRKu!*F?WBvzlpDl) zu9Z|Pq)T&Q97-J5m2gnW+;+kt&vU+!AY^oVBefYhz$|mt5j>fUYjw}WYy36mb1K&= z#YBlf$avDEuuVep((0KXg@iZc>5`_1%e!ID6&X{8&g&)-%&uCIwU&=t3eFDS-G!C@quJI;BpldSWHf zB9939C?lJ+ay@dUJ)^|RGlQ#UX09R%eE9h(Wv!H?ZA%zb>z9JM8*$Z*WY>14t@K@! z*@O~OWnL;&KdR&;+^z&-w{!6HLdF*%1DTmu{=^wzUSY-x>p?8pB+TlBP@cSj?ryAc zv0N1lwL%L+^8%vWGn{fEVaeEGX2@GorTPuHE7om;MRUlZRIMjxQ`} zIgD_~6}MU^Z$N8oV&d$SN|k_n3IQXXvXQkkn23VIQt`9zu+L0KW+V$x^~f*~!~eW> z_UETh{)fD|oMC?`R93!Jrd zOXAfSfs*lNR@RLOa5?B5^*|v3F!VylDY=7FI-7q--6n+11W_O4y;q2ryl_{@WaTYz%y~33eQ!CHcZ8L`cTQNkR<^U^zmo2kPM7RW%Vu(GV5!eOGwu z`Fu(vu22`A5kPg37QI7xXLcE6ut|E|pw&WBwweUEv}ol#kuEKf3T8+#9TEkQ($QKb z>a9|KQl=wxLrNnKY60kupI7}{^=08&T8bV) zJZP*juDwMQLzOGp3hvKV1)-{HdO*C31;G>GoGg4IS?`hyG?B`)JRd4JNmf)JmT;vh z-XyAj1TXu@WLA^ZBf?4xX+{l84F@HhWG>m@{!UJGb!LGik-Xi;; zt^}3tWS%rce#|Wh-!ORW+-$>6Us<)aowc1+8c2DQUJ+(TQZGmVSIRT+`>bX}FIME- zig{6}C7A?of-rCV9C$l)cjYi6H_PM);OxPp2cIh)#CF7({wc^yeoVb>XqQQjCM~)N z+NkoCtcq@SPW@(*X3yzZGk9&IWk5cJ&t~hBguX_$JkoB2x0n)t_j5W8;+`r; zCs`{R>AZpNV||NfCTEVEcmaad_B+%9Pf21?ktZfw`U>GF`4@SNEV!9vPuX2NrrQR)Cf?JTbTlqK(yU$XTZ3p%``P9eyZ%A| zb~(ucv7g8c6>bFh(Rb><;r5CDTibCl$s6k5{frVy1oeokcJ zJsUiYaXaw~3emE5EPdr#2W%$CW=wodL&AyhK22s(1w+@K;h710x2LljLAPQJjCLR` zg!3#iL7vZv6*8W?;@PGZddKQnso~@2#2hGCUdbsI|BH$}KgzYDS>dg=lR|@7^OzK4 zGOQT2E*SGfAQu-F8Wk^u<(XL1HbQJwOswR(K|ta*38uSa^PJYy>P-35HN|X|NiiN= zqdt4r6?(rCDU6I*G8@BxkFX03x3)q8k%>+4ByJc1t7UV5u~^7DV6bqLN0@KlD8Y=sFAJD<#t}k3R4J18%q=EMJGuFD>_HTh$tc`39069;k`*0AI^_nz1~M!;!ioC)PqZx^l*lu9TM==41`@B$pMIjL5G@}Z40 ziK$5eD9F!Z$|h9OlnGjVI1o+;CW*jMouIG{v73xbqIY-67*TTq-|C~(6G%8(5{OUc z9hhcILjuX|!^!?Wp8*4+mPf7Yr1H{YDq({=mUgpXM7@8~Vxp#@M+%f|0$1@2m_diF zlj2eGhSFDPIm3$0NcX6D(&c4^?Oic~mW}ZOPSq|v7nh+hK*@4 z071g3vXH_3OdB@Iw1P{7{4hRAnreUzg+PfriKQoVw_%}EnAaVU5C{)HhFEZ9Rg%%T zxzqrtDB!pnbV4o*DD5UrX=3IIyOJ}HsufvL2QXT4>k`ciqBY1RrOhAjullJ;&))Gf*6paYMFm6-!6QR+E+azR=tc=(1CDx2B>u}Rg}B<#3M zAiF3CkiD)&O`8&-Awwd3c7ZPY^F=mU$S6K%ER<+6u90uDdv|G^CW#kyVAIGjMhkua zB$NAHu}ouQs0s*LG!TnoEo>kOx_lT<=$9YPxhjU@mWrBCu(zV7-!h;A4PIu?gsdayKqcVLMv&cl_HmP?sAu$oimksQ^Bm*@r8#9-N8A$>LITMZRdEo|gya>4*b5o{h*%@lGByfYAdbs5 z17PptllW?&X z*v~B&ln)`{EnR|W7(A*x8`$7m_no&OONUdZ9-(skaR;! zB+6y_oSyw$Ez^LNj8-(#FPaMnn<>4oW=QOs!6+3a^x64z!_<2c9b;zgYer-tbt!R) zN@}x}=pq?Tr4dD(-u3Y@n_k3l2)&SSorU1u`4{=ED!#a1z&rly|4E>%=)sbd@SW03MNl{4vs&v89uP;ciD z&rX=-#t)`tTrHGcqV#MzYi35$8iX2?20Tf_(})=_ujdSfxZ|ykA)TB@nUE;0MM3Rk zN`4NXVk8Aq*t?Q($Vq&*5jYd;>5|E2(n*wTcPP0r%s*_;x>`nfsm}rZ(i1uZ-M1&^ zc&rAS(D4dkeU#EOm6)YyImEzT%&lUcn3hbEZ#BsmV5=k!RPYkw*(cL4Rn%m$;1Vr^ zT9kp9Jjph)bj}ZqWfM8-%7)Z1CVoVujvLIu}uq$tRJ{QH-B&^3|jm=I8Q=A=A`C2x`!O^ldPNQvxgb4z;v(Y+NTC5?mTY6*jRA1H2F{3-Q|IDlfawcp}#>U$LBR z@Pd6yi!$xoIEU>;Mz9~Sy=p?Q6pkN)*fY~vRk#vYc8OgkuO>spXulz={h_Q?pv${# zKXw`E_cQ<xFLk*79V5JxiQ*&msc{mXwZNHq1Wah zOUs!#YsAyHqFgUJH10S&j#fue8Bx2I7@>QqPP@ z?iv}U$~;wpC<7MUg}cekViycM<*QAs08~g~E;cf(%f1Ca{R#^vj&DKR4SQt3jgK&W|>h1TTe-}l*jS}XZP>~o}H6b|d?CNcDKJ~bJ=<)F3pqm3RkU`K1vpWp zGW_mF9MaUeHW?hi;^G>bp@~l!)&;+%QwEo;;OUl9m1qRU>vnd2)HIoL|CWWq+51}- zVdOZ|gPAI97DTMR)5I_oRk$1J2 zWATyZ@4-=`j#U`|gu5q3@eV7&)CogVj9^1n4KF?HF2fwfhzl;0TN&8~@Mw6Wg+c3< zwz27fh-+iR92NV}kch)7*JXJsCzmGjJB(y^S=bibrNfoLx|TR2gp=X$6CVbTfhVhh zLfMX8ESo`Cv$`%8tb>_6K+d+U!2-zccT+WGWK7UOt1@UY(pwnppOv#^Ybqx;qJOX+A(7#)2iqCb#Ww7(u2bo<@t3ZWGgOT4E zaYFsWLhF}?Mpr{SpxK)d3?xoZeT?qEs+`S26Sx;hX-&Ruv)>KomkY$q5d*+3m!WGc z7Pszw01b!ps^MQeC!oYvEO4zL4~`g$%d9QVy3V*pJE6;vh&N0wZ5QaC(1ZarVR^lw z@e839STS&n<1iH+eXiO8niV&dn43P10e1js5anQC4xpyRIU^wy1w8)I_!dPn2B!;b z1{^^ND;nC|6RHXuog_fXKr^C{9@v~BUipYpSbRghL9*_Vz__6-0m)c`BGjX3K$;P} zSs(_RM&uN-_XmrS%HoYCK-7_~Vb?8h6%2-e=5hrQQ;-&%vBfhFOV9v%I+cg^5fs?c zTbp2N)Msqy0xe1%2#VYx>=_?sAv;z;QwSXa16iUv?|wXl1LLQmT9-V{jncoYcwgMQ)X(CegtI>k(#nq zv+6wMpsH@L#0A^0sb*30CDwL=NsaRgk8Rj01~tw%l z_Q5PAsPxj4;I+g<_eUAKoUyY1cB-pPZ>=O6x7ca-+qC;Pe4h?=vB*6hH$k3u@$BTt z{5m%H5bKx-TSlu@_~=%?3s2VZ`JIy|)_zrGx5`4G#;a|rjp%LzRovoCudCSv_N!hs z>c^6+DVo(DwNc#hw%woJT{Kvn-OUcHug)&hm2XRY`V~WP#kg0|#LbdP@Q$hsiYTui<^U$KO-OPh z$p!{5QB~htHl|NED!Zr0@=+I2k*%piB7drOw-h5R>)hEt0QTg%e!rnmdw!9PV~MU? z1jJ61x~TKglJO^?I|0kmBO=je_Go`Azy8|Lqc%FRbgP)pgK1Ecs|(~6WpKqdmxMiR zhn4+*O7WxL^mrf<$j||_JGoOM&Q|v5pZ8Zxu&St3#pco1U%v=~;m6U;=7IJ4v-|p` z2^D}^avuXR8nZ<#rifD%gCd?3PAaMtq;0nkEqbNdW(=HbpF$n&5l@LZ^Y{{Bkexq| z%4NVO<@q(5&y9mVs%XJh8ipnu_eGVa0XXxD$|UX+&Jv-9(S-jva+{zfZH|xT4%2LI zM1(R#uEHxcOzCm~Tf!$j#8HD7%JB^*brWU~@3@JqA|i{(O6W1yttD``aM8`@gBjL_ z(V`*l$k=L0804-9TrFh9?<#*6Sj29@AlYVJLBsgF+g}WxY)CHNyOVrZq}@d?rn?&j zr*0f+he^Uql^0Z4ytO*ldtx-G*dGTsLK>er}YevPQ>|WK`ZOwu~;7cN8+X5fvK#+ms(0 z@nPGKj(9v$lgK6x<)f~3=_u-g8F3DoDj^o;_(VZ9va`|@5+l`%V=6{@GOkG!4JLQY zwwqZUnmQrp5;t;q>~WNIO&sH2@f#SR@ET$`JEKb48ol~1FK<}Rh;N5`inBRhGBXEe z%(~3XX3Cfot;^_yn%iH_7XdB$LtgeUs_of{{d(CsVDG2*^Rp}K6}!K&gi3nyC_!qwzxMb0H57zq5OAH!y3#<+*+ZuPBw z7Z+oNPD;_C!e#F5>A_iLh(b-X9T4kuxB>Q~t`Er&{83x2a5zoX20(Gr)alM6AeSU$ zik06V$h_pgNM7Vmo{``k8QN6>`0($P|C5KXlxlkv?N&eR0?}Ks7n;?<2j7xd5Be=o z0T?$-I|oNHd#IT8NnW-^(+9RPPLst4^(34~aOHQpnl)|XTZREwE=yy3AsbsV)t5}r z<0%AKDCw9ZbwySD0gPYCkRaZ0OfvpfIpZv^UZ+IC?SXw#&qu~;@O`S%QSn1xc|=@A zErz(TOB(71i{v#^p}?5NPxEHdK191)T><4&YXT1kAEf^0l-xMwf1ds!|18xAK8U*6 ze|VhT8!k;5 zMlxo(quO(nWWtKpnnIy!&2UQ)7C|f`u_~)nWwfdmSWh}>_`9wYLwf;y=u&c{vWv`t z5rIk&@g<&*_-VAKl)zyTBi)sL<^KykBg!g982Y1B7kag*7B}Oq4S}2l&OhAJ)jy$U z<_BG<);4f9Ku@;nc`(!xM_xI6%?@w^EC zl)3V$b=OaqqtJ%&MPVP0_Zgk32jyFbu_* zyo^_qkVLRoX|gjK>TeW9O8sF~4s99Q5_R>bbq08Iz*ucoG-6B3Z)3?2v=}7QEX*e$ z5Ai6rakWZgQCf*AmSrYBNBxq}4XEmRE}2A9xRR|E0bo-uCH81F2twmGiftZ-#q;I3 zw{MGLM=JhMg}7NfTV7xBo}+0J3qg)k^yNO5r`4; z%B_e2l3#Cvvi)tab4*pb{G zDXx6qX6H6Cv{8j1^SkLFMN5#yGUty(YIz|s8ign z{%@|YTr2xD295>$lZrGdViw-YX>^o>oL(dh!tHDlOw!KN5|M4mVq9n6hi4QKU8>|3K^plgX8OUPppC!CkDaAh99+Q6MFiQPc#=O)#ZE zPBLr_6^luGS6`o!dj|r<%$F)Teod&V7IbS_Y;c#Y>_Kox8(>B3rKN3J;5ivuT0dy| z2*;;B=gui~cYbMD3L3JZv>VhgQG|&_yfVbD`sG-OPxg<0R1S{Ltf*W1w5ovqV?zE= zeO<-yp$GDOD(FB}Kj6Y;-@5pDSPBirYZKmUjQEd~+JBPi*w9w`N2pf3_0-mM>K_aY zGX@7->lPy_s=%AA`Ke=R8U=)70kwtn{Euy6;LZHO@oI}83j8yR{y2%T6*wY6v%p7? zUht0yJuHZqltDGpkFaTRpp{;?1DZhOh!%n*iHnV_*7lGbVokK&D|X&1&>L#hyj}g$ zCk`k#SdF4t7JeN^1i}nNK=c}mnh0OE_ZgeCIZm@PfwVtpR#O&|HMRZw) z3UKn0TwwH1gsOMCCtk-S363o&Wtt})Pmi31@W-ZAH>n{kbj)XJW=2^WRk6rk5?8oD zGc7iXg~-MRv?lv`KLi-Pm|paK-f4ldIH@+kKMQ<_C+HTcVpg2aKso_@%1F4N!yq?; zZ`ioEWl!jgRMfT-F2AD4rKl+sDp$z5|FEXr1 zsU*?Qdiltd$HaDj8a4|~Dl|SN0d4dF#_7zaxXr?+(45&Ind*IcKvCv|CagzOWIoMS zf=tK&qC`}cBFRSbsSQG4*w`u|Q(4wm7^0lCcaZ?~92zhm*)Qv?9~%H39tmpV~_V%Q{`z5LBSar zVoE5Q)?VvK*Gbl-BIc~k{*Y8KR9|!uKu0GTe^*T&g{e(q}5$MZ;`8FPoyO*2$izt6lPPl8{wV>WYa@$M0B(xiuxT9AWi@PWJxQjs`E7 z2UvCPe8`eJX~IR>E-?~ARqlCH<5FzLNU0gcbi{Csm8v2JtcsX)g?7+@bPvMrt_l>f zEFv4w55GjanV%U&e&-UZhR>>hl)^>_^i|q5@Oa4ZMn~+E+;;SOx1!>(f)M=_g~xQes>sH3`QR2?N67CeTSpaPC!TgGb*K>vaEu;9Z~jhOBq zvjZ(jCyhq4*-oEVt%9LiDiLERK5P%^t$$SXVVHoGbFl&;90?Ka*getLB`^6tLL<5w zvT$%g=G8PgztGU`gpHvquxQ9H2tT+0H^7Qfv4amKkrFRx0KDlTUeczKDrAJ+2wN(Fj`ojHR^%l@fy+#`*U+|>G^RXk^GtknQNCxIrY-O* zSg7kZu5`_j(pNMy$7+6q=)mA!YjXvK@SL&C^UKj)%U4BU;dYX^MlCMhJe}kR`6Q2~ z%SY6U?73_m`D@3qyqY3jQnz^P^u2E@X^{2kA`h<-|MIJzjDFK`$^Jz;z1Je$GD)FD zeV)v}W7?vP17+@*GyXXzDYh#THTg@ISLwFkT+H%<@aR$SYeDaY};v zg?;{$EYY+IUe89j%WT|^X_ErFlZe?rA8M!+vquZ#A%QaM238i**S*MnC}~oE$Fnc` zM@iw2V|%nUGV}gN$_>m0^?|N#INFFd9Xf};Xj9vxShsO`GCOfU)dDL9aq_IzOeZ&q z4l+{;4DqK8q(hr_MAx#!g!jVvXkSx6Hjl6==BDr^W0G`uO?U)bBFxEhk_?nUXhLR%)}c9Tca>7`{W6gv>d4-8z}MD>E|bSgCX~kwfd?MQXHxh^m|~1bx8+ z-T9hW8vui2h69(3V^F4A9A8`J+<`eKv5kYSVyVy|2VQsxkeLGY9T^(*&pQzZ0(z+` zep4K1D67fYTy2$EXyOcqwWmFOfQ2s8<*L~ugOhzl>4eSS#<`+f^rq;$!J>swv&D=_ zgJhEX5BAm|^Zb#NF~D3M>H`O=Re&{5RtbQK4n_I#TBx{x3>{1aVvucm&=Fi5g^5j!0zh@lvn(K0uwiYcL~8VVewS5sMxYjCHp0kTaKi8l0#mu2PyaJ}@FxXO$(9tjZK?63WYbj)IaJlE zekC;P??)5)1C*S~-z;UU2IJka(P&U(uWu3JWK|)wDwP>c<6(}Rso(s_=q}JP)B+TN zQh*vkp`)bI6&f4{5$MY(XyUwBR+WTioB0kO=rLzacqa(umVnNkH7T9)v>FOJYZZG> z7Tla#3Ttf%$P+^nW|GD}-W6!=nA*Ppyj78x*2hQqwOfeFCppys8salED;_Xo5WJl~ zms>UYSs=1UrqnAopGHa0MLfAW{EUR`{Y<*9oJ$Y~d7LgmM9E0oE3MY6?sH8i;@peG zxvFhEx%DIGwF=sngAE41n*A5z_)9_IDyfyMH_uLlm_Cqe_{&k&n4A*}=*b4srDDgX z%7sIK6@f>3zFUK$1-rQ8hJ<`E`9o9-w$sQ;f82}3&mt6gYnn93StiuWh*Oo9n2-_{ zXVH*dl{y0Gznb4u*d6TSvHbpM^*Pxg7U0t8W8&_DwdjRIcGR@Psg?w00oX4Pqz8UW z6=Axf^AY>Q;*{7v)~)JW0P~m}O?zN9s|A$XXtJ{9M#4c|6diLWS|L#Ti6dBjkxH7O zpmkhaTxX_VCR-E0_#~1EG35AVAj$NOQ~Ms|<YN+qP}nwr$(CwPQOwb|$>%Kit=T?U(*mSJlF-N4JQ#z}=0Y zgULlXVtA+S<}bw3&5mvv6+-4>!g*(;Vzes4QyQAr=X=>TFO9Q{2&~2Jt^$=sKp-ya zRkgEWpOJ6P#TU&f_9}}igY5AUk!q{richAoSDjUa79)KQ17%oFV#V_}ELO1fYOzd4ckAYno-}b?kd}eYt&6JE8y>%g|V)?=H4`%VZSgvylBhx z#FB!JuExBrP9_YwBkaX#e|V^WZ4(+pp&Ki@1|lb2a?OGF%HiZI`Bc|L0^9gXN|uZ= z$?K&Z=bNaO-Q|MR~qEc&Nlvm@SFT$e|Yj2s= zp>uq2jq!c2B{+Xxn=JDou*wh-{6?NqJw35-KC1{RIVWq1Jsn86QA7%@;Deyd@;LRIFeW`Yh=MkTXuLw$_)Z*ONqmxQ6$#-|gN{?r zo=^31Y0)-OS7)Yd%QmZ)am**fZ32-0f?4)f_!}rOPpy5}nnG7`W4&Y3b1WAID#+7C zkaiw6$nDPX{dHvFB)v(q<hNg}kXu%-N0vl~hror4grI^H2AHAMp zlR9m2aU0}vz5*<$FkMuM)dS)`kt^?^EO+3r+HPxYf@-YMc(;j zH;`QpOME|nXCCPhEyJ%u#j?Kzj3WdWf;+jgJ-lk z$C~@=&JY-YiHS6}r>cj9&u?P@eo`qs7v;65z~&`_fAhinn|p*mh!Su<69XmWX7R%D z6o9eQewBg}u9sQ7oQ@fc;sd*1I(&eIr4GB3d^q2aKBs{K^>#OV9onLNqJnLeAN#_` z=9GNE#xpd4m9-jzh-#6qfeK!yB62?{mra)naY0kZ)?xTb)z*#?3$sSOYI!#r<n%8J{V`lF(I8Vh5Diz#p^zn8;hF!mzPaXyUbqPif}#?VNYP ztXu}wblsKJy||!1Y&4tX`%DJXjDcXUHXBzy!ZWcHWG!|ya?Q3;H7`3Etb{`u<)cf7+EYw1Im`D>gPPyFmPNn6pnQ zfZhQ*^(5Pu?r-*%j}t@n=QpT`zsI++4t$dV@G|M%XGQ#Ji}Mf&E`_7my7(z=bH56d z=hb+zpVexSh;g&3s%&{wF)ZlN4S)!wy^)>E=A$B40ke$ZXgri&V_lF6`QVM)@=I(@1S!<~{`_^Dil6Xkgyb{__ zap3T`ZIe)UAe-sU0jaE&*W=S_-4lN!iyBkqeFiu?xI&>$v~qvY@BjR(j4pnR zhr94>ieIz!C;Krxsyu-tgNn1%OOF4YAXpu?u)abD9-3Wk|39dLnR(4?(^{LYb4(6j zUGzP*Hv?LOMiS$I0w>uJsJFlJTW*=sip^LoB{I&4Os1U=ehl9>U}?WE&T*9 zmQ+r1;2|nNaFk5j87Ep-HHa$0Y|}`#WtnG+@x>?`#x?jL0aP z-OGI16@x6Cmy;W+JJKo5vNQi8DNF(uD^0z1g{%`ek^V-RY{_BpkJV?RtIEKafQnv; zz7k2js5U-_XoNvs6N6V%h2*l*4KX^0L&yWcP=p^~{CWnnaRkXc$ZJ_aM52*kI5EGh z4$X{WO^`<`-X^jFpBy|OQE@KenAl61zpI5dpQ-yev1i(uTa zsD2-i8ds%~Dy(t=Vwleea9|vmd^cXiyp5YLW1(55hvu6dpX3~UiHk4v>vz;?t2Br( zuNdKC2PSrz-If@@*x>yr$LX_j2+o;M-aXvAkr_ow=tz$|J4)guZN)DFN{yFkC7x9f zdM6^?JY{s%;QP0vf;^~@Fu<-D4kyD7pe}pE;E;m-Q0Y2VsLc_r~c{q!ksgbXb;Rsvy{Z=$zuwaJrr+?J!oxli_4U$CHV|$*8wj zEF9|3S*&tJC2KK(E*GxD-N#{WR5KN@5l!Jn-Vi^6y5u?v*`>vTk!+I!(p0U;F_!ybr>e;X>?VRu9p3}_c_HY z^6SB9LHqmE5VSvU5MG>Of2t&4OP`Inh1SfarkxGR>@~$RsNTIa>id~;tfd|{bOhjq z{+q^1{*WfNRxmKM^67Z3#3ZZR-W>+%Kx}Xcsr@H-+IN`#nUdua(uTE2+BSD(w8h5v z6^`tyu1PW+b^G0aK}wQ(+*SL_-;RdG4U4(mg`w8QWEre-a(Yj5hmiw@LjqX=!!e^< zeHxKL$BHXFFFCu)jH7af05J6E&3#p>Mcs0z;U`0sZQku#k(ITXZc9F}oyu$>o!yBQ zre66yYe7uw9kiW3g1GP;(~$CB5~MsrpK@MR_=HK|(znS@IV&8$}6C;}Z9WzC`8gQ$nSP zMIu2ahk}TOQ9dfg1u)DcnJ_As3}}Rz`7nAhi}iZm0BiQpi0-?$%+S$qSDWZIIzG;V}e7xbqdt|wZWSj(FEFp67-CH z9n0~wC@SO+xhfxix7S*95k(=Q+0g*rwz8`Fpu$*cW`%l&%vG~JHbXVr*Z=I!!?)NZ zIr`t?g(zXe%7sft19nohDdnF`1)M{Ol_a=UmnR2ahz{(gso7I3)HdguOHJK=;YeM8 zS3MNLk5$=p;7;_oXOAlLYzEMgfRlpa4?Aixl}3G?5lWK2YNwt{8;8oXSSd#t8#4Mx zpvwyK(iEMP)mFChdpdB0C09SBXu=uyIisfeo3ZC7|%5fzA%0y^Zq1>aRfNF z$LQuuiIA4cEzen6(H5jxQzIPOmz~K!OZ|nWxPBOxeKN_ZOfTcglnk`8W$@Sd>Nx>Z zR_y4|sWOt8)?`i_{Uuh$g|;H{7dOG9!ng8`wblw=*@Lw;1u43gaizWqOq;fg>522w zGWCl50F|`7P~v7mfu-ugRBPfydp{$LX0b4Nb0L}NazK~(sgB)KW#;cAlY#QEidBUK z3)fqHMVvj=*vcwxy?fo!TcToNl)vlfB!%C28s~^k>|_dFFxtP2C|}uIq3?g|Pf25^ z6S&z#ry2vwVPO}-U!9ILOZHCXZ`~aulC7pPAa2IWxDi^u1Gg1lx} zZty$p5-#~zETX0}bwDhrV}U$LBdn;_Vm$1Gi-{~&ak$W&CycZW!Eh_yPVt)AdV^fS z$Vzq`6`2Lb(8FvewvUkYg^lkt4a{E_dt+rsR|QRUU)XGnvW(mHRM!f=GPN#LQ`a|g zbi-6N5U%szmAE`!Sf$&qg-rLCPvny842T*Zd<^GBVL*3_<5z4k0yiCqA#W>7 z2qs^z3QXhlH)du;pDdSVQ}1a=LcnG3x?O97DR4A_Dq#^S4`2t7E)4f2Sni|F|u z1%=L;0qbCs@2)CYDee(VZy4?AHgUTAbn1*3bzPqa6deD%pWSu{XgFNMr8%x|b!kyy z^Rr2vXM3Xfb4(S4p3c<03?!i5b!G`_D7}_`n4gFq2B$w0La|9uh-m9FhLpnyu%HBHq$x zAPr4Vn{7V?RlwN4a?>cWhvHHaq`>a9>B1xBiifgHv#ZvKjaPm?AUv)GY`sE6i!O?I z(f({Fl!PZ7W|n!Z!elSy z#IuB#zPuiC(!Yc{+gM}%??P6 z`wx#=2m!L;xc0AH1kK5X^H%B1jZ4Z{gEkIS=j2FDthNyKOhz7@nTpQ>l-bF%aFP{dxzEq4u|M#x$Ec?gZ0gb#uv>IdS;*~2M8~Nu5%6)ib;QS z=gAC9^Y7Vsl|#or9)-|yo4~+IC)0){@0vcheCe49r`nn33W^ zd-c!cUj)gMYJ1?+k$P0}AR+oyR=9G7gU+ZAifMgGW;SJ1CbG>_`X&2M>OODl;@V;i zS4XIL;~ah*+JJTYf~i+zx()?HUul=Pr*9_g^25t|`i#k`&nC~Hpj9&s;*8wbHtmWL zg$Hb8<_FqR$e65b%|M7Vwp^K&Z9p@^--zPfiI(xKhziYE0i$dk_2`s57&rWcrsiOR zlCF2n@j@5A)moe(J&t`AT;$^6!BmeU_oB`=n;W#6QFoT}@y}Hn+iR^_^ zT04yO{Bgw95&eEL*XXe7N!O?bv<}Z(zDLx>B0VPjtwGbbR;QDX=1yWM}s%$Z?>ppMoQ=p0Rh;v5=p*mYMEYC^3#!J4@Y<%dhTjB zsuFZJwy<3%Vc_A}j0d6O-}3^93h_J9L%*SAAgOR+mf|K%s0 z*>;aTbz}x(djUrF_31q>ByFb9-kwmK+XkB!mRtSMJ!0~5YF=_j^JnoU0=-Mq#~6sR zb2&Fyzw&5)C15n?O8?85o%~bJ(nCJqlf|_wp;lcgBXNJMG;uU8XL3Eg-s$lRw^lAu(%0dM>$2P*o4Ph zpj0Or2D!1gAmaN4!WKqz5wmzvrU(eI&Rz#)iw=LvIpWUMMg%K7W3y6fgGDeG z=pCOZHl=v=Iu5ji|ZK zx<0+f`aMdZ^Vk=vG@j!(C-mDoiZ{lEq;BHW;YupoowKvQnRB!x{xS;HKSN!4?X*;$ z`=jzlD@U(zyw?Swo5YkpCrUkl*f=aYh4G<#50W>nn`DnDF6;e`?EO*sPky_~J*KBb zY3eg>jXA0C7bCc2@3n3*u+l?bM^#6sG_B90Y#Qy|szQ{8G~P%)Z&o>xnAOUDI?Wd+ z#}R`1u`NMMKWl^DGr*de;Zng-C(ELaN?PaffMbG4spjf7CbYjhZ$9}q6_&#CwmTlv z$5A+%RMximF8m)aMu!@RaG5sQW=gYtS7n#zn1C14hh*rP78%YHFqsc``yuvs(MA~! zCPieDQpXo`KMx)`PzluNOj?2tKynbOB;Q`q#kif*tmYPZeR^KfXj*LRD8peaZgI1v zXt68RH?lmWTaB*>3hqa_qz=Y;Q^Q6~6Y}rq!Bxc^;nRYx-_uK?&dfkqQG=Mn ziOwB`B;+D(!>)0%gstmi{XjsBy=L^LWNQLRBcZcM44cxcYSaFI6}q|fX*?X?K@Q3= zUn2U>(=$!RsJvtOTq3Tn-!;ZLG&eJfp1Dmc6_pBD5gcK%8JEQhYk?Zen3!tYS)x1{ zbeikjYgYMsf__ID*zs{fvDR4^Fmy3nU29z-k{+h}pmKZb8n5D}fJ`r6lSfU8wU3bEN*D$W9 zog3WT>D(siaM%;VqN^CsQ-xSpi-rI%lDQ+PKs41Q z*0usFf4((JLNIr-NRbzcWF%HwYHLrGibUfiZrhVGK0R~k+ppF#hFZW(!DT8YtB0-C z{mv3mOSJm6QkP(NYy9Hv5|oXv04UoAaxa2)@8usvz%7-TT|`ncbO=1)?3QRQQmS{h z&HCtjGZj9_Tj#T(p3SyRw~%(@ce1+jCpwyuYM9FCD2fnVEqlZr`lg`)QLDbxlpLbV z`d0|?CMc{QB0=hMHHg`b(vnfim9GY{JzjG}aXnOnDW`y&le%l^#YMP#SFdmMrE&w8 z629-obotx(MKTmW@3~r>1J~w`0DHiZg_oi3Yti1eG-p8CI3`1p} zuTKC=72^`nND{wYvFa6fO08zC?^+kRZ(IV*p>T7)UDLlS8xi;4;?+dAY`@+#60E^* zvo7WhdxO{72y^)8wgHg!g5R`EXc#jbBWUDU-Z6*TjwEaHTqU*p1OK_kP~&C|Yfy)r zvT0=o?|CbPn2EswNGYqT0qU6W4XgX~J1nS?^_ zY)c%s$;41Pqpt{V;{E@M9-&JNq0Kg+=e&%rP8m6YioIB`%2q!vNJip0LT!ioJ-39) zf(b4PIFTN8k9dfNa&QIZy$zMn_Mg*L){t)U__HXsIHuUrjk7g^cgnaoGh7Y!?x$tR zdP~q7gSOM~f}q0xIXv3(ERDMQTJ_={Ye_UAweo8~a)%WxCb9|H`cBd-=)YrPUdyCg zF3(`b+CCJ)9{(ibh<&$i^iKdPoK}%g>qb3A`Vi*JzY9-#z4LuLi>Fh$wq}{!nYsJ2 z5UqYV{zC&G`&gq!OnnvQZrP;Q4-irhrEGKd9{Xf*VYnUb!@8q6O5R>OQ_U2rZBjIHH89O$=etX*H*@%cmC8c z>B4Pf<0Z|qie}6@k$>>(UP9)qBh>J4dU6e(%%U>xo!(HjcBek#e+ zXj}>T75(iQqd6JMh83ud(urcMaakRc_8spgdY@}9{ivU)+vwN?-cDoXWQZa-3=`Jah}}zLhA6Hd!O?h4U+0;@ zxw+ZQRX4Vy63;-#X770lZp$Bs7@grKHBsaMsO@~{K8mHm7hCBiYTiLB!P!43W=O;z zXAa+N)xELwW^YTt7*4-*(u{K|8+7a%5n_TqpV_2nj=zeIn2v6*Li3UxbwBY7|Jpt+ zexStZ|998DvvSBB`TdZBi?{aQfGZ3d_0dNuq7ZeW{RP@f6ZgrOto77VlSu6#CHolx zE|@S9TQ3be40$TYtBbye=yoD2lp@BfhC!wpRE!f|+)?t+00kStQI;ua=44-~)v6(K z)*{D$IcZE94cd~vB16Y*Av(eIAIXw1)i|Aw8JB+{%6+FP?p&$FxnURgbZQCVhzNR2 zn^bZ~w-xnp&>m0hC2sP(W_mCtgIG~sg|=tvuG%YUK>);OercJS%gKrd6kG87A>(9P z1zttzmRjsUGnr>=pQh8F`qRx{-g2SK#vD}#lSQsbzMT|ns8bf>bTW`WGNLgRc$>;? zx#K)MFXXG~a9JK`D0Am8Vk$i}Mm=PX#)R~tz@mFDi<6t%cx_}xU2hocUmNDFAL#iHP#Dow$l)tx8i5eH2m(%B>6M1|q1z{OC9g6lG&L zF=TGdZkAA9k2OWV$Mhf5WOghTG+$haumbGN)N^v~(fBs4YSX@7%tNSl9zD|TXW862 z;aU5$+L$Z3sTCSY;6=aObU)sTKzt0s{|Fq>T@EYord8f8{i4NlE@z%1!!%OQ2lV;g%!vj3;CvHxYlrFFv0NYTU5si6 z8TnYk`GqYJ%t}lS>W}6)>CnbYEYAn8_s}VOSKaD(c|$lS2*%2BwylN1mX__c?6>bgKxe*AW`en$k^0SRuuu zzH4e^QD>-+KwKQwSZz@!SA+$KFxF2~Tfkl=09bjq17ZqETKE`+nh_B2FpnKz$m+ke z4iJgI5vGW{%(HGWKB4V2mt}Mr{!XW6mFxXbhazPeM!I9uJw~+21eXooG1D|#r@ax% zbDP|@>&9%Af91l8IeVQ=pUH#$R1fkD)wM(P%wr!hfv`H{tlO*F!x#=gN`Sybk*(|7 zvW&6P|BMdCNe8J0NSDnbNpvF-IPuUCF&eAb`8CXLUVrS-y;ypXL@4Xk^RbB^@z%k3r3V>9PVnx?G4#OUk7 zud5l~NU)IPbW2UGfX;HP@sHNyf4;aAf9o2nkLOLtEN}=RD^V4;VXv^t7MsO=j+DkH zTJi>8j?g8xEVOf+2I2|qyq zLD4GTmoEe5j%9Os4L^gtn(yZ+sgL7I8TLEiK+Ci9BwWHO19(W0gubF?cSYd%8|s@z|P`jJVD&sW3OFl-FG5hFViFfZ53Q;-eI21`X1 z&K^IVSGen1C9sm@T8vW!vPVd4B8+ge`QPe`g^9|rnF?i9275_L9oB4oPBGVNT91!j z>aIIlZrw4b4~leKV!YvUYL@b3rY~aGohv4(GLr7i+Ka6gJ0_^wkh8))8#^>imiEb( z+o;nb2Ut3H2XRk8Bbv))OsBFvKC6Ck(kv;C!kcVOOOQU$1bP$J@f zq%EeJ#)_-G%4kc^RF-yPSDQN++{t;HjiN`!M@`FdGMa*$`dBE#K1$G~Wqp}$`%H^v z@Fz>>Z7tpu!H5jX4)j(SY8pDic_y=E4o(^6F1A}~(s}P{9*rA!sgtt3zCQod8*;*d z(Tbmk=1GffJ{COmNe5nsY+k_D)w`5E=A&m9oHMrO5;z`0jh}21`0B6HG@X zp7uvDb3tO*v#CVwDh7eX1+q@+?goi`n@|P#XHV3IbLyDCvA)et`6Z_$Xjl8?M}bTF zYT{(sH=L%uF_7VqQKt5j6|ux#E91LXO<~21Kh42lSbV?FUPwP?tiBHV6*94#tb`}S z!sTd4f?Ixv@T0soU&HDn`J6qw_h=@>gaO4C87uUU66ba*HeqzsdXWWwC@F+~x9%T1Y*hs{X%?}ftM~;#p*P~O zO03^4_tAb$$vndJ? zhPk6LA1sA)avM1-Q6v#ZTTX0Dvfy-8ZjNJ+1`i{V)!Berm$0WU+Gx_9uZl!On?cU8 z7=p#swLU6Xk1()!K&GuB9GEK|3!)$sJ>-BBAS%{ka#dIpO|ExUDv@=I-p`TVEl0E% zO!rv@8P7$TTd+Nax!VEbfKg;Ks{8UU;ulMn=#Jjn{Idu#<$_{Wx*YZo;XiaDo2o65 zxX`ZHE^Spx(l_Z0tH zH5ZyxkJ5)pbx$J}%++P#bE<1P)}A)#USayg16KDhd7>L3FErf&CloLj7o^_RrBA^~ z%DRU#w^%7eT?vD|u%sx7YyH>iU>8MKhPGl1IRH-DZQL=SEI6W~G5*IvKGB2a_;S%q zEcdFybv?x>`i}hjih=y$cNoyGQVk=BMb`V7T-ihQPL6Sq$VX9eR3W?LP(y@c%nvR3 z_>|cB++O*w;#E`-pE3b~zVYsiwD;=9bC|H3`(g;M65s}%QT305Pvgz05I)+L7gTs6k!cer~&Ra-1# zaH^}dCYA5Djq+@`F~j@Xz8&|{4(zFJsmQukUPR~EC5Was2us59w6;+3tE<_*Y+$H2Pdp++5Xg}kY@_n=~ROZ*K^8H z1w(i?CNIhbV8Wl)zfi(`;4fSuKDjy;zS3|J;tQAKSJE(>9_g15MM<6|0kc9JN(ojO z=;qyia$YGet{|E|N_1Iik%W*J(rrY^h#f>vRievCyiGo)fZqZx4-KC)#M*cqh^?Jrxa zVk{2#cdD{{z7qII<=Y*<^=mjZpzC^QT~=ky?XTn9afm`1bADk}{P~pMU;b*%T(OdP z`YPu8g_gwXHO+C3wiJdJ+kCl`eRtzB2G`|?7XRboOXXKSJ1%nG=?qi58%2~+=Ky@Q zP|o^1kS*RS3npbP-#Q)%)3S38btK&24Blk+ZmHb(6%{p|m|N~x|k-2OksX4K=SMIRj^f$E@vMk9(EO{q&DdM?Z4 z!nwHTJ_;$`7&LP)WJf{K)ip1rQO!!zE`GYoyyE2qP<{GOY)NUy_z|`~O~CyQeM`pB7oj z;G7I%bQqh_uN2Z<@c^Xv<)8n+<5qUo7R!3tylb5_uVRHgC?a zT{jW>WCs;HNyN*mqS*re=#TEyMJ1zMHGsR1Uo3zVGa}#f)K(Owa)#Xcjd7~+QD!oQ zQxNg0n&H#DxS1w(f4B_9B?PT480Mqzu%0w#V)JuoB~e5aaxrR-_}93%5HO|yOgAeen(&OES;!SQBt#eY^-1FWZ>VX`=Zo=PO2;WC4T$7hmX^C(JuQP@(> z+IsonK~4F=e~&BaVqL-jE%)o*>axQZjww$=wtvVUp3e6rT(_{M05zg$dK+nQgp_gC zz8S3A2L}$E51H%m&3WZRcTJtFCD3-VePL7c*Nvo{;@660Mg-&sWd-;cck^ZaH*u?U zDD?iM!#XSq?*AgY4Utu*v%v3)4K@T(LhaWI8l5jNig@9R6S=9FqVQ{kL5o^)z1W+{ zH0>SVUROtMKTBf_6+lJ!7F-DCy3K}tXoT+zWd4l4Km$f(VctBkc|i?cb8g6;trA_#~P(clDqF6&k`e6lb$P4fTAmj}r&DFmN%4^@`olbTR2fWLZBimMn@m!*UwH3`OrvBM z5GNuqec0xa6$77jMiQ9f=^~v}-jSITgQlgT*|_J~(c7W7*_h)#u68=zx}*YGCfYTi zzRyV@huvIf6ZUu~O}Rfus$8nNnnurkFoNVSCP{Ij-GPVIYgE@g>yqN~+eJuOHQ$1{ zb~mbdU0}|Z-ZwdyWxTYnfl0vCMh$E($j36c6O4ENx7bu7;=|^&0N$Mwr*hgjao#y% zOo0B;@MFc1Z0}wXbF?HCWaOBiNCP7*?+mYWS0AZ#LRGWQ6y<9!KCAnD9kz%K6~?Qj zgz+?C1P*^%-!EsIB5VoBE=!);#GCv~5*yZdMpCt_JIxnbg|>S#K;Ez0b+h*h5UR;-td0Y(O1A?+G?O_d4DG3n=ZaON9;n_uGr9Fu_Yrd-sLP~Y`t-RM8jgy z)CyvW6@aDHqY4Xx{d&Bp41clAXi>)b4Z{F&7eoXUA7O!?vRcN338c? z0|<$@s_G0;Q|_a9qg$j z+T#hJMDp1tsg#thl9G!f;hpr@s_Z?)C!p#=$=#virmchARa>IVVu8D_mD(O1(%!vU zk~Q0u%iR^qDXgWoD0QdixPlOlwEP|Xdt{GCav;7PIGbK zJBAl+YdLqXNwZ2Tv})R1_LITItGwS|;>}bZK`hwvrA@X>!=9c9H7nihvZUK-@wUB4 z<;eHdZq-wt-7gaAk%eofQP9}cn8;Hn>EMzPZ4JJ$nOeMzJw}pdue931LoZ#i#6O2j zkkJy-*QD3e+PSYcF6wPQ-l@}#f2tavx4n?wodommZH|NpU~cu9S!x;2&R2z*F1Bg)c zsuwG7(sG&>rk6}N&-=P)I!V&l8lg=2_EpiczQTk;+4QNTHiGRneH02T{9z|05LCXa zac}ab4p?0pECT|wl9aD0Yeg#Xg6;opa>X*=TT$R(6jO9=Mf8Rt>qd|%R)=jgnqObD zTC4pR-j?4tJa1O5!{Zt}NB!-0f@nKC zR|hmucC}RP4j%4~)-us;noJrDZ@gHdGys|@7ZkYVRwa%1#`Fdkt|p-uEf}2)XE9-l zN`cfwPzE|nJM}*0s}*@{HcRj~Vb4jXC3ZJFI6d=p>5<6YTq!Jam()`k*g{EmA=T1Z zXM-mpA=?S}YVpa5g&}r?$Hqi@3{7Z7XRy>;;|VN+LbdH#3f;6wC$tvvWI^RC^-MVx zm3Worip>)l+JVY^#XLw>8@=)@AZ9}#DMx6zXp04TQ{gs1VpT=XD#DDrXG%@%uIR0C z6X&MkT$iuve#dBQfw+j z4(8S5Dyo;%=KV%CVuy_{vTi(2mZe4wxM~4wVzGIuJiA}XUZu^<^A@T@#fqSj|CLLC ztimG~7E5@3@PzlAT06ER`+8}#(Gv5q_x*X<|NY4SGyZem|9$)OkN@Y{{^$FP+`s?Z z@9XRR=cb@|NP-|1*U+ zkfkgUD|n{`?eCc&ob?~*yeLoy!A|@eUu8RptMDO)V;3g6XxfJ(s3t#1GQ;ssU8k3d z3-wsFEZ|5{SUQ+r;zhZOujBBQ&5`n1GH-$y z>Z*Ljg;i2DzymD3;Uw85`!`NX9{E>5Hh!3HOu12m_B3^ce1pVb5>=l=ca{dy-3inE zO_o6=LY+8=fIq@^6#wK|vMBV7BB1Kl9k!``TY5c{wsx7sCMeF$NwR%KRpBPziqwE9 zya?B+(>e-&|5sGUNq(Xk%O)fhpfn^{DH|bDi5!GTA^nDkhuPBzZYO^~lRG@PZbE>( zl}Vrph!NMKBd!b)(X;Zng7&Kje@Oh?su&;q)wGHOL;y#llBFuONZ{eM6Jo_2CCc*i zzoxjqf|cA?Li~ZR^*#^xp(ucrZNKAx2i%aFkxK`{@o4A!Mri{$MW|3??1Uhu#iVx<25)9 z`swX-W+4XBDUac(R1cjdBnBB8P0uM54kev$m0NSiNo6&(;>qrC1>u8Kn%b!}y^X}2 zU-t=^%P6piLSglm&O&nNC>i;efwoWT}#(OxPI`Bn<-$I%>Cow`Qxd9ewc4=!Rra~To?v% zlu0GTU_b&k6{gsGVb0EFa}e~Yyk}f;hsvW_n%b!-CNcB_vPK7^mn9I`=Y(RY^eUQW zW2bGgE3t~~{v)#@JT2$zs0&@_a%nT`pfd;0-&U#NVA?Si6(m~vAA>8m>*-6SN^R~e zh$2!5?b4HBvPD3a7CL1KebK5zL0D9OIys-hBl9?$!yyAipJFMheEW6F3fM7fn4YUd zC{g9zBY-2C==O-*uFa+Ro~m$088z+BWq+>dP#BfXSf8qJ9M|1JE2CXYv&QpFk(Y(b z^mUG`CJDD?&HDZR=R!7ZuBp-9E_5d4LrD%sE7J^2T>E#gm`7QiwqCu@oGInlI8y3y z1pQ0sEYxA;ES_&)$qpdVyCz%pb8#}57c?Zzu7HtP`7I01q`W}0#yYN!>euVFHf`#Y zNnqu88I$JD?OW^wsf0Q=IuFWfdsrkuCn>#k)!BE@SJAF%I!!eP8m+Ued(vvO*Zz)4R-{Yl?}k-p4r*+7iewbHB|om9yyRNz9i z1YPC`)3cBStBL?VRwJ{0D7Wh7{gMk!O)0qV)4H<7x8n>X+(ABc3O_v0y(b=9jogWDrl0kAb53F@k!(6 zb=EF|dq4G<2fDknk)AGz0%m2^aK3&*Ou>1(slR4&NIRZ|Nu^YIGCkz~vY6RzQVRZB ziLO4;i)&G`qjT)f*$F>TeDw2>KuF>sbM7y8^`lJS;B_j=Xu5i6Amez9cw!N7y+m0Ny!vRe?#1R0~F;fqtsj#}u-2E#^TtKYz{6tcW?@l&YID)G|geiydNAOqs=^ zle+~C3@*D2Vr65wA)>2_(aVP^44Woajnto|HPMS8Fwg=5X<%dUja)Fg`w?en#srSq`vEAC=OClC$ zG~(LqrW@#_!IKc-2SiJmm+=6ID(FPE45r2omB)u0D{pl+y|H?p@=CDuJng?#CCiFLUX6sUa^!i&{(%d$h}69YL9dt+$p-<6R6h;(;&oC$J>- zQR?1dn7>Q3*_~pDWeKPxS>oDW}+ZEfWsAmcH16&+?(Wh+zs4OJcXxMpcUWd( zW;b@f=4bQc#;sddva%{7v!W``;fPW3n@M2>YX96wG!E3JQU;%;3Beokv=aPnarS(g z5^HY}EXe$L+nrFjRnbq^K;~O=<7aBIlmrRJb}1kHZ)yRp3+qG*1t6L zl^-&kpcg?mXYxH-tN&A@Bb|j>&|39&sR}Aqg-V^@-$IcoCTqEWr1|*8?Kds{&z25< zi+2(jz2`fdPB{VGvp<=K8VsbVfx~ra4k(vs4EK<}rM@9TDQHBQ0nF|$88v;og#4E2 zvRUw2Yg~=hQxm03>es|kj3ym{Jsp&CF^urxcAv6GmiDwvjBaO22F}%wH>uMZ#)p}> z3?a4zvoX3`nx=7xqlrn!0h4?K0q*~9&pPyqVg1Kr;fa&2z4*&B_&$=^E0?oC* zFHRo8&fy)7XIS=YPj<@m_Hu@go=hCQ?|9r2K8*7ls9<=)_@4uE3!G*Qak?gYbC_dl zPSSkH5 zFc3i~x0!5jtHE!4_ZiVm-R3p!6BhPsuV*ZTgY?&Aik1C{026OS+-W*Y;g($JJ{^*= z#7IyiV|TDMWRywv*8oJzX>29YDNe2xY||<>6sqvW{zTy6D)6jaj@ypan?y0sf>8Fp zq?lakYx{;_Ukh_j%jK2(haq{TWF~;wjQ~CgSF!=yRhOb^|7+()9S`4u(m-FJ$xy`% z!0&jdyLei2wihfi>O~a_seJ^9VcFq_2$A&|nhjbiRQ4}IpApDpVMqp`S_Ug%8uM<@>>5JB?S{} zZWqY&(yn77ep0IqsvC59wEbf_k7V4_;(p1HquEavOphSuz16(&Fud+ zR+a|ekjG|t4l4SBuS*2duI-yoF79eT4FtukFzUyUzHnbQk#pS^SjSw%s028i!ORh? zjNpxURc1^W0Z<2R2g1tq>Yf$t!zjfx*f&1t+PEH1egc!d4SAmSNY>=Lk`HFc<@e8k zb&A9n!>1Y4=x39bFhkn|khHbZ1UoHU_mrTD9eeaIkajnV7JKpKp?1R+OC7e3JbMVK z4CqV?>m2efXG?9w*LjX#UDVAPgVbwCS%>dT+qQ+80x7%f_cjT_imqZes#3IBVMgBh85e;Y$W!&6|L zvS^Zm5eU*!Xgt&JnoHH9Wh2ZzC==Arl+73SS_px(s6SM8xtqCy*pN@)e^j!#PfxJ2 ze<|eqr3oCZ+o1LqtbMk{Ft*V(w`U}A!^3ex7B`nDf@ys4GJLGBRcfEp&%^7_U66)d zli@=bb4#Tim5}HtEsGcA1Kqb8;?`Sydt->O9t{vw20v0l_5MA_{bFPB^hp?hQ^Mx2 zwF@-hf3OU_JsJI;`8t^Y$H;szt~vwE;nTX4ZTn-z6KC1N1)F=#t5>W;zkz5vXYX^h zNbr2Q{w~HTZ2t2__R=;d+L;4mYJq1T_qwurq!&zs&4xKzz?ZcK z;({-=YyOJgbtqvZCY!`7C|s1()s}gz+Kww>;!XibhVN>o#mZU%Aq`_A&LkiC@y_>a zE7Q5=vV6lfh_cPiT}sQ((_8i!6^zr8EtP!VZ|D8lNWc%jSU|{vq6N8hBZorRk!>;c z)--lz=b!Zda)`#N)c?~kj4bJ};<~vnHTZ(9{fyPxHLKEx47nQxf_hQbLWsvOZ{dizKS^bAvu2yj4bjz4r_Zhw{(iq zrpLnjD<3xqN(wmpZ5g{JDVTZbEI^0Bsk_s4I5}MGhVPBLhjyxy(P-;l_~LdNU44j6 zS~DEu840LB{z-kx`45^*?OE)vOP!n#B(e4^KWyBY0Cs6&QH}`BHBFbhdK51g<~#6A z50ck~E$u*m$pMM^i{LLdHiM<^A=Btx;fnla40rqNubUn*Or7`FM?Y%2;$BUGKn|b0 zhXn%Ys#ln2#miAFx<;yUMG~Z>Z?8cU8|l@9@!_>~@q2U7m1? z_!bcH=9Em6IaF;}w%?x%7_xF|TH53Y^40Yvjx&0&$X@4t@BD;KN`?ZYX>5#%gzDAn z4)95m(iPh0Fj}*@9*{8~1lqZ78R!{dA$BPj8miCq?YCano75az5jyiE#>BEr-@%~M z2P|S&XmovvcFQ2GsE_u-H5#fI5d* zUD0G0{9deec`U@n_?0~3NA7cx=k#g5@d>FdJ(XkxX!ZZ>Q1z)~_Tx|^sT=GCdxiK0 z8OFCunhwJ6uv}I~N%>CeFU3^wT42+>bgG=`O#SnAZ{;)ggh!74T8dLiT7|Agx=8d? zS7~n>zEW0~Nrx^f&f6R-E<0x<{P%(-`b^=2$2$SnB>6ub4NuG5YQMB2W6@=*D&)O6 zdtjr1X7Ay3`xqLTkuMMSD|?WBk^L*|?SYHlp0lxaG-9e2L0>;5SkQ$aAt;?yv*h7CHBfvbf)n+TvwgbBZ>K#+jQYuqnraR#q=# zENHAf9#PTiAyzmVo4ajw`zV~vv_06d;e0$bLst}+;!=z@%^ib)&N!7m0*B}uB_UI5 zCsoUvr^)MHa>mDyLsBaD-b7J(Ij(TyZMX;+QC#=@#y=byXO(dcSEP>9f8Z6+-H#AU zMedbQGM^23>AaA9&JotvSf4|GWbFs$qLd@Kv90K}inJSSQ(g-?REG%(2W5Dqzl#{J ziCZ^2XOUuAzR0^MbqJY)v=;JBO`I)%QVY()4U^fFQ==xnIz!~Wt+@eX7Hj7`g!Xln zvniW!)U>f?kbqu0Z!%wpnbB zwJXj*jfo~uB;o9$MqP3(k?NKO`Lo(Qh70p*Q4WJ}OhQsqn)scyk-40hH?u<6-P4F) zhGJP2e_Nk|-Q#a#2q0Rtx-2@kuWAO9`Ny}yjvhLbSZLk*iy9@%zbBFbrqkGza? zgx7g4|BVNm`MW92U@Aa8VPj}(N zr2BW$+D7&jEEDb|u+x}JD={^O05~IHor)AS1CO47>&rc^G|Gy{RCd~0RE^c?K8XM+ zk5IgNnxQE1K`-+-!bLss?@v=spzv+7Qh3Qh0mGR5t(^$@=IjZT=+PPk?|RkSQr)yy z+fv&E)VN2$dghcV!ON0_?Q#@%G|kfNoOAbwdK`iDi%1XZ0eJ$>^qstb*PE|?UiZf% zNjv+-`~ED(Bn!lyA0ez0|Jn9?*|3=r$wt%FTZozE8JWwj;L1R-*VpV|DCI(J-{WGs z37waLt3tWg(j{VzODeM^L$mH}F0PJ60Ibc*Pktvl_Zhza_zg1sVjoWnQ7kHQ^oqVgQ@ZIlrlZZkSgx`5uXVNB2_MbZ!gKcU!)tJ$yJ5A5LC? z*Y@Z*uB$1X@&PZu-_B)($I@spBb>w) zYZZj1-LeeHbDvo+Z-#JBNKI49Q&YI*BbfFLm>NRVc?iV7r1S)2oe!cJ4@ohRS2r#C zBAz{G&Yn&W(4;pvHKq{$JLlWm)oUrlCaplYF-Nxe(IZV$5vSyTmX$Fc{7M=&RJ86% z#}j=ZrziOn#`1g84(C#dLaa~(7_LF}{`{O$p-(M!MzY+szOFeL=x#ikeiTgV%uzD9_N4RTafyoJ?aAmhPA`A!C-Ym};B64TZk@ z_q}nejhuYr^P*ov4fZYykEEy+Yd(k z0lblDhBIv-Y*7T>iBF$CQ%y(drQcE9ZGKTG4?&~9bc{?k_D<;DUIYs z+*HA?W0zf;i7S`djpbY)^ud3Kr%r|s5F>k=Z_WDyX>Rr9MHM6Ouofc|&pki?B65um zkY#kNin%_&9?Hf1I5ToK-`|36#9aEwgkh*O*{A5ZG20E0{j4>5F1*N%;3fo<@)!Od z@W)J*i$0BP@NKDE<;FK;K*Su5th|c4cr&0u=T+-&8ys-S-1b6&`HtG^kZTShLT&6q zu8>C-GaZul6B8)F^y2@`4At4+p{zBfTAgru?(v&i3V#N>v>q$Mty?dwT^~HRedMnbMmW zE@A3uoKh?y5;Wd35*u}^VbUf#mD(m=ZksB#$dY>a<-w15b5Z3n6rK}2!4R4+d*5F6=G zjWd6!*i-4&?EBGfe)h^;Cnig^fZPRYfh%5|oi?LI>zzi57YXf|*-ktn{zjO5b?6DQ z=eHq)z2M{S-RCNo+)}jhO9c-1z9$MIgx%>f`-y5MN(n=`nA@K)BwiL}WUb@U)DZ;7 ztcv1`(TqA=B*x8RYT^PK-rw;{ewhckZ?Xc}HR+fCsGSNoI?Qakk=1BzASaj=&=3fe{Ns{S{q1sXMU_h z`D^I&l;u*Lf)(!qDFeH}iO?O{kp)?`l+`Ev5d8V-b&|ca*4Jyy)yCt#&?J1<9m>&5 zn)P1J>-w8pSqdwIJ_uWn_@^ep{Ev6(%?;$Se-Y?)eFd*kH(fGIkkZYn>IoatVqh9w zZ$nSK)Hi1rO|w|~lLDBDz`L*JTJtsd$RH0q@{`)NW{diQEZ4zP5stJq$3~U5$BT^Y z2Shp&`?7?6hf)~+^tSDgjP+!^1?x5H-CF^vNz&=JxWwp%zPgI`` zd3bg+r|r`80AX{*!)=Y{$fU`6tSjXEmGyT*i)B1FWAOpe!{fX*OIPUd9SSPwivp)$ zJxaY7Xz|jg8CpFI-}sNqE7?Q9%K^B!q=-GC(vd>^_FU79Srh>X3%1Gc=$Q=4G7)hR zX&B%Qnn+nY;=??UYrr}bLf9gi(-w$rm!5xPfhrXJj5PFje@XC zLtZS>(3GwigswPK6{Pc+k!8uhAT7Maom>+k3QZ^1l$(o;e0}%ix`OuzLc~4Gu~R|e zT>(dEFoqcHqB-3n=&vD85d!Bf@|IlI?Zt;{(y;t+ zhr%PG)lWkzt2Vq7+5I?_TF{^YMNxV0urpM;>z>Hb=mQCO_Ah!fLN2us!1Z&!7Rz6V zDPhB?DyO{}fE69Qb7!#-QXDYRz?=c$vp$H#b`%zy19QM;K~#zwIVB|?F8C>a%53P+ z?FI#E=ntC4V(0E@pYa$)vvD0Skh7IW4doObou{8SGLgEMgR5#}=hh?Ao(#;&1W7x4 zZb^~iTL#h+y#V`9=U_u9Nb=^1@=O879I%OGRrkrV2x>UJVPuz5Dc7Pkag~c=olyH? z9D-|$;%WB?_!}7~4JGSxhyy+D?bh-g$V%vWw3~7>N|RU&wjR=KIP`aLZN(y(ML!*# z#CSB7?@=oHt75I$LE$Nh+ z+c)H+lteDVV@AQIs1hOA&#zSy z=^ja9P3`NC#Y+T>0~DU*e{K926-Fw|K+M(XBdHFiLC|QGTzNA>mL`vV?8#q3`pb$a zKeKpKpX-#N$O8M;r!c9vWE)4znoy zJy7vH>h^;bK^*~pM9S}hyZzN-Em8H~< z^gZv;K@OT$Acaai#r6`-&2Nkr-hY!J)6v4tICnr)v&cEthm~Vxl8NG`#T(1`U*51> zkjYSlC_qAWQAqfhmhC{SbTt7kF@I_DDZH|+vclP7CnalYt91Q!cwtq_xuFJ(0=_;a zl8iV-je0tB)SXu6Vs#`{#A!VvnSp)Mbk>Q?q1+0hbO4*N7%yEG4}ifxg^2sW>4`NXlexl_;=shti(FY7caoybzKv?7j0 zM~89=^m9+&9z4ykIfd9AKZ%^gZh^{u5wK-T=K~fllRX7?V9UNfw%hTEkXd7zBzeZC zu#b0Smz1N=8k)W6+|M19{rzOZV;n}=^Lu5x42TSzl8{nSx-f76xdkTzNi=zaOs4Ka zBnnosoi^fF*$ceHCMoeEc0Z)e^P2~guTg-`E6X%*5ePfzg+ptchzUv+$)r6dBybPWW0HLoP7TORPi^o^EGB74MD(mxZ4o zqvP*^HGRKwh-jJ|AuwLr>G-Q$d<~1pZlkH7`&MyCDD_;f$#vw67Iwrp055i4p{BO*I^4=jw zDEbQI6^R6!h4NS*kZYJg9^wsb(2rT=Ab?CPJKQRt!cxc%w0S*Fg-8H1n=Q1R`J~rD zu$G+P6xo$?c8#SxCLrV>dtSzQm)d%hu#Qssf_i!)Y;h4f#S{tV?~X;0H74y`go}LQ zO)F3ny&N=q$abG!nwdaru6PD-lJhXre~OJXFH8`8c^_ zQl~9RV#J^?iJm$GhHVC_TZI(retP;mf-xMtDS4Lk%wayEXu_Jn|p$#Zs*%AsWJh%A-I0ePw-2F}O zQqAUshWW%3L*@Bz?3f|y$x37k`{Fxg;HmQ_;N+b|02}mvj6bHWjp{dIOaw28l|Df~ zEmS2Ag@aL0u@T@A#2{A4wQ=3$=dMRQyr2w^_{;61uU~Q_$Kq>Edj5(63k!*esC;@z zd{mBxN&1I=GH}4AG`^X)q|1qxf5CdVL@s=HhMlrO`2~%5K!rs8C!;qTacbOZq*nk6 z!#W|5a+W{EFD8(DQ6;)afxHqh#Z9b!!seLksbkz>Nr@$$W^6wg7$cKBU!JB%i0I63t0lUrz2J!5Ca4SqG><|Vwghel}mf`W}3{r3P&Cn7=e`cRdvEa zS}oWcJGT$=Q>Jc=Xxo>VuHRCW9^LYVp+dsbyzf!e%9E*NLZeB4i@M|!r{w2i`8iAb z?EfNu`Y2E-YBpjI$%Kn-|3^bV04NR+$H(!$g{f7}-i@217i3XV(_RZ$GE*5-)plV5|qJz@+8^>V-t@u5U(0Ru6WjsIF|JgLw$i3H=K z?(0y!qi2|yL?y7t;8d??Gbcz>D&}MMGvY|xob6AC268CHdnI3GndbMS#rD8Jhy=Mj zZt3`-n?bVEqKyU=5@6kk36%Mus0D9BPhxP4*?LBK;AVu&es>V=9v%8VNDS}uFmxDk zlqPISOJPr#Q&wy5M?4gAeC7fA%idFbO~*qXrJOJXgXR_)D1ff=Tm9oAbO*UZGv?BA zhIP#Rs>|=^?QWC*+u-2m+cqe#^Z8>p@8fOU@bk1SYqIlYRB6-yv+v*kzqVz)eM-%> z`F8gxc zfg~rO6C%tNN9kYvw@!MfCWsG+5VQ!)ctznZ2r<|gIhK8qBiVm;;CZmd_>decX*3Uj+(mTVNI#z4@q46w-f_};EiETV2fRkH3Zb8csaqXRP3t=o`Wq+ADGEDjwOALD7*))w5#6^%*U%%lX-lK>f9Zi0 zD6gUfwN7IL6$r=h%msYWo!`Ys2W;gnYc@l~0I|#5`-M-7qer#VT1MQ_tl(;-524() zJvDe`Y#9E2xCT%!wg|X5b*$#5h7n?%vAEoJB2Jrn`8L6pUp%C3lDGCH-p*E=SaX+n zkopo&Of&6>u$yYh_B^(GUXyj585CDgiXI6N6I&tJ#^e(E;_q0~-O+QGyy*G^FR8a( zU(VLRrp)_sBM)YY?+zuw(GlBWW=>*m&Dl6Wvv5%Ci$MQ9mP(hM^cKR2d%~xH#I1d? zpORxov?I^g@fD*<5Vp=H9@W!#mn*1`M}Bqo?r0ZBzj$69(#LG=)3rwQtZd=eRTFYexdAgQ$DfK}*2=L_j5ZC%ebh z`_Tp2&MU@Y2Mm7Xr7O`I$E0`STB#?~ez#4e!z{lR+qz}NxlL&sJNM;6pSxHoU-0Ii zt#*Z5+f2(@{;Y##j>%F_&ha{{+{*^QN)zOLn+#4!n3 zPdp|5rc$t80c`2c9LCMBpPwm@m6dy8wQ8eAvZ+N3F)!)3NuD1PxtoA?o^E^qC1* zu|u@)oDr=x)xTEZ zAG11nc9n#DUJ^hPPrb8RU2m31on9ZWWIms7>vWyI?rD)qh5`cNmz!AImCPFs|B#tC z&39%W9iskj(b~4&q-^j-6K{0b#WDkZozR-r4g4+{-!GntJf1Hvxptq~nGGhRwYoL~ zh&w$NA)4-I8f^sqCuRVayMT6Yl}J#YKTS^)bDq`?Q>D|r#y;rq*~UunqT_c{reWII zVP-?+2XFM_KB1(m0y0B&2v1jAqi*MNfcGk_+~XInv3*-l2V+R1o5kw7ozUy;n``4q zN2ZFpBVx&9IZE{7iw|+xvD&IBqi=xWnkV$~WFv^@cA(+U)yC=h#=C|2M-^>LSnc!t zKiRG!=XTD@|;fPa9MW2ZMnh(*QDHpPz>H#L%Wf1 zfK|K62g`S_TIizAr{c_)t+czckzGOay3VBuE4)fZ?WWV+SIfL(zcK3x?#-i0Ea314 z|Fbzxi`>RNpf85g%M3e?*r3aOVMKMsfq6p6dBSJylJ{|y*v3(a*z)vGllcMAGR7(n z=TTCri%fM{(Y1YlF8Kz>f{Z%lCYJNQofQ^r_1l6$xz$x*Z!iu9>UO# z4MW$!e+Y}!-}cXd{E>*k z1XlCzPrtm*x_^GvH1YX7V{drN^vYfP5ATD_4)#%ym21xHc^sfQFRspYah1&(#6Dp5 z3`jMcJ$d^oB&A=`P51J4Pd?b>e%%e~zQUW5{C<5=Qt;Kb;ZEqmx}H}*{dVZV`v2Bj zjAsID7OHgW{#$9QeHiRAVm3}z|DVYJPGL|b;KDTRz;k(2;Musz zM*TQtIz8~Vn?oOGl}os)-+po_^yB)s*!lcwS$mzB)ux_jGIMtRCuEwSQ^4fDX&$rx z*+u^fF4ou2h)oxJ?w1p97uS1D;nu?ro&3(BI!#e|KF$x+?5_;Fg;CyndAWVg&#x`m z2+(h;A0Mh8ex5hqZ9q?F>)4wUS>8>~^i8)1&p*4cHpgPm%B<1so1KoGI_9~U_hGY%xCb3NgkqC^`L^Dw*4?K~zU{3fPwE@!{!z!5JpYqZ zZ!D^1Ap3Bj%$Hw#S@Cq|Is4>;%!%v%y6!tXk@z{>ko5CE?0!WY$a-bmSBa&4V^V*&93wf;Pc)qtah zzUAm(-Nni}!+EIt=XF72k(*BNiRBCDNzq>2De!g2|Ga6IV*?cwtIWV2pPA*tvs)B` zRQ=gejoe;+-tOdK=VzO?)eCoFI?6!{Jp9?5N2TO&`eAtHUln)JICnv*e=NId<`)1+ z(*@W}pfEA6&BuH?)QhP1t$uvoWb0vnEX3+g{LsPa;q$=f;~SNTu|zFVV>QZj!pxZT zv9zZcOuGQ#VWZ-g6#D z_uhci=E;BqXZkOyFP;H4d6wlpRe2WLJUh0Fhql*nQnbo2g?%GyGmA6FQ>t{^y9j2# zjYfDN{OlGwy z2_R%0G;HYpmHRaOz5mBlPq;sPd=RZC%{4`$HtYT8Y8 z+Rb%ZQ_xQX#gBD(sBW4k-K&Z%_HJzG_N2+p?OVl(1IS<_3?IfP^{b5hB*VKP5f->k zEFZcj`Ke(I&u$VNNJDr*OdqNzQOPc!4@JSx14k8yJ+KYg@VD=uZby$zaUI}9_v1n@ zW&W1qnGNubpuDxWr*q=Z>+AEwNkPAt?bXZ9&!@CJ!F8X96mOGoLboO3|EU=C@p-?U Q6#66vCX~C@C&7OEUtKH1ZvX%Q diff --git a/mmjson_verification/verify_mmjson.py b/mmjson_verification/verify_mmjson.py deleted file mode 100644 index 9e5f6244..00000000 --- a/mmjson_verification/verify_mmjson.py +++ /dev/null @@ -1,101 +0,0 @@ - -import sys -from pathlib import Path -import numpy as np -import logging - -# Configure logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger("verify_mmjson") - -try: - from atomworks.io.parser import parse - from atomworks.io.utils.io_utils import infer_pdb_file_type -except ImportError: - # Add src to path if running from root without package installed in editable mode - sys.path.append(str(Path(__file__).parent.parent / "src")) - from atomworks.io.parser import parse - from atomworks.io.utils.io_utils import infer_pdb_file_type - -PROJECT_ROOT = Path(__file__).parent.parent -EXAMPLE_DIR = Path(__file__).parent - -def verify_mmjson_parsing(): - print("Starting mmJSON verification...") - - json_path = EXAMPLE_DIR / "2hhb.json.gz" - cif_path = EXAMPLE_DIR / "2hhb.cif.gz" - - if not json_path.exists(): - print(f"Error: mmJSON file not found at {json_path}") - return - if not cif_path.exists(): - print(f"Error: CIF file not found at {cif_path}") - return - - # 1. Test File Type Inference - print("\n1. Testing File Type Inference...") - inferred_type = infer_pdb_file_type(json_path) - if inferred_type == "mmjson": - print(f"✅ Correctly inferred 'mmjson' from {json_path.name}") - else: - print(f"❌ Failed to infer 'mmjson'. Got: {inferred_type}") - - # 2. Parse mmJSON - print("\n2. Parsing mmJSON file...") - try: - result_json = parse(json_path, file_type="mmjson") - atoms_json = result_json["asym_unit"] - print(f"✅ Successfully parsed mmJSON. Loaded {atoms_json.array_length()} atoms.") - except Exception as e: - print(f"❌ Failed to parse mmJSON: {e}") - return - - # 3. Parse CIF for Comparison - print("\n3. Parsing CIF file for comparison...") - try: - result_cif = parse(cif_path, file_type="cif") - atoms_cif = result_cif["asym_unit"] - print(f"✅ Successfully parsed CIF. Loaded {atoms_cif.array_length()} atoms.") - except Exception as e: - print(f"❌ Failed to parse CIF: {e}") - return - - # 4. Compare Results - print("\n4. Comparing mmJSON vs CIF results...") - - # Compare Atom Count - if atoms_json.array_length() == atoms_cif.array_length(): - print("✅ Atom count matches.") - else: - print(f"❌ Atom count mismatch: JSON {atoms_json.array_length()} != CIF {atoms_cif.array_length()}") - - # Compare Coordinates - try: - np.testing.assert_allclose(atoms_json.coord, atoms_cif.coord, rtol=1e-3, atol=1e-3) - print("✅ Coordinates match (within tolerance).") - except AssertionError as e: - print(f"❌ Coordinates mismatch: {e}") - - # Compare Elements - if np.array_equal(atoms_json.element, atoms_cif.element): - print("✅ Elements match.") - else: - print("❌ Elements mismatch.") - - # Compare Residue Names - if np.array_equal(atoms_json.res_name, atoms_cif.res_name): - print("✅ Residue names match.") - else: - print("❌ Residue names mismatch.") - - # Compare Chain IDs - if np.array_equal(atoms_json.chain_id, atoms_cif.chain_id): - print("✅ Chain IDs match.") - else: - print("❌ Chain IDs mismatch.") - - print("\nVerification finished.") - -if __name__ == "__main__": - verify_mmjson_parsing() diff --git a/src/atomworks/io/utils/io_utils.py b/src/atomworks/io/utils/io_utils.py index b2eee443..dd230669 100644 --- a/src/atomworks/io/utils/io_utils.py +++ b/src/atomworks/io/utils/io_utils.py @@ -332,6 +332,25 @@ def get_structure( return atom_array_stack +def _infer_file_type_from_buffer(buffer: io.BytesIO | io.StringIO) -> str: + """Infer file type from buffer contents.""" + if isinstance(buffer, io.BytesIO): + return "bcif" + + # StringIO - peek at contents to determine format + buffer.seek(0) + first_char = buffer.read(1) + buffer.readline() # finish first line + second_line = buffer.readline() + buffer.seek(0) + + if first_char == "{": + return "mmjson" + if second_line.startswith("#"): + return "cif" + return "pdb" + + def infer_pdb_file_type( path_or_buffer: os.PathLike | io.StringIO | io.BytesIO, ) -> Literal["cif", "pdb", "bcif", "sdf", "mmjson"]: @@ -343,24 +362,8 @@ def infer_pdb_file_type( path_or_buffer = Path(path_or_buffer) # Determine file type and open context - if isinstance(path_or_buffer, io.BytesIO): - return "bcif" - elif isinstance(path_or_buffer, io.StringIO): - # ... if second line starts with '#', it is very likely a cif file - path_or_buffer.seek(0) - path_or_buffer.readline() # Skip the first line - second_line = path_or_buffer.readline().strip() - path_or_buffer.seek(0) - path_or_buffer.seek(0) - if second_line.startswith("#"): - return "cif" - # Check for JSON start - path_or_buffer.seek(0) - first_char = path_or_buffer.read(1) - path_or_buffer.seek(0) - if first_char == "{": - return "mmjson" - return "pdb" + if isinstance(path_or_buffer, io.StringIO | io.BytesIO): + return _infer_file_type_from_buffer(path_or_buffer) elif isinstance(path_or_buffer, Path): if path_or_buffer.suffix in (".gz", ".gzip"): inferred_file_type = Path(path_or_buffer.stem).suffix.lstrip(".") @@ -421,7 +424,7 @@ def read_any( # Determine file type if file_type is None: file_type = infer_pdb_file_type(path_or_buffer) - + open_mode = "rb" if file_type == "bcif" else "rt" # Convert string paths to Path objects and decompress if necessary @@ -446,7 +449,7 @@ def read_any( if isinstance(path_or_buffer, io.StringIO | io.BytesIO): return _read_mmjson(path_or_buffer) else: - with open(path_or_buffer, "r") as f: + with open(path_or_buffer) as f: return _read_mmjson(f) else: raise ValueError(f"Unsupported file type: {file_type}") diff --git a/tests/io/tools/test_mmjson.py b/tests/io/tools/test_mmjson.py new file mode 100644 index 00000000..346a811a --- /dev/null +++ b/tests/io/tools/test_mmjson.py @@ -0,0 +1,33 @@ +from pathlib import Path + +from atomworks.io.parser import parse +from atomworks.io.utils.io_utils import infer_pdb_file_type +from atomworks.io.utils.testing import assert_same_atom_array + +# Tests should look for data relative to their location or use a fixture +# Based on project structure, tests/data is likely where we moved the files +TEST_DATA_DIR = Path(__file__).parent.parent.parent / "data" / "io" + + +def test_mmjson_inference_and_parsing(): + json_path = TEST_DATA_DIR / "2hhb.json.gz" + cif_path = TEST_DATA_DIR / "2hhb.cif.gz" + + assert json_path.exists(), f"mmJSON file not found at {json_path}" + assert cif_path.exists(), f"CIF file not found at {cif_path}" + + # 1. Test File Type Inference + inferred_type = infer_pdb_file_type(json_path) + assert inferred_type == "mmjson", f"Failed to infer 'mmjson'. Got: {inferred_type}" + + # 2. Parse mmJSON + result_json = parse(json_path, file_type="mmjson") + atoms_json = result_json["asym_unit"] + + # 3. Parse CIF for Comparison + result_cif = parse(cif_path, file_type="cif") + atoms_cif = result_cif["asym_unit"] + + # 4. Compare Results + # This utility checks atom count, coordinates, and other annotations + assert_same_atom_array(atoms_json, atoms_cif) From b37aaf9110524e80fd07cdcbd4805b318d7da73b Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Fri, 12 Dec 2025 09:02:14 +0900 Subject: [PATCH 4/6] test: add 2hhb mmJSON and CIF test data and update test to use shared data directory fixture --- tests/data/io/2hhb.cif.gz | Bin 0 -> 131968 bytes tests/data/io/2hhb.json.gz | Bin 0 -> 85741 bytes tests/io/tools/test_mmjson.py | 9 +++------ 3 files changed, 3 insertions(+), 6 deletions(-) create mode 100644 tests/data/io/2hhb.cif.gz create mode 100644 tests/data/io/2hhb.json.gz diff --git a/tests/data/io/2hhb.cif.gz b/tests/data/io/2hhb.cif.gz new file mode 100644 index 0000000000000000000000000000000000000000..19767c42f907f39b856ba9342aca7c6ee679d666 GIT binary patch literal 131968 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 Q6#66vCX~C@C&7OEUtKH1ZvX%Q literal 0 HcmV?d00001 diff --git a/tests/io/tools/test_mmjson.py b/tests/io/tools/test_mmjson.py index 346a811a..6fcd0e65 100644 --- a/tests/io/tools/test_mmjson.py +++ b/tests/io/tools/test_mmjson.py @@ -1,17 +1,14 @@ -from pathlib import Path from atomworks.io.parser import parse from atomworks.io.utils.io_utils import infer_pdb_file_type from atomworks.io.utils.testing import assert_same_atom_array -# Tests should look for data relative to their location or use a fixture -# Based on project structure, tests/data is likely where we moved the files -TEST_DATA_DIR = Path(__file__).parent.parent.parent / "data" / "io" +from tests.conftest import TEST_DATA_DIR def test_mmjson_inference_and_parsing(): - json_path = TEST_DATA_DIR / "2hhb.json.gz" - cif_path = TEST_DATA_DIR / "2hhb.cif.gz" + json_path = TEST_DATA_DIR / "io" / "2hhb.json.gz" + cif_path = TEST_DATA_DIR / "io" / "2hhb.cif.gz" assert json_path.exists(), f"mmJSON file not found at {json_path}" assert cif_path.exists(), f"CIF file not found at {cif_path}" From 16e6a6f4013ff2163019cf9bde0e03982d330c68 Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Fri, 12 Dec 2025 16:30:44 +0900 Subject: [PATCH 5/6] style: apply ruff formatting and lint fixes --- .../examples/load_and_visualize_structures.py | 2 +- src/atomworks/biotite_patch.py | 2 +- src/atomworks/io/parser.py | 6 +- src/atomworks/io/tools/rdkit.py | 6 +- src/atomworks/io/transforms/categories.py | 6 +- src/atomworks/io/utils/assembly.py | 6 +- src/atomworks/io/utils/atom_array_plus.py | 12 +-- src/atomworks/io/utils/query.py | 2 +- src/atomworks/io/utils/testing.py | 18 ++--- src/atomworks/ml/datasets/concat_dataset.py | 6 +- src/atomworks/ml/encoding_definitions.py | 24 +++--- src/atomworks/ml/pipelines/af3.py | 6 +- src/atomworks/ml/pipelines/rf2aa.py | 6 +- src/atomworks/ml/preprocessing/msa/finding.py | 2 +- src/atomworks/ml/samplers.py | 6 +- .../ml/transforms/af3_reference_molecule.py | 6 +- src/atomworks/ml/transforms/atom_array.py | 24 +++--- .../ml/transforms/atom_level_embeddings.py | 6 +- src/atomworks/ml/transforms/base.py | 12 +-- .../transforms/center_random_augmentation.py | 6 +- src/atomworks/ml/transforms/crop.py | 24 +++--- src/atomworks/ml/transforms/design_task.py | 2 +- .../transforms/diffusion/batch_structures.py | 6 +- src/atomworks/ml/transforms/diffusion/edm.py | 6 +- src/atomworks/ml/transforms/dna/pad_dna.py | 6 +- src/atomworks/ml/transforms/filters.py | 6 +- src/atomworks/ml/transforms/mask_generator.py | 36 ++++----- src/atomworks/ml/transforms/masks.py | 6 +- .../ml/transforms/msa/_msa_pairing_utils.py | 6 +- src/atomworks/ml/transforms/msa/msa.py | 6 +- .../ml/transforms/openbabel_utils.py | 6 +- src/atomworks/ml/transforms/rdkit_utils.py | 6 +- .../ml/transforms/rf2aa_assumptions.py | 60 +++++++------- src/atomworks/ml/transforms/symmetry.py | 6 +- src/atomworks/ml/transforms/template.py | 60 +++++++------- src/atomworks/ml/utils/misc.py | 6 +- src/atomworks/ml/utils/numpy.py | 12 +-- src/atomworks/ml/utils/rng.py | 6 +- src/atomworks/ml/utils/token.py | 18 ++--- src/atomworks_cli/find.py | 2 +- tests/io/components/test_chain_types.py | 12 +-- .../io/components/test_entity_annotations.py | 12 +-- tests/io/components/test_identifiers.py | 6 +- tests/io/components/test_ignore_residues.py | 12 +-- tests/io/components/test_logging.py | 12 +-- tests/io/tools/test_inference_processing.py | 6 +- tests/io/tools/test_mmjson.py | 2 - tests/io/tools/test_rdkit.py | 12 +-- tests/io/utils/test_scatter.py | 42 +++++----- tests/io/utils/test_testing_tools.py | 6 +- tests/ml/conditions/test_annotator.py | 6 +- .../ml/conditions/test_condition_save_load.py | 16 ++-- .../ml/datasets/test_datasets_with_filters.py | 30 +++---- .../pipelines/test_data_loading_pipelines.py | 12 +-- .../ml/pipelines/test_inference_pipelines.py | 18 ++--- .../ml/pipelines/test_pipeline_regression.py | 12 +-- .../preprocessing/test_filtering_criteria.py | 6 +- tests/ml/preprocessing/test_get_atom_mask.py | 6 +- tests/ml/preprocessing/test_loi_extraction.py | 6 +- tests/ml/transforms/msa/test_featurize_msa.py | 72 ++++++++--------- tests/ml/transforms/msa/test_load_msas.py | 24 +++--- .../symmetry/test_automorphisms_networkx.py | 24 +++--- .../transforms/test_af3_reference_molecule.py | 39 +++++----- tests/ml/transforms/test_atom_array.py | 18 ++--- .../transforms/test_atom_level_embeddings.py | 12 +-- tests/ml/transforms/test_bonds.py | 18 ++--- .../transforms/test_confidence_transforms.py | 12 +-- tests/ml/transforms/test_crop.py | 72 ++++++++--------- tests/ml/transforms/test_encodings.py | 48 ++++++------ .../test_featurize_unresolved_residues.py | 6 +- tests/ml/transforms/test_filters.py | 30 +++---- tests/ml/transforms/test_rdkit_transforms.py | 6 +- tests/ml/transforms/test_rdkit_utils.py | 12 +-- tests/ml/transforms/test_templates.py | 78 +++++++++---------- tests/ml/transforms/test_token_utils.py | 24 +++--- tests/ml/utils/test_misc_utils.py | 12 +-- tests/ml/utils/test_rng_context.py | 24 +++--- 77 files changed, 608 insertions(+), 607 deletions(-) diff --git a/docs/examples/load_and_visualize_structures.py b/docs/examples/load_and_visualize_structures.py index 5841e48a..1421c200 100644 --- a/docs/examples/load_and_visualize_structures.py +++ b/docs/examples/load_and_visualize_structures.py @@ -82,7 +82,7 @@ print("Available annotations:") annotations = atom_array.get_annotation_categories() for i, annotation in enumerate(annotations): - print(f" {i+1:2d}. {annotation}") + print(f" {i + 1:2d}. {annotation}") # %% diff --git a/src/atomworks/biotite_patch.py b/src/atomworks/biotite_patch.py index 96c99828..28de1faa 100644 --- a/src/atomworks/biotite_patch.py +++ b/src/atomworks/biotite_patch.py @@ -184,7 +184,7 @@ def array(atoms: list[Atom]) -> AtomArray: for i, atom in enumerate(atoms): if sorted(atom._annot.keys()) != names: raise ValueError( - f"The atom at index {i} does not share the same " f"annotation categories as the atom at index 0" + f"The atom at index {i} does not share the same annotation categories as the atom at index 0" ) array = AtomArray(len(atoms)) diff --git a/src/atomworks/io/parser.py b/src/atomworks/io/parser.py index d57e75fe..399d70c6 100644 --- a/src/atomworks/io/parser.py +++ b/src/atomworks/io/parser.py @@ -637,9 +637,9 @@ def parse_atom_array( # ... build assemblies and add assembly-specific annotations (instance IDs like `chain_iid`, `pn_unit_iid`, `molecule_iid`) if exists(build_assembly): - assert build_assembly in ["first", "all"] or isinstance( - build_assembly, list | tuple - ), "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." + assert build_assembly in ["first", "all"] or isinstance(build_assembly, list | tuple), ( + "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." + ) # Determine assembly categories: use CIF data if build_assembly is set, otherwise identity operations if exists(build_assembly) and exists(_cif_file) and "pdbx_struct_assembly" in data_dict["cif_block"]: diff --git a/src/atomworks/io/tools/rdkit.py b/src/atomworks/io/tools/rdkit.py index 03ef2e07..6e4f679f 100644 --- a/src/atomworks/io/tools/rdkit.py +++ b/src/atomworks/io/tools/rdkit.py @@ -762,9 +762,9 @@ def atom_array_to_rdkit( # ... verify that atoms that are labelled as `_should_be_aromatic` are aromatic for atom_idx in _should_be_aromatic: - assert mol.GetAtomWithIdx( - atom_idx - ).GetIsAromatic(), f"Atom {atom_idx} is not aromatic but was labelled as aromatic." + assert mol.GetAtomWithIdx(atom_idx).GetIsAromatic(), ( + f"Atom {atom_idx} is not aromatic but was labelled as aromatic." + ) # Turn into a non-editable molecule mol = mol.GetMol() if isinstance(mol, Chem.RWMol) else mol diff --git a/src/atomworks/io/transforms/categories.py b/src/atomworks/io/transforms/categories.py index eabea63a..171a9702 100644 --- a/src/atomworks/io/transforms/categories.py +++ b/src/atomworks/io/transforms/categories.py @@ -158,9 +158,9 @@ def get_metadata_from_category(cif_block: CIFBlock, fallback_id: str | None = No metadata = {} # Assert that if the "entry.id" field is NOT present, a fallback ID is provided - assert ( - "entry" in cif_block and "id" in cif_block["entry"] - ) or fallback_id is not None, "No ID found in CIF block or provided as fallback." + assert ("entry" in cif_block and "id" in cif_block["entry"]) or fallback_id is not None, ( + "No ID found in CIF block or provided as fallback." + ) # Set the ID field, using the fallback if necessary metadata["id"] = ( diff --git a/src/atomworks/io/utils/assembly.py b/src/atomworks/io/utils/assembly.py index b6e7ccb7..e25c326f 100644 --- a/src/atomworks/io/utils/assembly.py +++ b/src/atomworks/io/utils/assembly.py @@ -119,9 +119,9 @@ def _build_bioassembly_from_asym_unit( to_build = available_assembly_ids else: # Assert that the given `assembly_ids` are valid - assert isinstance(assembly_ids, list | tuple) and all( - isinstance(_id, str) for _id in assembly_ids - ), "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." + assert isinstance(assembly_ids, list | tuple) and all(isinstance(_id, str) for _id in assembly_ids), ( + "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." + ) to_build = assembly_ids # ensure instructions for each requested assembly id exist diff --git a/src/atomworks/io/utils/atom_array_plus.py b/src/atomworks/io/utils/atom_array_plus.py index ec5dbc70..d3307908 100644 --- a/src/atomworks/io/utils/atom_array_plus.py +++ b/src/atomworks/io/utils/atom_array_plus.py @@ -928,9 +928,9 @@ def insert_atoms( The function is robust to both AtomArray and AtomArrayPlus, and preserves 2D annotations and bonds. """ n_atoms_orig = arr.array_length() - assert isinstance(new_atoms, list) and isinstance( - new_atoms[0], AtomArray | AtomArrayPlus | struc.Atom - ), "new_atoms must be a list of AtomArray, AtomArrayPlus, or Atom objects." + assert isinstance(new_atoms, list) and isinstance(new_atoms[0], AtomArray | AtomArrayPlus | struc.Atom), ( + "new_atoms must be a list of AtomArray, AtomArrayPlus, or Atom objects." + ) assert len(new_atoms) == len(insert_positions), "Each new atom must have a corresponding insert position." arr_all = concatenate_any([arr, *new_atoms]) @@ -954,9 +954,9 @@ def insert_atoms( if pos < n_atoms_orig: result_indices.append(orig_idx) orig_idx += 1 - assert ( - len(result_indices) == arr_all.array_length() - ), "Result indices must match the length of the concatenated array" + assert len(result_indices) == arr_all.array_length(), ( + "Result indices must match the length of the concatenated array" + ) return arr_all[result_indices] diff --git a/src/atomworks/io/utils/query.py b/src/atomworks/io/utils/query.py index 9ce41249..5bc29ec3 100644 --- a/src/atomworks/io/utils/query.py +++ b/src/atomworks/io/utils/query.py @@ -200,7 +200,7 @@ def _ensure_bool_array(mask: Any, expected_length: int) -> np.ndarray: # Check length if len(mask) != expected_length: raise ValueError( - f"Query resulted in mask of length {len(mask)}, " f"but AtomArray has length {expected_length}" + f"Query resulted in mask of length {len(mask)}, but AtomArray has length {expected_length}" ) return mask diff --git a/src/atomworks/io/utils/testing.py b/src/atomworks/io/utils/testing.py index 582abd3d..abbb7e7e 100644 --- a/src/atomworks/io/utils/testing.py +++ b/src/atomworks/io/utils/testing.py @@ -189,12 +189,12 @@ def assert_same_atom_array( Raises: AssertionError: If the AtomArray objects are not equal. """ - assert isinstance( - arr1, AtomArray | AtomArrayStack - ), f"arr1 is not an AtomArray or AtomArrayStack but has type {type(arr1)}" - assert isinstance( - arr2, AtomArray | AtomArrayStack - ), f"arr2 is not an AtomArray or AtomArrayStack but has type {type(arr2)}" + assert isinstance(arr1, AtomArray | AtomArrayStack), ( + f"arr1 is not an AtomArray or AtomArrayStack but has type {type(arr1)}" + ) + assert isinstance(arr2, AtomArray | AtomArrayStack), ( + f"arr2 is not an AtomArray or AtomArrayStack but has type {type(arr2)}" + ) # Copy both arrays to avoid modifying the original arrays arr1 = arr1.copy() @@ -231,9 +231,9 @@ def assert_same_atom_array( raise AssertionError(msg) if compare_coords: - assert ( - arr1.coord.shape == arr2.coord.shape - ), f"Coord shapes do not match: {arr1.coord.shape} != {arr2.coord.shape}" + assert arr1.coord.shape == arr2.coord.shape, ( + f"Coord shapes do not match: {arr1.coord.shape} != {arr2.coord.shape}" + ) if not np.allclose(arr1.coord, arr2.coord, equal_nan=True, atol=1e-3, rtol=1e-3): mismatch_idxs = np.where(arr1.coord != arr2.coord)[0] msg = f"Coords do not match at {len(mismatch_idxs)} indices. First few mismatches:" + "\n" diff --git a/src/atomworks/ml/datasets/concat_dataset.py b/src/atomworks/ml/datasets/concat_dataset.py index d4f15178..83b70265 100644 --- a/src/atomworks/ml/datasets/concat_dataset.py +++ b/src/atomworks/ml/datasets/concat_dataset.py @@ -222,7 +222,7 @@ def __getitem__(self, idxs: tuple[int, ...]) -> Any: for i, idx in enumerate(idxs): dataset = self.dataset if i == 0 else self.fallback_dataset - dataset_name = "Primary dataset" if i == 0 else f"Fallback {i}/{len(idxs)-1}" + dataset_name = "Primary dataset" if i == 0 else f"Fallback {i}/{len(idxs) - 1}" try: return dataset[idx] @@ -238,11 +238,11 @@ def __getitem__(self, idxs: tuple[int, ...]) -> Any: # Log fallback attempt if not the last one if i < len(idxs) - 1: - logger.warning(f"({dataset_name}): Trying fallback index {idxs[i+1]}.{example_id}") + logger.warning(f"({dataset_name}): Trying fallback index {idxs[i + 1]}.{example_id}") # All attempts failed logger.error( - f"(Exceeded all {len(idxs)-1} fallbacks. Training will crash now. Errors: {error_list} for examples: {example_id_list})" + f"(Exceeded all {len(idxs) - 1} fallbacks. Training will crash now. Errors: {error_list} for examples: {example_id_list})" ) raise RuntimeError(f"All attempts failed for indices {idxs}. See error_list for details.") from ExceptionGroup( "All fallback attempts failed", error_list diff --git a/src/atomworks/ml/encoding_definitions.py b/src/atomworks/ml/encoding_definitions.py index 04a08deb..dc728c6a 100644 --- a/src/atomworks/ml/encoding_definitions.py +++ b/src/atomworks/ml/encoding_definitions.py @@ -83,15 +83,15 @@ def __post_init__(self): # Ensure all values are of type `np.ndarray` and have the same 1-dimensional shape _target_len = len(next(iter(self.token_atoms.values()))) for token, atoms in self.token_atoms.items(): - assert isinstance( - atoms, np.ndarray - ), f"Expected `atoms` to be a `np.ndarray`, but got {type(atoms)} for token {token}." - assert ( - atoms.ndim == 1 - ), f"Expected `atoms` to be a 1-dimensional array, but got {atoms.ndim} dimensions for token {token}." - assert ( - len(atoms) == _target_len - ), f"Expected all atoms to have length {_target_len}, but got {len(atoms)} for token {token}." + assert isinstance(atoms, np.ndarray), ( + f"Expected `atoms` to be a `np.ndarray`, but got {type(atoms)} for token {token}." + ) + assert atoms.ndim == 1, ( + f"Expected `atoms` to be a 1-dimensional array, but got {atoms.ndim} dimensions for token {token}." + ) + assert len(atoms) == _target_len, ( + f"Expected all atoms to have length {_target_len}, but got {len(atoms)} for token {token}." + ) # Define mapping of unknown `chemcomp_type` to unknown token names if not exists(self.chemcomp_type_to_unknown): @@ -112,9 +112,9 @@ def __post_init__(self): # NOTE: This is set here to use caching. @lru_cache(maxsize=10000) def resolve_unknown_token_name(token_name: str | int, token_is_atom: bool) -> str: - assert isinstance( - token_name, str | int | np.integer - ), f"Expected `token_name` to be a string or int, but got {type(token_name)}: token_name={token_name}, token_is_atom={token_is_atom}." + assert isinstance(token_name, str | int | np.integer), ( + f"Expected `token_name` to be a string or int, but got {type(token_name)}: token_name={token_name}, token_is_atom={token_is_atom}." + ) # Case 1: Token is known & valid if token_name in self.token_atoms: diff --git a/src/atomworks/ml/pipelines/af3.py b/src/atomworks/ml/pipelines/af3.py index 0a2c4e97..cc890b33 100644 --- a/src/atomworks/ml/pipelines/af3.py +++ b/src/atomworks/ml/pipelines/af3.py @@ -178,9 +178,9 @@ def build_af3_transform_pipeline( """ if (crop_contiguous_probability > 0 or crop_spatial_probability > 0) and not is_inference: - assert np.isclose( - crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6 - ), "Crop probabilities must sum to 1.0" + assert np.isclose(crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6), ( + "Crop probabilities must sum to 1.0" + ) assert crop_size > 0, "Crop size must be greater than 0" assert crop_center_cutoff_distance > 0, "Crop center cutoff distance must be greater than 0" diff --git a/src/atomworks/ml/pipelines/rf2aa.py b/src/atomworks/ml/pipelines/rf2aa.py index a36d421d..3f429393 100644 --- a/src/atomworks/ml/pipelines/rf2aa.py +++ b/src/atomworks/ml/pipelines/rf2aa.py @@ -276,9 +276,9 @@ def build_rf2aa_transform_pipeline( Compose: A composed transformation pipeline. """ if crop_contiguous_probability > 0 or crop_spatial_probability > 0: - assert np.isclose( - crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6 - ), "Crop probabilities must sum to 1.0" + assert np.isclose(crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6), ( + "Crop probabilities must sum to 1.0" + ) assert crop_size > 0, "Crop size must be greater than 0" assert crop_center_cutoff_distance > 0, "Crop center cutoff distance must be greater than 0" diff --git a/src/atomworks/ml/preprocessing/msa/finding.py b/src/atomworks/ml/preprocessing/msa/finding.py index 27aa118f..6f4f0d38 100644 --- a/src/atomworks/ml/preprocessing/msa/finding.py +++ b/src/atomworks/ml/preprocessing/msa/finding.py @@ -110,7 +110,7 @@ def _build_msa_file_paths( for shard_depth in shard_depths: # Build shard path like "ab/cd/" for depth 2 with hash "abcd123..." - shard_path = "".join([f"{sequence_hash[(i*2):(i+1)*2]}/" for i in range(shard_depth)]) + shard_path = "".join([f"{sequence_hash[(i * 2) : (i + 1) * 2]}/" for i in range(shard_depth)]) for extension in extensions: file_path = msa_dir / shard_path / f"{sequence_hash}{extension}" diff --git a/src/atomworks/ml/samplers.py b/src/atomworks/ml/samplers.py index e47ba0ed..fe31e8cf 100644 --- a/src/atomworks/ml/samplers.py +++ b/src/atomworks/ml/samplers.py @@ -319,9 +319,9 @@ def _set_num_examples_per_epoch(self, n_examples_per_epoch: int) -> None: # ... and assert that either we have more than n_examples_per_epoch examples or we are sampling with replacement sampler_has_enough_data = len(sampler) >= n_examples sampler_is_replacement = getattr(sampler, "replacement", False) - assert ( - sampler_has_enough_data or sampler_is_replacement - ), "Must either have enough data or be sampling with replacement" + assert sampler_has_enough_data or sampler_is_replacement, ( + "Must either have enough data or be sampling with replacement" + ) def __iter__(self): # Trigger the __iter__ of each sampler upfront (generates a list of local indices based on the sampling scheme) diff --git a/src/atomworks/ml/transforms/af3_reference_molecule.py b/src/atomworks/ml/transforms/af3_reference_molecule.py index 05d707a3..fb270b66 100644 --- a/src/atomworks/ml/transforms/af3_reference_molecule.py +++ b/src/atomworks/ml/transforms/af3_reference_molecule.py @@ -432,9 +432,9 @@ def get_af3_reference_molecule_features( ref_atom_name_chars = _encode_atom_names_like_af3(atom_array.atom_name) if use_element_for_atom_names_of_atomized_tokens: - assert ( - "atomize" in atom_array.get_annotation_categories() - ), "Atomize annotation is required when using element for atom names of atomized tokens." + assert "atomize" in atom_array.get_annotation_categories(), ( + "Atomize annotation is required when using element for atom names of atomized tokens." + ) ref_atom_name_chars[atom_array.atomize] = _encode_atom_names_like_af3(atom_array.element[atom_array.atomize]) # ... space uid (type conversion needed for some older torch versions) diff --git a/src/atomworks/ml/transforms/atom_array.py b/src/atomworks/ml/transforms/atom_array.py index f317bb89..2afdc1a3 100644 --- a/src/atomworks/ml/transforms/atom_array.py +++ b/src/atomworks/ml/transforms/atom_array.py @@ -379,9 +379,9 @@ def copy_annotation(atom_array: AtomArray, annotation_to_copy: str, new_annotati updated_atom_array = copy_annotation(atom_array, "coord", "coord_to_be_noised") """ - assert ( - new_annotation not in atom_array.get_annotation_categories() and new_annotation != "coord" - ), f"Annotation {new_annotation} already exists in the AtomArray." + assert new_annotation not in atom_array.get_annotation_categories() and new_annotation != "coord", ( + f"Annotation {new_annotation} already exists in the AtomArray." + ) if annotation_to_copy == "coord": # We must handle the special case of copying the coordinates (since "coord" is not technically an annotation) @@ -400,12 +400,12 @@ def __init__(self, annotation_to_copy: str, new_annotation: str): self.new_annotation = new_annotation def check_input(self, data: dict) -> None: - assert has_annotation( - data["atom_array"], self.annotation_to_copy - ), f"Annotation {self.annotation_to_copy} does not exist in the AtomArray." - assert not has_annotation( - data["atom_array"], self.new_annotation - ), f"Annotation {self.new_annotation} already exists in the AtomArray." + assert has_annotation(data["atom_array"], self.annotation_to_copy), ( + f"Annotation {self.annotation_to_copy} does not exist in the AtomArray." + ) + assert not has_annotation(data["atom_array"], self.new_annotation), ( + f"Annotation {self.new_annotation} already exists in the AtomArray." + ) def forward(self, data: dict) -> dict: data["atom_array"] = copy_annotation( @@ -643,9 +643,9 @@ def sort_like_rf2aa(atom_array: AtomArray) -> AtomArray: pn_unit_mask = atom_array.pn_unit_iid == pn_unit_iid is_bonded_non_poly[pn_unit_mask] = np.any(is_poly[pn_unit_mask]) & is_non_poly[pn_unit_mask] is_free_non_poly = is_non_poly & (~is_bonded_non_poly) - assert np.sum(is_poly) + np.sum(is_bonded_non_poly) + np.sum(is_free_non_poly) == len( - atom_array - ), "overlapping groups" + assert np.sum(is_poly) + np.sum(is_bonded_non_poly) + np.sum(is_free_non_poly) == len(atom_array), ( + "overlapping groups" + ) # Sort by indexing according to # 0: by poly / bonded non-poly / free non-poly diff --git a/src/atomworks/ml/transforms/atom_level_embeddings.py b/src/atomworks/ml/transforms/atom_level_embeddings.py index b977244e..8f5fe583 100644 --- a/src/atomworks/ml/transforms/atom_level_embeddings.py +++ b/src/atomworks/ml/transforms/atom_level_embeddings.py @@ -65,9 +65,9 @@ def featurize_atom_level_embeddings( ) _has_descriptors = True except (StopIteration, ValueError): - assert ( - embedding_dim is not None and n_conformers is not None - ), "embedding_dim and n_conformers must be provided if no descriptors are available" + assert embedding_dim is not None and n_conformers is not None, ( + "embedding_dim and n_conformers must be provided if no descriptors are available" + ) _has_descriptors = False default_return = { diff --git a/src/atomworks/ml/transforms/base.py b/src/atomworks/ml/transforms/base.py index 0d1b8a5b..5a24080b 100644 --- a/src/atomworks/ml/transforms/base.py +++ b/src/atomworks/ml/transforms/base.py @@ -342,9 +342,9 @@ def __call__(self, data: dict[str, Any], *args, **kwargs) -> dict[str, Any]: # apply the transformation data = self.forward(data, *args, **kwargs) - assert isinstance( - data, dict - ), f"`forward` method of {self.__class__.__name__} must return a dictionary, not {type(data)}." + assert isinstance(data, dict), ( + f"`forward` method of {self.__class__.__name__} must return a dictionary, not {type(data)}." + ) # restore the transform history if `data` was copied (which loses the transform history) data = self._ensure_has_transform_history(data) @@ -798,9 +798,9 @@ def __init__(self, transforms: list[Transform], probs: list[float]): f"Number of transforms must match number of probabilities. " f"Got {len(transforms)} transforms and {len(probs)} probabilities." ) - assert np.isclose(np.sum(probs), 1) or np.isclose( - np.sum(probs), 0 - ), f"Probabilities must sum to 1 or 0. Got {np.sum(probs)}" + assert np.isclose(np.sum(probs), 1) or np.isclose(np.sum(probs), 0), ( + f"Probabilities must sum to 1 or 0. Got {np.sum(probs)}" + ) assert all(isinstance(t, Transform) for t in transforms), ( f"All elements in transforms must be Transform instances. " f"Got {type(next(t for t in transforms if not isinstance(t, Transform)))}" diff --git a/src/atomworks/ml/transforms/center_random_augmentation.py b/src/atomworks/ml/transforms/center_random_augmentation.py index d4e8bfaf..968cacb8 100644 --- a/src/atomworks/ml/transforms/center_random_augmentation.py +++ b/src/atomworks/ml/transforms/center_random_augmentation.py @@ -25,9 +25,9 @@ def check_input(self, data: dict) -> None: check_contains_keys(data, ["coord_atom_lvl_to_be_noised"]) check_contains_keys(data["ground_truth"], ["coord_atom_lvl", "mask_atom_lvl"]) - assert ( - data["coord_atom_lvl_to_be_noised"].shape[0] == self.batch_size - ), "Must batch coordinates to be noised before applying this transform" + assert data["coord_atom_lvl_to_be_noised"].shape[0] == self.batch_size, ( + "Must batch coordinates to be noised before applying this transform" + ) def forward(self, data: dict) -> dict: centered_coord_atom_lvl_to_be_noised = data["coord_atom_lvl_to_be_noised"] # (batch_size, n_atoms, 3) diff --git a/src/atomworks/ml/transforms/crop.py b/src/atomworks/ml/transforms/crop.py index 2db9ef77..88037fcc 100644 --- a/src/atomworks/ml/transforms/crop.py +++ b/src/atomworks/ml/transforms/crop.py @@ -119,12 +119,12 @@ def crop_contiguous_af2_multimer(iids: list[int | str], instance_lens: list[int] instance_lens = np.asarray(instance_lens) assert crop_size > 0, "Crop size must be greater than 0" - assert len(iids) == len( - instance_lens - ), f"Number of instance IDs ({len(iids)}) must match number of instance lengths ({len(instance_lens)})" - assert ( - len(iids) == np.unique(iids).size - ), f"Instance IDs must be unique, but got {len(iids)} IDs with only {np.unique(iids).size} unique values" + assert len(iids) == len(instance_lens), ( + f"Number of instance IDs ({len(iids)}) must match number of instance lengths ({len(instance_lens)})" + ) + assert len(iids) == np.unique(iids).size, ( + f"Instance IDs must be unique, but got {len(iids)} IDs with only {np.unique(iids).size} unique values" + ) # randomly permute the order of the instances to avoid cropping bias permutation = np.random.permutation(len(iids)) @@ -236,9 +236,9 @@ def get_spatial_crop_center( # If there's only one query unit, we don't need to check for spatial proximity, # so we can just return the mask for the query unit. can_be_crop_center = is_query_pn_unit & is_occupied - assert np.any( - can_be_crop_center - ), f"No crop center found! It appears `query_pn_unit_iid` {query_pn_unit_iids} is not in the atom array or unresolved." + assert np.any(can_be_crop_center), ( + f"No crop center found! It appears `query_pn_unit_iid` {query_pn_unit_iids} is not in the atom array or unresolved." + ) return can_be_crop_center @@ -299,9 +299,9 @@ def get_spatial_crop_mask( """ assert coord.ndim == 2, f"Expected coord to be 2-dimensional, got {coord.ndim} dimensions" assert coord.shape[1] == 3, f"Expected coord to have 3 coordinates per point, got {coord.shape[1]}" - assert ( - crop_center_idx < coord.shape[0] - ), f"Crop center index {crop_center_idx} is out of bounds for coord array of length {coord.shape[0]}" + assert crop_center_idx < coord.shape[0], ( + f"Crop center index {crop_center_idx} is out of bounds for coord array of length {coord.shape[0]}" + ) assert crop_size > 0, f"Crop size must be positive, got {crop_size}" assert jitter_scale >= 0, f"Jitter scale must be non-negative, got {jitter_scale}" diff --git a/src/atomworks/ml/transforms/design_task.py b/src/atomworks/ml/transforms/design_task.py index 242b7682..3200544e 100644 --- a/src/atomworks/ml/transforms/design_task.py +++ b/src/atomworks/ml/transforms/design_task.py @@ -85,7 +85,7 @@ def __init__( if not design_tasks_to_use: logger.warning( - "No design tasks with non-zero frequency found. " "SampleDesignTask will act as an identity transform." + "No design tasks with non-zero frequency found. SampleDesignTask will act as an identity transform." ) self.design_tasks = design_tasks_to_use diff --git a/src/atomworks/ml/transforms/diffusion/batch_structures.py b/src/atomworks/ml/transforms/diffusion/batch_structures.py index 2ab12b88..f82ac06d 100644 --- a/src/atomworks/ml/transforms/diffusion/batch_structures.py +++ b/src/atomworks/ml/transforms/diffusion/batch_structures.py @@ -34,9 +34,9 @@ def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data["ground_truth"], ["coord_atom_lvl", "mask_atom_lvl"]) if "coord_atom_lvl_to_be_noised" in data: - assert len(data["coord_atom_lvl_to_be_noised"]) == len( - data["atom_array"] - ), "structure must not be batched yet" + assert len(data["coord_atom_lvl_to_be_noised"]) == len(data["atom_array"]), ( + "structure must not be batched yet" + ) def forward(self, data: dict[str, Any]) -> dict[str, Any]: if "coord_atom_lvl_to_be_noised" in data: diff --git a/src/atomworks/ml/transforms/diffusion/edm.py b/src/atomworks/ml/transforms/diffusion/edm.py index 0c6d1dc2..21923128 100644 --- a/src/atomworks/ml/transforms/diffusion/edm.py +++ b/src/atomworks/ml/transforms/diffusion/edm.py @@ -49,9 +49,9 @@ def __init__(self, sigma_data: float, diffusion_batch_size: int, **kwargs): def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data, ["coord_atom_lvl_to_be_noised"]) - assert ( - data["coord_atom_lvl_to_be_noised"].shape[0] == self.diffusion_batch_size - ), "Must batch coordinates to be noised before applying this transform" + assert data["coord_atom_lvl_to_be_noised"].shape[0] == self.diffusion_batch_size, ( + "Must batch coordinates to be noised before applying this transform" + ) def forward(self, data: dict) -> dict: """ diff --git a/src/atomworks/ml/transforms/dna/pad_dna.py b/src/atomworks/ml/transforms/dna/pad_dna.py index ce7f643d..276431f6 100644 --- a/src/atomworks/ml/transforms/dna/pad_dna.py +++ b/src/atomworks/ml/transforms/dna/pad_dna.py @@ -683,9 +683,9 @@ def forward(self, data: dict[str, Any]) -> dict[str, Any]: seq2_rhs = "".join(chain2["canonical_seq"][-chain2_overhang[1] :]) try: - assert seq1_paired == to_reverse_complement( - seq2_paired - ), "sequences to be joined must be reverse-complements of each other" + assert seq1_paired == to_reverse_complement(seq2_paired), ( + "sequences to be joined must be reverse-complements of each other" + ) assert seq1_lhs == "" or seq2_rhs == "", "overhang1_lhs and overhang1_rhs are mutually exclusive" assert seq1_rhs == "" or seq2_lhs == "", "overhang2_lhs and overhang2_rhs are mutually exclusive" except AssertionError: diff --git a/src/atomworks/ml/transforms/filters.py b/src/atomworks/ml/transforms/filters.py index b0451652..675e4494 100644 --- a/src/atomworks/ml/transforms/filters.py +++ b/src/atomworks/ml/transforms/filters.py @@ -121,9 +121,9 @@ def remove_unsupported_chain_types( query_pn_unit_chain_types = np.unique( atom_array.chain_type[np.isin(atom_array.pn_unit_iid, query_pn_unit_iids)] ) - assert np.all( - np.isin(query_pn_unit_chain_types, supported_chain_types) - ), f"Query PN unit has an unsupported chain type: {query_pn_unit_chain_types}" + assert np.all(np.isin(query_pn_unit_chain_types, supported_chain_types)), ( + f"Query PN unit has an unsupported chain type: {query_pn_unit_chain_types}" + ) # Then, we filter out chains with unsupported chain types is_supported_chain_type = np.isin(atom_array.chain_type, supported_chain_types) diff --git a/src/atomworks/ml/transforms/mask_generator.py b/src/atomworks/ml/transforms/mask_generator.py index 89f91163..ecafd8d4 100644 --- a/src/atomworks/ml/transforms/mask_generator.py +++ b/src/atomworks/ml/transforms/mask_generator.py @@ -463,9 +463,9 @@ def __call__( region_starts = regions[:-1] region_stops = regions[1:] seed_region_idx = np.searchsorted(region_starts, seed_idx, side="right") - 1 - assert ( - region_starts[seed_region_idx] <= seed_idx < region_stops[seed_region_idx] - ), f"{seed_idx=} is not within the allowed region ({region_starts[seed_region_idx]}-{region_stops[seed_region_idx]})" + assert region_starts[seed_region_idx] <= seed_idx < region_stops[seed_region_idx], ( + f"{seed_idx=} is not within the allowed region ({region_starts[seed_region_idx]}-{region_stops[seed_region_idx]})" + ) region_start = region_starts[seed_region_idx] region_stop = region_stops[seed_region_idx] @@ -481,9 +481,9 @@ def __call__( # ... check that the region contains segments and that the seed is within the region assert len(segment_starts) > 0, "No candidate segments found" seed_segment_idx = np.searchsorted(segment_starts, seed_idx, side="right") - 1 - assert ( - segment_starts[seed_segment_idx] <= seed_idx < segment_stops[seed_segment_idx] - ), f"{seed_idx=} is not within the allowed region ({segment_starts[seed_segment_idx]}-{segment_stops[seed_segment_idx]})" + assert segment_starts[seed_segment_idx] <= seed_idx < segment_stops[seed_segment_idx], ( + f"{seed_idx=} is not within the allowed region ({segment_starts[seed_segment_idx]}-{segment_stops[seed_segment_idx]})" + ) # Sample island size and start position (to include the seed) n_candidate_segments = len(segment_starts) @@ -650,9 +650,9 @@ class CheckAtomBudget(CheckBudget): def __init__(self, n_min_atoms: int, n_max_atoms: int): self.n_min_atoms = n_min_atoms self.n_max_atoms = n_max_atoms - assert ( - self.n_min_atoms <= self.n_max_atoms - ), f"Can never satisfy budget with {self.n_min_atoms=}<= {self.n_max_atoms=}" + assert self.n_min_atoms <= self.n_max_atoms, ( + f"Can never satisfy budget with {self.n_min_atoms=}<= {self.n_max_atoms=}" + ) def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: n_atoms = len(total_mask) @@ -677,9 +677,9 @@ def __init__( ): self.n_min_residues = n_min_residues self.n_max_residues = n_max_residues - assert ( - self.n_min_residues <= self.n_max_residues - ), f"Can never satisfy budget with {self.n_min_residues=}<= {self.n_max_residues=}" + assert self.n_min_residues <= self.n_max_residues, ( + f"Can never satisfy budget with {self.n_min_residues=}<= {self.n_max_residues=}" + ) self.reduce = reduce def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: @@ -704,9 +704,9 @@ class CheckTokenBudget(CheckBudget): def __init__(self, n_min_tokens: int, n_max_tokens: int): self.n_min_tokens = n_min_tokens self.n_max_tokens = n_max_tokens - assert ( - self.n_min_tokens <= self.n_max_tokens - ), f"Can never satisfy budget with {self.n_min_tokens=}<= {self.n_max_tokens=}" + assert self.n_min_tokens <= self.n_max_tokens, ( + f"Can never satisfy budget with {self.n_min_tokens=}<= {self.n_max_tokens=}" + ) def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: token_starts = get_token_starts(atom_array) @@ -809,9 +809,9 @@ def sample_mask_via_seed_grow_merge( # ... grow nothing, just set `this_mask[seed_idx] = True` this_mask = np.zeros(n_atoms, dtype=bool) this_mask[seed_idx] = True - assert this_mask.shape == ( - n_atoms, - ), f"this_mask must be a boolean array of shape ({n_atoms=},). Got {this_mask.shape}" + assert this_mask.shape == (n_atoms,), ( + f"this_mask must be a boolean array of shape ({n_atoms=},). Got {this_mask.shape}" + ) assert this_mask.dtype == bool, f"this_mask must be a boolean array. Got {this_mask.dtype}" # Merge masks if function provided diff --git a/src/atomworks/ml/transforms/masks.py b/src/atomworks/ml/transforms/masks.py index 0586bb03..a6026694 100644 --- a/src/atomworks/ml/transforms/masks.py +++ b/src/atomworks/ml/transforms/masks.py @@ -95,9 +95,9 @@ def check_input(self, data: dict[str, Any]) -> None: check_is_instance(data, "atom_array", AtomArray) check_atom_array_annotation(data, ["chain_iid"]) - assert ( - len(data["atom_array"].coord) < self.max_atoms_in_crop - ), "Number of atoms in the atom array exceeds the maximum number of atoms in the crop" + assert len(data["atom_array"].coord) < self.max_atoms_in_crop, ( + "Number of atoms in the atom array exceeds the maximum number of atoms in the crop" + ) def forward(self, data: dict[str, Any]) -> dict[str, Any]: """ diff --git a/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py b/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py index 0f04df21..6e243c79 100644 --- a/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py +++ b/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py @@ -308,9 +308,9 @@ def join_two_msas_by_tax_id( assert np.all(residue_is_paired[all_paired, :]), "Residues in all_paired rows should all be paired" # ...and assert that the first row is still the query sequence as a sanity check - assert np.all( - msa[0] == np.concatenate([msa_a["msa"][0], msa_b["msa"][0]]) - ), "Query sequence must be the first row of the MSA" + assert np.all(msa[0] == np.concatenate([msa_a["msa"][0], msa_b["msa"][0]])), ( + "Query sequence must be the first row of the MSA" + ) result = { "msa": msa, diff --git a/src/atomworks/ml/transforms/msa/msa.py b/src/atomworks/ml/transforms/msa/msa.py index 5f64e065..b69c604b 100644 --- a/src/atomworks/ml/transforms/msa/msa.py +++ b/src/atomworks/ml/transforms/msa/msa.py @@ -547,9 +547,9 @@ def forward(self, data: dict) -> dict: existing_pad_tokens = data["polymer_msas_by_chain_id"][first_chain_id]["msa_is_padded_mask"] * first_encoded_msa if np.any(existing_pad_tokens): token = existing_pad_tokens.flat[np.flatnonzero(existing_pad_tokens)[0]] - assert ( - token == self.PAD_TOKEN - ), f"Given padding token {self.PAD_TOKEN} does not match existing padding token {token}" + assert token == self.PAD_TOKEN, ( + f"Given padding token {self.PAD_TOKEN} does not match existing padding token {token}" + ) # Set up empty encoded msa (purely padded) for encoded msa token_count = get_token_count(atom_array) diff --git a/src/atomworks/ml/transforms/openbabel_utils.py b/src/atomworks/ml/transforms/openbabel_utils.py index 9fa54758..7de9c70d 100644 --- a/src/atomworks/ml/transforms/openbabel_utils.py +++ b/src/atomworks/ml/transforms/openbabel_utils.py @@ -440,9 +440,9 @@ def find_automorphisms(obmol: openbabel.OBMol, max_automorphs: int = 1000, max_m [7 2]]] """ n_atoms = obmol.NumAtoms() - assert ( - n_atoms == obmol.NumHvyAtoms() - ), f"Found {n_atoms - obmol.NumHvyAtoms()} explicit hydrogens. This function assumes that the input molecule has no explicit hydrogens. Please remove." + assert n_atoms == obmol.NumHvyAtoms(), ( + f"Found {n_atoms - obmol.NumHvyAtoms()} explicit hydrogens. This function assumes that the input molecule has no explicit hydrogens. Please remove." + ) # ... initialize a vector container to store automorphs automorphs = openbabel.vvpairUIntUInt() # vector>> diff --git a/src/atomworks/ml/transforms/rdkit_utils.py b/src/atomworks/ml/transforms/rdkit_utils.py index fe9c55b8..da5d67bb 100644 --- a/src/atomworks/ml/transforms/rdkit_utils.py +++ b/src/atomworks/ml/transforms/rdkit_utils.py @@ -119,9 +119,9 @@ def generate_conformers( Improve Conformation Generation", JCIM, 2015. """ # Ensure that all properties are being pickled (needed when we use timeout) - assert ( - Chem.GetDefaultPickleProperties() == Chem.PropertyPickleOptions.AllProps - ), "Default pickle properties are not set to all properties. Annotation loss will occur." + assert Chem.GetDefaultPickleProperties() == Chem.PropertyPickleOptions.AllProps, ( + "Default pickle properties are not set to all properties. Annotation loss will occur." + ) assert attempts_with_distance_geometry > 0, "Attempts with distance geometry must be greater than 0." assert attempts_with_random_coordinates > 0, "Attempts with random coordinates must be greater than 0." diff --git a/src/atomworks/ml/transforms/rf2aa_assumptions.py b/src/atomworks/ml/transforms/rf2aa_assumptions.py index 017aa30c..352c77b8 100644 --- a/src/atomworks/ml/transforms/rf2aa_assumptions.py +++ b/src/atomworks/ml/transforms/rf2aa_assumptions.py @@ -157,22 +157,22 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # Assert that the correspondence between chains is the same in ch_label and same_chain is valid ch_label_diffs = np.where(ch_label.diff())[0] same_chain_diffs = np.unique(np.where(same_chain.diff())[1]) - assert np.all( - np.isin(ch_label_diffs, same_chain_diffs) - ), f"{item}: ch_label_diffs: {ch_label_diffs}, same_chain_diffs: {same_chain_diffs}" + assert np.all(np.isin(ch_label_diffs, same_chain_diffs)), ( + f"{item}: ch_label_diffs: {ch_label_diffs}, same_chain_diffs: {same_chain_diffs}" + ) # Assert that there are polymer tokens in the example: num_res_tokens = ((~_is_atom(seq[0])).sum()).item() - assert ( - num_res_tokens > 0 - ), f"{item}: num_res_tokens: {num_res_tokens}. No polymer tokens at all. This would lead RF2AA to crash." + assert num_res_tokens > 0, ( + f"{item}: num_res_tokens: {num_res_tokens}. No polymer tokens at all. This would lead RF2AA to crash." + ) assert num_res_tokens + num_atoms == L, f"{item}: num_res_tokens: {num_res_tokens}, num_atoms: {num_atoms}, L: {L}" if num_atoms > 0: # Assert that `same_chain` is block diagonal in the non-poly sector: - assert _is_block_diagonal_with_full_blocks( - same_chain[num_res_tokens:, num_res_tokens:] - ), f"{item}: non-poly sector of `same_chain` is not block diagonal" + assert _is_block_diagonal_with_full_blocks(same_chain[num_res_tokens:, num_res_tokens:]), ( + f"{item}: non-poly sector of `same_chain` is not block diagonal" + ) # Assert that in the non-poly sector, for label in np.unique(ch_label[num_res_tokens:]): @@ -182,24 +182,24 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # NOTE: This will currently fail (on purpose) for cropped covalent modifications, # where this assumption cannot be guaranteed with an AF3 like cropping strategy. same_chain_block = same_chain[num_res_tokens:, num_res_tokens:][np.ix_(idxs, idxs)] - assert _are_all_blocks_the_same_size( - same_chain_block - ), f"{item}: `same_chain` block {label} is not the same size" + assert _are_all_blocks_the_same_size(same_chain_block), ( + f"{item}: `same_chain` block {label} is not the same size" + ) # ... ensure there is no entirely unresolved `ch_label` segment in # the non-poly sector: - assert ( - mask_crds[0, idxs + num_res_tokens, :] - ).any(), f"{item}: Entity with `chain_label` {label} is entirely unresolved in the non-poly sector." + assert (mask_crds[0, idxs + num_res_tokens, :]).any(), ( + f"{item}: Entity with `chain_label` {label} is entirely unresolved in the non-poly sector." + ) # ... ensure there is at least one resolved coordinate for each chain in each entity _block_size = same_chain_block[0].sum() assert len(idxs) % _block_size == 0 for chain_idx in range(len(idxs) // _block_size): idxs_in_subblock = idxs[chain_idx * _block_size : (chain_idx + 1) * _block_size] - assert ( - mask_crds[0, idxs_in_subblock + num_res_tokens, :] - ).any(), f"{item}: Chain {chain_idx} in block with `chain_label` {label} has no resolved coordinates in the non-poly sector." + assert (mask_crds[0, idxs_in_subblock + num_res_tokens, :]).any(), ( + f"{item}: Chain {chain_idx} in block with `chain_label` {label} has no resolved coordinates in the non-poly sector." + ) # Assert that there are no masks in `msa`: assert not (msa == 21).any(), f"{item}: There are masks in the ground truth `msa`." @@ -207,21 +207,21 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # Assert that there are no entirely unresolved chains in the poly sector: for label in np.unique(ch_label[:num_res_tokens]): idxs = np.where(ch_label[:num_res_tokens] == label)[0] - assert ( - mask_crds[0, idxs, :] - ).any(), f"{item}: Entity with `chain_label` {label} is entirely unresolved in the poly sector." + assert (mask_crds[0, idxs, :]).any(), ( + f"{item}: Entity with `chain_label` {label} is entirely unresolved in the poly sector." + ) # Ensure there is at least one resolved coordinate for each symmetry copy: # mask_crds: (N_symm, L, NTOTAL) - assert mask_crds.any( - dim=(1, 2) - ).all(), f"{item}: There are no resolved coordinates for at least one symmetry copy (neither poly nor non-poly)." + assert mask_crds.any(dim=(1, 2)).all(), ( + f"{item}: There are no resolved coordinates for at least one symmetry copy (neither poly nor non-poly)." + ) # Ensure there is at least one resolved coordinate for each symmetry copy in the poly sector (excluding padding): n_symm_poly = mask_crds[:, :num_res_tokens].any(dim=(1, 2)).max().item() - assert ( - n_symm_poly > 0 - ), f"{item}: There are no resolved coordinates for the poly sector of at least one symmetry copy (excluding padding)." + assert n_symm_poly > 0, ( + f"{item}: There are no resolved coordinates for the poly sector of at least one symmetry copy (excluding padding)." + ) # If the given symmetry copy has a poly swap, check that the N-CA-C of at least one residue is resolved, which # is needed to construct the poly frames. @@ -229,9 +229,9 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: dim=1 ) problems = np.where(~symm_copies_has_at_least_one_resolved_N_CA_C)[0] - assert ( - len(problems) == 0 - ), f"{item}: The following symmetry copies have no resolved N-CA-C coordinates for the poly sector: {problems}" + assert len(problems) == 0, ( + f"{item}: The following symmetry copies have no resolved N-CA-C coordinates for the poly sector: {problems}" + ) class AssertRF2AAAssumptions(Transform): diff --git a/src/atomworks/ml/transforms/symmetry.py b/src/atomworks/ml/transforms/symmetry.py index d9dd1477..982164a7 100644 --- a/src/atomworks/ml/transforms/symmetry.py +++ b/src/atomworks/ml/transforms/symmetry.py @@ -220,9 +220,9 @@ def get_isomorphisms_from_symmetry_groups( # Determine tile size and number of tiles needed to fill the array tile_size = n_perm * n_reps # ... each tile has the permutation repeated n_reps times n_tile = math.ceil(n_isomorphisms / tile_size) # ... number of tiles needed to fill the array - assert (n_isomorphisms <= get_perm_count(permutations)) or ( - n_tile * tile_size == n_isomorphisms - ), f"{n_tile} * {tile_size} != {n_isomorphisms} (={n_tile * tile_size})" + assert (n_isomorphisms <= get_perm_count(permutations)) or (n_tile * tile_size == n_isomorphisms), ( + f"{n_tile} * {tile_size} != {n_isomorphisms} (={n_tile * tile_size})" + ) # Fill the isomorphisms array with `n_tile` copies of `perm`, each of which is repeated `n_reps` times isomorphisms[:, start_idx : start_idx + n_instances] = np.tile(np.repeat(perm, n_reps, axis=0), (n_tile, 1))[ diff --git a/src/atomworks/ml/transforms/template.py b/src/atomworks/ml/transforms/template.py index b1fb3ff7..576b19ad 100644 --- a/src/atomworks/ml/transforms/template.py +++ b/src/atomworks/ml/transforms/template.py @@ -153,9 +153,9 @@ def subset(self, template_idxs: list[int]) -> "RF2AATemplate": return self def to_atom_array(self, template_idx: int) -> AtomArray: - assert ( - isinstance(template_idx, int) and 0 <= template_idx <= self.n_templates - 1 - ), f"template_idx must be an int between 0 and {self.n_templates - 1}, got {template_idx}" + assert isinstance(template_idx, int) and 0 <= template_idx <= self.n_templates - 1, ( + f"template_idx must be an int between 0 and {self.n_templates - 1}, got {template_idx}" + ) # Get pdb_id and chain_id template_id = self.ids[template_idx] @@ -354,18 +354,18 @@ def __init__( AssertionError: If `n_template` is not a positive integer. AssertionError: If `min_template_length` is not a non-negative integer. """ - assert ( - 0.0 <= min_seq_similarity <= 100.0 - ), f"min_seq_similarity must be between 0.0 and 100.0, got {min_seq_similarity}" - assert ( - 0.0 <= max_seq_similarity <= 100.0 - ), f"max_seq_similarity must be between 0.0 and 100.0, got {max_seq_similarity}" - assert ( - isinstance(max_n_template, int) and max_n_template > 0 - ), f"max_n_template must be a positive integer, got {max_n_template}" - assert ( - isinstance(min_template_length, int) and min_template_length >= 0 - ), f"min_template_length must be a non-negative integer, got {min_template_length}" + assert 0.0 <= min_seq_similarity <= 100.0, ( + f"min_seq_similarity must be between 0.0 and 100.0, got {min_seq_similarity}" + ) + assert 0.0 <= max_seq_similarity <= 100.0, ( + f"max_seq_similarity must be between 0.0 and 100.0, got {max_seq_similarity}" + ) + assert isinstance(max_n_template, int) and max_n_template > 0, ( + f"max_n_template must be a positive integer, got {max_n_template}" + ) + assert isinstance(min_template_length, int) and min_template_length >= 0, ( + f"min_template_length must be a non-negative integer, got {min_template_length}" + ) self.n_template = max_n_template self.pick_top = pick_top @@ -511,18 +511,18 @@ def __init__( AssertionError: If `init_coords` is a tensor and its dimensions do not match the expected shape. AssertionError: If `allowed_chain_types` is not a list or contains any elements that are not instances of `ChainType`. """ - assert ( - isinstance(n_template, int) and n_template > 0 - ), f"n_template must be a positive integer, got {n_template}" - assert isinstance( - encoding, TokenEncoding - ), f"encoding must be an instance of TokenEncoding, got {type(encoding)}" - assert ( - isinstance(allowed_chain_types, list) and len(allowed_chain_types) > 0 - ), f"allowed_chain_types must be a non-empty list, got {allowed_chain_types}" - assert np.isin( - allowed_chain_types, ChainType - ).all(), f"Allowed chain types must be a list of ChainType enums. Got {allowed_chain_types=}." + assert isinstance(n_template, int) and n_template > 0, ( + f"n_template must be a positive integer, got {n_template}" + ) + assert isinstance(encoding, TokenEncoding), ( + f"encoding must be an instance of TokenEncoding, got {type(encoding)}" + ) + assert isinstance(allowed_chain_types, list) and len(allowed_chain_types) > 0, ( + f"allowed_chain_types must be a non-empty list, got {allowed_chain_types}" + ) + assert np.isin(allowed_chain_types, ChainType).all(), ( + f"Allowed chain types must be a list of ChainType enums. Got {allowed_chain_types=}." + ) self.n_template = n_template self.mask_token_idx = mask_token_idx self.init_coords = init_coords @@ -535,9 +535,9 @@ def __init__( if init_coords.ndim >= 2: n_token = init_coords.shape[-2] - assert ( - n_token == encoding.n_atoms_per_token - ), f"init_coords must have {encoding.n_atoms_per_token} tokens, got {n_token}" + assert n_token == encoding.n_atoms_per_token, ( + f"init_coords must have {encoding.n_atoms_per_token} tokens, got {n_token}" + ) def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data, ["template", "atom_array"]) diff --git a/src/atomworks/ml/utils/misc.py b/src/atomworks/ml/utils/misc.py index 28d38284..e9e279cd 100644 --- a/src/atomworks/ml/utils/misc.py +++ b/src/atomworks/ml/utils/misc.py @@ -376,9 +376,9 @@ def grouped_count( # Check input validity assert len(groups) == data.dim(), "Number of groups must match the number of dimensions in the data tensor." - assert all( - len(group) == shape for group, shape in zip(groups, data.shape, strict=True) - ), "The i-th assignments `groups` must have the same length as the i-th dimension of the data tensor." + assert all(len(group) == shape for group, shape in zip(groups, data.shape, strict=True)), ( + "The i-th assignments `groups` must have the same length as the i-th dimension of the data tensor." + ) # Infer the group sizes (= number of unique groups in each dimension) group_sizes = [max(group) + 1 for group in groups] diff --git a/src/atomworks/ml/utils/numpy.py b/src/atomworks/ml/utils/numpy.py index 80d3b381..28d0391b 100644 --- a/src/atomworks/ml/utils/numpy.py +++ b/src/atomworks/ml/utils/numpy.py @@ -38,12 +38,12 @@ def select_data_by_id( [8., 8., 8., 8., 8., 8.], [1., 1., 1., 1., 1., 1.]]) """ - assert data.shape[axis] == len( - data_ids - ), f"`data` must have `len(data_ids)` along axis `{axis}`, but got shape: {data.shape}" - assert np.unique(data_ids).size == len( - data_ids - ), f"`data_ids` must be unique. Got duplicates ({np.unique(data_ids)}) in {data_ids}" + assert data.shape[axis] == len(data_ids), ( + f"`data` must have `len(data_ids)` along axis `{axis}`, but got shape: {data.shape}" + ) + assert np.unique(data_ids).size == len(data_ids), ( + f"`data_ids` must be unique. Got duplicates ({np.unique(data_ids)}) in {data_ids}" + ) id_to_idx = np.vectorize({id_: idx for idx, id_ in enumerate(data_ids)}.__getitem__, otypes=[data_ids.dtype]) idxs_to_select = id_to_idx(select_ids) diff --git a/src/atomworks/ml/utils/rng.py b/src/atomworks/ml/utils/rng.py index 7bd00701..7d603b45 100644 --- a/src/atomworks/ml/utils/rng.py +++ b/src/atomworks/ml/utils/rng.py @@ -137,9 +137,9 @@ def create_rng_state_from_seeds( with rng_state(None): # Set seeds in context manager to reset RNG states after creating the rng_state_dict if np_seed is not None: - assert ( - isinstance(np_seed, int) and _MIN_SEED_VALUE <= np_seed <= _MAX_SEED_VALUE - ), f"np_seed must be an int between {_MIN_SEED_VALUE} and {_MAX_SEED_VALUE}, got {np_seed}" + assert isinstance(np_seed, int) and _MIN_SEED_VALUE <= np_seed <= _MAX_SEED_VALUE, ( + f"np_seed must be an int between {_MIN_SEED_VALUE} and {_MAX_SEED_VALUE}, got {np_seed}" + ) np.random.seed(np_seed) if torch_seed is not None: torch.manual_seed(torch_seed) diff --git a/src/atomworks/ml/utils/token.py b/src/atomworks/ml/utils/token.py index ba9e328c..c263eb0d 100644 --- a/src/atomworks/ml/utils/token.py +++ b/src/atomworks/ml/utils/token.py @@ -214,9 +214,9 @@ def apply_segment_wise_2d(array: np.ndarray, segment_start_end_idxs: np.ndarray, assert array.ndim == 2, "Array must be 2D" assert segment_start_end_idxs.ndim == 1, "Group start end idxs must be 1D" assert segment_start_end_idxs[0] == 0, "Group start end idxs must start with 0" - assert ( - segment_start_end_idxs[-1] == array.shape[0] - ), "Group start end idxs must end with the number of rows in the array" + assert segment_start_end_idxs[-1] == array.shape[0], ( + "Group start end idxs must end with the number of rows in the array" + ) assert np.all(np.diff(segment_start_end_idxs) > 0), "Group start end idxs must be strictly increasing" # reduce along rows @@ -248,9 +248,9 @@ def get_af3_token_representative_masks(atom_array: AtomArray, enforce_one_per_to Returns: np.ndarray: A boolean mask indicating the representative atoms of the tokens in the atom array. """ - assert ( - "atomize" in atom_array.get_annotation_categories() - ), "Atomize annotation is missing. Run AtomizeByCCDName Transform for magical atomization of ligands" + assert "atomize" in atom_array.get_annotation_categories(), ( + "Atomize annotation is missing. Run AtomizeByCCDName Transform for magical atomization of ligands" + ) pyrimidine_representative_atom = is_pyrimidine(atom_array.res_name) & (atom_array.atom_name == "C2") purine_representative_atom = is_purine(atom_array.res_name) & (atom_array.atom_name == "C4") unknown_na_representative_atom = is_unknown_nucleotide(atom_array.res_name) & (atom_array.atom_name == "C4") @@ -336,9 +336,9 @@ def get_af3_token_center_masks(atom_array: AtomArray, enforce_one_per_token: boo `AF3 Supplementary Information `_ """ - assert ( - "atomize" in atom_array.get_annotation_categories() - ), "Atomize annotation is missing. Run AtomizeByCCDName Transform first!" + assert "atomize" in atom_array.get_annotation_categories(), ( + "Atomize annotation is missing. Run AtomizeByCCDName Transform first!" + ) is_center_atom = ( atom_array.atomize # the atom itself for un-atomized tokens diff --git a/src/atomworks_cli/find.py b/src/atomworks_cli/find.py index d370c0f0..2d1f598d 100644 --- a/src/atomworks_cli/find.py +++ b/src/atomworks_cli/find.py @@ -145,7 +145,7 @@ def find( ) typer.secho(f" Found MSAs: {found_count:,} ({coverage_percent:.1f}%)", fg=found_color) typer.secho( - f" Missing MSAs: {missing_count:,} ({100-coverage_percent:.1f}%)", + f" Missing MSAs: {missing_count:,} ({100 - coverage_percent:.1f}%)", fg=typer.colors.RED if missing_count > 0 else typer.colors.GREEN, ) diff --git a/tests/io/components/test_chain_types.py b/tests/io/components/test_chain_types.py index 67192ebb..acd9c61e 100644 --- a/tests/io/components/test_chain_types.py +++ b/tests/io/components/test_chain_types.py @@ -61,13 +61,13 @@ def test_chain_types(test_case: dict[str, Any]): # Check ChainType got_chain_type = ChainType.as_enum(pn_unit_atom_array.chain_type[0]) expected_chain_type = test_case["chain_types"][pn_unit_id] - assert ( - got_chain_type == expected_chain_type - ), f"Mismatch for {pn_unit_id=}: {got_chain_type=}, {expected_chain_type=}" + assert got_chain_type == expected_chain_type, ( + f"Mismatch for {pn_unit_id=}: {got_chain_type=}, {expected_chain_type=}" + ) # Check is_polymer got_is_polymer = pn_unit_atom_array.is_polymer[0] expected_is_polymer = expected_chain_type.is_polymer() - assert ( - got_is_polymer == expected_is_polymer - ), f"Mismatch for {pn_unit_id=}: {got_is_polymer=}, {expected_is_polymer=}" + assert got_is_polymer == expected_is_polymer, ( + f"Mismatch for {pn_unit_id=}: {got_is_polymer=}, {expected_is_polymer=}" + ) diff --git a/tests/io/components/test_entity_annotations.py b/tests/io/components/test_entity_annotations.py index 00b19462..aa545f03 100644 --- a/tests/io/components/test_entity_annotations.py +++ b/tests/io/components/test_entity_annotations.py @@ -178,18 +178,18 @@ def test_regenerate_and_add_chain_entity_annotation(test_case): # ... that no other chains have the same chain_entity other_chain_atom_array = atom_array[not_isin(atom_array.chain_id, equivalent_chains)] - assert not np.any( - other_chain_atom_array.chain_entity == chain_entity - ), f"Chains {equivalent_chains} share chain_entity with other chains" + assert not np.any(other_chain_atom_array.chain_entity == chain_entity), ( + f"Chains {equivalent_chains} share chain_entity with other chains" + ) # ... and that all chains with the same chain_entity have the same sequence sequences = [ chain_entity_atom_array[chain_entity_atom_array.chain_id == chain_id].res_name for chain_id in equivalent_chains ] - assert all( - np.array_equal(sequences[0], arr) for arr in sequences[1:] - ), "Sequences are not equal within an entity." + assert all(np.array_equal(sequences[0], arr) for arr in sequences[1:]), ( + "Sequences are not equal within an entity." + ) if __name__ == "__main__": diff --git a/tests/io/components/test_identifiers.py b/tests/io/components/test_identifiers.py index e8527806..d1f5aa84 100644 --- a/tests/io/components/test_identifiers.py +++ b/tests/io/components/test_identifiers.py @@ -98,9 +98,9 @@ def test_identifiers(test_case): generated_pn_unit_iids = sorted(np.unique(atom_array.pn_unit_iid.astype(str))) reference_pn_unit_iids = sorted(test_case["pn_unit_iids"]) - assert ( - generated_pn_unit_iids == reference_pn_unit_iids - ), f"Generated PN unit instance IDs do not match reference PN unit IIDs for PDB ID {test_case['pdb_id']} and assembly_id {test_case['assembly_id']}." + assert generated_pn_unit_iids == reference_pn_unit_iids, ( + f"Generated PN unit instance IDs do not match reference PN unit IIDs for PDB ID {test_case['pdb_id']} and assembly_id {test_case['assembly_id']}." + ) MOLECULE_TEST_CASES = [ diff --git a/tests/io/components/test_ignore_residues.py b/tests/io/components/test_ignore_residues.py index 6436d1cd..8fed6390 100644 --- a/tests/io/components/test_ignore_residues.py +++ b/tests/io/components/test_ignore_residues.py @@ -14,12 +14,12 @@ def test_remove_crystallization_aids(pdbid: str): # Not excluding crystallization aids out1 = parse(filename=get_pdb_path(pdbid), remove_ccds=[]) - assert np.any( - np.isin(out1["asym_unit"].res_name, CRYSTALLIZATION_AIDS) - ), "No crystallization aids found when not excluding." + assert np.any(np.isin(out1["asym_unit"].res_name, CRYSTALLIZATION_AIDS)), ( + "No crystallization aids found when not excluding." + ) # Excluding crystallization aids out2 = parse(filename=get_pdb_path(pdbid), remove_ccds=CRYSTALLIZATION_AIDS) - assert not np.any( - np.isin(out2["asym_unit"].res_name, CRYSTALLIZATION_AIDS) - ), "Crystallization aids found when excluding." + assert not np.any(np.isin(out2["asym_unit"].res_name, CRYSTALLIZATION_AIDS)), ( + "Crystallization aids found when excluding." + ) diff --git a/tests/io/components/test_logging.py b/tests/io/components/test_logging.py index fcc28013..5049fb0d 100644 --- a/tests/io/components/test_logging.py +++ b/tests/io/components/test_logging.py @@ -20,9 +20,9 @@ def test_atomworks_logging_level(): atomworks_logger = logging.getLogger("atomworks") # Assert that the current logging level matches the expected level - assert ( - atomworks_logger.level == expected_level - ), f"Expected atomworks.logging level to be {logging.getLevelName(expected_level)}, but it was {logging.getLevelName(atomworks_logger.level)}" + assert atomworks_logger.level == expected_level, ( + f"Expected atomworks.logging level to be {logging.getLevelName(expected_level)}, but it was {logging.getLevelName(atomworks_logger.level)}" + ) def test_atomworks_logging_level_env_var(): @@ -43,9 +43,9 @@ def test_atomworks_logging_level_env_var(): atomworks_logger = logging.getLogger("atomworks") # Assert that the current logging level matches the set environment variable - assert ( - atomworks_logger.level == logging.DEBUG - ), f"Expected atomworks.logging level to be DEBUG, but it was {logging.getLevelName(atomworks_logger.level)}" + assert atomworks_logger.level == logging.DEBUG, ( + f"Expected atomworks.logging level to be DEBUG, but it was {logging.getLevelName(atomworks_logger.level)}" + ) finally: # Clean up: restore the original environment variable diff --git a/tests/io/tools/test_inference_processing.py b/tests/io/tools/test_inference_processing.py index f80de814..fd8c43f3 100644 --- a/tests/io/tools/test_inference_processing.py +++ b/tests/io/tools/test_inference_processing.py @@ -367,9 +367,9 @@ def test_full_components_input(dict_inputs, custom_residues): for index, chain_id in enumerate(extracted_chain_ids): if chain_id: chain_id_from_component = components[index].chain_id - assert ( - chain_id == chain_id_from_component - ), f"Mismatch at index {index}: {chain_id} != {chain_id_from_component}" + assert chain_id == chain_id_from_component, ( + f"Mismatch at index {index}: {chain_id} != {chain_id_from_component}" + ) # Sanity check outputs assert isinstance(atom_array, AtomArray) diff --git a/tests/io/tools/test_mmjson.py b/tests/io/tools/test_mmjson.py index 6fcd0e65..25e80ff7 100644 --- a/tests/io/tools/test_mmjson.py +++ b/tests/io/tools/test_mmjson.py @@ -1,8 +1,6 @@ - from atomworks.io.parser import parse from atomworks.io.utils.io_utils import infer_pdb_file_type from atomworks.io.utils.testing import assert_same_atom_array - from tests.conftest import TEST_DATA_DIR diff --git a/tests/io/tools/test_rdkit.py b/tests/io/tools/test_rdkit.py index e33736ff..c98705d2 100644 --- a/tests/io/tools/test_rdkit.py +++ b/tests/io/tools/test_rdkit.py @@ -176,12 +176,12 @@ def test_chirality_detection_from_ccd(): assert Chem.FindMolChiralCenters(ccd_code_to_rdkit(aa)) == [(1, "S")] # Check a handful of non-standard amino acids - assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DAL")) == [ - (1, "R") - ], "D-alanine should have a R configuration at the CA atom" - assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DCY")) == [ - (1, "S") - ], "D-cystine should have a S configuration at the CA atom" + assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DAL")) == [(1, "R")], ( + "D-alanine should have a R configuration at the CA atom" + ) + assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DCY")) == [(1, "S")], ( + "D-cystine should have a S configuration at the CA atom" + ) assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DTH")) == [ (1, "R"), (2, "S"), diff --git a/tests/io/utils/test_scatter.py b/tests/io/utils/test_scatter.py index 4db0161b..472a3e9d 100644 --- a/tests/io/utils/test_scatter.py +++ b/tests/io/utils/test_scatter.py @@ -62,9 +62,9 @@ def test_apply_group_wise_2d_sum(): data = np.array([[1, 1], [2, 2], [3, 3], [4, 4]]) result = apply_group_wise(groups, data, lambda arr: np.sum(arr, axis=0)) expected = np.array([[4, 4], [6, 6]]) - assert np.array_equal( - np.stack(result), expected - ), f"Failed 2D sum test. Expected {expected}, got {np.stack(result)}" + assert np.array_equal(np.stack(result), expected), ( + f"Failed 2D sum test. Expected {expected}, got {np.stack(result)}" + ) def test_spread_group_wise_basic(): @@ -99,9 +99,9 @@ def test_get_segments_docstring(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 2, 3, 4, 5]) assert np.array_equal(result, expected), f"Failed docstring test. Expected {expected}, got {result}" - assert np.array_equal( - result_from_groups, expected - ), f"Failed docstring test. Expected {expected}, got {result_from_groups}" + assert np.array_equal(result_from_groups, expected), ( + f"Failed docstring test. Expected {expected}, got {result_from_groups}" + ) def test_get_segments_single_array(): @@ -111,9 +111,9 @@ def test_get_segments_single_array(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 2, 4, 5]) assert np.array_equal(result, expected), f"Failed single array test. Expected {expected}, got {result}" - assert np.array_equal( - result_from_groups, expected - ), f"Failed single array test. Expected {expected}, got {result_from_groups}" + assert np.array_equal(result_from_groups, expected), ( + f"Failed single array test. Expected {expected}, got {result_from_groups}" + ) def test_get_segments_no_changes(): @@ -123,9 +123,9 @@ def test_get_segments_no_changes(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 5]) assert np.array_equal(result, expected), f"Failed no-change test. Expected {expected}, got {result}" - assert np.array_equal( - result_from_groups, expected - ), f"Failed no-change test. Expected {expected}, got {result_from_groups}" + assert np.array_equal(result_from_groups, expected), ( + f"Failed no-change test. Expected {expected}, got {result_from_groups}" + ) def test_get_segments_all_changes(): @@ -135,9 +135,9 @@ def test_get_segments_all_changes(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 1, 2, 3, 4, 5]) assert np.array_equal(result, expected), f"Failed all-changes test. Expected {expected}, got {result}" - assert np.array_equal( - result_from_groups, expected - ), f"Failed all-changes test. Expected {expected}, got {result_from_groups}" + assert np.array_equal(result_from_groups, expected), ( + f"Failed all-changes test. Expected {expected}, got {result_from_groups}" + ) def test_apply_and_spread_segment_wise_sum_and_mean(): @@ -150,18 +150,18 @@ def test_apply_and_spread_segment_wise_sum_and_mean(): result_sum_groups = apply_and_spread_group_wise(groups, data, np.sum) expected_sum = np.array([30, 30, 120, 120, 120, 60]) assert np.array_equal(result_sum, expected_sum), f"Failed sum test. Expected {expected_sum}, got {result_sum}" - assert np.array_equal( - result_sum_groups, expected_sum - ), f"Failed sum test. Expected {expected_sum}, got {result_sum_groups}" + assert np.array_equal(result_sum_groups, expected_sum), ( + f"Failed sum test. Expected {expected_sum}, got {result_sum_groups}" + ) # Test with np.mean result_mean = apply_and_spread_segment_wise(segments, data, np.mean) result_mean_groups = apply_and_spread_group_wise(groups, data, np.mean) expected_mean = np.array([15.0, 15.0, 40.0, 40.0, 40.0, 60.0]) assert np.allclose(result_mean, expected_mean), f"Failed mean test. Expected {expected_mean}, got {result_mean}" - assert np.allclose( - result_mean_groups, expected_mean - ), f"Failed mean test. Expected {expected_mean}, got {result_mean_groups}" + assert np.allclose(result_mean_groups, expected_mean), ( + f"Failed mean test. Expected {expected_mean}, got {result_mean_groups}" + ) if __name__ == "__main__": diff --git a/tests/io/utils/test_testing_tools.py b/tests/io/utils/test_testing_tools.py index 81f9118b..71bf7342 100644 --- a/tests/io/utils/test_testing_tools.py +++ b/tests/io/utils/test_testing_tools.py @@ -83,9 +83,9 @@ def test_is_same_in_segment(): segment_start_stop = np.array([0, 3, 6, 8]) # 3 segments data = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3]) # Each segment has same value result = is_same_in_segment(segment_start_stop, data) - assert np.array_equal( - result, np.array([True, True, True]) - ), f"Failed simple segments test. Expected {np.array([True, True, True])}, got {result}" + assert np.array_equal(result, np.array([True, True, True])), ( + f"Failed simple segments test. Expected {np.array([True, True, True])}, got {result}" + ) result_group = is_same_in_group(groups, data) assert np.array_equal(result_group, np.array([True, True, True])) diff --git a/tests/ml/conditions/test_annotator.py b/tests/ml/conditions/test_annotator.py index c89bae7e..44f89f1b 100644 --- a/tests/ml/conditions/test_annotator.py +++ b/tests/ml/conditions/test_annotator.py @@ -45,9 +45,9 @@ def test_ensure_annotations_basic(atom_array): # Check that annotation has correct shape annotation_data = atom_array.get_annotation(annot) - assert ( - len(annotation_data) == atom_array.array_length() - ), f"Annotation '{annot}' should have same length as atom array" + assert len(annotation_data) == atom_array.array_length(), ( + f"Annotation '{annot}' should have same length as atom array" + ) assert isinstance(annotation_data, np.ndarray), f"Annotation '{annot}' should be a numpy array" diff --git a/tests/ml/conditions/test_condition_save_load.py b/tests/ml/conditions/test_condition_save_load.py index a54aaed4..9450f681 100644 --- a/tests/ml/conditions/test_condition_save_load.py +++ b/tests/ml/conditions/test_condition_save_load.py @@ -59,9 +59,9 @@ def test_save_and_load_atom_array_with_defaults(atom_array: AtomArray): existing = set( get_annotation_categories(loaded_atom_array, n_body=1) + get_annotation_categories(loaded_atom_array, n_body=2) ) - assert possible.issubset( - existing - ), f"Some possible annotations are not found in loaded_atom_array: {possible - existing}" + assert possible.issubset(existing), ( + f"Some possible annotations are not found in loaded_atom_array: {possible - existing}" + ) for condition_cls in CONDITIONS: default_mask = condition_cls.default_mask(atom_array) @@ -179,14 +179,16 @@ def test_save_and_load_atom_array_with_conditions(atom_array: AtomArray): target_annotation = target_annotation.as_dense_array() loaded_annotation = loaded_annotation.as_dense_array() - assert np.array_equal( - target_mask, loaded_mask, equal_nan=True - ), f"Mismatch for {condition_cls.full_name}: {np.where(target_mask)} != {np.where(loaded_mask)}" + assert np.array_equal(target_mask, loaded_mask, equal_nan=True), ( + f"Mismatch for {condition_cls.full_name}: {np.where(target_mask)} != {np.where(loaded_mask)}" + ) assert np.array_equal( target_annotation[target_mask], loaded_annotation[loaded_mask], equal_nan=np.issubdtype(condition_cls.dtype, np.floating), - ), f"Mismatch for {condition_cls.full_name}: {target_annotation[target_mask]} != {loaded_annotation[loaded_mask]}" + ), ( + f"Mismatch for {condition_cls.full_name}: {target_annotation[target_mask]} != {loaded_annotation[loaded_mask]}" + ) if __name__ == "__main__": diff --git a/tests/ml/datasets/test_datasets_with_filters.py b/tests/ml/datasets/test_datasets_with_filters.py index 92e445a7..af6dddc1 100644 --- a/tests/ml/datasets/test_datasets_with_filters.py +++ b/tests/ml/datasets/test_datasets_with_filters.py @@ -30,9 +30,9 @@ def test_resolution_filter(rf2aa_pn_units_dataset): def test_method_filter(rf2aa_pn_units_dataset): # Check that the method filter was applied correctly filtered_data = rf2aa_pn_units_dataset.data - assert ( - filtered_data["method"].isin(["X-RAY_DIFFRACTION", "ELECTRON_MICROSCOPY"]).all() - ), "Method filter did not work correctly" + assert filtered_data["method"].isin(["X-RAY_DIFFRACTION", "ELECTRON_MICROSCOPY"]).all(), ( + "Method filter did not work correctly" + ) def test_af3_excluded_ligands_filter(rf2aa_pn_units_dataset, rf2aa_interfaces_dataset): @@ -41,20 +41,20 @@ def test_af3_excluded_ligands_filter(rf2aa_pn_units_dataset, rf2aa_interfaces_da filtered_interfaces_data = rf2aa_interfaces_dataset.data # ... check query PN Units - assert np.any( - filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['G_1']}" - ), "Entry removed that contained valid PN Units" - assert not np.any( - filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['DB_1']}" - ), "Entry remained that contains AF-3 excluded ligands as query PN Units" + assert np.any(filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['G_1']}"), ( + "Entry removed that contained valid PN Units" + ) + assert not np.any(filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['DB_1']}"), ( + "Entry remained that contains AF-3 excluded ligands as query PN Units" + ) # ... check interfaces - assert not np.any( - filtered_interfaces_data.pdb_id == "{['pdb', 'interfaces']}{2pno}{3}{['DB_1', 'G_1']}" - ), "Entry remained that contains AF-3 excluded ligands as query PN Units" - assert np.any( - filtered_interfaces_data.example_id == "{['pdb', 'interfaces']}{2pno}{3}{['G_1', 'H_1']}" - ), "Entry removed that contained valid PN Units" + assert not np.any(filtered_interfaces_data.pdb_id == "{['pdb', 'interfaces']}{2pno}{3}{['DB_1', 'G_1']}"), ( + "Entry remained that contains AF-3 excluded ligands as query PN Units" + ) + assert np.any(filtered_interfaces_data.example_id == "{['pdb', 'interfaces']}{2pno}{3}{['G_1', 'H_1']}"), ( + "Entry removed that contained valid PN Units" + ) def test_filter_no_impact(caplog, pn_units_df): diff --git a/tests/ml/pipelines/test_data_loading_pipelines.py b/tests/ml/pipelines/test_data_loading_pipelines.py index 3e396712..3fe04be3 100644 --- a/tests/ml/pipelines/test_data_loading_pipelines.py +++ b/tests/ml/pipelines/test_data_loading_pipelines.py @@ -84,16 +84,16 @@ def test_data_loading_pipelines_with_random_examples(datasets_to_test, dataset_t ] # Check if we can reverse-engineer the row from the example_id assert row is not None, f"Failed to get row from example_id for example_id: {example_id}" assert sample is not None, f"Sample is None, with example_id: {example_id}" - assert ( - row["example_id"] == example_id - ), f"Row example_id does not match example_id for example_id: {example_id}" + assert row["example_id"] == example_id, ( + f"Row example_id does not match example_id for example_id: {example_id}" + ) # For validation datasets, also check that the "ground_truth" key contains information on which chains/interfaces to score, and the map from token index to `chain_iid` if dataset_type == "validation": assert "ground_truth" in sample, f"Missing 'ground_truth' key in sample with example_id: {example_id}" - assert ( - "chain_iid_token_lvl" in sample["ground_truth"] - ), f"Missing 'chain_iid_token_lvl' key in sample with example_id: {example_id}" + assert "chain_iid_token_lvl" in sample["ground_truth"], ( + f"Missing 'chain_iid_token_lvl' key in sample with example_id: {example_id}" + ) if __name__ == "__main__": diff --git a/tests/ml/pipelines/test_inference_pipelines.py b/tests/ml/pipelines/test_inference_pipelines.py index a47746e6..df0c1130 100644 --- a/tests/ml/pipelines/test_inference_pipelines.py +++ b/tests/ml/pipelines/test_inference_pipelines.py @@ -52,9 +52,9 @@ def test_af3_confidence_pipeline_from_chai_fasta(): assert "confidence_feats" in transformed_data, "Missing feats in pipeline output." # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert ( - feat.isfinite().all() if isinstance(feat, torch.Tensor) else True - ), f"Found NaN in feats: {feat_name=}, {feat=}" + assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( + f"Found NaN in feats: {feat_name=}, {feat=}" + ) @skip_if_on_github_runner @@ -91,9 +91,9 @@ def test_af3_pipeline_from_chai_fasta(): assert "feats" in transformed_data, "Missing feats in pipeline output." # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert ( - feat.isfinite().all() if isinstance(feat, torch.Tensor) else True - ), f"Found NaN in feats: {feat_name=}, {feat=}" + assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( + f"Found NaN in feats: {feat_name=}, {feat=}" + ) AF3_PIPELINE_FROM_COMPONENTS_TEST_CASES = [ @@ -156,9 +156,9 @@ def test_af3_pipeline_from_sequence_and_smiles(inference_components): # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert ( - feat.isfinite().all() if isinstance(feat, torch.Tensor) else True - ), f"Found NaN in feats: {feat_name=}, {feat=}" + assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( + f"Found NaN in feats: {feat_name=}, {feat=}" + ) # Check that we successfully generated a reference conformer for the ligand assert not torch.any(torch.all(transformed_data["feats"]["ref_pos"] == 0, dim=1)) diff --git a/tests/ml/pipelines/test_pipeline_regression.py b/tests/ml/pipelines/test_pipeline_regression.py index 7dcb3f69..67cd0e01 100644 --- a/tests/ml/pipelines/test_pipeline_regression.py +++ b/tests/ml/pipelines/test_pipeline_regression.py @@ -145,17 +145,17 @@ def _assert_features_equal(feats: dict, expected_feats: dict, example_name: str, # rdkit versions seem to be compiled differently on different operating systems, making # this an operating system dependent test. Instead of the values, we just check the # shapes - assert ( - feats[key].shape == expected_feats[key].shape - ), f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feats[key].shape} vs {expected_feats[key].shape}" + assert feats[key].shape == expected_feats[key].shape, ( + f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feats[key].shape} vs {expected_feats[key].shape}" + ) continue feat = feats[key] expected_feat = expected_feats[key] # Check shapes - assert ( - feat.shape == expected_feat.shape - ), f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feat.shape} vs {expected_feat.shape}" + assert feat.shape == expected_feat.shape, ( + f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feat.shape} vs {expected_feat.shape}" + ) # Check values with tolerance _assert_tensor_or_array_equal( diff --git a/tests/ml/preprocessing/test_filtering_criteria.py b/tests/ml/preprocessing/test_filtering_criteria.py index 0e7de234..eb27c8fb 100644 --- a/tests/ml/preprocessing/test_filtering_criteria.py +++ b/tests/ml/preprocessing/test_filtering_criteria.py @@ -46,9 +46,9 @@ def test_filtering_criteria(test_case: dict[str, Any]): assert set(pn_unit_iids) >= set(df["q_pn_unit_iid"].unique().tolist()) # ...assert that all of the rows have the same PN units - assert ( - df["all_pn_unit_iids_after_processing"] == df["all_pn_unit_iids_after_processing"].iloc[0] - ).all(), "Not all rows have the same pn_units" + assert (df["all_pn_unit_iids_after_processing"] == df["all_pn_unit_iids_after_processing"].iloc[0]).all(), ( + "Not all rows have the same pn_units" + ) pn_units_to_keep = set(test_case["pn_units_to_keep"]) pn_units_to_remove = set(test_case["pn_units_to_remove"]) diff --git a/tests/ml/preprocessing/test_get_atom_mask.py b/tests/ml/preprocessing/test_get_atom_mask.py index eda173e3..5587ffc0 100644 --- a/tests/ml/preprocessing/test_get_atom_mask.py +++ b/tests/ml/preprocessing/test_get_atom_mask.py @@ -59,9 +59,9 @@ def test_get_atom_mask_from_cell_list(mock_data): chunk_size = 1000 # Small chunk_size result = get_atom_mask_from_cell_list(large_query_coords, cell_list, cell_list_size, clash_distance, chunk_size) expected = cell_list.get_atoms(large_query_coords, clash_distance, as_mask=True) - assert np.array_equal( - result, expected - ), "Result with large coord array and small chunk_size does not match expected output." + assert np.array_equal(result, expected), ( + "Result with large coord array and small chunk_size does not match expected output." + ) # Non-divisible chunk_size chunk_size = 1507 # Non-divisible chunk_size diff --git a/tests/ml/preprocessing/test_loi_extraction.py b/tests/ml/preprocessing/test_loi_extraction.py index 9d6bcbdf..70edb6ed 100644 --- a/tests/ml/preprocessing/test_loi_extraction.py +++ b/tests/ml/preprocessing/test_loi_extraction.py @@ -69,9 +69,9 @@ def test_loi_extraction(test_case: dict[str, Any]): structure[(np.isin(structure.chain_id, chain_ids)) & (structure.occupancy > 0)].res_name ) if test_case.get("has_covalently_bonded_loi", False): - assert any( - res in loi_set for res in res_names - ), f"No LOI molecule found for {row.q_pn_unit_iid} in {res_names}. LOIs: {loi_set}" + assert any(res in loi_set for res in res_names), ( + f"No LOI molecule found for {row.q_pn_unit_iid} in {res_names}. LOIs: {loi_set}" + ) for res in res_names: if res in loi_set: loi_seen[res] += 1 diff --git a/tests/ml/transforms/msa/test_featurize_msa.py b/tests/ml/transforms/msa/test_featurize_msa.py index 40563e78..f6eafb9f 100644 --- a/tests/ml/transforms/msa/test_featurize_msa.py +++ b/tests/ml/transforms/msa/test_featurize_msa.py @@ -206,15 +206,15 @@ def test_fill_full_msa_from_encoded(pdb_id): for index, token_atom_array in enumerate(token_iter(atom_array)): if token_atom_array.atomize[0]: # If this residue is atomized, ensure that the entire MSA column (other than the query sequence) is padding... - assert np.all( - output["encoded"]["msa"][1:, index] == pad_token - ), f"MSA column for atomized residue {index} is not padding" + assert np.all(output["encoded"]["msa"][1:, index] == pad_token), ( + f"MSA column for atomized residue {index} is not padding" + ) # ...and the padding is represented in the full MSA details assert not output["full_msa_details"]["token_idx_has_msa"][index], "Token index has MSA when it should not" - assert np.all( - output["full_msa_details"]["msa_is_padded_mask"][1:, index] - ), "MSA is not padded when it should be" + assert np.all(output["full_msa_details"]["msa_is_padded_mask"][1:, index]), ( + "MSA is not padded when it should be" + ) atomized_indices.append(index) else: # If this residue is not atomized, ensure that the MSA matches with the pre-atomized MSA... @@ -223,14 +223,14 @@ def test_fill_full_msa_from_encoded(pdb_id): encoded_old_msa = output["polymer_msas_by_chain_id"][chain_id]["encoded_msa"] msa_column_old = encoded_old_msa[:, within_poly_res_idx] msa_column_new = output["encoded"]["msa"][:, index] - assert np.array_equal( - msa_column_old, msa_column_new - ), f"MSA column for non-atomized residue {index} does not match" + assert np.array_equal(msa_column_old, msa_column_new), ( + f"MSA column for non-atomized residue {index} does not match" + ) # ...and that we are noting that this token has MSA - assert output["full_msa_details"]["token_idx_has_msa"][ - index - ], "Token index does not have MSA when it should" + assert output["full_msa_details"]["token_idx_has_msa"][index], ( + "Token index does not have MSA when it should" + ) # Check that there are no insertions where there is MSA padding... msa_raw_ins = output["full_msa_details"]["msa_raw_ins"] @@ -238,9 +238,9 @@ def test_fill_full_msa_from_encoded(pdb_id): assert np.sum(msa_raw_ins * msa_is_padded_mask) == 0, "There should be no insertions where there is MSA padding" # ...AND that there are no insertions where there are atomized tokens - assert ( - np.sum(msa_raw_ins[:, atomized_indices]) == 0 - ), "There should be no insertions where there are atomized tokens" + assert np.sum(msa_raw_ins[:, atomized_indices]) == 0, ( + "There should be no insertions where there are atomized tokens" + ) ASSIGN_EXTRA_ROWS_TEST_CASES = [ @@ -415,12 +415,12 @@ def test_summarize_clusters(test_case): n_tokens=3, ) - assert torch.allclose( - msa_cluster_profiles, expected_profiles, atol=1e-4 - ), f"Expected profiles {expected_profiles}, but got {msa_cluster_profiles}" - assert torch.allclose( - msa_cluster_ins, expected_insertions, atol=1e-4 - ), f"Expected insertions {expected_insertions}, but got {msa_cluster_ins}" + assert torch.allclose(msa_cluster_profiles, expected_profiles, atol=1e-4), ( + f"Expected profiles {expected_profiles}, but got {msa_cluster_profiles}" + ) + assert torch.allclose(msa_cluster_ins, expected_insertions, atol=1e-4), ( + f"Expected insertions {expected_insertions}, but got {msa_cluster_ins}" + ) def test_mask_msa_like_bert(): @@ -624,9 +624,9 @@ def test_msa_featurize_like_rf2aa_full_pipeline(pdb_id): # For each key in the dictionary, check that the values match for key, old_values in old_results.items(): new_values = output["features_per_recycle_dict"][key] - assert torch.allclose( - torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4 - ), f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" + assert torch.allclose(torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4), ( + f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" + ) @pytest.mark.parametrize("pdb_id", MSA_FEATURIZE_PIPELINE_TEST_CASES) @@ -689,14 +689,14 @@ def test_msa_featurize_like_af3_full_pipeline(pdb_id): ) # Assert that has_insertion is a boolean tensor... - assert ( - msa_features_per_recycle_dict["has_insertion"][0].dtype == torch.bool - ), "has_insertion must be of boolean dtype" + assert msa_features_per_recycle_dict["has_insertion"][0].dtype == torch.bool, ( + "has_insertion must be of boolean dtype" + ) # ...and that there's at least one - assert torch.any( - msa_features_per_recycle_dict["has_insertion"][0] - ), "There must be at least one insertion, if we're using examples with MSA's" + assert torch.any(msa_features_per_recycle_dict["has_insertion"][0]), ( + "There must be at least one insertion, if we're using examples with MSA's" + ) ############## Regression test ############## @@ -714,15 +714,15 @@ def test_msa_featurize_like_af3_full_pipeline(pdb_id): # For each key in the features that change across recycles, check that the values match... for key, old_values in old_results["msa_features_per_recycle_dict"].items(): new_values = msa_features_per_recycle_dict[key] - assert torch.allclose( - torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4 - ), f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" + assert torch.allclose(torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4), ( + f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" + ) # ... and for the static features as well for key, old_value in old_results["msa_static_features_dict"].items(): new_value = msa_static_features_dict[key] - assert torch.allclose( - new_value, old_value, atol=1e-4, rtol=1e-4 - ), f"Failed at key: {key}. Difference: {new_value - old_value}" + assert torch.allclose(new_value, old_value, atol=1e-4, rtol=1e-4), ( + f"Failed at key: {key}. Difference: {new_value - old_value}" + ) # Define a simple TokenEncoding class for testing diff --git a/tests/ml/transforms/msa/test_load_msas.py b/tests/ml/transforms/msa/test_load_msas.py index 6e3c6121..6687afd9 100644 --- a/tests/ml/transforms/msa/test_load_msas.py +++ b/tests/ml/transforms/msa/test_load_msas.py @@ -63,25 +63,25 @@ def _validate_msa_results(test_case: dict[str, Any], result: dict[str, Any], cha spot_check_index = test_case["spot_check"]["index"] assert result["msa"].shape[0] >= test_case["min_sequences_in_msa"], "MSA has too few sequences" - assert np.all( - result["msa"][0] == _encode_sequence(test_case["sequence"], chain_type) - ), "Query sequence is incorrect" + assert np.all(result["msa"][0] == _encode_sequence(test_case["sequence"], chain_type)), ( + "Query sequence is incorrect" + ) # Spot check assertions assert np.all( result["msa"][spot_check_index] == _encode_sequence(test_case["spot_check"]["sequence"], chain_type) ), "Spot check sequence is incorrect" - assert ( - np.sum(result["ins"][spot_check_index]) == test_case["spot_check"]["num_insertions"] - ), "Incorrect number of insertions" + assert np.sum(result["ins"][spot_check_index]) == test_case["spot_check"]["num_insertions"], ( + "Incorrect number of insertions" + ) assert result["ins"][spot_check_index].shape[0] == len(result["msa"][spot_check_index]), "Incorrect insertion shape" assert result["tax_ids"][spot_check_index].item() == str(test_case["spot_check"]["tax_id"]), "Incorrect tax ID" # Sequence similarity sanity checks calculated_sequence_similarity = np.mean(result["msa"][spot_check_index] == result["msa"][0]) - assert ( - calculated_sequence_similarity == result["sequence_similarity"][spot_check_index] - ), "Incorrect sequence similarity" + assert calculated_sequence_similarity == result["sequence_similarity"][spot_check_index], ( + "Incorrect sequence similarity" + ) assert result["sequence_similarity"][0] == 1.0, "Query sequence should have 100% similarity with itself" @@ -195,9 +195,9 @@ def _check_coverage_for_pdb_id( def test_msas_with_mse(): """Check that we correctly find MSAs for proteins with selenomethisone residues.""" results = _check_coverage_for_pdb_id("7dsu", PROTEIN_MSA_DIRS, RNA_MSA_DIRS) - assert ( - results["n_proteins_with_msas"] == results["n_proteins"] - ), "All proteins should have MSAs after MSE conversion" + assert results["n_proteins_with_msas"] == results["n_proteins"], ( + "All proteins should have MSAs after MSE conversion" + ) @pytest.mark.parametrize("test_case", MSA_TEST_CASES) diff --git a/tests/ml/transforms/symmetry/test_automorphisms_networkx.py b/tests/ml/transforms/symmetry/test_automorphisms_networkx.py index 1579ff1d..c62fe983 100644 --- a/tests/ml/transforms/symmetry/test_automorphisms_networkx.py +++ b/tests/ml/transforms/symmetry/test_automorphisms_networkx.py @@ -117,17 +117,17 @@ def test_find_automorphisms_within_entire_structure(pdb_id: str): assert len(automorphism) == 2, "Arginine should have 2 automorphisms." changing_column_indices = get_indices_of_non_constant_columns(automorphism) n_element = ELEMENT_NAME_TO_ATOMIC_NUMBER["N"] - assert np.all( - residue.atomic_number[changing_column_indices] == n_element - ), "All automorphisms of Arginine should involve nitrogens." + assert np.all(residue.atomic_number[changing_column_indices] == n_element), ( + "All automorphisms of Arginine should involve nitrogens." + ) # ...if it's a tyrosine, there should be 2 automorphisms, all involving carbons if residue_name == "TYR": assert len(automorphism) == 2, "Tyrosine should have 2 automorphisms (carbons must swap together)" changing_column_indices = get_indices_of_non_constant_columns(automorphism) n_element = ELEMENT_NAME_TO_ATOMIC_NUMBER["C"] - assert np.all( - residue.atomic_number[changing_column_indices] == n_element - ), "All automorphisms of Tyrosine should involve carbons." + assert np.all(residue.atomic_number[changing_column_indices] == n_element), ( + "All automorphisms of Tyrosine should involve carbons." + ) # ...isoleucine should have no automorphisms if residue_name == "ILE": assert len(automorphism) == 1, "Isoleucine should have no automorphisms." @@ -135,18 +135,18 @@ def test_find_automorphisms_within_entire_structure(pdb_id: str): # ...calculate automorphisms local_automorphisms = generate_automorphisms_from_atom_array_with_networkx(residue) - assert len(local_automorphisms) == len( - automorphism - ), "Unequal automorphism numbers; likely due to incorrect indexing." + assert len(local_automorphisms) == len(automorphism), ( + "Unequal automorphism numbers; likely due to incorrect indexing." + ) for local_automorphism in local_automorphisms: # ...map to the global frame, as given by the first row of the automorphism mapped_automorphism = automorphism[0][local_automorphism] # ...check that the automorphism is present - assert array_in_list( - mapped_automorphism, automorphism - ), "Automorphism not found in global automorphism list." + assert array_in_list(mapped_automorphism, automorphism), ( + "Automorphism not found in global automorphism list." + ) @pytest.mark.benchmark(group="find_automorphisms") diff --git a/tests/ml/transforms/test_af3_reference_molecule.py b/tests/ml/transforms/test_af3_reference_molecule.py index 96ba0002..408dae5d 100644 --- a/tests/ml/transforms/test_af3_reference_molecule.py +++ b/tests/ml/transforms/test_af3_reference_molecule.py @@ -187,9 +187,9 @@ def _assert_ref_pos_matches_ground_truth( mask: np.ndarray, ) -> None: """Assert that the reference positions are correctly aligned with the ground truth.""" - assert not np.any( - np.isclose(ref_pos, ground_truth_coord) - ), "Reference positions should differ from atom array coordinates under a transformation." + assert not np.any(np.isclose(ref_pos, ground_truth_coord)), ( + "Reference positions should differ from atom array coordinates under a transformation." + ) # Assert similar distances in masked positions dist1 = np.linalg.norm(ground_truth_coord[mask][:, None] - ground_truth_coord[mask], axis=2) @@ -243,16 +243,17 @@ def test_random_apply_ground_truth_conformer_by_chain_type(seed: int = 42): # Assert that all polymer atoms have the IGNORE policy polymer_mask = atom_array.is_polymer - assert np.all( - atom_array.ground_truth_conformer_policy[polymer_mask] == GroundTruthConformerPolicy.IGNORE - ), f"Expected all polymer atoms to have IGNORE policy, but got {atom_array.ground_truth_conformer_policy[polymer_mask]}" + assert np.all(atom_array.ground_truth_conformer_policy[polymer_mask] == GroundTruthConformerPolicy.IGNORE), ( + f"Expected all polymer atoms to have IGNORE policy, but got {atom_array.ground_truth_conformer_policy[polymer_mask]}" + ) # Assert that most non-polymer atoms have the REPLACE policy... non_polymer_mask = ~polymer_mask - assert ( - np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE) - > 0.5 * np.sum(non_polymer_mask) - ), f"Expected most non-polymer atoms to have REPLACE policy, but got {np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE)}" + assert np.sum( + atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE + ) > 0.5 * np.sum(non_polymer_mask), ( + f"Expected most non-polymer atoms to have REPLACE policy, but got {np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE)}" + ) # ... but not all assert np.any(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.IGNORE) @@ -355,9 +356,9 @@ def _prepare(res_name: str, chain_id: str, res_id: int, transformation_id: str) pipe = GetAF3ReferenceMoleculeFeatures(apply_random_rotation_and_translation=True) out = pipe({"atom_array": atom_array}) - assert np.all( - out["feats"]["ref_space_uid"] == expected_ref_space_uid - ), f"{out['feats']['ref_space_uid']}, but expected {expected_ref_space_uid}" + assert np.all(out["feats"]["ref_space_uid"] == expected_ref_space_uid), ( + f"{out['feats']['ref_space_uid']}, but expected {expected_ref_space_uid}" + ) def test_max_conformers_per_residue_functionality(): @@ -424,9 +425,9 @@ def test_af3_reference_molecule_features_with_cached_conformers(cache_dir): _ = transform_no_cache(data_no_cache) no_cache_time = time.time() - start_time - assert ( - cached_time < 0.8 * no_cache_time - ), f"Cached version should be faster than no cache version, but got {cached_time} vs {no_cache_time}" + assert cached_time < 0.8 * no_cache_time, ( + f"Cached version should be faster than no cache version, but got {cached_time} vs {no_cache_time}" + ) feats = result_data_cached["feats"] assert not np.any(np.isnan(feats["ref_pos"])) @@ -495,9 +496,9 @@ def test_af3_reference_molecule_features_with_subsampled_conformers(data_with_su actual_ref_mask = feats["ref_mask"][res_start:res_end] assert np.array_equal(actual_ref_mask, expected_ref_mask), "Reference masks don't match" - assert np.allclose( - expected_ref_pos[expected_ref_mask], actual_ref_pos[actual_ref_mask], atol=1e-6 - ), "Reference coordinates don't match" + assert np.allclose(expected_ref_pos[expected_ref_mask], actual_ref_pos[actual_ref_mask], atol=1e-6), ( + "Reference coordinates don't match" + ) def test_chiral_centers_with_cached_conformers(cache_dir, data_with_subsampled_conformers): diff --git a/tests/ml/transforms/test_atom_array.py b/tests/ml/transforms/test_atom_array.py index 58b11424..b3593719 100644 --- a/tests/ml/transforms/test_atom_array.py +++ b/tests/ml/transforms/test_atom_array.py @@ -58,12 +58,12 @@ def test_annotate_protein_termini(pdb_id: str): res_c_terminus = data["atom_array"][data["atom_array"].is_C_terminus] n_ntermini = struc.get_residue_count(res_n_terminus) n_ctermini = struc.get_residue_count(res_c_terminus) - assert ( - n_protein_chains == n_ntermini - ), f"Found {n_protein_chains} protein chains, but {n_ntermini} N-termini were annotated" - assert ( - n_protein_chains == n_ctermini - ), f"Found {n_protein_chains} protein chains, but {n_ctermini} C-termini were annotated" + assert n_protein_chains == n_ntermini, ( + f"Found {n_protein_chains} protein chains, but {n_ntermini} N-termini were annotated" + ) + assert n_protein_chains == n_ctermini, ( + f"Found {n_protein_chains} protein chains, but {n_ctermini} C-termini were annotated" + ) @pytest.mark.parametrize("pdb_id", MSA_PAIRING_PIPELINE_TEST_CASES) @@ -88,9 +88,9 @@ def test_add_within_poly_res_idx_annotation(pdb_id: str): # Check that all non-polymers have empty within_poly_res_idx non_polymer_chains = atom_array[~atom_array.is_polymer] - assert all( - non_polymer_chains.within_poly_res_idx == -1 - ), "Non-polymer chains should have within_poly_res_idx set -1" + assert all(non_polymer_chains.within_poly_res_idx == -1), ( + "Non-polymer chains should have within_poly_res_idx set -1" + ) # Check that we can use the within_poly_res_idx to index the MSA # Check that when we use `within_poly_res_idx` to index into the MSA, we get the same sequence as when we re-construct the one-letter sequence from the atom array diff --git a/tests/ml/transforms/test_atom_level_embeddings.py b/tests/ml/transforms/test_atom_level_embeddings.py index 531013fe..a8bc42ff 100644 --- a/tests/ml/transforms/test_atom_level_embeddings.py +++ b/tests/ml/transforms/test_atom_level_embeddings.py @@ -51,9 +51,9 @@ def test_featurize_with_unknown_residue(cache_dir, subsampled_cached_residue_dat has_embedding = result["has_atom_level_embedding"] # All atoms in the modified residue should have False in the mask - assert not has_embedding[ - res_mask - ].any(), f"Unknown residue {unknown_res_name} should have False mask for all its atoms" + assert not has_embedding[res_mask].any(), ( + f"Unknown residue {unknown_res_name} should have False mask for all its atoms" + ) # Verify embeddings for unknown residue are all zeros embeddings = result["atom_level_embedding"] # Shape: (n_conformers, L, D) @@ -109,9 +109,9 @@ def test_featurize_with_ignore_residues(cache_dir, subsampled_cached_residue_dat ignored_mask = atom_array.res_name == ignore_res_name if ignored_mask.any(): - assert not has_embedding[ - ignored_mask - ].any(), f"Ignored residue {ignore_res_name} should have False mask for all its atoms" + assert not has_embedding[ignored_mask].any(), ( + f"Ignored residue {ignore_res_name} should have False mask for all its atoms" + ) if __name__ == "__main__": diff --git a/tests/ml/transforms/test_bonds.py b/tests/ml/transforms/test_bonds.py index b4614214..b68de783 100644 --- a/tests/ml/transforms/test_bonds.py +++ b/tests/ml/transforms/test_bonds.py @@ -170,9 +170,9 @@ def test_create_rf2aa_bond_features_matrix(test_case): output = _create_rf2aa_bond_features_matrix( test_case["token_bond_adjacency"], test_case["token_is_atom"], test_case["atom_biotite_bond_type_matrix"] ) - assert np.array_equal( - output, test_case["expected_output"] - ), f"Expected {test_case['expected_output']}, but got {output}" + assert np.array_equal(output, test_case["expected_output"]), ( + f"Expected {test_case['expected_output']}, but got {output}" + ) @pytest.mark.parametrize("pdb_id", ["6wjc"]) @@ -271,12 +271,12 @@ def test_generate_rf2aa_traversal_distance_matrix(test_case): result = transform(data) # Check if the result matches the expected output, which matches the networkx output - assert np.allclose( - result["rf2aa_traversal_distance_matrix"], expected - ), f"Expected {expected}, but got {result['rf2aa_traversal_distance_matrix']}" - assert np.allclose( - result["rf2aa_traversal_distance_matrix"], expected_from_nx - ), f"Expected {expected_from_nx}, but got {result['rf2aa_traversal_distance_matrix']}" + assert np.allclose(result["rf2aa_traversal_distance_matrix"], expected), ( + f"Expected {expected}, but got {result['rf2aa_traversal_distance_matrix']}" + ) + assert np.allclose(result["rf2aa_traversal_distance_matrix"], expected_from_nx), ( + f"Expected {expected_from_nx}, but got {result['rf2aa_traversal_distance_matrix']}" + ) AF3_TOKEN_BOND_FEATURES_TEST_CASES = [ diff --git a/tests/ml/transforms/test_confidence_transforms.py b/tests/ml/transforms/test_confidence_transforms.py index e4d0434f..1dc68c14 100644 --- a/tests/ml/transforms/test_confidence_transforms.py +++ b/tests/ml/transforms/test_confidence_transforms.py @@ -104,12 +104,12 @@ def test_add_is_real_atom(test_case: dict[str, Any]): confidence_data = add_is_real_atom_pipeline(prepared_data) - assert confidence_data["is_real_atom"].sum() == len( - confidence_data["atom_array"] - ), "is_real_atom must account for all atoms in the atom array" - assert ( - confidence_data["is_real_atom"].shape == EXPECTED_OUTPUT_SHAPES[pdb_id]["is_real_atom"] - ), "is_real_atom shape should be [n_residues, 36]" + assert confidence_data["is_real_atom"].sum() == len(confidence_data["atom_array"]), ( + "is_real_atom must account for all atoms in the atom array" + ) + assert confidence_data["is_real_atom"].shape == EXPECTED_OUTPUT_SHAPES[pdb_id]["is_real_atom"], ( + "is_real_atom shape should be [n_residues, 36]" + ) @pytest.mark.parametrize("test_case", CONFIDENCE_MODIFICATION_TEST_CASES) diff --git a/tests/ml/transforms/test_crop.py b/tests/ml/transforms/test_crop.py index dc9ea87f..bfbc471a 100644 --- a/tests/ml/transforms/test_crop.py +++ b/tests/ml/transforms/test_crop.py @@ -163,9 +163,9 @@ def test_af3_like_spatial_crop_transform( # Ensure every query pn_unit is in the crop pn_unit_iids = np.unique(post_crop_atom_array.pn_unit_iid) - assert np.all( - np.isin(data["query_pn_unit_iids"], pn_unit_iids) - ), f"Query molecules {data['query_pn_unit_iids']} not in crop {pn_unit_iids}." + assert np.all(np.isin(data["query_pn_unit_iids"], pn_unit_iids)), ( + f"Query molecules {data['query_pn_unit_iids']} not in crop {pn_unit_iids}." + ) # Eval if no crop was performed if not data["crop_info"]["requires_crop"]: @@ -187,9 +187,9 @@ def test_af3_like_spatial_crop_transform( # Ensure correct, expected token count valid_pre_crop_tokens = get_token_count(pre_crop_atom_array[pre_crop_atom_array.occupancy > 0]) expected_token_count = min(crop_size, valid_pre_crop_tokens) - assert ( - get_token_count(post_crop_atom_array) == expected_token_count - ), f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." + assert get_token_count(post_crop_atom_array) == expected_token_count, ( + f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." + ) # Ensure there are no unoccupied atoms in the spatial crop assert np.all( @@ -198,19 +198,19 @@ def test_af3_like_spatial_crop_transform( # Check crop center atom crop_center_atom_id = data["crop_info"]["crop_center_atom_id"] - assert np.isin( - crop_center_atom_id, pre_crop_atom_array.atom_id - ), f"Crop center atom {crop_center_atom_id} not in pre-crop atom array." - assert np.isin( - crop_center_atom_id, post_crop_atom_array.atom_id - ), f"Crop center atom {crop_center_atom_id} not in post-crop atom array." + assert np.isin(crop_center_atom_id, pre_crop_atom_array.atom_id), ( + f"Crop center atom {crop_center_atom_id} not in pre-crop atom array." + ) + assert np.isin(crop_center_atom_id, post_crop_atom_array.atom_id), ( + f"Crop center atom {crop_center_atom_id} not in post-crop atom array." + ) # ... check that there is only one crop center crop_center = post_crop_atom_array[post_crop_atom_array.atom_id == crop_center_atom_id] assert len(crop_center) == 1, f"Expected exactly one crop center, got {len(crop_center)}." # ... check that crop center is occupied - assert ( - crop_center.occupancy[0] > 0 - ), f"Crop center atom {crop_center_atom_id} is not occupied in the cropped atom array." + assert crop_center.occupancy[0] > 0, ( + f"Crop center atom {crop_center_atom_id} is not occupied in the cropped atom array." + ) # ... check that crop center remains unchanged assert pre_crop_atom_array[pre_crop_atom_array.atom_id == crop_center_atom_id] == crop_center @@ -219,16 +219,16 @@ def test_af3_like_spatial_crop_transform( token_idx = atom_id_to_token_idx(post_crop_atom_array, crop_center_atom_id) post_crop_token = post_crop_atom_array[token_start_end_idxs[token_idx] : token_start_end_idxs[token_idx + 1]] # ... ensure atom id is inside token - assert np.isin( - crop_center_atom_id, post_crop_token.atom_id - ), f"Crop center atom {crop_center_atom_id} not in crop center token." + assert np.isin(crop_center_atom_id, post_crop_token.atom_id), ( + f"Crop center atom {crop_center_atom_id} not in crop center token." + ) # ... ensure token is unchanged token_start_end_idxs = get_token_starts(pre_crop_atom_array, add_exclusive_stop=True) token_idx = atom_id_to_token_idx(pre_crop_atom_array, crop_center_atom_id) pre_crop_token = pre_crop_atom_array[token_start_end_idxs[token_idx] : token_start_end_idxs[token_idx + 1]] - assert ( - pre_crop_token == post_crop_token - ), f"Crop center token {token_idx} changed: {pre_crop_token} -> {post_crop_token}" + assert pre_crop_token == post_crop_token, ( + f"Crop center token {token_idx} changed: {pre_crop_token} -> {post_crop_token}" + ) @pytest.mark.parametrize("example_id", BENCHMARK_EXAMPLE_IDS) @@ -262,9 +262,9 @@ def test_af3_like_contiguous_crop_transform( # Ensure correct, expected token count (in principle could be lower than 160 if there are fewer than 160 tokens in the full atom array) expected_token_count = min(crop_size, get_token_count(pre_crop_atom_array)) - assert ( - get_token_count(post_crop_atom_array) == expected_token_count - ), f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." + assert get_token_count(post_crop_atom_array) == expected_token_count, ( + f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." + ) if not data["crop_info"]["requires_crop"]: # ... no crop was performed @@ -283,9 +283,9 @@ def test_af3_like_contiguous_crop_transform( # Check that the molecule is contiguous (=fully connected by covalent bonds) submolecules = list(struc.molecule_iter(chain)) - assert ( - len(submolecules) == 1 - ), f"Chain {chain_iid} is not contiguous but has {len(submolecules)} connected components." + assert len(submolecules) == 1, ( + f"Chain {chain_iid} is not contiguous but has {len(submolecules)} connected components." + ) @pytest.mark.parametrize("example", BENCHMARK_EXAMPLES) @@ -360,9 +360,9 @@ def test_resize_crops_with_too_many_atoms(pdb_id, np_seed=1): data = prep_pipe(data) data = spatial_crop_pipe(data) post_crop_atom_array = data["atom_array"] - assert ( - len(post_crop_atom_array) < 3000 - ), f"Expected spatial crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." + assert len(post_crop_atom_array) < 3000, ( + f"Expected spatial crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." + ) # Test contiguous crop contiguous_crop_pipe = CropContiguousLikeAF3(crop_size=crop_size, max_atoms_in_crop=3000) @@ -371,9 +371,9 @@ def test_resize_crops_with_too_many_atoms(pdb_id, np_seed=1): data = prep_pipe(data) data = contiguous_crop_pipe(data) post_crop_atom_array = data["atom_array"] - assert ( - len(post_crop_atom_array) < 3000 - ), f"Expected contiguous crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." + assert len(post_crop_atom_array) < 3000, ( + f"Expected contiguous crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." + ) def test_compute_local_hash(): @@ -408,9 +408,9 @@ def test_compute_local_hash(): hash_post = compute_local_hash(post_crop) post_crop.set_annotation("hash_post", hash_post) - assert np.all( - post_crop.hash_pre == post_crop.hash_post - ), "Hash mismatch between pre- and post-crop despite not cropping." + assert np.all(post_crop.hash_pre == post_crop.hash_post), ( + "Hash mismatch between pre- and post-crop despite not cropping." + ) # Test 2: Spatial cropping crop_pipe = CropSpatialLikeAF3(crop_size=32) diff --git a/tests/ml/transforms/test_encodings.py b/tests/ml/transforms/test_encodings.py index c29afae7..70e60620 100644 --- a/tests/ml/transforms/test_encodings.py +++ b/tests/ml/transforms/test_encodings.py @@ -46,9 +46,9 @@ def test_encoding_af2_atom37_encoding(pdb_id: str): assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert ( - n_res == n_token_array - ), f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" + assert n_res == n_token_array, ( + f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" + ) @pytest.mark.parametrize("pdb_id", ["5ocm", "5ocn"]) @@ -84,9 +84,9 @@ def test_encoding_atom14_proteins_only(pdb_id: str, encoding: TokenEncoding): assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert ( - n_res == n_token_array - ), f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" + assert n_res == n_token_array, ( + f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" + ) @pytest.mark.parametrize("pdb_id", ["5ocm"]) @@ -123,9 +123,9 @@ def test_all_atom_encoding( assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert ( - n_res < n_token_array - ), f"n_res={n_res} > n_token_array={n_token_array} -- there should be more tokens than residues when atomizing" + assert n_res < n_token_array, ( + f"n_res={n_res} > n_token_array={n_token_array} -- there should be more tokens than residues when atomizing" + ) MOLECULE_TEST_CASES = [ @@ -173,30 +173,30 @@ def test_extra_annotations(test_case: dict): # Check `chain_id` annotations assert "chain_id" in data["encoded"], "chain_id not in encoded" - assert ( - len(data["encoded"]["chain_id"]) == n_token - ), f"chain_id length={len(data['encoded']['chain_id'])} != n_token={n_token}" + assert len(data["encoded"]["chain_id"]) == n_token, ( + f"chain_id length={len(data['encoded']['chain_id'])} != n_token={n_token}" + ) # Check `molecule_iid` annotations assert "molecule_iid" in data["encoded"], "molecule_iid not in encoded" - assert ( - len(data["encoded"]["molecule_iid"]) == n_token - ), f"molecule_iid length={len(data['encoded']['molecule_iid'])} != n_token={n_token}" - assert ( - len(data["encoded"]["molecule_iid_to_int"]) == test_case["num_molecules"] - ), f"molecule_iid_to_int length={len(data['encoded']['molecule_iid_to_int'])} != num_molecules={test_case['num_molecules']}" - assert np.all( - sorted(np.unique(data["encoded"]["molecule_iid"])) == np.arange(test_case["num_molecules"]) - ), f"molecule_iid unique values={np.unique(data['encoded']['molecule_iid'])} != num_molecules={test_case['num_molecules']}" + assert len(data["encoded"]["molecule_iid"]) == n_token, ( + f"molecule_iid length={len(data['encoded']['molecule_iid'])} != n_token={n_token}" + ) + assert len(data["encoded"]["molecule_iid_to_int"]) == test_case["num_molecules"], ( + f"molecule_iid_to_int length={len(data['encoded']['molecule_iid_to_int'])} != num_molecules={test_case['num_molecules']}" + ) + assert np.all(sorted(np.unique(data["encoded"]["molecule_iid"])) == np.arange(test_case["num_molecules"])), ( + f"molecule_iid unique values={np.unique(data['encoded']['molecule_iid'])} != num_molecules={test_case['num_molecules']}" + ) for molecule_iid, molecule_iidx in data["encoded"]["molecule_iid_to_int"].items(): raw_coords = atom_array[(atom_array.occupancy > 0) & (atom_array.molecule_iid == molecule_iid)].coord encoded_coords = data["encoded"]["xyz"][ (data["encoded"]["molecule_iid"] == molecule_iidx).reshape(-1, 1) & (data["encoded"]["mask"]) ] - assert ( - raw_coords.shape == encoded_coords.shape - ), f"raw_coords shape={raw_coords.shape} != encoded_coords shape={encoded_coords.shape}" + assert raw_coords.shape == encoded_coords.shape, ( + f"raw_coords shape={raw_coords.shape} != encoded_coords shape={encoded_coords.shape}" + ) # TODO: diff --git a/tests/ml/transforms/test_featurize_unresolved_residues.py b/tests/ml/transforms/test_featurize_unresolved_residues.py index 10191ff9..fb5fcc6e 100644 --- a/tests/ml/transforms/test_featurize_unresolved_residues.py +++ b/tests/ml/transforms/test_featurize_unresolved_residues.py @@ -155,9 +155,9 @@ def test_place_unresolved_token_on_closest_resolved_token_in_sequence(pdb_id): )(output) output_atom_array = output["atom_array"] - assert not np.isnan( - output_atom_array.coord_to_be_noised - ).any(), "There should be no NaNs in the output coordinates!" + assert not np.isnan(output_atom_array.coord_to_be_noised).any(), ( + "There should be no NaNs in the output coordinates!" + ) for chain_id in np.unique(output_atom_array.chain_id): chain_atom_array = output_atom_array[output_atom_array.chain_id == chain_id] diff --git a/tests/ml/transforms/test_filters.py b/tests/ml/transforms/test_filters.py index 68b4573b..9e9f9e3c 100644 --- a/tests/ml/transforms/test_filters.py +++ b/tests/ml/transforms/test_filters.py @@ -203,9 +203,9 @@ def test_remove_unsupported_chain_types(pdb_id: str, pn_units_df: pd.DataFrame): num_unsupported_atoms = len(original_atom_array) - len(atom_array) assert num_unsupported_atoms > 0, "There should be some atoms removed" chain_types = np.unique(atom_array.chain_type) - assert np.all( - np.isin(chain_types, TRAINING_SUPPORTED_CHAIN_TYPES) - ), "All remaining chain types should be supported" + assert np.all(np.isin(chain_types, TRAINING_SUPPORTED_CHAIN_TYPES)), ( + "All remaining chain types should be supported" + ) def test_handle_undesired_res_single(): @@ -393,9 +393,9 @@ def test_randomly_remove_ligands(): delete_probability=0.0, ) categories_0_percent = _categorize_pn_units(result_0_percent) - assert ( - categories_0_percent["all"] == original_categories["all"] - ), f"With 0% probability, all pn_units should remain. Expected {original_categories['counts']['all']}, got {categories_0_percent['counts']['all']}" + assert categories_0_percent["all"] == original_categories["all"], ( + f"With 0% probability, all pn_units should remain. Expected {original_categories['counts']['all']}, got {categories_0_percent['counts']['all']}" + ) # Test with 100% probability - all free-floating ligands should be removed with rng_state(create_rng_state_from_seeds(np_seed=42)): @@ -407,9 +407,9 @@ def test_randomly_remove_ligands(): categories_100_percent = _categorize_pn_units(result_100_percent) expected_remaining_100_percent = original_categories["all"] - original_categories["free_floating_ligand"] - assert ( - categories_100_percent["all"] == expected_remaining_100_percent - ), f"With 100% probability, only free-floating ligands should be removed. Expected {len(expected_remaining_100_percent)}, got {categories_100_percent['counts']['all']}" + assert categories_100_percent["all"] == expected_remaining_100_percent, ( + f"With 100% probability, only free-floating ligands should be removed. Expected {len(expected_remaining_100_percent)}, got {categories_100_percent['counts']['all']}" + ) # Test with 50% probability multiple times to verify randomness works results_50_percent = [] @@ -424,14 +424,14 @@ def test_randomly_remove_ligands(): results_50_percent.append(categories_50_percent["all"]) # Verify that the remaining pn_units are a subset of the original - assert categories_50_percent["all"].issubset( - original_categories["all"] - ), f"Remaining pn_units should be a subset of original (seed {seed})" + assert categories_50_percent["all"].issubset(original_categories["all"]), ( + f"Remaining pn_units should be a subset of original (seed {seed})" + ) # Verify that polymer pn_units are always preserved (they don't match the query) - assert ( - categories_50_percent["polymer"] == original_categories["polymer"] - ), f"Polymer pn_units should always be preserved (seed {seed})" + assert categories_50_percent["polymer"] == original_categories["polymer"], ( + f"Polymer pn_units should always be preserved (seed {seed})" + ) # Verify that we get different results across different seeds (randomness check) unique_results = {frozenset(result) for result in results_50_percent} diff --git a/tests/ml/transforms/test_rdkit_transforms.py b/tests/ml/transforms/test_rdkit_transforms.py index cb5313dd..6175fad3 100644 --- a/tests/ml/transforms/test_rdkit_transforms.py +++ b/tests/ml/transforms/test_rdkit_transforms.py @@ -86,9 +86,9 @@ def test_add_rdkit_molecules_for_atomized_molecules(test_case): expected_num_atoms = np.sum(pn_unit_mask) assert rdmol.GetNumAtoms() > 0, f"RDKit molecule {pn_unit_iid} has no atoms" assert rdmol.GetNumAtoms() == expected_num_atoms, f"RDKit molecule {pn_unit_iid} has the wrong number of atoms" - assert ( - Chem.SanitizeMol(rdmol, catchErrors=True) == Chem.SanitizeFlags.SANITIZE_NONE - ), f"RDKit molecule {pn_unit_iid} failed sanitization" + assert Chem.SanitizeMol(rdmol, catchErrors=True) == Chem.SanitizeFlags.SANITIZE_NONE, ( + f"RDKit molecule {pn_unit_iid} failed sanitization" + ) _mol_array = atom_array_from_rdkit( rdmol, set_coord_if_available=True, remove_hydrogens=True, remove_inferred_atoms=False diff --git a/tests/ml/transforms/test_rdkit_utils.py b/tests/ml/transforms/test_rdkit_utils.py index 7fb244ee..83efa0c0 100644 --- a/tests/ml/transforms/test_rdkit_utils.py +++ b/tests/ml/transforms/test_rdkit_utils.py @@ -167,13 +167,13 @@ def test_chirality_in_rdkit_conformer_generation(ccd_code, target_chirality, str for i in range(n_iterations): mol = ccd_code_to_rdkit_with_conformers(ccd_code, n_conformers=1, timeout=2, timeout_strategy=strategy) coord = mol.GetConformer(0).GetPositions()[0][0] - assert ( - coord != prev_coord - ), f"Conformer {i} has the same coordinate as the previous conformer: {coord} at iteration {i}/{n_iterations}." + assert coord != prev_coord, ( + f"Conformer {i} has the same coordinate as the previous conformer: {coord} at iteration {i}/{n_iterations}." + ) prev_coord = coord - assert ( - Chem.FindMolChiralCenters(mol) == target_chirality - ), f"Chiral center assignment is incorrect for {ccd_code} at iteration {i}/{n_iterations}." + assert Chem.FindMolChiralCenters(mol) == target_chirality, ( + f"Chiral center assignment is incorrect for {ccd_code} at iteration {i}/{n_iterations}." + ) @pytest.mark.filterwarnings("ignore: This process") diff --git a/tests/ml/transforms/test_templates.py b/tests/ml/transforms/test_templates.py index 5aadd035..9e5bd645 100644 --- a/tests/ml/transforms/test_templates.py +++ b/tests/ml/transforms/test_templates.py @@ -54,9 +54,9 @@ def test_add_rf_templates(test_case: dict): )(data) for chain, n_templates in test_case["n_templates"].items(): - assert ( - len(data["template"][chain]) == n_templates - ), f"For {pdb_id}-{chain}: Expected {n_templates} templates, got {len(data['template'][chain])}" + assert len(data["template"][chain]) == n_templates, ( + f"For {pdb_id}-{chain}: Expected {n_templates} templates, got {len(data['template'][chain])}" + ) @pytest.mark.parametrize("test_case", TEST_CASES) @@ -90,9 +90,9 @@ def test_subsample_template(test_case: dict): assert all(count <= 10 for count in template_counts), "Expected no template to have more than 10 templates" # Assert the mean is what we would expect (~7.5 = 0.5 * 10 + 0.5 * 5) - assert ( - 7.5 - 1 < sum(template_counts) / len(template_counts) < 7.5 + 1 - ), f"Expected mean to be around 7.5. Found {sum(template_counts) / len(template_counts)}. This is a stochastic test, so running again may fix this." + assert 7.5 - 1 < sum(template_counts) / len(template_counts) < 7.5 + 1, ( + f"Expected mean to be around 7.5. Found {sum(template_counts) / len(template_counts)}. This is a stochastic test, so running again may fix this." + ) @pytest.mark.parametrize("test_case", TEST_CASES) @@ -118,12 +118,12 @@ def test_add_rf_templates_filters( assert len(templates) > 0, f"No templates found for {pdb_id}-{chain}" assert len(templates) <= 5, f"Expected 5 templates, got {len(templates)} for {pdb_id}-{chain}" for template in templates: - assert ( - min_seq_similarity <= template["seq_similarity"] <= max_seq_similarity - ), f"Expected seq similarity between {min_seq_similarity} and {max_seq_similarity}, got {template['seq_similarity']} for {pdb_id}-{chain}-{template['id']}" - assert ( - template["n_res"] >= min_template_length - ), f"Expected at least {min_template_length} residues, got {template['n_res']} for {pdb_id}-{chain}-{template['id']}" + assert min_seq_similarity <= template["seq_similarity"] <= max_seq_similarity, ( + f"Expected seq similarity between {min_seq_similarity} and {max_seq_similarity}, got {template['seq_similarity']} for {pdb_id}-{chain}-{template['id']}" + ) + assert template["n_res"] >= min_template_length, ( + f"Expected at least {min_template_length} residues, got {template['n_res']} for {pdb_id}-{chain}-{template['id']}" + ) @pytest.mark.parametrize("test_case", TEST_CASES) @@ -186,15 +186,15 @@ def test_featurize_rf_templates(test_case: dict, encoding: TokenEncoding, n_temp assert t1d_template[0].shape == seq_encoded.shape # Check that the t1d last axis adds up to one when excluding the last dimension - assert torch.all( - t1d_template[..., :-1].sum(dim=-1) == 1 - ), f"Expected t1d last axis to add up to one (one-hot encoded), but got {t1d_template[..., :-1].sum(dim=-1)}" + assert torch.all(t1d_template[..., :-1].sum(dim=-1) == 1), ( + f"Expected t1d last axis to add up to one (one-hot encoded), but got {t1d_template[..., :-1].sum(dim=-1)}" + ) # Check that alignment confidences exist for all non-masked tokens is_masked = t1d_template[..., 21] == 1 - assert torch.all( - t1d_template[..., -1][~is_masked] > 0 - ), "Expected t1d last axis to be greater than zero (alignment confidence)" + assert torch.all(t1d_template[..., -1][~is_masked] > 0), ( + "Expected t1d last axis to be greater than zero (alignment confidence)" + ) # Check that all not-masked tokens have finite coordinates assert torch.all(torch.isfinite(xyz_template[mask_template])), "Expected non-masked template xyz to be finite" @@ -238,7 +238,9 @@ def test_add_input_file_template(test_case: dict): assert ( set(input_file_template[chosen_chain_to_template][0].keys()) == training_pipeline_template[chosen_chain_to_template][0].keys() - ), f"Expected input file template to have the same keys as the training pipeline template, but got {set(input_file_template[chosen_chain_to_template][0].keys())} and {set(training_pipeline_template[chosen_chain_to_template][0].keys())}" + ), ( + f"Expected input file template to have the same keys as the training pipeline template, but got {set(input_file_template[chosen_chain_to_template][0].keys())} and {set(training_pipeline_template[chosen_chain_to_template][0].keys())}" + ) # check that the template has the same fields as the template from AddRFTemplates required_annotations = [ @@ -251,30 +253,28 @@ def test_add_input_file_template(test_case: dict): training_pipeline_template_annotations = training_pipeline_template[chosen_chain_to_template][0][ "atom_array" ].get_annotation_categories() - assert set( - required_annotations - ).issubset( - input_file_template_annotations - ), f"Input file template is missing the following annotations: {set(required_annotations) - set(input_file_template_annotations)}" - assert set( - required_annotations - ).issubset( - training_pipeline_template_annotations - ), f"Training pipeline template is missing the following annotations: {set(required_annotations) - set(training_pipeline_template_annotations)}" + assert set(required_annotations).issubset(input_file_template_annotations), ( + f"Input file template is missing the following annotations: {set(required_annotations) - set(input_file_template_annotations)}" + ) + assert set(required_annotations).issubset(training_pipeline_template_annotations), ( + f"Training pipeline template is missing the following annotations: {set(required_annotations) - set(training_pipeline_template_annotations)}" + ) # check that one template has added for the first polymer chain - assert ( - len(input_file_template[chosen_chain_to_template]) == 1 - ), f"Expected input file template to have one template, but got {len(input_file_template[chosen_chain_to_template])}" + assert len(input_file_template[chosen_chain_to_template]) == 1, ( + f"Expected input file template to have one template, but got {len(input_file_template[chosen_chain_to_template])}" + ) - assert np.all( - input_file_template[chosen_chain_to_template][0]["atom_array"].alignment_confidence == 1 - ), f"Expected input file template to have template confidence of 1, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].alignment_confidence}" + assert np.all(input_file_template[chosen_chain_to_template][0]["atom_array"].alignment_confidence == 1), ( + f"Expected input file template to have template confidence of 1, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].alignment_confidence}" + ) assert np.all( input_file_template[chosen_chain_to_template][0]["atom_array"].aligned_query_res_idx == input_file_template[chosen_chain_to_template][0]["atom_array"].res_id - ), f"Expected input file template to have aligned query res idx equal to res id, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].aligned_query_res_idx} and {input_file_template[chosen_chain_to_template][0]['atom_array'].res_id}" + ), ( + f"Expected input file template to have aligned query res idx equal to res id, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].aligned_query_res_idx} and {input_file_template[chosen_chain_to_template][0]['atom_array'].res_id}" + ) @pytest.mark.parametrize("test_case", TEST_CASES) @@ -312,6 +312,6 @@ def test_featurize_input_templates(test_case): "template_distogram", "template_unit_vector", ] - assert set(expected_template_features).issubset( - data["feats"].keys() - ), f"Expected template features to be present, but got {set(data['feats'].keys())} instead" + assert set(expected_template_features).issubset(data["feats"].keys()), ( + f"Expected template features to be present, but got {set(data['feats'].keys())} instead" + ) diff --git a/tests/ml/transforms/test_token_utils.py b/tests/ml/transforms/test_token_utils.py index 2db6e355..2e4db014 100644 --- a/tests/ml/transforms/test_token_utils.py +++ b/tests/ml/transforms/test_token_utils.py @@ -75,9 +75,9 @@ def test_add_global_token_id_annotation_when_fully_atomized(pdb_id): assert "atom_id" in atom_array.get_annotation_categories() assert "token_id" in atom_array.get_annotation_categories() - assert np.all( - atom_array.atom_id == atom_array.token_id - ), "atom_id and token_id should be the same for a fully atomized atom_array" + assert np.all(atom_array.atom_id == atom_array.token_id), ( + "atom_id and token_id should be the same for a fully atomized atom_array" + ) # cross check by iterating over the tokens # ... via token starts @@ -252,19 +252,19 @@ def test_add_global_res_id_annotation(): # Check that res_id_global values are in the expected range unique_global_res_ids = np.unique(atom_array.res_id_global) - assert ( - len(unique_global_res_ids) == expected_n_residues - ), f"Expected {expected_n_residues} unique residue IDs, got {len(unique_global_res_ids)}" - assert np.all( - unique_global_res_ids == np.arange(expected_n_residues) - ), "Global residue IDs should be 0-indexed and continuous" + assert len(unique_global_res_ids) == expected_n_residues, ( + f"Expected {expected_n_residues} unique residue IDs, got {len(unique_global_res_ids)}" + ) + assert np.all(unique_global_res_ids == np.arange(expected_n_residues)), ( + "Global residue IDs should be 0-indexed and continuous" + ) # Check that residues have consistent res_id_global values for counter, residue in enumerate(struc.residue_iter(atom_array)): assert len(residue) >= 1, f"Residue should have length at least 1 but has length {len(residue)}" - assert np.all( - residue.res_id_global == counter - ), f"All atoms in residue should have res_id_global {counter} but got {residue.res_id_global}" + assert np.all(residue.res_id_global == counter), ( + f"All atoms in residue should have res_id_global {counter} but got {residue.res_id_global}" + ) if __name__ == "__main__": diff --git a/tests/ml/utils/test_misc_utils.py b/tests/ml/utils/test_misc_utils.py index befde322..6d586752 100644 --- a/tests/ml/utils/test_misc_utils.py +++ b/tests/ml/utils/test_misc_utils.py @@ -29,9 +29,9 @@ @pytest.mark.parametrize("test_case", GROUPED_SUM_TEST_CASES) def test_grouped_sum(test_case): output = grouped_sum(test_case["data"], test_case["assignment"], test_case["num_groups"]) - assert torch.equal( - output, test_case["expected_output"] - ), f"Expected {test_case['expected_output']}, but got {output}" + assert torch.equal(output, test_case["expected_output"]), ( + f"Expected {test_case['expected_output']}, but got {output}" + ) # Test cases for masked_mean @@ -68,6 +68,6 @@ def test_masked_mean(test_case): axis=test_case["axis"], drop_mask_channel=test_case["drop_mask_channel"], ) - assert torch.allclose( - output, test_case["expected_output"], atol=1e-6 - ), f"Expected {test_case['expected_output']}, but got {output}" + assert torch.allclose(output, test_case["expected_output"], atol=1e-6), ( + f"Expected {test_case['expected_output']}, but got {output}" + ) diff --git a/tests/ml/utils/test_rng_context.py b/tests/ml/utils/test_rng_context.py index f0cdaddf..1b73aec8 100644 --- a/tests/ml/utils/test_rng_context.py +++ b/tests/ml/utils/test_rng_context.py @@ -41,24 +41,24 @@ def test_rng_state(): torch_inside_expected = torch.tensor([0.88226926, 0.91500396, 0.38286376]) python_inside_expected = [0.6394267984578837, 0.025010755222666936, 0.27502931836911926] - assert not np.array_equal( - initial_numpy, final_numpy - ), "NumPy values should be different outside the context manager" + assert not np.array_equal(initial_numpy, final_numpy), ( + "NumPy values should be different outside the context manager" + ) assert not torch.equal(initial_torch, final_torch), "PyTorch values should be different outside the context manager" assert initial_python != final_python, "Python random values should be different outside the context manager" - assert np.array_equal( - numpy_inside, numpy_inside_again - ), "NumPy values should be the same inside the context manager" + assert np.array_equal(numpy_inside, numpy_inside_again), ( + "NumPy values should be the same inside the context manager" + ) assert torch.equal(torch_inside, torch_inside_again), "PyTorch values should be the same inside the context manager" assert python_inside == python_inside_again, "Python random values should be the same inside the context manager" - assert np.allclose( - numpy_inside, numpy_inside_expected - ), "NumPy values should be the same inside the context manager" - assert torch.allclose( - torch_inside, torch_inside_expected - ), "PyTorch values should be the same inside the context manager" + assert np.allclose(numpy_inside, numpy_inside_expected), ( + "NumPy values should be the same inside the context manager" + ) + assert torch.allclose(torch_inside, torch_inside_expected), ( + "PyTorch values should be the same inside the context manager" + ) assert python_inside == python_inside_expected, "Python random values should be the same inside the context manager" From 4941565a768ce39887773db12b6f158d932c97c2 Mon Sep 17 00:00:00 2001 From: TomiiLabo Date: Tue, 16 Dec 2025 10:22:25 +0900 Subject: [PATCH 6/6] style: apply formatting fixes --- src/atomworks/io/parser.py | 6 +- src/atomworks/io/tools/rdkit.py | 6 +- src/atomworks/io/transforms/categories.py | 6 +- src/atomworks/io/utils/assembly.py | 6 +- src/atomworks/io/utils/atom_array_plus.py | 12 +-- src/atomworks/io/utils/testing.py | 18 ++--- src/atomworks/ml/encoding_definitions.py | 24 +++--- src/atomworks/ml/pipelines/af3.py | 6 +- src/atomworks/ml/pipelines/rf2aa.py | 6 +- src/atomworks/ml/samplers.py | 6 +- .../ml/transforms/af3_reference_molecule.py | 6 +- src/atomworks/ml/transforms/atom_array.py | 24 +++--- .../ml/transforms/atom_level_embeddings.py | 6 +- src/atomworks/ml/transforms/base.py | 12 +-- .../transforms/center_random_augmentation.py | 6 +- src/atomworks/ml/transforms/crop.py | 24 +++--- .../transforms/diffusion/batch_structures.py | 6 +- src/atomworks/ml/transforms/diffusion/edm.py | 6 +- src/atomworks/ml/transforms/dna/pad_dna.py | 6 +- src/atomworks/ml/transforms/filters.py | 6 +- src/atomworks/ml/transforms/mask_generator.py | 36 ++++----- src/atomworks/ml/transforms/masks.py | 6 +- .../ml/transforms/msa/_msa_pairing_utils.py | 6 +- src/atomworks/ml/transforms/msa/msa.py | 6 +- .../ml/transforms/openbabel_utils.py | 6 +- src/atomworks/ml/transforms/rdkit_utils.py | 6 +- .../ml/transforms/rf2aa_assumptions.py | 60 +++++++------- src/atomworks/ml/transforms/symmetry.py | 6 +- src/atomworks/ml/transforms/template.py | 60 +++++++------- src/atomworks/ml/utils/misc.py | 6 +- src/atomworks/ml/utils/numpy.py | 12 +-- src/atomworks/ml/utils/rng.py | 6 +- src/atomworks/ml/utils/token.py | 18 ++--- tests/io/components/test_chain_types.py | 12 +-- .../io/components/test_entity_annotations.py | 12 +-- tests/io/components/test_identifiers.py | 6 +- tests/io/components/test_ignore_residues.py | 12 +-- tests/io/components/test_logging.py | 12 +-- tests/io/tools/test_inference_processing.py | 6 +- tests/io/tools/test_rdkit.py | 12 +-- tests/io/utils/test_scatter.py | 42 +++++----- tests/io/utils/test_testing_tools.py | 6 +- tests/ml/conditions/test_annotator.py | 6 +- .../ml/conditions/test_condition_save_load.py | 16 ++-- .../ml/datasets/test_datasets_with_filters.py | 30 +++---- .../pipelines/test_data_loading_pipelines.py | 12 +-- .../ml/pipelines/test_inference_pipelines.py | 18 ++--- .../ml/pipelines/test_pipeline_regression.py | 12 +-- .../preprocessing/test_filtering_criteria.py | 6 +- tests/ml/preprocessing/test_get_atom_mask.py | 6 +- tests/ml/preprocessing/test_loi_extraction.py | 6 +- tests/ml/transforms/msa/test_featurize_msa.py | 72 ++++++++--------- tests/ml/transforms/msa/test_load_msas.py | 24 +++--- .../symmetry/test_automorphisms_networkx.py | 24 +++--- .../transforms/test_af3_reference_molecule.py | 39 +++++----- tests/ml/transforms/test_atom_array.py | 18 ++--- .../transforms/test_atom_level_embeddings.py | 12 +-- tests/ml/transforms/test_bonds.py | 18 ++--- .../transforms/test_confidence_transforms.py | 12 +-- tests/ml/transforms/test_crop.py | 72 ++++++++--------- tests/ml/transforms/test_encodings.py | 48 ++++++------ .../test_featurize_unresolved_residues.py | 6 +- tests/ml/transforms/test_filters.py | 30 +++---- tests/ml/transforms/test_rdkit_transforms.py | 6 +- tests/ml/transforms/test_rdkit_utils.py | 12 +-- tests/ml/transforms/test_templates.py | 78 +++++++++---------- tests/ml/transforms/test_token_utils.py | 24 +++--- tests/ml/utils/test_misc_utils.py | 12 +-- tests/ml/utils/test_rng_context.py | 24 +++--- 69 files changed, 596 insertions(+), 599 deletions(-) diff --git a/src/atomworks/io/parser.py b/src/atomworks/io/parser.py index 399d70c6..d57e75fe 100644 --- a/src/atomworks/io/parser.py +++ b/src/atomworks/io/parser.py @@ -637,9 +637,9 @@ def parse_atom_array( # ... build assemblies and add assembly-specific annotations (instance IDs like `chain_iid`, `pn_unit_iid`, `molecule_iid`) if exists(build_assembly): - assert build_assembly in ["first", "all"] or isinstance(build_assembly, list | tuple), ( - "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." - ) + assert build_assembly in ["first", "all"] or isinstance( + build_assembly, list | tuple + ), "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." # Determine assembly categories: use CIF data if build_assembly is set, otherwise identity operations if exists(build_assembly) and exists(_cif_file) and "pdbx_struct_assembly" in data_dict["cif_block"]: diff --git a/src/atomworks/io/tools/rdkit.py b/src/atomworks/io/tools/rdkit.py index 6e4f679f..03ef2e07 100644 --- a/src/atomworks/io/tools/rdkit.py +++ b/src/atomworks/io/tools/rdkit.py @@ -762,9 +762,9 @@ def atom_array_to_rdkit( # ... verify that atoms that are labelled as `_should_be_aromatic` are aromatic for atom_idx in _should_be_aromatic: - assert mol.GetAtomWithIdx(atom_idx).GetIsAromatic(), ( - f"Atom {atom_idx} is not aromatic but was labelled as aromatic." - ) + assert mol.GetAtomWithIdx( + atom_idx + ).GetIsAromatic(), f"Atom {atom_idx} is not aromatic but was labelled as aromatic." # Turn into a non-editable molecule mol = mol.GetMol() if isinstance(mol, Chem.RWMol) else mol diff --git a/src/atomworks/io/transforms/categories.py b/src/atomworks/io/transforms/categories.py index 171a9702..eabea63a 100644 --- a/src/atomworks/io/transforms/categories.py +++ b/src/atomworks/io/transforms/categories.py @@ -158,9 +158,9 @@ def get_metadata_from_category(cif_block: CIFBlock, fallback_id: str | None = No metadata = {} # Assert that if the "entry.id" field is NOT present, a fallback ID is provided - assert ("entry" in cif_block and "id" in cif_block["entry"]) or fallback_id is not None, ( - "No ID found in CIF block or provided as fallback." - ) + assert ( + "entry" in cif_block and "id" in cif_block["entry"] + ) or fallback_id is not None, "No ID found in CIF block or provided as fallback." # Set the ID field, using the fallback if necessary metadata["id"] = ( diff --git a/src/atomworks/io/utils/assembly.py b/src/atomworks/io/utils/assembly.py index e25c326f..b6e7ccb7 100644 --- a/src/atomworks/io/utils/assembly.py +++ b/src/atomworks/io/utils/assembly.py @@ -119,9 +119,9 @@ def _build_bioassembly_from_asym_unit( to_build = available_assembly_ids else: # Assert that the given `assembly_ids` are valid - assert isinstance(assembly_ids, list | tuple) and all(isinstance(_id, str) for _id in assembly_ids), ( - "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." - ) + assert isinstance(assembly_ids, list | tuple) and all( + isinstance(_id, str) for _id in assembly_ids + ), "Invalid `build_assembly` option. Must be 'first', 'all', or a list/tuple of assembly IDs as strings." to_build = assembly_ids # ensure instructions for each requested assembly id exist diff --git a/src/atomworks/io/utils/atom_array_plus.py b/src/atomworks/io/utils/atom_array_plus.py index d3307908..ec5dbc70 100644 --- a/src/atomworks/io/utils/atom_array_plus.py +++ b/src/atomworks/io/utils/atom_array_plus.py @@ -928,9 +928,9 @@ def insert_atoms( The function is robust to both AtomArray and AtomArrayPlus, and preserves 2D annotations and bonds. """ n_atoms_orig = arr.array_length() - assert isinstance(new_atoms, list) and isinstance(new_atoms[0], AtomArray | AtomArrayPlus | struc.Atom), ( - "new_atoms must be a list of AtomArray, AtomArrayPlus, or Atom objects." - ) + assert isinstance(new_atoms, list) and isinstance( + new_atoms[0], AtomArray | AtomArrayPlus | struc.Atom + ), "new_atoms must be a list of AtomArray, AtomArrayPlus, or Atom objects." assert len(new_atoms) == len(insert_positions), "Each new atom must have a corresponding insert position." arr_all = concatenate_any([arr, *new_atoms]) @@ -954,9 +954,9 @@ def insert_atoms( if pos < n_atoms_orig: result_indices.append(orig_idx) orig_idx += 1 - assert len(result_indices) == arr_all.array_length(), ( - "Result indices must match the length of the concatenated array" - ) + assert ( + len(result_indices) == arr_all.array_length() + ), "Result indices must match the length of the concatenated array" return arr_all[result_indices] diff --git a/src/atomworks/io/utils/testing.py b/src/atomworks/io/utils/testing.py index abbb7e7e..582abd3d 100644 --- a/src/atomworks/io/utils/testing.py +++ b/src/atomworks/io/utils/testing.py @@ -189,12 +189,12 @@ def assert_same_atom_array( Raises: AssertionError: If the AtomArray objects are not equal. """ - assert isinstance(arr1, AtomArray | AtomArrayStack), ( - f"arr1 is not an AtomArray or AtomArrayStack but has type {type(arr1)}" - ) - assert isinstance(arr2, AtomArray | AtomArrayStack), ( - f"arr2 is not an AtomArray or AtomArrayStack but has type {type(arr2)}" - ) + assert isinstance( + arr1, AtomArray | AtomArrayStack + ), f"arr1 is not an AtomArray or AtomArrayStack but has type {type(arr1)}" + assert isinstance( + arr2, AtomArray | AtomArrayStack + ), f"arr2 is not an AtomArray or AtomArrayStack but has type {type(arr2)}" # Copy both arrays to avoid modifying the original arrays arr1 = arr1.copy() @@ -231,9 +231,9 @@ def assert_same_atom_array( raise AssertionError(msg) if compare_coords: - assert arr1.coord.shape == arr2.coord.shape, ( - f"Coord shapes do not match: {arr1.coord.shape} != {arr2.coord.shape}" - ) + assert ( + arr1.coord.shape == arr2.coord.shape + ), f"Coord shapes do not match: {arr1.coord.shape} != {arr2.coord.shape}" if not np.allclose(arr1.coord, arr2.coord, equal_nan=True, atol=1e-3, rtol=1e-3): mismatch_idxs = np.where(arr1.coord != arr2.coord)[0] msg = f"Coords do not match at {len(mismatch_idxs)} indices. First few mismatches:" + "\n" diff --git a/src/atomworks/ml/encoding_definitions.py b/src/atomworks/ml/encoding_definitions.py index dc728c6a..04a08deb 100644 --- a/src/atomworks/ml/encoding_definitions.py +++ b/src/atomworks/ml/encoding_definitions.py @@ -83,15 +83,15 @@ def __post_init__(self): # Ensure all values are of type `np.ndarray` and have the same 1-dimensional shape _target_len = len(next(iter(self.token_atoms.values()))) for token, atoms in self.token_atoms.items(): - assert isinstance(atoms, np.ndarray), ( - f"Expected `atoms` to be a `np.ndarray`, but got {type(atoms)} for token {token}." - ) - assert atoms.ndim == 1, ( - f"Expected `atoms` to be a 1-dimensional array, but got {atoms.ndim} dimensions for token {token}." - ) - assert len(atoms) == _target_len, ( - f"Expected all atoms to have length {_target_len}, but got {len(atoms)} for token {token}." - ) + assert isinstance( + atoms, np.ndarray + ), f"Expected `atoms` to be a `np.ndarray`, but got {type(atoms)} for token {token}." + assert ( + atoms.ndim == 1 + ), f"Expected `atoms` to be a 1-dimensional array, but got {atoms.ndim} dimensions for token {token}." + assert ( + len(atoms) == _target_len + ), f"Expected all atoms to have length {_target_len}, but got {len(atoms)} for token {token}." # Define mapping of unknown `chemcomp_type` to unknown token names if not exists(self.chemcomp_type_to_unknown): @@ -112,9 +112,9 @@ def __post_init__(self): # NOTE: This is set here to use caching. @lru_cache(maxsize=10000) def resolve_unknown_token_name(token_name: str | int, token_is_atom: bool) -> str: - assert isinstance(token_name, str | int | np.integer), ( - f"Expected `token_name` to be a string or int, but got {type(token_name)}: token_name={token_name}, token_is_atom={token_is_atom}." - ) + assert isinstance( + token_name, str | int | np.integer + ), f"Expected `token_name` to be a string or int, but got {type(token_name)}: token_name={token_name}, token_is_atom={token_is_atom}." # Case 1: Token is known & valid if token_name in self.token_atoms: diff --git a/src/atomworks/ml/pipelines/af3.py b/src/atomworks/ml/pipelines/af3.py index cc890b33..0a2c4e97 100644 --- a/src/atomworks/ml/pipelines/af3.py +++ b/src/atomworks/ml/pipelines/af3.py @@ -178,9 +178,9 @@ def build_af3_transform_pipeline( """ if (crop_contiguous_probability > 0 or crop_spatial_probability > 0) and not is_inference: - assert np.isclose(crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6), ( - "Crop probabilities must sum to 1.0" - ) + assert np.isclose( + crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6 + ), "Crop probabilities must sum to 1.0" assert crop_size > 0, "Crop size must be greater than 0" assert crop_center_cutoff_distance > 0, "Crop center cutoff distance must be greater than 0" diff --git a/src/atomworks/ml/pipelines/rf2aa.py b/src/atomworks/ml/pipelines/rf2aa.py index 3f429393..a36d421d 100644 --- a/src/atomworks/ml/pipelines/rf2aa.py +++ b/src/atomworks/ml/pipelines/rf2aa.py @@ -276,9 +276,9 @@ def build_rf2aa_transform_pipeline( Compose: A composed transformation pipeline. """ if crop_contiguous_probability > 0 or crop_spatial_probability > 0: - assert np.isclose(crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6), ( - "Crop probabilities must sum to 1.0" - ) + assert np.isclose( + crop_contiguous_probability + crop_spatial_probability, 1.0, atol=1e-6 + ), "Crop probabilities must sum to 1.0" assert crop_size > 0, "Crop size must be greater than 0" assert crop_center_cutoff_distance > 0, "Crop center cutoff distance must be greater than 0" diff --git a/src/atomworks/ml/samplers.py b/src/atomworks/ml/samplers.py index fe31e8cf..e47ba0ed 100644 --- a/src/atomworks/ml/samplers.py +++ b/src/atomworks/ml/samplers.py @@ -319,9 +319,9 @@ def _set_num_examples_per_epoch(self, n_examples_per_epoch: int) -> None: # ... and assert that either we have more than n_examples_per_epoch examples or we are sampling with replacement sampler_has_enough_data = len(sampler) >= n_examples sampler_is_replacement = getattr(sampler, "replacement", False) - assert sampler_has_enough_data or sampler_is_replacement, ( - "Must either have enough data or be sampling with replacement" - ) + assert ( + sampler_has_enough_data or sampler_is_replacement + ), "Must either have enough data or be sampling with replacement" def __iter__(self): # Trigger the __iter__ of each sampler upfront (generates a list of local indices based on the sampling scheme) diff --git a/src/atomworks/ml/transforms/af3_reference_molecule.py b/src/atomworks/ml/transforms/af3_reference_molecule.py index fb270b66..05d707a3 100644 --- a/src/atomworks/ml/transforms/af3_reference_molecule.py +++ b/src/atomworks/ml/transforms/af3_reference_molecule.py @@ -432,9 +432,9 @@ def get_af3_reference_molecule_features( ref_atom_name_chars = _encode_atom_names_like_af3(atom_array.atom_name) if use_element_for_atom_names_of_atomized_tokens: - assert "atomize" in atom_array.get_annotation_categories(), ( - "Atomize annotation is required when using element for atom names of atomized tokens." - ) + assert ( + "atomize" in atom_array.get_annotation_categories() + ), "Atomize annotation is required when using element for atom names of atomized tokens." ref_atom_name_chars[atom_array.atomize] = _encode_atom_names_like_af3(atom_array.element[atom_array.atomize]) # ... space uid (type conversion needed for some older torch versions) diff --git a/src/atomworks/ml/transforms/atom_array.py b/src/atomworks/ml/transforms/atom_array.py index 2afdc1a3..f317bb89 100644 --- a/src/atomworks/ml/transforms/atom_array.py +++ b/src/atomworks/ml/transforms/atom_array.py @@ -379,9 +379,9 @@ def copy_annotation(atom_array: AtomArray, annotation_to_copy: str, new_annotati updated_atom_array = copy_annotation(atom_array, "coord", "coord_to_be_noised") """ - assert new_annotation not in atom_array.get_annotation_categories() and new_annotation != "coord", ( - f"Annotation {new_annotation} already exists in the AtomArray." - ) + assert ( + new_annotation not in atom_array.get_annotation_categories() and new_annotation != "coord" + ), f"Annotation {new_annotation} already exists in the AtomArray." if annotation_to_copy == "coord": # We must handle the special case of copying the coordinates (since "coord" is not technically an annotation) @@ -400,12 +400,12 @@ def __init__(self, annotation_to_copy: str, new_annotation: str): self.new_annotation = new_annotation def check_input(self, data: dict) -> None: - assert has_annotation(data["atom_array"], self.annotation_to_copy), ( - f"Annotation {self.annotation_to_copy} does not exist in the AtomArray." - ) - assert not has_annotation(data["atom_array"], self.new_annotation), ( - f"Annotation {self.new_annotation} already exists in the AtomArray." - ) + assert has_annotation( + data["atom_array"], self.annotation_to_copy + ), f"Annotation {self.annotation_to_copy} does not exist in the AtomArray." + assert not has_annotation( + data["atom_array"], self.new_annotation + ), f"Annotation {self.new_annotation} already exists in the AtomArray." def forward(self, data: dict) -> dict: data["atom_array"] = copy_annotation( @@ -643,9 +643,9 @@ def sort_like_rf2aa(atom_array: AtomArray) -> AtomArray: pn_unit_mask = atom_array.pn_unit_iid == pn_unit_iid is_bonded_non_poly[pn_unit_mask] = np.any(is_poly[pn_unit_mask]) & is_non_poly[pn_unit_mask] is_free_non_poly = is_non_poly & (~is_bonded_non_poly) - assert np.sum(is_poly) + np.sum(is_bonded_non_poly) + np.sum(is_free_non_poly) == len(atom_array), ( - "overlapping groups" - ) + assert np.sum(is_poly) + np.sum(is_bonded_non_poly) + np.sum(is_free_non_poly) == len( + atom_array + ), "overlapping groups" # Sort by indexing according to # 0: by poly / bonded non-poly / free non-poly diff --git a/src/atomworks/ml/transforms/atom_level_embeddings.py b/src/atomworks/ml/transforms/atom_level_embeddings.py index 8f5fe583..b977244e 100644 --- a/src/atomworks/ml/transforms/atom_level_embeddings.py +++ b/src/atomworks/ml/transforms/atom_level_embeddings.py @@ -65,9 +65,9 @@ def featurize_atom_level_embeddings( ) _has_descriptors = True except (StopIteration, ValueError): - assert embedding_dim is not None and n_conformers is not None, ( - "embedding_dim and n_conformers must be provided if no descriptors are available" - ) + assert ( + embedding_dim is not None and n_conformers is not None + ), "embedding_dim and n_conformers must be provided if no descriptors are available" _has_descriptors = False default_return = { diff --git a/src/atomworks/ml/transforms/base.py b/src/atomworks/ml/transforms/base.py index 5a24080b..0d1b8a5b 100644 --- a/src/atomworks/ml/transforms/base.py +++ b/src/atomworks/ml/transforms/base.py @@ -342,9 +342,9 @@ def __call__(self, data: dict[str, Any], *args, **kwargs) -> dict[str, Any]: # apply the transformation data = self.forward(data, *args, **kwargs) - assert isinstance(data, dict), ( - f"`forward` method of {self.__class__.__name__} must return a dictionary, not {type(data)}." - ) + assert isinstance( + data, dict + ), f"`forward` method of {self.__class__.__name__} must return a dictionary, not {type(data)}." # restore the transform history if `data` was copied (which loses the transform history) data = self._ensure_has_transform_history(data) @@ -798,9 +798,9 @@ def __init__(self, transforms: list[Transform], probs: list[float]): f"Number of transforms must match number of probabilities. " f"Got {len(transforms)} transforms and {len(probs)} probabilities." ) - assert np.isclose(np.sum(probs), 1) or np.isclose(np.sum(probs), 0), ( - f"Probabilities must sum to 1 or 0. Got {np.sum(probs)}" - ) + assert np.isclose(np.sum(probs), 1) or np.isclose( + np.sum(probs), 0 + ), f"Probabilities must sum to 1 or 0. Got {np.sum(probs)}" assert all(isinstance(t, Transform) for t in transforms), ( f"All elements in transforms must be Transform instances. " f"Got {type(next(t for t in transforms if not isinstance(t, Transform)))}" diff --git a/src/atomworks/ml/transforms/center_random_augmentation.py b/src/atomworks/ml/transforms/center_random_augmentation.py index 968cacb8..d4e8bfaf 100644 --- a/src/atomworks/ml/transforms/center_random_augmentation.py +++ b/src/atomworks/ml/transforms/center_random_augmentation.py @@ -25,9 +25,9 @@ def check_input(self, data: dict) -> None: check_contains_keys(data, ["coord_atom_lvl_to_be_noised"]) check_contains_keys(data["ground_truth"], ["coord_atom_lvl", "mask_atom_lvl"]) - assert data["coord_atom_lvl_to_be_noised"].shape[0] == self.batch_size, ( - "Must batch coordinates to be noised before applying this transform" - ) + assert ( + data["coord_atom_lvl_to_be_noised"].shape[0] == self.batch_size + ), "Must batch coordinates to be noised before applying this transform" def forward(self, data: dict) -> dict: centered_coord_atom_lvl_to_be_noised = data["coord_atom_lvl_to_be_noised"] # (batch_size, n_atoms, 3) diff --git a/src/atomworks/ml/transforms/crop.py b/src/atomworks/ml/transforms/crop.py index 88037fcc..2db9ef77 100644 --- a/src/atomworks/ml/transforms/crop.py +++ b/src/atomworks/ml/transforms/crop.py @@ -119,12 +119,12 @@ def crop_contiguous_af2_multimer(iids: list[int | str], instance_lens: list[int] instance_lens = np.asarray(instance_lens) assert crop_size > 0, "Crop size must be greater than 0" - assert len(iids) == len(instance_lens), ( - f"Number of instance IDs ({len(iids)}) must match number of instance lengths ({len(instance_lens)})" - ) - assert len(iids) == np.unique(iids).size, ( - f"Instance IDs must be unique, but got {len(iids)} IDs with only {np.unique(iids).size} unique values" - ) + assert len(iids) == len( + instance_lens + ), f"Number of instance IDs ({len(iids)}) must match number of instance lengths ({len(instance_lens)})" + assert ( + len(iids) == np.unique(iids).size + ), f"Instance IDs must be unique, but got {len(iids)} IDs with only {np.unique(iids).size} unique values" # randomly permute the order of the instances to avoid cropping bias permutation = np.random.permutation(len(iids)) @@ -236,9 +236,9 @@ def get_spatial_crop_center( # If there's only one query unit, we don't need to check for spatial proximity, # so we can just return the mask for the query unit. can_be_crop_center = is_query_pn_unit & is_occupied - assert np.any(can_be_crop_center), ( - f"No crop center found! It appears `query_pn_unit_iid` {query_pn_unit_iids} is not in the atom array or unresolved." - ) + assert np.any( + can_be_crop_center + ), f"No crop center found! It appears `query_pn_unit_iid` {query_pn_unit_iids} is not in the atom array or unresolved." return can_be_crop_center @@ -299,9 +299,9 @@ def get_spatial_crop_mask( """ assert coord.ndim == 2, f"Expected coord to be 2-dimensional, got {coord.ndim} dimensions" assert coord.shape[1] == 3, f"Expected coord to have 3 coordinates per point, got {coord.shape[1]}" - assert crop_center_idx < coord.shape[0], ( - f"Crop center index {crop_center_idx} is out of bounds for coord array of length {coord.shape[0]}" - ) + assert ( + crop_center_idx < coord.shape[0] + ), f"Crop center index {crop_center_idx} is out of bounds for coord array of length {coord.shape[0]}" assert crop_size > 0, f"Crop size must be positive, got {crop_size}" assert jitter_scale >= 0, f"Jitter scale must be non-negative, got {jitter_scale}" diff --git a/src/atomworks/ml/transforms/diffusion/batch_structures.py b/src/atomworks/ml/transforms/diffusion/batch_structures.py index f82ac06d..2ab12b88 100644 --- a/src/atomworks/ml/transforms/diffusion/batch_structures.py +++ b/src/atomworks/ml/transforms/diffusion/batch_structures.py @@ -34,9 +34,9 @@ def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data["ground_truth"], ["coord_atom_lvl", "mask_atom_lvl"]) if "coord_atom_lvl_to_be_noised" in data: - assert len(data["coord_atom_lvl_to_be_noised"]) == len(data["atom_array"]), ( - "structure must not be batched yet" - ) + assert len(data["coord_atom_lvl_to_be_noised"]) == len( + data["atom_array"] + ), "structure must not be batched yet" def forward(self, data: dict[str, Any]) -> dict[str, Any]: if "coord_atom_lvl_to_be_noised" in data: diff --git a/src/atomworks/ml/transforms/diffusion/edm.py b/src/atomworks/ml/transforms/diffusion/edm.py index 21923128..0c6d1dc2 100644 --- a/src/atomworks/ml/transforms/diffusion/edm.py +++ b/src/atomworks/ml/transforms/diffusion/edm.py @@ -49,9 +49,9 @@ def __init__(self, sigma_data: float, diffusion_batch_size: int, **kwargs): def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data, ["coord_atom_lvl_to_be_noised"]) - assert data["coord_atom_lvl_to_be_noised"].shape[0] == self.diffusion_batch_size, ( - "Must batch coordinates to be noised before applying this transform" - ) + assert ( + data["coord_atom_lvl_to_be_noised"].shape[0] == self.diffusion_batch_size + ), "Must batch coordinates to be noised before applying this transform" def forward(self, data: dict) -> dict: """ diff --git a/src/atomworks/ml/transforms/dna/pad_dna.py b/src/atomworks/ml/transforms/dna/pad_dna.py index 276431f6..ce7f643d 100644 --- a/src/atomworks/ml/transforms/dna/pad_dna.py +++ b/src/atomworks/ml/transforms/dna/pad_dna.py @@ -683,9 +683,9 @@ def forward(self, data: dict[str, Any]) -> dict[str, Any]: seq2_rhs = "".join(chain2["canonical_seq"][-chain2_overhang[1] :]) try: - assert seq1_paired == to_reverse_complement(seq2_paired), ( - "sequences to be joined must be reverse-complements of each other" - ) + assert seq1_paired == to_reverse_complement( + seq2_paired + ), "sequences to be joined must be reverse-complements of each other" assert seq1_lhs == "" or seq2_rhs == "", "overhang1_lhs and overhang1_rhs are mutually exclusive" assert seq1_rhs == "" or seq2_lhs == "", "overhang2_lhs and overhang2_rhs are mutually exclusive" except AssertionError: diff --git a/src/atomworks/ml/transforms/filters.py b/src/atomworks/ml/transforms/filters.py index 675e4494..b0451652 100644 --- a/src/atomworks/ml/transforms/filters.py +++ b/src/atomworks/ml/transforms/filters.py @@ -121,9 +121,9 @@ def remove_unsupported_chain_types( query_pn_unit_chain_types = np.unique( atom_array.chain_type[np.isin(atom_array.pn_unit_iid, query_pn_unit_iids)] ) - assert np.all(np.isin(query_pn_unit_chain_types, supported_chain_types)), ( - f"Query PN unit has an unsupported chain type: {query_pn_unit_chain_types}" - ) + assert np.all( + np.isin(query_pn_unit_chain_types, supported_chain_types) + ), f"Query PN unit has an unsupported chain type: {query_pn_unit_chain_types}" # Then, we filter out chains with unsupported chain types is_supported_chain_type = np.isin(atom_array.chain_type, supported_chain_types) diff --git a/src/atomworks/ml/transforms/mask_generator.py b/src/atomworks/ml/transforms/mask_generator.py index ecafd8d4..89f91163 100644 --- a/src/atomworks/ml/transforms/mask_generator.py +++ b/src/atomworks/ml/transforms/mask_generator.py @@ -463,9 +463,9 @@ def __call__( region_starts = regions[:-1] region_stops = regions[1:] seed_region_idx = np.searchsorted(region_starts, seed_idx, side="right") - 1 - assert region_starts[seed_region_idx] <= seed_idx < region_stops[seed_region_idx], ( - f"{seed_idx=} is not within the allowed region ({region_starts[seed_region_idx]}-{region_stops[seed_region_idx]})" - ) + assert ( + region_starts[seed_region_idx] <= seed_idx < region_stops[seed_region_idx] + ), f"{seed_idx=} is not within the allowed region ({region_starts[seed_region_idx]}-{region_stops[seed_region_idx]})" region_start = region_starts[seed_region_idx] region_stop = region_stops[seed_region_idx] @@ -481,9 +481,9 @@ def __call__( # ... check that the region contains segments and that the seed is within the region assert len(segment_starts) > 0, "No candidate segments found" seed_segment_idx = np.searchsorted(segment_starts, seed_idx, side="right") - 1 - assert segment_starts[seed_segment_idx] <= seed_idx < segment_stops[seed_segment_idx], ( - f"{seed_idx=} is not within the allowed region ({segment_starts[seed_segment_idx]}-{segment_stops[seed_segment_idx]})" - ) + assert ( + segment_starts[seed_segment_idx] <= seed_idx < segment_stops[seed_segment_idx] + ), f"{seed_idx=} is not within the allowed region ({segment_starts[seed_segment_idx]}-{segment_stops[seed_segment_idx]})" # Sample island size and start position (to include the seed) n_candidate_segments = len(segment_starts) @@ -650,9 +650,9 @@ class CheckAtomBudget(CheckBudget): def __init__(self, n_min_atoms: int, n_max_atoms: int): self.n_min_atoms = n_min_atoms self.n_max_atoms = n_max_atoms - assert self.n_min_atoms <= self.n_max_atoms, ( - f"Can never satisfy budget with {self.n_min_atoms=}<= {self.n_max_atoms=}" - ) + assert ( + self.n_min_atoms <= self.n_max_atoms + ), f"Can never satisfy budget with {self.n_min_atoms=}<= {self.n_max_atoms=}" def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: n_atoms = len(total_mask) @@ -677,9 +677,9 @@ def __init__( ): self.n_min_residues = n_min_residues self.n_max_residues = n_max_residues - assert self.n_min_residues <= self.n_max_residues, ( - f"Can never satisfy budget with {self.n_min_residues=}<= {self.n_max_residues=}" - ) + assert ( + self.n_min_residues <= self.n_max_residues + ), f"Can never satisfy budget with {self.n_min_residues=}<= {self.n_max_residues=}" self.reduce = reduce def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: @@ -704,9 +704,9 @@ class CheckTokenBudget(CheckBudget): def __init__(self, n_min_tokens: int, n_max_tokens: int): self.n_min_tokens = n_min_tokens self.n_max_tokens = n_max_tokens - assert self.n_min_tokens <= self.n_max_tokens, ( - f"Can never satisfy budget with {self.n_min_tokens=}<= {self.n_max_tokens=}" - ) + assert ( + self.n_min_tokens <= self.n_max_tokens + ), f"Can never satisfy budget with {self.n_min_tokens=}<= {self.n_max_tokens=}" def __call__(self, atom_array: AtomArray, total_mask: np.ndarray, all_masks: list[np.ndarray]) -> bool: token_starts = get_token_starts(atom_array) @@ -809,9 +809,9 @@ def sample_mask_via_seed_grow_merge( # ... grow nothing, just set `this_mask[seed_idx] = True` this_mask = np.zeros(n_atoms, dtype=bool) this_mask[seed_idx] = True - assert this_mask.shape == (n_atoms,), ( - f"this_mask must be a boolean array of shape ({n_atoms=},). Got {this_mask.shape}" - ) + assert this_mask.shape == ( + n_atoms, + ), f"this_mask must be a boolean array of shape ({n_atoms=},). Got {this_mask.shape}" assert this_mask.dtype == bool, f"this_mask must be a boolean array. Got {this_mask.dtype}" # Merge masks if function provided diff --git a/src/atomworks/ml/transforms/masks.py b/src/atomworks/ml/transforms/masks.py index a6026694..0586bb03 100644 --- a/src/atomworks/ml/transforms/masks.py +++ b/src/atomworks/ml/transforms/masks.py @@ -95,9 +95,9 @@ def check_input(self, data: dict[str, Any]) -> None: check_is_instance(data, "atom_array", AtomArray) check_atom_array_annotation(data, ["chain_iid"]) - assert len(data["atom_array"].coord) < self.max_atoms_in_crop, ( - "Number of atoms in the atom array exceeds the maximum number of atoms in the crop" - ) + assert ( + len(data["atom_array"].coord) < self.max_atoms_in_crop + ), "Number of atoms in the atom array exceeds the maximum number of atoms in the crop" def forward(self, data: dict[str, Any]) -> dict[str, Any]: """ diff --git a/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py b/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py index 6e243c79..0f04df21 100644 --- a/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py +++ b/src/atomworks/ml/transforms/msa/_msa_pairing_utils.py @@ -308,9 +308,9 @@ def join_two_msas_by_tax_id( assert np.all(residue_is_paired[all_paired, :]), "Residues in all_paired rows should all be paired" # ...and assert that the first row is still the query sequence as a sanity check - assert np.all(msa[0] == np.concatenate([msa_a["msa"][0], msa_b["msa"][0]])), ( - "Query sequence must be the first row of the MSA" - ) + assert np.all( + msa[0] == np.concatenate([msa_a["msa"][0], msa_b["msa"][0]]) + ), "Query sequence must be the first row of the MSA" result = { "msa": msa, diff --git a/src/atomworks/ml/transforms/msa/msa.py b/src/atomworks/ml/transforms/msa/msa.py index b69c604b..5f64e065 100644 --- a/src/atomworks/ml/transforms/msa/msa.py +++ b/src/atomworks/ml/transforms/msa/msa.py @@ -547,9 +547,9 @@ def forward(self, data: dict) -> dict: existing_pad_tokens = data["polymer_msas_by_chain_id"][first_chain_id]["msa_is_padded_mask"] * first_encoded_msa if np.any(existing_pad_tokens): token = existing_pad_tokens.flat[np.flatnonzero(existing_pad_tokens)[0]] - assert token == self.PAD_TOKEN, ( - f"Given padding token {self.PAD_TOKEN} does not match existing padding token {token}" - ) + assert ( + token == self.PAD_TOKEN + ), f"Given padding token {self.PAD_TOKEN} does not match existing padding token {token}" # Set up empty encoded msa (purely padded) for encoded msa token_count = get_token_count(atom_array) diff --git a/src/atomworks/ml/transforms/openbabel_utils.py b/src/atomworks/ml/transforms/openbabel_utils.py index 7de9c70d..9fa54758 100644 --- a/src/atomworks/ml/transforms/openbabel_utils.py +++ b/src/atomworks/ml/transforms/openbabel_utils.py @@ -440,9 +440,9 @@ def find_automorphisms(obmol: openbabel.OBMol, max_automorphs: int = 1000, max_m [7 2]]] """ n_atoms = obmol.NumAtoms() - assert n_atoms == obmol.NumHvyAtoms(), ( - f"Found {n_atoms - obmol.NumHvyAtoms()} explicit hydrogens. This function assumes that the input molecule has no explicit hydrogens. Please remove." - ) + assert ( + n_atoms == obmol.NumHvyAtoms() + ), f"Found {n_atoms - obmol.NumHvyAtoms()} explicit hydrogens. This function assumes that the input molecule has no explicit hydrogens. Please remove." # ... initialize a vector container to store automorphs automorphs = openbabel.vvpairUIntUInt() # vector>> diff --git a/src/atomworks/ml/transforms/rdkit_utils.py b/src/atomworks/ml/transforms/rdkit_utils.py index da5d67bb..fe9c55b8 100644 --- a/src/atomworks/ml/transforms/rdkit_utils.py +++ b/src/atomworks/ml/transforms/rdkit_utils.py @@ -119,9 +119,9 @@ def generate_conformers( Improve Conformation Generation", JCIM, 2015. """ # Ensure that all properties are being pickled (needed when we use timeout) - assert Chem.GetDefaultPickleProperties() == Chem.PropertyPickleOptions.AllProps, ( - "Default pickle properties are not set to all properties. Annotation loss will occur." - ) + assert ( + Chem.GetDefaultPickleProperties() == Chem.PropertyPickleOptions.AllProps + ), "Default pickle properties are not set to all properties. Annotation loss will occur." assert attempts_with_distance_geometry > 0, "Attempts with distance geometry must be greater than 0." assert attempts_with_random_coordinates > 0, "Attempts with random coordinates must be greater than 0." diff --git a/src/atomworks/ml/transforms/rf2aa_assumptions.py b/src/atomworks/ml/transforms/rf2aa_assumptions.py index 352c77b8..017aa30c 100644 --- a/src/atomworks/ml/transforms/rf2aa_assumptions.py +++ b/src/atomworks/ml/transforms/rf2aa_assumptions.py @@ -157,22 +157,22 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # Assert that the correspondence between chains is the same in ch_label and same_chain is valid ch_label_diffs = np.where(ch_label.diff())[0] same_chain_diffs = np.unique(np.where(same_chain.diff())[1]) - assert np.all(np.isin(ch_label_diffs, same_chain_diffs)), ( - f"{item}: ch_label_diffs: {ch_label_diffs}, same_chain_diffs: {same_chain_diffs}" - ) + assert np.all( + np.isin(ch_label_diffs, same_chain_diffs) + ), f"{item}: ch_label_diffs: {ch_label_diffs}, same_chain_diffs: {same_chain_diffs}" # Assert that there are polymer tokens in the example: num_res_tokens = ((~_is_atom(seq[0])).sum()).item() - assert num_res_tokens > 0, ( - f"{item}: num_res_tokens: {num_res_tokens}. No polymer tokens at all. This would lead RF2AA to crash." - ) + assert ( + num_res_tokens > 0 + ), f"{item}: num_res_tokens: {num_res_tokens}. No polymer tokens at all. This would lead RF2AA to crash." assert num_res_tokens + num_atoms == L, f"{item}: num_res_tokens: {num_res_tokens}, num_atoms: {num_atoms}, L: {L}" if num_atoms > 0: # Assert that `same_chain` is block diagonal in the non-poly sector: - assert _is_block_diagonal_with_full_blocks(same_chain[num_res_tokens:, num_res_tokens:]), ( - f"{item}: non-poly sector of `same_chain` is not block diagonal" - ) + assert _is_block_diagonal_with_full_blocks( + same_chain[num_res_tokens:, num_res_tokens:] + ), f"{item}: non-poly sector of `same_chain` is not block diagonal" # Assert that in the non-poly sector, for label in np.unique(ch_label[num_res_tokens:]): @@ -182,24 +182,24 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # NOTE: This will currently fail (on purpose) for cropped covalent modifications, # where this assumption cannot be guaranteed with an AF3 like cropping strategy. same_chain_block = same_chain[num_res_tokens:, num_res_tokens:][np.ix_(idxs, idxs)] - assert _are_all_blocks_the_same_size(same_chain_block), ( - f"{item}: `same_chain` block {label} is not the same size" - ) + assert _are_all_blocks_the_same_size( + same_chain_block + ), f"{item}: `same_chain` block {label} is not the same size" # ... ensure there is no entirely unresolved `ch_label` segment in # the non-poly sector: - assert (mask_crds[0, idxs + num_res_tokens, :]).any(), ( - f"{item}: Entity with `chain_label` {label} is entirely unresolved in the non-poly sector." - ) + assert ( + mask_crds[0, idxs + num_res_tokens, :] + ).any(), f"{item}: Entity with `chain_label` {label} is entirely unresolved in the non-poly sector." # ... ensure there is at least one resolved coordinate for each chain in each entity _block_size = same_chain_block[0].sum() assert len(idxs) % _block_size == 0 for chain_idx in range(len(idxs) // _block_size): idxs_in_subblock = idxs[chain_idx * _block_size : (chain_idx + 1) * _block_size] - assert (mask_crds[0, idxs_in_subblock + num_res_tokens, :]).any(), ( - f"{item}: Chain {chain_idx} in block with `chain_label` {label} has no resolved coordinates in the non-poly sector." - ) + assert ( + mask_crds[0, idxs_in_subblock + num_res_tokens, :] + ).any(), f"{item}: Chain {chain_idx} in block with `chain_label` {label} has no resolved coordinates in the non-poly sector." # Assert that there are no masks in `msa`: assert not (msa == 21).any(), f"{item}: There are masks in the ground truth `msa`." @@ -207,21 +207,21 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: # Assert that there are no entirely unresolved chains in the poly sector: for label in np.unique(ch_label[:num_res_tokens]): idxs = np.where(ch_label[:num_res_tokens] == label)[0] - assert (mask_crds[0, idxs, :]).any(), ( - f"{item}: Entity with `chain_label` {label} is entirely unresolved in the poly sector." - ) + assert ( + mask_crds[0, idxs, :] + ).any(), f"{item}: Entity with `chain_label` {label} is entirely unresolved in the poly sector." # Ensure there is at least one resolved coordinate for each symmetry copy: # mask_crds: (N_symm, L, NTOTAL) - assert mask_crds.any(dim=(1, 2)).all(), ( - f"{item}: There are no resolved coordinates for at least one symmetry copy (neither poly nor non-poly)." - ) + assert mask_crds.any( + dim=(1, 2) + ).all(), f"{item}: There are no resolved coordinates for at least one symmetry copy (neither poly nor non-poly)." # Ensure there is at least one resolved coordinate for each symmetry copy in the poly sector (excluding padding): n_symm_poly = mask_crds[:, :num_res_tokens].any(dim=(1, 2)).max().item() - assert n_symm_poly > 0, ( - f"{item}: There are no resolved coordinates for the poly sector of at least one symmetry copy (excluding padding)." - ) + assert ( + n_symm_poly > 0 + ), f"{item}: There are no resolved coordinates for the poly sector of at least one symmetry copy (excluding padding)." # If the given symmetry copy has a poly swap, check that the N-CA-C of at least one residue is resolved, which # is needed to construct the poly frames. @@ -229,9 +229,9 @@ def assert_satisfies_rf2aa_assumptions(sample: dict[str, Any]) -> None: dim=1 ) problems = np.where(~symm_copies_has_at_least_one_resolved_N_CA_C)[0] - assert len(problems) == 0, ( - f"{item}: The following symmetry copies have no resolved N-CA-C coordinates for the poly sector: {problems}" - ) + assert ( + len(problems) == 0 + ), f"{item}: The following symmetry copies have no resolved N-CA-C coordinates for the poly sector: {problems}" class AssertRF2AAAssumptions(Transform): diff --git a/src/atomworks/ml/transforms/symmetry.py b/src/atomworks/ml/transforms/symmetry.py index 982164a7..d9dd1477 100644 --- a/src/atomworks/ml/transforms/symmetry.py +++ b/src/atomworks/ml/transforms/symmetry.py @@ -220,9 +220,9 @@ def get_isomorphisms_from_symmetry_groups( # Determine tile size and number of tiles needed to fill the array tile_size = n_perm * n_reps # ... each tile has the permutation repeated n_reps times n_tile = math.ceil(n_isomorphisms / tile_size) # ... number of tiles needed to fill the array - assert (n_isomorphisms <= get_perm_count(permutations)) or (n_tile * tile_size == n_isomorphisms), ( - f"{n_tile} * {tile_size} != {n_isomorphisms} (={n_tile * tile_size})" - ) + assert (n_isomorphisms <= get_perm_count(permutations)) or ( + n_tile * tile_size == n_isomorphisms + ), f"{n_tile} * {tile_size} != {n_isomorphisms} (={n_tile * tile_size})" # Fill the isomorphisms array with `n_tile` copies of `perm`, each of which is repeated `n_reps` times isomorphisms[:, start_idx : start_idx + n_instances] = np.tile(np.repeat(perm, n_reps, axis=0), (n_tile, 1))[ diff --git a/src/atomworks/ml/transforms/template.py b/src/atomworks/ml/transforms/template.py index 576b19ad..b1fb3ff7 100644 --- a/src/atomworks/ml/transforms/template.py +++ b/src/atomworks/ml/transforms/template.py @@ -153,9 +153,9 @@ def subset(self, template_idxs: list[int]) -> "RF2AATemplate": return self def to_atom_array(self, template_idx: int) -> AtomArray: - assert isinstance(template_idx, int) and 0 <= template_idx <= self.n_templates - 1, ( - f"template_idx must be an int between 0 and {self.n_templates - 1}, got {template_idx}" - ) + assert ( + isinstance(template_idx, int) and 0 <= template_idx <= self.n_templates - 1 + ), f"template_idx must be an int between 0 and {self.n_templates - 1}, got {template_idx}" # Get pdb_id and chain_id template_id = self.ids[template_idx] @@ -354,18 +354,18 @@ def __init__( AssertionError: If `n_template` is not a positive integer. AssertionError: If `min_template_length` is not a non-negative integer. """ - assert 0.0 <= min_seq_similarity <= 100.0, ( - f"min_seq_similarity must be between 0.0 and 100.0, got {min_seq_similarity}" - ) - assert 0.0 <= max_seq_similarity <= 100.0, ( - f"max_seq_similarity must be between 0.0 and 100.0, got {max_seq_similarity}" - ) - assert isinstance(max_n_template, int) and max_n_template > 0, ( - f"max_n_template must be a positive integer, got {max_n_template}" - ) - assert isinstance(min_template_length, int) and min_template_length >= 0, ( - f"min_template_length must be a non-negative integer, got {min_template_length}" - ) + assert ( + 0.0 <= min_seq_similarity <= 100.0 + ), f"min_seq_similarity must be between 0.0 and 100.0, got {min_seq_similarity}" + assert ( + 0.0 <= max_seq_similarity <= 100.0 + ), f"max_seq_similarity must be between 0.0 and 100.0, got {max_seq_similarity}" + assert ( + isinstance(max_n_template, int) and max_n_template > 0 + ), f"max_n_template must be a positive integer, got {max_n_template}" + assert ( + isinstance(min_template_length, int) and min_template_length >= 0 + ), f"min_template_length must be a non-negative integer, got {min_template_length}" self.n_template = max_n_template self.pick_top = pick_top @@ -511,18 +511,18 @@ def __init__( AssertionError: If `init_coords` is a tensor and its dimensions do not match the expected shape. AssertionError: If `allowed_chain_types` is not a list or contains any elements that are not instances of `ChainType`. """ - assert isinstance(n_template, int) and n_template > 0, ( - f"n_template must be a positive integer, got {n_template}" - ) - assert isinstance(encoding, TokenEncoding), ( - f"encoding must be an instance of TokenEncoding, got {type(encoding)}" - ) - assert isinstance(allowed_chain_types, list) and len(allowed_chain_types) > 0, ( - f"allowed_chain_types must be a non-empty list, got {allowed_chain_types}" - ) - assert np.isin(allowed_chain_types, ChainType).all(), ( - f"Allowed chain types must be a list of ChainType enums. Got {allowed_chain_types=}." - ) + assert ( + isinstance(n_template, int) and n_template > 0 + ), f"n_template must be a positive integer, got {n_template}" + assert isinstance( + encoding, TokenEncoding + ), f"encoding must be an instance of TokenEncoding, got {type(encoding)}" + assert ( + isinstance(allowed_chain_types, list) and len(allowed_chain_types) > 0 + ), f"allowed_chain_types must be a non-empty list, got {allowed_chain_types}" + assert np.isin( + allowed_chain_types, ChainType + ).all(), f"Allowed chain types must be a list of ChainType enums. Got {allowed_chain_types=}." self.n_template = n_template self.mask_token_idx = mask_token_idx self.init_coords = init_coords @@ -535,9 +535,9 @@ def __init__( if init_coords.ndim >= 2: n_token = init_coords.shape[-2] - assert n_token == encoding.n_atoms_per_token, ( - f"init_coords must have {encoding.n_atoms_per_token} tokens, got {n_token}" - ) + assert ( + n_token == encoding.n_atoms_per_token + ), f"init_coords must have {encoding.n_atoms_per_token} tokens, got {n_token}" def check_input(self, data: dict[str, Any]) -> None: check_contains_keys(data, ["template", "atom_array"]) diff --git a/src/atomworks/ml/utils/misc.py b/src/atomworks/ml/utils/misc.py index e9e279cd..28d38284 100644 --- a/src/atomworks/ml/utils/misc.py +++ b/src/atomworks/ml/utils/misc.py @@ -376,9 +376,9 @@ def grouped_count( # Check input validity assert len(groups) == data.dim(), "Number of groups must match the number of dimensions in the data tensor." - assert all(len(group) == shape for group, shape in zip(groups, data.shape, strict=True)), ( - "The i-th assignments `groups` must have the same length as the i-th dimension of the data tensor." - ) + assert all( + len(group) == shape for group, shape in zip(groups, data.shape, strict=True) + ), "The i-th assignments `groups` must have the same length as the i-th dimension of the data tensor." # Infer the group sizes (= number of unique groups in each dimension) group_sizes = [max(group) + 1 for group in groups] diff --git a/src/atomworks/ml/utils/numpy.py b/src/atomworks/ml/utils/numpy.py index 28d0391b..80d3b381 100644 --- a/src/atomworks/ml/utils/numpy.py +++ b/src/atomworks/ml/utils/numpy.py @@ -38,12 +38,12 @@ def select_data_by_id( [8., 8., 8., 8., 8., 8.], [1., 1., 1., 1., 1., 1.]]) """ - assert data.shape[axis] == len(data_ids), ( - f"`data` must have `len(data_ids)` along axis `{axis}`, but got shape: {data.shape}" - ) - assert np.unique(data_ids).size == len(data_ids), ( - f"`data_ids` must be unique. Got duplicates ({np.unique(data_ids)}) in {data_ids}" - ) + assert data.shape[axis] == len( + data_ids + ), f"`data` must have `len(data_ids)` along axis `{axis}`, but got shape: {data.shape}" + assert np.unique(data_ids).size == len( + data_ids + ), f"`data_ids` must be unique. Got duplicates ({np.unique(data_ids)}) in {data_ids}" id_to_idx = np.vectorize({id_: idx for idx, id_ in enumerate(data_ids)}.__getitem__, otypes=[data_ids.dtype]) idxs_to_select = id_to_idx(select_ids) diff --git a/src/atomworks/ml/utils/rng.py b/src/atomworks/ml/utils/rng.py index 7d603b45..7bd00701 100644 --- a/src/atomworks/ml/utils/rng.py +++ b/src/atomworks/ml/utils/rng.py @@ -137,9 +137,9 @@ def create_rng_state_from_seeds( with rng_state(None): # Set seeds in context manager to reset RNG states after creating the rng_state_dict if np_seed is not None: - assert isinstance(np_seed, int) and _MIN_SEED_VALUE <= np_seed <= _MAX_SEED_VALUE, ( - f"np_seed must be an int between {_MIN_SEED_VALUE} and {_MAX_SEED_VALUE}, got {np_seed}" - ) + assert ( + isinstance(np_seed, int) and _MIN_SEED_VALUE <= np_seed <= _MAX_SEED_VALUE + ), f"np_seed must be an int between {_MIN_SEED_VALUE} and {_MAX_SEED_VALUE}, got {np_seed}" np.random.seed(np_seed) if torch_seed is not None: torch.manual_seed(torch_seed) diff --git a/src/atomworks/ml/utils/token.py b/src/atomworks/ml/utils/token.py index c263eb0d..ba9e328c 100644 --- a/src/atomworks/ml/utils/token.py +++ b/src/atomworks/ml/utils/token.py @@ -214,9 +214,9 @@ def apply_segment_wise_2d(array: np.ndarray, segment_start_end_idxs: np.ndarray, assert array.ndim == 2, "Array must be 2D" assert segment_start_end_idxs.ndim == 1, "Group start end idxs must be 1D" assert segment_start_end_idxs[0] == 0, "Group start end idxs must start with 0" - assert segment_start_end_idxs[-1] == array.shape[0], ( - "Group start end idxs must end with the number of rows in the array" - ) + assert ( + segment_start_end_idxs[-1] == array.shape[0] + ), "Group start end idxs must end with the number of rows in the array" assert np.all(np.diff(segment_start_end_idxs) > 0), "Group start end idxs must be strictly increasing" # reduce along rows @@ -248,9 +248,9 @@ def get_af3_token_representative_masks(atom_array: AtomArray, enforce_one_per_to Returns: np.ndarray: A boolean mask indicating the representative atoms of the tokens in the atom array. """ - assert "atomize" in atom_array.get_annotation_categories(), ( - "Atomize annotation is missing. Run AtomizeByCCDName Transform for magical atomization of ligands" - ) + assert ( + "atomize" in atom_array.get_annotation_categories() + ), "Atomize annotation is missing. Run AtomizeByCCDName Transform for magical atomization of ligands" pyrimidine_representative_atom = is_pyrimidine(atom_array.res_name) & (atom_array.atom_name == "C2") purine_representative_atom = is_purine(atom_array.res_name) & (atom_array.atom_name == "C4") unknown_na_representative_atom = is_unknown_nucleotide(atom_array.res_name) & (atom_array.atom_name == "C4") @@ -336,9 +336,9 @@ def get_af3_token_center_masks(atom_array: AtomArray, enforce_one_per_token: boo `AF3 Supplementary Information `_ """ - assert "atomize" in atom_array.get_annotation_categories(), ( - "Atomize annotation is missing. Run AtomizeByCCDName Transform first!" - ) + assert ( + "atomize" in atom_array.get_annotation_categories() + ), "Atomize annotation is missing. Run AtomizeByCCDName Transform first!" is_center_atom = ( atom_array.atomize # the atom itself for un-atomized tokens diff --git a/tests/io/components/test_chain_types.py b/tests/io/components/test_chain_types.py index acd9c61e..67192ebb 100644 --- a/tests/io/components/test_chain_types.py +++ b/tests/io/components/test_chain_types.py @@ -61,13 +61,13 @@ def test_chain_types(test_case: dict[str, Any]): # Check ChainType got_chain_type = ChainType.as_enum(pn_unit_atom_array.chain_type[0]) expected_chain_type = test_case["chain_types"][pn_unit_id] - assert got_chain_type == expected_chain_type, ( - f"Mismatch for {pn_unit_id=}: {got_chain_type=}, {expected_chain_type=}" - ) + assert ( + got_chain_type == expected_chain_type + ), f"Mismatch for {pn_unit_id=}: {got_chain_type=}, {expected_chain_type=}" # Check is_polymer got_is_polymer = pn_unit_atom_array.is_polymer[0] expected_is_polymer = expected_chain_type.is_polymer() - assert got_is_polymer == expected_is_polymer, ( - f"Mismatch for {pn_unit_id=}: {got_is_polymer=}, {expected_is_polymer=}" - ) + assert ( + got_is_polymer == expected_is_polymer + ), f"Mismatch for {pn_unit_id=}: {got_is_polymer=}, {expected_is_polymer=}" diff --git a/tests/io/components/test_entity_annotations.py b/tests/io/components/test_entity_annotations.py index aa545f03..00b19462 100644 --- a/tests/io/components/test_entity_annotations.py +++ b/tests/io/components/test_entity_annotations.py @@ -178,18 +178,18 @@ def test_regenerate_and_add_chain_entity_annotation(test_case): # ... that no other chains have the same chain_entity other_chain_atom_array = atom_array[not_isin(atom_array.chain_id, equivalent_chains)] - assert not np.any(other_chain_atom_array.chain_entity == chain_entity), ( - f"Chains {equivalent_chains} share chain_entity with other chains" - ) + assert not np.any( + other_chain_atom_array.chain_entity == chain_entity + ), f"Chains {equivalent_chains} share chain_entity with other chains" # ... and that all chains with the same chain_entity have the same sequence sequences = [ chain_entity_atom_array[chain_entity_atom_array.chain_id == chain_id].res_name for chain_id in equivalent_chains ] - assert all(np.array_equal(sequences[0], arr) for arr in sequences[1:]), ( - "Sequences are not equal within an entity." - ) + assert all( + np.array_equal(sequences[0], arr) for arr in sequences[1:] + ), "Sequences are not equal within an entity." if __name__ == "__main__": diff --git a/tests/io/components/test_identifiers.py b/tests/io/components/test_identifiers.py index d1f5aa84..e8527806 100644 --- a/tests/io/components/test_identifiers.py +++ b/tests/io/components/test_identifiers.py @@ -98,9 +98,9 @@ def test_identifiers(test_case): generated_pn_unit_iids = sorted(np.unique(atom_array.pn_unit_iid.astype(str))) reference_pn_unit_iids = sorted(test_case["pn_unit_iids"]) - assert generated_pn_unit_iids == reference_pn_unit_iids, ( - f"Generated PN unit instance IDs do not match reference PN unit IIDs for PDB ID {test_case['pdb_id']} and assembly_id {test_case['assembly_id']}." - ) + assert ( + generated_pn_unit_iids == reference_pn_unit_iids + ), f"Generated PN unit instance IDs do not match reference PN unit IIDs for PDB ID {test_case['pdb_id']} and assembly_id {test_case['assembly_id']}." MOLECULE_TEST_CASES = [ diff --git a/tests/io/components/test_ignore_residues.py b/tests/io/components/test_ignore_residues.py index 8fed6390..6436d1cd 100644 --- a/tests/io/components/test_ignore_residues.py +++ b/tests/io/components/test_ignore_residues.py @@ -14,12 +14,12 @@ def test_remove_crystallization_aids(pdbid: str): # Not excluding crystallization aids out1 = parse(filename=get_pdb_path(pdbid), remove_ccds=[]) - assert np.any(np.isin(out1["asym_unit"].res_name, CRYSTALLIZATION_AIDS)), ( - "No crystallization aids found when not excluding." - ) + assert np.any( + np.isin(out1["asym_unit"].res_name, CRYSTALLIZATION_AIDS) + ), "No crystallization aids found when not excluding." # Excluding crystallization aids out2 = parse(filename=get_pdb_path(pdbid), remove_ccds=CRYSTALLIZATION_AIDS) - assert not np.any(np.isin(out2["asym_unit"].res_name, CRYSTALLIZATION_AIDS)), ( - "Crystallization aids found when excluding." - ) + assert not np.any( + np.isin(out2["asym_unit"].res_name, CRYSTALLIZATION_AIDS) + ), "Crystallization aids found when excluding." diff --git a/tests/io/components/test_logging.py b/tests/io/components/test_logging.py index 5049fb0d..fcc28013 100644 --- a/tests/io/components/test_logging.py +++ b/tests/io/components/test_logging.py @@ -20,9 +20,9 @@ def test_atomworks_logging_level(): atomworks_logger = logging.getLogger("atomworks") # Assert that the current logging level matches the expected level - assert atomworks_logger.level == expected_level, ( - f"Expected atomworks.logging level to be {logging.getLevelName(expected_level)}, but it was {logging.getLevelName(atomworks_logger.level)}" - ) + assert ( + atomworks_logger.level == expected_level + ), f"Expected atomworks.logging level to be {logging.getLevelName(expected_level)}, but it was {logging.getLevelName(atomworks_logger.level)}" def test_atomworks_logging_level_env_var(): @@ -43,9 +43,9 @@ def test_atomworks_logging_level_env_var(): atomworks_logger = logging.getLogger("atomworks") # Assert that the current logging level matches the set environment variable - assert atomworks_logger.level == logging.DEBUG, ( - f"Expected atomworks.logging level to be DEBUG, but it was {logging.getLevelName(atomworks_logger.level)}" - ) + assert ( + atomworks_logger.level == logging.DEBUG + ), f"Expected atomworks.logging level to be DEBUG, but it was {logging.getLevelName(atomworks_logger.level)}" finally: # Clean up: restore the original environment variable diff --git a/tests/io/tools/test_inference_processing.py b/tests/io/tools/test_inference_processing.py index fd8c43f3..f80de814 100644 --- a/tests/io/tools/test_inference_processing.py +++ b/tests/io/tools/test_inference_processing.py @@ -367,9 +367,9 @@ def test_full_components_input(dict_inputs, custom_residues): for index, chain_id in enumerate(extracted_chain_ids): if chain_id: chain_id_from_component = components[index].chain_id - assert chain_id == chain_id_from_component, ( - f"Mismatch at index {index}: {chain_id} != {chain_id_from_component}" - ) + assert ( + chain_id == chain_id_from_component + ), f"Mismatch at index {index}: {chain_id} != {chain_id_from_component}" # Sanity check outputs assert isinstance(atom_array, AtomArray) diff --git a/tests/io/tools/test_rdkit.py b/tests/io/tools/test_rdkit.py index c98705d2..e33736ff 100644 --- a/tests/io/tools/test_rdkit.py +++ b/tests/io/tools/test_rdkit.py @@ -176,12 +176,12 @@ def test_chirality_detection_from_ccd(): assert Chem.FindMolChiralCenters(ccd_code_to_rdkit(aa)) == [(1, "S")] # Check a handful of non-standard amino acids - assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DAL")) == [(1, "R")], ( - "D-alanine should have a R configuration at the CA atom" - ) - assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DCY")) == [(1, "S")], ( - "D-cystine should have a S configuration at the CA atom" - ) + assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DAL")) == [ + (1, "R") + ], "D-alanine should have a R configuration at the CA atom" + assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DCY")) == [ + (1, "S") + ], "D-cystine should have a S configuration at the CA atom" assert Chem.FindMolChiralCenters(ccd_code_to_rdkit("DTH")) == [ (1, "R"), (2, "S"), diff --git a/tests/io/utils/test_scatter.py b/tests/io/utils/test_scatter.py index 472a3e9d..4db0161b 100644 --- a/tests/io/utils/test_scatter.py +++ b/tests/io/utils/test_scatter.py @@ -62,9 +62,9 @@ def test_apply_group_wise_2d_sum(): data = np.array([[1, 1], [2, 2], [3, 3], [4, 4]]) result = apply_group_wise(groups, data, lambda arr: np.sum(arr, axis=0)) expected = np.array([[4, 4], [6, 6]]) - assert np.array_equal(np.stack(result), expected), ( - f"Failed 2D sum test. Expected {expected}, got {np.stack(result)}" - ) + assert np.array_equal( + np.stack(result), expected + ), f"Failed 2D sum test. Expected {expected}, got {np.stack(result)}" def test_spread_group_wise_basic(): @@ -99,9 +99,9 @@ def test_get_segments_docstring(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 2, 3, 4, 5]) assert np.array_equal(result, expected), f"Failed docstring test. Expected {expected}, got {result}" - assert np.array_equal(result_from_groups, expected), ( - f"Failed docstring test. Expected {expected}, got {result_from_groups}" - ) + assert np.array_equal( + result_from_groups, expected + ), f"Failed docstring test. Expected {expected}, got {result_from_groups}" def test_get_segments_single_array(): @@ -111,9 +111,9 @@ def test_get_segments_single_array(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 2, 4, 5]) assert np.array_equal(result, expected), f"Failed single array test. Expected {expected}, got {result}" - assert np.array_equal(result_from_groups, expected), ( - f"Failed single array test. Expected {expected}, got {result_from_groups}" - ) + assert np.array_equal( + result_from_groups, expected + ), f"Failed single array test. Expected {expected}, got {result_from_groups}" def test_get_segments_no_changes(): @@ -123,9 +123,9 @@ def test_get_segments_no_changes(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 5]) assert np.array_equal(result, expected), f"Failed no-change test. Expected {expected}, got {result}" - assert np.array_equal(result_from_groups, expected), ( - f"Failed no-change test. Expected {expected}, got {result_from_groups}" - ) + assert np.array_equal( + result_from_groups, expected + ), f"Failed no-change test. Expected {expected}, got {result_from_groups}" def test_get_segments_all_changes(): @@ -135,9 +135,9 @@ def test_get_segments_all_changes(): result_from_groups = get_segments(result_groups, add_exclusive_stop=True) expected = np.array([0, 1, 2, 3, 4, 5]) assert np.array_equal(result, expected), f"Failed all-changes test. Expected {expected}, got {result}" - assert np.array_equal(result_from_groups, expected), ( - f"Failed all-changes test. Expected {expected}, got {result_from_groups}" - ) + assert np.array_equal( + result_from_groups, expected + ), f"Failed all-changes test. Expected {expected}, got {result_from_groups}" def test_apply_and_spread_segment_wise_sum_and_mean(): @@ -150,18 +150,18 @@ def test_apply_and_spread_segment_wise_sum_and_mean(): result_sum_groups = apply_and_spread_group_wise(groups, data, np.sum) expected_sum = np.array([30, 30, 120, 120, 120, 60]) assert np.array_equal(result_sum, expected_sum), f"Failed sum test. Expected {expected_sum}, got {result_sum}" - assert np.array_equal(result_sum_groups, expected_sum), ( - f"Failed sum test. Expected {expected_sum}, got {result_sum_groups}" - ) + assert np.array_equal( + result_sum_groups, expected_sum + ), f"Failed sum test. Expected {expected_sum}, got {result_sum_groups}" # Test with np.mean result_mean = apply_and_spread_segment_wise(segments, data, np.mean) result_mean_groups = apply_and_spread_group_wise(groups, data, np.mean) expected_mean = np.array([15.0, 15.0, 40.0, 40.0, 40.0, 60.0]) assert np.allclose(result_mean, expected_mean), f"Failed mean test. Expected {expected_mean}, got {result_mean}" - assert np.allclose(result_mean_groups, expected_mean), ( - f"Failed mean test. Expected {expected_mean}, got {result_mean_groups}" - ) + assert np.allclose( + result_mean_groups, expected_mean + ), f"Failed mean test. Expected {expected_mean}, got {result_mean_groups}" if __name__ == "__main__": diff --git a/tests/io/utils/test_testing_tools.py b/tests/io/utils/test_testing_tools.py index 71bf7342..81f9118b 100644 --- a/tests/io/utils/test_testing_tools.py +++ b/tests/io/utils/test_testing_tools.py @@ -83,9 +83,9 @@ def test_is_same_in_segment(): segment_start_stop = np.array([0, 3, 6, 8]) # 3 segments data = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3]) # Each segment has same value result = is_same_in_segment(segment_start_stop, data) - assert np.array_equal(result, np.array([True, True, True])), ( - f"Failed simple segments test. Expected {np.array([True, True, True])}, got {result}" - ) + assert np.array_equal( + result, np.array([True, True, True]) + ), f"Failed simple segments test. Expected {np.array([True, True, True])}, got {result}" result_group = is_same_in_group(groups, data) assert np.array_equal(result_group, np.array([True, True, True])) diff --git a/tests/ml/conditions/test_annotator.py b/tests/ml/conditions/test_annotator.py index 44f89f1b..c89bae7e 100644 --- a/tests/ml/conditions/test_annotator.py +++ b/tests/ml/conditions/test_annotator.py @@ -45,9 +45,9 @@ def test_ensure_annotations_basic(atom_array): # Check that annotation has correct shape annotation_data = atom_array.get_annotation(annot) - assert len(annotation_data) == atom_array.array_length(), ( - f"Annotation '{annot}' should have same length as atom array" - ) + assert ( + len(annotation_data) == atom_array.array_length() + ), f"Annotation '{annot}' should have same length as atom array" assert isinstance(annotation_data, np.ndarray), f"Annotation '{annot}' should be a numpy array" diff --git a/tests/ml/conditions/test_condition_save_load.py b/tests/ml/conditions/test_condition_save_load.py index 9450f681..a54aaed4 100644 --- a/tests/ml/conditions/test_condition_save_load.py +++ b/tests/ml/conditions/test_condition_save_load.py @@ -59,9 +59,9 @@ def test_save_and_load_atom_array_with_defaults(atom_array: AtomArray): existing = set( get_annotation_categories(loaded_atom_array, n_body=1) + get_annotation_categories(loaded_atom_array, n_body=2) ) - assert possible.issubset(existing), ( - f"Some possible annotations are not found in loaded_atom_array: {possible - existing}" - ) + assert possible.issubset( + existing + ), f"Some possible annotations are not found in loaded_atom_array: {possible - existing}" for condition_cls in CONDITIONS: default_mask = condition_cls.default_mask(atom_array) @@ -179,16 +179,14 @@ def test_save_and_load_atom_array_with_conditions(atom_array: AtomArray): target_annotation = target_annotation.as_dense_array() loaded_annotation = loaded_annotation.as_dense_array() - assert np.array_equal(target_mask, loaded_mask, equal_nan=True), ( - f"Mismatch for {condition_cls.full_name}: {np.where(target_mask)} != {np.where(loaded_mask)}" - ) + assert np.array_equal( + target_mask, loaded_mask, equal_nan=True + ), f"Mismatch for {condition_cls.full_name}: {np.where(target_mask)} != {np.where(loaded_mask)}" assert np.array_equal( target_annotation[target_mask], loaded_annotation[loaded_mask], equal_nan=np.issubdtype(condition_cls.dtype, np.floating), - ), ( - f"Mismatch for {condition_cls.full_name}: {target_annotation[target_mask]} != {loaded_annotation[loaded_mask]}" - ) + ), f"Mismatch for {condition_cls.full_name}: {target_annotation[target_mask]} != {loaded_annotation[loaded_mask]}" if __name__ == "__main__": diff --git a/tests/ml/datasets/test_datasets_with_filters.py b/tests/ml/datasets/test_datasets_with_filters.py index af6dddc1..92e445a7 100644 --- a/tests/ml/datasets/test_datasets_with_filters.py +++ b/tests/ml/datasets/test_datasets_with_filters.py @@ -30,9 +30,9 @@ def test_resolution_filter(rf2aa_pn_units_dataset): def test_method_filter(rf2aa_pn_units_dataset): # Check that the method filter was applied correctly filtered_data = rf2aa_pn_units_dataset.data - assert filtered_data["method"].isin(["X-RAY_DIFFRACTION", "ELECTRON_MICROSCOPY"]).all(), ( - "Method filter did not work correctly" - ) + assert ( + filtered_data["method"].isin(["X-RAY_DIFFRACTION", "ELECTRON_MICROSCOPY"]).all() + ), "Method filter did not work correctly" def test_af3_excluded_ligands_filter(rf2aa_pn_units_dataset, rf2aa_interfaces_dataset): @@ -41,20 +41,20 @@ def test_af3_excluded_ligands_filter(rf2aa_pn_units_dataset, rf2aa_interfaces_da filtered_interfaces_data = rf2aa_interfaces_dataset.data # ... check query PN Units - assert np.any(filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['G_1']}"), ( - "Entry removed that contained valid PN Units" - ) - assert not np.any(filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['DB_1']}"), ( - "Entry remained that contains AF-3 excluded ligands as query PN Units" - ) + assert np.any( + filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['G_1']}" + ), "Entry removed that contained valid PN Units" + assert not np.any( + filtered_pn_units_data.example_id == "{['pdb', 'pn_units']}{2pno}{3}{['DB_1']}" + ), "Entry remained that contains AF-3 excluded ligands as query PN Units" # ... check interfaces - assert not np.any(filtered_interfaces_data.pdb_id == "{['pdb', 'interfaces']}{2pno}{3}{['DB_1', 'G_1']}"), ( - "Entry remained that contains AF-3 excluded ligands as query PN Units" - ) - assert np.any(filtered_interfaces_data.example_id == "{['pdb', 'interfaces']}{2pno}{3}{['G_1', 'H_1']}"), ( - "Entry removed that contained valid PN Units" - ) + assert not np.any( + filtered_interfaces_data.pdb_id == "{['pdb', 'interfaces']}{2pno}{3}{['DB_1', 'G_1']}" + ), "Entry remained that contains AF-3 excluded ligands as query PN Units" + assert np.any( + filtered_interfaces_data.example_id == "{['pdb', 'interfaces']}{2pno}{3}{['G_1', 'H_1']}" + ), "Entry removed that contained valid PN Units" def test_filter_no_impact(caplog, pn_units_df): diff --git a/tests/ml/pipelines/test_data_loading_pipelines.py b/tests/ml/pipelines/test_data_loading_pipelines.py index 3fe04be3..3e396712 100644 --- a/tests/ml/pipelines/test_data_loading_pipelines.py +++ b/tests/ml/pipelines/test_data_loading_pipelines.py @@ -84,16 +84,16 @@ def test_data_loading_pipelines_with_random_examples(datasets_to_test, dataset_t ] # Check if we can reverse-engineer the row from the example_id assert row is not None, f"Failed to get row from example_id for example_id: {example_id}" assert sample is not None, f"Sample is None, with example_id: {example_id}" - assert row["example_id"] == example_id, ( - f"Row example_id does not match example_id for example_id: {example_id}" - ) + assert ( + row["example_id"] == example_id + ), f"Row example_id does not match example_id for example_id: {example_id}" # For validation datasets, also check that the "ground_truth" key contains information on which chains/interfaces to score, and the map from token index to `chain_iid` if dataset_type == "validation": assert "ground_truth" in sample, f"Missing 'ground_truth' key in sample with example_id: {example_id}" - assert "chain_iid_token_lvl" in sample["ground_truth"], ( - f"Missing 'chain_iid_token_lvl' key in sample with example_id: {example_id}" - ) + assert ( + "chain_iid_token_lvl" in sample["ground_truth"] + ), f"Missing 'chain_iid_token_lvl' key in sample with example_id: {example_id}" if __name__ == "__main__": diff --git a/tests/ml/pipelines/test_inference_pipelines.py b/tests/ml/pipelines/test_inference_pipelines.py index df0c1130..a47746e6 100644 --- a/tests/ml/pipelines/test_inference_pipelines.py +++ b/tests/ml/pipelines/test_inference_pipelines.py @@ -52,9 +52,9 @@ def test_af3_confidence_pipeline_from_chai_fasta(): assert "confidence_feats" in transformed_data, "Missing feats in pipeline output." # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( - f"Found NaN in feats: {feat_name=}, {feat=}" - ) + assert ( + feat.isfinite().all() if isinstance(feat, torch.Tensor) else True + ), f"Found NaN in feats: {feat_name=}, {feat=}" @skip_if_on_github_runner @@ -91,9 +91,9 @@ def test_af3_pipeline_from_chai_fasta(): assert "feats" in transformed_data, "Missing feats in pipeline output." # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( - f"Found NaN in feats: {feat_name=}, {feat=}" - ) + assert ( + feat.isfinite().all() if isinstance(feat, torch.Tensor) else True + ), f"Found NaN in feats: {feat_name=}, {feat=}" AF3_PIPELINE_FROM_COMPONENTS_TEST_CASES = [ @@ -156,9 +156,9 @@ def test_af3_pipeline_from_sequence_and_smiles(inference_components): # Check that none of the feats is `nan` for feat_name, feat in transformed_data["feats"].items(): - assert feat.isfinite().all() if isinstance(feat, torch.Tensor) else True, ( - f"Found NaN in feats: {feat_name=}, {feat=}" - ) + assert ( + feat.isfinite().all() if isinstance(feat, torch.Tensor) else True + ), f"Found NaN in feats: {feat_name=}, {feat=}" # Check that we successfully generated a reference conformer for the ligand assert not torch.any(torch.all(transformed_data["feats"]["ref_pos"] == 0, dim=1)) diff --git a/tests/ml/pipelines/test_pipeline_regression.py b/tests/ml/pipelines/test_pipeline_regression.py index 67cd0e01..7dcb3f69 100644 --- a/tests/ml/pipelines/test_pipeline_regression.py +++ b/tests/ml/pipelines/test_pipeline_regression.py @@ -145,17 +145,17 @@ def _assert_features_equal(feats: dict, expected_feats: dict, example_name: str, # rdkit versions seem to be compiled differently on different operating systems, making # this an operating system dependent test. Instead of the values, we just check the # shapes - assert feats[key].shape == expected_feats[key].shape, ( - f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feats[key].shape} vs {expected_feats[key].shape}" - ) + assert ( + feats[key].shape == expected_feats[key].shape + ), f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feats[key].shape} vs {expected_feats[key].shape}" continue feat = feats[key] expected_feat = expected_feats[key] # Check shapes - assert feat.shape == expected_feat.shape, ( - f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feat.shape} vs {expected_feat.shape}" - ) + assert ( + feat.shape == expected_feat.shape + ), f"Feature {key} shape mismatch for {example_name} in {mode} mode: {feat.shape} vs {expected_feat.shape}" # Check values with tolerance _assert_tensor_or_array_equal( diff --git a/tests/ml/preprocessing/test_filtering_criteria.py b/tests/ml/preprocessing/test_filtering_criteria.py index eb27c8fb..0e7de234 100644 --- a/tests/ml/preprocessing/test_filtering_criteria.py +++ b/tests/ml/preprocessing/test_filtering_criteria.py @@ -46,9 +46,9 @@ def test_filtering_criteria(test_case: dict[str, Any]): assert set(pn_unit_iids) >= set(df["q_pn_unit_iid"].unique().tolist()) # ...assert that all of the rows have the same PN units - assert (df["all_pn_unit_iids_after_processing"] == df["all_pn_unit_iids_after_processing"].iloc[0]).all(), ( - "Not all rows have the same pn_units" - ) + assert ( + df["all_pn_unit_iids_after_processing"] == df["all_pn_unit_iids_after_processing"].iloc[0] + ).all(), "Not all rows have the same pn_units" pn_units_to_keep = set(test_case["pn_units_to_keep"]) pn_units_to_remove = set(test_case["pn_units_to_remove"]) diff --git a/tests/ml/preprocessing/test_get_atom_mask.py b/tests/ml/preprocessing/test_get_atom_mask.py index 5587ffc0..eda173e3 100644 --- a/tests/ml/preprocessing/test_get_atom_mask.py +++ b/tests/ml/preprocessing/test_get_atom_mask.py @@ -59,9 +59,9 @@ def test_get_atom_mask_from_cell_list(mock_data): chunk_size = 1000 # Small chunk_size result = get_atom_mask_from_cell_list(large_query_coords, cell_list, cell_list_size, clash_distance, chunk_size) expected = cell_list.get_atoms(large_query_coords, clash_distance, as_mask=True) - assert np.array_equal(result, expected), ( - "Result with large coord array and small chunk_size does not match expected output." - ) + assert np.array_equal( + result, expected + ), "Result with large coord array and small chunk_size does not match expected output." # Non-divisible chunk_size chunk_size = 1507 # Non-divisible chunk_size diff --git a/tests/ml/preprocessing/test_loi_extraction.py b/tests/ml/preprocessing/test_loi_extraction.py index 70edb6ed..9d6bcbdf 100644 --- a/tests/ml/preprocessing/test_loi_extraction.py +++ b/tests/ml/preprocessing/test_loi_extraction.py @@ -69,9 +69,9 @@ def test_loi_extraction(test_case: dict[str, Any]): structure[(np.isin(structure.chain_id, chain_ids)) & (structure.occupancy > 0)].res_name ) if test_case.get("has_covalently_bonded_loi", False): - assert any(res in loi_set for res in res_names), ( - f"No LOI molecule found for {row.q_pn_unit_iid} in {res_names}. LOIs: {loi_set}" - ) + assert any( + res in loi_set for res in res_names + ), f"No LOI molecule found for {row.q_pn_unit_iid} in {res_names}. LOIs: {loi_set}" for res in res_names: if res in loi_set: loi_seen[res] += 1 diff --git a/tests/ml/transforms/msa/test_featurize_msa.py b/tests/ml/transforms/msa/test_featurize_msa.py index f6eafb9f..40563e78 100644 --- a/tests/ml/transforms/msa/test_featurize_msa.py +++ b/tests/ml/transforms/msa/test_featurize_msa.py @@ -206,15 +206,15 @@ def test_fill_full_msa_from_encoded(pdb_id): for index, token_atom_array in enumerate(token_iter(atom_array)): if token_atom_array.atomize[0]: # If this residue is atomized, ensure that the entire MSA column (other than the query sequence) is padding... - assert np.all(output["encoded"]["msa"][1:, index] == pad_token), ( - f"MSA column for atomized residue {index} is not padding" - ) + assert np.all( + output["encoded"]["msa"][1:, index] == pad_token + ), f"MSA column for atomized residue {index} is not padding" # ...and the padding is represented in the full MSA details assert not output["full_msa_details"]["token_idx_has_msa"][index], "Token index has MSA when it should not" - assert np.all(output["full_msa_details"]["msa_is_padded_mask"][1:, index]), ( - "MSA is not padded when it should be" - ) + assert np.all( + output["full_msa_details"]["msa_is_padded_mask"][1:, index] + ), "MSA is not padded when it should be" atomized_indices.append(index) else: # If this residue is not atomized, ensure that the MSA matches with the pre-atomized MSA... @@ -223,14 +223,14 @@ def test_fill_full_msa_from_encoded(pdb_id): encoded_old_msa = output["polymer_msas_by_chain_id"][chain_id]["encoded_msa"] msa_column_old = encoded_old_msa[:, within_poly_res_idx] msa_column_new = output["encoded"]["msa"][:, index] - assert np.array_equal(msa_column_old, msa_column_new), ( - f"MSA column for non-atomized residue {index} does not match" - ) + assert np.array_equal( + msa_column_old, msa_column_new + ), f"MSA column for non-atomized residue {index} does not match" # ...and that we are noting that this token has MSA - assert output["full_msa_details"]["token_idx_has_msa"][index], ( - "Token index does not have MSA when it should" - ) + assert output["full_msa_details"]["token_idx_has_msa"][ + index + ], "Token index does not have MSA when it should" # Check that there are no insertions where there is MSA padding... msa_raw_ins = output["full_msa_details"]["msa_raw_ins"] @@ -238,9 +238,9 @@ def test_fill_full_msa_from_encoded(pdb_id): assert np.sum(msa_raw_ins * msa_is_padded_mask) == 0, "There should be no insertions where there is MSA padding" # ...AND that there are no insertions where there are atomized tokens - assert np.sum(msa_raw_ins[:, atomized_indices]) == 0, ( - "There should be no insertions where there are atomized tokens" - ) + assert ( + np.sum(msa_raw_ins[:, atomized_indices]) == 0 + ), "There should be no insertions where there are atomized tokens" ASSIGN_EXTRA_ROWS_TEST_CASES = [ @@ -415,12 +415,12 @@ def test_summarize_clusters(test_case): n_tokens=3, ) - assert torch.allclose(msa_cluster_profiles, expected_profiles, atol=1e-4), ( - f"Expected profiles {expected_profiles}, but got {msa_cluster_profiles}" - ) - assert torch.allclose(msa_cluster_ins, expected_insertions, atol=1e-4), ( - f"Expected insertions {expected_insertions}, but got {msa_cluster_ins}" - ) + assert torch.allclose( + msa_cluster_profiles, expected_profiles, atol=1e-4 + ), f"Expected profiles {expected_profiles}, but got {msa_cluster_profiles}" + assert torch.allclose( + msa_cluster_ins, expected_insertions, atol=1e-4 + ), f"Expected insertions {expected_insertions}, but got {msa_cluster_ins}" def test_mask_msa_like_bert(): @@ -624,9 +624,9 @@ def test_msa_featurize_like_rf2aa_full_pipeline(pdb_id): # For each key in the dictionary, check that the values match for key, old_values in old_results.items(): new_values = output["features_per_recycle_dict"][key] - assert torch.allclose(torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4), ( - f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" - ) + assert torch.allclose( + torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4 + ), f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" @pytest.mark.parametrize("pdb_id", MSA_FEATURIZE_PIPELINE_TEST_CASES) @@ -689,14 +689,14 @@ def test_msa_featurize_like_af3_full_pipeline(pdb_id): ) # Assert that has_insertion is a boolean tensor... - assert msa_features_per_recycle_dict["has_insertion"][0].dtype == torch.bool, ( - "has_insertion must be of boolean dtype" - ) + assert ( + msa_features_per_recycle_dict["has_insertion"][0].dtype == torch.bool + ), "has_insertion must be of boolean dtype" # ...and that there's at least one - assert torch.any(msa_features_per_recycle_dict["has_insertion"][0]), ( - "There must be at least one insertion, if we're using examples with MSA's" - ) + assert torch.any( + msa_features_per_recycle_dict["has_insertion"][0] + ), "There must be at least one insertion, if we're using examples with MSA's" ############## Regression test ############## @@ -714,15 +714,15 @@ def test_msa_featurize_like_af3_full_pipeline(pdb_id): # For each key in the features that change across recycles, check that the values match... for key, old_values in old_results["msa_features_per_recycle_dict"].items(): new_values = msa_features_per_recycle_dict[key] - assert torch.allclose(torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4), ( - f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" - ) + assert torch.allclose( + torch.stack(new_values), torch.stack(old_values), atol=1e-4, rtol=1e-4 + ), f"Failed at key: {key}. Difference: {set(new_values) - set(old_values)}" # ... and for the static features as well for key, old_value in old_results["msa_static_features_dict"].items(): new_value = msa_static_features_dict[key] - assert torch.allclose(new_value, old_value, atol=1e-4, rtol=1e-4), ( - f"Failed at key: {key}. Difference: {new_value - old_value}" - ) + assert torch.allclose( + new_value, old_value, atol=1e-4, rtol=1e-4 + ), f"Failed at key: {key}. Difference: {new_value - old_value}" # Define a simple TokenEncoding class for testing diff --git a/tests/ml/transforms/msa/test_load_msas.py b/tests/ml/transforms/msa/test_load_msas.py index 6687afd9..6e3c6121 100644 --- a/tests/ml/transforms/msa/test_load_msas.py +++ b/tests/ml/transforms/msa/test_load_msas.py @@ -63,25 +63,25 @@ def _validate_msa_results(test_case: dict[str, Any], result: dict[str, Any], cha spot_check_index = test_case["spot_check"]["index"] assert result["msa"].shape[0] >= test_case["min_sequences_in_msa"], "MSA has too few sequences" - assert np.all(result["msa"][0] == _encode_sequence(test_case["sequence"], chain_type)), ( - "Query sequence is incorrect" - ) + assert np.all( + result["msa"][0] == _encode_sequence(test_case["sequence"], chain_type) + ), "Query sequence is incorrect" # Spot check assertions assert np.all( result["msa"][spot_check_index] == _encode_sequence(test_case["spot_check"]["sequence"], chain_type) ), "Spot check sequence is incorrect" - assert np.sum(result["ins"][spot_check_index]) == test_case["spot_check"]["num_insertions"], ( - "Incorrect number of insertions" - ) + assert ( + np.sum(result["ins"][spot_check_index]) == test_case["spot_check"]["num_insertions"] + ), "Incorrect number of insertions" assert result["ins"][spot_check_index].shape[0] == len(result["msa"][spot_check_index]), "Incorrect insertion shape" assert result["tax_ids"][spot_check_index].item() == str(test_case["spot_check"]["tax_id"]), "Incorrect tax ID" # Sequence similarity sanity checks calculated_sequence_similarity = np.mean(result["msa"][spot_check_index] == result["msa"][0]) - assert calculated_sequence_similarity == result["sequence_similarity"][spot_check_index], ( - "Incorrect sequence similarity" - ) + assert ( + calculated_sequence_similarity == result["sequence_similarity"][spot_check_index] + ), "Incorrect sequence similarity" assert result["sequence_similarity"][0] == 1.0, "Query sequence should have 100% similarity with itself" @@ -195,9 +195,9 @@ def _check_coverage_for_pdb_id( def test_msas_with_mse(): """Check that we correctly find MSAs for proteins with selenomethisone residues.""" results = _check_coverage_for_pdb_id("7dsu", PROTEIN_MSA_DIRS, RNA_MSA_DIRS) - assert results["n_proteins_with_msas"] == results["n_proteins"], ( - "All proteins should have MSAs after MSE conversion" - ) + assert ( + results["n_proteins_with_msas"] == results["n_proteins"] + ), "All proteins should have MSAs after MSE conversion" @pytest.mark.parametrize("test_case", MSA_TEST_CASES) diff --git a/tests/ml/transforms/symmetry/test_automorphisms_networkx.py b/tests/ml/transforms/symmetry/test_automorphisms_networkx.py index c62fe983..1579ff1d 100644 --- a/tests/ml/transforms/symmetry/test_automorphisms_networkx.py +++ b/tests/ml/transforms/symmetry/test_automorphisms_networkx.py @@ -117,17 +117,17 @@ def test_find_automorphisms_within_entire_structure(pdb_id: str): assert len(automorphism) == 2, "Arginine should have 2 automorphisms." changing_column_indices = get_indices_of_non_constant_columns(automorphism) n_element = ELEMENT_NAME_TO_ATOMIC_NUMBER["N"] - assert np.all(residue.atomic_number[changing_column_indices] == n_element), ( - "All automorphisms of Arginine should involve nitrogens." - ) + assert np.all( + residue.atomic_number[changing_column_indices] == n_element + ), "All automorphisms of Arginine should involve nitrogens." # ...if it's a tyrosine, there should be 2 automorphisms, all involving carbons if residue_name == "TYR": assert len(automorphism) == 2, "Tyrosine should have 2 automorphisms (carbons must swap together)" changing_column_indices = get_indices_of_non_constant_columns(automorphism) n_element = ELEMENT_NAME_TO_ATOMIC_NUMBER["C"] - assert np.all(residue.atomic_number[changing_column_indices] == n_element), ( - "All automorphisms of Tyrosine should involve carbons." - ) + assert np.all( + residue.atomic_number[changing_column_indices] == n_element + ), "All automorphisms of Tyrosine should involve carbons." # ...isoleucine should have no automorphisms if residue_name == "ILE": assert len(automorphism) == 1, "Isoleucine should have no automorphisms." @@ -135,18 +135,18 @@ def test_find_automorphisms_within_entire_structure(pdb_id: str): # ...calculate automorphisms local_automorphisms = generate_automorphisms_from_atom_array_with_networkx(residue) - assert len(local_automorphisms) == len(automorphism), ( - "Unequal automorphism numbers; likely due to incorrect indexing." - ) + assert len(local_automorphisms) == len( + automorphism + ), "Unequal automorphism numbers; likely due to incorrect indexing." for local_automorphism in local_automorphisms: # ...map to the global frame, as given by the first row of the automorphism mapped_automorphism = automorphism[0][local_automorphism] # ...check that the automorphism is present - assert array_in_list(mapped_automorphism, automorphism), ( - "Automorphism not found in global automorphism list." - ) + assert array_in_list( + mapped_automorphism, automorphism + ), "Automorphism not found in global automorphism list." @pytest.mark.benchmark(group="find_automorphisms") diff --git a/tests/ml/transforms/test_af3_reference_molecule.py b/tests/ml/transforms/test_af3_reference_molecule.py index 408dae5d..96ba0002 100644 --- a/tests/ml/transforms/test_af3_reference_molecule.py +++ b/tests/ml/transforms/test_af3_reference_molecule.py @@ -187,9 +187,9 @@ def _assert_ref_pos_matches_ground_truth( mask: np.ndarray, ) -> None: """Assert that the reference positions are correctly aligned with the ground truth.""" - assert not np.any(np.isclose(ref_pos, ground_truth_coord)), ( - "Reference positions should differ from atom array coordinates under a transformation." - ) + assert not np.any( + np.isclose(ref_pos, ground_truth_coord) + ), "Reference positions should differ from atom array coordinates under a transformation." # Assert similar distances in masked positions dist1 = np.linalg.norm(ground_truth_coord[mask][:, None] - ground_truth_coord[mask], axis=2) @@ -243,17 +243,16 @@ def test_random_apply_ground_truth_conformer_by_chain_type(seed: int = 42): # Assert that all polymer atoms have the IGNORE policy polymer_mask = atom_array.is_polymer - assert np.all(atom_array.ground_truth_conformer_policy[polymer_mask] == GroundTruthConformerPolicy.IGNORE), ( - f"Expected all polymer atoms to have IGNORE policy, but got {atom_array.ground_truth_conformer_policy[polymer_mask]}" - ) + assert np.all( + atom_array.ground_truth_conformer_policy[polymer_mask] == GroundTruthConformerPolicy.IGNORE + ), f"Expected all polymer atoms to have IGNORE policy, but got {atom_array.ground_truth_conformer_policy[polymer_mask]}" # Assert that most non-polymer atoms have the REPLACE policy... non_polymer_mask = ~polymer_mask - assert np.sum( - atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE - ) > 0.5 * np.sum(non_polymer_mask), ( - f"Expected most non-polymer atoms to have REPLACE policy, but got {np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE)}" - ) + assert ( + np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE) + > 0.5 * np.sum(non_polymer_mask) + ), f"Expected most non-polymer atoms to have REPLACE policy, but got {np.sum(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.REPLACE)}" # ... but not all assert np.any(atom_array.ground_truth_conformer_policy[non_polymer_mask] == GroundTruthConformerPolicy.IGNORE) @@ -356,9 +355,9 @@ def _prepare(res_name: str, chain_id: str, res_id: int, transformation_id: str) pipe = GetAF3ReferenceMoleculeFeatures(apply_random_rotation_and_translation=True) out = pipe({"atom_array": atom_array}) - assert np.all(out["feats"]["ref_space_uid"] == expected_ref_space_uid), ( - f"{out['feats']['ref_space_uid']}, but expected {expected_ref_space_uid}" - ) + assert np.all( + out["feats"]["ref_space_uid"] == expected_ref_space_uid + ), f"{out['feats']['ref_space_uid']}, but expected {expected_ref_space_uid}" def test_max_conformers_per_residue_functionality(): @@ -425,9 +424,9 @@ def test_af3_reference_molecule_features_with_cached_conformers(cache_dir): _ = transform_no_cache(data_no_cache) no_cache_time = time.time() - start_time - assert cached_time < 0.8 * no_cache_time, ( - f"Cached version should be faster than no cache version, but got {cached_time} vs {no_cache_time}" - ) + assert ( + cached_time < 0.8 * no_cache_time + ), f"Cached version should be faster than no cache version, but got {cached_time} vs {no_cache_time}" feats = result_data_cached["feats"] assert not np.any(np.isnan(feats["ref_pos"])) @@ -496,9 +495,9 @@ def test_af3_reference_molecule_features_with_subsampled_conformers(data_with_su actual_ref_mask = feats["ref_mask"][res_start:res_end] assert np.array_equal(actual_ref_mask, expected_ref_mask), "Reference masks don't match" - assert np.allclose(expected_ref_pos[expected_ref_mask], actual_ref_pos[actual_ref_mask], atol=1e-6), ( - "Reference coordinates don't match" - ) + assert np.allclose( + expected_ref_pos[expected_ref_mask], actual_ref_pos[actual_ref_mask], atol=1e-6 + ), "Reference coordinates don't match" def test_chiral_centers_with_cached_conformers(cache_dir, data_with_subsampled_conformers): diff --git a/tests/ml/transforms/test_atom_array.py b/tests/ml/transforms/test_atom_array.py index b3593719..58b11424 100644 --- a/tests/ml/transforms/test_atom_array.py +++ b/tests/ml/transforms/test_atom_array.py @@ -58,12 +58,12 @@ def test_annotate_protein_termini(pdb_id: str): res_c_terminus = data["atom_array"][data["atom_array"].is_C_terminus] n_ntermini = struc.get_residue_count(res_n_terminus) n_ctermini = struc.get_residue_count(res_c_terminus) - assert n_protein_chains == n_ntermini, ( - f"Found {n_protein_chains} protein chains, but {n_ntermini} N-termini were annotated" - ) - assert n_protein_chains == n_ctermini, ( - f"Found {n_protein_chains} protein chains, but {n_ctermini} C-termini were annotated" - ) + assert ( + n_protein_chains == n_ntermini + ), f"Found {n_protein_chains} protein chains, but {n_ntermini} N-termini were annotated" + assert ( + n_protein_chains == n_ctermini + ), f"Found {n_protein_chains} protein chains, but {n_ctermini} C-termini were annotated" @pytest.mark.parametrize("pdb_id", MSA_PAIRING_PIPELINE_TEST_CASES) @@ -88,9 +88,9 @@ def test_add_within_poly_res_idx_annotation(pdb_id: str): # Check that all non-polymers have empty within_poly_res_idx non_polymer_chains = atom_array[~atom_array.is_polymer] - assert all(non_polymer_chains.within_poly_res_idx == -1), ( - "Non-polymer chains should have within_poly_res_idx set -1" - ) + assert all( + non_polymer_chains.within_poly_res_idx == -1 + ), "Non-polymer chains should have within_poly_res_idx set -1" # Check that we can use the within_poly_res_idx to index the MSA # Check that when we use `within_poly_res_idx` to index into the MSA, we get the same sequence as when we re-construct the one-letter sequence from the atom array diff --git a/tests/ml/transforms/test_atom_level_embeddings.py b/tests/ml/transforms/test_atom_level_embeddings.py index a8bc42ff..531013fe 100644 --- a/tests/ml/transforms/test_atom_level_embeddings.py +++ b/tests/ml/transforms/test_atom_level_embeddings.py @@ -51,9 +51,9 @@ def test_featurize_with_unknown_residue(cache_dir, subsampled_cached_residue_dat has_embedding = result["has_atom_level_embedding"] # All atoms in the modified residue should have False in the mask - assert not has_embedding[res_mask].any(), ( - f"Unknown residue {unknown_res_name} should have False mask for all its atoms" - ) + assert not has_embedding[ + res_mask + ].any(), f"Unknown residue {unknown_res_name} should have False mask for all its atoms" # Verify embeddings for unknown residue are all zeros embeddings = result["atom_level_embedding"] # Shape: (n_conformers, L, D) @@ -109,9 +109,9 @@ def test_featurize_with_ignore_residues(cache_dir, subsampled_cached_residue_dat ignored_mask = atom_array.res_name == ignore_res_name if ignored_mask.any(): - assert not has_embedding[ignored_mask].any(), ( - f"Ignored residue {ignore_res_name} should have False mask for all its atoms" - ) + assert not has_embedding[ + ignored_mask + ].any(), f"Ignored residue {ignore_res_name} should have False mask for all its atoms" if __name__ == "__main__": diff --git a/tests/ml/transforms/test_bonds.py b/tests/ml/transforms/test_bonds.py index b68de783..b4614214 100644 --- a/tests/ml/transforms/test_bonds.py +++ b/tests/ml/transforms/test_bonds.py @@ -170,9 +170,9 @@ def test_create_rf2aa_bond_features_matrix(test_case): output = _create_rf2aa_bond_features_matrix( test_case["token_bond_adjacency"], test_case["token_is_atom"], test_case["atom_biotite_bond_type_matrix"] ) - assert np.array_equal(output, test_case["expected_output"]), ( - f"Expected {test_case['expected_output']}, but got {output}" - ) + assert np.array_equal( + output, test_case["expected_output"] + ), f"Expected {test_case['expected_output']}, but got {output}" @pytest.mark.parametrize("pdb_id", ["6wjc"]) @@ -271,12 +271,12 @@ def test_generate_rf2aa_traversal_distance_matrix(test_case): result = transform(data) # Check if the result matches the expected output, which matches the networkx output - assert np.allclose(result["rf2aa_traversal_distance_matrix"], expected), ( - f"Expected {expected}, but got {result['rf2aa_traversal_distance_matrix']}" - ) - assert np.allclose(result["rf2aa_traversal_distance_matrix"], expected_from_nx), ( - f"Expected {expected_from_nx}, but got {result['rf2aa_traversal_distance_matrix']}" - ) + assert np.allclose( + result["rf2aa_traversal_distance_matrix"], expected + ), f"Expected {expected}, but got {result['rf2aa_traversal_distance_matrix']}" + assert np.allclose( + result["rf2aa_traversal_distance_matrix"], expected_from_nx + ), f"Expected {expected_from_nx}, but got {result['rf2aa_traversal_distance_matrix']}" AF3_TOKEN_BOND_FEATURES_TEST_CASES = [ diff --git a/tests/ml/transforms/test_confidence_transforms.py b/tests/ml/transforms/test_confidence_transforms.py index 1dc68c14..e4d0434f 100644 --- a/tests/ml/transforms/test_confidence_transforms.py +++ b/tests/ml/transforms/test_confidence_transforms.py @@ -104,12 +104,12 @@ def test_add_is_real_atom(test_case: dict[str, Any]): confidence_data = add_is_real_atom_pipeline(prepared_data) - assert confidence_data["is_real_atom"].sum() == len(confidence_data["atom_array"]), ( - "is_real_atom must account for all atoms in the atom array" - ) - assert confidence_data["is_real_atom"].shape == EXPECTED_OUTPUT_SHAPES[pdb_id]["is_real_atom"], ( - "is_real_atom shape should be [n_residues, 36]" - ) + assert confidence_data["is_real_atom"].sum() == len( + confidence_data["atom_array"] + ), "is_real_atom must account for all atoms in the atom array" + assert ( + confidence_data["is_real_atom"].shape == EXPECTED_OUTPUT_SHAPES[pdb_id]["is_real_atom"] + ), "is_real_atom shape should be [n_residues, 36]" @pytest.mark.parametrize("test_case", CONFIDENCE_MODIFICATION_TEST_CASES) diff --git a/tests/ml/transforms/test_crop.py b/tests/ml/transforms/test_crop.py index bfbc471a..dc9ea87f 100644 --- a/tests/ml/transforms/test_crop.py +++ b/tests/ml/transforms/test_crop.py @@ -163,9 +163,9 @@ def test_af3_like_spatial_crop_transform( # Ensure every query pn_unit is in the crop pn_unit_iids = np.unique(post_crop_atom_array.pn_unit_iid) - assert np.all(np.isin(data["query_pn_unit_iids"], pn_unit_iids)), ( - f"Query molecules {data['query_pn_unit_iids']} not in crop {pn_unit_iids}." - ) + assert np.all( + np.isin(data["query_pn_unit_iids"], pn_unit_iids) + ), f"Query molecules {data['query_pn_unit_iids']} not in crop {pn_unit_iids}." # Eval if no crop was performed if not data["crop_info"]["requires_crop"]: @@ -187,9 +187,9 @@ def test_af3_like_spatial_crop_transform( # Ensure correct, expected token count valid_pre_crop_tokens = get_token_count(pre_crop_atom_array[pre_crop_atom_array.occupancy > 0]) expected_token_count = min(crop_size, valid_pre_crop_tokens) - assert get_token_count(post_crop_atom_array) == expected_token_count, ( - f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." - ) + assert ( + get_token_count(post_crop_atom_array) == expected_token_count + ), f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." # Ensure there are no unoccupied atoms in the spatial crop assert np.all( @@ -198,19 +198,19 @@ def test_af3_like_spatial_crop_transform( # Check crop center atom crop_center_atom_id = data["crop_info"]["crop_center_atom_id"] - assert np.isin(crop_center_atom_id, pre_crop_atom_array.atom_id), ( - f"Crop center atom {crop_center_atom_id} not in pre-crop atom array." - ) - assert np.isin(crop_center_atom_id, post_crop_atom_array.atom_id), ( - f"Crop center atom {crop_center_atom_id} not in post-crop atom array." - ) + assert np.isin( + crop_center_atom_id, pre_crop_atom_array.atom_id + ), f"Crop center atom {crop_center_atom_id} not in pre-crop atom array." + assert np.isin( + crop_center_atom_id, post_crop_atom_array.atom_id + ), f"Crop center atom {crop_center_atom_id} not in post-crop atom array." # ... check that there is only one crop center crop_center = post_crop_atom_array[post_crop_atom_array.atom_id == crop_center_atom_id] assert len(crop_center) == 1, f"Expected exactly one crop center, got {len(crop_center)}." # ... check that crop center is occupied - assert crop_center.occupancy[0] > 0, ( - f"Crop center atom {crop_center_atom_id} is not occupied in the cropped atom array." - ) + assert ( + crop_center.occupancy[0] > 0 + ), f"Crop center atom {crop_center_atom_id} is not occupied in the cropped atom array." # ... check that crop center remains unchanged assert pre_crop_atom_array[pre_crop_atom_array.atom_id == crop_center_atom_id] == crop_center @@ -219,16 +219,16 @@ def test_af3_like_spatial_crop_transform( token_idx = atom_id_to_token_idx(post_crop_atom_array, crop_center_atom_id) post_crop_token = post_crop_atom_array[token_start_end_idxs[token_idx] : token_start_end_idxs[token_idx + 1]] # ... ensure atom id is inside token - assert np.isin(crop_center_atom_id, post_crop_token.atom_id), ( - f"Crop center atom {crop_center_atom_id} not in crop center token." - ) + assert np.isin( + crop_center_atom_id, post_crop_token.atom_id + ), f"Crop center atom {crop_center_atom_id} not in crop center token." # ... ensure token is unchanged token_start_end_idxs = get_token_starts(pre_crop_atom_array, add_exclusive_stop=True) token_idx = atom_id_to_token_idx(pre_crop_atom_array, crop_center_atom_id) pre_crop_token = pre_crop_atom_array[token_start_end_idxs[token_idx] : token_start_end_idxs[token_idx + 1]] - assert pre_crop_token == post_crop_token, ( - f"Crop center token {token_idx} changed: {pre_crop_token} -> {post_crop_token}" - ) + assert ( + pre_crop_token == post_crop_token + ), f"Crop center token {token_idx} changed: {pre_crop_token} -> {post_crop_token}" @pytest.mark.parametrize("example_id", BENCHMARK_EXAMPLE_IDS) @@ -262,9 +262,9 @@ def test_af3_like_contiguous_crop_transform( # Ensure correct, expected token count (in principle could be lower than 160 if there are fewer than 160 tokens in the full atom array) expected_token_count = min(crop_size, get_token_count(pre_crop_atom_array)) - assert get_token_count(post_crop_atom_array) == expected_token_count, ( - f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." - ) + assert ( + get_token_count(post_crop_atom_array) == expected_token_count + ), f"Cropped atom array has {get_token_count(post_crop_atom_array)} tokens but expected {expected_token_count}." if not data["crop_info"]["requires_crop"]: # ... no crop was performed @@ -283,9 +283,9 @@ def test_af3_like_contiguous_crop_transform( # Check that the molecule is contiguous (=fully connected by covalent bonds) submolecules = list(struc.molecule_iter(chain)) - assert len(submolecules) == 1, ( - f"Chain {chain_iid} is not contiguous but has {len(submolecules)} connected components." - ) + assert ( + len(submolecules) == 1 + ), f"Chain {chain_iid} is not contiguous but has {len(submolecules)} connected components." @pytest.mark.parametrize("example", BENCHMARK_EXAMPLES) @@ -360,9 +360,9 @@ def test_resize_crops_with_too_many_atoms(pdb_id, np_seed=1): data = prep_pipe(data) data = spatial_crop_pipe(data) post_crop_atom_array = data["atom_array"] - assert len(post_crop_atom_array) < 3000, ( - f"Expected spatial crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." - ) + assert ( + len(post_crop_atom_array) < 3000 + ), f"Expected spatial crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." # Test contiguous crop contiguous_crop_pipe = CropContiguousLikeAF3(crop_size=crop_size, max_atoms_in_crop=3000) @@ -371,9 +371,9 @@ def test_resize_crops_with_too_many_atoms(pdb_id, np_seed=1): data = prep_pipe(data) data = contiguous_crop_pipe(data) post_crop_atom_array = data["atom_array"] - assert len(post_crop_atom_array) < 3000, ( - f"Expected contiguous crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." - ) + assert ( + len(post_crop_atom_array) < 3000 + ), f"Expected contiguous crop to be resized to less than 3000 atoms, got {len(post_crop_atom_array)} atoms." def test_compute_local_hash(): @@ -408,9 +408,9 @@ def test_compute_local_hash(): hash_post = compute_local_hash(post_crop) post_crop.set_annotation("hash_post", hash_post) - assert np.all(post_crop.hash_pre == post_crop.hash_post), ( - "Hash mismatch between pre- and post-crop despite not cropping." - ) + assert np.all( + post_crop.hash_pre == post_crop.hash_post + ), "Hash mismatch between pre- and post-crop despite not cropping." # Test 2: Spatial cropping crop_pipe = CropSpatialLikeAF3(crop_size=32) diff --git a/tests/ml/transforms/test_encodings.py b/tests/ml/transforms/test_encodings.py index 70e60620..c29afae7 100644 --- a/tests/ml/transforms/test_encodings.py +++ b/tests/ml/transforms/test_encodings.py @@ -46,9 +46,9 @@ def test_encoding_af2_atom37_encoding(pdb_id: str): assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert n_res == n_token_array, ( - f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" - ) + assert ( + n_res == n_token_array + ), f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" @pytest.mark.parametrize("pdb_id", ["5ocm", "5ocn"]) @@ -84,9 +84,9 @@ def test_encoding_atom14_proteins_only(pdb_id: str, encoding: TokenEncoding): assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert n_res == n_token_array, ( - f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" - ) + assert ( + n_res == n_token_array + ), f"n_res={n_res} != n_token_array={n_token_array} -- this should be case when not atomizing" @pytest.mark.parametrize("pdb_id", ["5ocm"]) @@ -123,9 +123,9 @@ def test_all_atom_encoding( assert n_token_seq == n_token_struc, f"n_token_seq={n_token_seq} != n_token_struc={n_token_struc}" assert n_token_seq == n_token_mask, f"n_token_seq={n_token_seq} != n_token_mask={n_token_mask}" assert n_token_seq == n_token_array, f"n_token_seq={n_token_seq} != n_token_array={n_token_array}" - assert n_res < n_token_array, ( - f"n_res={n_res} > n_token_array={n_token_array} -- there should be more tokens than residues when atomizing" - ) + assert ( + n_res < n_token_array + ), f"n_res={n_res} > n_token_array={n_token_array} -- there should be more tokens than residues when atomizing" MOLECULE_TEST_CASES = [ @@ -173,30 +173,30 @@ def test_extra_annotations(test_case: dict): # Check `chain_id` annotations assert "chain_id" in data["encoded"], "chain_id not in encoded" - assert len(data["encoded"]["chain_id"]) == n_token, ( - f"chain_id length={len(data['encoded']['chain_id'])} != n_token={n_token}" - ) + assert ( + len(data["encoded"]["chain_id"]) == n_token + ), f"chain_id length={len(data['encoded']['chain_id'])} != n_token={n_token}" # Check `molecule_iid` annotations assert "molecule_iid" in data["encoded"], "molecule_iid not in encoded" - assert len(data["encoded"]["molecule_iid"]) == n_token, ( - f"molecule_iid length={len(data['encoded']['molecule_iid'])} != n_token={n_token}" - ) - assert len(data["encoded"]["molecule_iid_to_int"]) == test_case["num_molecules"], ( - f"molecule_iid_to_int length={len(data['encoded']['molecule_iid_to_int'])} != num_molecules={test_case['num_molecules']}" - ) - assert np.all(sorted(np.unique(data["encoded"]["molecule_iid"])) == np.arange(test_case["num_molecules"])), ( - f"molecule_iid unique values={np.unique(data['encoded']['molecule_iid'])} != num_molecules={test_case['num_molecules']}" - ) + assert ( + len(data["encoded"]["molecule_iid"]) == n_token + ), f"molecule_iid length={len(data['encoded']['molecule_iid'])} != n_token={n_token}" + assert ( + len(data["encoded"]["molecule_iid_to_int"]) == test_case["num_molecules"] + ), f"molecule_iid_to_int length={len(data['encoded']['molecule_iid_to_int'])} != num_molecules={test_case['num_molecules']}" + assert np.all( + sorted(np.unique(data["encoded"]["molecule_iid"])) == np.arange(test_case["num_molecules"]) + ), f"molecule_iid unique values={np.unique(data['encoded']['molecule_iid'])} != num_molecules={test_case['num_molecules']}" for molecule_iid, molecule_iidx in data["encoded"]["molecule_iid_to_int"].items(): raw_coords = atom_array[(atom_array.occupancy > 0) & (atom_array.molecule_iid == molecule_iid)].coord encoded_coords = data["encoded"]["xyz"][ (data["encoded"]["molecule_iid"] == molecule_iidx).reshape(-1, 1) & (data["encoded"]["mask"]) ] - assert raw_coords.shape == encoded_coords.shape, ( - f"raw_coords shape={raw_coords.shape} != encoded_coords shape={encoded_coords.shape}" - ) + assert ( + raw_coords.shape == encoded_coords.shape + ), f"raw_coords shape={raw_coords.shape} != encoded_coords shape={encoded_coords.shape}" # TODO: diff --git a/tests/ml/transforms/test_featurize_unresolved_residues.py b/tests/ml/transforms/test_featurize_unresolved_residues.py index fb5fcc6e..10191ff9 100644 --- a/tests/ml/transforms/test_featurize_unresolved_residues.py +++ b/tests/ml/transforms/test_featurize_unresolved_residues.py @@ -155,9 +155,9 @@ def test_place_unresolved_token_on_closest_resolved_token_in_sequence(pdb_id): )(output) output_atom_array = output["atom_array"] - assert not np.isnan(output_atom_array.coord_to_be_noised).any(), ( - "There should be no NaNs in the output coordinates!" - ) + assert not np.isnan( + output_atom_array.coord_to_be_noised + ).any(), "There should be no NaNs in the output coordinates!" for chain_id in np.unique(output_atom_array.chain_id): chain_atom_array = output_atom_array[output_atom_array.chain_id == chain_id] diff --git a/tests/ml/transforms/test_filters.py b/tests/ml/transforms/test_filters.py index 9e9f9e3c..68b4573b 100644 --- a/tests/ml/transforms/test_filters.py +++ b/tests/ml/transforms/test_filters.py @@ -203,9 +203,9 @@ def test_remove_unsupported_chain_types(pdb_id: str, pn_units_df: pd.DataFrame): num_unsupported_atoms = len(original_atom_array) - len(atom_array) assert num_unsupported_atoms > 0, "There should be some atoms removed" chain_types = np.unique(atom_array.chain_type) - assert np.all(np.isin(chain_types, TRAINING_SUPPORTED_CHAIN_TYPES)), ( - "All remaining chain types should be supported" - ) + assert np.all( + np.isin(chain_types, TRAINING_SUPPORTED_CHAIN_TYPES) + ), "All remaining chain types should be supported" def test_handle_undesired_res_single(): @@ -393,9 +393,9 @@ def test_randomly_remove_ligands(): delete_probability=0.0, ) categories_0_percent = _categorize_pn_units(result_0_percent) - assert categories_0_percent["all"] == original_categories["all"], ( - f"With 0% probability, all pn_units should remain. Expected {original_categories['counts']['all']}, got {categories_0_percent['counts']['all']}" - ) + assert ( + categories_0_percent["all"] == original_categories["all"] + ), f"With 0% probability, all pn_units should remain. Expected {original_categories['counts']['all']}, got {categories_0_percent['counts']['all']}" # Test with 100% probability - all free-floating ligands should be removed with rng_state(create_rng_state_from_seeds(np_seed=42)): @@ -407,9 +407,9 @@ def test_randomly_remove_ligands(): categories_100_percent = _categorize_pn_units(result_100_percent) expected_remaining_100_percent = original_categories["all"] - original_categories["free_floating_ligand"] - assert categories_100_percent["all"] == expected_remaining_100_percent, ( - f"With 100% probability, only free-floating ligands should be removed. Expected {len(expected_remaining_100_percent)}, got {categories_100_percent['counts']['all']}" - ) + assert ( + categories_100_percent["all"] == expected_remaining_100_percent + ), f"With 100% probability, only free-floating ligands should be removed. Expected {len(expected_remaining_100_percent)}, got {categories_100_percent['counts']['all']}" # Test with 50% probability multiple times to verify randomness works results_50_percent = [] @@ -424,14 +424,14 @@ def test_randomly_remove_ligands(): results_50_percent.append(categories_50_percent["all"]) # Verify that the remaining pn_units are a subset of the original - assert categories_50_percent["all"].issubset(original_categories["all"]), ( - f"Remaining pn_units should be a subset of original (seed {seed})" - ) + assert categories_50_percent["all"].issubset( + original_categories["all"] + ), f"Remaining pn_units should be a subset of original (seed {seed})" # Verify that polymer pn_units are always preserved (they don't match the query) - assert categories_50_percent["polymer"] == original_categories["polymer"], ( - f"Polymer pn_units should always be preserved (seed {seed})" - ) + assert ( + categories_50_percent["polymer"] == original_categories["polymer"] + ), f"Polymer pn_units should always be preserved (seed {seed})" # Verify that we get different results across different seeds (randomness check) unique_results = {frozenset(result) for result in results_50_percent} diff --git a/tests/ml/transforms/test_rdkit_transforms.py b/tests/ml/transforms/test_rdkit_transforms.py index 6175fad3..cb5313dd 100644 --- a/tests/ml/transforms/test_rdkit_transforms.py +++ b/tests/ml/transforms/test_rdkit_transforms.py @@ -86,9 +86,9 @@ def test_add_rdkit_molecules_for_atomized_molecules(test_case): expected_num_atoms = np.sum(pn_unit_mask) assert rdmol.GetNumAtoms() > 0, f"RDKit molecule {pn_unit_iid} has no atoms" assert rdmol.GetNumAtoms() == expected_num_atoms, f"RDKit molecule {pn_unit_iid} has the wrong number of atoms" - assert Chem.SanitizeMol(rdmol, catchErrors=True) == Chem.SanitizeFlags.SANITIZE_NONE, ( - f"RDKit molecule {pn_unit_iid} failed sanitization" - ) + assert ( + Chem.SanitizeMol(rdmol, catchErrors=True) == Chem.SanitizeFlags.SANITIZE_NONE + ), f"RDKit molecule {pn_unit_iid} failed sanitization" _mol_array = atom_array_from_rdkit( rdmol, set_coord_if_available=True, remove_hydrogens=True, remove_inferred_atoms=False diff --git a/tests/ml/transforms/test_rdkit_utils.py b/tests/ml/transforms/test_rdkit_utils.py index 83efa0c0..7fb244ee 100644 --- a/tests/ml/transforms/test_rdkit_utils.py +++ b/tests/ml/transforms/test_rdkit_utils.py @@ -167,13 +167,13 @@ def test_chirality_in_rdkit_conformer_generation(ccd_code, target_chirality, str for i in range(n_iterations): mol = ccd_code_to_rdkit_with_conformers(ccd_code, n_conformers=1, timeout=2, timeout_strategy=strategy) coord = mol.GetConformer(0).GetPositions()[0][0] - assert coord != prev_coord, ( - f"Conformer {i} has the same coordinate as the previous conformer: {coord} at iteration {i}/{n_iterations}." - ) + assert ( + coord != prev_coord + ), f"Conformer {i} has the same coordinate as the previous conformer: {coord} at iteration {i}/{n_iterations}." prev_coord = coord - assert Chem.FindMolChiralCenters(mol) == target_chirality, ( - f"Chiral center assignment is incorrect for {ccd_code} at iteration {i}/{n_iterations}." - ) + assert ( + Chem.FindMolChiralCenters(mol) == target_chirality + ), f"Chiral center assignment is incorrect for {ccd_code} at iteration {i}/{n_iterations}." @pytest.mark.filterwarnings("ignore: This process") diff --git a/tests/ml/transforms/test_templates.py b/tests/ml/transforms/test_templates.py index 9e5bd645..5aadd035 100644 --- a/tests/ml/transforms/test_templates.py +++ b/tests/ml/transforms/test_templates.py @@ -54,9 +54,9 @@ def test_add_rf_templates(test_case: dict): )(data) for chain, n_templates in test_case["n_templates"].items(): - assert len(data["template"][chain]) == n_templates, ( - f"For {pdb_id}-{chain}: Expected {n_templates} templates, got {len(data['template'][chain])}" - ) + assert ( + len(data["template"][chain]) == n_templates + ), f"For {pdb_id}-{chain}: Expected {n_templates} templates, got {len(data['template'][chain])}" @pytest.mark.parametrize("test_case", TEST_CASES) @@ -90,9 +90,9 @@ def test_subsample_template(test_case: dict): assert all(count <= 10 for count in template_counts), "Expected no template to have more than 10 templates" # Assert the mean is what we would expect (~7.5 = 0.5 * 10 + 0.5 * 5) - assert 7.5 - 1 < sum(template_counts) / len(template_counts) < 7.5 + 1, ( - f"Expected mean to be around 7.5. Found {sum(template_counts) / len(template_counts)}. This is a stochastic test, so running again may fix this." - ) + assert ( + 7.5 - 1 < sum(template_counts) / len(template_counts) < 7.5 + 1 + ), f"Expected mean to be around 7.5. Found {sum(template_counts) / len(template_counts)}. This is a stochastic test, so running again may fix this." @pytest.mark.parametrize("test_case", TEST_CASES) @@ -118,12 +118,12 @@ def test_add_rf_templates_filters( assert len(templates) > 0, f"No templates found for {pdb_id}-{chain}" assert len(templates) <= 5, f"Expected 5 templates, got {len(templates)} for {pdb_id}-{chain}" for template in templates: - assert min_seq_similarity <= template["seq_similarity"] <= max_seq_similarity, ( - f"Expected seq similarity between {min_seq_similarity} and {max_seq_similarity}, got {template['seq_similarity']} for {pdb_id}-{chain}-{template['id']}" - ) - assert template["n_res"] >= min_template_length, ( - f"Expected at least {min_template_length} residues, got {template['n_res']} for {pdb_id}-{chain}-{template['id']}" - ) + assert ( + min_seq_similarity <= template["seq_similarity"] <= max_seq_similarity + ), f"Expected seq similarity between {min_seq_similarity} and {max_seq_similarity}, got {template['seq_similarity']} for {pdb_id}-{chain}-{template['id']}" + assert ( + template["n_res"] >= min_template_length + ), f"Expected at least {min_template_length} residues, got {template['n_res']} for {pdb_id}-{chain}-{template['id']}" @pytest.mark.parametrize("test_case", TEST_CASES) @@ -186,15 +186,15 @@ def test_featurize_rf_templates(test_case: dict, encoding: TokenEncoding, n_temp assert t1d_template[0].shape == seq_encoded.shape # Check that the t1d last axis adds up to one when excluding the last dimension - assert torch.all(t1d_template[..., :-1].sum(dim=-1) == 1), ( - f"Expected t1d last axis to add up to one (one-hot encoded), but got {t1d_template[..., :-1].sum(dim=-1)}" - ) + assert torch.all( + t1d_template[..., :-1].sum(dim=-1) == 1 + ), f"Expected t1d last axis to add up to one (one-hot encoded), but got {t1d_template[..., :-1].sum(dim=-1)}" # Check that alignment confidences exist for all non-masked tokens is_masked = t1d_template[..., 21] == 1 - assert torch.all(t1d_template[..., -1][~is_masked] > 0), ( - "Expected t1d last axis to be greater than zero (alignment confidence)" - ) + assert torch.all( + t1d_template[..., -1][~is_masked] > 0 + ), "Expected t1d last axis to be greater than zero (alignment confidence)" # Check that all not-masked tokens have finite coordinates assert torch.all(torch.isfinite(xyz_template[mask_template])), "Expected non-masked template xyz to be finite" @@ -238,9 +238,7 @@ def test_add_input_file_template(test_case: dict): assert ( set(input_file_template[chosen_chain_to_template][0].keys()) == training_pipeline_template[chosen_chain_to_template][0].keys() - ), ( - f"Expected input file template to have the same keys as the training pipeline template, but got {set(input_file_template[chosen_chain_to_template][0].keys())} and {set(training_pipeline_template[chosen_chain_to_template][0].keys())}" - ) + ), f"Expected input file template to have the same keys as the training pipeline template, but got {set(input_file_template[chosen_chain_to_template][0].keys())} and {set(training_pipeline_template[chosen_chain_to_template][0].keys())}" # check that the template has the same fields as the template from AddRFTemplates required_annotations = [ @@ -253,28 +251,30 @@ def test_add_input_file_template(test_case: dict): training_pipeline_template_annotations = training_pipeline_template[chosen_chain_to_template][0][ "atom_array" ].get_annotation_categories() - assert set(required_annotations).issubset(input_file_template_annotations), ( - f"Input file template is missing the following annotations: {set(required_annotations) - set(input_file_template_annotations)}" - ) - assert set(required_annotations).issubset(training_pipeline_template_annotations), ( - f"Training pipeline template is missing the following annotations: {set(required_annotations) - set(training_pipeline_template_annotations)}" - ) + assert set( + required_annotations + ).issubset( + input_file_template_annotations + ), f"Input file template is missing the following annotations: {set(required_annotations) - set(input_file_template_annotations)}" + assert set( + required_annotations + ).issubset( + training_pipeline_template_annotations + ), f"Training pipeline template is missing the following annotations: {set(required_annotations) - set(training_pipeline_template_annotations)}" # check that one template has added for the first polymer chain - assert len(input_file_template[chosen_chain_to_template]) == 1, ( - f"Expected input file template to have one template, but got {len(input_file_template[chosen_chain_to_template])}" - ) + assert ( + len(input_file_template[chosen_chain_to_template]) == 1 + ), f"Expected input file template to have one template, but got {len(input_file_template[chosen_chain_to_template])}" - assert np.all(input_file_template[chosen_chain_to_template][0]["atom_array"].alignment_confidence == 1), ( - f"Expected input file template to have template confidence of 1, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].alignment_confidence}" - ) + assert np.all( + input_file_template[chosen_chain_to_template][0]["atom_array"].alignment_confidence == 1 + ), f"Expected input file template to have template confidence of 1, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].alignment_confidence}" assert np.all( input_file_template[chosen_chain_to_template][0]["atom_array"].aligned_query_res_idx == input_file_template[chosen_chain_to_template][0]["atom_array"].res_id - ), ( - f"Expected input file template to have aligned query res idx equal to res id, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].aligned_query_res_idx} and {input_file_template[chosen_chain_to_template][0]['atom_array'].res_id}" - ) + ), f"Expected input file template to have aligned query res idx equal to res id, but got {input_file_template[chosen_chain_to_template][0]['atom_array'].aligned_query_res_idx} and {input_file_template[chosen_chain_to_template][0]['atom_array'].res_id}" @pytest.mark.parametrize("test_case", TEST_CASES) @@ -312,6 +312,6 @@ def test_featurize_input_templates(test_case): "template_distogram", "template_unit_vector", ] - assert set(expected_template_features).issubset(data["feats"].keys()), ( - f"Expected template features to be present, but got {set(data['feats'].keys())} instead" - ) + assert set(expected_template_features).issubset( + data["feats"].keys() + ), f"Expected template features to be present, but got {set(data['feats'].keys())} instead" diff --git a/tests/ml/transforms/test_token_utils.py b/tests/ml/transforms/test_token_utils.py index 2e4db014..2db6e355 100644 --- a/tests/ml/transforms/test_token_utils.py +++ b/tests/ml/transforms/test_token_utils.py @@ -75,9 +75,9 @@ def test_add_global_token_id_annotation_when_fully_atomized(pdb_id): assert "atom_id" in atom_array.get_annotation_categories() assert "token_id" in atom_array.get_annotation_categories() - assert np.all(atom_array.atom_id == atom_array.token_id), ( - "atom_id and token_id should be the same for a fully atomized atom_array" - ) + assert np.all( + atom_array.atom_id == atom_array.token_id + ), "atom_id and token_id should be the same for a fully atomized atom_array" # cross check by iterating over the tokens # ... via token starts @@ -252,19 +252,19 @@ def test_add_global_res_id_annotation(): # Check that res_id_global values are in the expected range unique_global_res_ids = np.unique(atom_array.res_id_global) - assert len(unique_global_res_ids) == expected_n_residues, ( - f"Expected {expected_n_residues} unique residue IDs, got {len(unique_global_res_ids)}" - ) - assert np.all(unique_global_res_ids == np.arange(expected_n_residues)), ( - "Global residue IDs should be 0-indexed and continuous" - ) + assert ( + len(unique_global_res_ids) == expected_n_residues + ), f"Expected {expected_n_residues} unique residue IDs, got {len(unique_global_res_ids)}" + assert np.all( + unique_global_res_ids == np.arange(expected_n_residues) + ), "Global residue IDs should be 0-indexed and continuous" # Check that residues have consistent res_id_global values for counter, residue in enumerate(struc.residue_iter(atom_array)): assert len(residue) >= 1, f"Residue should have length at least 1 but has length {len(residue)}" - assert np.all(residue.res_id_global == counter), ( - f"All atoms in residue should have res_id_global {counter} but got {residue.res_id_global}" - ) + assert np.all( + residue.res_id_global == counter + ), f"All atoms in residue should have res_id_global {counter} but got {residue.res_id_global}" if __name__ == "__main__": diff --git a/tests/ml/utils/test_misc_utils.py b/tests/ml/utils/test_misc_utils.py index 6d586752..befde322 100644 --- a/tests/ml/utils/test_misc_utils.py +++ b/tests/ml/utils/test_misc_utils.py @@ -29,9 +29,9 @@ @pytest.mark.parametrize("test_case", GROUPED_SUM_TEST_CASES) def test_grouped_sum(test_case): output = grouped_sum(test_case["data"], test_case["assignment"], test_case["num_groups"]) - assert torch.equal(output, test_case["expected_output"]), ( - f"Expected {test_case['expected_output']}, but got {output}" - ) + assert torch.equal( + output, test_case["expected_output"] + ), f"Expected {test_case['expected_output']}, but got {output}" # Test cases for masked_mean @@ -68,6 +68,6 @@ def test_masked_mean(test_case): axis=test_case["axis"], drop_mask_channel=test_case["drop_mask_channel"], ) - assert torch.allclose(output, test_case["expected_output"], atol=1e-6), ( - f"Expected {test_case['expected_output']}, but got {output}" - ) + assert torch.allclose( + output, test_case["expected_output"], atol=1e-6 + ), f"Expected {test_case['expected_output']}, but got {output}" diff --git a/tests/ml/utils/test_rng_context.py b/tests/ml/utils/test_rng_context.py index 1b73aec8..f0cdaddf 100644 --- a/tests/ml/utils/test_rng_context.py +++ b/tests/ml/utils/test_rng_context.py @@ -41,24 +41,24 @@ def test_rng_state(): torch_inside_expected = torch.tensor([0.88226926, 0.91500396, 0.38286376]) python_inside_expected = [0.6394267984578837, 0.025010755222666936, 0.27502931836911926] - assert not np.array_equal(initial_numpy, final_numpy), ( - "NumPy values should be different outside the context manager" - ) + assert not np.array_equal( + initial_numpy, final_numpy + ), "NumPy values should be different outside the context manager" assert not torch.equal(initial_torch, final_torch), "PyTorch values should be different outside the context manager" assert initial_python != final_python, "Python random values should be different outside the context manager" - assert np.array_equal(numpy_inside, numpy_inside_again), ( - "NumPy values should be the same inside the context manager" - ) + assert np.array_equal( + numpy_inside, numpy_inside_again + ), "NumPy values should be the same inside the context manager" assert torch.equal(torch_inside, torch_inside_again), "PyTorch values should be the same inside the context manager" assert python_inside == python_inside_again, "Python random values should be the same inside the context manager" - assert np.allclose(numpy_inside, numpy_inside_expected), ( - "NumPy values should be the same inside the context manager" - ) - assert torch.allclose(torch_inside, torch_inside_expected), ( - "PyTorch values should be the same inside the context manager" - ) + assert np.allclose( + numpy_inside, numpy_inside_expected + ), "NumPy values should be the same inside the context manager" + assert torch.allclose( + torch_inside, torch_inside_expected + ), "PyTorch values should be the same inside the context manager" assert python_inside == python_inside_expected, "Python random values should be the same inside the context manager"