From e5c7a3b16efe6d992a0b6367789218b49bf7c086 Mon Sep 17 00:00:00 2001 From: Ken Lui <116421546+kenlhlui@users.noreply.github.com> Date: Fri, 17 Jan 2025 17:23:03 -0500 Subject: [PATCH] Inital Commit. --- CITATION.cff | 10 + LICENSE | 21 + README.md | 165 ++++ dvmeta/__init__.py | 0 dvmeta/dirmanager.py | 50 ++ dvmeta/func.py | 192 +++++ dvmeta/httpxclient.py | 122 +++ dvmeta/log_generation.py | 66 ++ dvmeta/main.py | 259 ++++++ dvmeta/metadatacrawler.py | 126 +++ dvmeta/spreadsheet.py | 275 ++++++ dvmeta/utils.py | 181 ++++ poetry.lock | 1715 +++++++++++++++++++++++++++++++++++++ pyproject.toml | 107 +++ requirements.txt | 762 ++++++++++++++++ res/log_template.txt | 27 + res/screenshot.png | Bin 0 -> 92815 bytes res/spreadsheet_order.csv | 118 +++ 18 files changed, 4196 insertions(+) create mode 100644 CITATION.cff create mode 100644 LICENSE create mode 100644 README.md create mode 100644 dvmeta/__init__.py create mode 100644 dvmeta/dirmanager.py create mode 100644 dvmeta/func.py create mode 100644 dvmeta/httpxclient.py create mode 100644 dvmeta/log_generation.py create mode 100644 dvmeta/main.py create mode 100644 dvmeta/metadatacrawler.py create mode 100644 dvmeta/spreadsheet.py create mode 100644 dvmeta/utils.py create mode 100644 poetry.lock create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100644 res/log_template.txt create mode 100644 res/screenshot.png create mode 100644 res/spreadsheet_order.csv diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..4700932 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,10 @@ +cff-version: 0.1.0 +message: "If you use this software, please cite it as below." +authors: +- family-names: "Lui" + given-names: "Lok Hei" + orcid: "https://orcid.org/0000-0001-5077-1530" +title: "Dataverse metadata Crawler" +version: 0.1.0 +date-released: 2025-01-16 +url: "https://github.com/kenlhlui/dataverse-metadata-crawler-p" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1aa3d6d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Lok Hei Lui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf4b45d --- /dev/null +++ b/README.md @@ -0,0 +1,165 @@ +[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Licnese: MIT](https://img.shields.io/badge/Licnese-MIT-blue)](https://opensource.org/license/mit) +[![Dataverse](https://img.shields.io/badge/Dataverse-FFA500?)](https://dataverse.org/) +[![Code Style: Black](https://img.shields.io/badge/code_style-black-black?)](https://github.com/psf/black) + +# Dataverse Metadata Crawler +![Screencapture of the CLI tool](res/screenshot.png) + +## 📜Description +A Python CLI tool for extracting and exporting metadata from [Dataverse](https://dataverse.org/) repositories. It supports bulk extraction of dataverses, datasets, and data file metadata from any chosen level of dataverse collection (whole Dataverse repository/sub-Dataverse), with flexible export options to JSON and CSV formats. + +## ✨Features +1. Bulk metadata extraction from Dataverse repositories from any chosen level of collection (top level or selected collection) +2. JSON & CSV file export options + +## 📦Prerequisites +1. Git +2. Python 3.10+ + +## ⚙️Installation + +1. Clone the repository + ```sh + git clone https://github.com/scholarsportal/dataverse-metadata-crawler.git + ``` + +2. Change to the project directory + ```sh + cd ~/dataverse-metadata-export-p + ``` + +3. Create an environment file (.env) + ```sh + touch .env # For Unix/MacOS + nano .env # or vim .env, or your preferred editor + # OR + New-Item .env -Type File # For Windows (Powershell) + notepad .env + ``` + +4. Configure environment file using your text editor at your choice + ```sh + # .env file + BASE_URL = "TARGET_REPO_URL" # e.g., "https://demo.borealisdata.ca/" + API_KEY = "YOUR_API_KEY" # Find in your Dataverse account settings. You may also specify it in the CLI interface (with -a flag) + ``` + +5. Set up virtual environment (recommended) + ```sh + python3 -m venv .venv + source .venv/bin/activate # For Unix/MacOS + # OR + .venv\Scripts\activate # For Windows + ``` + +6. Install dependencies + ```sh + pip install -r requirements.txt + ``` + +## 🛠️Usage + +### Basic Command +```sh +python3 dvmeta/main.py [-a AUTH] [-l] [-d] [-p] [-f] [-e] [-s] -c COLLECTION_ALIAS -v VERSION +``` +**Required arguments:** +| **Option** | **Short** | **Type** | **Description** | **Default** | +|--------------------|-----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| --collection_alias | -c | TEXT | Name of the collection to crawl.
**[required]** | None | +| --version | -v | TEXT | The Dataset version to crawl. Options include:
• `draft` - The draft version, if any
• `latest` - Either a draft (if exists) or the latest published version
• `latest-published` - The latest published version
• `x.y` - A specific version
**[required]** | None (required) | + + +**Optional arguments:** +| **Option** | **Short** | **Type** | **Description** | **Default** | +|----------------------|-----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------| +| --auth | -a | TEXT | Authentication token to access the Dataverse repository.
If | None | +| --log
--no-log | -l | | Output a log file.
Use `--no-log` to disable logging. | `log` (unless `--no-log`) | +| --dvdfds_metadata | -d | | Output a JSON file containing metadata of Dataverses, Datasets, and Data Files. | | +| --permission | -p | | Output a JSON file that stores permission metadata for all Datasets in the repository. | | +| --emptydv | -e | | Output a JSON file that stores all Dataverses which do **not** contain Datasets (though they might have child Dataverses which have Datasets). | | +| --failed | -f | | Output a JSON file of Dataverses/Datasets that failed to be crawled. | | +| --spreadsheet | -s | | Output a CSV file of the metadata of Datasets. | | +| --help | | | Show the help message. | | + +### Examples +```sh +# Export the metadata of latest version of datasets under collection 'demo' to JSON +python3 dvmeta/main.py -c demo -v latest -d + +# Export the metadata of version 1.0 of all datasets under collection 'demo' to JSON and CSV +python3 dvmeta/main.py -c demo -v 1.0 -d -s + +# Export the metadata and permission metadata of version 1.0 of all datasets under collection 'demo' to JSON and CSV, with the API token specified in the CLI interface +python3 dvmeta/main.py -c demo -v 1.0 -d -s -p -a xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx +``` + +## 📂Output Structure +| File | Description | +|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| +| ds_metadata_yyyymmdd-HHMMSS.json | Datasets' their data files' metadata in JSON format. | +| empty_dv_yyyymmdd-HHMMSS.json | The id of empty dataverse(s) in list format. | +| failed_metadata_uris_yyyymmdd-HHMMSS.json | The URIs (URL) of datasets failed to be downloaded. | +| permission_dict_yyyymmdd-HHMMSS.json | The perission metadata of datasets with their dataset id. | +| pid_dict_yyyymmdd-HHMMSS.json | Datasets' basic info with hierarchical information dictionary.Only exported if -p (permission) flag is used without -d (metadata) flag. | +| pid_dict_dd_yyyymmdd-HHMMSS.json | The Hierarchical information of deaccessioned/draft datasets. | +| ds_metadata_yyyymmdd-HHMMSS.csv | Datasets' their data files' metadata in CSV format. | +| log_yyyymmdd-HHMMSS.txt | Summary of the crawling work. | + +```sh +exported_files/ +├── json_files/ +│ └── ds_metadata_yyyymmdd-HHMMSS.json # With -d flag enabled +│ └── empty_dv_yyyymmdd-HHMMSS.json # With -e flag enabled +│ └── failed_metadata_uris_yyyymmdd-HHMMSS.json +│ └── permission_dict_yyyymmdd-HHMMSS.json # With -p flag enabled +│ └── pid_dict_yyyymmdd-HHMMSS.json # Only exported if -p flag is used without -d flag +│ └── pid_dict_dd_yyyymmdd-HHMMSS.json # Hierarchical information of deaccessioned/draft datasets +├── csv_files/ +│ └── ds_metadata_yyyymmdd-HHMMSS.csv # with -s flag enabled +└── logs_files/ + └── log_yyyymmdd-HHMMSS.txt # Exported by default, without specifying --no-log +``` + +## ✅Tests +No tests have been written yet. Contributions welcome! + +## 💻Development +1. Dependencies managment: [poetry](https://python-poetry.org/) - Update the pyproject.toml dependencies changes +2. Linter: [ruff](https://docs.astral.sh/ruff/) - Linting rules are outlined in the pyproject.toml + +## 🙌Contributing +1. Fork the repository +2. Create a feature branch +3. Submit a pull request + +## 📄License +[MIT](https://choosealicense.com/licenses/mit/) + +## 🆘Support +- Create an issue in the GitHub repository + +## 📚Citation +If you use this software in your work, please cite it using the following metadata. + +APA: +``` +Lui, L. H. (2025). Dataverse metadata Crawler (Version 0.1.0) [Computer software]. https://github.com/kenlhlui/dataverse-metadata-crawler-p +``` + +BibTeX: +``` +@software{Lui_Dataverse_metadata_Crawler_2025, +author = {Lui, Lok Hei}, +month = jan, +title = {{Dataverse metadata Crawler}}, +url = {https://github.com/kenlhlui/dataverse-metadata-crawler-p}, +version = {0.1.0}, +year = {2025} +} +``` + +## ✍️Authors +Ken Lui - Data Curation Specialist, Map and Data Library, University of Toronto - kenlh.lui@utoronto.ca + diff --git a/dvmeta/__init__.py b/dvmeta/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dvmeta/dirmanager.py b/dvmeta/dirmanager.py new file mode 100644 index 0000000..ff514e4 --- /dev/null +++ b/dvmeta/dirmanager.py @@ -0,0 +1,50 @@ +"""Module to manage the directories for exported files.""" + +from pathlib import Path + + +class DirManager: + """Class to manage directories and files in the data vault.""" + + def __init__(self) -> None: + """Initialize the class with the base directory for exported files.""" + self.export_base_dir = r'./exported_files' + self.res_dir = r'./res' + + @staticmethod + def _create_dir(path: Path) -> Path: + """Helper method to create a directory if it doesn't exist. + + Args: + path (Path): The path to the directory. + + Returns: + str: The path to the directory. + """ + if not Path.exists(path): + Path(path).mkdir(parents=True, exist_ok=True) + return path + + def json_files_dir(self) -> Path: + """Create a new directory to store json files. + + Returns: + Path: The path to the new directory. + """ + return self._create_dir(Path(self.export_base_dir) / 'json_files') + + def log_files_dir(self) -> Path: + """Create a new directory to store log files. + + Returns: + Path: The path to the new directory. + """ + return self._create_dir(Path(self.export_base_dir) / 'log_files') + + def csv_files_dir(self) -> Path: + """Create a new directory to store csv files. + + Returns: + Path: The path to the new directory. + """ + return self._create_dir(Path(self.export_base_dir) / 'csv_files') diff --git a/dvmeta/func.py b/dvmeta/func.py new file mode 100644 index 0000000..8784d83 --- /dev/null +++ b/dvmeta/func.py @@ -0,0 +1,192 @@ +"""This module contains functions used in the dvmeta package.""" +import os +import re + +import httpx +import jmespath +import typer +from dotenv import load_dotenv +from httpxclient import HttpxClient + + +def get_pids(read_dict: dict, config: dict) -> tuple: + """Get URIs in collections_tree_flatten/root_datasets. + + And append them to pid_dict. + + Args: + read_dict (dict): Dictionary containing the metadata of datasets + config (dict): Configuration dictionary + + Returns: + list: List of empty datasets + dict: Dictionary containing the URIs + """ + empty_dv = [] + write_dict = {} + for key, _item in read_dict.items(): + result = jmespath.search( + "data[?type=='dataset'].{ds_id: id, protocol: protocol, authority: authority, identifier: identifier, path: path, path_ids: path_ids}", # noqa: E501 + read_dict[key], # noqa: PLR1733 + ) + if result: + for item in result: + pid = f"{item['protocol']}:{item['authority']}/{item['identifier']}" + ds_id = item['ds_id'] + path = '/' + item['path'] if item['path'] else None + path_ids = item['path_ids'] + dict_to_append = { + str(pid): { # pid needs to be converted to string if it's not already + 'collection_alias': config['COLLECTION_ALIAS'], + 'collection_id': config['COLLECTION_ID'], + 'pid': pid, + 'ds_id': ds_id, + 'path': path, + 'path_ids': path_ids, + } + } + write_dict.update(dict_to_append) + else: + empty_dv.append(key) + return empty_dv, write_dict + + +def check_connection(config: dict) -> bool: + """Check the connection to the dataverse repository. + + Args: + config (dict): Configuration dictionary + auth (bool): Check the connection with authentication + + Returns: + bool: True if the connection is successful, False otherwise + """ + if config.get('API_KEY'): + url = f"{config['BASE_URL']}/api/mydata/retrieve?role_ids=8&dvobject_types=Dataverse&published_states=Published&per_page=1" # noqa: E501 + config['HEADERS'] = {'X-Dataverse-key': config['API_KEY']} + print('Checking the connection to the dataverse repository with authentication...\n') # noqa: E501 + else: + url = f"{config['BASE_URL']}/api/info/version" + config['HEADERS'] = {} + print('Checking the connection to the dataverse repository without authentication...\n') # noqa: E501 + try: + with HttpxClient(config) as httpx_client: + response = httpx_client.sync_get(url) + if response and response.status_code == httpx_client.httpx_success_status: + print(f'Connection to the dataverse repository {config["BASE_URL"]} is successful.\n') # noqa: E501 + return True + print('Your API_KEY is invalid and therefore failed to connect to the dataverse repository. Please check your input.\n') # noqa: E501 + return False + except httpx.HTTPStatusError as e: + print(f'Failed to connect to the dataverse repository {config["BASE_URL"]}: HTTP Error {e.response.status_code}\n') # noqa: E501 + return False + + +def version_type(value: str) -> str: + """Validate the value of --version argument. + + Args: + value (str): Value of --version argument. + + Returns: + str: Value of --version argument if it is valid. + + Raises: + typer.BadParameter: If the value is not valid. + """ + valid_special_versions = {'draft', 'latest', 'latest-published'} + + # Normalize and validate the input + value = str(value).lower().strip() + + if value in valid_special_versions or re.match(r'^\d+(\.\d+)?$', value): + return value + msg = f'Invalid value for --version: "{value}".\nMust be "draft", "latest", "latest-published", or a version number like "x" or "x.y".' # noqa: E501 + raise typer.BadParameter( + msg + ) + + +def validate_spreadsheet(value: bool, dvdfds_metadata: bool) -> bool: + """Validate the value of --spreadsheet argument.""" + if value and not dvdfds_metadata: + msg = 'The --spreadsheet option can only be used if --dvdfds_metadata is set to True.' + raise typer.BadParameter(msg) + return value + + +def count_files_size(read_dict: dict) -> tuple: + """Count the number of files and the total size of files in the dataset. + + Args: + read_dict (dict): Dictionary containing the metadata of datasets + + Returns: + int: Total number of files in the dataset + int: Total size of files in the dataset + """ + filecount_list = [] + filesize_list = [] + for key, _item in read_dict.items(): + if read_dict.get(key).get('data').get('files'): # type: ignore + filecount_list.append(len(read_dict.get(key).get('data').get('files'))) # type: ignore + filesize_list.append(sum(jmespath.search('data.files[*].dataFile.filesize|[]', read_dict[key]))) # noqa: PLR1733 + else: + filecount_list.append(0) + filesize_list.append(0) + + return sum(filecount_list), sum(filesize_list) + + +def add_path_to_dataverse_contents(des_dict: dict, ref_dict: dict) -> dict: + """Add path_ids and path to dataverse_contents from collections_tree_flatten. + + Args: + des_dict (dict): Dictionary containing the metadata of datasets + ref_dict (dict): Dictionary containing the metadata of dataverses + + Returns: + dict: Dictionary containing the metadata of datasets with path_ids and path added + """ # noqa: W505 + for key, value in des_dict.items(): + if key in ref_dict: + if value['data']: + for item in value['data']: + item.update({'path': ref_dict[key]['path']}) + item.update({'path_ids': ref_dict[key]['path_ids']}) + else: + value['data'].append({'path': ref_dict[key]['path']}) + value['data'].append({'path_ids': ref_dict[key]['path_ids']}) + return des_dict + + +def add_path_info(meta_dict: dict, pid_dict: dict) -> tuple: + """Add path_info to the metadata dictionary.""" + pid_dict_copy = pid_dict.copy() + for key in list(pid_dict_copy.keys()): + if key in meta_dict: + meta_dict[key]['path_info'] = pid_dict_copy[key] + pid_dict_copy.pop(key) + + return meta_dict, pid_dict_copy + + +def load_env() -> dict: + """Load the environment variables. + + Returns: + dict: A dictionary containing the environment variables + """ + # Load the environment variables + load_dotenv() + + config = { + 'API_KEY': os.getenv('API_KEY', None), + 'BASE_URL': os.getenv('BASE_URL'), + 'TIMEOUT': None, + } + if config['API_KEY']: + config['HEADERS'] = {'X-Dataverse-key': config['API_KEY'], 'Accept': 'application/json'} + else: + config['HEADERS'] = {'Accept': 'application/json'} + return config diff --git a/dvmeta/httpxclient.py b/dvmeta/httpxclient.py new file mode 100644 index 0000000..c353684 --- /dev/null +++ b/dvmeta/httpxclient.py @@ -0,0 +1,122 @@ +"""HTTP client class for making GET requests.""" +import asyncio +from types import TracebackType +from typing import Optional + +import httpx + + +class HttpxClient: + """HTTP client class for making GET requests.""" + + def __init__(self, config: dict) -> None: + """Initialize HTTP client. + + Args: + config (dict): Configuration settings + semaphore (asyncio.Semaphore): Semaphore object for limiting concurrent requests + sync_client (httpx.Client): Synchronous HTTP client + async_client (httpx.AsyncClient): Asynchronous HTTP client + async_sleep_time (int): Sleep time for asynchronous requests + """ # noqa: W505 + self.config = config + self.semaphore = asyncio.Semaphore(10) # 10 concurrent requests # TODO: make this configurable + self.sync_client = httpx.Client(timeout=None, headers=dict(config['HEADERS'])) + self.async_client = httpx.AsyncClient(timeout=None, headers=dict(config['HEADERS'])) + self.async_sleep_time = 0 # TODO: make this configurable + self.httpx_success_status = 200 + + def __enter__(self) -> 'HttpxClient': + """Enter context manager. + + Returns: + HttpxClient: Self reference + """ + return self + + def __exit__( + self, + exc_type: Optional[type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType] + ) -> None: + """Exit context manager and cleanup resources. + + Args: + exc_type: Exception type if an exception was raised + exc_val: Exception value if an exception was raised + exc_tb: Exception traceback if an exception was raised + """ + self.sync_client.close() + if not self.async_client.is_closed: + asyncio.run(self.async_client.aclose()) + + async def __aenter__(self) -> 'HttpxClient': + """Enter asynchronous context manager.""" + return self + + async def __aexit__(self, + exc_type: Optional[type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: + """Exit asynchronous context manager and cleanup resources.""" + await self.async_client.aclose() + self.sync_client.close() + + async def _async_semaphore_client(self, url: str) -> httpx.Response | None: + """Asynchronous HTTP client with semaphore. + + Args: + url (str): URL to GET + + Returns: + httpx.Response: Response object + """ + async with self.semaphore: + try: + response = await self.async_client.get(url) + if response.status_code != self.httpx_success_status: + # print(f'HTTP request Error for {url}: {response.status_code}') + return response + return response + except (httpx.HTTPStatusError, httpx.RequestError) as exc: + # print(f'HTTP request Error for {url}: {exc}') + return None + + def sync_get(self, url: str) -> httpx.Response | None: + """Synchronous GET request. + + Args: + url (str): URL to GET + + Returns: + httpx.Response: Response object + """ + if self.sync_client.is_closed: + self.sync_client = httpx.Client(timeout=None) + with self.sync_client as client: + try: + response = client.get(url) + if response.status_code != self.httpx_success_status: + # print(f'HTTP request Error for {url}: {response.status_code}') + return None + + except (httpx.HTTPStatusError, httpx.RequestError) as exc: + # print(f'HTTP request Error for {url}: {exc}') + return None + + return response + + async def async_get(self, url_list: list) -> list: + """Asynchronous GET request. + + Args: + url_list (list): List of URLs to GET + + Returns: + list: List of httpx.Response objects + """ + tasks = [self._async_semaphore_client(url) for url in url_list] + + # Using asyncio.gather to collect results + return await asyncio.gather(*tasks) diff --git a/dvmeta/log_generation.py b/dvmeta/log_generation.py new file mode 100644 index 0000000..435ad98 --- /dev/null +++ b/dvmeta/log_generation.py @@ -0,0 +1,66 @@ +"""Module to generate log file.""" +from pathlib import Path + +import utils +from dirmanager import DirManager +from func import count_files_size +from jinja2 import Template + + +def write_to_log( # noqa: PLR0913 + config: dict, + start_time_display: str, + end_time_display: str, + elapsed_time: str, + meta_dict: dict, + collections_tree_flatten: dict, + failed_metadata_ids: dict, + json_file_checksum_dict: dict, +) -> None: + """Write the crawl log to a file. + + Args: + config (dict): Configuration dictionary + start_time_display (str): Start time of the crawl + end_time_display (str): End time of the crawl + elapsed_time (str): Elapsed time of the crawl + meta_dict (dict): Metadata dictionary + collections_tree_flatten (dict): Flattened collections tree + failed_metadata_ids (dict): Dictionary of failed metadata IDs + json_file_checksum_dict (dict): Dictionary of JSON file checksums + + Returns: + str: Path to the log file + """ + report = Template(read_template()) + rendered = report.render(config=config, + start_time_display=start_time_display, + end_time_display=end_time_display, + elapsed_time=elapsed_time, + meta_dict=utils.count_key(meta_dict), + collections_tree_flatten=utils.count_key(collections_tree_flatten), + failed_metadata_ids=utils.count_key(failed_metadata_ids), + file_num=count_files_size(meta_dict)[0], + file_size=count_files_size(meta_dict)[1], + json_file_checksum_dict=json_file_checksum_dict + ) + + log_file_path = f'{DirManager().log_files_dir()}/log_{utils.Timestamp().get_file_timestamp()}.txt' + + with Path(log_file_path).open('w', encoding='utf-8') as file: + file.write(rendered) + + return print(f'The crawl log is saved at: {log_file_path}') + + +def read_template() -> str: + """Read the log template file from res directory. + + Returns: + str: Content of the template file as string + + Raises: + FileNotFoundError: If template file doesn't exist + """ + with Path('res/log_template.txt').open(encoding='utf-8') as file: + return file.read() diff --git a/dvmeta/main.py b/dvmeta/main.py new file mode 100644 index 0000000..b587516 --- /dev/null +++ b/dvmeta/main.py @@ -0,0 +1,259 @@ +"""The command line interface for dvmeta.""" +import asyncio +import sys + +import func +import typer +import utils +from log_generation import write_to_log +from metadatacrawler import MetaDataCrawler +from spreadsheet import Spreadsheet +from typing_extensions import Annotated + + +app = typer.Typer() + +@app.command() +def main( + auth: str = typer.Option( + None, + '--auth', + '-a', + help='Authentication token to access the dataverse repository', + hide_input=True, + envvar='API_KEY', + ), + log: bool = typer.Option(True, '--log/--no-log', '-l', help='Output log file'), + dvdfds_matadata: bool = typer.Option( + False, '--dvdfds_metadata', '-d', help='Output JSON file of metadata of dataverse, dataset and datafiles' + ), + permission: bool = typer.Option( + False, + '--permission', + '-p', + help='Output JSON file that stores permission metadata of all datasets in the repository', + ), + collection_alias: str = typer.Option( + ..., '--collection_alias', '-c', help='Name of the collection to crawl', allow_dash=True, prompt_required=True + ), + version: str = typer.Option( + ..., + '--version', + '-v', + help=( + 'The dataset version to crawl. Options are:\n' + " 'draft' - the draft version, if any\n" + " 'latest' - either a draft (if exists) or the latest published version\n" + " 'latest-published' - the latest published version\n" + " 'x.y' - a specific version, where x is the major version number and y is the minor version number\n" + " 'x' - same as 'x.0'" + ), + prompt_required=True, + callback=func.version_type, + ), + empty_dv: bool = typer.Option( + False, + '--emptydv', + '-e', + help='Output JSON file that stores all dataverses that does have contain datasets (but might include child dataverses and their child dataverses might have datasets)', + ), + failed: bool = typer.Option( + False, '--failed', '-f', help='Output JSON file that stores dataverses/datasets failed to be crawled' + ), + spreadsheet: bool = typer.Option( + False, '--spreadsheet', '-s', help='Output a CSV file of the metadata of datasets' + ), +): + """A command line utility that crawls a dataverse repository, extracting metadata for dataverses, datasets, and permissions, and then stores it in JSON format.""" + # Load the environment variables #! This need to be modified as it nullifies the auth token provided by the user + config: dict = func.load_env() + + config['COLLECTION_ALIAS'] = collection_alias + config['VERSION'] = version + config['API_KEY'] = ( + auth if auth else config['API_KEY'] + ) # Reassign the API_KEY and replace it specified in the .env file + + # Check if -s flag is provided without -d flag + func.validate_spreadsheet(spreadsheet, dvdfds_matadata) + + # Start time + start_time_obj, start_time_display = utils.Timestamp().get_current_time(), utils.Timestamp().get_display_time() + print(f'Start time: {start_time_display}\n') + + # Load the crawler + metadata_crawler = MetaDataCrawler(config) + + # Check if either dvdfds_matadata or permission is provided + if not dvdfds_matadata and not permission: + print( + 'Please provide the type of metadata to crawl. Use -d or/and -p flag for crawling metadata of datasets or permission metadata, respectively.' + ) + sys.exit(1) + + # Check if the authentication token is provided if the permission metadata is requested to be crawled + if permission and config.get('API_KEY') is None: + print('Error: Crawling permission metadata requires API Token. Please provide the API Token.\nExiting...') + sys.exit(1) + + # Check the connection to the dataverse repository + if not func.check_connection(config): + sys.exit(1) + + # Crawl the collection tree metadata + collections_tree = metadata_crawler.get_collections_tree(collection_alias).json() + + # Add collection id and alias to config + if collections_tree['status'] == 'OK': + config['COLLECTION_ID'], config['COLLECTION_ALIAS'], config['COLLECTION_NAME'] = ( + collections_tree['data']['id'], + collections_tree['data']['alias'], + collections_tree['data']['name'], + ) + + else: + print(f"Collection alias '{collection_alias}' is not found in the repository. Exiting...") + sys.exit(1) + + # Start the main function + print('Starting the main crawling function...\n') + + async def main_crawler(): + # Initialize empty dict and list to store metadata + pid_dict = {'pid': []} + failed_metadata_ids = [] + json_file_checksum_dict = [] + + # Flatten the collections tree + collections_tree_flatten = utils.flatten_collection(collections_tree) + print('Flattened the collections tree...\n') + + # Add collection id to collection_id_list + collection_id_list = [item['id'] for item in collections_tree_flatten.values()] + + # Add root collection id to collection_id_list + collection_id_list.append(config['COLLECTION_ID']) + + print('Getting basic metadata of datasets in across dataverses (incl. all children)...\n') + dataverse_contents, failed_dataverse_contents = await metadata_crawler.get_dataverse_contents(collection_id_list) + + # Add path_ids and path to dataverse_contents from collections_tree_flatten + dataverse_contents = func.add_path_to_dataverse_contents(dataverse_contents, collections_tree_flatten) + + # Get URIs in collections_tree_flatten and append them to pid_dict, and return empty dataverse to empty_dv + empty_dv_dict, pid_dict = func.get_pids(dataverse_contents, config) + + # Optional arguments + meta_dict = {} + failed_metadata_uris = [] + if dvdfds_matadata: + # Export dataverse_contents + print('\nCrawling Representation and File metadata of datasets...\n') + pid_list = list(pid_dict) + meta_dict, failed_metadata_uris = await metadata_crawler.get_datasets_meta(pid_list) + + # Add the path_info to the metadata + meta_dict, pid_dict_dd = func.add_path_info(meta_dict, pid_dict) + + # Export the metadata to a JSON file + meta_json_file_path, meta_json_checksum = utils.orjson_export(meta_dict, 'meta_dict') + json_file_checksum_dict.append( + { + 'type': 'Dataset Metadata (Representation & File)', + 'path': meta_json_file_path, + 'checksum': meta_json_checksum, + } + ) + print( + f'Successfully crawled {utils.count_key(meta_dict)} metadata of dataset representation and file in total.\n' + ) + + # Export the updated pid_dict_dd (Which contains deaccessioned/draft datasets) to a JSON file + pid_dict_json, pid_dict_checksum = utils.orjson_export(pid_dict_dd, 'pid_dict_dd') + json_file_checksum_dict.append( + { + 'type': 'Hierarchical Information of Datasets(deaccessioned/draft)', + 'path': pid_dict_json, + 'checksum': pid_dict_checksum, + } + ) + + if failed: + failed_metadata_uris_json, failed_metadata_uris_checksum = utils.orjson_export( + failed_metadata_uris, 'failed_metadata_uris' + ) + json_file_checksum_dict.append( + { + 'type': 'PIDs of Datasets Failed to be crawled (Representation & File)', + 'path': failed_metadata_uris_json, + 'checksum': failed_metadata_uris_checksum, + } + ) + + if spreadsheet: + # Export the metadata to a CSV file + csv_file_path, csv_file_checksum = Spreadsheet(config).make_csv(meta_dict) + json_file_checksum_dict.append( + {'type': 'Dataset Metadata CSV', 'path': csv_file_path, 'checksum': csv_file_checksum} + ) + + if permission: + print('\nCrawling Permission metadata of datasets...\n') + ds_id_list = [item['ds_id'] for item in pid_dict.values()] + permission_dict, failed_permission_uris = await (metadata_crawler.get_datasets_permissions(ds_id_list)) + permission_json_file_path, permission_json_checksum = utils.orjson_export( + permission_dict, 'permission_dict' + ) + json_file_checksum_dict.append( + { + 'type': 'Dataset Metadata (Permission)', + 'path': permission_json_file_path, + 'checksum': permission_json_checksum, + } + ) + print( + f'Successfully crawled permission metadata for {utils.count_key(permission_dict)} datasets in total.\n' + ) + + # Export the pid_dict to a JSON file, if dfdfds_metadata is not provided + if not dvdfds_matadata: + pid_dict_json, pid_dict_checksum = utils.orjson_export(pid_dict, 'pid_dict') + json_file_checksum_dict.append( + { + 'type': 'Hierarchical Information of Datasets', + 'path': pid_dict_json, + 'checksum': pid_dict_checksum, + } + ) + + if empty_dv: + empty_dv_json, empty_dv_checksum = utils.orjson_export(empty_dv_dict, 'empty_dv') + json_file_checksum_dict.append( + {'type': 'Empty Dataverses', 'path': empty_dv_json, 'checksum': empty_dv_checksum} + ) + + return meta_dict, json_file_checksum_dict, failed_metadata_uris, collections_tree_flatten + + meta_dict, json_file_checksum_dict, failed_metadata_uris, collections_tree_flatten = asyncio.run(main_crawler()) + + # End time + end_time_obj, end_time_display = utils.Timestamp().get_current_time(), utils.Timestamp().get_display_time() + print(f'End time: {end_time_display}\n') + + # Print the elapsed time for the crawling process + elapsed_time = end_time_obj - start_time_obj + print(f'Elapsed time: {elapsed_time}\n') + + if log: + # Write to log + write_to_log(config, + start_time_display, + end_time_display, + elapsed_time, + meta_dict, + collections_tree_flatten, + failed_metadata_uris, + json_file_checksum_dict) + +if __name__ == '__main__': + app() diff --git a/dvmeta/metadatacrawler.py b/dvmeta/metadatacrawler.py new file mode 100644 index 0000000..481ca14 --- /dev/null +++ b/dvmeta/metadatacrawler.py @@ -0,0 +1,126 @@ +"""Crawl metadata of datasets in a collection.""" +import httpx +from httpxclient import HttpxClient + + +class MetaDataCrawler: + """Crawl metadata of datasets in a collection. + + Attributes: + config (dict): Configuration dictionary + + Methods: + get_collections_tree: Get the tree structure of the collection + get_dataverse_contents: Get basic metadata of datasets in a collection + crawl_datasets_meta: Crawl metadata of datasets in a collection + _get_dataset_content_url: Get the URL of the dataset content + _get_permission_url: Get the URL of the dataset permission + _get_dataverse_contents_url: Get the URL of the dataverse contents + _get_tree_url: Get the URL of the tree structure + """ + + def __init__(self, config: dict) -> None: + """Initialize the class with the configuration settings.""" + self.config = config + self.url_tree = f"{config['BASE_URL']}/api/info/metrics/tree?parentAlias={config['COLLECTION_ALIAS']}" + self.http_success_status = 200 + self.url_dataverse = f"{config['BASE_URL']}/api/dataverses" + self.count = 0 + self.last_printed_count = 0 + self.write_dict = {} + self.failed_dict = [] + self.url = None + self.client = HttpxClient(config) + + def _get_dataset_content_url(self, identifier: str) -> str: + return f"{self.config['BASE_URL']}/api/datasets/:persistentId/versions/:{self.config['VERSION']}?persistentId={identifier}" # noqa: E501 + + def _get_permission_url(self, identifier: str) -> str: + return f"{self.config['BASE_URL']}/api/datasets/{identifier}/assignments" + + def _get_dataverse_contents_url(self, identifier: str) -> str: + return f"{self.config['BASE_URL']}/api/dataverses/{identifier}/contents" + + def _get_tree_url(self, parent_alias: str | None = None) -> str: + if parent_alias: + return f"{self.config['BASE_URL']}/api/info/metrics/tree?parentAlias={self.config['COLLECTION_ALIAS']}" + return f"{self.config['BASE_URL']}/api/info/metrics/tree" + + def get_collections_tree(self, parent_alias: str | None = None) -> httpx.Response | None: + """Get the tree structure of the collection. + + Returns: + dict: Dictionary containing the tree structure of the collection + """ + response = self.client.sync_get(self._get_tree_url(parent_alias)) + + if response and response.status_code == self.http_success_status: + return response + return None + + async def get_dataverse_contents(self, id_list: list) -> tuple[dict, dict]: + """Get basic metadata of datasets in all collections. + + Args: + id_list (list): List of dataset IDs + + Returns: + tuple[dict, dict]: Tuple containing two dictionaries: + - dataverse_contents: Successful metadata indexed by identifier + - failed_dataverse_contents: Failed metadata indexed by identifier + """ # noqa: W505 + url_list = [self._get_dataverse_contents_url(identifier) for identifier in id_list] + + response = await self.client.async_get(url_list) + + dataverse_contents = {} + failed_dataverse_contents = {} + + for identifier, item in zip(id_list, response): + if item and item.status_code == self.http_success_status and item.json(): + dataverse_contents[identifier] = item.json() + else: + failed_dataverse_contents[identifier] = { + 'url': item.url if item else None, + 'status_code': item.status_code if item else None, + } + + return dataverse_contents, failed_dataverse_contents + + async def get_datasets_meta(self, id_list: list) -> tuple[dict, dict]: + """Crawl complete metadata of datasets.""" + url_list = [self._get_dataset_content_url(identifier) for identifier in id_list] + + response = await self.client.async_get(url_list) + + dataset_meta = {} + failed_dataset_meta = {} + + for item in response: + if item and item.status_code == self.http_success_status and item.json(): + dataset_persistent_idd = item.json().get('data').get('datasetPersistentId') + dataset_meta[dataset_persistent_idd] = item.json() + else: + failed_dataset_meta[str(item.url)] = item.status_code + + return dataset_meta, failed_dataset_meta + + async def get_datasets_permissions(self, id_list: list) -> tuple[dict, dict]: + """Crawl permissions of datasets.""" + id_url_dict = {self._get_permission_url(identifier): identifier for identifier in id_list} + + responses = await self.client.async_get(list(id_url_dict.keys())) + + permission_meta = {} + failed_permission_meta = {} + + for resp in responses: + # Look up the identifier by the original request URL + identifier = id_url_dict.get(str(resp.url)) + + if resp.status_code == self.http_success_status and resp.json(): + permission_meta[identifier] = resp.json() + else: + failed_permission_meta[str(resp.url)] = resp.status_code + + return permission_meta, failed_permission_meta diff --git a/dvmeta/spreadsheet.py b/dvmeta/spreadsheet.py new file mode 100644 index 0000000..826a8e1 --- /dev/null +++ b/dvmeta/spreadsheet.py @@ -0,0 +1,275 @@ +# ruff: noqa: PLR1733 +"""A module to manage the creation of CSV files from metadata dictionaries.""" +from pathlib import Path + +import jmespath +import pandas as pd +from dirmanager import DirManager +from utils import Timestamp +from utils import convert_size +from utils import gen_checksum +from utils import list_to_string + + +class Spreadsheet: + """A class to manage the creation of CSV files from metadata dictionaries.""" + + def __init__(self, config: dict) -> None: + """Initialize the class with the configuration settings.""" + self.config = config + self.search_string = """{ + DatasetTitle: data.metadataBlocks.citation.fields[?typeName==`title`].value|[] + DatasetPersistentId: data.datasetPersistentId, + ID: data.id, + DatasetId: data.datasetId, + VersionState: data.versionState, + LastUpdateTime: data.lastUpdateTime, + ReleaseTime: data.releaseTime, + CreateTime: data.createTime, + License: data.license.name + TermsAccess: data.termsOfAccess + RequestAcces: data.fileAccessRequest + versionNumber: data.versionNumber, + versionMinorNumber: data.versionMinorNumber, + CM_Subtitle: data.metadataBlocks.citation.fields[?typeName==`subtitle`].value|[] + CM_AltTitle: data.metadataBlocks.citation.fields[?typeName==`alternativeTitle`].value|[] + CM_Author: data.metadataBlocks.citation.fields[?typeName==`author`].value|[*]|[].authorName.value + CM_ContactAff: data.metadataBlocks.citation.fields[?typeName==`author`].value|[*]|[].authorAffiliation.value + CM_AuthorID: data.metadataBlocks.citation.fields[?typeName==`author`].value|[*]|[].authorIdentifier.value + CM_AuthorIDType: data.metadataBlocks.citation.fields[?typeName==`author`].value|[*]|[].authorIdentifierScheme.value + CM_ContactName: data.metadataBlocks.citation.fields[?typeName==`datasetContact`].value|[*]|[].datasetContactName.value + CM_ContactAff: data.metadataBlocks.citation.fields[?typeName==`datasetContact`].value|[*]|[].datasetContactAffiliation.value + CM_Descr: data.metadataBlocks.citation.fields[?typeName==`dsDescription`].value|[*]|[].dsDescriptionValue.value + CM_DescrDate: data.metadataBlocks.citation.fields[?typeName==`dsDescription`].value|[*]|[].dsDescriptionDate.value + CM_Subject: data.metadataBlocks.citation.fields[?typeName==`subject`].value|[] + CM_Keyword: data.metadataBlocks.citation.fields[?typeName==`keyword`].value|[].keywordValue.value + CM_KeywordVocab: data.metadataBlocks.citation.fields[?typeName==`keyword`].value|[].keywordVocabulary.value + CM_KeywordURI: data.metadataBlocks.citation.fields[?typeName==`keyword`].value|[].keywordVocabularyURI.value + CM_TopicTerm: data.metadataBlocks.citation.fields[?typeName==`topicClassification`].value|[].topicClassValue.value + CM_TopicVocab: data.metadataBlocks.citation.fields[?typeName==`topicClassification`].value|[].topicClassVocab.value + CM_TopicURL: data.metadataBlocks.citation.fields[?typeName==`topicClassification`].value|[].topicClassVocabURI.value + CM_PubCit: data.metadataBlocks.citation.fields[?typeName==`publication`].value|[].publicationCitation.value + CM_PubIDType: data.metadataBlocks.citation.fields[?typeName==`publication`].value|[].publicationIDType.value + CM_PubID: data.metadataBlocks.citation.fields[?typeName==`publication`].value|[].publicationIDNumber.value + CM_PubURL: data.metadataBlocks.citation.fields[?typeName==`publication`].value|[].publicationURL.value + CM_Notes: data.metadataBlocks.citation.fields[?typeName==`notesText`].value|[] + CM_Lang: data.metadataBlocks.citation.fields[?typeName==`language`].value|[] + CM_ProdName: data.metadataBlocks.citation.fields[?typeName==`producer`].value|[].producerName.value + CM_ProdAff: data.metadataBlocks.citation.fields[?typeName==`producer`].value|[].producerAffiliation.value + CM_ProdAbrev: data.metadataBlocks.citation.fields[?typeName==`producer`].value|[].producerAbbreviation.value + CM_ProdURL: data.metadataBlocks.citation.fields[?typeName==`producer`].value|[].producerURL.value + CM_ProdLogo: data.metadataBlocks.citation.fields[?typeName==`producer`].value|[].producerLogoURL.value + CM_ProdDate: data.metadataBlocks.citation.fields[?typeName==`productionDate`].value|[] + CM_ProdLocation: data.metadataBlocks.citation.fields[?typeName==`productionPlace`].value|[] + CM_ContribName: data.metadataBlocks.citation.fields[?typeName==`contributor`].value|[].contributorName.value + CM_ContribType: data.metadataBlocks.citation.fields[?typeName==`contributor`].value|[].contributorType.value + CM_FundingAgency: data.metadataBlocks.citation.fields[?typeName==`grantNumber`].value|[].grantNumberAgency.value + CM_FundingID: data.metadataBlocks.citation.fields[?typeName==`grantNumber`].value|[].grantNumberValue.value + CM_DisName: data.metadataBlocks.citation.fields[?typeName==`distributor`].value|[].distributorName.value + CM_DisAff: data.metadataBlocks.citation.fields[?typeName==`distributor`].value|[].distributorAffiliation.value + CM_DisAbbrev: data.metadataBlocks.citation.fields[?typeName==`distributor`].value|[].distributorAbbreviation.value + CM_DisURL: data.metadataBlocks.citation.fields[?typeName==`distributor`].value|[].distributorURL.value + CM_DisLogoURL: data.metadataBlocks.citation.fields[?typeName==`distributor`].value|[].distributorLogoURL.value + CM_DisDate: data.metadataBlocks.citation.fields[?typeName==`distributionDate`].value|[] + CM_Depositor: data.metadataBlocks.citation.fields[?typeName==`depositor`].value|[] + CM_DepositDate: data.metadataBlocks.citation.fields[?typeName==`dateOfDeposit`].value|[] + CM_TimeStart: data.metadataBlocks.citation.fields[?typeName==`timePeriodCovered`].value|[].timePeriodCoveredStart.value + CM_TimeEnd: data.metadataBlocks.citation.fields[?typeName==`dateOfCollection`].value|[].dateOfCollectionStart.value + CM_CollectionStart: data.metadataBlocks.citation.fields[?typeName==`dateOfCollection`].value|[].dateOfCollectionEnd.value + CM_DataType: data.metadataBlocks.citation.fields[?typeName==`kindOfData`].value|[] + CM_SeriesName: data.metadataBlocks.citation.fields[?typeName==`series`].value|[].seriesName.value + CM_SeriesInfo: data.metadataBlocks.citation.fields[?typeName==`series`].value|[].seriesInformation.value + CM_SoftwareName: data.metadataBlocks.citation.fields[?typeName==`software`].value|[].softwareName.value + CM_SoftwareVers: data.metadataBlocks.citation.fields[?typeName==`software`].value|[].softwareVersion.value + CM_RelMaterial: data.metadataBlocks.citation.fields[?typeName==`relatedMaterial`].value|[] + CM_RelDatasets: data.metadataBlocks.citation.fields[?typeName==`relatedDatasets`].value|[] + CM_OtherRef: data.metadataBlocks.citation.fields[?typeName==`otherReferences`].value|[] + CM_DataSources: data.metadataBlocks.citation.fields[?typeName==`dataSources`].value|[] + CM_OriginSources: data.metadataBlocks.citation.fields[?typeName==`originOfSources`].value|[] + CM_CharSources: data.metadataBlocks.citation.fields[?typeName==`characteristicOfSources`].value|[] + CM_DocSources: data.metadataBlocks.citation.fields[?typeName==`accessToSources`].value|[] + DataverseSubCollection: path_info.path + }""" # noqa: E501 + self.csv_file_dir = DirManager().csv_files_dir() + self.spreadsheet_order_file_path = Path(DirManager().res_dir) / 'spreadsheet_order.csv' + + @staticmethod + def _mk_csv_file_dir() -> str: + csv_file_dir = r'./csv_files' + if not Path(csv_file_dir).exists(): + Path.mkdir(Path(csv_file_dir)) + + return csv_file_dir + + @staticmethod + def _get_data_files_size(dictionary: dict) -> int | str: + data = dictionary.get('data') + if data is not None and 'files' in data: + data_files_size_list: list = jmespath.search('data.files[*].dataFile.filesize|[]', dictionary) + if data_files_size_list: + return sum(data_files_size_list) + return 'Error' + + @staticmethod + def _get_data_files_count(dictionary: dict) -> int | str: + data = dictionary.get('data') + if data is not None and 'files' in data: + data_files_count: int = len(jmespath.search('data.files', dictionary)) + return data_files_count + return 'Error' + + @staticmethod + def _get_restricted_data_files_count(dictionary: dict) -> int | str: + data = dictionary.get('data') + if data is not None and 'files' in data: + data_files_count: list = jmespath.search('data.files[?restricted==`true`]', dictionary) + return len(data_files_count) if data_files_count else 0 + return 'Error' + + @staticmethod + def _get_dataset_path(dictionary: dict) -> str: + path_info = dictionary.get('path_info') + if path_info is not None and 'path' in path_info: + return path_info.get('path') + if path_info is None: + return 'root' + return 'Error' + + @staticmethod + def _get_dataset_version(dictionary: dict) -> float | str: + version_number = dictionary.get('versionNumber') + version_minor_number = dictionary.get('versionMinorNumber') + if version_number is not None and version_minor_number is not None: + return float(f'{version_number}.{version_minor_number}') + return 'Error' + + @staticmethod + def _get_dataset_subjects(dictionary: dict) -> dict: + subject_list = dictionary.get('CM_subject') + subject_dict = { + 'CM_Subject_Agri': 'Agricultural Sciences', + 'CM_Subject_AH': 'Arts and Humanities', + 'CM_Subject_Astro': 'Astronomy and Astrophysics', + 'CM_Subject_BM': 'Business and Management', + 'CM_Subject_Chem': 'Chemistry', + 'CM_Subject_Comp': 'Computer and Information Science', + 'CM_Subject_EES': 'Earth and Environmental Sciences', + 'CM_Subject_Eng': 'Engineering', + 'CM_Subject_Law': 'Law', + 'CM_Subject_Math': 'Mathematical Sciences', + 'CM_Subject_Med': 'Medicine, Health and Life Sciences', + 'CM_Subject_Phys': 'Physics', + 'CM_Subject_SocSci': 'Social Sciences', + 'CM_Subject_Other': 'Other' + } + # Initialize an empty dictionary to store the result + result_dict = {} + + # Iterate through the keys in return_dict and check if the subject is in subject_list + if subject_list: + for key, value in subject_dict.items(): + result_dict[key] = value in subject_list + + # If there are no subjects in the list, return a dictionary with all values set to False + if not subject_list: + return dict.fromkeys(subject_dict, False) + + return result_dict + + @staticmethod + def _get_metadata_blocks(dictionary: dict) -> dict: + metadata_block_dict = { + 'Meta_Geo': 'geospatial', + 'Meta_SSHM': 'socialscience', + 'Meta_Astro': 'astrophysics', + 'Meta_LS': 'biomedical', + 'Meta_Journal': 'journal', + 'Meta_CWF': 'computationalworkflow', + } + + # Loop through the metadata blocks and check if they are in the dictionary + result_dict = {} + for key, value in metadata_block_dict.items(): + result_dict[key] = value in dictionary + + return result_dict + + def _get_spreadsheet_order(self) -> list[str]: + with Path(self.spreadsheet_order_file_path).open(encoding='utf-8') as file: + return file.read().splitlines() + + def _reoder_df_columns(self, df: pd.DataFrame) -> pd.DataFrame: + order_list = self._get_spreadsheet_order() + + # Filter the preset column order to only include existing columns in the DataFrame + valid_columns = [col for col in order_list if col in df.columns] + + # Get columns not in the preset order + remaining_columns = [col for col in df.columns if col not in valid_columns] + + # Combine valid columns (from the preset) and the remaining columns + final_column_order = valid_columns + remaining_columns + + return df[final_column_order] + + def make_csv(self, meta_dict: dict) -> tuple[str, str]: + """Create a CSV file from the metadata dictionary. + + Args: + meta_dict (dict): Metadata dictionary + + Returns: + tuple[str, str]: Path to the CSV file, Checksum of the CSV file + """ + holding_list = [] + for key, _value in meta_dict.items(): + jmespath_dict: dict = jmespath.search(f'{self.search_string}', meta_dict[key]) + # Get the file size and count + jmespath_dict['FileSize'] = self._get_data_files_size(meta_dict[key]) + jmespath_dict['FileSize_normalized'] = convert_size(jmespath_dict['FileSize']) + jmespath_dict['FileCount'] = self._get_data_files_count(meta_dict[key]) + + # Get the number of restricted files + jmespath_dict['RestrictedFiles'] = self._get_restricted_data_files_count(meta_dict[key]) + + # Get the URL for the dataset + jmespath_dict['DatasetURL'] = f"{self.config['BASE_URL']}/dataset.xhtml?persistentId={jmespath_dict['DatasetPersistentId']}" # noqa: E501 + + # Get the dataset version + jmespath_dict['Version'] = self._get_dataset_version(jmespath_dict) + + # Get the number of authors + jmespath_dict['CM_NumberAuthors'] = len(jmespath_dict['CM_Author']) if jmespath_dict['CM_Author'] else 0 + + # Get the number of subjects add the the result dictionary + jmespath_dict.update(self._get_dataset_subjects(jmespath_dict)) + + # Get the metadata blocks and add them to the result dictionary + jmespath_dict.update(self._get_metadata_blocks(jmespath_dict)) + + # Drop the versionNumber and versionMinorNumber keys from the dictionary + jmespath_dict.pop('versionNumber', None) + jmespath_dict.pop('versionMinorNumber', None) + + # Last step: Turn the lists in the dictionary into strings + jmespath_dict = {key: list_to_string(value) if isinstance(value, list) else value for key, value in jmespath_dict.items()} + + holding_list.append(jmespath_dict) + + df = pd.DataFrame(holding_list) + + # Reoder the columns in the DataFrame + df = self._reoder_df_columns(df) + + # Create the CSV file + csv_file_path = f'{self.csv_file_dir}/ds_metadata_{Timestamp().get_file_timestamp()}.csv' + + df.to_csv(csv_file_path, index=False) + + # Generate a checksum for the CSV file + checksum = gen_checksum(csv_file_path) + + print(f'\n[INFO] Exported Dataset Metadata CSV: {csv_file_path}' + f'\n[INFO] Checksum (SHA-256): {checksum}\n') + + return csv_file_path, checksum diff --git a/dvmeta/utils.py b/dvmeta/utils.py new file mode 100644 index 0000000..e2c1ab1 --- /dev/null +++ b/dvmeta/utils.py @@ -0,0 +1,181 @@ +"""This module contains utility functions for the dvmeta package.""" +import math +from datetime import datetime +from hashlib import sha256 +from pathlib import Path + +import orjson +from dirmanager import DirManager + + +class Timestamp: + """A class to manage timestamps. + + Attributes: + current_time (datetime): The current time. + + Methods: + get_current_time: Returns the current time as a datetime object. + get_display_time: Returns a string representation of the current time. + get_file_timestamp: Returns a string representation of the current time for use in file names. + """ + + def __init__(self) -> None: + """Initialize the class with the current time.""" + self.current_time = datetime.now() + + def get_current_time(self) -> datetime: + """Returns the current time as a datetime object. + + Returns: + datetime: The current time + """ + return self.current_time + + def get_display_time(self) -> str: + """Returns a string representation of the current time in the format: YYYY-MM-DD HH:MM:SS. + + Returns: + str: A string representation of the current time. + """ + return self.current_time.strftime('%Y-%m-%d %H:%M:%S') + + def get_file_timestamp(self) -> str: + """Returns a string representation of the current time in the format: YYYYMMDD-HHMMSS. + + Returns: + str: A string representation of the current time for use in file names + """ + return self.current_time.strftime('%Y%m%d-%H%M%S') + + +def count_key(key: dict | list | tuple) -> int: + """Count the number of keys in a dictionary, list or tuple. + + Args: + key (dict, list, tuple): The dictionary, list or tuple to count the keys of. + + Returns: + int: The number of keys in the dictionary, list or tuple. + """ + return len(key) if isinstance(key, (dict, list, tuple)) else 0 + + +def convert_size(size_bytes: int | str) -> str: + """Convert the size of a file from bytes to a human-readable format. + + Args: + size_bytes (int): The size of the file in bytes. + + Returns: + str: The size of the file in a human-readable format + """ + if not isinstance(size_bytes, int): + return 'Error' + if size_bytes == 0: + return '0B' + size_name = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB') + i = int(math.floor(math.log(size_bytes, 1024))) + p = math.pow(1024, i) + s = round(size_bytes / p, 2) + return f'{s} {size_name[i]}' + + +def gen_checksum(json_file_path: str) -> str: + """Generate a SHA-256 checksum for a file. + + Args: + json_file_path (str): The path to the file for which to generate the checksum. + + Returns: + str: The SHA-256 checksum of the file. + """ + sha256_hash = sha256() + with Path(json_file_path).open('rb') as f: + # Read and update hash string value in blocks of 4K + for byte_block in iter(lambda: f.read(4096), b''): + sha256_hash.update(byte_block) + return sha256_hash.hexdigest() # Return the hexadecimal digest of the hash + + +def list_to_string(list: list) -> str: + """Joins list items into comma-separated string after converting to string and stripping whitespace. + + Args: + list (list): A list of values to be processed. + + Returns: + str: A single string with the processed values separated by commas. + """ + # Ensure each value is a string and strip whitespace from each string + stripped_values = [str(value).strip() for value in list] + + # Join the stripped strings with a comma + return ', '.join(stripped_values) + + +def orjson_export(data_dict: dict, file_name: str) -> tuple: + """Export a dictionary to a json file using the orjson library. + + Args: + data_dict (dict): The dictionary to export to a json file. + file_name (str): The name of the json file to create. + + Returns: + str: The path to the created json file. + """ + json_dir = DirManager().json_files_dir() + json_file_path = f'{json_dir}/{file_name}_{Timestamp().get_file_timestamp()}.json' + if data_dict: + with Path(json_file_path).open('wb') as file: # Open file in binary write mode + file.write(orjson.dumps(data_dict, option=orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS)) + checksum = gen_checksum(json_file_path) + print(f'\n[INFO] Exported {file_name} to json file: {json_file_path}' + f'\n[INFO] Checksum (SHA-256): {checksum}\n') + + return json_file_path, checksum + print(f'\n[INFO] {file_name} is empty, no json file is created.') + + return None, None + + +def flatten_collection(readdict, path_name='', path_ids=[]): + """Flatten a nested collection in a dictionary. + + Args: + readdict (dict): The dictionary to flatten. + path_name (str): The path name. + path_ids (list): The path IDs. + + Returns: + dict: The flattened dictionary. + """ + write_dict = {} + dictionary_data = readdict['data'] + + def loop_item(dictionary_data, path_name='', path_ids=[]): + """Loop through the items in the dictionary and flatten them. + + Args: + dictionary_data (dict): The dictionary to loop through. + path_name (str): The path name. + path_ids (list): The path IDs. + + Returns: + dict: The flattened dictionary. + """ + for item in dictionary_data['children']: + new_item = item.copy() + + current_path_ids = path_ids + [item['id']] + + new_item['path_ids'] = current_path_ids + new_item['path'] = f"{path_name}/{item['name']}" if path_name else item['name'] + new_item.pop('children', None) + write_dict[item['id']] = new_item + if 'children' in item: + loop_item(item, new_item['path'], current_path_ids) + return write_dict + if 'children' not in dictionary_data or not dictionary_data['children']: + return {} + return loop_item(dictionary_data, path_name, path_ids) diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..f56e92b --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1715 @@ +# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. + +[[package]] +name = "anyio" +version = "4.8.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, + {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] + +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and platform_system == \"Darwin\" or python_version >= \"3.12\" and platform_system == \"Darwin\"" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, + {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, +] + +[package.extras] +astroid = ["astroid (>=2,<4)"] +test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "asyncio" +version = "3.4.3" +description = "reference implementation of PEP 3156" +optional = false +python-versions = "*" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "asyncio-3.4.3-cp33-none-win32.whl", hash = "sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de"}, + {file = "asyncio-3.4.3-cp33-none-win_amd64.whl", hash = "sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c"}, + {file = "asyncio-3.4.3-py3-none-any.whl", hash = "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"}, + {file = "asyncio-3.4.3.tar.gz", hash = "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41"}, +] + +[[package]] +name = "attrs" +version = "24.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "certifi" +version = "2024.12.14" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and implementation_name == \"pypy\" or python_version >= \"3.12\" and implementation_name == \"pypy\"" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +markers = {main = "python_version <= \"3.11\" and platform_system == \"Windows\" or python_version <= \"3.11\" and sys_platform == \"win32\" or python_version >= \"3.12\" and platform_system == \"Windows\" or python_version >= \"3.12\" and sys_platform == \"win32\"", dev = "python_version <= \"3.11\" and sys_platform == \"win32\" or python_version >= \"3.12\" and sys_platform == \"win32\""} + +[[package]] +name = "comm" +version = "0.2.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "debugpy" +version = "1.8.12" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "debugpy-1.8.12-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a"}, + {file = "debugpy-1.8.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45"}, + {file = "debugpy-1.8.12-cp310-cp310-win32.whl", hash = "sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c"}, + {file = "debugpy-1.8.12-cp310-cp310-win_amd64.whl", hash = "sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9"}, + {file = "debugpy-1.8.12-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5"}, + {file = "debugpy-1.8.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7"}, + {file = "debugpy-1.8.12-cp311-cp311-win32.whl", hash = "sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb"}, + {file = "debugpy-1.8.12-cp311-cp311-win_amd64.whl", hash = "sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1"}, + {file = "debugpy-1.8.12-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498"}, + {file = "debugpy-1.8.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06"}, + {file = "debugpy-1.8.12-cp312-cp312-win32.whl", hash = "sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d"}, + {file = "debugpy-1.8.12-cp312-cp312-win_amd64.whl", hash = "sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969"}, + {file = "debugpy-1.8.12-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f"}, + {file = "debugpy-1.8.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9"}, + {file = "debugpy-1.8.12-cp313-cp313-win32.whl", hash = "sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180"}, + {file = "debugpy-1.8.12-cp313-cp313-win_amd64.whl", hash = "sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c"}, + {file = "debugpy-1.8.12-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:b0232cd42506d0c94f9328aaf0d1d0785f90f87ae72d9759df7e5051be039738"}, + {file = "debugpy-1.8.12-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9af40506a59450f1315168d47a970db1a65aaab5df3833ac389d2899a5d63b3f"}, + {file = "debugpy-1.8.12-cp38-cp38-win32.whl", hash = "sha256:5cc45235fefac57f52680902b7d197fb2f3650112379a6fa9aa1b1c1d3ed3f02"}, + {file = "debugpy-1.8.12-cp38-cp38-win_amd64.whl", hash = "sha256:557cc55b51ab2f3371e238804ffc8510b6ef087673303890f57a24195d096e61"}, + {file = "debugpy-1.8.12-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:b5c6c967d02fee30e157ab5227706f965d5c37679c687b1e7bbc5d9e7128bd41"}, + {file = "debugpy-1.8.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a77f422f31f170c4b7e9ca58eae2a6c8e04da54121900651dfa8e66c29901a"}, + {file = "debugpy-1.8.12-cp39-cp39-win32.whl", hash = "sha256:a4042edef80364239f5b7b5764e55fd3ffd40c32cf6753da9bda4ff0ac466018"}, + {file = "debugpy-1.8.12-cp39-cp39-win_amd64.whl", hash = "sha256:f30b03b0f27608a0b26c75f0bb8a880c752c0e0b01090551b9d87c7d783e2069"}, + {file = "debugpy-1.8.12-py2.py3-none-any.whl", hash = "sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6"}, + {file = "debugpy-1.8.12.tar.gz", hash = "sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["main", "dev"] +markers = "python_version < \"3.11\"" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "executing" +version = "2.1.0" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, + {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.27.2" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "ipykernel" +version = "6.29.5" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.31.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.10" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "ipython-8.31.0-py3-none-any.whl", hash = "sha256:46ec58f8d3d076a61d128fe517a51eb730e3aaf0c184ea8c17d16e366660c6a6"}, + {file = "ipython-8.31.0.tar.gz", hash = "sha256:b6a2274606bec6166405ff05e54932ed6e5cfecaca1fc05f2cacde7bb074d70b"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} +prompt_toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack_data = "*" +traitlets = ">=5.13.0" +typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} + +[package.extras] +all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing_extensions"] +kernel = ["ipykernel"] +matplotlib = ["matplotlib"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] + +[[package]] +name = "jedi" +version = "0.19.2" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, + {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, +] + +[package.dependencies] +parso = ">=0.8.4,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.5" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "json2" +version = "0.9.0" +description = "Add convenience function to pythons default json implementation" +optional = false +python-versions = ">=2.5" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "json2-0.9.0-py3-none-any.whl", hash = "sha256:1f6273489f58fe7676df9edf6066ece2dadc015b0d6626ba8e4f1827b2c112ba"}, + {file = "json2-0.9.0.tar.gz", hash = "sha256:28c7ac7e9475d8758e05f19b34b1defe9df8a8fe21e8818895c7b357a6e71c9d"}, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, + {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jupyter-client" +version = "8.6.3" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"}, + {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"}, +] + +[package.dependencies] +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = ">=5.3" + +[package.extras] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "numpy" +version = "2.2.1" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "numpy-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528"}, + {file = "numpy-2.2.1-cp310-cp310-win32.whl", hash = "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95"}, + {file = "numpy-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0"}, + {file = "numpy-2.2.1-cp311-cp311-win32.whl", hash = "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd"}, + {file = "numpy-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046"}, + {file = "numpy-2.2.1-cp312-cp312-win32.whl", hash = "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2"}, + {file = "numpy-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716"}, + {file = "numpy-2.2.1-cp313-cp313-win32.whl", hash = "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e"}, + {file = "numpy-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71"}, + {file = "numpy-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2"}, + {file = "numpy-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e"}, + {file = "numpy-2.2.1.tar.gz", hash = "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918"}, +] + +[[package]] +name = "orjson" +version = "3.10.14" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "orjson-3.10.14-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:849ea7845a55f09965826e816cdc7689d6cf74fe9223d79d758c714af955bcb6"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5947b139dfa33f72eecc63f17e45230a97e741942955a6c9e650069305eb73d"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cde6d76910d3179dae70f164466692f4ea36da124d6fb1a61399ca589e81d69a"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6dfbaeb7afa77ca608a50e2770a0461177b63a99520d4928e27591b142c74b1"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa45e489ef80f28ff0e5ba0a72812b8cfc7c1ef8b46a694723807d1b07c89ebb"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5007abfdbb1d866e2aa8990bd1c465f0f6da71d19e695fc278282be12cffa5"}, + {file = "orjson-3.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b49e2af011c84c3f2d541bb5cd1e3c7c2df672223e7e3ea608f09cf295e5f8a"}, + {file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:164ac155109226b3a2606ee6dda899ccfbe6e7e18b5bdc3fbc00f79cc074157d"}, + {file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6b1225024cf0ef5d15934b5ffe9baf860fe8bc68a796513f5ea4f5056de30bca"}, + {file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d6546e8073dc382e60fcae4a001a5a1bc46da5eab4a4878acc2d12072d6166d5"}, + {file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f1d2942605c894162252d6259b0121bf1cb493071a1ea8cb35d79cb3e6ac5bc"}, + {file = "orjson-3.10.14-cp310-cp310-win32.whl", hash = "sha256:397083806abd51cf2b3bbbf6c347575374d160331a2d33c5823e22249ad3118b"}, + {file = "orjson-3.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:fa18f949d3183a8d468367056be989666ac2bef3a72eece0bade9cdb733b3c28"}, + {file = "orjson-3.10.14-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f506fd666dd1ecd15a832bebc66c4df45c1902fd47526292836c339f7ba665a9"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe5fd254cfb0eeee13b8ef7ecb20f5d5a56ddda8a587f3852ab2cedfefdb5f6"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ddc8c866d7467f5ee2991397d2ea94bcf60d0048bdd8ca555740b56f9042725"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af8e42ae4363773658b8d578d56dedffb4f05ceeb4d1d4dd3fb504950b45526"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84dd83110503bc10e94322bf3ffab8bc49150176b49b4984dc1cce4c0a993bf9"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36f5bfc0399cd4811bf10ec7a759c7ab0cd18080956af8ee138097d5b5296a95"}, + {file = "orjson-3.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868943660fb2a1e6b6b965b74430c16a79320b665b28dd4511d15ad5038d37d5"}, + {file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33449c67195969b1a677533dee9d76e006001213a24501333624623e13c7cc8e"}, + {file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4c9f60f9fb0b5be66e416dcd8c9d94c3eabff3801d875bdb1f8ffc12cf86905"}, + {file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0de4d6315cfdbd9ec803b945c23b3a68207fd47cbe43626036d97e8e9561a436"}, + {file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83adda3db595cb1a7e2237029b3249c85afbe5c747d26b41b802e7482cb3933e"}, + {file = "orjson-3.10.14-cp311-cp311-win32.whl", hash = "sha256:998019ef74a4997a9d741b1473533cdb8faa31373afc9849b35129b4b8ec048d"}, + {file = "orjson-3.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:9d034abdd36f0f0f2240f91492684e5043d46f290525d1117712d5b8137784eb"}, + {file = "orjson-3.10.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780"}, + {file = "orjson-3.10.14-cp312-cp312-win32.whl", hash = "sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1"}, + {file = "orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406"}, + {file = "orjson-3.10.14-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:0905ca08a10f7e0e0c97d11359609300eb1437490a7f32bbaa349de757e2e0c7"}, + {file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92d13292249f9f2a3e418cbc307a9fbbef043c65f4bd8ba1eb620bc2aaba3d15"}, + {file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90937664e776ad316d64251e2fa2ad69265e4443067668e4727074fe39676414"}, + {file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9ed3d26c4cb4f6babaf791aa46a029265850e80ec2a566581f5c2ee1a14df4f1"}, + {file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:56ee546c2bbe9599aba78169f99d1dc33301853e897dbaf642d654248280dc6e"}, + {file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:901e826cb2f1bdc1fcef3ef59adf0c451e8f7c0b5deb26c1a933fb66fb505eae"}, + {file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26336c0d4b2d44636e1e1e6ed1002f03c6aae4a8a9329561c8883f135e9ff010"}, + {file = "orjson-3.10.14-cp313-cp313-win32.whl", hash = "sha256:e2bc525e335a8545c4e48f84dd0328bc46158c9aaeb8a1c2276546e94540ea3d"}, + {file = "orjson-3.10.14-cp313-cp313-win_amd64.whl", hash = "sha256:eca04dfd792cedad53dc9a917da1a522486255360cb4e77619343a20d9f35364"}, + {file = "orjson-3.10.14-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9a0fba3b8a587a54c18585f077dcab6dd251c170d85cfa4d063d5746cd595a0f"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:175abf3d20e737fec47261d278f95031736a49d7832a09ab684026528c4d96db"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29ca1a93e035d570e8b791b6c0feddd403c6a5388bfe870bf2aa6bba1b9d9b8e"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f77202c80e8ab5a1d1e9faf642343bee5aaf332061e1ada4e9147dbd9eb00c46"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e2ec73b7099b6a29b40a62e08a23b936423bd35529f8f55c42e27acccde7954"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2d1679df9f9cd9504f8dff24555c1eaabba8aad7f5914f28dab99e3c2552c9d"}, + {file = "orjson-3.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691ab9a13834310a263664313e4f747ceb93662d14a8bdf20eb97d27ed488f16"}, + {file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b11ed82054fce82fb74cea33247d825d05ad6a4015ecfc02af5fbce442fbf361"}, + {file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:e70a1d62b8288677d48f3bea66c21586a5f999c64ecd3878edb7393e8d1b548d"}, + {file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:16642f10c1ca5611251bd835de9914a4b03095e28a34c8ba6a5500b5074338bd"}, + {file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3871bad546aa66c155e3f36f99c459780c2a392d502a64e23fb96d9abf338511"}, + {file = "orjson-3.10.14-cp38-cp38-win32.whl", hash = "sha256:0293a88815e9bb5c90af4045f81ed364d982f955d12052d989d844d6c4e50945"}, + {file = "orjson-3.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:6169d3868b190d6b21adc8e61f64e3db30f50559dfbdef34a1cd6c738d409dfc"}, + {file = "orjson-3.10.14-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:06d4ec218b1ec1467d8d64da4e123b4794c781b536203c309ca0f52819a16c03"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962c2ec0dcaf22b76dee9831fdf0c4a33d4bf9a257a2bc5d4adc00d5c8ad9034"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:21d3be4132f71ef1360385770474f29ea1538a242eef72ac4934fe142800e37f"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c28ed60597c149a9e3f5ad6dd9cebaee6fb2f0e3f2d159a4a2b9b862d4748860"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e947f70167fe18469f2023644e91ab3d24f9aed69a5e1c78e2c81b9cea553fb"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64410696c97a35af2432dea7bdc4ce32416458159430ef1b4beb79fd30093ad6"}, + {file = "orjson-3.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8050a5d81c022561ee29cd2739de5b4445f3c72f39423fde80a63299c1892c52"}, + {file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b49a28e30d3eca86db3fe6f9b7f4152fcacbb4a467953cd1b42b94b479b77956"}, + {file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ca041ad20291a65d853a9523744eebc3f5a4b2f7634e99f8fe88320695ddf766"}, + {file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d313a2998b74bb26e9e371851a173a9b9474764916f1fc7971095699b3c6e964"}, + {file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7796692136a67b3e301ef9052bde6fe8e7bd5200da766811a3a608ffa62aaff0"}, + {file = "orjson-3.10.14-cp39-cp39-win32.whl", hash = "sha256:eee4bc767f348fba485ed9dc576ca58b0a9eac237f0e160f7a59bce628ed06b3"}, + {file = "orjson-3.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:96a1c0ee30fb113b3ae3c748fd75ca74a157ff4c58476c47db4d61518962a011"}, + {file = "orjson-3.10.14.tar.gz", hash = "sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed"}, +] + +[[package]] +name = "packaging" +version = "24.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] + +[[package]] +name = "pandas" +version = "2.2.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, + {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, + {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, + {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, + {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, + {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, + {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, + {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "parso" +version = "0.8.4" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] + +[package.extras] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and (sys_platform != \"win32\" and sys_platform != \"emscripten\") or python_version >= \"3.12\" and (sys_platform != \"win32\" and sys_platform != \"emscripten\")" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.48" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, + {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "6.1.1" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, + {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, + {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, + {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, + {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, + {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, + {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, + {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, +] + +[package.extras] +dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and (sys_platform != \"win32\" and sys_platform != \"emscripten\") or python_version >= \"3.12\" and (sys_platform != \"win32\" and sys_platform != \"emscripten\")" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and implementation_name == \"pypy\" or python_version >= \"3.12\" and implementation_name == \"pypy\"" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydataverse" +version = "0.3.4" +description = "A Python module for Dataverse." +optional = false +python-versions = "<4.0.0,>=3.8.1" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pydataverse-0.3.4-py3-none-any.whl", hash = "sha256:4bcfdb43dcd030eb491d383dffd9887da67c6ba9f119ef9bbb9fa5d4396ed5aa"}, + {file = "pydataverse-0.3.4.tar.gz", hash = "sha256:3cc3750211cbece3a309a99e2a3f26622b83071e2e4ebd9d1d5e8e88f593974e"}, +] + +[package.dependencies] +httpx = ">=0.27.0,<0.28.0" +jsonschema = ">=4.21.1,<5.0.0" + +[[package]] +name = "pygments" +version = "2.19.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "pytz" +version = "2024.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + +[[package]] +name = "pywin32" +version = "308" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" and sys_platform == \"win32\" and platform_python_implementation != \"PyPy\" or python_version >= \"3.12\" and sys_platform == \"win32\" and platform_python_implementation != \"PyPy\"" +files = [ + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, + {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, + {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, + {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, + {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, + {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, + {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, +] + +[[package]] +name = "pyzmq" +version = "26.2.0" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "pyzmq-26.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629"}, + {file = "pyzmq-26.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea"}, + {file = "pyzmq-26.2.0-cp310-cp310-win32.whl", hash = "sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2"}, + {file = "pyzmq-26.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971"}, + {file = "pyzmq-26.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa"}, + {file = "pyzmq-26.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218"}, + {file = "pyzmq-26.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6"}, + {file = "pyzmq-26.2.0-cp311-cp311-win32.whl", hash = "sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4"}, + {file = "pyzmq-26.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5"}, + {file = "pyzmq-26.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003"}, + {file = "pyzmq-26.2.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9"}, + {file = "pyzmq-26.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b"}, + {file = "pyzmq-26.2.0-cp312-cp312-win32.whl", hash = "sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7"}, + {file = "pyzmq-26.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a"}, + {file = "pyzmq-26.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b"}, + {file = "pyzmq-26.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9dd8cd1aeb00775f527ec60022004d030ddc51d783d056e3e23e74e623e33726"}, + {file = "pyzmq-26.2.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:28c812d9757fe8acecc910c9ac9dafd2ce968c00f9e619db09e9f8f54c3a68a3"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d80b1dd99c1942f74ed608ddb38b181b87476c6a966a88a950c7dee118fdf50"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c997098cc65e3208eca09303630e84d42718620e83b733d0fd69543a9cab9cb"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ad1bc8d1b7a18497dda9600b12dc193c577beb391beae5cd2349184db40f187"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:bea2acdd8ea4275e1278350ced63da0b166421928276c7c8e3f9729d7402a57b"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:23f4aad749d13698f3f7b64aad34f5fc02d6f20f05999eebc96b89b01262fb18"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a4f96f0d88accc3dbe4a9025f785ba830f968e21e3e2c6321ccdfc9aef755115"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ced65e5a985398827cc9276b93ef6dfabe0273c23de8c7931339d7e141c2818e"}, + {file = "pyzmq-26.2.0-cp313-cp313-win32.whl", hash = "sha256:31507f7b47cc1ead1f6e86927f8ebb196a0bab043f6345ce070f412a59bf87b5"}, + {file = "pyzmq-26.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:70fc7fcf0410d16ebdda9b26cbd8bf8d803d220a7f3522e060a69a9c87bf7bad"}, + {file = "pyzmq-26.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:c3789bd5768ab5618ebf09cef6ec2b35fed88709b104351748a63045f0ff9797"}, + {file = "pyzmq-26.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:034da5fc55d9f8da09015d368f519478a52675e558c989bfcb5cf6d4e16a7d2a"}, + {file = "pyzmq-26.2.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c92d73464b886931308ccc45b2744e5968cbaade0b1d6aeb40d8ab537765f5bc"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:794a4562dcb374f7dbbfb3f51d28fb40123b5a2abadee7b4091f93054909add5"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aee22939bb6075e7afededabad1a56a905da0b3c4e3e0c45e75810ebe3a52672"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae90ff9dad33a1cfe947d2c40cb9cb5e600d759ac4f0fd22616ce6540f72797"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:43a47408ac52647dfabbc66a25b05b6a61700b5165807e3fbd40063fcaf46386"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:25bf2374a2a8433633c65ccb9553350d5e17e60c8eb4de4d92cc6bd60f01d306"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:007137c9ac9ad5ea21e6ad97d3489af654381324d5d3ba614c323f60dab8fae6"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:470d4a4f6d48fb34e92d768b4e8a5cc3780db0d69107abf1cd7ff734b9766eb0"}, + {file = "pyzmq-26.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b55a4229ce5da9497dd0452b914556ae58e96a4381bb6f59f1305dfd7e53fc8"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9cb3a6460cdea8fe8194a76de8895707e61ded10ad0be97188cc8463ffa7e3a8"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ab5cad923cc95c87bffee098a27856c859bd5d0af31bd346035aa816b081fe1"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ed69074a610fad1c2fda66180e7b2edd4d31c53f2d1872bc2d1211563904cd9"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cccba051221b916a4f5e538997c45d7d136a5646442b1231b916d0164067ea27"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:0eaa83fc4c1e271c24eaf8fb083cbccef8fde77ec8cd45f3c35a9a123e6da097"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9edda2df81daa129b25a39b86cb57dfdfe16f7ec15b42b19bfac503360d27a93"}, + {file = "pyzmq-26.2.0-cp37-cp37m-win32.whl", hash = "sha256:ea0eb6af8a17fa272f7b98d7bebfab7836a0d62738e16ba380f440fceca2d951"}, + {file = "pyzmq-26.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4ff9dc6bc1664bb9eec25cd17506ef6672d506115095411e237d571e92a58231"}, + {file = "pyzmq-26.2.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2eb7735ee73ca1b0d71e0e67c3739c689067f055c764f73aac4cc8ecf958ee3f"}, + {file = "pyzmq-26.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a534f43bc738181aa7cbbaf48e3eca62c76453a40a746ab95d4b27b1111a7d2"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:aedd5dd8692635813368e558a05266b995d3d020b23e49581ddd5bbe197a8ab6"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8be4700cd8bb02cc454f630dcdf7cfa99de96788b80c51b60fe2fe1dac480289"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fcc03fa4997c447dce58264e93b5aa2d57714fbe0f06c07b7785ae131512732"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:402b190912935d3db15b03e8f7485812db350d271b284ded2b80d2e5704be780"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8685fa9c25ff00f550c1fec650430c4b71e4e48e8d852f7ddcf2e48308038640"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:76589c020680778f06b7e0b193f4b6dd66d470234a16e1df90329f5e14a171cd"}, + {file = "pyzmq-26.2.0-cp38-cp38-win32.whl", hash = "sha256:8423c1877d72c041f2c263b1ec6e34360448decfb323fa8b94e85883043ef988"}, + {file = "pyzmq-26.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:76589f2cd6b77b5bdea4fca5992dc1c23389d68b18ccc26a53680ba2dc80ff2f"}, + {file = "pyzmq-26.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:b1d464cb8d72bfc1a3adc53305a63a8e0cac6bc8c5a07e8ca190ab8d3faa43c2"}, + {file = "pyzmq-26.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4da04c48873a6abdd71811c5e163bd656ee1b957971db7f35140a2d573f6949c"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d049df610ac811dcffdc147153b414147428567fbbc8be43bb8885f04db39d98"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05590cdbc6b902101d0e65d6a4780af14dc22914cc6ab995d99b85af45362cc9"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c811cfcd6a9bf680236c40c6f617187515269ab2912f3d7e8c0174898e2519db"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6835dd60355593de10350394242b5757fbbd88b25287314316f266e24c61d073"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc6bee759a6bddea5db78d7dcd609397449cb2d2d6587f48f3ca613b19410cfc"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c530e1eecd036ecc83c3407f77bb86feb79916d4a33d11394b8234f3bd35b940"}, + {file = "pyzmq-26.2.0-cp39-cp39-win32.whl", hash = "sha256:367b4f689786fca726ef7a6c5ba606958b145b9340a5e4808132cc65759abd44"}, + {file = "pyzmq-26.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6fa2e3e683f34aea77de8112f6483803c96a44fd726d7358b9888ae5bb394ec"}, + {file = "pyzmq-26.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:7445be39143a8aa4faec43b076e06944b8f9d0701b669df4af200531b21e40bb"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2ea4ad4e6a12e454de05f2949d4beddb52460f3de7c8b9d5c46fbb7d7222e02c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fc4f7a173a5609631bb0c42c23d12c49df3966f89f496a51d3eb0ec81f4519d6"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:878206a45202247781472a2d99df12a176fef806ca175799e1c6ad263510d57c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17c412bad2eb9468e876f556eb4ee910e62d721d2c7a53c7fa31e643d35352e6"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:0d987a3ae5a71c6226b203cfd298720e0086c7fe7c74f35fa8edddfbd6597eed"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:39887ac397ff35b7b775db7201095fc6310a35fdbae85bac4523f7eb3b840e20"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fdb5b3e311d4d4b0eb8b3e8b4d1b0a512713ad7e6a68791d0923d1aec433d919"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:226af7dcb51fdb0109f0016449b357e182ea0ceb6b47dfb5999d569e5db161d5"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bed0e799e6120b9c32756203fb9dfe8ca2fb8467fed830c34c877e25638c3fc"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:29c7947c594e105cb9e6c466bace8532dc1ca02d498684128b339799f5248277"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cdeabcff45d1c219636ee2e54d852262e5c2e085d6cb476d938aee8d921356b3"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35cffef589bcdc587d06f9149f8d5e9e8859920a071df5a2671de2213bef592a"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18c8dc3b7468d8b4bdf60ce9d7141897da103c7a4690157b32b60acb45e333e6"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7133d0a1677aec369d67dd78520d3fa96dd7f3dcec99d66c1762870e5ea1a50a"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a96179a24b14fa6428cbfc08641c779a53f8fcec43644030328f44034c7f1f4"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4f78c88905461a9203eac9faac157a2a0dbba84a0fd09fd29315db27be40af9f"}, + {file = "pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "referencing" +version = "0.36.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "referencing-0.36.0-py3-none-any.whl", hash = "sha256:01fc2916bab821aa3284d645bbbb41ba39609e7ff47072416a39ec2fb04d10d9"}, + {file = "referencing-0.36.0.tar.gz", hash = "sha256:246db964bb6101905167895cd66499cfb2aabc5f83277d008c52afe918ef29ba"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" +typing-extensions = {version = "*", markers = "python_version < \"3.13\""} + +[[package]] +name = "rich" +version = "13.9.4" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "rich-argparse" +version = "1.6.0" +description = "Rich help formatters for argparse and optparse" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "rich_argparse-1.6.0-py3-none-any.whl", hash = "sha256:fbe70a1d821b3f2fa8958cddf0cae131870a6e9faa04ab52b409cb1eda809bd7"}, + {file = "rich_argparse-1.6.0.tar.gz", hash = "sha256:092083c30da186f25bcdff8b1d47fdfb571288510fb051e0488a72cc3128de13"}, +] + +[package.dependencies] +rich = ">=11.0.0" + +[[package]] +name = "rpds-py" +version = "0.22.3" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967"}, + {file = "rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf"}, + {file = "rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652"}, + {file = "rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a"}, + {file = "rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64"}, + {file = "rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7"}, + {file = "rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627"}, + {file = "rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f"}, + {file = "rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de"}, + {file = "rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520"}, + {file = "rpds_py-0.22.3-cp39-cp39-win32.whl", hash = "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9"}, + {file = "rpds_py-0.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6"}, + {file = "rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d"}, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "tornado" +version = "6.4.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1"}, + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c"}, + {file = "tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482"}, + {file = "tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38"}, + {file = "tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"}, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "typer" +version = "0.13.1" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "typer-0.13.1-py3-none-any.whl", hash = "sha256:5b59580fd925e89463a29d363e0a43245ec02765bde9fb77d39e5d0f29dd7157"}, + {file = "typer-0.13.1.tar.gz", hash = "sha256:9d444cb96cc268ce6f8b94e13b4335084cef4c079998a9f4851a90229a3bd25c"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] +markers = {main = "python_version <= \"3.11\" or python_version >= \"3.12\"", dev = "python_version <= \"3.11\""} + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +groups = ["main"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +groups = ["main", "dev"] +markers = "python_version <= \"3.11\" or python_version >= \"3.12\"" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[metadata] +lock-version = "2.1" +python-versions = "^3.10" +content-hash = "51d846fcf3406f709e746219b4f791a1866d2933254073f10d2c1b626426e018" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3b2d991 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,107 @@ +[tool.poetry] +name = "dataverse-metadata-crawler" +version = "0.1.0" +description = "A Python CLI tool for extracting and exporting metadata from Dataverse repositories to JSON and CSV formats." +authors = ["Ken Lui "] +license = "MIT" +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.10" +httpx = "^0.27.2" +orjson = "^3.10.14" +asyncio = "^3.4.3" +jmespath = "^1.0.1" +typer = "^0.13.1" +rich-argparse = "^1.6.0" +jinja2 = "^3.1.4" +ipykernel = "^6.29.5" +pandas = "^2.2.3" +python-dotenv = "^1.0.1" +pydataverse = "^0.3.4" +numpy = "^2.2.1" +json2 = "^0.9.0" + + +[tool.poetry.group.dev.dependencies] +ipykernel = "^6.29.5" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.ruff] +# General settings +line-length = 120 +indent-width = 4 +ignore = ["T201"] # Ignore print statements globally + +[tool.ruff.format] +quote-style = "single" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[tool.ruff.lint] +# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. +select = [ + "E", # pycodestyle errors + "F", # Pyflakes + "W", # pycodestyle warnings + "C90", # mccabe + "I", # isort + "N", # pep8-naming + "D", # pydocstring + "UP", # pyupgrade + "ANN", # flake8-annotations + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "DTZ", # flake8-datetimez + "EM", # flake8-errmsg + "G", # flake8-logging-format + "PIE", # flake8-pie + "T20", # flake8-print + "Q", # flake8-quotes + "RSE", # flake8-raise + "RET", # flake8-return + "SIM", # flake8-simplify + "PTH", # flake8-use-pathlib + "PL", # Pylint +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.lint.isort] +force-single-line = true +lines-after-imports = 2 +known-first-party = ["my_package"] + +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "single" + +[tool.ruff.lint.pylint] +max-args = 6 # Google suggests keeping functions focused +max-locals = 15 +max-statements = 50 + +[tool.ruff.lint.mccabe] +max-complexity = 10 # Google suggests keeping functions simple + +[tool.ruff.lint.per-file-ignores] +# Ignore some rules in tests +"test_*.py" = ["D", "ANN"] +# Ignore some rules in __init__.py files +"__init__.py" = ["F401"] +# Ignore long line warnings in main.py +"dvmeta/main.py" = ["E501", "W505"] + +[tool.ruff.lint.pep8-naming] +# Google style guide naming conventions +classmethod-decorators = ["classmethod"] +staticmethod-decorators = ["staticmethod"] + +[tool.ruff.lint.pycodestyle] +max-doc-length = 120 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e0bf57b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,762 @@ +anyio==4.8.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a \ + --hash=sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a +appnope==0.1.4 ; python_version >= "3.10" and python_version <= "3.11" and platform_system == "Darwin" or python_version >= "3.12" and python_version < "4.0" and platform_system == "Darwin" \ + --hash=sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee \ + --hash=sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c +asttokens==3.0.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7 \ + --hash=sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2 +asyncio==3.4.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41 \ + --hash=sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de \ + --hash=sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c \ + --hash=sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d +attrs==24.3.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff \ + --hash=sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308 +certifi==2024.12.14 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \ + --hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db +cffi==1.17.1 ; python_version >= "3.10" and python_version <= "3.11" and implementation_name == "pypy" or python_version >= "3.12" and python_version < "4.0" and implementation_name == "pypy" \ + --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ + --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ + --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ + --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ + --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ + --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ + --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ + --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ + --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ + --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ + --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ + --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ + --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ + --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ + --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ + --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ + --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ + --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ + --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ + --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ + --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ + --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ + --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ + --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ + --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ + --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ + --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ + --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ + --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ + --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ + --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ + --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ + --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ + --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ + --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ + --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ + --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ + --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ + --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ + --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ + --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ + --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ + --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ + --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ + --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ + --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ + --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ + --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ + --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ + --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ + --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ + --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ + --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ + --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ + --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ + --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ + --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ + --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ + --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ + --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ + --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ + --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ + --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ + --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ + --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ + --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ + --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b +click==8.1.8 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2 \ + --hash=sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a +colorama==0.4.6 ; python_version >= "3.10" and python_version <= "3.11" and platform_system == "Windows" or python_version >= "3.10" and python_version <= "3.11" and sys_platform == "win32" or python_version >= "3.12" and python_version < "4.0" and platform_system == "Windows" or python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 +comm==0.2.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e \ + --hash=sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3 +debugpy==1.8.12 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06 \ + --hash=sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180 \ + --hash=sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6 \ + --hash=sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d \ + --hash=sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5 \ + --hash=sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969 \ + --hash=sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1 \ + --hash=sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb \ + --hash=sha256:557cc55b51ab2f3371e238804ffc8510b6ef087673303890f57a24195d096e61 \ + --hash=sha256:5cc45235fefac57f52680902b7d197fb2f3650112379a6fa9aa1b1c1d3ed3f02 \ + --hash=sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce \ + --hash=sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f \ + --hash=sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498 \ + --hash=sha256:88a77f422f31f170c4b7e9ca58eae2a6c8e04da54121900651dfa8e66c29901a \ + --hash=sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9 \ + --hash=sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9 \ + --hash=sha256:9af40506a59450f1315168d47a970db1a65aaab5df3833ac389d2899a5d63b3f \ + --hash=sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7 \ + --hash=sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a \ + --hash=sha256:a4042edef80364239f5b7b5764e55fd3ffd40c32cf6753da9bda4ff0ac466018 \ + --hash=sha256:b0232cd42506d0c94f9328aaf0d1d0785f90f87ae72d9759df7e5051be039738 \ + --hash=sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c \ + --hash=sha256:b5c6c967d02fee30e157ab5227706f965d5c37679c687b1e7bbc5d9e7128bd41 \ + --hash=sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45 \ + --hash=sha256:f30b03b0f27608a0b26c75f0bb8a880c752c0e0b01090551b9d87c7d783e2069 \ + --hash=sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c +decorator==5.1.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330 \ + --hash=sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186 +exceptiongroup==1.2.2 ; python_version >= "3.10" and python_version < "3.11" \ + --hash=sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b \ + --hash=sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc +executing==2.1.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf \ + --hash=sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab +h11==0.14.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ + --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 +httpcore==1.0.7 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c \ + --hash=sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd +httpx==0.27.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ + --hash=sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2 +idna==3.10 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +ipykernel==6.29.5 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5 \ + --hash=sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215 +ipython==8.31.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:46ec58f8d3d076a61d128fe517a51eb730e3aaf0c184ea8c17d16e366660c6a6 \ + --hash=sha256:b6a2274606bec6166405ff05e54932ed6e5cfecaca1fc05f2cacde7bb074d70b +jedi==0.19.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ + --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 +jinja2==3.1.5 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb \ + --hash=sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb +jmespath==1.0.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ + --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe +json2==0.9.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:1f6273489f58fe7676df9edf6066ece2dadc015b0d6626ba8e4f1827b2c112ba \ + --hash=sha256:28c7ac7e9475d8758e05f19b34b1defe9df8a8fe21e8818895c7b357a6e71c9d +jsonschema-specifications==2024.10.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272 \ + --hash=sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf +jsonschema==4.23.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4 \ + --hash=sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566 +jupyter-client==8.6.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419 \ + --hash=sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f +jupyter-core==5.7.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409 \ + --hash=sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9 +markdown-it-py==3.0.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ + --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb +markupsafe==3.0.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \ + --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \ + --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \ + --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \ + --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \ + --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \ + --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \ + --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \ + --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \ + --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \ + --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \ + --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \ + --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \ + --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \ + --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \ + --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \ + --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \ + --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \ + --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \ + --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \ + --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \ + --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \ + --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ + --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 +matplotlib-inline==0.1.7 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90 \ + --hash=sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca +mdurl==0.1.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ + --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba +nest-asyncio==1.6.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe \ + --hash=sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c +numpy==2.2.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2 \ + --hash=sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5 \ + --hash=sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60 \ + --hash=sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71 \ + --hash=sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631 \ + --hash=sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8 \ + --hash=sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2 \ + --hash=sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16 \ + --hash=sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa \ + --hash=sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591 \ + --hash=sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964 \ + --hash=sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821 \ + --hash=sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484 \ + --hash=sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957 \ + --hash=sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800 \ + --hash=sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918 \ + --hash=sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95 \ + --hash=sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0 \ + --hash=sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e \ + --hash=sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d \ + --hash=sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73 \ + --hash=sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59 \ + --hash=sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51 \ + --hash=sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355 \ + --hash=sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348 \ + --hash=sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e \ + --hash=sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440 \ + --hash=sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675 \ + --hash=sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84 \ + --hash=sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046 \ + --hash=sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab \ + --hash=sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712 \ + --hash=sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308 \ + --hash=sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315 \ + --hash=sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3 \ + --hash=sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008 \ + --hash=sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5 \ + --hash=sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2 \ + --hash=sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e \ + --hash=sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7 \ + --hash=sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf \ + --hash=sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab \ + --hash=sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd \ + --hash=sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf \ + --hash=sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8 \ + --hash=sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb \ + --hash=sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268 \ + --hash=sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d \ + --hash=sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780 \ + --hash=sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716 \ + --hash=sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e \ + --hash=sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528 \ + --hash=sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af \ + --hash=sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7 \ + --hash=sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51 +orjson==3.10.14 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:0293a88815e9bb5c90af4045f81ed364d982f955d12052d989d844d6c4e50945 \ + --hash=sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780 \ + --hash=sha256:06d4ec218b1ec1467d8d64da4e123b4794c781b536203c309ca0f52819a16c03 \ + --hash=sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe \ + --hash=sha256:0905ca08a10f7e0e0c97d11359609300eb1437490a7f32bbaa349de757e2e0c7 \ + --hash=sha256:0de4d6315cfdbd9ec803b945c23b3a68207fd47cbe43626036d97e8e9561a436 \ + --hash=sha256:164ac155109226b3a2606ee6dda899ccfbe6e7e18b5bdc3fbc00f79cc074157d \ + --hash=sha256:16642f10c1ca5611251bd835de9914a4b03095e28a34c8ba6a5500b5074338bd \ + --hash=sha256:175abf3d20e737fec47261d278f95031736a49d7832a09ab684026528c4d96db \ + --hash=sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406 \ + --hash=sha256:1b49e2af011c84c3f2d541bb5cd1e3c7c2df672223e7e3ea608f09cf295e5f8a \ + --hash=sha256:21d3be4132f71ef1360385770474f29ea1538a242eef72ac4934fe142800e37f \ + --hash=sha256:26336c0d4b2d44636e1e1e6ed1002f03c6aae4a8a9329561c8883f135e9ff010 \ + --hash=sha256:29ca1a93e035d570e8b791b6c0feddd403c6a5388bfe870bf2aa6bba1b9d9b8e \ + --hash=sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09 \ + --hash=sha256:33449c67195969b1a677533dee9d76e006001213a24501333624623e13c7cc8e \ + --hash=sha256:36f5bfc0399cd4811bf10ec7a759c7ab0cd18080956af8ee138097d5b5296a95 \ + --hash=sha256:3871bad546aa66c155e3f36f99c459780c2a392d502a64e23fb96d9abf338511 \ + --hash=sha256:397083806abd51cf2b3bbbf6c347575374d160331a2d33c5823e22249ad3118b \ + --hash=sha256:3af8e42ae4363773658b8d578d56dedffb4f05ceeb4d1d4dd3fb504950b45526 \ + --hash=sha256:4ddc8c866d7467f5ee2991397d2ea94bcf60d0048bdd8ca555740b56f9042725 \ + --hash=sha256:4f5007abfdbb1d866e2aa8990bd1c465f0f6da71d19e695fc278282be12cffa5 \ + --hash=sha256:56ee546c2bbe9599aba78169f99d1dc33301853e897dbaf642d654248280dc6e \ + --hash=sha256:6169d3868b190d6b21adc8e61f64e3db30f50559dfbdef34a1cd6c738d409dfc \ + --hash=sha256:64410696c97a35af2432dea7bdc4ce32416458159430ef1b4beb79fd30093ad6 \ + --hash=sha256:691ab9a13834310a263664313e4f747ceb93662d14a8bdf20eb97d27ed488f16 \ + --hash=sha256:6b1225024cf0ef5d15934b5ffe9baf860fe8bc68a796513f5ea4f5056de30bca \ + --hash=sha256:6e2ec73b7099b6a29b40a62e08a23b936423bd35529f8f55c42e27acccde7954 \ + --hash=sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953 \ + --hash=sha256:7796692136a67b3e301ef9052bde6fe8e7bd5200da766811a3a608ffa62aaff0 \ + --hash=sha256:7e947f70167fe18469f2023644e91ab3d24f9aed69a5e1c78e2c81b9cea553fb \ + --hash=sha256:8050a5d81c022561ee29cd2739de5b4445f3c72f39423fde80a63299c1892c52 \ + --hash=sha256:83adda3db595cb1a7e2237029b3249c85afbe5c747d26b41b802e7482cb3933e \ + --hash=sha256:849ea7845a55f09965826e816cdc7689d6cf74fe9223d79d758c714af955bcb6 \ + --hash=sha256:84dd83110503bc10e94322bf3ffab8bc49150176b49b4984dc1cce4c0a993bf9 \ + --hash=sha256:868943660fb2a1e6b6b965b74430c16a79320b665b28dd4511d15ad5038d37d5 \ + --hash=sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb \ + --hash=sha256:901e826cb2f1bdc1fcef3ef59adf0c451e8f7c0b5deb26c1a933fb66fb505eae \ + --hash=sha256:90937664e776ad316d64251e2fa2ad69265e4443067668e4727074fe39676414 \ + --hash=sha256:92d13292249f9f2a3e418cbc307a9fbbef043c65f4bd8ba1eb620bc2aaba3d15 \ + --hash=sha256:962c2ec0dcaf22b76dee9831fdf0c4a33d4bf9a257a2bc5d4adc00d5c8ad9034 \ + --hash=sha256:96a1c0ee30fb113b3ae3c748fd75ca74a157ff4c58476c47db4d61518962a011 \ + --hash=sha256:998019ef74a4997a9d741b1473533cdb8faa31373afc9849b35129b4b8ec048d \ + --hash=sha256:9a0fba3b8a587a54c18585f077dcab6dd251c170d85cfa4d063d5746cd595a0f \ + --hash=sha256:9d034abdd36f0f0f2240f91492684e5043d46f290525d1117712d5b8137784eb \ + --hash=sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b \ + --hash=sha256:9ed3d26c4cb4f6babaf791aa46a029265850e80ec2a566581f5c2ee1a14df4f1 \ + --hash=sha256:9f1d2942605c894162252d6259b0121bf1cb493071a1ea8cb35d79cb3e6ac5bc \ + --hash=sha256:a2d1679df9f9cd9504f8dff24555c1eaabba8aad7f5914f28dab99e3c2552c9d \ + --hash=sha256:b11ed82054fce82fb74cea33247d825d05ad6a4015ecfc02af5fbce442fbf361 \ + --hash=sha256:b49a28e30d3eca86db3fe6f9b7f4152fcacbb4a467953cd1b42b94b479b77956 \ + --hash=sha256:b5947b139dfa33f72eecc63f17e45230a97e741942955a6c9e650069305eb73d \ + --hash=sha256:c28ed60597c149a9e3f5ad6dd9cebaee6fb2f0e3f2d159a4a2b9b862d4748860 \ + --hash=sha256:c6dfbaeb7afa77ca608a50e2770a0461177b63a99520d4928e27591b142c74b1 \ + --hash=sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf \ + --hash=sha256:ca041ad20291a65d853a9523744eebc3f5a4b2f7634e99f8fe88320695ddf766 \ + --hash=sha256:cde6d76910d3179dae70f164466692f4ea36da124d6fb1a61399ca589e81d69a \ + --hash=sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed \ + --hash=sha256:d313a2998b74bb26e9e371851a173a9b9474764916f1fc7971095699b3c6e964 \ + --hash=sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1 \ + --hash=sha256:d6546e8073dc382e60fcae4a001a5a1bc46da5eab4a4878acc2d12072d6166d5 \ + --hash=sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c \ + --hash=sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3 \ + --hash=sha256:e2bc525e335a8545c4e48f84dd0328bc46158c9aaeb8a1c2276546e94540ea3d \ + --hash=sha256:e4c9f60f9fb0b5be66e416dcd8c9d94c3eabff3801d875bdb1f8ffc12cf86905 \ + --hash=sha256:e70a1d62b8288677d48f3bea66c21586a5f999c64ecd3878edb7393e8d1b548d \ + --hash=sha256:eca04dfd792cedad53dc9a917da1a522486255360cb4e77619343a20d9f35364 \ + --hash=sha256:eee4bc767f348fba485ed9dc576ca58b0a9eac237f0e160f7a59bce628ed06b3 \ + --hash=sha256:efe5fd254cfb0eeee13b8ef7ecb20f5d5a56ddda8a587f3852ab2cedfefdb5f6 \ + --hash=sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d \ + --hash=sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7 \ + --hash=sha256:f506fd666dd1ecd15a832bebc66c4df45c1902fd47526292836c339f7ba665a9 \ + --hash=sha256:f77202c80e8ab5a1d1e9faf642343bee5aaf332061e1ada4e9147dbd9eb00c46 \ + --hash=sha256:fa18f949d3183a8d468367056be989666ac2bef3a72eece0bade9cdb733b3c28 \ + --hash=sha256:fa45e489ef80f28ff0e5ba0a72812b8cfc7c1ef8b46a694723807d1b07c89ebb +packaging==24.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ + --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f +pandas==2.2.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a \ + --hash=sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d \ + --hash=sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5 \ + --hash=sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4 \ + --hash=sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0 \ + --hash=sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32 \ + --hash=sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea \ + --hash=sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28 \ + --hash=sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f \ + --hash=sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348 \ + --hash=sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18 \ + --hash=sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468 \ + --hash=sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5 \ + --hash=sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e \ + --hash=sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667 \ + --hash=sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645 \ + --hash=sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13 \ + --hash=sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30 \ + --hash=sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3 \ + --hash=sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d \ + --hash=sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb \ + --hash=sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3 \ + --hash=sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039 \ + --hash=sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8 \ + --hash=sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd \ + --hash=sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761 \ + --hash=sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659 \ + --hash=sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57 \ + --hash=sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c \ + --hash=sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c \ + --hash=sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4 \ + --hash=sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a \ + --hash=sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9 \ + --hash=sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42 \ + --hash=sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2 \ + --hash=sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39 \ + --hash=sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc \ + --hash=sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698 \ + --hash=sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed \ + --hash=sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015 \ + --hash=sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24 \ + --hash=sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319 +parso==0.8.4 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18 \ + --hash=sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d +pexpect==4.9.0 ; python_version >= "3.10" and python_version <= "3.11" and (sys_platform != "win32" and sys_platform != "emscripten") or python_version >= "3.12" and python_version < "4.0" and (sys_platform != "win32" and sys_platform != "emscripten") \ + --hash=sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 \ + --hash=sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f +platformdirs==4.3.6 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ + --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb +prompt-toolkit==3.0.48 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90 \ + --hash=sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e +psutil==6.1.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca \ + --hash=sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377 \ + --hash=sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468 \ + --hash=sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3 \ + --hash=sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603 \ + --hash=sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac \ + --hash=sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303 \ + --hash=sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4 \ + --hash=sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160 \ + --hash=sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8 \ + --hash=sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003 \ + --hash=sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030 \ + --hash=sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777 \ + --hash=sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5 \ + --hash=sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53 \ + --hash=sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649 \ + --hash=sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8 +ptyprocess==0.7.0 ; python_version >= "3.10" and python_version <= "3.11" and (sys_platform != "win32" and sys_platform != "emscripten") or python_version >= "3.12" and python_version < "4.0" and (sys_platform != "win32" and sys_platform != "emscripten") \ + --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ + --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 +pure-eval==0.2.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 \ + --hash=sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42 +pycparser==2.22 ; python_version >= "3.10" and python_version <= "3.11" and implementation_name == "pypy" or python_version >= "3.12" and python_version < "4.0" and implementation_name == "pypy" \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc +pydataverse==0.3.4 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:3cc3750211cbece3a309a99e2a3f26622b83071e2e4ebd9d1d5e8e88f593974e \ + --hash=sha256:4bcfdb43dcd030eb491d383dffd9887da67c6ba9f119ef9bbb9fa5d4396ed5aa +pygments==2.19.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f \ + --hash=sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c +python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 +python-dotenv==1.0.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ + --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a +pytz==2024.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \ + --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725 +pywin32==308 ; python_version >= "3.10" and python_version <= "3.11" and sys_platform == "win32" and platform_python_implementation != "PyPy" or python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" and platform_python_implementation != "PyPy" \ + --hash=sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47 \ + --hash=sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6 \ + --hash=sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6 \ + --hash=sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed \ + --hash=sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff \ + --hash=sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de \ + --hash=sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e \ + --hash=sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b \ + --hash=sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0 \ + --hash=sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897 \ + --hash=sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a \ + --hash=sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920 \ + --hash=sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341 \ + --hash=sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e \ + --hash=sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091 \ + --hash=sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c \ + --hash=sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd \ + --hash=sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4 +pyzmq==26.2.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:007137c9ac9ad5ea21e6ad97d3489af654381324d5d3ba614c323f60dab8fae6 \ + --hash=sha256:034da5fc55d9f8da09015d368f519478a52675e558c989bfcb5cf6d4e16a7d2a \ + --hash=sha256:05590cdbc6b902101d0e65d6a4780af14dc22914cc6ab995d99b85af45362cc9 \ + --hash=sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f \ + --hash=sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37 \ + --hash=sha256:0bed0e799e6120b9c32756203fb9dfe8ca2fb8467fed830c34c877e25638c3fc \ + --hash=sha256:0d987a3ae5a71c6226b203cfd298720e0086c7fe7c74f35fa8edddfbd6597eed \ + --hash=sha256:0eaa83fc4c1e271c24eaf8fb083cbccef8fde77ec8cd45f3c35a9a123e6da097 \ + --hash=sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d \ + --hash=sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52 \ + --hash=sha256:17c412bad2eb9468e876f556eb4ee910e62d721d2c7a53c7fa31e643d35352e6 \ + --hash=sha256:18c8dc3b7468d8b4bdf60ce9d7141897da103c7a4690157b32b60acb45e333e6 \ + --hash=sha256:1a534f43bc738181aa7cbbaf48e3eca62c76453a40a746ab95d4b27b1111a7d2 \ + --hash=sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282 \ + --hash=sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3 \ + --hash=sha256:1fcc03fa4997c447dce58264e93b5aa2d57714fbe0f06c07b7785ae131512732 \ + --hash=sha256:226af7dcb51fdb0109f0016449b357e182ea0ceb6b47dfb5999d569e5db161d5 \ + --hash=sha256:23f4aad749d13698f3f7b64aad34f5fc02d6f20f05999eebc96b89b01262fb18 \ + --hash=sha256:25bf2374a2a8433633c65ccb9553350d5e17e60c8eb4de4d92cc6bd60f01d306 \ + --hash=sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f \ + --hash=sha256:28c812d9757fe8acecc910c9ac9dafd2ce968c00f9e619db09e9f8f54c3a68a3 \ + --hash=sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b \ + --hash=sha256:29c7947c594e105cb9e6c466bace8532dc1ca02d498684128b339799f5248277 \ + --hash=sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a \ + --hash=sha256:2ae90ff9dad33a1cfe947d2c40cb9cb5e600d759ac4f0fd22616ce6540f72797 \ + --hash=sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca \ + --hash=sha256:2ea4ad4e6a12e454de05f2949d4beddb52460f3de7c8b9d5c46fbb7d7222e02c \ + --hash=sha256:2eb7735ee73ca1b0d71e0e67c3739c689067f055c764f73aac4cc8ecf958ee3f \ + --hash=sha256:31507f7b47cc1ead1f6e86927f8ebb196a0bab043f6345ce070f412a59bf87b5 \ + --hash=sha256:35cffef589bcdc587d06f9149f8d5e9e8859920a071df5a2671de2213bef592a \ + --hash=sha256:367b4f689786fca726ef7a6c5ba606958b145b9340a5e4808132cc65759abd44 \ + --hash=sha256:39887ac397ff35b7b775db7201095fc6310a35fdbae85bac4523f7eb3b840e20 \ + --hash=sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4 \ + --hash=sha256:3b55a4229ce5da9497dd0452b914556ae58e96a4381bb6f59f1305dfd7e53fc8 \ + --hash=sha256:402b190912935d3db15b03e8f7485812db350d271b284ded2b80d2e5704be780 \ + --hash=sha256:43a47408ac52647dfabbc66a25b05b6a61700b5165807e3fbd40063fcaf46386 \ + --hash=sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5 \ + --hash=sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2 \ + --hash=sha256:470d4a4f6d48fb34e92d768b4e8a5cc3780db0d69107abf1cd7ff734b9766eb0 \ + --hash=sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971 \ + --hash=sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b \ + --hash=sha256:4d80b1dd99c1942f74ed608ddb38b181b87476c6a966a88a950c7dee118fdf50 \ + --hash=sha256:4da04c48873a6abdd71811c5e163bd656ee1b957971db7f35140a2d573f6949c \ + --hash=sha256:4f78c88905461a9203eac9faac157a2a0dbba84a0fd09fd29315db27be40af9f \ + --hash=sha256:4ff9dc6bc1664bb9eec25cd17506ef6672d506115095411e237d571e92a58231 \ + --hash=sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c \ + --hash=sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08 \ + --hash=sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5 \ + --hash=sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6 \ + --hash=sha256:6835dd60355593de10350394242b5757fbbd88b25287314316f266e24c61d073 \ + --hash=sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e \ + --hash=sha256:6a96179a24b14fa6428cbfc08641c779a53f8fcec43644030328f44034c7f1f4 \ + --hash=sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317 \ + --hash=sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3 \ + --hash=sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072 \ + --hash=sha256:70fc7fcf0410d16ebdda9b26cbd8bf8d803d220a7f3522e060a69a9c87bf7bad \ + --hash=sha256:7133d0a1677aec369d67dd78520d3fa96dd7f3dcec99d66c1762870e5ea1a50a \ + --hash=sha256:7445be39143a8aa4faec43b076e06944b8f9d0701b669df4af200531b21e40bb \ + --hash=sha256:76589c020680778f06b7e0b193f4b6dd66d470234a16e1df90329f5e14a171cd \ + --hash=sha256:76589f2cd6b77b5bdea4fca5992dc1c23389d68b18ccc26a53680ba2dc80ff2f \ + --hash=sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef \ + --hash=sha256:794a4562dcb374f7dbbfb3f51d28fb40123b5a2abadee7b4091f93054909add5 \ + --hash=sha256:7ad1bc8d1b7a18497dda9600b12dc193c577beb391beae5cd2349184db40f187 \ + --hash=sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711 \ + --hash=sha256:8423c1877d72c041f2c263b1ec6e34360448decfb323fa8b94e85883043ef988 \ + --hash=sha256:8685fa9c25ff00f550c1fec650430c4b71e4e48e8d852f7ddcf2e48308038640 \ + --hash=sha256:878206a45202247781472a2d99df12a176fef806ca175799e1c6ad263510d57c \ + --hash=sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764 \ + --hash=sha256:8ab5cad923cc95c87bffee098a27856c859bd5d0af31bd346035aa816b081fe1 \ + --hash=sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1 \ + --hash=sha256:8be4700cd8bb02cc454f630dcdf7cfa99de96788b80c51b60fe2fe1dac480289 \ + --hash=sha256:8c997098cc65e3208eca09303630e84d42718620e83b733d0fd69543a9cab9cb \ + --hash=sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a \ + --hash=sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218 \ + --hash=sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c \ + --hash=sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf \ + --hash=sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7 \ + --hash=sha256:9cb3a6460cdea8fe8194a76de8895707e61ded10ad0be97188cc8463ffa7e3a8 \ + --hash=sha256:9dd8cd1aeb00775f527ec60022004d030ddc51d783d056e3e23e74e623e33726 \ + --hash=sha256:9ed69074a610fad1c2fda66180e7b2edd4d31c53f2d1872bc2d1211563904cd9 \ + --hash=sha256:9edda2df81daa129b25a39b86cb57dfdfe16f7ec15b42b19bfac503360d27a93 \ + --hash=sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88 \ + --hash=sha256:a4f96f0d88accc3dbe4a9025f785ba830f968e21e3e2c6321ccdfc9aef755115 \ + --hash=sha256:aedd5dd8692635813368e558a05266b995d3d020b23e49581ddd5bbe197a8ab6 \ + --hash=sha256:aee22939bb6075e7afededabad1a56a905da0b3c4e3e0c45e75810ebe3a52672 \ + --hash=sha256:b1d464cb8d72bfc1a3adc53305a63a8e0cac6bc8c5a07e8ca190ab8d3faa43c2 \ + --hash=sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea \ + --hash=sha256:bc6bee759a6bddea5db78d7dcd609397449cb2d2d6587f48f3ca613b19410cfc \ + --hash=sha256:bea2acdd8ea4275e1278350ced63da0b166421928276c7c8e3f9729d7402a57b \ + --hash=sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa \ + --hash=sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003 \ + --hash=sha256:c3789bd5768ab5618ebf09cef6ec2b35fed88709b104351748a63045f0ff9797 \ + --hash=sha256:c530e1eecd036ecc83c3407f77bb86feb79916d4a33d11394b8234f3bd35b940 \ + --hash=sha256:c811cfcd6a9bf680236c40c6f617187515269ab2912f3d7e8c0174898e2519db \ + --hash=sha256:c92d73464b886931308ccc45b2744e5968cbaade0b1d6aeb40d8ab537765f5bc \ + --hash=sha256:cccba051221b916a4f5e538997c45d7d136a5646442b1231b916d0164067ea27 \ + --hash=sha256:cdeabcff45d1c219636ee2e54d852262e5c2e085d6cb476d938aee8d921356b3 \ + --hash=sha256:ced65e5a985398827cc9276b93ef6dfabe0273c23de8c7931339d7e141c2818e \ + --hash=sha256:d049df610ac811dcffdc147153b414147428567fbbc8be43bb8885f04db39d98 \ + --hash=sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b \ + --hash=sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629 \ + --hash=sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9 \ + --hash=sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6 \ + --hash=sha256:e6fa2e3e683f34aea77de8112f6483803c96a44fd726d7358b9888ae5bb394ec \ + --hash=sha256:ea0eb6af8a17fa272f7b98d7bebfab7836a0d62738e16ba380f440fceca2d951 \ + --hash=sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae \ + --hash=sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4 \ + --hash=sha256:fc4f7a173a5609631bb0c42c23d12c49df3966f89f496a51d3eb0ec81f4519d6 \ + --hash=sha256:fdb5b3e311d4d4b0eb8b3e8b4d1b0a512713ad7e6a68791d0923d1aec433d919 +referencing==0.36.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:01fc2916bab821aa3284d645bbbb41ba39609e7ff47072416a39ec2fb04d10d9 \ + --hash=sha256:246db964bb6101905167895cd66499cfb2aabc5f83277d008c52afe918ef29ba +rich-argparse==1.6.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:092083c30da186f25bcdff8b1d47fdfb571288510fb051e0488a72cc3128de13 \ + --hash=sha256:fbe70a1d821b3f2fa8958cddf0cae131870a6e9faa04ab52b409cb1eda809bd7 +rich==13.9.4 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098 \ + --hash=sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90 +rpds-py==0.22.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518 \ + --hash=sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059 \ + --hash=sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61 \ + --hash=sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5 \ + --hash=sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9 \ + --hash=sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543 \ + --hash=sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2 \ + --hash=sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a \ + --hash=sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d \ + --hash=sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56 \ + --hash=sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d \ + --hash=sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd \ + --hash=sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b \ + --hash=sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4 \ + --hash=sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99 \ + --hash=sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d \ + --hash=sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd \ + --hash=sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe \ + --hash=sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1 \ + --hash=sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e \ + --hash=sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f \ + --hash=sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3 \ + --hash=sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca \ + --hash=sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d \ + --hash=sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e \ + --hash=sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc \ + --hash=sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea \ + --hash=sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38 \ + --hash=sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b \ + --hash=sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c \ + --hash=sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff \ + --hash=sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723 \ + --hash=sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e \ + --hash=sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493 \ + --hash=sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6 \ + --hash=sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83 \ + --hash=sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091 \ + --hash=sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1 \ + --hash=sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627 \ + --hash=sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1 \ + --hash=sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728 \ + --hash=sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16 \ + --hash=sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c \ + --hash=sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45 \ + --hash=sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7 \ + --hash=sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a \ + --hash=sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730 \ + --hash=sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967 \ + --hash=sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25 \ + --hash=sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24 \ + --hash=sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055 \ + --hash=sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d \ + --hash=sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0 \ + --hash=sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e \ + --hash=sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7 \ + --hash=sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c \ + --hash=sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f \ + --hash=sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd \ + --hash=sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652 \ + --hash=sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8 \ + --hash=sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11 \ + --hash=sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333 \ + --hash=sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96 \ + --hash=sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64 \ + --hash=sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b \ + --hash=sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e \ + --hash=sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c \ + --hash=sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9 \ + --hash=sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec \ + --hash=sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb \ + --hash=sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37 \ + --hash=sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad \ + --hash=sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9 \ + --hash=sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c \ + --hash=sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf \ + --hash=sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4 \ + --hash=sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f \ + --hash=sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d \ + --hash=sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09 \ + --hash=sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d \ + --hash=sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566 \ + --hash=sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74 \ + --hash=sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338 \ + --hash=sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15 \ + --hash=sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c \ + --hash=sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648 \ + --hash=sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84 \ + --hash=sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3 \ + --hash=sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123 \ + --hash=sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520 \ + --hash=sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831 \ + --hash=sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e \ + --hash=sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf \ + --hash=sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b \ + --hash=sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2 \ + --hash=sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3 \ + --hash=sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130 \ + --hash=sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b \ + --hash=sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de \ + --hash=sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5 \ + --hash=sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d \ + --hash=sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00 \ + --hash=sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e +shellingham==1.5.4 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ + --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de +six==1.17.0 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 +sniffio==1.3.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ + --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc +stack-data==0.6.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ + --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 +tornado==6.4.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803 \ + --hash=sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec \ + --hash=sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482 \ + --hash=sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634 \ + --hash=sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38 \ + --hash=sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b \ + --hash=sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c \ + --hash=sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf \ + --hash=sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946 \ + --hash=sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73 \ + --hash=sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1 +traitlets==5.14.3 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ + --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f +typer==0.13.1 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:5b59580fd925e89463a29d363e0a43245ec02765bde9fb77d39e5d0f29dd7157 \ + --hash=sha256:9d444cb96cc268ce6f8b94e13b4335084cef4c079998a9f4851a90229a3bd25c +typing-extensions==4.12.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 +tzdata==2024.2 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc \ + --hash=sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd +wcwidth==0.2.13 ; python_version >= "3.10" and python_version <= "3.11" or python_version >= "3.12" and python_version < "4.0" \ + --hash=sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859 \ + --hash=sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5 diff --git a/res/log_template.txt b/res/log_template.txt new file mode 100644 index 0000000..d94118b --- /dev/null +++ b/res/log_template.txt @@ -0,0 +1,27 @@ +--- Summary --- +Repository base URL: {{ config.BASE_URL }} +Collection Name: {{ config.COLLECTION_NAME }} +Collection Alias: {{ config.COLLECTION_ALIAS }} +Collection ID: {{ config.COLLECTION_ID }} +Dataset Version: {{ config.VERSION }} + +Start time: {{ start_time_display }} +End time: {{ end_time_display }} +Execution time: {{ elapsed_time }} + +Total number of dataset crawled from the collection: {{ meta_dict }} +Number of dataverses (at all levels/depths) crawled from the collection: {{ collections_tree_flatten }} +Number of datasets failed to be crawled: {{ failed_metadata_ids }} + +Total number of files in the collection: {{ file_num }} +Total size of files in the collection: {{ file_size }} bytes + +{% if json_file_checksum_dict %} +Files saved: +{% for item in json_file_checksum_dict %} +Item type: {{ item.type }} +Item path: {{ item.path }} +Item checksum (SHA-256): {{ item.checksum }} +{% endfor %} +{% endif %} +--- End of Log --- \ No newline at end of file diff --git a/res/screenshot.png b/res/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..7175bd0ecfc73b4615138985f25625558cd5e8b1 GIT binary patch literal 92815 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
3hDmtn73ggPy3L?kz>B%cm2M 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